Skip to content

[Clang][AST][NFC] MemberExpr stores NestedNameSpecifierLoc and DeclAccessPair separately #86678

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 14 additions & 23 deletions clang/include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -3163,23 +3163,12 @@ class CallExpr : public Expr {
}
};

/// 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;
Expand All @@ -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;
Expand Down Expand Up @@ -3264,24 +3255,24 @@ class MemberExpr final

/// 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
Expand Down
10 changes: 6 additions & 4 deletions clang/include/clang/AST/Stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -583,11 +583,13 @@ class alignas(void *) Stmt {
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>,
Expand Down
41 changes: 20 additions & 21 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

MemberExprNameQualifier *NQ =
E->getTrailingObjects<MemberExprNameQualifier>();
NQ->QualifierLoc = QualifierLoc;
NQ->FoundDecl = FoundDecl;
}
E->MemberExprBits.HasQualifier = HasQualifier;
E->MemberExprBits.HasFoundDecl = HasFoundDecl;
E->MemberExprBits.HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;

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();
Expand All @@ -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());
}
Expand Down
26 changes: 9 additions & 17 deletions clang/lib/Serialization/ASTReaderStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
11 changes: 4 additions & 7 deletions clang/lib/Serialization/ASTWriterStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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>());
Expand Down