[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
This commit is contained in:
James Y Knight 2015-12-29 18:15:14 +00:00
parent 59309cc090
commit e7d82283cd
8 changed files with 337 additions and 416 deletions

View File

@ -919,7 +919,11 @@ public:
/// DeclRefExprBits.RefersToEnclosingVariableOrCapture /// DeclRefExprBits.RefersToEnclosingVariableOrCapture
/// Specifies when this declaration reference expression (validly) /// Specifies when this declaration reference expression (validly)
/// refers to an enclosed local or a captured variable. /// 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<DeclRefExpr, NestedNameSpecifierLoc,
NamedDecl *, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
/// \brief The declaration that we are referencing. /// \brief The declaration that we are referencing.
ValueDecl *D; ValueDecl *D;
@ -930,36 +934,22 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DeclRefExpr : public Expr {
/// embedded in D. /// embedded in D.
DeclarationNameLoc DNLoc; DeclarationNameLoc DNLoc;
/// \brief Helper to retrieve the optional NestedNameSpecifierLoc. size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
NestedNameSpecifierLoc &getInternalQualifierLoc() { return hasQualifier() ? 1 : 0;
assert(hasQualifier());
return *reinterpret_cast<NestedNameSpecifierLoc *>(this + 1);
} }
/// \brief Helper to retrieve the optional NestedNameSpecifierLoc. size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
const NestedNameSpecifierLoc &getInternalQualifierLoc() const { return hasFoundDecl() ? 1 : 0;
return const_cast<DeclRefExpr *>(this)->getInternalQualifierLoc(); }
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
return hasTemplateKWAndArgsInfo() ? 1 : 0;
} }
/// \brief Test whether there is a distinct FoundDecl attached to the end of /// \brief Test whether there is a distinct FoundDecl attached to the end of
/// this DRE. /// this DRE.
bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; } 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<NamedDecl **>(&getInternalQualifierLoc() + 1);
return *reinterpret_cast<NamedDecl **>(this + 1);
}
/// \brief Helper to retrieve the optional NamedDecl through which this
/// reference occurred.
NamedDecl *getInternalFoundDecl() const {
return const_cast<DeclRefExpr *>(this)->getInternalFoundDecl();
}
DeclRefExpr(const ASTContext &Ctx, DeclRefExpr(const ASTContext &Ctx,
NestedNameSpecifierLoc QualifierLoc, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc, SourceLocation TemplateKWLoc,
@ -1031,22 +1021,18 @@ public:
/// C++ nested-name-specifier, e.g., \c N::foo. /// C++ nested-name-specifier, e.g., \c N::foo.
bool hasQualifier() const { return DeclRefExprBits.HasQualifier; } 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 /// \brief If the name was qualified, retrieves the nested-name-specifier
/// that precedes the name, with source-location information. /// that precedes the name, with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const { NestedNameSpecifierLoc getQualifierLoc() const {
if (!hasQualifier()) if (!hasQualifier())
return NestedNameSpecifierLoc(); return NestedNameSpecifierLoc();
return *getTrailingObjects<NestedNameSpecifierLoc>();
}
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. /// \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 /// 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 /// presence of using declarations, etc. It always returns non-NULL, and may
/// simple return the ValueDecl when appropriate. /// simple return the ValueDecl when appropriate.
NamedDecl *getFoundDecl() { NamedDecl *getFoundDecl() {
return hasFoundDecl() ? getInternalFoundDecl() : D; return hasFoundDecl() ? *getTrailingObjects<NamedDecl *>() : D;
} }
/// \brief Get the NamedDecl through which this reference occurred. /// \brief Get the NamedDecl through which this reference occurred.
/// See non-const variant. /// See non-const variant.
const NamedDecl *getFoundDecl() const { const NamedDecl *getFoundDecl() const {
return hasFoundDecl() ? getInternalFoundDecl() : D; return hasFoundDecl() ? *getTrailingObjects<NamedDecl *>() : D;
} }
bool hasTemplateKWAndArgsInfo() const { bool hasTemplateKWAndArgsInfo() const {
return DeclRefExprBits.HasTemplateKWAndArgsInfo; return DeclRefExprBits.HasTemplateKWAndArgsInfo;
} }
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
if (!hasTemplateKWAndArgsInfo())
return nullptr;
if (hasFoundDecl()) {
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(
llvm::alignAddr(&getInternalFoundDecl() + 1,
llvm::alignOf<ASTTemplateKWAndArgsInfo>()));
}
if (hasQualifier()) {
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(
llvm::alignAddr(&getInternalQualifierLoc() + 1,
llvm::alignOf<ASTTemplateKWAndArgsInfo>()));
}
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(this + 1);
}
/// \brief Return the optional template keyword and arguments info.
const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const {
return const_cast<DeclRefExpr*>(this)->getTemplateKWAndArgsInfo();
}
/// \brief Retrieve the location of the template keyword preceding /// \brief Retrieve the location of the template keyword preceding
/// this name, if any. /// this name, if any.
SourceLocation getTemplateKeywordLoc() const { SourceLocation getTemplateKeywordLoc() const {
if (!hasTemplateKWAndArgsInfo()) return SourceLocation(); if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
return getTemplateKWAndArgsInfo()->TemplateKWLoc; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
} }
/// \brief Retrieve the location of the left angle bracket starting the /// \brief Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the name, if any. /// explicit template argument list following the name, if any.
SourceLocation getLAngleLoc() const { SourceLocation getLAngleLoc() const {
if (!hasTemplateKWAndArgsInfo()) return SourceLocation(); if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
return getTemplateKWAndArgsInfo()->LAngleLoc; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
} }
/// \brief Retrieve the location of the right angle bracket ending the /// \brief Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the name, if any. /// explicit template argument list following the name, if any.
SourceLocation getRAngleLoc() const { SourceLocation getRAngleLoc() const {
if (!hasTemplateKWAndArgsInfo()) return SourceLocation(); if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
return getTemplateKWAndArgsInfo()->RAngleLoc; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
} }
/// \brief Determines whether the name in this declaration reference /// \brief Determines whether the name in this declaration reference
@ -1126,7 +1088,8 @@ public:
/// structure. /// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgs()) if (hasExplicitTemplateArgs())
getTemplateKWAndArgsInfo()->copyInto(List); getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
getTrailingObjects<TemplateArgumentLoc>(), List);
} }
/// \brief Retrieve the template arguments provided as part of this /// \brief Retrieve the template arguments provided as part of this
@ -1135,7 +1098,7 @@ public:
if (!hasExplicitTemplateArgs()) if (!hasExplicitTemplateArgs())
return nullptr; return nullptr;
return getTemplateKWAndArgsInfo()->getTemplateArgs(); return getTrailingObjects<TemplateArgumentLoc>();
} }
/// \brief Retrieve the number of template arguments provided as part of this /// \brief Retrieve the number of template arguments provided as part of this
@ -1144,7 +1107,7 @@ public:
if (!hasExplicitTemplateArgs()) if (!hasExplicitTemplateArgs())
return 0; return 0;
return getTemplateKWAndArgsInfo()->NumTemplateArgs; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
} }
/// \brief Returns true if this expression refers to a function that /// \brief Returns true if this expression refers to a function that
@ -1174,6 +1137,7 @@ public:
return child_range(child_iterator(), child_iterator()); return child_range(child_iterator(), child_iterator());
} }
friend TrailingObjects;
friend class ASTStmtReader; friend class ASTStmtReader;
friend class ASTStmtWriter; 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. /// 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 { class MemberExpr final
/// Extra data stored in some member expressions. : public Expr,
struct LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) MemberNameQualifier { private llvm::TrailingObjects<MemberExpr, MemberExprNameQualifier,
/// \brief The nested-name-specifier that qualifies the name, including ASTTemplateKWAndArgsInfo,
/// source-location information. TemplateArgumentLoc> {
NestedNameSpecifierLoc QualifierLoc;
/// \brief The DeclAccessPair through which the MemberDecl was found due to
/// name qualifiers.
DeclAccessPair FoundDecl;
};
/// Base - the expression for the base pointer or structure references. In /// Base - the expression for the base pointer or structure references. In
/// X.F, this is "X". /// X.F, this is "X".
Stmt *Base; 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 /// \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 /// 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. /// structure is allocated immediately after the MemberExpr.
bool HasQualifierOrFoundDecl : 1; 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<int>, /// and/or a template argument list explicitly, e.g., x->f<int>,
/// x->template f, x->template f<int>. /// x->template f, x->template f<int>.
/// When true, an ASTTemplateKWAndArgsInfo structure and its /// When true, an ASTTemplateKWAndArgsInfo structure and its
/// TemplateArguments (if any) are allocated immediately after /// TemplateArguments (if any) are present.
/// the MemberExpr or, if the member expression also has a qualifier,
/// after the MemberNameQualifier structure.
bool HasTemplateKWAndArgsInfo : 1; bool HasTemplateKWAndArgsInfo : 1;
/// \brief True if this member expression refers to a method that /// \brief True if this member expression refers to a method that
/// was resolved from an overloaded set having size greater than 1. /// was resolved from an overloaded set having size greater than 1.
bool HadMultipleCandidates : 1; bool HadMultipleCandidates : 1;
/// \brief Retrieve the qualifier that preceded the member name, if any. size_t numTrailingObjects(OverloadToken<MemberExprNameQualifier>) const {
MemberNameQualifier *getMemberQualifier() { return HasQualifierOrFoundDecl ? 1 : 0;
assert(HasQualifierOrFoundDecl);
return reinterpret_cast<MemberNameQualifier *> (this + 1);
} }
/// \brief Retrieve the qualifier that preceded the member name, if any. size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
const MemberNameQualifier *getMemberQualifier() const { return HasTemplateKWAndArgsInfo ? 1 : 0;
return const_cast<MemberExpr *>(this)->getMemberQualifier();
} }
public: public:
@ -2432,7 +2395,7 @@ public:
if (!HasQualifierOrFoundDecl) if (!HasQualifierOrFoundDecl)
return DeclAccessPair::make(getMemberDecl(), return DeclAccessPair::make(getMemberDecl(),
getMemberDecl()->getAccess()); getMemberDecl()->getAccess());
return getMemberQualifier()->FoundDecl; return getTrailingObjects<MemberExprNameQualifier>()->FoundDecl;
} }
/// \brief Determines whether this member expression actually had /// \brief Determines whether this member expression actually had
@ -2440,62 +2403,42 @@ public:
/// x->Base::foo. /// x->Base::foo.
bool hasQualifier() const { return getQualifier() != nullptr; } 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 /// \brief If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name, with source-location /// nested-name-specifier that precedes the member name, with source-location
/// information. /// information.
NestedNameSpecifierLoc getQualifierLoc() const { NestedNameSpecifierLoc getQualifierLoc() const {
if (!hasQualifier()) if (!HasQualifierOrFoundDecl)
return NestedNameSpecifierLoc(); return NestedNameSpecifierLoc();
return getMemberQualifier()->QualifierLoc; return getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc;
} }
/// \brief Return the optional template keyword and arguments info. /// \brief If the member name was qualified, retrieves the
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { /// nested-name-specifier that precedes the member name. Otherwise, returns
if (!HasTemplateKWAndArgsInfo) /// NULL.
return nullptr; NestedNameSpecifier *getQualifier() const {
return getQualifierLoc().getNestedNameSpecifier();
if (!HasQualifierOrFoundDecl)
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(this + 1);
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(
getMemberQualifier() + 1);
}
/// \brief Return the optional template keyword and arguments info.
const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const {
return const_cast<MemberExpr*>(this)->getTemplateKWAndArgsInfo();
} }
/// \brief Retrieve the location of the template keyword preceding /// \brief Retrieve the location of the template keyword preceding
/// the member name, if any. /// the member name, if any.
SourceLocation getTemplateKeywordLoc() const { SourceLocation getTemplateKeywordLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation(); if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTemplateKWAndArgsInfo()->TemplateKWLoc; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
} }
/// \brief Retrieve the location of the left angle bracket starting the /// \brief Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the member name, if any. /// explicit template argument list following the member name, if any.
SourceLocation getLAngleLoc() const { SourceLocation getLAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation(); if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTemplateKWAndArgsInfo()->LAngleLoc; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
} }
/// \brief Retrieve the location of the right angle bracket ending the /// \brief Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the member name, if any. /// explicit template argument list following the member name, if any.
SourceLocation getRAngleLoc() const { SourceLocation getRAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation(); if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTemplateKWAndArgsInfo()->RAngleLoc; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
} }
/// Determines whether the member name was preceded by the template keyword. /// Determines whether the member name was preceded by the template keyword.
@ -2509,7 +2452,8 @@ public:
/// structure. /// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgs()) if (hasExplicitTemplateArgs())
getTemplateKWAndArgsInfo()->copyInto(List); getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
getTrailingObjects<TemplateArgumentLoc>(), List);
} }
/// \brief Retrieve the template arguments provided as part of this /// \brief Retrieve the template arguments provided as part of this
@ -2518,7 +2462,7 @@ public:
if (!hasExplicitTemplateArgs()) if (!hasExplicitTemplateArgs())
return nullptr; return nullptr;
return getTemplateKWAndArgsInfo()->getTemplateArgs(); return getTrailingObjects<TemplateArgumentLoc>();
} }
/// \brief Retrieve the number of template arguments provided as part of this /// \brief Retrieve the number of template arguments provided as part of this
@ -2527,7 +2471,7 @@ public:
if (!hasExplicitTemplateArgs()) if (!hasExplicitTemplateArgs())
return 0; return 0;
return getTemplateKWAndArgsInfo()->NumTemplateArgs; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
} }
/// \brief Retrieve the member declaration name info. /// \brief Retrieve the member declaration name info.
@ -2583,6 +2527,7 @@ public:
// Iterators // Iterators
child_range children() { return child_range(&Base, &Base+1); } child_range children() { return child_range(&Base, &Base+1); }
friend TrailingObjects;
friend class ASTReader; friend class ASTReader;
friend class ASTStmtWriter; friend class ASTStmtWriter;
}; };

View File

@ -2428,7 +2428,7 @@ public:
/// \brief A reference to an overloaded function set, either an /// \brief A reference to an overloaded function set, either an
/// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr. /// \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. /// \brief The common name of these declarations.
DeclarationNameInfo NameInfo; DeclarationNameInfo NameInfo;
@ -2448,13 +2448,18 @@ protected:
bool HasTemplateKWAndArgsInfo; bool HasTemplateKWAndArgsInfo;
/// \brief Return the optional template keyword and arguments info. /// \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. /// \brief Return the optional template keyword and arguments info.
const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const {
return const_cast<OverloadExpr*>(this)->getTemplateKWAndArgsInfo(); return const_cast<OverloadExpr *>(this)
->getTrailingASTTemplateKWAndArgsInfo();
} }
/// Return the optional template arguments.
TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below
OverloadExpr(StmtClass K, const ASTContext &C, OverloadExpr(StmtClass K, const ASTContext &C,
NestedNameSpecifierLoc QualifierLoc, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc, SourceLocation TemplateKWLoc,
@ -2545,21 +2550,21 @@ public:
/// this name, if any. /// this name, if any.
SourceLocation getTemplateKeywordLoc() const { SourceLocation getTemplateKeywordLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation(); if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTemplateKWAndArgsInfo()->TemplateKWLoc; return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc;
} }
/// \brief Retrieve the location of the left angle bracket starting the /// \brief Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the name, if any. /// explicit template argument list following the name, if any.
SourceLocation getLAngleLoc() const { SourceLocation getLAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation(); if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTemplateKWAndArgsInfo()->LAngleLoc; return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc;
} }
/// \brief Retrieve the location of the right angle bracket ending the /// \brief Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the name, if any. /// explicit template argument list following the name, if any.
SourceLocation getRAngleLoc() const { SourceLocation getRAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation(); if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTemplateKWAndArgsInfo()->RAngleLoc; return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc;
} }
/// \brief Determines whether the name was preceded by the template keyword. /// \brief Determines whether the name was preceded by the template keyword.
@ -2571,21 +2576,20 @@ public:
TemplateArgumentLoc const *getTemplateArgs() const { TemplateArgumentLoc const *getTemplateArgs() const {
if (!hasExplicitTemplateArgs()) if (!hasExplicitTemplateArgs())
return nullptr; return nullptr;
return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc();
return getTemplateKWAndArgsInfo()->getTemplateArgs();
} }
unsigned getNumTemplateArgs() const { unsigned getNumTemplateArgs() const {
if (!hasExplicitTemplateArgs()) if (!hasExplicitTemplateArgs())
return 0; return 0;
return getTemplateKWAndArgsInfo()->NumTemplateArgs; return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs;
} }
/// \brief Copies the template arguments into the given structure. /// \brief Copies the template arguments into the given structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgs()) if (hasExplicitTemplateArgs())
getTemplateKWAndArgsInfo()->copyInto(List); getTrailingASTTemplateKWAndArgsInfo()->copyInto(getTemplateArgs(), List);
} }
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
@ -2608,7 +2612,10 @@ public:
/// ///
/// These never include UnresolvedUsingValueDecls, which are always class /// These never include UnresolvedUsingValueDecls, which are always class
/// members and therefore appear only in UnresolvedMemberLookupExprs. /// 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 /// True if these lookup results should be extended by
/// argument-dependent lookup if this is the operand of a function /// argument-dependent lookup if this is the operand of a function
/// call. /// call.
@ -2625,6 +2632,10 @@ class UnresolvedLookupExpr : public OverloadExpr {
/// against the qualified-lookup bits. /// against the qualified-lookup bits.
CXXRecordDecl *NamingClass; CXXRecordDecl *NamingClass;
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
return HasTemplateKWAndArgsInfo ? 1 : 0;
}
UnresolvedLookupExpr(const ASTContext &C, UnresolvedLookupExpr(const ASTContext &C,
CXXRecordDecl *NamingClass, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc, NestedNameSpecifierLoc QualifierLoc,
@ -2644,6 +2655,8 @@ class UnresolvedLookupExpr : public OverloadExpr {
RequiresADL(false), Overloaded(false), NamingClass(nullptr) RequiresADL(false), Overloaded(false), NamingClass(nullptr)
{} {}
friend TrailingObjects;
friend class OverloadExpr;
friend class ASTStmtReader; friend class ASTStmtReader;
public: public:
@ -2719,8 +2732,11 @@ public:
/// qualifier (X<T>::) and the name of the entity being referenced /// qualifier (X<T>::) and the name of the entity being referenced
/// ("value"). Such expressions will instantiate to a DeclRefExpr once the /// ("value"). Such expressions will instantiate to a DeclRefExpr once the
/// declaration can be found. /// declaration can be found.
class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentScopeDeclRefExpr class DependentScopeDeclRefExpr final
: public Expr { : public Expr,
private llvm::TrailingObjects<DependentScopeDeclRefExpr,
ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
/// \brief The nested-name-specifier that qualifies this unresolved /// \brief The nested-name-specifier that qualifies this unresolved
/// declaration name. /// declaration name.
NestedNameSpecifierLoc QualifierLoc; NestedNameSpecifierLoc QualifierLoc;
@ -2732,15 +2748,8 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentScopeDeclRefExpr
/// keyword and arguments. /// keyword and arguments.
bool HasTemplateKWAndArgsInfo; bool HasTemplateKWAndArgsInfo;
/// \brief Return the optional template keyword and arguments info. size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { return HasTemplateKWAndArgsInfo ? 1 : 0;
if (!HasTemplateKWAndArgsInfo) return nullptr;
return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1);
}
/// \brief Return the optional template keyword and arguments info.
const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const {
return const_cast<DependentScopeDeclRefExpr*>(this)
->getTemplateKWAndArgsInfo();
} }
DependentScopeDeclRefExpr(QualType T, DependentScopeDeclRefExpr(QualType T,
@ -2785,21 +2794,21 @@ public:
/// this name, if any. /// this name, if any.
SourceLocation getTemplateKeywordLoc() const { SourceLocation getTemplateKeywordLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation(); if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTemplateKWAndArgsInfo()->TemplateKWLoc; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
} }
/// \brief Retrieve the location of the left angle bracket starting the /// \brief Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the name, if any. /// explicit template argument list following the name, if any.
SourceLocation getLAngleLoc() const { SourceLocation getLAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation(); if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTemplateKWAndArgsInfo()->LAngleLoc; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
} }
/// \brief Retrieve the location of the right angle bracket ending the /// \brief Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the name, if any. /// explicit template argument list following the name, if any.
SourceLocation getRAngleLoc() const { SourceLocation getRAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation(); if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTemplateKWAndArgsInfo()->RAngleLoc; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
} }
/// Determines whether the name was preceded by the template keyword. /// Determines whether the name was preceded by the template keyword.
@ -2812,21 +2821,22 @@ public:
/// structure. /// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgs()) if (hasExplicitTemplateArgs())
getTemplateKWAndArgsInfo()->copyInto(List); getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
getTrailingObjects<TemplateArgumentLoc>(), List);
} }
TemplateArgumentLoc const *getTemplateArgs() const { TemplateArgumentLoc const *getTemplateArgs() const {
if (!hasExplicitTemplateArgs()) if (!hasExplicitTemplateArgs())
return nullptr; return nullptr;
return getTemplateKWAndArgsInfo()->getTemplateArgs(); return getTrailingObjects<TemplateArgumentLoc>();
} }
unsigned getNumTemplateArgs() const { unsigned getNumTemplateArgs() const {
if (!hasExplicitTemplateArgs()) if (!hasExplicitTemplateArgs())
return 0; return 0;
return getTemplateKWAndArgsInfo()->NumTemplateArgs; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
} }
/// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr, /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr,
@ -2848,6 +2858,7 @@ public:
return child_range(child_iterator(), child_iterator()); return child_range(child_iterator(), child_iterator());
} }
friend TrailingObjects;
friend class ASTStmtReader; friend class ASTStmtReader;
friend class ASTStmtWriter; friend class ASTStmtWriter;
}; };
@ -3050,8 +3061,11 @@ public:
/// Like UnresolvedMemberExprs, these can be either implicit or /// Like UnresolvedMemberExprs, these can be either implicit or
/// explicit accesses. It is only possible to get one of these with /// explicit accesses. It is only possible to get one of these with
/// an implicit access if a qualifier is provided. /// an implicit access if a qualifier is provided.
class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) CXXDependentScopeMemberExpr class CXXDependentScopeMemberExpr final
: public Expr { : public Expr,
private llvm::TrailingObjects<CXXDependentScopeMemberExpr,
ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
/// \brief The expression for the base pointer or class reference, /// \brief The expression for the base pointer or class reference,
/// e.g., the \c x in x.f. Can be null in implicit accesses. /// e.g., the \c x in x.f. Can be null in implicit accesses.
Stmt *Base; Stmt *Base;
@ -3089,15 +3103,8 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) CXXDependentScopeMemberExpr
/// FIXME: could also be a template-id /// FIXME: could also be a template-id
DeclarationNameInfo MemberNameInfo; DeclarationNameInfo MemberNameInfo;
/// \brief Return the optional template keyword and arguments info. size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { return HasTemplateKWAndArgsInfo ? 1 : 0;
if (!HasTemplateKWAndArgsInfo) return nullptr;
return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1);
}
/// \brief Return the optional template keyword and arguments info.
const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const {
return const_cast<CXXDependentScopeMemberExpr*>(this)
->getTemplateKWAndArgsInfo();
} }
CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base, CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
@ -3193,21 +3200,21 @@ public:
/// member name, if any. /// member name, if any.
SourceLocation getTemplateKeywordLoc() const { SourceLocation getTemplateKeywordLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation(); if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTemplateKWAndArgsInfo()->TemplateKWLoc; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
} }
/// \brief Retrieve the location of the left angle bracket starting the /// \brief Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the member name, if any. /// explicit template argument list following the member name, if any.
SourceLocation getLAngleLoc() const { SourceLocation getLAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation(); if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTemplateKWAndArgsInfo()->LAngleLoc; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
} }
/// \brief Retrieve the location of the right angle bracket ending the /// \brief Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the member name, if any. /// explicit template argument list following the member name, if any.
SourceLocation getRAngleLoc() const { SourceLocation getRAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation(); if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTemplateKWAndArgsInfo()->RAngleLoc; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
} }
/// Determines whether the member name was preceded by the template keyword. /// Determines whether the member name was preceded by the template keyword.
@ -3221,7 +3228,8 @@ public:
/// structure. /// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgs()) if (hasExplicitTemplateArgs())
getTemplateKWAndArgsInfo()->copyInto(List); getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
getTrailingObjects<TemplateArgumentLoc>(), List);
} }
/// \brief Retrieve the template arguments provided as part of this /// \brief Retrieve the template arguments provided as part of this
@ -3230,7 +3238,7 @@ public:
if (!hasExplicitTemplateArgs()) if (!hasExplicitTemplateArgs())
return nullptr; return nullptr;
return getTemplateKWAndArgsInfo()->getTemplateArgs(); return getTrailingObjects<TemplateArgumentLoc>();
} }
/// \brief Retrieve the number of template arguments provided as part of this /// \brief Retrieve the number of template arguments provided as part of this
@ -3239,7 +3247,7 @@ public:
if (!hasExplicitTemplateArgs()) if (!hasExplicitTemplateArgs())
return 0; return 0;
return getTemplateKWAndArgsInfo()->NumTemplateArgs; return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
} }
SourceLocation getLocStart() const LLVM_READONLY { SourceLocation getLocStart() const LLVM_READONLY {
@ -3248,8 +3256,8 @@ public:
if (getQualifier()) if (getQualifier())
return getQualifierLoc().getBeginLoc(); return getQualifierLoc().getBeginLoc();
return MemberNameInfo.getBeginLoc(); return MemberNameInfo.getBeginLoc();
} }
SourceLocation getLocEnd() const LLVM_READONLY { SourceLocation getLocEnd() const LLVM_READONLY {
if (hasExplicitTemplateArgs()) if (hasExplicitTemplateArgs())
return getRAngleLoc(); return getRAngleLoc();
@ -3267,6 +3275,7 @@ public:
return child_range(&Base, &Base + 1); return child_range(&Base, &Base + 1);
} }
friend TrailingObjects;
friend class ASTStmtReader; friend class ASTStmtReader;
friend class ASTStmtWriter; friend class ASTStmtWriter;
}; };
@ -3286,8 +3295,10 @@ public:
/// In the final AST, an explicit access always becomes a MemberExpr. /// In the final AST, an explicit access always becomes a MemberExpr.
/// An implicit access may become either a MemberExpr or a /// An implicit access may become either a MemberExpr or a
/// DeclRefExpr, depending on whether the member is static. /// DeclRefExpr, depending on whether the member is static.
class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) UnresolvedMemberExpr class UnresolvedMemberExpr final
: public OverloadExpr { : public OverloadExpr,
private llvm::TrailingObjects<
UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
/// \brief Whether this member expression used the '->' operator or /// \brief Whether this member expression used the '->' operator or
/// the '.' operator. /// the '.' operator.
bool IsArrow : 1; bool IsArrow : 1;
@ -3308,6 +3319,10 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) UnresolvedMemberExpr
/// \brief The location of the '->' or '.' operator. /// \brief The location of the '->' or '.' operator.
SourceLocation OperatorLoc; SourceLocation OperatorLoc;
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
return HasTemplateKWAndArgsInfo ? 1 : 0;
}
UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing, UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow, Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc, SourceLocation OperatorLoc,
@ -3321,6 +3336,8 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) UnresolvedMemberExpr
: OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false), : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
HasUnresolvedUsing(false), Base(nullptr) { } HasUnresolvedUsing(false), Base(nullptr) { }
friend TrailingObjects;
friend class OverloadExpr;
friend class ASTStmtReader; friend class ASTStmtReader;
public: public:
@ -3412,15 +3429,26 @@ public:
} }
}; };
inline ASTTemplateKWAndArgsInfo *OverloadExpr::getTemplateKWAndArgsInfo() { inline ASTTemplateKWAndArgsInfo *
OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
if (!HasTemplateKWAndArgsInfo) if (!HasTemplateKWAndArgsInfo)
return nullptr; return nullptr;
if (isa<UnresolvedLookupExpr>(this)) if (isa<UnresolvedLookupExpr>(this))
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>( return cast<UnresolvedLookupExpr>(this)
cast<UnresolvedLookupExpr>(this) + 1); ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
else else
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>( return cast<UnresolvedMemberExpr>(this)
cast<UnresolvedMemberExpr>(this) + 1); ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
}
inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
if (isa<UnresolvedLookupExpr>(this))
return cast<UnresolvedLookupExpr>(this)
->getTrailingObjects<TemplateArgumentLoc>();
else
return cast<UnresolvedMemberExpr>(this)
->getTrailingObjects<TemplateArgumentLoc>();
} }
/// \brief Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]). /// \brief Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).

View File

@ -595,18 +595,13 @@ public:
}; };
/// \brief Represents an explicit template argument list in C++, e.g., /// \brief Represents an explicit template argument list in C++, e.g.,
/// the "<int>" in "sort<int>". This is safe to be used inside an AST /// the "<int>" in "sort<int>".
/// node, in contrast with TemplateArgumentListInfo.
/// ///
/// This is currently very similar to ASTTemplateArgumentListInfo /// It is intended to be used as a trailing object on AST nodes, and
/// class, but a) has a extra member, TemplateKWLoc, and b) is /// as such, doesn't contain the array of TemplateArgumentLoc itself,
/// intended to be tacked on the end of some of the Expr classes, not /// but expects the containing object to also provide storage for
/// as a public interface. /// that.
struct ASTTemplateKWAndArgsInfo final struct LLVM_ALIGNAS(LLVM_PTR_SIZE) ASTTemplateKWAndArgsInfo {
: private llvm::TrailingObjects<ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
friend TrailingObjects;
/// \brief The source location of the left angle bracket ('<'). /// \brief The source location of the left angle bracket ('<').
SourceLocation LAngleLoc; SourceLocation LAngleLoc;
@ -622,30 +617,18 @@ struct ASTTemplateKWAndArgsInfo final
/// \brief The number of template arguments in TemplateArgs. /// \brief The number of template arguments in TemplateArgs.
unsigned NumTemplateArgs; unsigned NumTemplateArgs;
/// \brief Retrieve the template arguments
TemplateArgumentLoc *getTemplateArgs() {
return getTrailingObjects<TemplateArgumentLoc>();
}
/// \brief Retrieve the template arguments
const TemplateArgumentLoc *getTemplateArgs() const {
return getTrailingObjects<TemplateArgumentLoc>();
}
const TemplateArgumentLoc &operator[](unsigned I) const {
return getTemplateArgs()[I];
}
void initializeFrom(SourceLocation TemplateKWLoc,
const TemplateArgumentListInfo &List);
void initializeFrom(SourceLocation TemplateKWLoc, void initializeFrom(SourceLocation TemplateKWLoc,
const TemplateArgumentListInfo &List, const TemplateArgumentListInfo &List,
bool &Dependent, bool &InstantiationDependent, TemplateArgumentLoc *OutArgArray);
void initializeFrom(SourceLocation TemplateKWLoc,
const TemplateArgumentListInfo &List,
TemplateArgumentLoc *OutArgArray, bool &Dependent,
bool &InstantiationDependent,
bool &ContainsUnexpandedParameterPack); bool &ContainsUnexpandedParameterPack);
void initializeFrom(SourceLocation TemplateKWLoc); void initializeFrom(SourceLocation TemplateKWLoc);
void copyInto(TemplateArgumentListInfo &List) const; void copyInto(const TemplateArgumentLoc *ArgArray,
static std::size_t sizeFor(unsigned NumTemplateArgs); TemplateArgumentListInfo &List) const;
}; };
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,

