saar.raz created this revision.
saar.raz added reviewers: changyu, hubert.reinterpretcast, rsmith, nwilson.
Herald added a subscriber: cfe-commits.

Added code to correctly calculate the associated constraints of a template. 
Depends on https://reviews.llvm.org/D41217.


Repository:
  rC Clang

https://reviews.llvm.org/D41284

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1402,6 +1402,12 @@
     Record.AddDeclRef(D->getInstantiatedFromMemberTemplate());
     if (D->getInstantiatedFromMemberTemplate())
       Record.push_back(D->isMemberSpecialization());
+
+    Expr *AssociatedConstraints = D->getAssociatedConstraints();
+    Record.push_back(AssociatedConstraints != nullptr);
+    if (AssociatedConstraints) {
+      Record.AddStmt(AssociatedConstraints);
+    }
   }
   
   VisitTemplateDecl(D);
@@ -1463,6 +1469,11 @@
   if (D->getPreviousDecl() == nullptr) {
     Record.AddDeclRef(D->getInstantiatedFromMember());
     Record.push_back(D->isMemberSpecialization());
+    Expr *AssociatedConstraints = D->getAssociatedConstraints();
+    Record.push_back(AssociatedConstraints != nullptr);
+    if (AssociatedConstraints) {
+      Record.AddStmt(AssociatedConstraints);
+    }
   }
 
   Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION;
@@ -1523,6 +1534,11 @@
   if (D->getPreviousDecl() == nullptr) {
     Record.AddDeclRef(D->getInstantiatedFromMember());
     Record.push_back(D->isMemberSpecialization());
+    Expr *AssociatedConstraints = D->getAssociatedConstraints();
+    Record.push_back(AssociatedConstraints != nullptr);
+    if (AssociatedConstraints) {
+      Record.AddStmt(AssociatedConstraints);
+    }
   }
 
   Code = serialization::DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION;
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -5850,10 +5850,16 @@
   AddSourceLocation(TemplateParams->getTemplateLoc());
   AddSourceLocation(TemplateParams->getLAngleLoc());
   AddSourceLocation(TemplateParams->getRAngleLoc());
-  // TODO: Concepts
+
   Record->push_back(TemplateParams->size());
   for (const auto &P : *TemplateParams)
-    AddDeclRef(P);
+    AddDeclRef(P); // TODO: Concepts - constrained parameters.
+  if (const Expr *RequiresClause = TemplateParams->getRequiresClause()) {
+    Record->push_back(true);
+    AddStmt(const_cast<Expr*>(RequiresClause));
+  } else {
+    Record->push_back(false);
+  }
 }
 
 /// \brief Emit a template argument list.
Index: lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -1965,7 +1965,6 @@
   DeclID PatternID = ReadDeclID();
   NamedDecl *TemplatedDecl = cast_or_null<NamedDecl>(Reader.GetDecl(PatternID));
   TemplateParameterList *TemplateParams = Record.readTemplateParameterList();
-  // FIXME handle associated constraints
   D->init(TemplatedDecl, TemplateParams);
 
   return PatternID;
@@ -1991,6 +1990,7 @@
 
   // If this is the first declaration of the template, fill in the information
   // for the 'common' pointer.
+  Expr *AssociatedConstraints = nullptr;
   if (ThisDeclID == Redecl.getFirstID()) {
     if (RedeclarableTemplateDecl *RTD
           = ReadDeclAs<RedeclarableTemplateDecl>()) {
@@ -2000,11 +2000,23 @@
       if (Record.readInt())
         D->setMemberSpecialization();
     }
+    bool HasAssociatedConstraints = Record.readInt();
+    if (HasAssociatedConstraints) {
+       AssociatedConstraints = Record.readExpr();
+    }
   }
 
   DeclID PatternID = VisitTemplateDecl(D);
   D->IdentifierNamespace = Record.readInt();
 
+  D->TemplateParams.setInt(true);
+  if (AssociatedConstraints) {
+    auto *CTDI = new (Reader.getContext()) ConstrainedTemplateDeclInfo;
+    CTDI->setTemplateParameters(D->getTemplateParameters());
+    CTDI->setAssociatedConstraints(AssociatedConstraints);
+    D->TemplateParams.setPointer(CTDI);
+  }
+
   mergeRedeclarable(D, Redecl, PatternID);
 
   // If we merged the template with a prior declaration chain, merge the common
@@ -2132,14 +2144,24 @@
                                     ClassTemplatePartialSpecializationDecl *D) {
   RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D);
 
