[AST] Store the results in OverloadExpr in a trailing array

Use the newly available space in the bit-fields of Stmt to pack
OverloadExpr, UnresolvedLookupExpr and UnresolvedMemberExpr.

Additionally store the results in the overload set in a trailing array.
This saves 1 pointer + 8 bytes per UnresolvedLookupExpr and
UnresolvedMemberExpr.

Differential Revision: https://reviews.llvm.org/D56368

Reviewed By: rjmccall

llvm-svn: 350732
This commit is contained in:
Bruno Ricci 2019-01-09 15:43:19 +00:00
parent 59e916c214
commit d7628d9993
5 changed files with 387 additions and 274 deletions

View File

@ -2658,58 +2658,54 @@ public:
/// A reference to an overloaded function set, either an
/// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr.
class OverloadExpr : public Expr {
friend class ASTStmtReader;
friend class ASTStmtWriter;
/// The common name of these declarations.
DeclarationNameInfo NameInfo;
/// The nested-name-specifier that qualifies the name, if any.
NestedNameSpecifierLoc QualifierLoc;
/// The results. These are undesugared, which is to say, they may
/// include UsingShadowDecls. Access is relative to the naming
/// class.
// FIXME: Allocate this data after the OverloadExpr subclass.
DeclAccessPair *Results = nullptr;
unsigned NumResults = 0;
protected:
/// Whether the name includes info for explicit template
/// keyword and arguments.
bool HasTemplateKWAndArgsInfo = false;
OverloadExpr(StmtClass K, const ASTContext &C,
OverloadExpr(StmtClass SC, const ASTContext &Context,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End,
bool KnownDependent,
bool KnownInstantiationDependent,
bool KnownDependent, bool KnownInstantiationDependent,
bool KnownContainsUnexpandedParameterPack);
OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty) {}
/// Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *
getTrailingASTTemplateKWAndArgsInfo(); // defined far below.
OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults,
bool HasTemplateKWAndArgsInfo);
/// Return the results. Defined after UnresolvedMemberExpr.
inline DeclAccessPair *getTrailingResults();
const DeclAccessPair *getTrailingResults() const {
return const_cast<OverloadExpr *>(this)->getTrailingResults();
}
/// Return the optional template keyword and arguments info.
/// Defined after UnresolvedMemberExpr.
inline ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo();
const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const {
return const_cast<OverloadExpr *>(this)
->getTrailingASTTemplateKWAndArgsInfo();
}
/// Return the optional template arguments.
TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below
/// Return the optional template arguments. Defined after
/// UnresolvedMemberExpr.
inline TemplateArgumentLoc *getTrailingTemplateArgumentLoc();
const TemplateArgumentLoc *getTrailingTemplateArgumentLoc() const {
return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc();
}
void initializeResults(const ASTContext &C,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End);
bool hasTemplateKWAndArgsInfo() const {
return OverloadExprBits.HasTemplateKWAndArgsInfo;
}
public:
friend class ASTStmtReader;
friend class ASTStmtWriter;
struct FindResult {
OverloadExpr *Expression;
bool IsAddressOfOperand;
@ -2745,20 +2741,26 @@ public:
}
/// Gets the naming class of this lookup, if any.
CXXRecordDecl *getNamingClass() const;
/// Defined after UnresolvedMemberExpr.
inline CXXRecordDecl *getNamingClass();
const CXXRecordDecl *getNamingClass() const {
return const_cast<OverloadExpr *>(this)->getNamingClass();
}
using decls_iterator = UnresolvedSetImpl::iterator;
decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); }
decls_iterator decls_begin() const {
return UnresolvedSetIterator(getTrailingResults());
}
decls_iterator decls_end() const {
return UnresolvedSetIterator(Results + NumResults);
return UnresolvedSetIterator(getTrailingResults() + getNumDecls());
}
llvm::iterator_range<decls_iterator> decls() const {
return llvm::make_range(decls_begin(), decls_end());
}
/// Gets the number of declarations in the unresolved set.
unsigned getNumDecls() const { return NumResults; }
unsigned getNumDecls() const { return OverloadExprBits.NumResults; }
/// Gets the full name info.
const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
@ -2781,21 +2783,24 @@ public:
/// Retrieve the location of the template keyword preceding
/// this name, if any.
SourceLocation getTemplateKeywordLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
if (!hasTemplateKWAndArgsInfo())
return SourceLocation();
return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc;
}
/// 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();
if (!hasTemplateKWAndArgsInfo())
return SourceLocation();
return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc;
}
/// 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();
if (!hasTemplateKWAndArgsInfo())
return SourceLocation();
return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc;
}
@ -2847,86 +2852,82 @@ public:
/// members and therefore appear only in UnresolvedMemberLookupExprs.
class UnresolvedLookupExpr final
: public OverloadExpr,
private llvm::TrailingObjects<
UnresolvedLookupExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
private llvm::TrailingObjects<UnresolvedLookupExpr, DeclAccessPair,
ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
friend class ASTStmtReader;
friend class OverloadExpr;
friend TrailingObjects;
/// True if these lookup results should be extended by
/// argument-dependent lookup if this is the operand of a function
/// call.
bool RequiresADL = false;
/// True if these lookup results are overloaded. This is pretty
/// trivially rederivable if we urgently need to kill this field.
bool Overloaded = false;
/// The naming class (C++ [class.access.base]p5) of the lookup, if
/// any. This can generally be recalculated from the context chain,
/// but that can be fairly expensive for unqualified lookups. If we
/// want to improve memory use here, this could go in a union
/// against the qualified-lookup bits.
CXXRecordDecl *NamingClass = nullptr;
/// but that can be fairly expensive for unqualified lookups.
CXXRecordDecl *NamingClass;
UnresolvedLookupExpr(const ASTContext &C,
CXXRecordDecl *NamingClass,
// UnresolvedLookupExpr is followed by several trailing objects.
// They are in order:
//
// * An array of getNumResults() DeclAccessPair for the results. These are
// undesugared, which is to say, they may include UsingShadowDecls.
// Access is relative to the naming class.
//
// * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
// template keyword and arguments. Present if and only if
// hasTemplateKWAndArgsInfo().
//
// * An array of getNumTemplateArgs() TemplateArgumentLoc containing
// location information for the explicitly specified template arguments.
UnresolvedLookupExpr(const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
bool RequiresADL, bool Overloaded,
const DeclarationNameInfo &NameInfo, bool RequiresADL,
bool Overloaded,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End)
: OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc,
NameInfo, TemplateArgs, Begin, End, false, false, false),
RequiresADL(RequiresADL),
Overloaded(Overloaded), NamingClass(NamingClass) {}
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
UnresolvedLookupExpr(EmptyShell Empty)
: OverloadExpr(UnresolvedLookupExprClass, Empty) {}
UnresolvedLookupExpr(EmptyShell Empty, unsigned NumResults,
bool HasTemplateKWAndArgsInfo);
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
return HasTemplateKWAndArgsInfo ? 1 : 0;
unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const {
return getNumDecls();
}
unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
return hasTemplateKWAndArgsInfo();
}
public:
static UnresolvedLookupExpr *Create(const ASTContext &C,
CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
bool ADL, bool Overloaded,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End) {
return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
SourceLocation(), NameInfo,
ADL, Overloaded, nullptr, Begin, End);
}
static UnresolvedLookupExpr *
Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
static UnresolvedLookupExpr *Create(const ASTContext &C,
CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
bool ADL,
const TemplateArgumentListInfo *Args,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End);
static UnresolvedLookupExpr *
Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo, bool RequiresADL,
const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
UnresolvedSetIterator End);
static UnresolvedLookupExpr *CreateEmpty(const ASTContext &C,
static UnresolvedLookupExpr *CreateEmpty(const ASTContext &Context,
unsigned NumResults,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);
/// True if this declaration should be extended by
/// argument-dependent lookup.
bool requiresADL() const { return RequiresADL; }
bool requiresADL() const { return UnresolvedLookupExprBits.RequiresADL; }
/// True if this lookup is overloaded.
bool isOverloaded() const { return Overloaded; }
bool isOverloaded() const { return UnresolvedLookupExprBits.Overloaded; }
/// Gets the 'naming class' (in the sense of C++0x
/// [class.access.base]p5) of the lookup. This is the scope
/// that was looked in to find these results.
CXXRecordDecl *getNamingClass() const { return NamingClass; }
CXXRecordDecl *getNamingClass() { return NamingClass; }
const CXXRecordDecl *getNamingClass() const { return NamingClass; }
SourceLocation getBeginLoc() const LLVM_READONLY {
if (NestedNameSpecifierLoc l = getQualifierLoc())
@ -3561,25 +3562,18 @@ public:
/// DeclRefExpr, depending on whether the member is static.
class UnresolvedMemberExpr final
: public OverloadExpr,
private llvm::TrailingObjects<
UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
private llvm::TrailingObjects<UnresolvedMemberExpr, DeclAccessPair,
ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
friend class ASTStmtReader;
friend class OverloadExpr;
friend TrailingObjects;
/// Whether this member expression used the '->' operator or
/// the '.' operator.
bool IsArrow : 1;
/// Whether the lookup results contain an unresolved using
/// declaration.
bool HasUnresolvedUsing : 1;
/// The expression for the base pointer or class reference,
/// e.g., the \c x in x.f.
///
/// This can be null if this is an 'unbased' member expression.
Stmt *Base = nullptr;
Stmt *Base;
/// The type of the base expression; never null.
QualType BaseType;
@ -3587,7 +3581,21 @@ class UnresolvedMemberExpr final
/// The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing,
// UnresolvedMemberExpr is followed by several trailing objects.
// They are in order:
//
// * An array of getNumResults() DeclAccessPair for the results. These are
// undesugared, which is to say, they may include UsingShadowDecls.
// Access is relative to the naming class.
//
// * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
// template keyword and arguments. Present if and only if
// hasTemplateKWAndArgsInfo().
//
// * An array of getNumTemplateArgs() TemplateArgumentLoc containing
// location information for the explicitly specified template arguments.
UnresolvedMemberExpr(const ASTContext &Context, bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifierLoc QualifierLoc,
@ -3596,28 +3604,30 @@ class UnresolvedMemberExpr final
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
UnresolvedMemberExpr(EmptyShell Empty)
: OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
HasUnresolvedUsing(false) {}
UnresolvedMemberExpr(EmptyShell Empty, unsigned NumResults,
bool HasTemplateKWAndArgsInfo);
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
return HasTemplateKWAndArgsInfo ? 1 : 0;
unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const {
return getNumDecls();
}
unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
return hasTemplateKWAndArgsInfo();
}
public:
static UnresolvedMemberExpr *
Create(const ASTContext &C, bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
Create(const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
static UnresolvedMemberExpr *
CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);
static UnresolvedMemberExpr *CreateEmpty(const ASTContext &Context,
unsigned NumResults,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);
/// True if this is an implicit access, i.e., one in which the
/// member being accessed was not written in the source.
@ -3640,32 +3650,36 @@ public:
/// Determine whether the lookup results contain an unresolved using
/// declaration.
bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
bool hasUnresolvedUsing() const {
return UnresolvedMemberExprBits.HasUnresolvedUsing;
}
/// Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
bool isArrow() const { return IsArrow; }
bool isArrow() const { return UnresolvedMemberExprBits.IsArrow; }
/// Retrieve the location of the '->' or '.' operator.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
/// Retrieve the naming class of this lookup.
CXXRecordDecl *getNamingClass() const;
CXXRecordDecl *getNamingClass();
const CXXRecordDecl *getNamingClass() const {
return const_cast<UnresolvedMemberExpr *>(this)->getNamingClass();
}
/// Retrieve the full name info for the member that this expression
/// refers to.
const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
/// Retrieve the name of the member that this expression
/// refers to.
/// Retrieve the name of the member that this expression refers to.
DeclarationName getMemberName() const { return getName(); }
// Retrieve the location of the name of the member that this
// expression refers to.
/// Retrieve the location of the name of the member that this
/// expression refers to.
SourceLocation getMemberLoc() const { return getNameLoc(); }
// Return the preferred location (the member name) for the arrow when
// diagnosing a problem with this expression.
/// Return the preferred location (the member name) for the arrow when
/// diagnosing a problem with this expression.
SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); }
SourceLocation getBeginLoc() const LLVM_READONLY {
@ -3694,26 +3708,33 @@ public:
}
};
inline ASTTemplateKWAndArgsInfo *
OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
if (!HasTemplateKWAndArgsInfo)
return nullptr;
if (isa<UnresolvedLookupExpr>(this))
return cast<UnresolvedLookupExpr>(this)
->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
else
return cast<UnresolvedMemberExpr>(this)
->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
DeclAccessPair *OverloadExpr::getTrailingResults() {
if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
return ULE->getTrailingObjects<DeclAccessPair>();
return cast<UnresolvedMemberExpr>(this)->getTrailingObjects<DeclAccessPair>();
}
inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
if (isa<UnresolvedLookupExpr>(this))
return cast<UnresolvedLookupExpr>(this)
->getTrailingObjects<TemplateArgumentLoc>();
else
return cast<UnresolvedMemberExpr>(this)
->getTrailingObjects<TemplateArgumentLoc>();
ASTTemplateKWAndArgsInfo *OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
if (!hasTemplateKWAndArgsInfo())
return nullptr;
if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
return ULE->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
return cast<UnresolvedMemberExpr>(this)
->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
}
TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
return ULE->getTrailingObjects<TemplateArgumentLoc>();
return cast<UnresolvedMemberExpr>(this)
->getTrailingObjects<TemplateArgumentLoc>();
}
CXXRecordDecl *OverloadExpr::getNamingClass() {
if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
return ULE->getNamingClass();
return cast<UnresolvedMemberExpr>(this)->getNamingClass();
}
/// Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).

