Skip to content

Commit a94165a

Browse files
committed
[PATCH 6/6] [clang] improve NestedNameSpecifier
1 parent 3c4412b commit a94165a

File tree

124 files changed

+3390
-3229
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+3390
-3229
lines changed

clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,9 @@ llvm::SmallVector<llvm::StringRef, 4> splitSymbolName(llvm::StringRef Name) {
3131
return Splitted;
3232
}
3333

34-
SourceLocation startLocationForType(TypeLoc TLoc) {
35-
// For elaborated types (e.g. `struct a::A`) we want the portion after the
36-
// `struct` but including the namespace qualifier, `a::`.
37-
if (TLoc.getTypeLocClass() == TypeLoc::Elaborated) {
38-
NestedNameSpecifierLoc NestedNameSpecifier =
39-
TLoc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
40-
if (NestedNameSpecifier.getNestedNameSpecifier())
41-
return NestedNameSpecifier.getBeginLoc();
42-
TLoc = TLoc.getNextTypeLoc();
43-
}
44-
return TLoc.getBeginLoc();
45-
}
46-
4734
SourceLocation endLocationForType(TypeLoc TLoc) {
48-
// Dig past any namespace or keyword qualifications.
49-
while (TLoc.getTypeLocClass() == TypeLoc::Elaborated ||
50-
TLoc.getTypeLocClass() == TypeLoc::Qualified)
51-
TLoc = TLoc.getNextTypeLoc();
35+
if (auto QTL = TLoc.getAs<QualifiedTypeLoc>())
36+
TLoc = QTL.getUnqualifiedLoc();
5237

5338
// The location for template specializations (e.g. Foo<int>) includes the
5439
// templated types in its location range. We want to restrict this to just
@@ -550,8 +535,8 @@ void ChangeNamespaceTool::run(
550535
Result.Nodes.getNodeAs<NestedNameSpecifierLoc>(
551536
"nested_specifier_loc")) {
552537
SourceLocation Start = Specifier->getBeginLoc();
553-
SourceLocation End = endLocationForType(Specifier->getTypeLoc());
554-
fixTypeLoc(Result, Start, End, Specifier->getTypeLoc());
538+
SourceLocation End = endLocationForType(Specifier->castAsTypeLoc());
539+
fixTypeLoc(Result, Start, End, Specifier->castAsTypeLoc());
555540
} else if (const auto *BaseInitializer =
556541
Result.Nodes.getNodeAs<CXXCtorInitializer>(
557542
"base_initializer")) {
@@ -562,19 +547,16 @@ void ChangeNamespaceTool::run(
562547
// filtered by matchers in some cases, e.g. the type is templated. We should
563548
// handle the record type qualifier instead.
564549
TypeLoc Loc = *TLoc;
565-
while (Loc.getTypeLocClass() == TypeLoc::Qualified)
566-
Loc = Loc.getNextTypeLoc();
567-
if (Loc.getTypeLocClass() == TypeLoc::Elaborated) {
568-
NestedNameSpecifierLoc NestedNameSpecifier =
569-
Loc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
570-
// FIXME: avoid changing injected class names.
571-
if (auto *NNS = NestedNameSpecifier.getNestedNameSpecifier()) {
572-
const Type *SpecifierType = NNS->getAsType();
573-
if (SpecifierType && SpecifierType->isRecordType())
574-
return;
575-
}
576-
}
577-
fixTypeLoc(Result, startLocationForType(Loc), endLocationForType(Loc), Loc);
550+
if (auto QTL = Loc.getAs<QualifiedTypeLoc>())
551+
Loc = QTL.getUnqualifiedLoc();
552+
// FIXME: avoid changing injected class names.
553+
if (NestedNameSpecifier NestedNameSpecifier =
554+
Loc.getPrefix().getNestedNameSpecifier();
555+
NestedNameSpecifier.getKind() == NestedNameSpecifier::Kind::Type &&
556+
NestedNameSpecifier.getAsType()->isRecordType())
557+
return;
558+
fixTypeLoc(Result, Loc.getNonElaboratedBeginLoc(), endLocationForType(Loc),
559+
Loc);
578560
} else if (const auto *VarRef =
579561
Result.Nodes.getNodeAs<DeclRefExpr>("var_ref")) {
580562
const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var_decl");
@@ -588,10 +570,9 @@ void ChangeNamespaceTool::run(
588570
} else if (const auto *EnumConstRef =
589571
Result.Nodes.getNodeAs<DeclRefExpr>("enum_const_ref")) {
590572
// Do not rename the reference if it is already scoped by the EnumDecl name.
591-
if (EnumConstRef->hasQualifier() &&
592-
EnumConstRef->getQualifier()->getKind() ==
593-
NestedNameSpecifier::SpecifierKind::TypeSpec &&
594-
EnumConstRef->getQualifier()->getAsType()->isEnumeralType())
573+
if (NestedNameSpecifier Qualifier = EnumConstRef->getQualifier();
574+
Qualifier.getKind() == NestedNameSpecifier::Kind::Type &&
575+
Qualifier.getAsType()->isEnumeralType())
595576
return;
596577
const auto *EnumConstDecl =
597578
Result.Nodes.getNodeAs<EnumConstantDecl>("enum_const_decl");

clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,8 @@ void ClangTidyDiagnosticConsumer::forwardDiagnostic(const Diagnostic &Info) {
533533
Builder << reinterpret_cast<const NamedDecl *>(Info.getRawArg(Index));
534534
break;
535535
case clang::DiagnosticsEngine::ak_nestednamespec:
536-
Builder << reinterpret_cast<NestedNameSpecifier *>(Info.getRawArg(Index));
536+
Builder << NestedNameSpecifier::getFromVoidPointer(
537+
reinterpret_cast<void *>(Info.getRawArg(Index)));
537538
break;
538539
case clang::DiagnosticsEngine::ak_declcontext:
539540
Builder << reinterpret_cast<DeclContext *>(Info.getRawArg(Index));

clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,17 @@ AST_MATCHER(QualType, isEnableIf) {
3333
BaseType = BaseType->getPointeeType().getTypePtr();
3434
}
3535
// Case: type parameter dependent (enable_if<is_integral<T>>).
36-
if (const auto *Dependent = BaseType->getAs<DependentNameType>()) {
37-
BaseType = Dependent->getQualifier()->getAsType();
38-
}
36+
if (const auto *Dependent = BaseType->getAs<DependentNameType>())
37+
BaseType = Dependent->getQualifier().getAsType();
3938
if (!BaseType)
4039
return false;
4140
if (CheckTemplate(BaseType->getAs<TemplateSpecializationType>()))
4241
return true; // Case: enable_if_t< >.
43-
if (const auto *Elaborated = BaseType->getAs<ElaboratedType>()) {
44-
if (const auto *Q = Elaborated->getQualifier())
45-
if (const auto *Qualifier = Q->getAsType()) {
46-
if (CheckTemplate(Qualifier->getAs<TemplateSpecializationType>())) {
47-
return true; // Case: enable_if< >::type.
48-
}
49-
}
50-
}
42+
if (const auto *TT = BaseType->getAs<TypedefType>())
43+
if (NestedNameSpecifier Q = TT->getQualifier();
44+
Q.getKind() == NestedNameSpecifier::Kind::Type)
45+
if (CheckTemplate(Q.getAsType()->getAs<TemplateSpecializationType>()))
46+
return true; // Case: enable_if< >::type.
5147
return false;
5248
}
5349
AST_MATCHER_P(TemplateTypeParmDecl, hasDefaultArgument,

clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,31 @@ static void replaceMoveWithForward(const UnresolvedLookupExpr *Callee,
3939
// std::move(). This will hopefully prevent erroneous replacements if the
4040
// code does unusual things (e.g. create an alias for std::move() in
4141
// another namespace).
42-
NestedNameSpecifier *NNS = Callee->getQualifier();
43-
if (!NNS) {
42+
NestedNameSpecifier NNS = Callee->getQualifier();
43+
switch (NNS.getKind()) {
44+
case NestedNameSpecifier::Kind::Null:
4445
// Called as "move" (i.e. presumably the code had a "using std::move;").
4546
// We still conservatively put a "std::" in front of the forward because
4647
// we don't know whether the code also had a "using std::forward;".
4748
Diag << FixItHint::CreateReplacement(CallRange, "std::" + ForwardName);
48-
} else if (const NamespaceBaseDecl *Namespace = NNS->getAsNamespace()) {
49+
break;
50+
case NestedNameSpecifier::Kind::Namespace: {
51+
auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();
4952
if (Namespace->getName() == "std") {
50-
if (!NNS->getPrefix()) {
53+
if (!Prefix) {
5154
// Called as "std::move".
5255
Diag << FixItHint::CreateReplacement(CallRange,
5356
"std::" + ForwardName);
54-
} else if (NNS->getPrefix()->getKind() == NestedNameSpecifier::Global) {
57+
} else if (Prefix.getKind() == NestedNameSpecifier::Kind::Global) {
5558
// Called as "::std::move".
5659
Diag << FixItHint::CreateReplacement(CallRange,
5760
"::std::" + ForwardName);
5861
}
5962
}
63+
break;
64+
}
65+
default:
66+
return;
6067
}
6168
}
6269
}

clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,6 @@ static bool incrementWithoutOverflow(const APSInt &Value, APSInt &Result) {
4545
return Value < Result;
4646
}
4747

48-
static bool areEquivalentNameSpecifier(const NestedNameSpecifier *Left,
49-
const NestedNameSpecifier *Right) {
50-
llvm::FoldingSetNodeID LeftID, RightID;
51-
Left->Profile(LeftID);
52-
Right->Profile(RightID);
53-
return LeftID == RightID;
54-
}
55-
5648
static bool areEquivalentExpr(const Expr *Left, const Expr *Right) {
5749
if (!Left || !Right)
5850
return !Left && !Right;

clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ void UnusedAliasDeclsCheck::check(const MatchFinder::MatchResult &Result) {
3535
}
3636

3737
if (const auto *NestedName =
38-
Result.Nodes.getNodeAs<NestedNameSpecifier>("nns")) {
39-
if (const auto *AliasDecl = dyn_cast_if_present<NamespaceAliasDecl>(
40-
NestedName->getAsNamespace())) {
38+
Result.Nodes.getNodeAs<NestedNameSpecifier>("nns");
39+
NestedName &&
40+
NestedName->getKind() == NestedNameSpecifier::Kind::Namespace)
41+
if (const auto *AliasDecl = dyn_cast<NamespaceAliasDecl>(
42+
NestedName->getAsNamespaceAndPrefix().Namespace))
4143
FoundDecls[AliasDecl] = CharSourceRange();
42-
}
43-
}
4444
}
4545

4646
void UnusedAliasDeclsCheck::onEndOfTranslationUnit() {

clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,11 @@ static bool isNamedDeclInStdTraitsSet(const NamedDecl *ND,
214214
Set.contains(ND->getName());
215215
}
216216

217-
static bool checkTemplatedDecl(const NestedNameSpecifier *NNS,
217+
static bool checkTemplatedDecl(NestedNameSpecifier NNS,
218218
const llvm::StringSet<> &Set) {
219-
if (!NNS)
219+
if (NNS.getKind() != NestedNameSpecifier::Kind::Type)
220220
return false;
221-
const Type *NNST = NNS->getAsType();
222-
if (!NNST)
223-
return false;
224-
const auto *TST = NNST->getAs<TemplateSpecializationType>();
221+
const auto *TST = NNS.getAsType()->getAs<TemplateSpecializationType>();
225222
if (!TST)
226223
return false;
227224
if (const TemplateDecl *TD = TST->getTemplateName().getAsTemplateDecl()) {
@@ -238,8 +235,8 @@ void TypeTraitsCheck::check(const MatchFinder::MatchResult &Result) {
238235
auto EmitValueWarning = [this, &Result](const NestedNameSpecifierLoc &QualLoc,
239236
SourceLocation EndLoc) {
240237
SourceLocation TemplateNameEndLoc;
241-
if (auto TSTL = QualLoc.getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
242-
!TSTL.isNull())
238+
if (auto TSTL =
239+
QualLoc.getAsTypeLoc().getAs<TemplateSpecializationTypeLoc>())
243240
TemplateNameEndLoc = Lexer::getLocForEndOfToken(
244241
TSTL.getTemplateNameLoc(), 0, *Result.SourceManager,
245242
Result.Context->getLangOpts());
@@ -289,23 +286,21 @@ void TypeTraitsCheck::check(const MatchFinder::MatchResult &Result) {
289286
if (!DRE->hasQualifier())
290287
return;
291288
if (const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
292-
DRE->getQualifier()->getAsRecordDecl())) {
289+
DRE->getQualifier().getAsRecordDecl())) {
293290
if (isNamedDeclInStdTraitsSet(CTSD, ValueTraits))
294291
EmitValueWarning(DRE->getQualifierLoc(), DRE->getEndLoc());
295292
}
296293
return;
297294
}
298295

299-
if (const auto *ETL = Result.Nodes.getNodeAs<ElaboratedTypeLoc>(Bind)) {
300-
const NestedNameSpecifierLoc QualLoc = ETL->getQualifierLoc();
301-
const auto *NNS = QualLoc.getNestedNameSpecifier();
302-
if (!NNS)
303-
return;
296+
if (const auto *TL = Result.Nodes.getNodeAs<TypedefTypeLoc>(Bind)) {
297+
const NestedNameSpecifierLoc QualLoc = TL->getQualifierLoc();
298+
NestedNameSpecifier NNS = QualLoc.getNestedNameSpecifier();
304299
if (const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
305-
NNS->getAsRecordDecl())) {
300+
NNS.getAsRecordDecl())) {
306301
if (isNamedDeclInStdTraitsSet(CTSD, TypeTraits))
307-
EmitTypeWarning(ETL->getQualifierLoc(), ETL->getEndLoc(),
308-
ETL->getElaboratedKeywordLoc());
302+
EmitTypeWarning(TL->getQualifierLoc(), TL->getEndLoc(),
303+
TL->getElaboratedKeywordLoc());
309304
}
310305
return;
311306
}

clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp

Lines changed: 46 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -64,66 +64,65 @@ struct UnqualNameVisitor : public RecursiveASTVisitor<UnqualNameVisitor> {
6464
return false;
6565
}
6666

67-
bool TraverseTypeLoc(TypeLoc TL, bool Elaborated = false) {
67+
bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true) {
6868
if (TL.isNull())
6969
return true;
7070

71-
if (!Elaborated) {
72-
switch (TL.getTypeLocClass()) {
73-
case TypeLoc::Record:
74-
if (visitUnqualName(
75-
TL.getAs<RecordTypeLoc>().getTypePtr()->getDecl()->getName()))
76-
return false;
71+
switch (TL.getTypeLocClass()) {
72+
case TypeLoc::InjectedClassName:
73+
case TypeLoc::Record:
74+
case TypeLoc::Enum: {
75+
auto TTL = TL.getAs<TagTypeLoc>();
76+
const auto *T = TTL.getTypePtr();
77+
if (T->getKeyword() != ElaboratedTypeKeyword::None ||
78+
TTL.getQualifierLoc())
7779
break;
78-
case TypeLoc::Enum:
79-
if (visitUnqualName(
80-
TL.getAs<EnumTypeLoc>().getTypePtr()->getDecl()->getName()))
81-
return false;
82-
break;
83-
case TypeLoc::TemplateSpecialization:
84-
if (visitUnqualName(TL.getAs<TemplateSpecializationTypeLoc>()
85-
.getTypePtr()
86-
->getTemplateName()
87-
.getAsTemplateDecl()
88-
->getName()))
89-
return false;
90-
break;
91-
case TypeLoc::Typedef:
92-
if (visitUnqualName(
93-
TL.getAs<TypedefTypeLoc>().getTypePtr()->getDecl()->getName()))
94-
return false;
80+
if (visitUnqualName(T->getOriginalDecl()->getName()))
81+
return false;
82+
break;
83+
}
84+
case TypeLoc::TemplateSpecialization: {
85+
auto TTL = TL.getAs<TemplateSpecializationTypeLoc>();
86+
const auto *T = TTL.getTypePtr();
87+
if (T->getKeyword() != ElaboratedTypeKeyword::None ||
88+
TTL.getQualifierLoc())
9589
break;
96-
case TypeLoc::Using:
97-
if (visitUnqualName(TL.getAs<UsingTypeLoc>()
98-
.getTypePtr()
99-
->getFoundDecl()
100-
->getName()))
101-
return false;
90+
if (visitUnqualName(T->getTemplateName().getAsTemplateDecl()->getName()))
91+
return false;
92+
break;
93+
}
94+
case TypeLoc::Typedef: {
95+
auto TTL = TL.getAs<TypedefTypeLoc>();
96+
const auto *T = TTL.getTypePtr();
97+
if (T->getKeyword() != ElaboratedTypeKeyword::None ||
98+
TTL.getQualifierLoc())
10299
break;
103-
default:
100+
if (visitUnqualName(T->getDecl()->getName()))
101+
return false;
102+
break;
103+
}
104+
case TypeLoc::Using: {
105+
auto TTL = TL.getAs<UsingTypeLoc>();
106+
const auto *T = TTL.getTypePtr();
107+
if (T->getKeyword() != ElaboratedTypeKeyword::None ||
108+
TTL.getQualifierLoc())
104109
break;
105-
}
110+
if (visitUnqualName(T->getDecl()->getName()))
111+
return false;
112+
break;
113+
}
114+
default:
115+
break;
106116
}
107117

108-
return RecursiveASTVisitor<UnqualNameVisitor>::TraverseTypeLoc(TL);
118+
return RecursiveASTVisitor<UnqualNameVisitor>::TraverseTypeLoc(
119+
TL, TraverseQualifier);
109120
}
110121

111122
// Replace the base method in order to call our own
112123
// TraverseTypeLoc().
113-
bool TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
114-
return TraverseTypeLoc(TL.getUnqualifiedLoc());
115-
}
116-
117-
// Replace the base version to inform TraverseTypeLoc that the type is
118-
// elaborated.
119-
bool TraverseElaboratedTypeLoc(ElaboratedTypeLoc TL) {
120-
if (TL.getQualifierLoc() &&
121-
!TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()))
122-
return false;
123-
const auto *T = TL.getTypePtr();
124-
return TraverseTypeLoc(TL.getNamedTypeLoc(),
125-
T->getKeyword() != ElaboratedTypeKeyword::None ||
126-
T->getQualifier());
124+
bool TraverseQualifiedTypeLoc(QualifiedTypeLoc TL, bool TraverseQualifier) {
125+
return TraverseTypeLoc(TL.getUnqualifiedLoc(), TraverseQualifier);
127126
}
128127

129128
bool VisitDeclRefExpr(DeclRefExpr *S) {

clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,25 @@ namespace {
1919
AST_MATCHER(CXXMethodDecl, isStatic) { return Node.isStatic(); }
2020
} // namespace
2121

22-
static unsigned getNameSpecifierNestingLevel(const QualType &QType) {
23-
if (const auto *ElType = QType->getAs<ElaboratedType>()) {
24-
if (const NestedNameSpecifier *NestedSpecifiers = ElType->getQualifier()) {
25-
unsigned NameSpecifierNestingLevel = 1;
26-
do {
27-
NameSpecifierNestingLevel++;
28-
NestedSpecifiers = NestedSpecifiers->getPrefix();
29-
} while (NestedSpecifiers);
30-
22+
static unsigned getNameSpecifierNestingLevel(QualType QType) {
23+
unsigned NameSpecifierNestingLevel = 1;
24+
for (NestedNameSpecifier Qualifier = QType->getPrefix(); /**/;
25+
++NameSpecifierNestingLevel) {
26+
switch (Qualifier.getKind()) {
27+
case NestedNameSpecifier::Kind::Null:
3128
return NameSpecifierNestingLevel;
29+
case NestedNameSpecifier::Kind::Global:
30+
case NestedNameSpecifier::Kind::MicrosoftSuper:
31+
return NameSpecifierNestingLevel + 1;
32+
case NestedNameSpecifier::Kind::Namespace:
33+
Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix;
34+
continue;
35+
case NestedNameSpecifier::Kind::Type:
36+
Qualifier = Qualifier.getAsType()->getPrefix();
37+
continue;
3238
}
39+
llvm_unreachable("unhandled nested name specifier kind");
3340
}
34-
return 0;
3541
}
3642

3743
void StaticAccessedThroughInstanceCheck::storeOptions(

0 commit comments

Comments
 (0)