-  D->TemplateParams = Record.readTemplateParameterList();
+  TemplateParameterList *Params = Record.readTemplateParameterList();
+  D->TemplateParams.setPointer(Params);
   D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
 
   // These are read/set from/to the first declaration.
   if (ThisDeclID == Redecl.getFirstID()) {
     D->InstantiatedFromMember.setPointer(
       ReadDeclAs<ClassTemplatePartialSpecializationDecl>());
     D->InstantiatedFromMember.setInt(Record.readInt());
+    bool HasAssociatedConstraints = Record.readInt();
+    D->TemplateParams.setInt(true);
+    if (HasAssociatedConstraints) {
+      Expr *AssociatedConstraints = Record.readExpr();
+      auto *CTDI = new (Reader.getContext()) ConstrainedTemplateDeclInfo;
+      CTDI->setTemplateParameters(Params);
+      CTDI->setAssociatedConstraints(AssociatedConstraints);
+      D->TemplateParams.setPointer(CTDI);
+    }
   }
 }
 
@@ -2233,14 +2255,25 @@
     VarTemplatePartialSpecializationDecl *D) {
   RedeclarableResult Redecl = VisitVarTemplateSpecializationDeclImpl(D);
 
-  D->TemplateParams = Record.readTemplateParameterList();
+  TemplateParameterList *Params = Record.readTemplateParameterList();
+  D->TemplateParams.setPointer(Params);
   D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
 
   // These are read/set from/to the first declaration.
   if (ThisDeclID == Redecl.getFirstID()) {
     D->InstantiatedFromMember.setPointer(
         ReadDeclAs<VarTemplatePartialSpecializationDecl>());
     D->InstantiatedFromMember.setInt(Record.readInt());
+
+    bool HasAssociatedConstraints = Record.readInt();
+    D->TemplateParams.setInt(true);
+    if (HasAssociatedConstraints) {
+      Expr *AssociatedConstraints = Record.readExpr();
+      auto *CTDI = new (Reader.getContext()) ConstrainedTemplateDeclInfo;
+      CTDI->setTemplateParameters(Params);
+      CTDI->setAssociatedConstraints(AssociatedConstraints);
+      D->TemplateParams.setPointer(CTDI);
+    }
   }
 }
 
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -8664,10 +8664,13 @@
   Params.reserve(NumParams);
   while (NumParams--)
     Params.push_back(ReadDeclAs<NamedDecl>(F, Record, Idx));
+    // TODO: Concepts: Constrained parameters
+
+  bool HasRequiresClause = Record[Idx++];
+  Expr *RequiresClause = HasRequiresClause ? ReadExpr(F) : nullptr;
 
-  // TODO: Concepts
   TemplateParameterList *TemplateParams = TemplateParameterList::Create(
-      getContext(), TemplateLoc, LAngleLoc, Params, RAngleLoc, nullptr);
+      getContext(), TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause);
   return TemplateParams;
 }
 
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3138,14 +3138,19 @@
   if (Invalid)
     return nullptr;
 
-  // Note: we substitute into associated constraints later
-  Expr *const UninstantiatedRequiresClause = L->getRequiresClause();
+  Expr *InstRequiresClause = nullptr;
+  if (Expr *E = L->getRequiresClause()) {
+    ExprResult Res = SemaRef.SubstExpr(E, TemplateArgs);
+    if (!Res.isInvalid()) {
+      return nullptr;
+    }
+    InstRequiresClause = Res.get();
+  }
 
   TemplateParameterList *InstL
     = TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(),
                                     L->getLAngleLoc(), Params,
-                                    L->getRAngleLoc(),
-                                    UninstantiatedRequiresClause);
+                                    L->getRAngleLoc(), InstRequiresClause);
   return InstL;
 }
 
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -1408,15 +1408,10 @@
     AddMsStructLayoutForRecord(NewClass);
   }
 
-  // Attach the associated constraints when the declaration will not be part of
-  // a decl chain.
-  Expr *const ACtoAttach =
-      PrevClassTemplate && ShouldAddRedecl ? nullptr : CurAC;
-
   ClassTemplateDecl *NewTemplate
     = ClassTemplateDecl::Create(Context, SemanticContext, NameLoc,
                                 DeclarationName(Name), TemplateParams,
-                                NewClass, ACtoAttach);
+                                NewClass);
 
   if (ShouldAddRedecl)
     NewTemplate->setPreviousDecl(PrevClassTemplate);
