hubert.reinterpretcast updated this revision to Diff 54456.
hubert.reinterpretcast added a comment.

Actually add parens this time


http://reviews.llvm.org/D19322

Files:
  include/clang/AST/DeclTemplate.h
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp

Index: lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- lib/Sema/SemaTemplateDeduction.cpp
+++ lib/Sema/SemaTemplateDeduction.cpp
@@ -4034,8 +4034,8 @@
                                  nullptr, false, false);
   QualType TemplArg = QualType(TemplParam->getTypeForDecl(), 0);
   NamedDecl *TemplParamPtr = TemplParam;
-  FixedSizeTemplateParameterListStorage<1> TemplateParamsSt(
-      Loc, Loc, TemplParamPtr, Loc);
+  FixedSizeTemplateParameterListStorage<1, false> TemplateParamsSt(
+      Loc, Loc, TemplParamPtr, Loc, nullptr);
 
   QualType FuncParam = SubstituteAutoTransform(*this, TemplArg).Apply(Type);
   assert(!FuncParam.isNull() &&
Index: lib/AST/DeclTemplate.cpp
===================================================================
--- lib/AST/DeclTemplate.cpp
+++ lib/AST/DeclTemplate.cpp
@@ -31,9 +31,11 @@
 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
                                              SourceLocation LAngleLoc,
                                              ArrayRef<NamedDecl *> Params,
-                                             SourceLocation RAngleLoc)
+                                             SourceLocation RAngleLoc,
+                                             Expr *RequiresClause)
   : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
-    NumParams(Params.size()), ContainsUnexpandedParameterPack(false) {
+    NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
+    HasRequiresClause(static_cast<bool>(RequiresClause)) {
   assert(this->NumParams == NumParams && "Too many template parameters");
   for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
     NamedDecl *P = Params[Idx];
@@ -52,15 +54,21 @@
       // template parameter list does too.
     }
   }
+  if (RequiresClause) {
+    *getTrailingObjects<Expr *>() = RequiresClause;
+  }
 }
 
-TemplateParameterList *TemplateParameterList::Create(
-    const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc,
-    ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc) {
-  void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *>(Params.size()),
+TemplateParameterList *
+TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
+                              SourceLocation LAngleLoc,
+                              ArrayRef<NamedDecl *> Params,
+                              SourceLocation RAngleLoc, Expr *RequiresClause) {
+  void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
+                             Params.size(), RequiresClause ? 1u : 0u),
                          llvm::alignOf<TemplateParameterList>());
   return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
-                                         RAngleLoc);
+                                         RAngleLoc, RequiresClause);
 }
 
 unsigned TemplateParameterList::getMinRequiredArguments() const {
Index: include/clang/AST/DeclTemplate.h
===================================================================
--- include/clang/AST/DeclTemplate.h
+++ include/clang/AST/DeclTemplate.h
@@ -46,7 +46,8 @@
 /// \brief Stores a list of template parameters for a TemplateDecl and its
 /// derived classes.
 class TemplateParameterList final
-    : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *> {
+    : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
+                                    Expr *> {
 
   /// The location of the 'template' keyword.
   SourceLocation TemplateLoc;
@@ -56,26 +57,36 @@
 
   /// The number of template parameters in this template
   /// parameter list.
-  unsigned NumParams : 31;
+  unsigned NumParams : 30;
 
   /// Whether this template parameter list contains an unexpanded parameter
   /// pack.
   unsigned ContainsUnexpandedParameterPack : 1;
 
+  /// Whether this template parameter list has an associated requires-clause
+  unsigned HasRequiresClause : 1;
+
 protected:
   size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
     return NumParams;
   }
 
+  size_t numTrailingObjects(OverloadToken<Expr *>) const {
+    return HasRequiresClause;
+  }
+
   TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
-                        ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc);
+                        ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc,
+                        Expr *RequiresClause);
 
 public:
+  // FIXME: remove default argument for RequiresClause
   static TemplateParameterList *Create(const ASTContext &C,
                                        SourceLocation TemplateLoc,
                                        SourceLocation LAngleLoc,
                                        ArrayRef<NamedDecl *> Params,
-                                       SourceLocation RAngleLoc);
+                                       SourceLocation RAngleLoc,
+                                       Expr *RequiresClause = nullptr);
 
   /// \brief Iterates through the template parameters in this list.
   typedef NamedDecl** iterator;
@@ -127,6 +138,11 @@
     return ContainsUnexpandedParameterPack;
   }
 
+  /// \brief The constraint-expression of the associated requires-clause.
+  const Expr *getRequiresClause() const {
+    return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr;
+  }
+
   SourceLocation getTemplateLoc() const { return TemplateLoc; }
   SourceLocation getLAngleLoc() const { return LAngleLoc; }
   SourceLocation getRAngleLoc() const { return RAngleLoc; }
@@ -136,34 +152,50 @@
   }
 
   friend TrailingObjects;
-  template <size_t N> friend class FixedSizeTemplateParameterListStorage;
+
+  template <size_t N, bool HasRequiresClause>
+  friend class FixedSizeTemplateParameterListStorage;
 };
 
-/// \brief Stores a list of template parameters for a TemplateDecl and its
-/// derived classes. Suitable for creating on the stack.
-template <size_t N> class FixedSizeTemplateParameterListStorage {
+/// \brief Stores a list of template parameters and the associated
+/// requires-clause (if any) for a TemplateDecl and its derived classes.
+/// Suitable for creating on the stack.
+template <size_t N, bool HasRequiresClause>
+class FixedSizeTemplateParameterListStorage {
   // This is kinda ugly: TemplateParameterList usually gets allocated
   // in a block of memory with NamedDecls appended to it. Here, to get
-  // it stack allocated, we include the params as a separate
-  // variable. After allocation, the TemplateParameterList object
-  // treats them as part of itself.
+  // it stack allocated, we include the constraint-expression from the
+  // requires-clause and the params as separate variables.
+  // After allocation, the TemplateParameterList object treats them as
+  // part of itself.
+  // TODO: RequiresClause does not always need to be allocated
   TemplateParameterList List;
   NamedDecl *Params[N];
+  Expr *RequiresClause;
 
 public:
   FixedSizeTemplateParameterListStorage(SourceLocation TemplateLoc,
                                         SourceLocation LAngleLoc,
                                         ArrayRef<NamedDecl *> Params,
-                                        SourceLocation RAngleLoc)
-      : List(TemplateLoc, LAngleLoc, Params, RAngleLoc) {
+                                        SourceLocation RAngleLoc,
+                                        Expr *RequiresClause)
+      : List(TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause) {
+
+    assert(N == Params.size());
+    assert(HasRequiresClause == static_cast<bool>(RequiresClause));
+
     // Because we're doing an evil layout hack above, have some
     // asserts, just to double-check everything is laid out like
     // expected.
-    assert(sizeof(*this) ==
-               TemplateParameterList::totalSizeToAlloc<NamedDecl *>(N) &&
-           "Object layout not as expected");
+    assert((sizeof(*this) ==
+                TemplateParameterList::totalSizeToAlloc<NamedDecl *, Expr *>(
+                    N, 1) &&
+            "Object layout not as expected"));
     assert(this->Params == List.getTrailingObjects<NamedDecl *>() &&
            "Object layout not as expected");
+    assert(!HasRequiresClause ||
+           (&this->RequiresClause == List.getTrailingObjects<Expr *>() &&
+            "Object layout not as expected"));
   }
   TemplateParameterList *get() { return &List; }
 };
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to