View File

@ -331,7 +331,8 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) { D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) {
DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0; DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
if (QualifierLoc) { if (QualifierLoc) {
getInternalQualifierLoc() = QualifierLoc; new (getTrailingObjects<NestedNameSpecifierLoc>())
NestedNameSpecifierLoc(QualifierLoc);
auto *NNS = QualifierLoc.getNestedNameSpecifier(); auto *NNS = QualifierLoc.getNestedNameSpecifier();
if (NNS->isInstantiationDependent()) if (NNS->isInstantiationDependent())
ExprBits.InstantiationDependent = true; ExprBits.InstantiationDependent = true;
@ -340,7 +341,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
} }
DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0; DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0;
if (FoundD) if (FoundD)
getInternalFoundDecl() = FoundD; *getTrailingObjects<NamedDecl *>() = FoundD;
DeclRefExprBits.HasTemplateKWAndArgsInfo DeclRefExprBits.HasTemplateKWAndArgsInfo
= (TemplateArgs || TemplateKWLoc.isValid()) ? 1 : 0; = (TemplateArgs || TemplateKWLoc.isValid()) ? 1 : 0;
DeclRefExprBits.RefersToEnclosingVariableOrCapture = DeclRefExprBits.RefersToEnclosingVariableOrCapture =
@ -349,15 +350,15 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
bool Dependent = false; bool Dependent = false;
bool InstantiationDependent = false; bool InstantiationDependent = false;
bool ContainsUnexpandedParameterPack = false; bool ContainsUnexpandedParameterPack = false;
getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *TemplateArgs, getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
Dependent, TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
InstantiationDependent, Dependent, InstantiationDependent, ContainsUnexpandedParameterPack);
ContainsUnexpandedParameterPack);
assert(!Dependent && "built a DeclRefExpr with dependent template args"); assert(!Dependent && "built a DeclRefExpr with dependent template args");
ExprBits.InstantiationDependent |= InstantiationDependent; ExprBits.InstantiationDependent |= InstantiationDependent;
ExprBits.ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack; ExprBits.ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack;
} else if (TemplateKWLoc.isValid()) { } else if (TemplateKWLoc.isValid()) {
getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc);
} }
DeclRefExprBits.HadMultipleCandidates = 0; DeclRefExprBits.HadMultipleCandidates = 0;
@ -394,20 +395,13 @@ DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context,
if (D == FoundD) if (D == FoundD)
FoundD = nullptr; FoundD = nullptr;
std::size_t Size = sizeof(DeclRefExpr); bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
if (QualifierLoc) std::size_t Size =
Size += sizeof(NestedNameSpecifierLoc); totalSizeToAlloc<NestedNameSpecifierLoc, NamedDecl *,
if (FoundD) ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
Size += sizeof(NamedDecl *); QualifierLoc ? 1 : 0, FoundD ? 1 : 0,
if (TemplateArgs) { HasTemplateKWAndArgsInfo ? 1 : 0,
Size = llvm::RoundUpToAlignment(Size, TemplateArgs ? TemplateArgs->size() : 0);
llvm::alignOf<ASTTemplateKWAndArgsInfo>());
Size += ASTTemplateKWAndArgsInfo::sizeFor(TemplateArgs->size());
} else if (TemplateKWLoc.isValid()) {
Size = llvm::RoundUpToAlignment(Size,
llvm::alignOf<ASTTemplateKWAndArgsInfo>());
Size += ASTTemplateKWAndArgsInfo::sizeFor(0);
}
void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>()); void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
return new (Mem) DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D, return new (Mem) DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D,
@ -420,17 +414,12 @@ DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context,
bool HasFoundDecl, bool HasFoundDecl,
bool HasTemplateKWAndArgsInfo, bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) { unsigned NumTemplateArgs) {
std::size_t Size = sizeof(DeclRefExpr); assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
if (HasQualifier) std::size_t Size =
Size += sizeof(NestedNameSpecifierLoc); totalSizeToAlloc<NestedNameSpecifierLoc, NamedDecl *,
if (HasFoundDecl) ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
Size += sizeof(NamedDecl *); HasQualifier ? 1 : 0, HasFoundDecl ? 1 : 0, HasTemplateKWAndArgsInfo,
if (HasTemplateKWAndArgsInfo) { NumTemplateArgs);
Size = llvm::RoundUpToAlignment(Size,
llvm::alignOf<ASTTemplateKWAndArgsInfo>());
Size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs);
}
void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>()); void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
return new (Mem) DeclRefExpr(EmptyShell()); return new (Mem) DeclRefExpr(EmptyShell());
} }
@ -1419,18 +1408,17 @@ MemberExpr *MemberExpr::Create(
ValueDecl *memberdecl, DeclAccessPair founddecl, ValueDecl *memberdecl, DeclAccessPair founddecl,
DeclarationNameInfo nameinfo, const TemplateArgumentListInfo *targs, DeclarationNameInfo nameinfo, const TemplateArgumentListInfo *targs,
QualType ty, ExprValueKind vk, ExprObjectKind ok) { QualType ty, ExprValueKind vk, ExprObjectKind ok) {
std::size_t Size = sizeof(MemberExpr);
bool hasQualOrFound = (QualifierLoc || bool hasQualOrFound = (QualifierLoc ||
founddecl.getDecl() != memberdecl || founddecl.getDecl() != memberdecl ||
founddecl.getAccess() != memberdecl->getAccess()); founddecl.getAccess() != memberdecl->getAccess());
if (hasQualOrFound)
Size += sizeof(MemberNameQualifier);
if (targs) bool HasTemplateKWAndArgsInfo = targs || TemplateKWLoc.isValid();
Size += ASTTemplateKWAndArgsInfo::sizeFor(targs->size()); std::size_t Size =
else if (TemplateKWLoc.isValid()) totalSizeToAlloc<MemberExprNameQualifier, ASTTemplateKWAndArgsInfo,
Size += ASTTemplateKWAndArgsInfo::sizeFor(0); TemplateArgumentLoc>(hasQualOrFound ? 1 : 0,
HasTemplateKWAndArgsInfo ? 1 : 0,
targs ? targs->size() : 0);
void *Mem = C.Allocate(Size, llvm::alignOf<MemberExpr>()); void *Mem = C.Allocate(Size, llvm::alignOf<MemberExpr>());
MemberExpr *E = new (Mem) MemberExpr *E = new (Mem)
@ -1449,7 +1437,8 @@ MemberExpr *MemberExpr::Create(
E->HasQualifierOrFoundDecl = true; E->HasQualifierOrFoundDecl = true;
MemberNameQualifier *NQ = E->getMemberQualifier(); MemberExprNameQualifier *NQ =
E->getTrailingObjects<MemberExprNameQualifier>();
NQ->QualifierLoc = QualifierLoc; NQ->QualifierLoc = QualifierLoc;
NQ->FoundDecl = founddecl; NQ->FoundDecl = founddecl;
} }
@ -1460,14 +1449,14 @@ MemberExpr *MemberExpr::Create(
bool Dependent = false; bool Dependent = false;
bool InstantiationDependent = false; bool InstantiationDependent = false;
bool ContainsUnexpandedParameterPack = false; bool ContainsUnexpandedParameterPack = false;
E->getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *targs, E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
Dependent, TemplateKWLoc, *targs, E->getTrailingObjects<TemplateArgumentLoc>(),
InstantiationDependent, Dependent, InstantiationDependent, ContainsUnexpandedParameterPack);
ContainsUnexpandedParameterPack);
if (InstantiationDependent) if (InstantiationDependent)
E->setInstantiationDependent(true); E->setInstantiationDependent(true);
} else if (TemplateKWLoc.isValid()) { } else if (TemplateKWLoc.isValid()) {
E->getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc);
} }
return E; return E;
@ -4055,4 +4044,3 @@ QualType OMPArraySectionExpr::getBaseOriginalType(Expr *Base) {
} }
return OriginalTy; return OriginalTy;
} }