Index: lib/AST/DeclTemplate.cpp
===================================================================
--- lib/AST/DeclTemplate.cpp
+++ lib/AST/DeclTemplate.cpp
@@ -146,6 +146,65 @@
 
 } // namespace clang
 
+static ConstrainedTemplateDeclInfo *
+collectAssociatedConstraints(ASTContext& C, TemplateParameterList *Params) {
+  // TODO: Instead of calling getRequiresClause - write and call a
+  // TemplateParameterList member function calculateAssociatedConstraints, which
+  // will also fetch constraint-expressions from constrained-parameters.
+  Expr *AssociatedConstraints = Params->getRequiresClause();
+  // TODO: Collect function requires clause, if any.
+  if (AssociatedConstraints) {
+    ConstrainedTemplateDeclInfo *CTDI = new (C) ConstrainedTemplateDeclInfo;
+    CTDI->setAssociatedConstraints(AssociatedConstraints);
+    CTDI->setTemplateParameters(Params);
+    return CTDI;
+  }
+  return nullptr;
+}
+
+// This function exists outside TemplateDecl because
+// '*TemplatePartialSpecializationDecls' need this code too, and are not derived
+// from the former.
+Expr *
+getOrCollectAssociatedConstraints(ASTContext& C,
+                                  llvm::PointerIntPair<
+                                    llvm::PointerUnion<TemplateParameterList *,
+                                                 ConstrainedTemplateDeclInfo *>,
+                                    1, bool>& TemplateParamsMember) {
+  if (!TemplateParamsMember.getInt()) {
+    TemplateParamsMember.setInt(true);
+    ConstrainedTemplateDeclInfo *CTDI =
+      collectAssociatedConstraints(C, TemplateParamsMember.getPointer()
+                                        .get<TemplateParameterList*>());
+    if (CTDI) {
+      TemplateParamsMember.setPointer(CTDI);
+      return CTDI->getAssociatedConstraints();
+    }
+    return nullptr;
+  }
+  const auto *const CTDI = TemplateParamsMember.getPointer()
+                             .dyn_cast<ConstrainedTemplateDeclInfo *>();
+  return CTDI ? CTDI->getAssociatedConstraints() : nullptr;
+}
+
+//===----------------------------------------------------------------------===//
+// TemplateDecl Implementation
+//===----------------------------------------------------------------------===//
+
+TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
+                           DeclarationName Name, TemplateParameterList *Params,
+                           NamedDecl *Decl)
+    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
+      TemplateParams(Params, false) {}
+
+
+Expr *TemplateDecl::getAssociatedConstraints() {
+  return getOrCollectAssociatedConstraints(getASTContext(),
+                        cast<TemplateDecl>(getCanonicalDecl())->TemplateParams);
+}
+
+void TemplateDecl::anchor() {}
+
 //===----------------------------------------------------------------------===//
 // RedeclarableTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
@@ -308,19 +367,10 @@
                                              SourceLocation L,
                                              DeclarationName Name,
                                              TemplateParameterList *Params,
-                                             NamedDecl *Decl,
-                                             Expr *AssociatedConstraints) {
+                                             NamedDecl *Decl) {
   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
 
-  if (!AssociatedConstraints) {
-    return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
-  }
-
-  ConstrainedTemplateDeclInfo *const CTDI = new (C) ConstrainedTemplateDeclInfo;
-  ClassTemplateDecl *const New =
-      new (C, DC) ClassTemplateDecl(CTDI, C, DC, L, Name, Params, Decl);
-  New->setAssociatedConstraints(AssociatedConstraints);
-  return New;
+  return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
 }
 
 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
@@ -680,12 +730,6 @@
                                                     POI);
 }
 
-//===----------------------------------------------------------------------===//
-// TemplateDecl Implementation
-//===----------------------------------------------------------------------===//
-
-void TemplateDecl::anchor() {}
-
 //===----------------------------------------------------------------------===//
 // ClassTemplateSpecializationDecl Implementation
 //===----------------------------------------------------------------------===//
@@ -838,8 +882,8 @@
                                       ClassTemplatePartialSpecialization,
                                       TK, DC, StartLoc, IdLoc,
                                       SpecializedTemplate, Args, PrevDecl),
-      TemplateParams(Params), ArgsAsWritten(ArgInfos),
-      InstantiatedFromMember(nullptr, false) {
+      TemplateParams(Params, false),
+      ArgsAsWritten(ArgInfos), InstantiatedFromMember(nullptr, false) {
   AdoptTemplateParameterList(Params, this);
 }
 
@@ -876,6 +920,12 @@
   return Result;
 }
 
