[Clang][AST][NFC] MemberExpr stores NestedNameSpecifierLoc and DeclAccessPair separately (#86678)
Currently, `MemberExpr` allocates a trailing `MemberExprNameQualifier` object if it either has a `NestedNameSpecifierLoc`, or if it names a member found via using declaration. Since the presence of a _nested-name-specifier_ does not necessarily imply the named member was found via using declaration, this patch removes `MemberExprNameQualifier` and allocates the members separately.
This commit is contained in:
parent
82d8a95611
commit
ea9a66ea8b
@ -3163,23 +3163,12 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// Extra data stored in some MemberExpr objects.
|
||||
struct MemberExprNameQualifier {
|
||||
/// The nested-name-specifier that qualifies the name, including
|
||||
/// source-location information.
|
||||
NestedNameSpecifierLoc QualifierLoc;
|
||||
|
||||
/// The DeclAccessPair through which the MemberDecl was found due to
|
||||
/// name qualifiers.
|
||||
DeclAccessPair FoundDecl;
|
||||
};
|
||||
|
||||
/// MemberExpr - [C99 6.5.2.3] Structure and Union Members. X->F and X.F.
|
||||
///
|
||||
class MemberExpr final
|
||||
: public Expr,
|
||||
private llvm::TrailingObjects<MemberExpr, MemberExprNameQualifier,
|
||||
ASTTemplateKWAndArgsInfo,
|
||||
private llvm::TrailingObjects<MemberExpr, NestedNameSpecifierLoc,
|
||||
DeclAccessPair, ASTTemplateKWAndArgsInfo,
|
||||
TemplateArgumentLoc> {
|
||||
friend class ASTReader;
|
||||
friend class ASTStmtReader;
|
||||
@ -3201,17 +3190,19 @@ class MemberExpr final
|
||||
/// MemberLoc - This is the location of the member name.
|
||||
SourceLocation MemberLoc;
|
||||
|
||||
size_t numTrailingObjects(OverloadToken<MemberExprNameQualifier>) const {
|
||||
return hasQualifierOrFoundDecl();
|
||||
size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
|
||||
return hasQualifier();
|
||||
}
|
||||
|
||||
size_t numTrailingObjects(OverloadToken<DeclAccessPair>) const {
|
||||
return hasFoundDecl();
|
||||
}
|
||||
|
||||
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
|
||||
return hasTemplateKWAndArgsInfo();
|
||||
}
|
||||
|
||||
bool hasQualifierOrFoundDecl() const {
|
||||
return MemberExprBits.HasQualifierOrFoundDecl;
|
||||
}
|
||||
bool hasFoundDecl() const { return MemberExprBits.HasFoundDecl; }
|
||||
|
||||
bool hasTemplateKWAndArgsInfo() const {
|
||||
return MemberExprBits.HasTemplateKWAndArgsInfo;
|
||||
@ -3264,24 +3255,24 @@ public:
|
||||
|
||||
/// Retrieves the declaration found by lookup.
|
||||
DeclAccessPair getFoundDecl() const {
|
||||
if (!hasQualifierOrFoundDecl())
|
||||
if (!hasFoundDecl())
|
||||
return DeclAccessPair::make(getMemberDecl(),
|
||||
getMemberDecl()->getAccess());
|
||||
return getTrailingObjects<MemberExprNameQualifier>()->FoundDecl;
|
||||
return *getTrailingObjects<DeclAccessPair>();
|
||||
}
|
||||
|
||||
/// Determines whether this member expression actually had
|
||||
/// a C++ nested-name-specifier prior to the name of the member, e.g.,
|
||||
/// x->Base::foo.
|
||||
bool hasQualifier() const { return getQualifier() != nullptr; }
|
||||
bool hasQualifier() const { return MemberExprBits.HasQualifier; }
|
||||
|
||||
/// If the member name was qualified, retrieves the
|
||||
/// nested-name-specifier that precedes the member name, with source-location
|
||||
/// information.
|
||||
NestedNameSpecifierLoc getQualifierLoc() const {
|
||||
if (!hasQualifierOrFoundDecl())
|
||||
if (!hasQualifier())
|
||||
return NestedNameSpecifierLoc();
|
||||
return getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc;
|
||||
return *getTrailingObjects<NestedNameSpecifierLoc>();
|
||||
}
|
||||
|
||||
/// If the member name was qualified, retrieves the
|
||||
|
||||
@ -583,11 +583,13 @@ protected:
|
||||
unsigned IsArrow : 1;
|
||||
|
||||
/// True if this member expression used a nested-name-specifier to
|
||||
/// refer to the member, e.g., "x->Base::f", or found its member via
|
||||
/// a using declaration. When true, a MemberExprNameQualifier
|
||||
/// structure is allocated immediately after the MemberExpr.
|
||||
/// refer to the member, e.g., "x->Base::f".
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned HasQualifierOrFoundDecl : 1;
|
||||
unsigned HasQualifier : 1;
|
||||
|
||||
// True if this member expression found its member via a using declaration.
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned HasFoundDecl : 1;
|
||||
|
||||
/// True if this member expression specified a template keyword
|
||||
/// and/or a template argument list explicitly, e.g., x->f<int>,
|
||||
|
||||
@ -1721,7 +1721,8 @@ MemberExpr::MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc,
|
||||
assert(!NameInfo.getName() ||
|
||||
MemberDecl->getDeclName() == NameInfo.getName());
|
||||
MemberExprBits.IsArrow = IsArrow;
|
||||
MemberExprBits.HasQualifierOrFoundDecl = false;
|
||||
MemberExprBits.HasQualifier = false;
|
||||
MemberExprBits.HasFoundDecl = false;
|
||||
MemberExprBits.HasTemplateKWAndArgsInfo = false;
|
||||
MemberExprBits.HadMultipleCandidates = false;
|
||||
MemberExprBits.NonOdrUseReason = NOUR;
|
||||
@ -1735,30 +1736,29 @@ MemberExpr *MemberExpr::Create(
|
||||
ValueDecl *MemberDecl, DeclAccessPair FoundDecl,
|
||||
DeclarationNameInfo NameInfo, const TemplateArgumentListInfo *TemplateArgs,
|
||||
QualType T, ExprValueKind VK, ExprObjectKind OK, NonOdrUseReason NOUR) {
|
||||
bool HasQualOrFound = QualifierLoc || FoundDecl.getDecl() != MemberDecl ||
|
||||
FoundDecl.getAccess() != MemberDecl->getAccess();
|
||||
bool HasQualifier = QualifierLoc.hasQualifier();
|
||||
bool HasFoundDecl = FoundDecl.getDecl() != MemberDecl ||
|
||||
FoundDecl.getAccess() != MemberDecl->getAccess();
|
||||
bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
|
||||
std::size_t Size =
|
||||
totalSizeToAlloc<MemberExprNameQualifier, ASTTemplateKWAndArgsInfo,
|
||||
TemplateArgumentLoc>(
|
||||
HasQualOrFound ? 1 : 0, HasTemplateKWAndArgsInfo ? 1 : 0,
|
||||
totalSizeToAlloc<NestedNameSpecifierLoc, DeclAccessPair,
|
||||
ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
|
||||
HasQualifier, HasFoundDecl, HasTemplateKWAndArgsInfo,
|
||||
TemplateArgs ? TemplateArgs->size() : 0);
|
||||
|
||||
void *Mem = C.Allocate(Size, alignof(MemberExpr));
|
||||
MemberExpr *E = new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, MemberDecl,
|
||||
NameInfo, T, VK, OK, NOUR);
|
||||
|
||||
if (HasQualOrFound) {
|
||||
E->MemberExprBits.HasQualifierOrFoundDecl = true;
|
||||
E->MemberExprBits.HasQualifier = HasQualifier;
|
||||
E->MemberExprBits.HasFoundDecl = HasFoundDecl;
|
||||
E->MemberExprBits.HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
|
||||
|
||||
MemberExprNameQualifier *NQ =
|
||||
E->getTrailingObjects<MemberExprNameQualifier>();
|
||||
NQ->QualifierLoc = QualifierLoc;
|
||||
NQ->FoundDecl = FoundDecl;
|
||||
}
|
||||
|
||||
E->MemberExprBits.HasTemplateKWAndArgsInfo =
|
||||
TemplateArgs || TemplateKWLoc.isValid();
|
||||
if (HasQualifier)
|
||||
new (E->getTrailingObjects<NestedNameSpecifierLoc>())
|
||||
NestedNameSpecifierLoc(QualifierLoc);
|
||||
if (HasFoundDecl)
|
||||
*E->getTrailingObjects<DeclAccessPair>() = FoundDecl;
|
||||
|
||||
// FIXME: remove remaining dependence computation to computeDependence().
|
||||
auto Deps = E->getDependence();
|
||||
@ -1785,12 +1785,11 @@ MemberExpr *MemberExpr::CreateEmpty(const ASTContext &Context,
|
||||
unsigned NumTemplateArgs) {
|
||||
assert((!NumTemplateArgs || HasTemplateKWAndArgsInfo) &&
|
||||
"template args but no template arg info?");
|
||||
bool HasQualOrFound = HasQualifier || HasFoundDecl;
|
||||
std::size_t Size =
|
||||
totalSizeToAlloc<MemberExprNameQualifier, ASTTemplateKWAndArgsInfo,
|
||||
TemplateArgumentLoc>(HasQualOrFound ? 1 : 0,
|
||||
HasTemplateKWAndArgsInfo ? 1 : 0,
|
||||
NumTemplateArgs);
|
||||
totalSizeToAlloc<NestedNameSpecifierLoc, DeclAccessPair,
|
||||
ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
|
||||
HasQualifier, HasFoundDecl, HasTemplateKWAndArgsInfo,
|
||||
NumTemplateArgs);
|
||||
void *Mem = Context.Allocate(Size, alignof(MemberExpr));
|
||||
return new (Mem) MemberExpr(EmptyShell());
|
||||
}
|
||||
|
||||
@ -1047,30 +1047,22 @@ void ASTStmtReader::VisitMemberExpr(MemberExpr *E) {
|
||||
E->MemberDNLoc = Record.readDeclarationNameLoc(E->MemberDecl->getDeclName());
|
||||
E->MemberLoc = Record.readSourceLocation();
|
||||
E->MemberExprBits.IsArrow = CurrentUnpackingBits->getNextBit();
|
||||
E->MemberExprBits.HasQualifierOrFoundDecl = HasQualifier || HasFoundDecl;
|
||||
E->MemberExprBits.HasQualifier = HasQualifier;
|
||||
E->MemberExprBits.HasFoundDecl = HasFoundDecl;
|
||||
E->MemberExprBits.HasTemplateKWAndArgsInfo = HasTemplateInfo;
|
||||
E->MemberExprBits.HadMultipleCandidates = CurrentUnpackingBits->getNextBit();
|
||||
E->MemberExprBits.NonOdrUseReason =
|
||||
CurrentUnpackingBits->getNextBits(/*Width=*/2);
|
||||
E->MemberExprBits.OperatorLoc = Record.readSourceLocation();
|
||||
|
||||
if (HasQualifier || HasFoundDecl) {
|
||||
DeclAccessPair FoundDecl;
|
||||
if (HasFoundDecl) {
|
||||
auto *FoundD = Record.readDeclAs<NamedDecl>();
|
||||
auto AS = (AccessSpecifier)CurrentUnpackingBits->getNextBits(/*Width=*/2);
|
||||
FoundDecl = DeclAccessPair::make(FoundD, AS);
|
||||
} else {
|
||||
FoundDecl = DeclAccessPair::make(E->MemberDecl,
|
||||
E->MemberDecl->getAccess());
|
||||
}
|
||||
E->getTrailingObjects<MemberExprNameQualifier>()->FoundDecl = FoundDecl;
|
||||
if (HasQualifier)
|
||||
new (E->getTrailingObjects<NestedNameSpecifierLoc>())
|
||||
NestedNameSpecifierLoc(Record.readNestedNameSpecifierLoc());
|
||||
|
||||
NestedNameSpecifierLoc QualifierLoc;
|
||||
if (HasQualifier)
|
||||
QualifierLoc = Record.readNestedNameSpecifierLoc();
|
||||
E->getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc =
|
||||
QualifierLoc;
|
||||
if (HasFoundDecl) {
|
||||
auto *FoundD = Record.readDeclAs<NamedDecl>();
|
||||
auto AS = (AccessSpecifier)CurrentUnpackingBits->getNextBits(/*Width=*/2);
|
||||
*E->getTrailingObjects<DeclAccessPair>() = DeclAccessPair::make(FoundD, AS);
|
||||
}
|
||||
|
||||
if (HasTemplateInfo)
|
||||
|
||||
@ -970,10 +970,7 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
|
||||
VisitExpr(E);
|
||||
|
||||
bool HasQualifier = E->hasQualifier();
|
||||
bool HasFoundDecl =
|
||||
E->hasQualifierOrFoundDecl() &&
|
||||
(E->getFoundDecl().getDecl() != E->getMemberDecl() ||
|
||||
E->getFoundDecl().getAccess() != E->getMemberDecl()->getAccess());
|
||||
bool HasFoundDecl = E->hasFoundDecl();
|
||||
bool HasTemplateInfo = E->hasTemplateKWAndArgsInfo();
|
||||
unsigned NumTemplateArgs = E->getNumTemplateArgs();
|
||||
|
||||
@ -995,15 +992,15 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
|
||||
CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
|
||||
Record.AddSourceLocation(E->getOperatorLoc());
|
||||
|
||||
if (HasQualifier)
|
||||
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
||||
|
||||
if (HasFoundDecl) {
|
||||
DeclAccessPair FoundDecl = E->getFoundDecl();
|
||||
Record.AddDeclRef(FoundDecl.getDecl());
|
||||
CurrentPackingBits.addBits(FoundDecl.getAccess(), /*BitWidth=*/2);
|
||||
}
|
||||
|
||||
if (HasQualifier)
|
||||
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
||||
|
||||
if (HasTemplateInfo)
|
||||
AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
|
||||
E->getTrailingObjects<TemplateArgumentLoc>());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user