Skip to content

Commit a421d32

Browse files
committed
[FOLD] store all results found by unqualified lookup for the first component name of a member-qualified nested-name-specifier
1 parent 71e6bae commit a421d32

22 files changed

+359
-226
lines changed

clang/include/clang/AST/ExprCXX.h

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3672,8 +3672,10 @@ class CXXUnresolvedConstructExpr final
36723672
class CXXDependentScopeMemberExpr final
36733673
: public Expr,
36743674
private llvm::TrailingObjects<CXXDependentScopeMemberExpr,
3675+
NestedNameSpecifierLoc,
3676+
DeclAccessPair,
36753677
ASTTemplateKWAndArgsInfo,
3676-
TemplateArgumentLoc, NamedDecl *> {
3678+
TemplateArgumentLoc> {
36773679
friend class ASTStmtReader;
36783680
friend class ASTStmtWriter;
36793681
friend TrailingObjects;
@@ -3686,17 +3688,15 @@ class CXXDependentScopeMemberExpr final
36863688
/// implicit accesses.
36873689
QualType BaseType;
36883690

3689-
/// The nested-name-specifier that precedes the member name, if any.
3690-
/// FIXME: This could be in principle store as a trailing object.
3691-
/// However the performance impact of doing so should be investigated first.
3692-
NestedNameSpecifierLoc QualifierLoc;
3693-
36943691
/// The member to which this member expression refers, which
36953692
/// can be name, overloaded operator, or destructor.
36963693
///
36973694
/// FIXME: could also be a template-id
36983695
DeclarationNameInfo MemberNameInfo;
36993696

3697+
/// The location of the '->' or '.' operator.
3698+
SourceLocation OperatorLoc;
3699+
37003700
// CXXDependentScopeMemberExpr is followed by several trailing objects,
37013701
// some of which optional. They are in order:
37023702
//
@@ -3716,8 +3716,16 @@ class CXXDependentScopeMemberExpr final
37163716
return CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo;
37173717
}
37183718

3719-
bool hasFirstQualifierFoundInScope() const {
3720-
return CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope;
3719+
unsigned getNumUnqualifiedLookups() const {
3720+
return CXXDependentScopeMemberExprBits.NumUnqualifiedLookups;
3721+
}
3722+
3723+
unsigned numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
3724+
return hasQualifier();
3725+
}
3726+
3727+
unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const {
3728+
return getNumUnqualifiedLookups();
37213729
}
37223730

37233731
unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
@@ -3728,33 +3736,35 @@ class CXXDependentScopeMemberExpr final
37283736
return getNumTemplateArgs();
37293737
}
37303738

3731-
unsigned numTrailingObjects(OverloadToken<NamedDecl *>) const {
3732-
return hasFirstQualifierFoundInScope();
3733-
}
3734-
37353739
CXXDependentScopeMemberExpr(const ASTContext &Ctx, Expr *Base,
37363740
QualType BaseType, bool IsArrow,
37373741
SourceLocation OperatorLoc,
37383742
NestedNameSpecifierLoc QualifierLoc,
37393743
SourceLocation TemplateKWLoc,
3740-
NamedDecl *FirstQualifierFoundInScope,
3744+
ArrayRef<DeclAccessPair> UnqualifiedLookups,
37413745
DeclarationNameInfo MemberNameInfo,
37423746
const TemplateArgumentListInfo *TemplateArgs);
37433747

3744-
CXXDependentScopeMemberExpr(EmptyShell Empty, bool HasTemplateKWAndArgsInfo,
3745-
bool HasFirstQualifierFoundInScope);
3748+
CXXDependentScopeMemberExpr(EmptyShell Empty, bool HasQualifier,
3749+
unsigned NumUnqualifiedLookups,
3750+
bool HasTemplateKWAndArgsInfo);
37463751