+Expr* ClassTemplatePartialSpecializationDecl::getAssociatedConstraints() {
+  return getOrCollectAssociatedConstraints(getASTContext(),
+           cast<ClassTemplatePartialSpecializationDecl>(getCanonicalDecl())
+             ->TemplateParams);
+}
+
 //===----------------------------------------------------------------------===//
 // FriendTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
@@ -1131,7 +1181,7 @@
     : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
                                     TInfo, S, Args),
-      TemplateParams(Params), ArgsAsWritten(ArgInfos),
+      TemplateParams(Params, false), ArgsAsWritten(ArgInfos),
       InstantiatedFromMember(nullptr, false) {
   // TODO: The template parameters should be in DC by now. Verify.
   // AdoptTemplateParameterList(Params, DC);
@@ -1161,6 +1211,12 @@
   return new (C, ID) VarTemplatePartialSpecializationDecl(C);
 }
 
+Expr* VarTemplatePartialSpecializationDecl::getAssociatedConstraints() {
+  return getOrCollectAssociatedConstraints(getASTContext(),
+           cast<VarTemplatePartialSpecializationDecl>(getCanonicalDecl())
+             ->TemplateParams);
+}
+
 static TemplateParameterList *
 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
   // typename T
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -1594,9 +1594,11 @@
 bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
     TemplateParameterList *TPL) {
   if (TPL) {
-    for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
-         I != E; ++I) {
-      TRY_TO(TraverseDecl(*I));
+    for (NamedDecl *D : *TPL) {
+      TRY_TO(TraverseDecl(D));
+    }
+    if (Expr *RequiresClause = TPL->getRequiresClause()) {
+      TRY_TO(TraverseStmt(RequiresClause));
     }
   }
   return true;
Index: include/clang/AST/DeclTemplate.h
===================================================================
--- include/clang/AST/DeclTemplate.h
+++ include/clang/AST/DeclTemplate.h
@@ -368,8 +368,6 @@
 /// \brief Stores the template parameter list and associated constraints for
 /// \c TemplateDecl objects that track associated constraints.
 class ConstrainedTemplateDeclInfo {
-  friend TemplateDecl;
-
 public:
   ConstrainedTemplateDeclInfo() = default;
 
@@ -379,13 +377,14 @@
 
   Expr *getAssociatedConstraints() const { return AssociatedConstraints; }
 
-protected:
   void setTemplateParameters(TemplateParameterList *TParams) {
     TemplateParams = TParams;
   }
 
   void setAssociatedConstraints(Expr *AC) { AssociatedConstraints = AC; }
 
+protected:
+
   TemplateParameterList *TemplateParams = nullptr;
   Expr *AssociatedConstraints = nullptr;
 };
@@ -400,54 +399,33 @@
   void anchor() override;
 
 protected:
+  // Construct a template decl with name, parameters, and templated element.
+  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
+               TemplateParameterList *Params, NamedDecl *Decl);
+
   // Construct a template decl with the given name and parameters.
   // Used when there is no templated element (e.g., for tt-params).
-  TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
-               SourceLocation L, DeclarationName Name,
-               TemplateParameterList *Params)
-      : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
-        TemplateParams(CTDI) {
-    this->setTemplateParameters(Params);
-  }
-
   TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
                TemplateParameterList *Params)
-      : TemplateDecl(nullptr, DK, DC, L, Name, Params) {}
-
-  // Construct a template decl with name, parameters, and templated element.
-  TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
-               SourceLocation L, DeclarationName Name,
-               TemplateParameterList *Params, NamedDecl *Decl)
-      : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
-        TemplateParams(CTDI) {
-    this->setTemplateParameters(Params);
-  }
-
-  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
-               TemplateParameterList *Params, NamedDecl *Decl)
-      : TemplateDecl(nullptr, DK, DC, L, Name, Params, Decl) {}
+      : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
 
 public:
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+
   /// Get the list of template parameters
   TemplateParameterList *getTemplateParameters() const {
     const auto *const CTDI =
-        TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
+        TemplateParams.getPointer().dyn_cast<ConstrainedTemplateDeclInfo *>();
     return CTDI ? CTDI->getTemplateParameters()
-                : TemplateParams.get<TemplateParameterList *>();
-  }
-
-  /// Get the constraint-expression from the associated requires-clause (if any)
-  const Expr *getRequiresClause() const {
-    const TemplateParameterList *const TP = getTemplateParameters();
-    return TP ? TP->getRequiresClause() : nullptr;
+                : TemplateParams.getPointer().get<TemplateParameterList *>();
   }
 
