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

View File

@ -769,6 +769,61 @@ protected:
SourceLocation OperatorLoc; 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 { class CXXNoexceptExprBitfields {
friend class ASTStmtReader; friend class ASTStmtReader;
friend class CXXNoexceptExpr; friend class CXXNoexceptExpr;
@ -877,6 +932,9 @@ protected:
ExprWithCleanupsBitfields ExprWithCleanupsBits; ExprWithCleanupsBitfields ExprWithCleanupsBits;
CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits; CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits;
CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits; CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits;
OverloadExprBitfields OverloadExprBits;
UnresolvedLookupExprBitfields UnresolvedLookupExprBits;
UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
CXXNoexceptExprBitfields CXXNoexceptExprBits; CXXNoexceptExprBitfields CXXNoexceptExprBits;
SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits; SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;

View File

@ -302,68 +302,95 @@ SourceLocation CXXPseudoDestructorExpr::getEndLoc() const {
} }
// UnresolvedLookupExpr // UnresolvedLookupExpr
UnresolvedLookupExpr * UnresolvedLookupExpr::UnresolvedLookupExpr(
UnresolvedLookupExpr::Create(const ASTContext &C, const ASTContext &Context, CXXRecordDecl *NamingClass,
CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
SourceLocation TemplateKWLoc, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
const DeclarationNameInfo &NameInfo, UnresolvedSetIterator End)
bool ADL, : OverloadExpr(UnresolvedLookupExprClass, Context, QualifierLoc,
const TemplateArgumentListInfo *Args, TemplateKWLoc, NameInfo, TemplateArgs, Begin, End, false,
UnresolvedSetIterator Begin, false, false),
UnresolvedSetIterator End) { 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()); assert(Args || TemplateKWLoc.isValid());
unsigned num_args = Args ? Args->size() : 0; unsigned NumResults = End - Begin;
unsigned NumTemplateArgs = Args ? Args->size() : 0;
std::size_t Size = unsigned Size =
totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(1, totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
num_args); TemplateArgumentLoc>(NumResults, 1, NumTemplateArgs);
void *Mem = C.Allocate(Size, alignof(UnresolvedLookupExpr)); void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc,
TemplateKWLoc, NameInfo, TemplateKWLoc, NameInfo, RequiresADL,
ADL, /*Overload*/ true, Args, /*Overloaded*/ true, Args, Begin, End);
Begin, End);
} }
UnresolvedLookupExpr * UnresolvedLookupExpr *UnresolvedLookupExpr::CreateEmpty(
UnresolvedLookupExpr::CreateEmpty(const ASTContext &C, const ASTContext &Context, unsigned NumResults,
bool HasTemplateKWAndArgsInfo, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) {
unsigned NumTemplateArgs) {
assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo); assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
std::size_t Size = unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>( TemplateArgumentLoc>(
HasTemplateKWAndArgsInfo, NumTemplateArgs); NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = C.Allocate(Size, alignof(UnresolvedLookupExpr)); void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
auto *E = new (Mem) UnresolvedLookupExpr(EmptyShell()); return new (Mem)
E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo; UnresolvedLookupExpr(EmptyShell(), NumResults, HasTemplateKWAndArgsInfo);
return E;
} }
OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C, OverloadExpr::OverloadExpr(StmtClass SC, const ASTContext &Context,
NestedNameSpecifierLoc QualifierLoc, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo, const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator Begin,
UnresolvedSetIterator End, UnresolvedSetIterator End, bool KnownDependent,
bool KnownDependent,
bool KnownInstantiationDependent, bool KnownInstantiationDependent,
bool KnownContainsUnexpandedParameterPack) bool KnownContainsUnexpandedParameterPack)
: Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent, : Expr(
KnownDependent, SC, Context.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent,
(KnownInstantiationDependent || KnownDependent,
NameInfo.isInstantiationDependent() || (KnownInstantiationDependent || NameInfo.isInstantiationDependent() ||
(QualifierLoc && (QualifierLoc &&
QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())), QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())),
(KnownContainsUnexpandedParameterPack || (KnownContainsUnexpandedParameterPack ||
NameInfo.containsUnexpandedParameterPack() || NameInfo.containsUnexpandedParameterPack() ||
(QualifierLoc && (QualifierLoc && QualifierLoc.getNestedNameSpecifier()
QualifierLoc.getNestedNameSpecifier() ->containsUnexpandedParameterPack()))),
->containsUnexpandedParameterPack()))), NameInfo(NameInfo), QualifierLoc(QualifierLoc) {
NameInfo(NameInfo), QualifierLoc(QualifierLoc), NumResults(End - Begin), unsigned NumResults = End - Begin;
HasTemplateKWAndArgsInfo(TemplateArgs != nullptr || OverloadExprBits.NumResults = NumResults;
TemplateKWLoc.isValid()) { OverloadExprBits.HasTemplateKWAndArgsInfo =
NumResults = End - Begin; (TemplateArgs != nullptr ) || TemplateKWLoc.isValid();
if (NumResults) { if (NumResults) {
// Determine whether this expression is type-dependent. // Determine whether this expression is type-dependent.
for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) { 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( // Copy the results to the trailing array past UnresolvedLookupExpr
sizeof(DeclAccessPair) * NumResults, alignof(DeclAccessPair))); // or UnresolvedMemberExpr.
DeclAccessPair *Results = getTrailingResults();
memcpy(Results, Begin.I, NumResults * sizeof(DeclAccessPair)); memcpy(Results, Begin.I, NumResults * sizeof(DeclAccessPair));
} }
@ -404,28 +432,14 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
} }
if (isTypeDependent()) if (isTypeDependent())
setType(C.DependentTy); setType(Context.DependentTy);
} }
void OverloadExpr::initializeResults(const ASTContext &C, OverloadExpr::OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults,
UnresolvedSetIterator Begin, bool HasTemplateKWAndArgsInfo)
UnresolvedSetIterator End) { : Expr(SC, Empty) {
assert(!Results && "Results already initialized!"); OverloadExprBits.NumResults = NumResults;
NumResults = End - Begin; OverloadExprBits.HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
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();
} }
// DependentScopeDeclRefExpr // DependentScopeDeclRefExpr
@ -1401,19 +1415,15 @@ static bool hasOnlyNonStaticMemberFunctions(UnresolvedSetIterator begin,
return true; return true;
} }
UnresolvedMemberExpr::UnresolvedMemberExpr(const ASTContext &C, UnresolvedMemberExpr::UnresolvedMemberExpr(
bool HasUnresolvedUsing, const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
Expr *Base, QualType BaseType, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
bool IsArrow, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
SourceLocation OperatorLoc, const DeclarationNameInfo &MemberNameInfo,
NestedNameSpecifierLoc QualifierLoc, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
SourceLocation TemplateKWLoc, UnresolvedSetIterator End)
const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End)
: OverloadExpr( : OverloadExpr(
UnresolvedMemberExprClass, C, QualifierLoc, TemplateKWLoc, UnresolvedMemberExprClass, Context, QualifierLoc, TemplateKWLoc,
MemberNameInfo, TemplateArgs, Begin, End, MemberNameInfo, TemplateArgs, Begin, End,
// Dependent // Dependent
((Base && Base->isTypeDependent()) || BaseType->isDependentType()), ((Base && Base->isTypeDependent()) || BaseType->isDependentType()),
@ -1422,14 +1432,22 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(const ASTContext &C,
// Contains unexpanded parameter pack // Contains unexpanded parameter pack
((Base && Base->containsUnexpandedParameterPack()) || ((Base && Base->containsUnexpandedParameterPack()) ||
BaseType->containsUnexpandedParameterPack())), BaseType->containsUnexpandedParameterPack())),
IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing), Base(Base), Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
BaseType(BaseType), OperatorLoc(OperatorLoc) { UnresolvedMemberExprBits.IsArrow = IsArrow;
UnresolvedMemberExprBits.HasUnresolvedUsing = HasUnresolvedUsing;
// Check whether all of the members are non-static member functions, // Check whether all of the members are non-static member functions,
// and if so, mark give this bound-member type instead of overload type. // and if so, mark give this bound-member type instead of overload type.
if (hasOnlyNonStaticMemberFunctions(Begin, End)) 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 { bool UnresolvedMemberExpr::isImplicitAccess() const {
if (!Base) if (!Base)
return true; return true;
@ -1438,39 +1456,37 @@ bool UnresolvedMemberExpr::isImplicitAccess() const {
} }
UnresolvedMemberExpr *UnresolvedMemberExpr::Create( UnresolvedMemberExpr *UnresolvedMemberExpr::Create(
const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
bool IsArrow, SourceLocation OperatorLoc, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &MemberNameInfo, const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
UnresolvedSetIterator End) { UnresolvedSetIterator End) {
unsigned NumResults = End - Begin;
bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid(); bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
std::size_t Size = unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0;
totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>( unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
HasTemplateKWAndArgsInfo, TemplateArgs ? TemplateArgs->size() : 0); TemplateArgumentLoc>(
NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = C.Allocate(Size, alignof(UnresolvedMemberExpr)); void *Mem = Context.Allocate(Size, alignof(UnresolvedMemberExpr));
return new (Mem) UnresolvedMemberExpr( return new (Mem) UnresolvedMemberExpr(
C, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc, Context, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc,
TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End); QualifierLoc, TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End);
} }
UnresolvedMemberExpr * UnresolvedMemberExpr *UnresolvedMemberExpr::CreateEmpty(
UnresolvedMemberExpr::CreateEmpty(const ASTContext &C, const ASTContext &Context, unsigned NumResults,
bool HasTemplateKWAndArgsInfo, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) {
unsigned NumTemplateArgs) {
assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo); assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
std::size_t Size = unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>( TemplateArgumentLoc>(
HasTemplateKWAndArgsInfo, NumTemplateArgs); NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = Context.Allocate(Size, alignof(UnresolvedMemberExpr));
void *Mem = C.Allocate(Size, alignof(UnresolvedMemberExpr)); return new (Mem)
auto *E = new (Mem) UnresolvedMemberExpr(EmptyShell()); UnresolvedMemberExpr(EmptyShell(), NumResults, HasTemplateKWAndArgsInfo);
E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
return E;
} }
CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const { CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() {
// Unlike for UnresolvedLookupExpr, it is very easy to re-derive this. // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
// If there was a nested name specifier, it names the naming class. // 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) { void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
VisitExpr(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(), ReadTemplateKWAndArgsInfo(*E->getTrailingASTTemplateKWAndArgsInfo(),
E->getTrailingTemplateArgumentLoc(), E->getTrailingTemplateArgumentLoc(),
/*NumTemplateArgs=*/Record.readInt()); NumTemplateArgs);
assert((E->getNumTemplateArgs() == NumTemplateArgs) &&
"Wrong NumTemplateArgs!");
}
unsigned NumDecls = Record.readInt();
UnresolvedSet<8> Decls; UnresolvedSet<8> Decls;
for (unsigned i = 0; i != NumDecls; ++i) { for (unsigned I = 0; I != NumResults; ++I) {
auto *D = ReadDeclAs<NamedDecl>(); auto *D = ReadDeclAs<NamedDecl>();
auto AS = (AccessSpecifier)Record.readInt(); auto AS = (AccessSpecifier)Record.readInt();
Decls.addDecl(D, AS); 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); ReadDeclarationNameInfo(E->NameInfo);
E->QualifierLoc = Record.readNestedNameSpecifierLoc(); E->QualifierLoc = Record.readNestedNameSpecifierLoc();
@ -1668,8 +1682,8 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
VisitOverloadExpr(E); VisitOverloadExpr(E);
E->IsArrow = Record.readInt(); E->UnresolvedMemberExprBits.IsArrow = Record.readInt();
E->HasUnresolvedUsing = Record.readInt(); E->UnresolvedMemberExprBits.HasUnresolvedUsing = Record.readInt();
E->Base = Record.readSubExpr(); E->Base = Record.readSubExpr();
E->BaseType = Record.readType(); E->BaseType = Record.readType();
E->OperatorLoc = ReadSourceLocation(); E->OperatorLoc = ReadSourceLocation();
@ -1677,8 +1691,8 @@ void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
VisitOverloadExpr(E); VisitOverloadExpr(E);
E->RequiresADL = Record.readInt(); E->UnresolvedLookupExprBits.RequiresADL = Record.readInt();
E->Overloaded = Record.readInt(); E->UnresolvedLookupExprBits.Overloaded = Record.readInt();
E->NamingClass = ReadDeclAs<CXXRecordDecl>(); E->NamingClass = ReadDeclAs<CXXRecordDecl>();
} }
@ -3261,19 +3275,25 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
break; break;
case EXPR_CXX_UNRESOLVED_MEMBER: case EXPR_CXX_UNRESOLVED_MEMBER:
S = UnresolvedMemberExpr::CreateEmpty(Context, S = UnresolvedMemberExpr::CreateEmpty(
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields], Context,
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] /*NumResults=*/Record[ASTStmtReader::NumExprFields],
? Record[ASTStmtReader::NumExprFields + 1] /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 1],
: 0); /*NumTemplateArgs=*/
Record[ASTStmtReader::NumExprFields + 1]
? Record[ASTStmtReader::NumExprFields + 2]
: 0);
break; break;
case EXPR_CXX_UNRESOLVED_LOOKUP: case EXPR_CXX_UNRESOLVED_LOOKUP:
S = UnresolvedLookupExpr::CreateEmpty(Context, S = UnresolvedLookupExpr::CreateEmpty(
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields], Context,
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] /*NumResults=*/Record[ASTStmtReader::NumExprFields],
? Record[ASTStmtReader::NumExprFields + 1] /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 1],
: 0); /*NumTemplateArgs=*/
Record[ASTStmtReader::NumExprFields + 1]
? Record[ASTStmtReader::NumExprFields + 2]
: 0);
break; break;
case EXPR_TYPE_TRAIT: case EXPR_TYPE_TRAIT:

View File

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