View File

@ -295,8 +295,11 @@ UnresolvedLookupExpr::Create(const ASTContext &C,
{ {
assert(Args || TemplateKWLoc.isValid()); assert(Args || TemplateKWLoc.isValid());
unsigned num_args = Args ? Args->size() : 0; unsigned num_args = Args ? Args->size() : 0;
void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) +
ASTTemplateKWAndArgsInfo::sizeFor(num_args)); std::size_t Size =
totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(1,
num_args);
void *Mem = C.Allocate(Size, llvm::alignOf<UnresolvedLookupExpr>());
return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
TemplateKWLoc, NameInfo, TemplateKWLoc, NameInfo,
ADL, /*Overload*/ true, Args, ADL, /*Overload*/ true, Args,
@ -307,11 +310,11 @@ UnresolvedLookupExpr *
UnresolvedLookupExpr::CreateEmpty(const ASTContext &C, UnresolvedLookupExpr::CreateEmpty(const ASTContext &C,
bool HasTemplateKWAndArgsInfo, bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) { unsigned NumTemplateArgs) {
std::size_t size = sizeof(UnresolvedLookupExpr); assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
if (HasTemplateKWAndArgsInfo) std::size_t Size =
size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = C.Allocate(size, llvm::alignOf<UnresolvedLookupExpr>()); void *Mem = C.Allocate(Size, llvm::alignOf<UnresolvedLookupExpr>());
UnresolvedLookupExpr *E = new (Mem) UnresolvedLookupExpr(EmptyShell()); UnresolvedLookupExpr *E = new (Mem) UnresolvedLookupExpr(EmptyShell());
E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo; E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
return E; return E;
@ -367,10 +370,9 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
bool Dependent = false; bool Dependent = false;
bool InstantiationDependent = false; bool InstantiationDependent = false;
bool ContainsUnexpandedParameterPack = false; bool ContainsUnexpandedParameterPack = false;
getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *TemplateArgs, getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(
Dependent, TemplateKWLoc, *TemplateArgs, getTrailingTemplateArgumentLoc(),
InstantiationDependent, Dependent, InstantiationDependent, ContainsUnexpandedParameterPack);
ContainsUnexpandedParameterPack);
if (Dependent) { if (Dependent) {
ExprBits.TypeDependent = true; ExprBits.TypeDependent = true;
@ -381,7 +383,7 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
if (ContainsUnexpandedParameterPack) if (ContainsUnexpandedParameterPack)
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
} else if (TemplateKWLoc.isValid()) { } else if (TemplateKWLoc.isValid()) {
getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc);
} }
if (isTypeDependent()) if (isTypeDependent())
@ -432,13 +434,13 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T,
bool InstantiationDependent = true; bool InstantiationDependent = true;
bool ContainsUnexpandedParameterPack bool ContainsUnexpandedParameterPack
= ExprBits.ContainsUnexpandedParameterPack; = ExprBits.ContainsUnexpandedParameterPack;
getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *Args, getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
Dependent, TemplateKWLoc, *Args, getTrailingObjects<TemplateArgumentLoc>(),
InstantiationDependent, Dependent, InstantiationDependent, ContainsUnexpandedParameterPack);
ContainsUnexpandedParameterPack);
ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
} else if (TemplateKWLoc.isValid()) { } else if (TemplateKWLoc.isValid()) {
getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc);
} }
} }
@ -449,12 +451,11 @@ DependentScopeDeclRefExpr::Create(const ASTContext &C,
const DeclarationNameInfo &NameInfo, const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *Args) { const TemplateArgumentListInfo *Args) {
assert(QualifierLoc && "should be created for dependent qualifiers"); assert(QualifierLoc && "should be created for dependent qualifiers");
std::size_t size = sizeof(DependentScopeDeclRefExpr); bool HasTemplateKWAndArgsInfo = Args || TemplateKWLoc.isValid();
if (Args) std::size_t Size =
size += ASTTemplateKWAndArgsInfo::sizeFor(Args->size()); totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
else if (TemplateKWLoc.isValid()) HasTemplateKWAndArgsInfo, Args ? Args->size() : 0);
size += ASTTemplateKWAndArgsInfo::sizeFor(0); void *Mem = C.Allocate(Size);
void *Mem = C.Allocate(size);
return new (Mem) DependentScopeDeclRefExpr(C.DependentTy, QualifierLoc, return new (Mem) DependentScopeDeclRefExpr(C.DependentTy, QualifierLoc,
TemplateKWLoc, NameInfo, Args); TemplateKWLoc, NameInfo, Args);
} }
@ -463,10 +464,11 @@ DependentScopeDeclRefExpr *
DependentScopeDeclRefExpr::CreateEmpty(const ASTContext &C, DependentScopeDeclRefExpr::CreateEmpty(const ASTContext &C,
bool HasTemplateKWAndArgsInfo, bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) { unsigned NumTemplateArgs) {
std::size_t size = sizeof(DependentScopeDeclRefExpr); assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
if (HasTemplateKWAndArgsInfo) std::size_t Size =
size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
void *Mem = C.Allocate(size); HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = C.Allocate(Size);
DependentScopeDeclRefExpr *E DependentScopeDeclRefExpr *E
= new (Mem) DependentScopeDeclRefExpr(QualType(), NestedNameSpecifierLoc(), = new (Mem) DependentScopeDeclRefExpr(QualType(), NestedNameSpecifierLoc(),
SourceLocation(), SourceLocation(),
@ -1195,63 +1197,40 @@ SourceLocation CXXUnresolvedConstructExpr::getLocStart() const {
return Type->getTypeLoc().getBeginLoc(); return Type->getTypeLoc().getBeginLoc();
} }
CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(const ASTContext &C, CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
Expr *Base, QualType BaseType, const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow,
bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
SourceLocation OperatorLoc, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
NestedNameSpecifierLoc QualifierLoc, DeclarationNameInfo MemberNameInfo,
SourceLocation TemplateKWLoc, const TemplateArgumentListInfo *TemplateArgs)
NamedDecl *FirstQualifierFoundInScope, : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, VK_LValue,
DeclarationNameInfo MemberNameInfo, OK_Ordinary, true, true, true,
const TemplateArgumentListInfo *TemplateArgs) ((Base && Base->containsUnexpandedParameterPack()) ||
: Expr(CXXDependentScopeMemberExprClass, C.DependentTy, (QualifierLoc &&
VK_LValue, OK_Ordinary, true, true, true, QualifierLoc.getNestedNameSpecifier()
((Base && Base->containsUnexpandedParameterPack()) || ->containsUnexpandedParameterPack()) ||
(QualifierLoc && MemberNameInfo.containsUnexpandedParameterPack())),
QualifierLoc.getNestedNameSpecifier() Base(Base), BaseType(BaseType), IsArrow(IsArrow),
->containsUnexpandedParameterPack()) || HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
MemberNameInfo.containsUnexpandedParameterPack())), TemplateKWLoc.isValid()),
Base(Base), BaseType(BaseType), IsArrow(IsArrow), OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc),
HasTemplateKWAndArgsInfo(TemplateArgs != nullptr || FirstQualifierFoundInScope(FirstQualifierFoundInScope),
TemplateKWLoc.isValid()), MemberNameInfo(MemberNameInfo) {
OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc),
FirstQualifierFoundInScope(FirstQualifierFoundInScope),
MemberNameInfo(MemberNameInfo) {
if (TemplateArgs) { if (TemplateArgs) {
bool Dependent = true; bool Dependent = true;
bool InstantiationDependent = true; bool InstantiationDependent = true;
bool ContainsUnexpandedParameterPack = false; bool ContainsUnexpandedParameterPack = false;
getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *TemplateArgs, getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
Dependent, TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
InstantiationDependent, Dependent, InstantiationDependent, ContainsUnexpandedParameterPack);
ContainsUnexpandedParameterPack);
if (ContainsUnexpandedParameterPack) if (ContainsUnexpandedParameterPack)
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
} else if (TemplateKWLoc.isValid()) { } else if (TemplateKWLoc.isValid()) {
getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); getTrailingObjects<ASTTemplateKWAndArgsInfo>()->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 *
CXXDependentScopeMemberExpr::Create(const ASTContext &C, CXXDependentScopeMemberExpr::Create(const ASTContext &C,
Expr *Base, QualType BaseType, bool IsArrow, Expr *Base, QualType BaseType, bool IsArrow,
@ -1261,18 +1240,13 @@ CXXDependentScopeMemberExpr::Create(const ASTContext &C,
NamedDecl *FirstQualifierFoundInScope, NamedDecl *FirstQualifierFoundInScope,
DeclarationNameInfo MemberNameInfo, DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs) { const TemplateArgumentListInfo *TemplateArgs) {
if (!TemplateArgs && !TemplateKWLoc.isValid()) bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType,
IsArrow, OperatorLoc,
QualifierLoc,
FirstQualifierFoundInScope,
MemberNameInfo);
unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0; unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0;
std::size_t size = sizeof(CXXDependentScopeMemberExpr) std::size_t Size =
+ ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = C.Allocate(size, llvm::alignOf<CXXDependentScopeMemberExpr>()); void *Mem = C.Allocate(Size, llvm::alignOf<CXXDependentScopeMemberExpr>());
return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType, return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType,
IsArrow, OperatorLoc, IsArrow, OperatorLoc,
QualifierLoc, QualifierLoc,
@ -1285,22 +1259,18 @@ CXXDependentScopeMemberExpr *
CXXDependentScopeMemberExpr::CreateEmpty(const ASTContext &C, CXXDependentScopeMemberExpr::CreateEmpty(const ASTContext &C,
bool HasTemplateKWAndArgsInfo, bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) { unsigned NumTemplateArgs) {
if (!HasTemplateKWAndArgsInfo) assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
return new (C) CXXDependentScopeMemberExpr(C, nullptr, QualType(), std::size_t Size =
0, SourceLocation(), totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
NestedNameSpecifierLoc(), HasTemplateKWAndArgsInfo, NumTemplateArgs);
nullptr, DeclarationNameInfo()); void *Mem = C.Allocate(Size, llvm::alignOf<CXXDependentScopeMemberExpr>());
std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs);
void *Mem = C.Allocate(size, llvm::alignOf<CXXDependentScopeMemberExpr>());
CXXDependentScopeMemberExpr *E CXXDependentScopeMemberExpr *E
= new (Mem) CXXDependentScopeMemberExpr(C, nullptr, QualType(), = new (Mem) CXXDependentScopeMemberExpr(C, nullptr, QualType(),
0, SourceLocation(), 0, SourceLocation(),
NestedNameSpecifierLoc(), NestedNameSpecifierLoc(),
SourceLocation(), nullptr, SourceLocation(), nullptr,
DeclarationNameInfo(), nullptr); DeclarationNameInfo(), nullptr);
E->HasTemplateKWAndArgsInfo = true; E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
return E; return E;
} }
@ -1365,38 +1335,34 @@ bool UnresolvedMemberExpr::isImplicitAccess() const {
return cast<Expr>(Base)->isImplicitCXXThis(); return cast<Expr>(Base)->isImplicitCXXThis();
} }
UnresolvedMemberExpr * UnresolvedMemberExpr *UnresolvedMemberExpr::Create(
UnresolvedMemberExpr::Create(const ASTContext &C, bool HasUnresolvedUsing, const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType,
Expr *Base, QualType BaseType, bool IsArrow, bool IsArrow, SourceLocation OperatorLoc,
SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &MemberNameInfo,
SourceLocation TemplateKWLoc, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
const DeclarationNameInfo &MemberNameInfo, UnresolvedSetIterator End) {
const TemplateArgumentListInfo *TemplateArgs, bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
UnresolvedSetIterator Begin, std::size_t Size =
UnresolvedSetIterator End) { totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
std::size_t size = sizeof(UnresolvedMemberExpr); HasTemplateKWAndArgsInfo, TemplateArgs ? TemplateArgs->size() : 0);
if (TemplateArgs)
size += ASTTemplateKWAndArgsInfo::sizeFor(TemplateArgs->size());
else if (TemplateKWLoc.isValid())
size += ASTTemplateKWAndArgsInfo::sizeFor(0);
void *Mem = C.Allocate(size, llvm::alignOf<UnresolvedMemberExpr>()); void *Mem = C.Allocate(Size, llvm::alignOf<UnresolvedMemberExpr>());
return new (Mem) UnresolvedMemberExpr(C, return new (Mem) UnresolvedMemberExpr(
HasUnresolvedUsing, Base, BaseType, C, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc,
IsArrow, OperatorLoc, QualifierLoc, TemplateKWLoc, TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End);
MemberNameInfo, TemplateArgs, Begin, End);
} }
UnresolvedMemberExpr * UnresolvedMemberExpr *
UnresolvedMemberExpr::CreateEmpty(const ASTContext &C, UnresolvedMemberExpr::CreateEmpty(const ASTContext &C,
bool HasTemplateKWAndArgsInfo, bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) { unsigned NumTemplateArgs) {
std::size_t size = sizeof(UnresolvedMemberExpr); assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
if (HasTemplateKWAndArgsInfo) std::size_t Size =
size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = C.Allocate(size, llvm::alignOf<UnresolvedMemberExpr>()); void *Mem = C.Allocate(Size, llvm::alignOf<UnresolvedMemberExpr>());
UnresolvedMemberExpr *E = new (Mem) UnresolvedMemberExpr(EmptyShell()); UnresolvedMemberExpr *E = new (Mem) UnresolvedMemberExpr(EmptyShell());
E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo; E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
return E; return E;

View File

@ -537,15 +537,15 @@ ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
} }
void ASTTemplateKWAndArgsInfo::initializeFrom( void ASTTemplateKWAndArgsInfo::initializeFrom(
SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info) { SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
TemplateArgumentLoc *OutArgArray) {
this->TemplateKWLoc = TemplateKWLoc; this->TemplateKWLoc = TemplateKWLoc;
LAngleLoc = Info.getLAngleLoc(); LAngleLoc = Info.getLAngleLoc();
RAngleLoc = Info.getRAngleLoc(); RAngleLoc = Info.getRAngleLoc();
NumTemplateArgs = Info.size(); NumTemplateArgs = Info.size();
TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
for (unsigned i = 0; i != NumTemplateArgs; ++i) for (unsigned i = 0; i != NumTemplateArgs; ++i)
new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
} }
void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
@ -558,14 +558,13 @@ void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
void ASTTemplateKWAndArgsInfo::initializeFrom( void ASTTemplateKWAndArgsInfo::initializeFrom(
SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
bool &Dependent, bool &InstantiationDependent, TemplateArgumentLoc *OutArgArray, bool &Dependent,
bool &ContainsUnexpandedParameterPack) { bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack) {
this->TemplateKWLoc = TemplateKWLoc; this->TemplateKWLoc = TemplateKWLoc;
LAngleLoc = Info.getLAngleLoc(); LAngleLoc = Info.getLAngleLoc();
RAngleLoc = Info.getRAngleLoc(); RAngleLoc = Info.getRAngleLoc();
NumTemplateArgs = Info.size(); NumTemplateArgs = Info.size();
TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
for (unsigned i = 0; i != NumTemplateArgs; ++i) { for (unsigned i = 0; i != NumTemplateArgs; ++i) {
Dependent = Dependent || Info[i].getArgument().isDependent(); Dependent = Dependent || Info[i].getArgument().isDependent();
InstantiationDependent = InstantiationDependent || InstantiationDependent = InstantiationDependent ||
@ -574,17 +573,14 @@ void ASTTemplateKWAndArgsInfo::initializeFrom(
ContainsUnexpandedParameterPack || ContainsUnexpandedParameterPack ||
Info[i].getArgument().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.setLAngleLoc(LAngleLoc);
Info.setRAngleLoc(RAngleLoc); Info.setRAngleLoc(RAngleLoc);
for (unsigned I = 0; I != NumTemplateArgs; ++I) for (unsigned I = 0; I != NumTemplateArgs; ++I)
Info.addArgument(getTemplateArgs()[I]); Info.addArgument(ArgArray[I]);
}
std::size_t ASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) {
return totalSizeToAlloc<TemplateArgumentLoc>(NumTemplateArgs);
} }

View File

@ -93,6 +93,7 @@ namespace clang {
/// \brief Read and initialize a ExplicitTemplateArgumentList structure. /// \brief Read and initialize a ExplicitTemplateArgumentList structure.
void ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, void ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args,
TemplateArgumentLoc *ArgsLocArray,
unsigned NumTemplateArgs); unsigned NumTemplateArgs);
/// \brief Read and initialize a ExplicitTemplateArgumentList structure. /// \brief Read and initialize a ExplicitTemplateArgumentList structure.
void ReadExplicitTemplateArgumentList(ASTTemplateArgumentListInfo &ArgList, void ReadExplicitTemplateArgumentList(ASTTemplateArgumentListInfo &ArgList,
@ -105,9 +106,9 @@ namespace clang {
}; };
} }
void ASTStmtReader:: void ASTStmtReader::ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args,
ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, TemplateArgumentLoc *ArgsLocArray,
unsigned NumTemplateArgs) { unsigned NumTemplateArgs) {
SourceLocation TemplateKWLoc = ReadSourceLocation(Record, Idx); SourceLocation TemplateKWLoc = ReadSourceLocation(Record, Idx);
TemplateArgumentListInfo ArgInfo; TemplateArgumentListInfo ArgInfo;
ArgInfo.setLAngleLoc(ReadSourceLocation(Record, Idx)); ArgInfo.setLAngleLoc(ReadSourceLocation(Record, Idx));
@ -115,7 +116,7 @@ ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args,
for (unsigned i = 0; i != NumTemplateArgs; ++i) for (unsigned i = 0; i != NumTemplateArgs; ++i)
ArgInfo.addArgument( ArgInfo.addArgument(
Reader.ReadTemplateArgumentLoc(F, Record, Idx)); Reader.ReadTemplateArgumentLoc(F, Record, Idx));
Args.initializeFrom(TemplateKWLoc, ArgInfo); Args.initializeFrom(TemplateKWLoc, ArgInfo, ArgsLocArray);
} }
void ASTStmtReader::VisitStmt(Stmt *S) { void ASTStmtReader::VisitStmt(Stmt *S) {
@ -459,15 +460,17 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
NumTemplateArgs = Record[Idx++]; NumTemplateArgs = Record[Idx++];
if (E->hasQualifier()) if (E->hasQualifier())
E->getInternalQualifierLoc() new (E->getTrailingObjects<NestedNameSpecifierLoc>())
= Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); NestedNameSpecifierLoc(
Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
if (E->hasFoundDecl()) if (E->hasFoundDecl())
E->getInternalFoundDecl() = ReadDeclAs<NamedDecl>(Record, Idx); *E->getTrailingObjects<NamedDecl *>() = ReadDeclAs<NamedDecl>(Record, Idx);
if (E->hasTemplateKWAndArgsInfo()) if (E->hasTemplateKWAndArgsInfo())
ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(), ReadTemplateKWAndArgsInfo(
NumTemplateArgs); *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
E->getTrailingObjects<TemplateArgumentLoc>(), NumTemplateArgs);
E->setDecl(ReadDeclAs<ValueDecl>(Record, Idx)); E->setDecl(ReadDeclAs<ValueDecl>(Record, Idx));
E->setLocation(ReadSourceLocation(Record, Idx)); E->setLocation(ReadSourceLocation(Record, Idx));
@ -1453,8 +1456,10 @@ ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
VisitExpr(E); VisitExpr(E);
if (Record[Idx++]) // HasTemplateKWAndArgsInfo if (Record[Idx++]) // HasTemplateKWAndArgsInfo
ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(), ReadTemplateKWAndArgsInfo(
/*NumTemplateArgs=*/Record[Idx++]); *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
E->getTrailingObjects<TemplateArgumentLoc>(),
/*NumTemplateArgs=*/Record[Idx++]);
E->Base = Reader.ReadSubExpr(); E->Base = Reader.ReadSubExpr();
E->BaseType = Reader.readType(F, Record, Idx); E->BaseType = Reader.readType(F, Record, Idx);
@ -1470,8 +1475,10 @@ ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
VisitExpr(E); VisitExpr(E);
if (Record[Idx++]) // HasTemplateKWAndArgsInfo if (Record[Idx++]) // HasTemplateKWAndArgsInfo
ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(), ReadTemplateKWAndArgsInfo(
/*NumTemplateArgs=*/Record[Idx++]); *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
E->getTrailingObjects<TemplateArgumentLoc>(),
/*NumTemplateArgs=*/Record[Idx++]);
E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
ReadDeclarationNameInfo(E->NameInfo, Record, Idx); ReadDeclarationNameInfo(E->NameInfo, Record, Idx);
@ -1493,7 +1500,8 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
VisitExpr(E); VisitExpr(E);
if (Record[Idx++]) // HasTemplateKWAndArgsInfo if (Record[Idx++]) // HasTemplateKWAndArgsInfo
ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(), ReadTemplateKWAndArgsInfo(*E->getTrailingASTTemplateKWAndArgsInfo(),
E->getTrailingTemplateArgumentLoc(),
/*NumTemplateArgs=*/Record[Idx++]); /*NumTemplateArgs=*/Record[Idx++]);
unsigned NumDecls = Record[Idx++]; unsigned NumDecls = Record[Idx++];

View File

@ -40,7 +40,8 @@ namespace clang {
ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record) ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
: Writer(Writer), Record(Record) { } : Writer(Writer), Record(Record) { }
void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args); void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &ArgInfo,
const TemplateArgumentLoc *Args);
void VisitStmt(Stmt *S); void VisitStmt(Stmt *S);
#define STMT(Type, Base) \ #define STMT(Type, Base) \
@ -49,13 +50,13 @@ namespace clang {
}; };
} }
void ASTStmtWriter:: void ASTStmtWriter::AddTemplateKWAndArgsInfo(
AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args) { const ASTTemplateKWAndArgsInfo &ArgInfo, const TemplateArgumentLoc *Args) {
Writer.AddSourceLocation(Args.TemplateKWLoc, Record); Writer.AddSourceLocation(ArgInfo.TemplateKWLoc, Record);
Writer.AddSourceLocation(Args.LAngleLoc, Record); Writer.AddSourceLocation(ArgInfo.LAngleLoc, Record);
Writer.AddSourceLocation(Args.RAngleLoc, Record); Writer.AddSourceLocation(ArgInfo.RAngleLoc, Record);
for (unsigned i=0; i != Args.NumTemplateArgs; ++i) for (unsigned i = 0; i != ArgInfo.NumTemplateArgs; ++i)
Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record); Writer.AddTemplateArgumentLoc(Args[i], Record);
} }
void ASTStmtWriter::VisitStmt(Stmt *S) { void ASTStmtWriter::VisitStmt(Stmt *S) {
@ -386,7 +387,8 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
Writer.AddDeclRef(E->getFoundDecl(), Record); Writer.AddDeclRef(E->getFoundDecl(), Record);
if (E->hasTemplateKWAndArgsInfo()) if (E->hasTemplateKWAndArgsInfo())
AddTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo()); AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
E->getTrailingObjects<TemplateArgumentLoc>());
Writer.AddDeclRef(E->getDecl(), Record); Writer.AddDeclRef(E->getDecl(), Record);
Writer.AddSourceLocation(E->getLocation(), Record); Writer.AddSourceLocation(E->getLocation(), Record);
@ -1440,9 +1442,11 @@ ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
Record.push_back(E->HasTemplateKWAndArgsInfo); Record.push_back(E->HasTemplateKWAndArgsInfo);
if (E->HasTemplateKWAndArgsInfo) { if (E->HasTemplateKWAndArgsInfo) {
const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo(); const ASTTemplateKWAndArgsInfo &ArgInfo =
Record.push_back(Args.NumTemplateArgs); *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
AddTemplateKWAndArgsInfo(Args); Record.push_back(ArgInfo.NumTemplateArgs);
AddTemplateKWAndArgsInfo(ArgInfo,
E->getTrailingObjects<TemplateArgumentLoc>());
} }
if (!E->isImplicitAccess()) if (!E->isImplicitAccess())
@ -1467,9 +1471,11 @@ ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
Record.push_back(E->HasTemplateKWAndArgsInfo); Record.push_back(E->HasTemplateKWAndArgsInfo);
if (E->HasTemplateKWAndArgsInfo) { if (E->HasTemplateKWAndArgsInfo) {
const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo(); const ASTTemplateKWAndArgsInfo &ArgInfo =
Record.push_back(Args.NumTemplateArgs); *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
AddTemplateKWAndArgsInfo(Args); Record.push_back(ArgInfo.NumTemplateArgs);
AddTemplateKWAndArgsInfo(ArgInfo,
E->getTrailingObjects<TemplateArgumentLoc>());
} }
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
@ -1498,9 +1504,10 @@ void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
Record.push_back(E->HasTemplateKWAndArgsInfo); Record.push_back(E->HasTemplateKWAndArgsInfo);
if (E->HasTemplateKWAndArgsInfo) { if (E->HasTemplateKWAndArgsInfo) {
const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo(); const ASTTemplateKWAndArgsInfo &ArgInfo =
Record.push_back(Args.NumTemplateArgs); *E->getTrailingASTTemplateKWAndArgsInfo();
AddTemplateKWAndArgsInfo(Args); Record.push_back(ArgInfo.NumTemplateArgs);
AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
} }
Record.push_back(E->getNumDecls()); Record.push_back(E->getNumDecls());