-  Expr *getAssociatedConstraints() const {
-    const TemplateDecl *const C = cast<TemplateDecl>(getCanonicalDecl());
-    const auto *const CTDI =
-        C->TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
-    return CTDI ? CTDI->getAssociatedConstraints() : nullptr;
-  }
+  /// \brief Get the total constraint-expression associated with this template,
+  /// including constraint-expressions derived from the requires-clause,
+  /// trailing requires-clause (for functions and methods) and constrained
+  /// template parameters.
+  Expr *getAssociatedConstraints();
 
   /// Get the underlying, templated declaration.
   NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
@@ -466,38 +444,32 @@
 
 protected:
   NamedDecl *TemplatedDecl;
-  /// \brief The template parameter list and optional requires-clause
-  /// associated with this declaration; alternatively, a
-  /// \c ConstrainedTemplateDeclInfo if the associated constraints of the
-  /// template are being tracked by this particular declaration.
-  llvm::PointerUnion<TemplateParameterList *,
-                     ConstrainedTemplateDeclInfo *>
-      TemplateParams;
+  /// \brief If the int part is true, this declaration is the canonical
+  /// declaration, and the associated constraints for it have been calculated.
+  /// If any constraints were found, the pointer part will contain a
+  /// \c ConstrainedTemplateDeclInfo with the collected associated constraints.
+  /// Otherwise, this will just contain the template parameter list.
+  llvm::PointerIntPair<llvm::PointerUnion<TemplateParameterList *,
+                                          ConstrainedTemplateDeclInfo *>, 1,
+                       bool> TemplateParams;
 
   void setTemplateParameters(TemplateParameterList *TParams) {
-    if (auto *const CTDI =
-            TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>()) {
+    if (auto *const CTDI = TemplateParams.getPointer()
+                             .dyn_cast<ConstrainedTemplateDeclInfo *>()) {
       CTDI->setTemplateParameters(TParams);
     } else {
-      TemplateParams = TParams;
+      TemplateParams.setPointer(TParams);
     }
   }
 
-  void setAssociatedConstraints(Expr *AC) {
-    assert(isCanonicalDecl() &&
-           "Attaching associated constraints to non-canonical Decl");
-    TemplateParams.get<ConstrainedTemplateDeclInfo *>()
-        ->setAssociatedConstraints(AC);
-  }
-
 public:
   /// \brief Initialize the underlying templated declaration and
   /// template parameters.
   void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
     assert(!TemplatedDecl && "TemplatedDecl already set!");
     assert(!TemplateParams && "TemplateParams already set!");
     TemplatedDecl = templatedDecl;
-    TemplateParams = templateParams;
+    TemplateParams.setPointer(templateParams);
   }
 };
 
@@ -822,17 +794,10 @@
   virtual CommonBase *newCommon(ASTContext &C) const = 0;
 
   // Construct a template decl with name, parameters, and templated element.
-  RedeclarableTemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK,
-                           ASTContext &C, DeclContext *DC, SourceLocation L,
-                           DeclarationName Name, TemplateParameterList *Params,
-                           NamedDecl *Decl)
-      : TemplateDecl(CTDI, DK, DC, L, Name, Params, Decl), redeclarable_base(C)
-        {}
-
   RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
                            SourceLocation L, DeclarationName Name,
                            TemplateParameterList *Params, NamedDecl *Decl)
-      : RedeclarableTemplateDecl(nullptr, DK, C, DC, L, Name, Params, Decl) {}
+      : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
 
 public:
   friend class ASTDeclReader;
