[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:
parent
59e916c214
commit
d7628d9993
|
@ -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]).
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue