From e7d82283cd59e334aea02140dacd7c3d518b48bf Mon Sep 17 00:00:00 2001 From: James Y Knight Date: Tue, 29 Dec 2015 18:15:14 +0000 Subject: [PATCH] [TrailingObjects] Convert AST classes that had a ASTTemplateKWAndArgsInfo. So, also: - Moved the TemplateArgumentLoc array out of the ASTTemplateKWAndArgsInfo class (making it a simple fixed-size object), to avoid needing to have a variable-length object as part of a variable-length object. Now the objects that have a ASTTemplateKWAndArgsInfo also have some TemplateArgumentLoc objects appended directly. - Removed some internal-use accessors which became simply a wrapper on getTrailingObjects. - Moved MemberNameQualifier out of the MemberExpr class, renamed it MemberExprNameQualifier, because the template can't refer to a class nested within the class it's defining. llvm-svn: 256570 --- clang/include/clang/AST/Expr.h | 191 ++++++++------------ clang/include/clang/AST/ExprCXX.h | 136 +++++++++------ clang/include/clang/AST/TemplateBase.h | 43 ++--- clang/lib/AST/Expr.cpp | 80 ++++----- clang/lib/AST/ExprCXX.cpp | 202 +++++++++------------- clang/lib/AST/TemplateBase.cpp | 22 +-- clang/lib/Serialization/ASTReaderStmt.cpp | 36 ++-- clang/lib/Serialization/ASTWriterStmt.cpp | 43 +++-- 8 files changed, 337 insertions(+), 416 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 2a67303c6a50..d19d22ca04b4 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -919,7 +919,11 @@ public: /// DeclRefExprBits.RefersToEnclosingVariableOrCapture /// Specifies when this declaration reference expression (validly) /// refers to an enclosed local or a captured variable. -class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DeclRefExpr : public Expr { +class DeclRefExpr final + : public Expr, + private llvm::TrailingObjects { /// \brief The declaration that we are referencing. ValueDecl *D; @@ -930,36 +934,22 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DeclRefExpr : public Expr { /// embedded in D. DeclarationNameLoc DNLoc; - /// \brief Helper to retrieve the optional NestedNameSpecifierLoc. - NestedNameSpecifierLoc &getInternalQualifierLoc() { - assert(hasQualifier()); - return *reinterpret_cast(this + 1); + size_t numTrailingObjects(OverloadToken) const { + return hasQualifier() ? 1 : 0; } - /// \brief Helper to retrieve the optional NestedNameSpecifierLoc. - const NestedNameSpecifierLoc &getInternalQualifierLoc() const { - return const_cast(this)->getInternalQualifierLoc(); + size_t numTrailingObjects(OverloadToken) const { + return hasFoundDecl() ? 1 : 0; + } + + size_t numTrailingObjects(OverloadToken) const { + return hasTemplateKWAndArgsInfo() ? 1 : 0; } /// \brief Test whether there is a distinct FoundDecl attached to the end of /// this DRE. bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; } - /// \brief Helper to retrieve the optional NamedDecl through which this - /// reference occurred. - NamedDecl *&getInternalFoundDecl() { - assert(hasFoundDecl()); - if (hasQualifier()) - return *reinterpret_cast(&getInternalQualifierLoc() + 1); - return *reinterpret_cast(this + 1); - } - - /// \brief Helper to retrieve the optional NamedDecl through which this - /// reference occurred. - NamedDecl *getInternalFoundDecl() const { - return const_cast(this)->getInternalFoundDecl(); - } - DeclRefExpr(const ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, @@ -1031,22 +1021,18 @@ public: /// C++ nested-name-specifier, e.g., \c N::foo. bool hasQualifier() const { return DeclRefExprBits.HasQualifier; } - /// \brief If the name was qualified, retrieves the nested-name-specifier - /// that precedes the name. Otherwise, returns NULL. - NestedNameSpecifier *getQualifier() const { - if (!hasQualifier()) - return nullptr; - - return getInternalQualifierLoc().getNestedNameSpecifier(); - } - /// \brief If the name was qualified, retrieves the nested-name-specifier /// that precedes the name, with source-location information. NestedNameSpecifierLoc getQualifierLoc() const { if (!hasQualifier()) return NestedNameSpecifierLoc(); + return *getTrailingObjects(); + } - return getInternalQualifierLoc(); + /// \brief If the name was qualified, retrieves the nested-name-specifier + /// that precedes the name. Otherwise, returns NULL. + NestedNameSpecifier *getQualifier() const { + return getQualifierLoc().getNestedNameSpecifier(); } /// \brief Get the NamedDecl through which this reference occurred. @@ -1054,64 +1040,40 @@ public: /// This Decl may be different from the ValueDecl actually referred to in the /// presence of using declarations, etc. It always returns non-NULL, and may /// simple return the ValueDecl when appropriate. + NamedDecl *getFoundDecl() { - return hasFoundDecl() ? getInternalFoundDecl() : D; + return hasFoundDecl() ? *getTrailingObjects() : D; } /// \brief Get the NamedDecl through which this reference occurred. /// See non-const variant. const NamedDecl *getFoundDecl() const { - return hasFoundDecl() ? getInternalFoundDecl() : D; + return hasFoundDecl() ? *getTrailingObjects() : D; } bool hasTemplateKWAndArgsInfo() const { return DeclRefExprBits.HasTemplateKWAndArgsInfo; } - /// \brief Return the optional template keyword and arguments info. - ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { - if (!hasTemplateKWAndArgsInfo()) - return nullptr; - - if (hasFoundDecl()) { - return reinterpret_cast( - llvm::alignAddr(&getInternalFoundDecl() + 1, - llvm::alignOf())); - } - - if (hasQualifier()) { - return reinterpret_cast( - llvm::alignAddr(&getInternalQualifierLoc() + 1, - llvm::alignOf())); - } - - return reinterpret_cast(this + 1); - } - - /// \brief Return the optional template keyword and arguments info. - const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { - return const_cast(this)->getTemplateKWAndArgsInfo(); - } - /// \brief Retrieve the location of the template keyword preceding /// this name, if any. SourceLocation getTemplateKeywordLoc() const { if (!hasTemplateKWAndArgsInfo()) return SourceLocation(); - return getTemplateKWAndArgsInfo()->TemplateKWLoc; + return getTrailingObjects()->TemplateKWLoc; } /// \brief Retrieve the location of the left angle bracket starting the /// explicit template argument list following the name, if any. SourceLocation getLAngleLoc() const { if (!hasTemplateKWAndArgsInfo()) return SourceLocation(); - return getTemplateKWAndArgsInfo()->LAngleLoc; + return getTrailingObjects()->LAngleLoc; } /// \brief Retrieve the location of the right angle bracket ending the /// explicit template argument list following the name, if any. SourceLocation getRAngleLoc() const { if (!hasTemplateKWAndArgsInfo()) return SourceLocation(); - return getTemplateKWAndArgsInfo()->RAngleLoc; + return getTrailingObjects()->RAngleLoc; } /// \brief Determines whether the name in this declaration reference @@ -1126,7 +1088,8 @@ public: /// structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { if (hasExplicitTemplateArgs()) - getTemplateKWAndArgsInfo()->copyInto(List); + getTrailingObjects()->copyInto( + getTrailingObjects(), List); } /// \brief Retrieve the template arguments provided as part of this @@ -1135,7 +1098,7 @@ public: if (!hasExplicitTemplateArgs()) return nullptr; - return getTemplateKWAndArgsInfo()->getTemplateArgs(); + return getTrailingObjects(); } /// \brief Retrieve the number of template arguments provided as part of this @@ -1144,7 +1107,7 @@ public: if (!hasExplicitTemplateArgs()) return 0; - return getTemplateKWAndArgsInfo()->NumTemplateArgs; + return getTrailingObjects()->NumTemplateArgs; } /// \brief Returns true if this expression refers to a function that @@ -1174,6 +1137,7 @@ public: return child_range(child_iterator(), child_iterator()); } + friend TrailingObjects; friend class ASTStmtReader; friend class ASTStmtWriter; }; @@ -2314,20 +2278,24 @@ public: } }; +/// Extra data stored in some MemberExpr objects. +struct MemberExprNameQualifier { + /// \brief The nested-name-specifier that qualifies the name, including + /// source-location information. + NestedNameSpecifierLoc QualifierLoc; + + /// \brief The DeclAccessPair through which the MemberDecl was found due to + /// name qualifiers. + DeclAccessPair FoundDecl; +}; + /// MemberExpr - [C99 6.5.2.3] Structure and Union Members. X->F and X.F. /// -class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) MemberExpr : public Expr { - /// Extra data stored in some member expressions. - struct LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) MemberNameQualifier { - /// \brief The nested-name-specifier that qualifies the name, including - /// source-location information. - NestedNameSpecifierLoc QualifierLoc; - - /// \brief The DeclAccessPair through which the MemberDecl was found due to - /// name qualifiers. - DeclAccessPair FoundDecl; - }; - +class MemberExpr final + : public Expr, + private llvm::TrailingObjects { /// Base - the expression for the base pointer or structure references. In /// X.F, this is "X". Stmt *Base; @@ -2351,7 +2319,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) MemberExpr : public Expr { /// \brief True if this member expression used a nested-name-specifier to /// refer to the member, e.g., "x->Base::f", or found its member via a using - /// declaration. When true, a MemberNameQualifier + /// declaration. When true, a MemberExprNameQualifier /// structure is allocated immediately after the MemberExpr. bool HasQualifierOrFoundDecl : 1; @@ -2359,24 +2327,19 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) MemberExpr : public Expr { /// and/or a template argument list explicitly, e.g., x->f, /// x->template f, x->template f. /// When true, an ASTTemplateKWAndArgsInfo structure and its - /// TemplateArguments (if any) are allocated immediately after - /// the MemberExpr or, if the member expression also has a qualifier, - /// after the MemberNameQualifier structure. + /// TemplateArguments (if any) are present. bool HasTemplateKWAndArgsInfo : 1; /// \brief True if this member expression refers to a method that /// was resolved from an overloaded set having size greater than 1. bool HadMultipleCandidates : 1; - /// \brief Retrieve the qualifier that preceded the member name, if any. - MemberNameQualifier *getMemberQualifier() { - assert(HasQualifierOrFoundDecl); - return reinterpret_cast (this + 1); + size_t numTrailingObjects(OverloadToken) const { + return HasQualifierOrFoundDecl ? 1 : 0; } - /// \brief Retrieve the qualifier that preceded the member name, if any. - const MemberNameQualifier *getMemberQualifier() const { - return const_cast(this)->getMemberQualifier(); + size_t numTrailingObjects(OverloadToken) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; } public: @@ -2432,7 +2395,7 @@ public: if (!HasQualifierOrFoundDecl) return DeclAccessPair::make(getMemberDecl(), getMemberDecl()->getAccess()); - return getMemberQualifier()->FoundDecl; + return getTrailingObjects()->FoundDecl; } /// \brief Determines whether this member expression actually had @@ -2440,62 +2403,42 @@ public: /// x->Base::foo. bool hasQualifier() const { return getQualifier() != nullptr; } - /// \brief If the member name was qualified, retrieves the - /// nested-name-specifier that precedes the member name. Otherwise, returns - /// NULL. - NestedNameSpecifier *getQualifier() const { - if (!HasQualifierOrFoundDecl) - return nullptr; - - return getMemberQualifier()->QualifierLoc.getNestedNameSpecifier(); - } - /// \brief If the member name was qualified, retrieves the /// nested-name-specifier that precedes the member name, with source-location /// information. NestedNameSpecifierLoc getQualifierLoc() const { - if (!hasQualifier()) + if (!HasQualifierOrFoundDecl) return NestedNameSpecifierLoc(); - return getMemberQualifier()->QualifierLoc; + return getTrailingObjects()->QualifierLoc; } - /// \brief Return the optional template keyword and arguments info. - ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { - if (!HasTemplateKWAndArgsInfo) - return nullptr; - - if (!HasQualifierOrFoundDecl) - return reinterpret_cast(this + 1); - - return reinterpret_cast( - getMemberQualifier() + 1); - } - - /// \brief Return the optional template keyword and arguments info. - const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { - return const_cast(this)->getTemplateKWAndArgsInfo(); + /// \brief If the member name was qualified, retrieves the + /// nested-name-specifier that precedes the member name. Otherwise, returns + /// NULL. + NestedNameSpecifier *getQualifier() const { + return getQualifierLoc().getNestedNameSpecifier(); } /// \brief Retrieve the location of the template keyword preceding /// the member name, if any. SourceLocation getTemplateKeywordLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->TemplateKWLoc; + return getTrailingObjects()->TemplateKWLoc; } /// \brief Retrieve the location of the left angle bracket starting the /// explicit template argument list following the member name, if any. SourceLocation getLAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->LAngleLoc; + return getTrailingObjects()->LAngleLoc; } /// \brief Retrieve the location of the right angle bracket ending the /// explicit template argument list following the member name, if any. SourceLocation getRAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->RAngleLoc; + return getTrailingObjects()->RAngleLoc; } /// Determines whether the member name was preceded by the template keyword. @@ -2509,7 +2452,8 @@ public: /// structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { if (hasExplicitTemplateArgs()) - getTemplateKWAndArgsInfo()->copyInto(List); + getTrailingObjects()->copyInto( + getTrailingObjects(), List); } /// \brief Retrieve the template arguments provided as part of this @@ -2518,7 +2462,7 @@ public: if (!hasExplicitTemplateArgs()) return nullptr; - return getTemplateKWAndArgsInfo()->getTemplateArgs(); + return getTrailingObjects(); } /// \brief Retrieve the number of template arguments provided as part of this @@ -2527,7 +2471,7 @@ public: if (!hasExplicitTemplateArgs()) return 0; - return getTemplateKWAndArgsInfo()->NumTemplateArgs; + return getTrailingObjects()->NumTemplateArgs; } /// \brief Retrieve the member declaration name info. @@ -2583,6 +2527,7 @@ public: // Iterators child_range children() { return child_range(&Base, &Base+1); } + friend TrailingObjects; friend class ASTReader; friend class ASTStmtWriter; }; diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 4be4aac6806d..fcdbd201f3c7 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -2428,7 +2428,7 @@ public: /// \brief A reference to an overloaded function set, either an /// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr. -class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) OverloadExpr : public Expr { +class OverloadExpr : public Expr { /// \brief The common name of these declarations. DeclarationNameInfo NameInfo; @@ -2448,13 +2448,18 @@ protected: bool HasTemplateKWAndArgsInfo; /// \brief Return the optional template keyword and arguments info. - ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo(); // defined far below. + ASTTemplateKWAndArgsInfo * + getTrailingASTTemplateKWAndArgsInfo(); // defined far below. /// \brief Return the optional template keyword and arguments info. - const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { - return const_cast(this)->getTemplateKWAndArgsInfo(); + const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const { + return const_cast(this) + ->getTrailingASTTemplateKWAndArgsInfo(); } + /// Return the optional template arguments. + TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below + OverloadExpr(StmtClass K, const ASTContext &C, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, @@ -2545,21 +2550,21 @@ public: /// this name, if any. SourceLocation getTemplateKeywordLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->TemplateKWLoc; + return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc; } /// \brief Retrieve the location of the left angle bracket starting the /// explicit template argument list following the name, if any. SourceLocation getLAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->LAngleLoc; + return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc; } /// \brief Retrieve the location of the right angle bracket ending the /// explicit template argument list following the name, if any. SourceLocation getRAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->RAngleLoc; + return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc; } /// \brief Determines whether the name was preceded by the template keyword. @@ -2571,21 +2576,20 @@ public: TemplateArgumentLoc const *getTemplateArgs() const { if (!hasExplicitTemplateArgs()) return nullptr; - - return getTemplateKWAndArgsInfo()->getTemplateArgs(); + return const_cast(this)->getTrailingTemplateArgumentLoc(); } unsigned getNumTemplateArgs() const { if (!hasExplicitTemplateArgs()) return 0; - return getTemplateKWAndArgsInfo()->NumTemplateArgs; + return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs; } /// \brief Copies the template arguments into the given structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { if (hasExplicitTemplateArgs()) - getTemplateKWAndArgsInfo()->copyInto(List); + getTrailingASTTemplateKWAndArgsInfo()->copyInto(getTemplateArgs(), List); } static bool classof(const Stmt *T) { @@ -2608,7 +2612,10 @@ public: /// /// These never include UnresolvedUsingValueDecls, which are always class /// members and therefore appear only in UnresolvedMemberLookupExprs. -class UnresolvedLookupExpr : public OverloadExpr { +class UnresolvedLookupExpr final + : public OverloadExpr, + private llvm::TrailingObjects< + UnresolvedLookupExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> { /// True if these lookup results should be extended by /// argument-dependent lookup if this is the operand of a function /// call. @@ -2625,6 +2632,10 @@ class UnresolvedLookupExpr : public OverloadExpr { /// against the qualified-lookup bits. CXXRecordDecl *NamingClass; + size_t numTrailingObjects(OverloadToken) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; + } + UnresolvedLookupExpr(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, @@ -2644,6 +2655,8 @@ class UnresolvedLookupExpr : public OverloadExpr { RequiresADL(false), Overloaded(false), NamingClass(nullptr) {} + friend TrailingObjects; + friend class OverloadExpr; friend class ASTStmtReader; public: @@ -2719,8 +2732,11 @@ public: /// qualifier (X::) and the name of the entity being referenced /// ("value"). Such expressions will instantiate to a DeclRefExpr once the /// declaration can be found. -class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentScopeDeclRefExpr - : public Expr { +class DependentScopeDeclRefExpr final + : public Expr, + private llvm::TrailingObjects { /// \brief The nested-name-specifier that qualifies this unresolved /// declaration name. NestedNameSpecifierLoc QualifierLoc; @@ -2732,15 +2748,8 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentScopeDeclRefExpr /// keyword and arguments. bool HasTemplateKWAndArgsInfo; - /// \brief Return the optional template keyword and arguments info. - ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { - if (!HasTemplateKWAndArgsInfo) return nullptr; - return reinterpret_cast(this + 1); - } - /// \brief Return the optional template keyword and arguments info. - const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { - return const_cast(this) - ->getTemplateKWAndArgsInfo(); + size_t numTrailingObjects(OverloadToken) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; } DependentScopeDeclRefExpr(QualType T, @@ -2785,21 +2794,21 @@ public: /// this name, if any. SourceLocation getTemplateKeywordLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->TemplateKWLoc; + return getTrailingObjects()->TemplateKWLoc; } /// \brief Retrieve the location of the left angle bracket starting the /// explicit template argument list following the name, if any. SourceLocation getLAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->LAngleLoc; + return getTrailingObjects()->LAngleLoc; } /// \brief Retrieve the location of the right angle bracket ending the /// explicit template argument list following the name, if any. SourceLocation getRAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->RAngleLoc; + return getTrailingObjects()->RAngleLoc; } /// Determines whether the name was preceded by the template keyword. @@ -2812,21 +2821,22 @@ public: /// structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { if (hasExplicitTemplateArgs()) - getTemplateKWAndArgsInfo()->copyInto(List); + getTrailingObjects()->copyInto( + getTrailingObjects(), List); } TemplateArgumentLoc const *getTemplateArgs() const { if (!hasExplicitTemplateArgs()) return nullptr; - return getTemplateKWAndArgsInfo()->getTemplateArgs(); + return getTrailingObjects(); } unsigned getNumTemplateArgs() const { if (!hasExplicitTemplateArgs()) return 0; - return getTemplateKWAndArgsInfo()->NumTemplateArgs; + return getTrailingObjects()->NumTemplateArgs; } /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr, @@ -2848,6 +2858,7 @@ public: return child_range(child_iterator(), child_iterator()); } + friend TrailingObjects; friend class ASTStmtReader; friend class ASTStmtWriter; }; @@ -3050,8 +3061,11 @@ public: /// Like UnresolvedMemberExprs, these can be either implicit or /// explicit accesses. It is only possible to get one of these with /// an implicit access if a qualifier is provided. -class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) CXXDependentScopeMemberExpr - : public Expr { +class CXXDependentScopeMemberExpr final + : public Expr, + private llvm::TrailingObjects { /// \brief The expression for the base pointer or class reference, /// e.g., the \c x in x.f. Can be null in implicit accesses. Stmt *Base; @@ -3089,15 +3103,8 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) CXXDependentScopeMemberExpr /// FIXME: could also be a template-id DeclarationNameInfo MemberNameInfo; - /// \brief Return the optional template keyword and arguments info. - ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { - if (!HasTemplateKWAndArgsInfo) return nullptr; - return reinterpret_cast(this + 1); - } - /// \brief Return the optional template keyword and arguments info. - const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { - return const_cast(this) - ->getTemplateKWAndArgsInfo(); + size_t numTrailingObjects(OverloadToken) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; } CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base, @@ -3193,21 +3200,21 @@ public: /// member name, if any. SourceLocation getTemplateKeywordLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->TemplateKWLoc; + return getTrailingObjects()->TemplateKWLoc; } /// \brief Retrieve the location of the left angle bracket starting the /// explicit template argument list following the member name, if any. SourceLocation getLAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->LAngleLoc; + return getTrailingObjects()->LAngleLoc; } /// \brief Retrieve the location of the right angle bracket ending the /// explicit template argument list following the member name, if any. SourceLocation getRAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->RAngleLoc; + return getTrailingObjects()->RAngleLoc; } /// Determines whether the member name was preceded by the template keyword. @@ -3221,7 +3228,8 @@ public: /// structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { if (hasExplicitTemplateArgs()) - getTemplateKWAndArgsInfo()->copyInto(List); + getTrailingObjects()->copyInto( + getTrailingObjects(), List); } /// \brief Retrieve the template arguments provided as part of this @@ -3230,7 +3238,7 @@ public: if (!hasExplicitTemplateArgs()) return nullptr; - return getTemplateKWAndArgsInfo()->getTemplateArgs(); + return getTrailingObjects(); } /// \brief Retrieve the number of template arguments provided as part of this @@ -3239,7 +3247,7 @@ public: if (!hasExplicitTemplateArgs()) return 0; - return getTemplateKWAndArgsInfo()->NumTemplateArgs; + return getTrailingObjects()->NumTemplateArgs; } SourceLocation getLocStart() const LLVM_READONLY { @@ -3248,8 +3256,8 @@ public: if (getQualifier()) return getQualifierLoc().getBeginLoc(); return MemberNameInfo.getBeginLoc(); - } + SourceLocation getLocEnd() const LLVM_READONLY { if (hasExplicitTemplateArgs()) return getRAngleLoc(); @@ -3267,6 +3275,7 @@ public: return child_range(&Base, &Base + 1); } + friend TrailingObjects; friend class ASTStmtReader; friend class ASTStmtWriter; }; @@ -3286,8 +3295,10 @@ public: /// In the final AST, an explicit access always becomes a MemberExpr. /// An implicit access may become either a MemberExpr or a /// DeclRefExpr, depending on whether the member is static. -class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) UnresolvedMemberExpr - : public OverloadExpr { +class UnresolvedMemberExpr final + : public OverloadExpr, + private llvm::TrailingObjects< + UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> { /// \brief Whether this member expression used the '->' operator or /// the '.' operator. bool IsArrow : 1; @@ -3308,6 +3319,10 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) UnresolvedMemberExpr /// \brief The location of the '->' or '.' operator. SourceLocation OperatorLoc; + size_t numTrailingObjects(OverloadToken) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; + } + UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, @@ -3321,6 +3336,8 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) UnresolvedMemberExpr : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false), HasUnresolvedUsing(false), Base(nullptr) { } + friend TrailingObjects; + friend class OverloadExpr; friend class ASTStmtReader; public: @@ -3412,15 +3429,26 @@ public: } }; -inline ASTTemplateKWAndArgsInfo *OverloadExpr::getTemplateKWAndArgsInfo() { +inline ASTTemplateKWAndArgsInfo * +OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() { if (!HasTemplateKWAndArgsInfo) return nullptr; + if (isa(this)) - return reinterpret_cast( - cast(this) + 1); + return cast(this) + ->getTrailingObjects(); else - return reinterpret_cast( - cast(this) + 1); + return cast(this) + ->getTrailingObjects(); +} + +inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() { + if (isa(this)) + return cast(this) + ->getTrailingObjects(); + else + return cast(this) + ->getTrailingObjects(); } /// \brief Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]). diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h index ac2f511335fc..f87171a81d1d 100644 --- a/clang/include/clang/AST/TemplateBase.h +++ b/clang/include/clang/AST/TemplateBase.h @@ -595,18 +595,13 @@ public: }; /// \brief Represents an explicit template argument list in C++, e.g., -/// the "" in "sort". This is safe to be used inside an AST -/// node, in contrast with TemplateArgumentListInfo. +/// the "" in "sort". /// -/// This is currently very similar to ASTTemplateArgumentListInfo -/// class, but a) has a extra member, TemplateKWLoc, and b) is -/// intended to be tacked on the end of some of the Expr classes, not -/// as a public interface. -struct ASTTemplateKWAndArgsInfo final - : private llvm::TrailingObjects { - friend TrailingObjects; - +/// It is intended to be used as a trailing object on AST nodes, and +/// as such, doesn't contain the array of TemplateArgumentLoc itself, +/// but expects the containing object to also provide storage for +/// that. +struct LLVM_ALIGNAS(LLVM_PTR_SIZE) ASTTemplateKWAndArgsInfo { /// \brief The source location of the left angle bracket ('<'). SourceLocation LAngleLoc; @@ -622,30 +617,18 @@ struct ASTTemplateKWAndArgsInfo final /// \brief The number of template arguments in TemplateArgs. unsigned NumTemplateArgs; - /// \brief Retrieve the template arguments - TemplateArgumentLoc *getTemplateArgs() { - return getTrailingObjects(); - } - - /// \brief Retrieve the template arguments - const TemplateArgumentLoc *getTemplateArgs() const { - return getTrailingObjects(); - } - - const TemplateArgumentLoc &operator[](unsigned I) const { - return getTemplateArgs()[I]; - } - - void initializeFrom(SourceLocation TemplateKWLoc, - const TemplateArgumentListInfo &List); void initializeFrom(SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &List, - bool &Dependent, bool &InstantiationDependent, + TemplateArgumentLoc *OutArgArray); + void initializeFrom(SourceLocation TemplateKWLoc, + const TemplateArgumentListInfo &List, + TemplateArgumentLoc *OutArgArray, bool &Dependent, + bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack); void initializeFrom(SourceLocation TemplateKWLoc); - void copyInto(TemplateArgumentListInfo &List) const; - static std::size_t sizeFor(unsigned NumTemplateArgs); + void copyInto(const TemplateArgumentLoc *ArgArray, + TemplateArgumentListInfo &List) const; }; const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index b09824483a22..7e58653efe18 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -331,7 +331,8 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) { DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0; if (QualifierLoc) { - getInternalQualifierLoc() = QualifierLoc; + new (getTrailingObjects()) + NestedNameSpecifierLoc(QualifierLoc); auto *NNS = QualifierLoc.getNestedNameSpecifier(); if (NNS->isInstantiationDependent()) ExprBits.InstantiationDependent = true; @@ -340,7 +341,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, } DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0; if (FoundD) - getInternalFoundDecl() = FoundD; + *getTrailingObjects() = FoundD; DeclRefExprBits.HasTemplateKWAndArgsInfo = (TemplateArgs || TemplateKWLoc.isValid()) ? 1 : 0; DeclRefExprBits.RefersToEnclosingVariableOrCapture = @@ -349,15 +350,15 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, bool Dependent = false; bool InstantiationDependent = false; bool ContainsUnexpandedParameterPack = false; - getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *TemplateArgs, - Dependent, - InstantiationDependent, - ContainsUnexpandedParameterPack); + getTrailingObjects()->initializeFrom( + TemplateKWLoc, *TemplateArgs, getTrailingObjects(), + Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); assert(!Dependent && "built a DeclRefExpr with dependent template args"); ExprBits.InstantiationDependent |= InstantiationDependent; ExprBits.ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack; } else if (TemplateKWLoc.isValid()) { - getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); + getTrailingObjects()->initializeFrom( + TemplateKWLoc); } DeclRefExprBits.HadMultipleCandidates = 0; @@ -394,20 +395,13 @@ DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context, if (D == FoundD) FoundD = nullptr; - std::size_t Size = sizeof(DeclRefExpr); - if (QualifierLoc) - Size += sizeof(NestedNameSpecifierLoc); - if (FoundD) - Size += sizeof(NamedDecl *); - if (TemplateArgs) { - Size = llvm::RoundUpToAlignment(Size, - llvm::alignOf()); - Size += ASTTemplateKWAndArgsInfo::sizeFor(TemplateArgs->size()); - } else if (TemplateKWLoc.isValid()) { - Size = llvm::RoundUpToAlignment(Size, - llvm::alignOf()); - Size += ASTTemplateKWAndArgsInfo::sizeFor(0); - } + bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid(); + std::size_t Size = + totalSizeToAlloc( + QualifierLoc ? 1 : 0, FoundD ? 1 : 0, + HasTemplateKWAndArgsInfo ? 1 : 0, + TemplateArgs ? TemplateArgs->size() : 0); void *Mem = Context.Allocate(Size, llvm::alignOf()); return new (Mem) DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D, @@ -420,17 +414,12 @@ DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context, bool HasFoundDecl, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) { - std::size_t Size = sizeof(DeclRefExpr); - if (HasQualifier) - Size += sizeof(NestedNameSpecifierLoc); - if (HasFoundDecl) - Size += sizeof(NamedDecl *); - if (HasTemplateKWAndArgsInfo) { - Size = llvm::RoundUpToAlignment(Size, - llvm::alignOf()); - Size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); - } - + assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo); + std::size_t Size = + totalSizeToAlloc( + HasQualifier ? 1 : 0, HasFoundDecl ? 1 : 0, HasTemplateKWAndArgsInfo, + NumTemplateArgs); void *Mem = Context.Allocate(Size, llvm::alignOf()); return new (Mem) DeclRefExpr(EmptyShell()); } @@ -1419,18 +1408,17 @@ MemberExpr *MemberExpr::Create( ValueDecl *memberdecl, DeclAccessPair founddecl, DeclarationNameInfo nameinfo, const TemplateArgumentListInfo *targs, QualType ty, ExprValueKind vk, ExprObjectKind ok) { - std::size_t Size = sizeof(MemberExpr); bool hasQualOrFound = (QualifierLoc || founddecl.getDecl() != memberdecl || founddecl.getAccess() != memberdecl->getAccess()); - if (hasQualOrFound) - Size += sizeof(MemberNameQualifier); - if (targs) - Size += ASTTemplateKWAndArgsInfo::sizeFor(targs->size()); - else if (TemplateKWLoc.isValid()) - Size += ASTTemplateKWAndArgsInfo::sizeFor(0); + bool HasTemplateKWAndArgsInfo = targs || TemplateKWLoc.isValid(); + std::size_t Size = + totalSizeToAlloc(hasQualOrFound ? 1 : 0, + HasTemplateKWAndArgsInfo ? 1 : 0, + targs ? targs->size() : 0); void *Mem = C.Allocate(Size, llvm::alignOf()); MemberExpr *E = new (Mem) @@ -1449,7 +1437,8 @@ MemberExpr *MemberExpr::Create( E->HasQualifierOrFoundDecl = true; - MemberNameQualifier *NQ = E->getMemberQualifier(); + MemberExprNameQualifier *NQ = + E->getTrailingObjects(); NQ->QualifierLoc = QualifierLoc; NQ->FoundDecl = founddecl; } @@ -1460,14 +1449,14 @@ MemberExpr *MemberExpr::Create( bool Dependent = false; bool InstantiationDependent = false; bool ContainsUnexpandedParameterPack = false; - E->getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *targs, - Dependent, - InstantiationDependent, - ContainsUnexpandedParameterPack); + E->getTrailingObjects()->initializeFrom( + TemplateKWLoc, *targs, E->getTrailingObjects(), + Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); if (InstantiationDependent) E->setInstantiationDependent(true); } else if (TemplateKWLoc.isValid()) { - E->getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); + E->getTrailingObjects()->initializeFrom( + TemplateKWLoc); } return E; @@ -4055,4 +4044,3 @@ QualType OMPArraySectionExpr::getBaseOriginalType(Expr *Base) { } return OriginalTy; } - diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index b7f266ceccb1..c0aafd42ad53 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -295,8 +295,11 @@ UnresolvedLookupExpr::Create(const ASTContext &C, { assert(Args || TemplateKWLoc.isValid()); unsigned num_args = Args ? Args->size() : 0; - void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) + - ASTTemplateKWAndArgsInfo::sizeFor(num_args)); + + std::size_t Size = + totalSizeToAlloc(1, + num_args); + void *Mem = C.Allocate(Size, llvm::alignOf()); return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, TemplateKWLoc, NameInfo, ADL, /*Overload*/ true, Args, @@ -307,11 +310,11 @@ UnresolvedLookupExpr * UnresolvedLookupExpr::CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) { - std::size_t size = sizeof(UnresolvedLookupExpr); - if (HasTemplateKWAndArgsInfo) - size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); - - void *Mem = C.Allocate(size, llvm::alignOf()); + assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo); + std::size_t Size = + totalSizeToAlloc( + HasTemplateKWAndArgsInfo, NumTemplateArgs); + void *Mem = C.Allocate(Size, llvm::alignOf()); UnresolvedLookupExpr *E = new (Mem) UnresolvedLookupExpr(EmptyShell()); E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo; return E; @@ -367,10 +370,9 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C, bool Dependent = false; bool InstantiationDependent = false; bool ContainsUnexpandedParameterPack = false; - getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *TemplateArgs, - Dependent, - InstantiationDependent, - ContainsUnexpandedParameterPack); + getTrailingASTTemplateKWAndArgsInfo()->initializeFrom( + TemplateKWLoc, *TemplateArgs, getTrailingTemplateArgumentLoc(), + Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); if (Dependent) { ExprBits.TypeDependent = true; @@ -381,7 +383,7 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C, if (ContainsUnexpandedParameterPack) ExprBits.ContainsUnexpandedParameterPack = true; } else if (TemplateKWLoc.isValid()) { - getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); + getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); } if (isTypeDependent()) @@ -432,13 +434,13 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, bool InstantiationDependent = true; bool ContainsUnexpandedParameterPack = ExprBits.ContainsUnexpandedParameterPack; - getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *Args, - Dependent, - InstantiationDependent, - ContainsUnexpandedParameterPack); + getTrailingObjects()->initializeFrom( + TemplateKWLoc, *Args, getTrailingObjects(), + Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; } else if (TemplateKWLoc.isValid()) { - getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); + getTrailingObjects()->initializeFrom( + TemplateKWLoc); } } @@ -449,12 +451,11 @@ DependentScopeDeclRefExpr::Create(const ASTContext &C, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *Args) { assert(QualifierLoc && "should be created for dependent qualifiers"); - std::size_t size = sizeof(DependentScopeDeclRefExpr); - if (Args) - size += ASTTemplateKWAndArgsInfo::sizeFor(Args->size()); - else if (TemplateKWLoc.isValid()) - size += ASTTemplateKWAndArgsInfo::sizeFor(0); - void *Mem = C.Allocate(size); + bool HasTemplateKWAndArgsInfo = Args || TemplateKWLoc.isValid(); + std::size_t Size = + totalSizeToAlloc( + HasTemplateKWAndArgsInfo, Args ? Args->size() : 0); + void *Mem = C.Allocate(Size); return new (Mem) DependentScopeDeclRefExpr(C.DependentTy, QualifierLoc, TemplateKWLoc, NameInfo, Args); } @@ -463,10 +464,11 @@ DependentScopeDeclRefExpr * DependentScopeDeclRefExpr::CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) { - std::size_t size = sizeof(DependentScopeDeclRefExpr); - if (HasTemplateKWAndArgsInfo) - size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); - void *Mem = C.Allocate(size); + assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo); + std::size_t Size = + totalSizeToAlloc( + HasTemplateKWAndArgsInfo, NumTemplateArgs); + void *Mem = C.Allocate(Size); DependentScopeDeclRefExpr *E = new (Mem) DependentScopeDeclRefExpr(QualType(), NestedNameSpecifierLoc(), SourceLocation(), @@ -1195,63 +1197,40 @@ SourceLocation CXXUnresolvedConstructExpr::getLocStart() const { return Type->getTypeLoc().getBeginLoc(); } -CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(const ASTContext &C, - Expr *Base, QualType BaseType, - bool IsArrow, - SourceLocation OperatorLoc, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - NamedDecl *FirstQualifierFoundInScope, - DeclarationNameInfo MemberNameInfo, - const TemplateArgumentListInfo *TemplateArgs) - : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, - VK_LValue, OK_Ordinary, true, true, true, - ((Base && Base->containsUnexpandedParameterPack()) || - (QualifierLoc && - QualifierLoc.getNestedNameSpecifier() - ->containsUnexpandedParameterPack()) || - MemberNameInfo.containsUnexpandedParameterPack())), - Base(Base), BaseType(BaseType), IsArrow(IsArrow), - HasTemplateKWAndArgsInfo(TemplateArgs != nullptr || - TemplateKWLoc.isValid()), - OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc), - FirstQualifierFoundInScope(FirstQualifierFoundInScope), - MemberNameInfo(MemberNameInfo) { +CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr( + const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, + SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, + DeclarationNameInfo MemberNameInfo, + const TemplateArgumentListInfo *TemplateArgs) + : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, VK_LValue, + OK_Ordinary, true, true, true, + ((Base && Base->containsUnexpandedParameterPack()) || + (QualifierLoc && + QualifierLoc.getNestedNameSpecifier() + ->containsUnexpandedParameterPack()) || + MemberNameInfo.containsUnexpandedParameterPack())), + Base(Base), BaseType(BaseType), IsArrow(IsArrow), + HasTemplateKWAndArgsInfo(TemplateArgs != nullptr || + TemplateKWLoc.isValid()), + OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc), + FirstQualifierFoundInScope(FirstQualifierFoundInScope), + MemberNameInfo(MemberNameInfo) { if (TemplateArgs) { bool Dependent = true; bool InstantiationDependent = true; bool ContainsUnexpandedParameterPack = false; - getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *TemplateArgs, - Dependent, - InstantiationDependent, - ContainsUnexpandedParameterPack); + getTrailingObjects()->initializeFrom( + TemplateKWLoc, *TemplateArgs, getTrailingObjects(), + Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); if (ContainsUnexpandedParameterPack) ExprBits.ContainsUnexpandedParameterPack = true; } else if (TemplateKWLoc.isValid()) { - getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); + getTrailingObjects()->initializeFrom( + TemplateKWLoc); } } -CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(const ASTContext &C, - Expr *Base, QualType BaseType, - bool IsArrow, - SourceLocation OperatorLoc, - NestedNameSpecifierLoc QualifierLoc, - NamedDecl *FirstQualifierFoundInScope, - DeclarationNameInfo MemberNameInfo) - : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, - VK_LValue, OK_Ordinary, true, true, true, - ((Base && Base->containsUnexpandedParameterPack()) || - (QualifierLoc && - QualifierLoc.getNestedNameSpecifier()-> - containsUnexpandedParameterPack()) || - MemberNameInfo.containsUnexpandedParameterPack())), - Base(Base), BaseType(BaseType), IsArrow(IsArrow), - HasTemplateKWAndArgsInfo(false), - OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc), - FirstQualifierFoundInScope(FirstQualifierFoundInScope), - MemberNameInfo(MemberNameInfo) { } - CXXDependentScopeMemberExpr * CXXDependentScopeMemberExpr::Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, @@ -1261,18 +1240,13 @@ CXXDependentScopeMemberExpr::Create(const ASTContext &C, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs) { - if (!TemplateArgs && !TemplateKWLoc.isValid()) - return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType, - IsArrow, OperatorLoc, - QualifierLoc, - FirstQualifierFoundInScope, - MemberNameInfo); - + bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid(); unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0; - std::size_t size = sizeof(CXXDependentScopeMemberExpr) - + ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); + std::size_t Size = + totalSizeToAlloc( + HasTemplateKWAndArgsInfo, NumTemplateArgs); - void *Mem = C.Allocate(size, llvm::alignOf()); + void *Mem = C.Allocate(Size, llvm::alignOf()); return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc, @@ -1285,22 +1259,18 @@ CXXDependentScopeMemberExpr * CXXDependentScopeMemberExpr::CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) { - if (!HasTemplateKWAndArgsInfo) - return new (C) CXXDependentScopeMemberExpr(C, nullptr, QualType(), - 0, SourceLocation(), - NestedNameSpecifierLoc(), - nullptr, DeclarationNameInfo()); - - std::size_t size = sizeof(CXXDependentScopeMemberExpr) + - ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); - void *Mem = C.Allocate(size, llvm::alignOf()); + assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo); + std::size_t Size = + totalSizeToAlloc( + HasTemplateKWAndArgsInfo, NumTemplateArgs); + void *Mem = C.Allocate(Size, llvm::alignOf()); CXXDependentScopeMemberExpr *E = new (Mem) CXXDependentScopeMemberExpr(C, nullptr, QualType(), 0, SourceLocation(), NestedNameSpecifierLoc(), SourceLocation(), nullptr, DeclarationNameInfo(), nullptr); - E->HasTemplateKWAndArgsInfo = true; + E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo; return E; } @@ -1365,38 +1335,34 @@ bool UnresolvedMemberExpr::isImplicitAccess() const { return cast(Base)->isImplicitCXXThis(); } -UnresolvedMemberExpr * -UnresolvedMemberExpr::Create(const ASTContext &C, bool HasUnresolvedUsing, - Expr *Base, QualType BaseType, bool IsArrow, - SourceLocation OperatorLoc, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - const DeclarationNameInfo &MemberNameInfo, - const TemplateArgumentListInfo *TemplateArgs, - UnresolvedSetIterator Begin, - UnresolvedSetIterator End) { - std::size_t size = sizeof(UnresolvedMemberExpr); - if (TemplateArgs) - size += ASTTemplateKWAndArgsInfo::sizeFor(TemplateArgs->size()); - else if (TemplateKWLoc.isValid()) - size += ASTTemplateKWAndArgsInfo::sizeFor(0); +UnresolvedMemberExpr *UnresolvedMemberExpr::Create( + const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, + bool IsArrow, SourceLocation OperatorLoc, + NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, + const DeclarationNameInfo &MemberNameInfo, + const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, + UnresolvedSetIterator End) { + bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid(); + std::size_t Size = + totalSizeToAlloc( + HasTemplateKWAndArgsInfo, TemplateArgs ? TemplateArgs->size() : 0); - void *Mem = C.Allocate(size, llvm::alignOf()); - return new (Mem) UnresolvedMemberExpr(C, - HasUnresolvedUsing, Base, BaseType, - IsArrow, OperatorLoc, QualifierLoc, TemplateKWLoc, - MemberNameInfo, TemplateArgs, Begin, End); + void *Mem = C.Allocate(Size, llvm::alignOf()); + return new (Mem) UnresolvedMemberExpr( + C, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc, + TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End); } UnresolvedMemberExpr * UnresolvedMemberExpr::CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) { - std::size_t size = sizeof(UnresolvedMemberExpr); - if (HasTemplateKWAndArgsInfo) - size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); + assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo); + std::size_t Size = + totalSizeToAlloc( + HasTemplateKWAndArgsInfo, NumTemplateArgs); - void *Mem = C.Allocate(size, llvm::alignOf()); + void *Mem = C.Allocate(Size, llvm::alignOf()); UnresolvedMemberExpr *E = new (Mem) UnresolvedMemberExpr(EmptyShell()); E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo; return E; diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index c389a094f3b0..e9edb0df66df 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -537,15 +537,15 @@ ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo( } void ASTTemplateKWAndArgsInfo::initializeFrom( - SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info) { + SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, + TemplateArgumentLoc *OutArgArray) { this->TemplateKWLoc = TemplateKWLoc; LAngleLoc = Info.getLAngleLoc(); RAngleLoc = Info.getRAngleLoc(); NumTemplateArgs = Info.size(); - TemplateArgumentLoc *ArgBuffer = getTemplateArgs(); for (unsigned i = 0; i != NumTemplateArgs; ++i) - new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); + new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); } void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { @@ -558,14 +558,13 @@ void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { void ASTTemplateKWAndArgsInfo::initializeFrom( SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, - bool &Dependent, bool &InstantiationDependent, - bool &ContainsUnexpandedParameterPack) { + TemplateArgumentLoc *OutArgArray, bool &Dependent, + bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack) { this->TemplateKWLoc = TemplateKWLoc; LAngleLoc = Info.getLAngleLoc(); RAngleLoc = Info.getRAngleLoc(); NumTemplateArgs = Info.size(); - TemplateArgumentLoc *ArgBuffer = getTemplateArgs(); for (unsigned i = 0; i != NumTemplateArgs; ++i) { Dependent = Dependent || Info[i].getArgument().isDependent(); InstantiationDependent = InstantiationDependent || @@ -574,17 +573,14 @@ void ASTTemplateKWAndArgsInfo::initializeFrom( ContainsUnexpandedParameterPack || Info[i].getArgument().containsUnexpandedParameterPack(); - new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); + new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); } } -void ASTTemplateKWAndArgsInfo::copyInto(TemplateArgumentListInfo &Info) const { +void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray, + TemplateArgumentListInfo &Info) const { Info.setLAngleLoc(LAngleLoc); Info.setRAngleLoc(RAngleLoc); for (unsigned I = 0; I != NumTemplateArgs; ++I) - Info.addArgument(getTemplateArgs()[I]); -} - -std::size_t ASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) { - return totalSizeToAlloc(NumTemplateArgs); + Info.addArgument(ArgArray[I]); } diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 109ef1fa9b2e..84622cf8ef74 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -93,6 +93,7 @@ namespace clang { /// \brief Read and initialize a ExplicitTemplateArgumentList structure. void ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, + TemplateArgumentLoc *ArgsLocArray, unsigned NumTemplateArgs); /// \brief Read and initialize a ExplicitTemplateArgumentList structure. void ReadExplicitTemplateArgumentList(ASTTemplateArgumentListInfo &ArgList, @@ -105,9 +106,9 @@ namespace clang { }; } -void ASTStmtReader:: -ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, - unsigned NumTemplateArgs) { +void ASTStmtReader::ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, + TemplateArgumentLoc *ArgsLocArray, + unsigned NumTemplateArgs) { SourceLocation TemplateKWLoc = ReadSourceLocation(Record, Idx); TemplateArgumentListInfo ArgInfo; ArgInfo.setLAngleLoc(ReadSourceLocation(Record, Idx)); @@ -115,7 +116,7 @@ ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, for (unsigned i = 0; i != NumTemplateArgs; ++i) ArgInfo.addArgument( Reader.ReadTemplateArgumentLoc(F, Record, Idx)); - Args.initializeFrom(TemplateKWLoc, ArgInfo); + Args.initializeFrom(TemplateKWLoc, ArgInfo, ArgsLocArray); } void ASTStmtReader::VisitStmt(Stmt *S) { @@ -459,15 +460,17 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { NumTemplateArgs = Record[Idx++]; if (E->hasQualifier()) - E->getInternalQualifierLoc() - = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); + new (E->getTrailingObjects()) + NestedNameSpecifierLoc( + Reader.ReadNestedNameSpecifierLoc(F, Record, Idx)); if (E->hasFoundDecl()) - E->getInternalFoundDecl() = ReadDeclAs(Record, Idx); + *E->getTrailingObjects() = ReadDeclAs(Record, Idx); if (E->hasTemplateKWAndArgsInfo()) - ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(), - NumTemplateArgs); + ReadTemplateKWAndArgsInfo( + *E->getTrailingObjects(), + E->getTrailingObjects(), NumTemplateArgs); E->setDecl(ReadDeclAs(Record, Idx)); E->setLocation(ReadSourceLocation(Record, Idx)); @@ -1453,8 +1456,10 @@ ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ VisitExpr(E); if (Record[Idx++]) // HasTemplateKWAndArgsInfo - ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(), - /*NumTemplateArgs=*/Record[Idx++]); + ReadTemplateKWAndArgsInfo( + *E->getTrailingObjects(), + E->getTrailingObjects(), + /*NumTemplateArgs=*/Record[Idx++]); E->Base = Reader.ReadSubExpr(); E->BaseType = Reader.readType(F, Record, Idx); @@ -1470,8 +1475,10 @@ ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { VisitExpr(E); if (Record[Idx++]) // HasTemplateKWAndArgsInfo - ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(), - /*NumTemplateArgs=*/Record[Idx++]); + ReadTemplateKWAndArgsInfo( + *E->getTrailingObjects(), + E->getTrailingObjects(), + /*NumTemplateArgs=*/Record[Idx++]); E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); ReadDeclarationNameInfo(E->NameInfo, Record, Idx); @@ -1493,7 +1500,8 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) { VisitExpr(E); if (Record[Idx++]) // HasTemplateKWAndArgsInfo - ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(), + ReadTemplateKWAndArgsInfo(*E->getTrailingASTTemplateKWAndArgsInfo(), + E->getTrailingTemplateArgumentLoc(), /*NumTemplateArgs=*/Record[Idx++]); unsigned NumDecls = Record[Idx++]; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 8a4e9ab0176b..849c6fa4ecf9 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -40,7 +40,8 @@ namespace clang { ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record) : Writer(Writer), Record(Record) { } - void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args); + void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &ArgInfo, + const TemplateArgumentLoc *Args); void VisitStmt(Stmt *S); #define STMT(Type, Base) \ @@ -49,13 +50,13 @@ namespace clang { }; } -void ASTStmtWriter:: -AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args) { - Writer.AddSourceLocation(Args.TemplateKWLoc, Record); - Writer.AddSourceLocation(Args.LAngleLoc, Record); - Writer.AddSourceLocation(Args.RAngleLoc, Record); - for (unsigned i=0; i != Args.NumTemplateArgs; ++i) - Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record); +void ASTStmtWriter::AddTemplateKWAndArgsInfo( + const ASTTemplateKWAndArgsInfo &ArgInfo, const TemplateArgumentLoc *Args) { + Writer.AddSourceLocation(ArgInfo.TemplateKWLoc, Record); + Writer.AddSourceLocation(ArgInfo.LAngleLoc, Record); + Writer.AddSourceLocation(ArgInfo.RAngleLoc, Record); + for (unsigned i = 0; i != ArgInfo.NumTemplateArgs; ++i) + Writer.AddTemplateArgumentLoc(Args[i], Record); } void ASTStmtWriter::VisitStmt(Stmt *S) { @@ -386,7 +387,8 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { Writer.AddDeclRef(E->getFoundDecl(), Record); if (E->hasTemplateKWAndArgsInfo()) - AddTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo()); + AddTemplateKWAndArgsInfo(*E->getTrailingObjects(), + E->getTrailingObjects()); Writer.AddDeclRef(E->getDecl(), Record); Writer.AddSourceLocation(E->getLocation(), Record); @@ -1440,9 +1442,11 @@ ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ Record.push_back(E->HasTemplateKWAndArgsInfo); if (E->HasTemplateKWAndArgsInfo) { - const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo(); - Record.push_back(Args.NumTemplateArgs); - AddTemplateKWAndArgsInfo(Args); + const ASTTemplateKWAndArgsInfo &ArgInfo = + *E->getTrailingObjects(); + Record.push_back(ArgInfo.NumTemplateArgs); + AddTemplateKWAndArgsInfo(ArgInfo, + E->getTrailingObjects()); } if (!E->isImplicitAccess()) @@ -1467,9 +1471,11 @@ ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { Record.push_back(E->HasTemplateKWAndArgsInfo); if (E->HasTemplateKWAndArgsInfo) { - const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo(); - Record.push_back(Args.NumTemplateArgs); - AddTemplateKWAndArgsInfo(Args); + const ASTTemplateKWAndArgsInfo &ArgInfo = + *E->getTrailingObjects(); + Record.push_back(ArgInfo.NumTemplateArgs); + AddTemplateKWAndArgsInfo(ArgInfo, + E->getTrailingObjects()); } Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); @@ -1498,9 +1504,10 @@ void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) { Record.push_back(E->HasTemplateKWAndArgsInfo); if (E->HasTemplateKWAndArgsInfo) { - const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo(); - Record.push_back(Args.NumTemplateArgs); - AddTemplateKWAndArgsInfo(Args); + const ASTTemplateKWAndArgsInfo &ArgInfo = + *E->getTrailingASTTemplateKWAndArgsInfo(); + Record.push_back(ArgInfo.NumTemplateArgs); + AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc()); } Record.push_back(E->getNumDecls());