r303594 - [NFC, Refactor] Modernize TemplateIdAnnotation using TrailingObjects

Faisal Vali via cfe-commits cfe-commits at lists.llvm.org
Mon May 22 18:07:12 PDT 2017


Author: faisalv
Date: Mon May 22 20:07:12 2017
New Revision: 303594

URL: http://llvm.org/viewvc/llvm-project?rev=303594&view=rev
Log:
[NFC, Refactor] Modernize TemplateIdAnnotation using TrailingObjects

A refactoring of TemplateIdAnnotation that uses TrailingObjects to create a variably-sized object on the heap.

https://reviews.llvm.org/D31414

Thanks to Aaron B for the review!


Modified:
    cfe/trunk/include/clang/Basic/TemplateKinds.h
    cfe/trunk/include/clang/Sema/ParsedTemplate.h
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp

Modified: cfe/trunk/include/clang/Basic/TemplateKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TemplateKinds.h?rev=303594&r1=303593&r2=303594&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TemplateKinds.h (original)
+++ cfe/trunk/include/clang/Basic/TemplateKinds.h Mon May 22 20:07:12 2017
@@ -26,13 +26,21 @@ enum TemplateNameKind {
   TNK_Function_template,
   /// The name refers to a template whose specialization produces a
   /// type. The template itself could be a class template, template
-  /// template parameter, or C++0x template alias.
+  /// template parameter, or template alias.
   TNK_Type_template,
   /// The name refers to a variable template whose specialization produces a
   /// variable.
   TNK_Var_template,
-  /// The name refers to a dependent template name. Whether the
-  /// template name is assumed to refer to a type template or a
+  /// The name refers to a dependent template name: 
+  /// \code
+  /// template<typename MetaFun, typename T1, typename T2> struct apply2 {
+  ///   typedef typename MetaFun::template apply<T1, T2>::type type;
+  /// };
+  /// \endcode
+  ///
+  /// Here, "apply" is a dependent template name within the typename
+  /// specifier in the typedef. "apply" is a nested template, and 
+  /// whether the template name is assumed to refer to a type template or a
   /// function template depends on the context in which the template
   /// name occurs.
   TNK_Dependent_template_name

Modified: cfe/trunk/include/clang/Sema/ParsedTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ParsedTemplate.h?rev=303594&r1=303593&r2=303594&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ParsedTemplate.h (original)
+++ cfe/trunk/include/clang/Sema/ParsedTemplate.h Mon May 22 20:07:12 2017
@@ -145,12 +145,15 @@ namespace clang {
   /// expressions, or template names, and the source locations for important 
   /// tokens. All of the information about template arguments is allocated 
   /// directly after this structure.
-  struct TemplateIdAnnotation {
+  struct TemplateIdAnnotation final
+      : private llvm::TrailingObjects<TemplateIdAnnotation,
+                                      ParsedTemplateArgument> {
+    friend TrailingObjects;
     /// \brief The nested-name-specifier that precedes the template name.
     CXXScopeSpec SS;
 
-    /// TemplateKWLoc - The location of the template keyword within the
-    /// source.
+    /// TemplateKWLoc - The location of the template keyword.
+    /// For e.g. typename T::template Y<U>
     SourceLocation TemplateKWLoc;
 
     /// TemplateNameLoc - The location of the template name within the
@@ -183,34 +186,56 @@ namespace clang {
     
     /// \brief Retrieves a pointer to the template arguments
     ParsedTemplateArgument *getTemplateArgs() { 
-      return reinterpret_cast<ParsedTemplateArgument *>(this + 1); 
+      return getTrailingObjects<ParsedTemplateArgument>(); 
     }
 
     /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
     /// appends it to List.
     static TemplateIdAnnotation *
-    Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) {
-      TemplateIdAnnotation *TemplateId
-        = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
-                                      sizeof(ParsedTemplateArgument) * NumArgs);
-      TemplateId->NumArgs = NumArgs;
-      
-      // Default-construct nested-name-specifier.
-      new (&TemplateId->SS) CXXScopeSpec();
-      
-      // Default-construct parsed template arguments.
-      ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs();
-      for (unsigned I = 0; I != NumArgs; ++I)
-        new (TemplateArgs + I) ParsedTemplateArgument();
-      
-      List.push_back(TemplateId);
+    Create(CXXScopeSpec SS, SourceLocation TemplateKWLoc,
+           SourceLocation TemplateNameLoc, IdentifierInfo *Name,
+           OverloadedOperatorKind OperatorKind,
+           ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
+           SourceLocation LAngleLoc, SourceLocation RAngleLoc,
+           ArrayRef<ParsedTemplateArgument> TemplateArgs,
+           SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) {
+
+      TemplateIdAnnotation *TemplateId = new (std::malloc(
+          totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
+          TemplateIdAnnotation(SS, TemplateKWLoc, TemplateNameLoc, Name,
+                               OperatorKind, OpaqueTemplateName, TemplateKind,
+                               LAngleLoc, RAngleLoc, TemplateArgs);
+      CleanupList.push_back(TemplateId);
       return TemplateId;
     }
-    
-    void Destroy() { 
-      SS.~CXXScopeSpec();
+
+    void Destroy() {
+      std::for_each(
+          getTemplateArgs(), getTemplateArgs() + NumArgs,
+          [](ParsedTemplateArgument &A) { A.~ParsedTemplateArgument(); });
+      this->~TemplateIdAnnotation();
       free(this); 
     }
+  private:
+    TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
+
+    TemplateIdAnnotation(CXXScopeSpec SS, SourceLocation TemplateKWLoc,
+                         SourceLocation TemplateNameLoc, IdentifierInfo *Name,
+                         OverloadedOperatorKind OperatorKind,
+                         ParsedTemplateTy OpaqueTemplateName,
+                         TemplateNameKind TemplateKind,
+                         SourceLocation LAngleLoc, SourceLocation RAngleLoc,
+                         ArrayRef<ParsedTemplateArgument> TemplateArgs) noexcept
+        : SS(SS), TemplateKWLoc(TemplateKWLoc),
+          TemplateNameLoc(TemplateNameLoc), Name(Name), Operator(OperatorKind),
+          Template(OpaqueTemplateName), Kind(TemplateKind),
+          LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
+          NumArgs(TemplateArgs.size()) {
+
+      std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
+                              getTemplateArgs());
+    }
+    ~TemplateIdAnnotation() = default;
   };
 
   /// Retrieves the range of the given template parameter lists.

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=303594&r1=303593&r2=303594&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon May 22 20:07:12 2017
@@ -2120,31 +2120,18 @@ bool Parser::ParseUnqualifiedIdTemplateI
       Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) {
     // Form a parsed representation of the template-id to be stored in the
     // UnqualifiedId.
-    TemplateIdAnnotation *TemplateId
-      = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
 
     // FIXME: Store name for literal operator too.
-    if (Id.getKind() == UnqualifiedId::IK_Identifier) {
-      TemplateId->Name = Id.Identifier;
-      TemplateId->Operator = OO_None;
-      TemplateId->TemplateNameLoc = Id.StartLocation;
-    } else {
-      TemplateId->Name = nullptr;
-      TemplateId->Operator = Id.OperatorFunctionId.Operator;
-      TemplateId->TemplateNameLoc = Id.StartLocation;
-    }
+    IdentifierInfo *TemplateII =
+        Id.getKind() == UnqualifiedId::IK_Identifier ? Id.Identifier : nullptr;
+    OverloadedOperatorKind OpKind = Id.getKind() == UnqualifiedId::IK_Identifier
+                                        ? OO_None
+                                        : Id.OperatorFunctionId.Operator;
+
+    TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
+        SS, TemplateKWLoc, Id.StartLocation, TemplateII, OpKind, Template, TNK,
+        LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds);
 
-    TemplateId->SS = SS;
-    TemplateId->TemplateKWLoc = TemplateKWLoc;
-    TemplateId->Template = Template;
-    TemplateId->Kind = TNK;
-    TemplateId->LAngleLoc = LAngleLoc;
-    TemplateId->RAngleLoc = RAngleLoc;
-    ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
-    for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); 
-         Arg != ArgEnd; ++Arg)
-      Args[Arg] = TemplateArgs[Arg];
-    
     Id.setTemplateId(TemplateId);
     return false;
   }

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=303594&r1=303593&r2=303594&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Mon May 22 20:07:12 2017
@@ -1011,25 +1011,21 @@ bool Parser::AnnotateTemplateIdToken(Tem
     // Build a template-id annotation token that can be processed
     // later.
     Tok.setKind(tok::annot_template_id);
-    TemplateIdAnnotation *TemplateId
-      = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
-    TemplateId->TemplateNameLoc = TemplateNameLoc;
-    if (TemplateName.getKind() == UnqualifiedId::IK_Identifier) {
-      TemplateId->Name = TemplateName.Identifier;
-      TemplateId->Operator = OO_None;
-    } else {
-      TemplateId->Name = nullptr;
-      TemplateId->Operator = TemplateName.OperatorFunctionId.Operator;
-    }
-    TemplateId->SS = SS;
-    TemplateId->TemplateKWLoc = TemplateKWLoc;
-    TemplateId->Template = Template;
-    TemplateId->Kind = TNK;
-    TemplateId->LAngleLoc = LAngleLoc;
-    TemplateId->RAngleLoc = RAngleLoc;
-    ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
-    for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
-      Args[Arg] = ParsedTemplateArgument(TemplateArgs[Arg]);
+    
+    IdentifierInfo *TemplateII =
+        TemplateName.getKind() == UnqualifiedId::IK_Identifier
+            ? TemplateName.Identifier
+            : nullptr;
+
+    OverloadedOperatorKind OpKind =
+        TemplateName.getKind() == UnqualifiedId::IK_Identifier
+            ? OO_None
+            : TemplateName.OperatorFunctionId.Operator;
+
+    TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
+      SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
+      LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds);
+    
     Tok.setAnnotationValue(TemplateId);
     if (TemplateKWLoc.isValid())
       Tok.setLocation(TemplateKWLoc);




More information about the cfe-commits mailing list