View File

@ -769,6 +769,61 @@ protected:
SourceLocation OperatorLoc;
};
class OverloadExprBitfields {
friend class ASTStmtReader;
friend class OverloadExpr;
unsigned : NumExprBits;
/// Whether the name includes info for explicit template
/// keyword and arguments.
unsigned HasTemplateKWAndArgsInfo : 1;
/// Padding used by the derived classes to store various bits. If you
/// need to add some data here, shrink this padding and add your data
/// above. NumOverloadExprBits also needs to be updated.
unsigned : 32 - NumExprBits - 1;
/// The number of results.
unsigned NumResults;
};
enum { NumOverloadExprBits = NumExprBits + 1 };
class UnresolvedLookupExprBitfields {
friend class ASTStmtReader;
friend class UnresolvedLookupExpr;
unsigned : NumOverloadExprBits;
/// True if these lookup results should be extended by
/// argument-dependent lookup if this is the operand of a function call.
unsigned RequiresADL : 1;
/// True if these lookup results are overloaded. This is pretty trivially
/// rederivable if we urgently need to kill this field.
unsigned Overloaded : 1;
};
static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4,
"UnresolvedLookupExprBitfields must be <= than 4 bytes to"
"avoid trashing OverloadExprBitfields::NumResults!");
class UnresolvedMemberExprBitfields {
friend class ASTStmtReader;
friend class UnresolvedMemberExpr;
unsigned : NumOverloadExprBits;
/// Whether this member expression used the '->' operator or
/// the '.' operator.
unsigned IsArrow : 1;
/// Whether the lookup results contain an unresolved using declaration.
unsigned HasUnresolvedUsing : 1;
};
static_assert(sizeof(UnresolvedMemberExprBitfields) <= 4,
"UnresolvedMemberExprBitfields must be <= than 4 bytes to"
"avoid trashing OverloadExprBitfields::NumResults!");
class CXXNoexceptExprBitfields {
friend class ASTStmtReader;
friend class CXXNoexceptExpr;
@ -877,6 +932,9 @@ protected:
ExprWithCleanupsBitfields ExprWithCleanupsBits;
CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits;
CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits;
OverloadExprBitfields OverloadExprBits;
UnresolvedLookupExprBitfields UnresolvedLookupExprBits;
UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
CXXNoexceptExprBitfields CXXNoexceptExprBits;
SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;

View File

@ -302,68 +302,95 @@ SourceLocation CXXPseudoDestructorExpr::getEndLoc() const {
}
// UnresolvedLookupExpr
UnresolvedLookupExpr *
UnresolvedLookupExpr::Create(const ASTContext &C,
CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
bool ADL,
const TemplateArgumentListInfo *Args,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End) {
UnresolvedLookupExpr::UnresolvedLookupExpr(
const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
UnresolvedSetIterator End)
: OverloadExpr(UnresolvedLookupExprClass, Context, QualifierLoc,
TemplateKWLoc, NameInfo, TemplateArgs, Begin, End, false,
false, false),
NamingClass(NamingClass) {
UnresolvedLookupExprBits.RequiresADL = RequiresADL;
UnresolvedLookupExprBits.Overloaded = Overloaded;
}
UnresolvedLookupExpr::UnresolvedLookupExpr(EmptyShell Empty,
unsigned NumResults,
bool HasTemplateKWAndArgsInfo)
: OverloadExpr(UnresolvedLookupExprClass, Empty, NumResults,
HasTemplateKWAndArgsInfo) {}
UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin,
UnresolvedSetIterator End) {
unsigned NumResults = End - Begin;
unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc>(NumResults, 0, 0);
void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc,
SourceLocation(), NameInfo, RequiresADL,
Overloaded, nullptr, Begin, End);
}
UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo, bool RequiresADL,
const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
UnresolvedSetIterator End) {
assert(Args || TemplateKWLoc.isValid());
unsigned num_args = Args ? Args->size() : 0;
std::size_t Size =
totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(1,
num_args);
void *Mem = C.Allocate(Size, alignof(UnresolvedLookupExpr));
return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
TemplateKWLoc, NameInfo,
ADL, /*Overload*/ true, Args,
Begin, End);
unsigned NumResults = End - Begin;
unsigned NumTemplateArgs = Args ? Args->size() : 0;
unsigned Size =
totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc>(NumResults, 1, NumTemplateArgs);
void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc,
TemplateKWLoc, NameInfo, RequiresADL,
/*Overloaded*/ true, Args, Begin, End);
}
UnresolvedLookupExpr *
UnresolvedLookupExpr::CreateEmpty(const ASTContext &C,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) {
UnresolvedLookupExpr *UnresolvedLookupExpr::CreateEmpty(
const ASTContext &Context, unsigned NumResults,
bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) {
assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
std::size_t Size =
totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = C.Allocate(Size, alignof(UnresolvedLookupExpr));
auto *E = new (Mem) UnresolvedLookupExpr(EmptyShell());
E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
return E;
unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc>(
NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
return new (Mem)
UnresolvedLookupExpr(EmptyShell(), NumResults, HasTemplateKWAndArgsInfo);
}
OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
OverloadExpr::OverloadExpr(StmtClass SC, const ASTContext &Context,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End,
bool KnownDependent,
UnresolvedSetIterator End, bool KnownDependent,
bool KnownInstantiationDependent,
bool KnownContainsUnexpandedParameterPack)
: Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent,
KnownDependent,
(KnownInstantiationDependent ||
NameInfo.isInstantiationDependent() ||
(QualifierLoc &&
: Expr(
SC, Context.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent,
KnownDependent,
(KnownInstantiationDependent || NameInfo.isInstantiationDependent() ||
(QualifierLoc &&
QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())),
(KnownContainsUnexpandedParameterPack ||
NameInfo.containsUnexpandedParameterPack() ||
(QualifierLoc &&
QualifierLoc.getNestedNameSpecifier()
->containsUnexpandedParameterPack()))),
NameInfo(NameInfo), QualifierLoc(QualifierLoc), NumResults(End - Begin),
HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
TemplateKWLoc.isValid()) {
NumResults = End - Begin;
(KnownContainsUnexpandedParameterPack ||
NameInfo.containsUnexpandedParameterPack() ||
(QualifierLoc && QualifierLoc.getNestedNameSpecifier()
->containsUnexpandedParameterPack()))),
NameInfo(NameInfo), QualifierLoc(QualifierLoc) {
unsigned NumResults = End - Begin;
OverloadExprBits.NumResults = NumResults;
OverloadExprBits.HasTemplateKWAndArgsInfo =
(TemplateArgs != nullptr ) || TemplateKWLoc.isValid();
if (NumResults) {
// Determine whether this expression is type-dependent.
for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) {
@ -375,8 +402,9 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
}
}
Results = static_cast<DeclAccessPair *>(C.Allocate(
sizeof(DeclAccessPair) * NumResults, alignof(DeclAccessPair)));
// Copy the results to the trailing array past UnresolvedLookupExpr
// or UnresolvedMemberExpr.
DeclAccessPair *Results = getTrailingResults();
memcpy(Results, Begin.I, NumResults * sizeof(DeclAccessPair));
}
@ -404,28 +432,14 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
}
if (isTypeDependent())
setType(C.DependentTy);
setType(Context.DependentTy);
}
void OverloadExpr::initializeResults(const ASTContext &C,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End) {
assert(!Results && "Results already initialized!");
NumResults = End - Begin;
if (NumResults) {
Results = static_cast<DeclAccessPair *>(
C.Allocate(sizeof(DeclAccessPair) * NumResults,
alignof(DeclAccessPair)));
memcpy(Results, Begin.I, NumResults * sizeof(DeclAccessPair));
}
}
CXXRecordDecl *OverloadExpr::getNamingClass() const {
if (isa<UnresolvedLookupExpr>(this))
return cast<UnresolvedLookupExpr>(this)->getNamingClass();
else
return cast<UnresolvedMemberExpr>(this)->getNamingClass();
OverloadExpr::OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults,
bool HasTemplateKWAndArgsInfo)
: Expr(SC, Empty) {
OverloadExprBits.NumResults = NumResults;
OverloadExprBits.HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
}
// DependentScopeDeclRefExpr
@ -1401,19 +1415,15 @@ static bool hasOnlyNonStaticMemberFunctions(UnresolvedSetIterator begin,
return true;
}
UnresolvedMemberExpr::UnresolvedMemberExpr(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)
UnresolvedMemberExpr::UnresolvedMemberExpr(
const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
UnresolvedSetIterator End)
: OverloadExpr(
UnresolvedMemberExprClass, C, QualifierLoc, TemplateKWLoc,
UnresolvedMemberExprClass, Context, QualifierLoc, TemplateKWLoc,
MemberNameInfo, TemplateArgs, Begin, End,
// Dependent
((Base && Base->isTypeDependent()) || BaseType->isDependentType()),
@ -1422,14 +1432,22 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(const ASTContext &C,
// Contains unexpanded parameter pack
((Base && Base->containsUnexpandedParameterPack()) ||
BaseType->containsUnexpandedParameterPack())),
IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing), Base(Base),
BaseType(BaseType), OperatorLoc(OperatorLoc) {
Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
UnresolvedMemberExprBits.IsArrow = IsArrow;
UnresolvedMemberExprBits.HasUnresolvedUsing = HasUnresolvedUsing;
// Check whether all of the members are non-static member functions,
// and if so, mark give this bound-member type instead of overload type.
if (hasOnlyNonStaticMemberFunctions(Begin, End))
setType(C.BoundMemberTy);
setType(Context.BoundMemberTy);
}
UnresolvedMemberExpr::UnresolvedMemberExpr(EmptyShell Empty,
unsigned NumResults,
bool HasTemplateKWAndArgsInfo)
: OverloadExpr(UnresolvedMemberExprClass, Empty, NumResults,
HasTemplateKWAndArgsInfo) {}
bool UnresolvedMemberExpr::isImplicitAccess() const {
if (!Base)
return true;
@ -1438,39 +1456,37 @@ bool UnresolvedMemberExpr::isImplicitAccess() const {
}
UnresolvedMemberExpr *UnresolvedMemberExpr::Create(
const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType,
bool IsArrow, SourceLocation OperatorLoc,
const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
UnresolvedSetIterator End) {
unsigned NumResults = End - Begin;
bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
std::size_t Size =
totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
HasTemplateKWAndArgsInfo, TemplateArgs ? TemplateArgs->size() : 0);
void *Mem = C.Allocate(Size, alignof(UnresolvedMemberExpr));
unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0;
unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc>(
NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = Context.Allocate(Size, alignof(UnresolvedMemberExpr));
return new (Mem) UnresolvedMemberExpr(
C, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc,
TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End);
Context, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc,
QualifierLoc, TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End);
}
UnresolvedMemberExpr *
UnresolvedMemberExpr::CreateEmpty(const ASTContext &C,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) {
UnresolvedMemberExpr *UnresolvedMemberExpr::CreateEmpty(
const ASTContext &Context, unsigned NumResults,
bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) {
assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
std::size_t Size =
totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = C.Allocate(Size, alignof(UnresolvedMemberExpr));
auto *E = new (Mem) UnresolvedMemberExpr(EmptyShell());
E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
return E;
unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc>(
NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = Context.Allocate(Size, alignof(UnresolvedMemberExpr));
return new (Mem)
UnresolvedMemberExpr(EmptyShell(), NumResults, HasTemplateKWAndArgsInfo);
}
CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() {
// Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
// If there was a nested name specifier, it names the naming class.

View File

@ -1648,19 +1648,33 @@ ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
VisitExpr(E);
if (Record.readInt()) // HasTemplateKWAndArgsInfo
unsigned NumResults = Record.readInt();
bool HasTemplateKWAndArgsInfo = Record.readInt();
assert((E->getNumDecls() == NumResults) && "Wrong NumResults!");
assert((E->hasTemplateKWAndArgsInfo() == HasTemplateKWAndArgsInfo) &&
"Wrong HasTemplateKWAndArgsInfo!");
if (HasTemplateKWAndArgsInfo) {
unsigned NumTemplateArgs = Record.readInt();
ReadTemplateKWAndArgsInfo(*E->getTrailingASTTemplateKWAndArgsInfo(),
E->getTrailingTemplateArgumentLoc(),
/*NumTemplateArgs=*/Record.readInt());
NumTemplateArgs);
assert((E->getNumTemplateArgs() == NumTemplateArgs) &&
"Wrong NumTemplateArgs!");
}
unsigned NumDecls = Record.readInt();
UnresolvedSet<8> Decls;
for (unsigned i = 0; i != NumDecls; ++i) {
for (unsigned I = 0; I != NumResults; ++I) {
auto *D = ReadDeclAs<NamedDecl>();
auto AS = (AccessSpecifier)Record.readInt();
Decls.addDecl(D, AS);
}
E->initializeResults(Record.getContext(), Decls.begin(), Decls.end());
DeclAccessPair *Results = E->getTrailingResults();
UnresolvedSetIterator Iter = Decls.begin();
for (unsigned I = 0; I != NumResults; ++I) {
Results[I] = (Iter + I).getPair();
}
ReadDeclarationNameInfo(E->NameInfo);
E->QualifierLoc = Record.readNestedNameSpecifierLoc();
@ -1668,8 +1682,8 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
VisitOverloadExpr(E);
E->IsArrow = Record.readInt();
E->HasUnresolvedUsing = Record.readInt();
E->UnresolvedMemberExprBits.IsArrow = Record.readInt();
E->UnresolvedMemberExprBits.HasUnresolvedUsing = Record.readInt();
E->Base = Record.readSubExpr();
E->BaseType = Record.readType();
E->OperatorLoc = ReadSourceLocation();
@ -1677,8 +1691,8 @@ void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
VisitOverloadExpr(E);
E->RequiresADL = Record.readInt();
E->Overloaded = Record.readInt();
E->UnresolvedLookupExprBits.RequiresADL = Record.readInt();
E->UnresolvedLookupExprBits.Overloaded = Record.readInt();
E->NamingClass = ReadDeclAs<CXXRecordDecl>();
}
@ -3261,19 +3275,25 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
break;
case EXPR_CXX_UNRESOLVED_MEMBER:
S = UnresolvedMemberExpr::CreateEmpty(Context,
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
? Record[ASTStmtReader::NumExprFields + 1]
: 0);
S = UnresolvedMemberExpr::CreateEmpty(
Context,
/*NumResults=*/Record[ASTStmtReader::NumExprFields],
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 1],
/*NumTemplateArgs=*/
Record[ASTStmtReader::NumExprFields + 1]
? Record[ASTStmtReader::NumExprFields + 2]
: 0);
break;
case EXPR_CXX_UNRESOLVED_LOOKUP:
S = UnresolvedLookupExpr::CreateEmpty(Context,
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
? Record[ASTStmtReader::NumExprFields + 1]
: 0);
S = UnresolvedLookupExpr::CreateEmpty(
Context,
/*NumResults=*/Record[ASTStmtReader::NumExprFields],
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 1],
/*NumTemplateArgs=*/
Record[ASTStmtReader::NumExprFields + 1]
? Record[ASTStmtReader::NumExprFields + 2]
: 0);
break;
case EXPR_TYPE_TRAIT:

View File

@ -1625,25 +1625,23 @@ ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
VisitExpr(E);
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
// emitted first.
Record.push_back(E->HasTemplateKWAndArgsInfo);
if (E->HasTemplateKWAndArgsInfo) {
Record.push_back(E->getNumDecls());
Record.push_back(E->hasTemplateKWAndArgsInfo());
if (E->hasTemplateKWAndArgsInfo()) {
const ASTTemplateKWAndArgsInfo &ArgInfo =
*E->getTrailingASTTemplateKWAndArgsInfo();
Record.push_back(ArgInfo.NumTemplateArgs);
AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
}
Record.push_back(E->getNumDecls());
for (OverloadExpr::decls_iterator
OvI = E->decls_begin(), OvE = E->decls_end(); OvI != OvE; ++OvI) {
for (OverloadExpr::decls_iterator OvI = E->decls_begin(),
OvE = E->decls_end();
OvI != OvE; ++OvI) {
Record.AddDeclRef(OvI.getDecl());
Record.push_back(OvI.getAccess());
}
Record.AddDeclarationNameInfo(E->NameInfo);
Record.AddDeclarationNameInfo(E->getNameInfo());
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
}