37473752
public:
37483753
static CXXDependentScopeMemberExpr *
3749-
Create(const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
3750-
SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
3751-
SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
3754+
Create(const ASTContext &Ctx, Expr *Base,
3755+
QualType BaseType, bool IsArrow,
3756+
SourceLocation OperatorLoc,
3757+
NestedNameSpecifierLoc QualifierLoc,
3758+
SourceLocation TemplateKWLoc,
3759+
ArrayRef<DeclAccessPair> UnqualifiedLookups,
37523760
DeclarationNameInfo MemberNameInfo,
37533761
const TemplateArgumentListInfo *TemplateArgs);
37543762

37553763
static CXXDependentScopeMemberExpr *
3756-
CreateEmpty(const ASTContext &Ctx, bool HasTemplateKWAndArgsInfo,
3757-
unsigned NumTemplateArgs, bool HasFirstQualifierFoundInScope);
3764+
CreateEmpty(const ASTContext &Ctx, bool HasQualifier,
3765+
unsigned NumUnqualifiedLookups,
3766+
bool HasTemplateKWAndArgsInfo,
3767+
unsigned NumTemplateArgs);
37583768

37593769
/// True if this is an implicit access, i.e. one in which the
37603770
/// member being accessed was not written in the source. The source
@@ -3780,18 +3790,32 @@ class CXXDependentScopeMemberExpr final
37803790

37813791
/// Retrieve the location of the '->' or '.' operator.
37823792
SourceLocation getOperatorLoc() const {
3783-
return CXXDependentScopeMemberExprBits.OperatorLoc;
3793+
return OperatorLoc;
3794+
}
3795+
3796+
/// Determines whether this member expression had a nested-name-specifier
3797+
/// prior to the name of the member, e.g., x->Base::foo.
3798+
bool hasQualifier() const {
3799+
return CXXDependentScopeMemberExprBits.HasQualifier;
37843800
}
37853801

3786-
/// Retrieve the nested-name-specifier that qualifies the member name.
3802+
/// If the member name was qualified, retrieves the nested-name-specifier
3803+
/// that precedes the member name, with source-location information.
3804+
NestedNameSpecifierLoc getQualifierLoc() const {
3805+
if (!hasQualifier())
3806+
return NestedNameSpecifierLoc();
3807+
return *getTrailingObjects<NestedNameSpecifierLoc>();
3808+
}
3809+
3810+
/// If the member name was qualified, retrieves the
3811+
/// nested-name-specifier that precedes the member name. Otherwise, returns
3812+
/// NULL.
37873813
NestedNameSpecifier *getQualifier() const {
3788-
return QualifierLoc.getNestedNameSpecifier();
3814+
return getQualifierLoc().getNestedNameSpecifier();
37893815
}
37903816

3791-
/// Retrieve the nested-name-specifier that qualifies the member
3792-
/// name, with source location information.
3793-
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
37943817

3818+
#if 0
37953819
/// Retrieve the first part of the nested-name-specifier that was
37963820
/// found in the scope of the member access expression when the member access
37973821
/// was initially parsed.
@@ -3808,6 +3832,13 @@ class CXXDependentScopeMemberExpr final
38083832
return nullptr;
38093833
return *getTrailingObjects<NamedDecl *>();
38103834
}
3835+
#endif
3836+
3837+
ArrayRef<DeclAccessPair> unqualified_lookups() const {
3838+
if (!getNumUnqualifiedLookups())
3839+
return std::nullopt;
3840+
return {getTrailingObjects<DeclAccessPair>(), getNumUnqualifiedLookups()};
3841+
}
38113842

38123843
/// Retrieve the name of the member that this expression refers to.
38133844
const DeclarationNameInfo &getMemberNameInfo() const {

clang/include/clang/AST/Stmt.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,18 +1020,25 @@ class alignas(void *) Stmt {
10201020
LLVM_PREFERRED_TYPE(bool)
10211021
unsigned IsArrow : 1;
10221022

1023+
/// True if this member expression used a nested-name-specifier to
1024+
/// refer to the member, e.g., "x->Base::f".
1025+
LLVM_PREFERRED_TYPE(bool)
1026+
unsigned HasQualifier : 1;
1027+
10231028
/// Whether this member expression has info for explicit template
10241029
/// keyword and arguments.
10251030
LLVM_PREFERRED_TYPE(bool)
10261031
unsigned HasTemplateKWAndArgsInfo : 1;
10271032

1033+
#if 0
10281034
/// See getFirstQualifierFoundInScope() and the comment listing
10291035
/// the trailing objects.
10301036
LLVM_PREFERRED_TYPE(bool)
10311037
unsigned HasFirstQualifierFoundInScope : 1;
1032-
1033-
/// The location of the '->' or '.' operator.
1034-
SourceLocation OperatorLoc;
1038+
#endif
1039+
/// Number of declarations found by unqualified lookup for the
1040+
/// first component name of the nested-name-specifier.
1041+
unsigned NumUnqualifiedLookups;
10351042
};
10361043

10371044
class OverloadExprBitfields {

clang/include/clang/AST/UnresolvedSet.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ class UnresolvedSetImpl {
9696
decls().push_back(DeclAccessPair::make(D, AS));
9797
}
9898

99+
void addAllDecls(ArrayRef<DeclAccessPair> Other) {
100+
append(iterator(Other.begin()), iterator(Other.end()));
101+
}
102+
99103
/// Replaces the given declaration with the new one, once.
100104
///
101105
/// \return true if the set changed

clang/include/clang/Sema/DeclSpec.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class CXXScopeSpec {
7575
SourceRange Range;
7676
NestedNameSpecifierLocBuilder Builder;
7777
ArrayRef<TemplateParameterList *> TemplateParamLists;
78-
NamedDecl *FoundFirstQualifierInScope;
78+
ArrayRef<DeclAccessPair> UnqualifiedLookups;
7979

8080
public:
8181
SourceRange getRange() const { return Range; }
@@ -92,11 +92,11 @@ class CXXScopeSpec {
9292
return TemplateParamLists;
9393
}
9494

95-
void setFoundFirstQualifierInScope(NamedDecl *Found) {
96-
FoundFirstQualifierInScope = Found;
95+
void setUnqualifiedLookups(ArrayRef<DeclAccessPair> Found) {
96+
UnqualifiedLookups = Found;
9797
}
98-
NamedDecl *getFirstQualifierFoundInScope() const {
99-
return FoundFirstQualifierInScope;
98+
ArrayRef<DeclAccessPair> getUnqualifiedLookups() const {
99+
return UnqualifiedLookups;
100100
}
101101

102102
/// Retrieve the representation of the nested-name-specifier.

clang/include/clang/Sema/Lookup.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,11 +483,15 @@ class LookupResult {
483483
ResultKind = Found;
484484
}
485485

486+
void addAllDecls(ArrayRef<DeclAccessPair> Other) {
487+
Decls.addAllDecls(Other);
488+
ResultKind = Found;
489+
}
490+
486491
/// Add all the declarations from another set of lookup
487492
/// results.
488493
void addAllDecls(const LookupResult &Other) {
489-
Decls.append(Other.Decls.begin(), Other.Decls.end());
490-
ResultKind = Found;
494+
addAllDecls(Other.Decls.pairs());
491495
}
492496

493497
/// Determine whether no result was found because we could not

clang/include/clang/Sema/Sema.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,7 +2390,7 @@ class Sema final : public SemaBase {
23902390

23912391
bool isAcceptableNestedNameSpecifier(const NamedDecl *SD,
23922392
bool *CanCorrect = nullptr);
2393-
NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
2393+
bool LookupFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS, UnresolvedSetImpl &R);
23942394

23952395
/// Keeps information about an identifier in a nested-name-spec.
23962396
///
@@ -2423,7 +2423,6 @@ class Sema final : public SemaBase {
24232423

24242424
bool BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
24252425
bool EnteringContext, CXXScopeSpec &SS,
2426-
NamedDecl *ScopeLookupResult,
24272426
bool ErrorRecoveryLookup,
24282427
bool *IsCorrectedToColon = nullptr,
24292428
bool OnlyNamespace = false);
@@ -6938,7 +6937,7 @@ class Sema final : public SemaBase {
69386937
ExprResult ActOnDependentMemberExpr(
69396938
Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OpLoc,
69406939
const CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
6941-
NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo,
6940+
const DeclarationNameInfo &NameInfo,
69426941
const TemplateArgumentListInfo *TemplateArgs);
69436942

69446943
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
@@ -6973,15 +6972,14 @@ class Sema final : public SemaBase {
69736972
ExprResult BuildMemberReferenceExpr(
69746973
Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow,
69756974
CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
6976-
NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo,
6975+
const DeclarationNameInfo &NameInfo,
69776976
const TemplateArgumentListInfo *TemplateArgs, const Scope *S,
69786977
ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
69796978

69806979
ExprResult
69816980
BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc,
69826981
bool IsArrow, const CXXScopeSpec &SS,
6983-
SourceLocation TemplateKWLoc,
6984-
NamedDecl *FirstQualifierInScope, LookupResult &R,
6982+
SourceLocation TemplateKWLoc, LookupResult &R,
69856983
const TemplateArgumentListInfo *TemplateArgs,
69866984
const Scope *S, bool SuppressQualifierCheck = false,
69876985
ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);

clang/lib/AST/ASTImporter.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8432,8 +8432,15 @@ ExpectedStmt ASTNodeImporter::VisitCXXDependentScopeMemberExpr(
84328432
auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
84338433
auto ToQualifierLoc = importChecked(Err, E->getQualifierLoc());
84348434
auto ToTemplateKeywordLoc = importChecked(Err, E->getTemplateKeywordLoc());
8435-
auto ToFirstQualifierFoundInScope =
8436-
importChecked(Err, E->getFirstQualifierFoundInScope());
8435+
8436+
8437+
UnresolvedSet<8> ToUnqualifiedLookups;
8438+
for (auto D : E->unqualified_lookups())
8439+
if (auto ToDOrErr = import(D.getDecl()))
8440+
ToUnqualifiedLookups.addDecl(*ToDOrErr);
8441+
else
8442+
return ToDOrErr.takeError();
8443+
84378444
if (Err)
84388445
return std::move(Err);
84398446

@@ -8467,7 +8474,7 @@ ExpectedStmt ASTNodeImporter::VisitCXXDependentScopeMemberExpr(
84678474

84688475
return CXXDependentScopeMemberExpr::Create(
84698476
Importer.getToContext(), ToBase, ToType, E->isArrow(), ToOperatorLoc,
8470-
ToQualifierLoc, ToTemplateKeywordLoc, ToFirstQualifierFoundInScope,
8477+
ToQualifierLoc, ToTemplateKeywordLoc, ToUnqualifiedLookups.pairs(),
84718478
ToMemberNameInfo, ResInfo);
84728479
}
84738480

0 commit comments

Comments
 (0)