@@ -1897,8 +1862,14 @@
 
 class ClassTemplatePartialSpecializationDecl
   : public ClassTemplateSpecializationDecl {
-  /// \brief The list of template parameters
-  TemplateParameterList* TemplateParams = nullptr;
+  /// \brief If the int part is true, this declaration is the canonical
+  /// declaration, and the associated constraints for it have been calculated.
+  /// If any constraints were found, the pointer part will contain a
+  /// \c ConstrainedTemplateDeclInfo with the collected associated constraints.
+  /// Otherwise, this will just contain the template parameter list.
+  llvm::PointerIntPair<llvm::PointerUnion<TemplateParameterList *,
+                                          ConstrainedTemplateDeclInfo *>, 1,
+                       bool> TemplateParams;
 
   /// \brief The source info for the template arguments as written.
   /// FIXME: redundant with TypeAsWritten?
@@ -1953,9 +1924,18 @@
 
   /// Get the list of template parameters
   TemplateParameterList *getTemplateParameters() const {
-    return TemplateParams;
+    const auto *const CTDI =
+        TemplateParams.getPointer().dyn_cast<ConstrainedTemplateDeclInfo *>();
+    return CTDI ? CTDI->getTemplateParameters()
+                : TemplateParams.getPointer().get<TemplateParameterList *>();
   }
 
+  /// \brief Get the total constraint-expression associated with this template,
+  /// including constraint-expressions derived from the requires-clause,
+  /// trailing requires-clause (for functions and methods) and constrained
+  /// template parameters.
+  Expr *getAssociatedConstraints();
+
   /// Get the template arguments as written.
   const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
     return ArgsAsWritten;
@@ -2084,16 +2064,10 @@
   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
   getPartialSpecializations();
 
-  ClassTemplateDecl(ConstrainedTemplateDeclInfo *CTDI, ASTContext &C,
-                    DeclContext *DC, SourceLocation L, DeclarationName Name,
-                    TemplateParameterList *Params, NamedDecl *Decl)
-      : RedeclarableTemplateDecl(CTDI, ClassTemplate, C, DC, L, Name, Params,
-                                 Decl) {}
-
   ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
                     DeclarationName Name, TemplateParameterList *Params,
                     NamedDecl *Decl)
-      : ClassTemplateDecl(nullptr, C, DC, L, Name, Params, Decl) {}
+      : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
 
   CommonBase *newCommon(ASTContext &C) const override;
 
@@ -2125,8 +2099,7 @@
                                    SourceLocation L,
                                    DeclarationName Name,
                                    TemplateParameterList *Params,
-                                   NamedDecl *Decl,
-                                   Expr *AssociatedConstraints = nullptr);
+                                   NamedDecl *Decl);
 
   /// \brief Create an empty class template node.
   static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -2740,8 +2713,14 @@
 
 class VarTemplatePartialSpecializationDecl
     : public VarTemplateSpecializationDecl {
-  /// \brief The list of template parameters
-  TemplateParameterList *TemplateParams = nullptr;
+  /// \brief If the int part is true, this declaration is the canonical
+  /// declaration, and the associated constraints for it have been calculated.
+  /// If any constraints were found, the pointer part will contain a
+  /// \c ConstrainedTemplateDeclInfo with the collected associated constraints.
+  /// Otherwise, this will just contain the template parameter list.
+  llvm::PointerIntPair<llvm::PointerUnion<TemplateParameterList *,
+                                          ConstrainedTemplateDeclInfo *>, 1,
+                       bool> TemplateParams;
 
   /// \brief The source info for the template arguments as written.
   /// FIXME: redundant with TypeAsWritten?
@@ -2791,14 +2770,23 @@
 
   /// Get the list of template parameters
   TemplateParameterList *getTemplateParameters() const {
-    return TemplateParams;
+    const auto *const CTDI =
+        TemplateParams.getPointer().dyn_cast<ConstrainedTemplateDeclInfo *>();
+    return CTDI ? CTDI->getTemplateParameters()
+                : TemplateParams.getPointer().get<TemplateParameterList *>();
   }
 
   /// Get the template arguments as written.
   const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
     return ArgsAsWritten;
   }
 
+  /// \brief Get the total constraint-expression associated with this template,
+  /// including constraint-expressions derived from the requires-clause,
+  /// trailing requires-clause (for functions and methods) and constrained
+  /// template parameters.
+  Expr *getAssociatedConstraints();
+
   /// \brief Retrieve the member variable template partial specialization from
   /// which this particular variable template partial specialization was
   /// instantiated.
@@ -3037,11 +3025,9 @@
 protected:
   Expr *ConstraintExpr;
 
-  ConceptDecl(DeclContext *DC,
-              SourceLocation L, DeclarationName Name,
-              TemplateParameterList *Params,
-              Expr *ConstraintExpr)
-      : TemplateDecl(nullptr, Concept, DC, L, Name, Params),
+  ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
+              TemplateParameterList *Params, Expr *ConstraintExpr)
+      : TemplateDecl(Concept, DC, L, Name, Params),
         ConstraintExpr(ConstraintExpr) {};
 public:
   static ConceptDecl *Create(ASTContext &C, DeclContext *DC,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to