forked from OSchip/llvm-project
[AST] Pack CXXDependentScopeMemberExpr
Use the newly available space in the bit-fields of Stmt. Additionally store FirstQualifierFoundInScope as a trailing object since it is most of the time null (non-null for 2 of the 35446 CXXDependentScopeMemberExpr when parsing all of Boost). It would be possible to move the data for the nested-name-specifier to a trailing object too to save another 2 pointers, however doing so did actually regress the time taken to parse all of Boost slightly. This saves 8 bytes + 1 pointer per CXXDependentScopeMemberExpr in the vast majority of cases. Differential Revision: https://reviews.llvm.org/D56367 Reviewed By: rjmccall llvm-svn: 350625
This commit is contained in:
parent
efb5ad1c58
commit
2e6dc538be
|
@ -3306,7 +3306,11 @@ class CXXDependentScopeMemberExpr final
|
|||
: public Expr,
|
||||
private llvm::TrailingObjects<CXXDependentScopeMemberExpr,
|
||||
ASTTemplateKWAndArgsInfo,
|
||||
TemplateArgumentLoc> {
|
||||
TemplateArgumentLoc, NamedDecl *> {
|
||||
friend class ASTStmtReader;
|
||||
friend class ASTStmtWriter;
|
||||
friend TrailingObjects;
|
||||
|
||||
/// The expression for the base pointer or class reference,
|
||||
/// e.g., the \c x in x.f. Can be null in implicit accesses.
|
||||
Stmt *Base;
|
||||
|
@ -3315,40 +3319,53 @@ class CXXDependentScopeMemberExpr final
|
|||
/// implicit accesses.
|
||||
QualType BaseType;
|
||||
|
||||
/// Whether this member expression used the '->' operator or
|
||||
/// the '.' operator.
|
||||
bool IsArrow : 1;
|
||||
|
||||
/// Whether this member expression has info for explicit template
|
||||
/// keyword and arguments.
|
||||
bool HasTemplateKWAndArgsInfo : 1;
|
||||
|
||||
/// The location of the '->' or '.' operator.
|
||||
SourceLocation OperatorLoc;
|
||||
|
||||
/// The nested-name-specifier that precedes the member name, if any.
|
||||
/// FIXME: This could be in principle store as a trailing object.
|
||||
/// However the performance impact of doing so should be investigated first.
|
||||
NestedNameSpecifierLoc QualifierLoc;
|
||||
|
||||
/// In a qualified member access expression such as t->Base::f, this
|
||||
/// member stores the resolves of name lookup in the context of the member
|
||||
/// access expression, to be used at instantiation time.
|
||||
///
|
||||
/// FIXME: This member, along with the QualifierLoc, could
|
||||
/// be stuck into a structure that is optionally allocated at the end of
|
||||
/// the CXXDependentScopeMemberExpr, to save space in the common case.
|
||||
NamedDecl *FirstQualifierFoundInScope;
|
||||
|
||||
/// The member to which this member expression refers, which
|
||||
/// can be name, overloaded operator, or destructor.
|
||||
///
|
||||
/// FIXME: could also be a template-id
|
||||
DeclarationNameInfo MemberNameInfo;
|
||||
|
||||
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
|
||||
return HasTemplateKWAndArgsInfo ? 1 : 0;
|
||||
// CXXDependentScopeMemberExpr is followed by several trailing objects,
|
||||
// some of which optional. They are in order:
|
||||
//
|
||||
// * 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.
|
||||
//
|
||||
// * An optional NamedDecl *. In a qualified member access expression such
|
||||
// as t->Base::f, this member stores the resolves of name lookup in the
|
||||
// context of the member access expression, to be used at instantiation
|
||||
// time. Present if and only if hasFirstQualifierFoundInScope().
|
||||
|
||||
bool hasTemplateKWAndArgsInfo() const {
|
||||
return CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo;
|
||||
}
|
||||
|
||||
CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
|
||||
bool hasFirstQualifierFoundInScope() const {
|
||||
return CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope;
|
||||
}
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
|
||||
return hasTemplateKWAndArgsInfo();
|
||||
}
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
|
||||
return getNumTemplateArgs();
|
||||
}
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<NamedDecl *>) const {
|
||||
return hasFirstQualifierFoundInScope();
|
||||
}
|
||||
|
||||
CXXDependentScopeMemberExpr(const ASTContext &Ctx, Expr *Base,
|
||||
QualType BaseType, bool IsArrow,
|
||||
SourceLocation OperatorLoc,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
|
@ -3357,33 +3374,29 @@ class CXXDependentScopeMemberExpr final
|
|||
DeclarationNameInfo MemberNameInfo,
|
||||
const TemplateArgumentListInfo *TemplateArgs);
|
||||
|
||||
CXXDependentScopeMemberExpr(EmptyShell Empty, bool HasTemplateKWAndArgsInfo,
|
||||
bool HasFirstQualifierFoundInScope);
|
||||
|
||||
public:
|
||||
friend class ASTStmtReader;
|
||||
friend class ASTStmtWriter;
|
||||
friend TrailingObjects;
|
||||
|
||||
CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
|
||||
QualType BaseType, bool IsArrow,
|
||||
SourceLocation OperatorLoc,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
NamedDecl *FirstQualifierFoundInScope,
|
||||
DeclarationNameInfo MemberNameInfo);
|
||||
|
||||
static CXXDependentScopeMemberExpr *
|
||||
Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow,
|
||||
Create(const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
|
||||
SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
|
||||
SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
|
||||
DeclarationNameInfo MemberNameInfo,
|
||||
const TemplateArgumentListInfo *TemplateArgs);
|
||||
|
||||
static CXXDependentScopeMemberExpr *
|
||||
CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
|
||||
unsigned NumTemplateArgs);
|
||||
CreateEmpty(const ASTContext &Ctx, bool HasTemplateKWAndArgsInfo,
|
||||
unsigned NumTemplateArgs, bool HasFirstQualifierFoundInScope);
|
||||
|
||||
/// True if this is an implicit access, i.e. one in which the
|
||||
/// member being accessed was not written in the source. The source
|
||||
/// location of the operator is invalid in this case.
|
||||
bool isImplicitAccess() const;
|
||||
bool isImplicitAccess() const {
|
||||
if (!Base)
|
||||
return true;
|
||||
return cast<Expr>(Base)->isImplicitCXXThis();
|
||||
}
|
||||
|
||||
/// Retrieve the base object of this member expressions,
|
||||
/// e.g., the \c x in \c x.m.
|
||||
|
@ -3396,13 +3409,14 @@ public:
|
|||
|
||||
/// Determine whether this member expression used the '->'
|
||||
/// operator; otherwise, it used the '.' operator.
|
||||
bool isArrow() const { return IsArrow; }
|
||||
bool isArrow() const { return CXXDependentScopeMemberExprBits.IsArrow; }
|
||||
|
||||
/// Retrieve the location of the '->' or '.' operator.
|
||||
SourceLocation getOperatorLoc() const { return OperatorLoc; }
|
||||
SourceLocation getOperatorLoc() const {
|
||||
return CXXDependentScopeMemberExprBits.OperatorLoc;
|
||||
}
|
||||
|
||||
/// Retrieve the nested-name-specifier that qualifies the member
|
||||
/// name.
|
||||
/// Retrieve the nested-name-specifier that qualifies the member name.
|
||||
NestedNameSpecifier *getQualifier() const {
|
||||
return QualifierLoc.getNestedNameSpecifier();
|
||||
}
|
||||
|
@ -3423,17 +3437,17 @@ public:
|
|||
/// combined with the results of name lookup into the type of the object
|
||||
/// expression itself (the class type of x).
|
||||
NamedDecl *getFirstQualifierFoundInScope() const {
|
||||
return FirstQualifierFoundInScope;
|
||||
if (!hasFirstQualifierFoundInScope())
|
||||
return nullptr;
|
||||
return *getTrailingObjects<NamedDecl *>();
|
||||
}
|
||||
|
||||
/// Retrieve the name of the member that this expression
|
||||
/// refers to.
|
||||
/// Retrieve the name of the member that this expression refers to.
|
||||
const DeclarationNameInfo &getMemberNameInfo() const {
|
||||
return MemberNameInfo;
|
||||
}
|
||||
|
||||
/// Retrieve the name of the member that this expression
|
||||
/// refers to.
|
||||
/// Retrieve the name of the member that this expression refers to.
|
||||
DeclarationName getMember() const { return MemberNameInfo.getName(); }
|
||||
|
||||
// Retrieve the location of the name of the member that this
|
||||
|
@ -3443,21 +3457,24 @@ public:
|
|||
/// Retrieve the location of the template keyword preceding the
|
||||
/// member name, if any.
|
||||
SourceLocation getTemplateKeywordLoc() const {
|
||||
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
|
||||
if (!hasTemplateKWAndArgsInfo())
|
||||
return SourceLocation();
|
||||
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
|
||||
}
|
||||
|
||||
/// Retrieve the location of the left angle bracket starting the
|
||||
/// explicit template argument list following the member name, if any.
|
||||
SourceLocation getLAngleLoc() const {
|
||||
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
|
||||
if (!hasTemplateKWAndArgsInfo())
|
||||
return SourceLocation();
|
||||
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
|
||||
}
|
||||
|
||||
/// Retrieve the location of the right angle bracket ending the
|
||||
/// explicit template argument list following the member name, if any.
|
||||
SourceLocation getRAngleLoc() const {
|
||||
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
|
||||
if (!hasTemplateKWAndArgsInfo())
|
||||
return SourceLocation();
|
||||
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
|
||||
}
|
||||
|
||||
|
|
|
@ -738,6 +738,28 @@ protected:
|
|||
unsigned NumArgs;
|
||||
};
|
||||
|
||||
class CXXDependentScopeMemberExprBitfields {
|
||||
friend class ASTStmtReader;
|
||||
friend class CXXDependentScopeMemberExpr;
|
||||
|
||||
unsigned : NumExprBits;
|
||||
|
||||
/// Whether this member expression used the '->' operator or
|
||||
/// the '.' operator.
|
||||
unsigned IsArrow : 1;
|
||||
|
||||
/// Whether this member expression has info for explicit template
|
||||
/// keyword and arguments.
|
||||
unsigned HasTemplateKWAndArgsInfo : 1;
|
||||
|
||||
/// See getFirstQualifierFoundInScope() and the comment listing
|
||||
/// the trailing objects.
|
||||
unsigned HasFirstQualifierFoundInScope : 1;
|
||||
|
||||
/// The location of the '->' or '.' operator.
|
||||
SourceLocation OperatorLoc;
|
||||
};
|
||||
|
||||
//===--- C++ Coroutines TS bitfields classes ---===//
|
||||
|
||||
class CoawaitExprBitfields {
|
||||
|
@ -825,6 +847,7 @@ protected:
|
|||
CXXConstructExprBitfields CXXConstructExprBits;
|
||||
ExprWithCleanupsBitfields ExprWithCleanupsBits;
|
||||
CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits;
|
||||
CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits;
|
||||
|
||||
// C++ Coroutines TS expressions
|
||||
CoawaitExprBitfields CoawaitBits;
|
||||
|
|
|
@ -1301,24 +1301,26 @@ SourceLocation CXXUnresolvedConstructExpr::getBeginLoc() const {
|
|||
}
|
||||
|
||||
CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
|
||||
const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow,
|
||||
const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
|
||||
SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
|
||||
SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
|
||||
DeclarationNameInfo MemberNameInfo,
|
||||
const TemplateArgumentListInfo *TemplateArgs)
|
||||
: Expr(CXXDependentScopeMemberExprClass, C.DependentTy, VK_LValue,
|
||||
: Expr(CXXDependentScopeMemberExprClass, Ctx.DependentTy, VK_LValue,
|
||||
OK_Ordinary, true, true, true,
|
||||
((Base && Base->containsUnexpandedParameterPack()) ||
|
||||
(QualifierLoc &&
|
||||
QualifierLoc.getNestedNameSpecifier()
|
||||
->containsUnexpandedParameterPack()) ||
|
||||
(QualifierLoc && QualifierLoc.getNestedNameSpecifier()
|
||||
->containsUnexpandedParameterPack()) ||
|
||||
MemberNameInfo.containsUnexpandedParameterPack())),
|
||||
Base(Base), BaseType(BaseType), IsArrow(IsArrow),
|
||||
HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
|
||||
TemplateKWLoc.isValid()),
|
||||
OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc),
|
||||
FirstQualifierFoundInScope(FirstQualifierFoundInScope),
|
||||
Base(Base), BaseType(BaseType), QualifierLoc(QualifierLoc),
|
||||
MemberNameInfo(MemberNameInfo) {
|
||||
CXXDependentScopeMemberExprBits.IsArrow = IsArrow;
|
||||
CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo =
|
||||
(TemplateArgs != nullptr) || TemplateKWLoc.isValid();
|
||||
CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope =
|
||||
FirstQualifierFoundInScope != nullptr;
|
||||
CXXDependentScopeMemberExprBits.OperatorLoc = OperatorLoc;
|
||||
|
||||
if (TemplateArgs) {
|
||||
bool Dependent = true;
|
||||
bool InstantiationDependent = true;
|
||||
|
@ -1332,56 +1334,54 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
|
|||
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
|
||||
TemplateKWLoc);
|
||||
}
|
||||
|
||||
if (hasFirstQualifierFoundInScope())
|
||||
*getTrailingObjects<NamedDecl *>() = FirstQualifierFoundInScope;
|
||||
}
|
||||
|
||||
CXXDependentScopeMemberExpr *
|
||||
CXXDependentScopeMemberExpr::Create(const ASTContext &C,
|
||||
Expr *Base, QualType BaseType, bool IsArrow,
|
||||
SourceLocation OperatorLoc,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
SourceLocation TemplateKWLoc,
|
||||
NamedDecl *FirstQualifierFoundInScope,
|
||||
DeclarationNameInfo MemberNameInfo,
|
||||
const TemplateArgumentListInfo *TemplateArgs) {
|
||||
bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
|
||||
CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
|
||||
EmptyShell Empty, bool HasTemplateKWAndArgsInfo,
|
||||
bool HasFirstQualifierFoundInScope)
|
||||
: Expr(CXXDependentScopeMemberExprClass, Empty) {
|
||||
CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo =
|
||||
HasTemplateKWAndArgsInfo;
|
||||
CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope =
|
||||
HasFirstQualifierFoundInScope;
|
||||
}
|
||||
|
||||
CXXDependentScopeMemberExpr *CXXDependentScopeMemberExpr::Create(
|
||||
const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
|
||||
SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
|
||||
SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
|
||||
DeclarationNameInfo MemberNameInfo,
|
||||
const TemplateArgumentListInfo *TemplateArgs) {
|
||||
bool HasTemplateKWAndArgsInfo =
|
||||
(TemplateArgs != nullptr) || TemplateKWLoc.isValid();
|
||||
unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0;
|
||||
std::size_t Size =
|
||||
totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
|
||||
HasTemplateKWAndArgsInfo, NumTemplateArgs);
|
||||
bool HasFirstQualifierFoundInScope = FirstQualifierFoundInScope != nullptr;
|
||||
|
||||
void *Mem = C.Allocate(Size, alignof(CXXDependentScopeMemberExpr));
|
||||
return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType,
|
||||
IsArrow, OperatorLoc,
|
||||
QualifierLoc,
|
||||
TemplateKWLoc,
|
||||
FirstQualifierFoundInScope,
|
||||
MemberNameInfo, TemplateArgs);
|
||||
unsigned Size = totalSizeToAlloc<ASTTemplateKWAndArgsInfo,
|
||||
TemplateArgumentLoc, NamedDecl *>(
|
||||
HasTemplateKWAndArgsInfo, NumTemplateArgs, HasFirstQualifierFoundInScope);
|
||||
|
||||
void *Mem = Ctx.Allocate(Size, alignof(CXXDependentScopeMemberExpr));
|
||||
return new (Mem) CXXDependentScopeMemberExpr(
|
||||
Ctx, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc, TemplateKWLoc,
|
||||
FirstQualifierFoundInScope, MemberNameInfo, TemplateArgs);
|
||||
}
|
||||
|
||||
CXXDependentScopeMemberExpr *
|
||||
CXXDependentScopeMemberExpr::CreateEmpty(const ASTContext &C,
|
||||
bool HasTemplateKWAndArgsInfo,
|
||||
unsigned NumTemplateArgs) {
|
||||
CXXDependentScopeMemberExpr *CXXDependentScopeMemberExpr::CreateEmpty(
|
||||
const ASTContext &Ctx, bool HasTemplateKWAndArgsInfo,
|
||||
unsigned NumTemplateArgs, bool HasFirstQualifierFoundInScope) {
|
||||
assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
|
||||
std::size_t Size =
|
||||
totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
|
||||
HasTemplateKWAndArgsInfo, NumTemplateArgs);
|
||||
void *Mem = C.Allocate(Size, alignof(CXXDependentScopeMemberExpr));
|
||||
auto *E =
|
||||
new (Mem) CXXDependentScopeMemberExpr(C, nullptr, QualType(),
|
||||
false, SourceLocation(),
|
||||
NestedNameSpecifierLoc(),
|
||||
SourceLocation(), nullptr,
|
||||
DeclarationNameInfo(), nullptr);
|
||||
E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
|
||||
return E;
|
||||
}
|
||||
|
||||
bool CXXDependentScopeMemberExpr::isImplicitAccess() const {
|
||||
if (!Base)
|
||||
return true;
|
||||
unsigned Size = totalSizeToAlloc<ASTTemplateKWAndArgsInfo,
|
||||
TemplateArgumentLoc, NamedDecl *>(
|
||||
HasTemplateKWAndArgsInfo, NumTemplateArgs, HasFirstQualifierFoundInScope);
|
||||
|
||||
return cast<Expr>(Base)->isImplicitCXXThis();
|
||||
void *Mem = Ctx.Allocate(Size, alignof(CXXDependentScopeMemberExpr));
|
||||
return new (Mem) CXXDependentScopeMemberExpr(
|
||||
EmptyShell(), HasTemplateKWAndArgsInfo, HasFirstQualifierFoundInScope);
|
||||
}
|
||||
|
||||
static bool hasOnlyNonStaticMemberFunctions(UnresolvedSetIterator begin,
|
||||
|
|
|
@ -1584,22 +1584,37 @@ void ASTStmtReader::VisitExprWithCleanups(ExprWithCleanups *E) {
|
|||
E->SubExpr = Record.readSubExpr();
|
||||
}
|
||||
|
||||
void
|
||||
ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
|
||||
void ASTStmtReader::VisitCXXDependentScopeMemberExpr(
|
||||
CXXDependentScopeMemberExpr *E) {
|
||||
VisitExpr(E);
|
||||
|
||||
if (Record.readInt()) // HasTemplateKWAndArgsInfo
|
||||
bool HasTemplateKWAndArgsInfo = Record.readInt();
|
||||
unsigned NumTemplateArgs = Record.readInt();
|
||||
bool HasFirstQualifierFoundInScope = Record.readInt();
|
||||
|
||||
assert((HasTemplateKWAndArgsInfo == E->hasTemplateKWAndArgsInfo()) &&
|
||||
"Wrong HasTemplateKWAndArgsInfo!");
|
||||
assert(
|
||||
(HasFirstQualifierFoundInScope == E->hasFirstQualifierFoundInScope()) &&
|
||||
"Wrong HasFirstQualifierFoundInScope!");
|
||||
|
||||
if (HasTemplateKWAndArgsInfo)
|
||||
ReadTemplateKWAndArgsInfo(
|
||||
*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
|
||||
E->getTrailingObjects<TemplateArgumentLoc>(),
|
||||
/*NumTemplateArgs=*/Record.readInt());
|
||||
E->getTrailingObjects<TemplateArgumentLoc>(), NumTemplateArgs);
|
||||
|
||||
E->Base = Record.readSubExpr();
|
||||
assert((NumTemplateArgs == E->getNumTemplateArgs()) &&
|
||||
"Wrong NumTemplateArgs!");
|
||||
|
||||
E->CXXDependentScopeMemberExprBits.IsArrow = Record.readInt();
|
||||
E->CXXDependentScopeMemberExprBits.OperatorLoc = ReadSourceLocation();
|
||||
E->BaseType = Record.readType();
|
||||
E->IsArrow = Record.readInt();
|
||||
E->OperatorLoc = ReadSourceLocation();
|
||||
E->QualifierLoc = Record.readNestedNameSpecifierLoc();
|
||||
E->FirstQualifierFoundInScope = ReadDeclAs<NamedDecl>();
|
||||
E->Base = Record.readSubExpr();
|
||||
|
||||
if (HasFirstQualifierFoundInScope)
|
||||
*E->getTrailingObjects<NamedDecl *>() = ReadDeclAs<NamedDecl>();
|
||||
|
||||
ReadDeclarationNameInfo(E->MemberNameInfo);
|
||||
}
|
||||
|
||||
|
@ -3224,11 +3239,12 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
|
|||
break;
|
||||
|
||||
case EXPR_CXX_DEPENDENT_SCOPE_MEMBER:
|
||||
S = CXXDependentScopeMemberExpr::CreateEmpty(Context,
|
||||
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
|
||||
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
|
||||
? Record[ASTStmtReader::NumExprFields + 1]
|
||||
: 0);
|
||||
S = CXXDependentScopeMemberExpr::CreateEmpty(
|
||||
Context,
|
||||
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
|
||||
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1],
|
||||
/*HasFirstQualifierFoundInScope=*/
|
||||
Record[ASTStmtReader::NumExprFields + 2]);
|
||||
break;
|
||||
|
||||
case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF:
|
||||
|
|
|
@ -1554,31 +1554,36 @@ void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
|
|||
Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
|
||||
}
|
||||
|
||||
void
|
||||
ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
|
||||
void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
|
||||
CXXDependentScopeMemberExpr *E) {
|
||||
VisitExpr(E);
|
||||
|
||||
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
|
||||
// emitted first.
|
||||
// Don't emit anything here (or if you do you will have to update
|
||||
// the corresponding deserialization function).
|
||||
|
||||
Record.push_back(E->HasTemplateKWAndArgsInfo);
|
||||
if (E->HasTemplateKWAndArgsInfo) {
|
||||
Record.push_back(E->hasTemplateKWAndArgsInfo());
|
||||
Record.push_back(E->getNumTemplateArgs());
|
||||
Record.push_back(E->hasFirstQualifierFoundInScope());
|
||||
|
||||
if (E->hasTemplateKWAndArgsInfo()) {
|
||||
const ASTTemplateKWAndArgsInfo &ArgInfo =
|
||||
*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
|
||||
Record.push_back(ArgInfo.NumTemplateArgs);
|
||||
AddTemplateKWAndArgsInfo(ArgInfo,
|
||||
E->getTrailingObjects<TemplateArgumentLoc>());
|
||||
}
|
||||
|
||||
Record.push_back(E->isArrow());
|
||||
Record.AddSourceLocation(E->getOperatorLoc());
|
||||
Record.AddTypeRef(E->getBaseType());
|
||||
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
||||
if (!E->isImplicitAccess())
|
||||
Record.AddStmt(E->getBase());
|
||||
else
|
||||
Record.AddStmt(nullptr);
|
||||
Record.AddTypeRef(E->getBaseType());
|
||||
Record.push_back(E->isArrow());
|
||||
Record.AddSourceLocation(E->getOperatorLoc());
|
||||
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
||||
Record.AddDeclRef(E->getFirstQualifierFoundInScope());
|
||||
|
||||
if (E->hasFirstQualifierFoundInScope())
|
||||
Record.AddDeclRef(E->getFirstQualifierFoundInScope());
|
||||
|
||||
Record.AddDeclarationNameInfo(E->MemberNameInfo);
|
||||
Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue