From 43caf6785f5bdafa11de2dbc520f2eb859282506 Mon Sep 17 00:00:00 2001 From: Faisal Vali Date: Tue, 23 May 2017 01:07:12 +0000 Subject: [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! llvm-svn: 303594 --- clang/include/clang/Basic/TemplateKinds.h | 14 +++++-- clang/include/clang/Sema/ParsedTemplate.h | 69 +++++++++++++++++++++---------- clang/lib/Parse/ParseExprCXX.cpp | 31 ++++---------- clang/lib/Parse/ParseTemplate.cpp | 34 +++++++-------- 4 files changed, 82 insertions(+), 66 deletions(-) diff --git a/clang/include/clang/Basic/TemplateKinds.h b/clang/include/clang/Basic/TemplateKinds.h index aed287b4622..ac99ad185f3 100644 --- a/clang/include/clang/Basic/TemplateKinds.h +++ b/clang/include/clang/Basic/TemplateKinds.h @@ -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 struct apply2 { + /// typedef typename MetaFun::template apply::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 diff --git a/clang/include/clang/Sema/ParsedTemplate.h b/clang/include/clang/Sema/ParsedTemplate.h index 03de9ff6ae4..01a4ab3f37a 100644 --- a/clang/include/clang/Sema/ParsedTemplate.h +++ b/clang/include/clang/Sema/ParsedTemplate.h @@ -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 { + 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 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(this + 1); + return getTrailingObjects(); } /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and /// appends it to List. static TemplateIdAnnotation * - Allocate(unsigned NumArgs, SmallVectorImpl &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 TemplateArgs, + SmallVectorImpl &CleanupList) { + + TemplateIdAnnotation *TemplateId = new (std::malloc( + totalSizeToAlloc(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 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. diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 0b210e0360a..dcafbadae5c 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -2120,31 +2120,18 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, 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; } diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index a919d870810..37c80fe5e52 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -1011,25 +1011,21 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, // 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); -- cgit v1.2.1