[llvm-branch-commits] [clang-tools-extra] [PATCH 4/6] [clang] Improve nested name specifier AST representation (PR #148015)
Matheus Izvekov via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Jul 20 20:28:04 PDT 2025
https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/148015
>From 07134c3a595386732fb7c7b86d725bfccf885820 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Thu, 10 Jul 2025 14:07:34 -0300
Subject: [PATCH] [PATCH 4/6] [clang] Improve nested name specifier AST
representation
clang tools extra changes
---
.../find-all-symbols/FindAllSymbols.cpp | 3 +-
.../CrtpConstructorAccessibilityCheck.cpp | 6 ++-
.../EasilySwappableParametersCheck.cpp | 14 ++---
.../ForwardDeclarationNamespaceCheck.cpp | 11 ++--
.../bugprone/IncorrectEnableIfCheck.cpp | 19 +++----
.../bugprone/SizeofExpressionCheck.cpp | 10 ++--
.../NoSuspendWithLockCheck.cpp | 4 +-
.../google/AvoidCStyleCastsCheck.cpp | 31 ++++++++---
.../google/UpgradeGoogletestCaseCheck.cpp | 9 +++-
.../clang-tidy/misc/ConstCorrectnessCheck.cpp | 11 ++--
.../clang-tidy/misc/MisplacedConstCheck.cpp | 14 ++---
.../misc/RedundantExpressionCheck.cpp | 5 +-
.../clang-tidy/misc/UnusedUsingDeclsCheck.cpp | 6 +--
.../DeprecatedIosBaseAliasesCheck.cpp | 11 ++--
.../clang-tidy/modernize/PassByValueCheck.cpp | 3 +-
.../modernize/ReplaceAutoPtrCheck.cpp | 15 +++---
.../clang-tidy/modernize/TypeTraitsCheck.cpp | 34 ++++--------
.../clang-tidy/modernize/UseAutoCheck.cpp | 18 +++----
.../modernize/UseConstraintsCheck.cpp | 7 ++-
.../clang-tidy/modernize/UseEmplaceCheck.cpp | 53 +++++++++----------
.../modernize/UseScopedLockCheck.cpp | 41 +++++---------
.../modernize/UseTransparentFunctorsCheck.cpp | 16 +++---
.../performance/NoAutomaticMoveCheck.cpp | 8 +--
.../portability/StdAllocatorConstCheck.cpp | 11 ++--
.../readability/UseStdMinMaxCheck.cpp | 6 +--
.../clang-tidy/utils/Matchers.cpp | 2 +-
.../utils/RenamerClangTidyCheck.cpp | 30 +++--------
clang-tools-extra/clangd/AST.cpp | 11 ++--
clang-tools-extra/clangd/AST.h | 3 +-
clang-tools-extra/clangd/DumpAST.cpp | 6 ++-
clang-tools-extra/clangd/FindTarget.cpp | 36 ++-----------
clang-tools-extra/clangd/Hover.cpp | 18 ++++---
clang-tools-extra/clangd/InlayHints.cpp | 28 +++++-----
clang-tools-extra/clangd/Selection.cpp | 15 +++---
clang-tools-extra/clangd/XRefs.cpp | 13 +++--
.../refactor/tweaks/ExtractFunction.cpp | 5 +-
.../clangd/unittests/ASTTests.cpp | 7 +--
.../clangd/unittests/DumpASTTests.cpp | 15 +++---
.../clangd/unittests/HoverTests.cpp | 10 ++--
.../clangd/unittests/InlayHintTests.cpp | 9 +---
.../clangd/unittests/QualityTests.cpp | 14 +++--
.../include-cleaner/lib/WalkAST.cpp | 6 +--
.../bugprone/copy-constructor-init.cpp | 1 -
.../unused-local-non-trivial-variable.cpp | 6 +--
.../portability/std-allocator-const.cpp | 22 ++++----
45 files changed, 289 insertions(+), 334 deletions(-)
diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
index bb48883f88815..1f30d27c0a54f 100644
--- a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
+++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
@@ -216,8 +216,7 @@ void FindAllSymbols::registerMatchers(MatchFinder *MatchFinder) {
// Uses of most types: just look at what the typeLoc refers to.
MatchFinder->addMatcher(
typeLoc(isExpansionInMainFile(),
- loc(qualType(allOf(unless(elaboratedType()),
- hasDeclaration(Types.bind("use")))))),
+ loc(qualType(hasDeclaration(Types.bind("use"))))),
this);
// Uses of typedefs: these are often transparent to hasDeclaration, so we need
// to handle them explicitly.
diff --git a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
index 6565fa3f7c85b..0625468d9da88 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
@@ -43,7 +43,8 @@ static bool isDerivedClassBefriended(const CXXRecordDecl *CRTP,
return false;
}
- return FriendType->getType()->getAsCXXRecordDecl() == Derived;
+ return declaresSameEntity(FriendType->getType()->getAsCXXRecordDecl(),
+ Derived);
});
}
@@ -55,7 +56,8 @@ getDerivedParameter(const ClassTemplateSpecializationDecl *CRTP,
CRTP->getTemplateArgs().asArray(), [&](const TemplateArgument &Arg) {
++Idx;
return Arg.getKind() == TemplateArgument::Type &&
- Arg.getAsType()->getAsCXXRecordDecl() == Derived;
+ declaresSameEntity(Arg.getAsType()->getAsCXXRecordDecl(),
+ Derived);
});
return AnyOf ? CRTP->getSpecializedTemplate()
diff --git a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
index a179d4bf66b4d..3cacb90cace52 100644
--- a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
@@ -577,7 +577,7 @@ approximateImplicitConversion(const TheCheck &Check, QualType LType,
ImplicitConversionModellingMode ImplicitMode);
static inline bool isUselessSugar(const Type *T) {
- return isa<AttributedType, DecayedType, ElaboratedType, ParenType>(T);
+ return isa<AttributedType, DecayedType, ParenType>(T);
}
namespace {
@@ -1040,7 +1040,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From,
const auto *ToRecord = To->getAsCXXRecordDecl();
if (isDerivedToBase(FromRecord, ToRecord)) {
LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Derived To Base.\n");
- WorkType = QualType{ToRecord->getTypeForDecl(), FastQualifiersToApply};
+ WorkType = QualType{
+ ToRecord->getASTContext().getCanonicalTagType(ToRecord)->getTypePtr(),
+ FastQualifiersToApply};
}
if (Ctx.getLangOpts().CPlusPlus17 && FromPtr && ToPtr) {
@@ -1072,9 +1074,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From,
WorkType = To;
}
- if (WorkType == To) {
+ if (Ctx.hasSameType(WorkType, To)) {
LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Reached 'To' type.\n");
- return {WorkType};
+ return {Ctx.getCommonSugaredType(WorkType, To)};
}
LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Did not reach 'To'.\n");
@@ -1219,7 +1221,7 @@ tryConversionOperators(const TheCheck &Check, const CXXRecordDecl *RD,
if (std::optional<UserDefinedConversionSelector::PreparedConversion>
SelectedConversion = ConversionSet()) {
- QualType RecordType{RD->getTypeForDecl(), 0};
+ CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD);
ConversionSequence Result{RecordType, ToType};
// The conversion from the operator call's return type to ToType was
@@ -1270,7 +1272,7 @@ tryConvertingConstructors(const TheCheck &Check, QualType FromType,
if (std::optional<UserDefinedConversionSelector::PreparedConversion>
SelectedConversion = ConversionSet()) {
- QualType RecordType{RD->getTypeForDecl(), 0};
+ CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD);
ConversionSequence Result{FromType, RecordType};
Result.AfterFirstStandard = SelectedConversion->Seq.AfterFirstStandard;
diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
index 75ef628436738..070ed04efffc4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
@@ -69,10 +69,9 @@ void ForwardDeclarationNamespaceCheck::check(
// struct B { friend A; };
// \endcode
// `A` will not be marked as "referenced" in the AST.
- if (const TypeSourceInfo *Tsi = Decl->getFriendType()) {
- QualType Desugared = Tsi->getType().getDesugaredType(*Result.Context);
- FriendTypes.insert(Desugared.getTypePtr());
- }
+ if (const TypeSourceInfo *Tsi = Decl->getFriendType())
+ FriendTypes.insert(
+ Tsi->getType()->getCanonicalTypeUnqualified().getTypePtr());
}
}
@@ -119,7 +118,9 @@ void ForwardDeclarationNamespaceCheck::onEndOfTranslationUnit() {
if (CurDecl->hasDefinition() || CurDecl->isReferenced()) {
continue; // Skip forward declarations that are used/referenced.
}
- if (FriendTypes.contains(CurDecl->getTypeForDecl())) {
+ if (FriendTypes.contains(CurDecl->getASTContext()
+ .getCanonicalTagType(CurDecl)
+ ->getTypePtr())) {
continue; // Skip forward declarations referenced as friend.
}
if (CurDecl->getLocation().isMacroID() ||
diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
index 75f1107904fce..07cd90d64c2a4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
@@ -32,13 +32,10 @@ AST_MATCHER_P(TemplateTypeParmDecl, hasUnnamedDefaultArgument,
void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
templateTypeParmDecl(
- hasUnnamedDefaultArgument(
- elaboratedTypeLoc(
- hasNamedTypeLoc(templateSpecializationTypeLoc(
- loc(qualType(hasDeclaration(namedDecl(
- hasName("::std::enable_if"))))))
- .bind("enable_if_specialization")))
- .bind("elaborated")))
+ hasUnnamedDefaultArgument(templateSpecializationTypeLoc(
+ loc(qualType(hasDeclaration(namedDecl(
+ hasName("::std::enable_if"))))))
+ .bind("enable_if_specialization")))
.bind("enable_if"),
this);
}
@@ -46,13 +43,11 @@ void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {
void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {
const auto *EnableIf =
Result.Nodes.getNodeAs<TemplateTypeParmDecl>("enable_if");
- const auto *ElaboratedLoc =
- Result.Nodes.getNodeAs<ElaboratedTypeLoc>("elaborated");
const auto *EnableIfSpecializationLoc =
Result.Nodes.getNodeAs<TemplateSpecializationTypeLoc>(
"enable_if_specialization");
- if (!EnableIf || !ElaboratedLoc || !EnableIfSpecializationLoc)
+ if (!EnableIf || !EnableIfSpecializationLoc)
return;
const SourceManager &SM = *Result.SourceManager;
@@ -62,8 +57,10 @@ void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {
auto Diag = diag(EnableIf->getBeginLoc(),
"incorrect std::enable_if usage detected; use "
"'typename std::enable_if<...>::type'");
+ // FIXME: This should handle the enable_if specialization already having an
+ // elaborated keyword.
if (!getLangOpts().CPlusPlus20) {
- Diag << FixItHint::CreateInsertion(ElaboratedLoc->getBeginLoc(),
+ Diag << FixItHint::CreateInsertion(EnableIfSpecializationLoc->getBeginLoc(),
"typename ");
}
Diag << FixItHint::CreateInsertion(RAngleLoc.getLocWithOffset(1), "::type");
diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
index 88e048e65d4e8..8da6227e172cd 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
@@ -425,7 +425,7 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
"suspicious usage of 'sizeof(array)/sizeof(...)';"
" denominator differs from the size of array elements")
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
- } else if (NumTy && DenomTy && NumTy == DenomTy &&
+ } else if (NumTy && DenomTy && Ctx.hasSameType(NumTy, DenomTy) &&
!NumTy->isDependentType()) {
// Dependent type should not be compared.
diag(E->getOperatorLoc(),
@@ -434,7 +434,7 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
} else if (!WarnOnSizeOfPointer) {
// When 'WarnOnSizeOfPointer' is enabled, these messages become redundant:
- if (PointedTy && DenomTy && PointedTy == DenomTy) {
+ if (PointedTy && DenomTy && Ctx.hasSameType(PointedTy, DenomTy)) {
diag(E->getOperatorLoc(),
"suspicious usage of 'sizeof(...)/sizeof(...)'; size of pointer "
"is divided by size of pointed type")
@@ -463,7 +463,8 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
const auto *SizeOfExpr =
Result.Nodes.getNodeAs<UnaryExprOrTypeTraitExpr>("sizeof-ptr-mul-expr");
- if ((LPtrTy == RPtrTy) && (LPtrTy == SizeofArgTy)) {
+ if (Ctx.hasSameType(LPtrTy, RPtrTy) &&
+ Ctx.hasSameType(LPtrTy, SizeofArgTy)) {
diag(SizeOfExpr->getBeginLoc(), "suspicious usage of 'sizeof(...)' in "
"pointer arithmetic")
<< SizeOfExpr->getSourceRange() << E->getOperatorLoc()
@@ -477,7 +478,8 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
const auto *SizeOfExpr =
Result.Nodes.getNodeAs<UnaryExprOrTypeTraitExpr>("sizeof-ptr-div-expr");
- if ((LPtrTy == RPtrTy) && (LPtrTy == SizeofArgTy)) {
+ if (Ctx.hasSameType(LPtrTy, RPtrTy) &&
+ Ctx.hasSameType(LPtrTy, SizeofArgTy)) {
diag(SizeOfExpr->getBeginLoc(), "suspicious usage of 'sizeof(...)' in "
"pointer arithmetic")
<< SizeOfExpr->getSourceRange() << E->getOperatorLoc()
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp
index ca293178c78b4..29470b1f725fb 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp
@@ -23,9 +23,9 @@ void NoSuspendWithLockCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
}
void NoSuspendWithLockCheck::registerMatchers(MatchFinder *Finder) {
- auto LockType = elaboratedType(namesType(templateSpecializationType(
+ auto LockType = templateSpecializationType(
hasDeclaration(namedDecl(matchers::matchesAnyListedName(
- utils::options::parseStringList(LockGuards)))))));
+ utils::options::parseStringList(LockGuards)))));
StatementMatcher Lock =
declStmt(has(varDecl(hasType(LockType)).bind("lock-decl")))
diff --git a/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp b/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp
index e076b39b5d978..14e11eb0bc697 100644
--- a/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp
@@ -89,6 +89,30 @@ static StringRef getDestTypeString(const SourceManager &SM,
SM, LangOpts);
}
+static bool sameTypeAsWritten(QualType X, QualType Y) {
+ if (X.getCanonicalType() != Y.getCanonicalType())
+ return false;
+
+ auto TC = X->getTypeClass();
+ if (TC != Y->getTypeClass())
+ return false;
+
+ switch (TC) {
+ case Type::Typedef:
+ return declaresSameEntity(cast<TypedefType>(X)->getDecl(),
+ cast<TypedefType>(Y)->getDecl());
+ case Type::Pointer:
+ return sameTypeAsWritten(cast<PointerType>(X)->getPointeeType(),
+ cast<PointerType>(Y)->getPointeeType());
+ case Type::RValueReference:
+ case Type::LValueReference:
+ return sameTypeAsWritten(cast<ReferenceType>(X)->getPointeeType(),
+ cast<ReferenceType>(Y)->getPointeeType());
+ default:
+ return true;
+ }
+}
+
void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) {
const auto *CastExpr = Result.Nodes.getNodeAs<ExplicitCastExpr>("cast");
@@ -128,12 +152,7 @@ void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) {
// case of overloaded functions, so detection of redundant casts is trickier
// in this case. Don't emit "redundant cast" warnings for function
// pointer/reference types.
- QualType Src = SourceTypeAsWritten, Dst = DestTypeAsWritten;
- if (const auto *ElTy = dyn_cast<ElaboratedType>(Src))
- Src = ElTy->getNamedType();
- if (const auto *ElTy = dyn_cast<ElaboratedType>(Dst))
- Dst = ElTy->getNamedType();
- if (Src == Dst) {
+ if (sameTypeAsWritten(SourceTypeAsWritten, DestTypeAsWritten)) {
diag(CastExpr->getBeginLoc(), "redundant cast to the same type")
<< FixItHint::CreateRemoval(ReplaceRange);
return;
diff --git a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp
index 805dcaf3ce402..274b8afa98bd6 100644
--- a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp
+++ b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp
@@ -257,8 +257,13 @@ getAliasNameRange(const MatchFinder::MatchResult &Result) {
return CharSourceRange::getTokenRange(
Using->getNameInfo().getSourceRange());
}
- return CharSourceRange::getTokenRange(
- Result.Nodes.getNodeAs<TypeLoc>("typeloc")->getSourceRange());
+ TypeLoc TL = *Result.Nodes.getNodeAs<TypeLoc>("typeloc");
+ if (auto QTL = TL.getAs<QualifiedTypeLoc>())
+ TL = QTL.getUnqualifiedLoc();
+
+ if (auto TTL = TL.getAs<TypedefTypeLoc>())
+ return CharSourceRange::getTokenRange(TTL.getNameLoc());
+ return CharSourceRange::getTokenRange(TL.castAs<UsingTypeLoc>().getNameLoc());
}
void UpgradeGoogletestCaseCheck::check(const MatchFinder::MatchResult &Result) {
diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
index 697398a54332d..b32507d66cbac 100644
--- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
@@ -98,11 +98,12 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) {
hasType(referenceType(pointee(hasCanonicalType(templateTypeParmType())))),
hasType(referenceType(pointee(substTemplateTypeParmType()))));
- const auto AllowedType = hasType(qualType(anyOf(
- hasDeclaration(namedDecl(matchers::matchesAnyListedName(AllowedTypes))),
- references(namedDecl(matchers::matchesAnyListedName(AllowedTypes))),
- pointerType(pointee(hasDeclaration(
- namedDecl(matchers::matchesAnyListedName(AllowedTypes))))))));
+ auto AllowedTypeDecl = namedDecl(
+ anyOf(matchers::matchesAnyListedName(AllowedTypes), usingShadowDecl()));
+
+ const auto AllowedType = hasType(qualType(
+ anyOf(hasDeclaration(AllowedTypeDecl), references(AllowedTypeDecl),
+ pointerType(pointee(hasDeclaration(AllowedTypeDecl))))));
const auto AutoTemplateType = varDecl(
anyOf(hasType(autoType()), hasType(referenceType(pointee(autoType()))),
diff --git a/clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp b/clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp
index 0cdd48c13b2a6..bb64a5618620c 100644
--- a/clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp
@@ -19,13 +19,13 @@ void MisplacedConstCheck::registerMatchers(MatchFinder *Finder) {
pointee(anyOf(isConstQualified(), ignoringParens(functionType()))))));
Finder->addMatcher(
- valueDecl(hasType(qualType(
- isConstQualified(),
- elaboratedType(namesType(typedefType(hasDeclaration(
- anyOf(typedefDecl(NonConstAndNonFunctionPointerType)
- .bind("typedef"),
- typeAliasDecl(NonConstAndNonFunctionPointerType)
- .bind("typeAlias")))))))))
+ valueDecl(
+ hasType(qualType(isConstQualified(),
+ typedefType(hasDeclaration(anyOf(
+ typedefDecl(NonConstAndNonFunctionPointerType)
+ .bind("typedef"),
+ typeAliasDecl(NonConstAndNonFunctionPointerType)
+ .bind("typeAlias")))))))
.bind("decl"),
this);
}
diff --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
index 9b2af2a8ca7d8..99763bd430f00 100644
--- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -104,9 +104,8 @@ static bool areEquivalentExpr(const Expr *Left, const Expr *Right) {
if (cast<DependentScopeDeclRefExpr>(Left)->getDeclName() !=
cast<DependentScopeDeclRefExpr>(Right)->getDeclName())
return false;
- return areEquivalentNameSpecifier(
- cast<DependentScopeDeclRefExpr>(Left)->getQualifier(),
- cast<DependentScopeDeclRefExpr>(Right)->getQualifier());
+ return cast<DependentScopeDeclRefExpr>(Left)->getQualifier() ==
+ cast<DependentScopeDeclRefExpr>(Right)->getQualifier();
case Stmt::DeclRefExprClass:
return cast<DeclRefExpr>(Left)->getDecl() ==
cast<DeclRefExpr>(Right)->getDecl();
diff --git a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
index d5c5fa3364d63..e5e8c91a9da30 100644
--- a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
@@ -71,11 +71,7 @@ void UnusedUsingDeclsCheck::registerMatchers(MatchFinder *Finder) {
templateArgument().bind("used")))),
this);
Finder->addMatcher(userDefinedLiteral().bind("used"), this);
- Finder->addMatcher(
- loc(elaboratedType(unless(hasQualifier(nestedNameSpecifier())),
- hasUnqualifiedDesugaredType(
- type(asTagDecl(tagDecl().bind("used")))))),
- this);
+ Finder->addMatcher(loc(asTagDecl(tagDecl().bind("used"))), this);
// Cases where we can identify the UsingShadowDecl directly, rather than
// just its target.
// FIXME: cover more cases in this way, as the AST supports it.
diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp
index f22f48d831608..2aca61021166d 100644
--- a/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp
@@ -29,8 +29,7 @@ static std::optional<const char *> getReplacementType(StringRef Type) {
void DeprecatedIosBaseAliasesCheck::registerMatchers(MatchFinder *Finder) {
auto IoStateDecl = typedefDecl(hasAnyName(DeprecatedTypes)).bind("TypeDecl");
- auto IoStateType =
- qualType(hasDeclaration(IoStateDecl), unless(elaboratedType()));
+ auto IoStateType = typedefType(hasDeclaration(IoStateDecl));
Finder->addMatcher(typeLoc(loc(IoStateType)).bind("TypeLoc"), this);
}
@@ -43,12 +42,14 @@ void DeprecatedIosBaseAliasesCheck::check(
StringRef TypeName = Typedef->getName();
auto Replacement = getReplacementType(TypeName);
- const auto *TL = Result.Nodes.getNodeAs<TypeLoc>("TypeLoc");
- SourceLocation IoStateLoc = TL->getBeginLoc();
+ TypeLoc TL = *Result.Nodes.getNodeAs<TypeLoc>("TypeLoc");
+ if (auto QTL = TL.getAs<QualifiedTypeLoc>())
+ TL = QTL.getUnqualifiedLoc();
+ SourceLocation IoStateLoc = TL.castAs<TypedefTypeLoc>().getNameLoc();
// Do not generate fixits for matches depending on template arguments and
// macro expansions.
- bool Fix = Replacement && !TL->getType()->isDependentType();
+ bool Fix = Replacement && !TL.getType()->isDependentType();
if (IoStateLoc.isMacroID()) {
IoStateLoc = SM.getSpellingLoc(IoStateLoc);
Fix = false;
diff --git a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp
index 1e271dfa768ce..a54d0721a5b7d 100644
--- a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp
@@ -77,8 +77,7 @@ AST_MATCHER_P(CXXRecordDecl, isMoveConstructibleInBoundCXXRecordDecl, StringRef,
static TypeMatcher notTemplateSpecConstRefType() {
return lValueReferenceType(
- pointee(unless(elaboratedType(namesType(templateSpecializationType()))),
- isConstQualified()));
+ pointee(unless(templateSpecializationType()), isConstQualified()));
}
static TypeMatcher nonConstValueType() {
diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
index 1ad31d315dc2a..f2142b810a126 100644
--- a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
@@ -48,7 +48,7 @@ void ReplaceAutoPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
auto AutoPtrDecl = recordDecl(hasName("auto_ptr"), isInStdNamespace());
- auto AutoPtrType = qualType(hasDeclaration(AutoPtrDecl));
+ auto AutoPtrType = hasCanonicalType(recordType(hasDeclaration(AutoPtrDecl)));
// std::auto_ptr<int> a;
// ^~~~~~~~~~~~~
@@ -58,11 +58,7 @@ void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
//
// std::auto_ptr<int> fn(std::auto_ptr<int>);
// ^~~~~~~~~~~~~ ^~~~~~~~~~~~~
- Finder->addMatcher(typeLoc(loc(qualType(AutoPtrType,
- // Skip elaboratedType() as the named
- // type will match soon thereafter.
- unless(elaboratedType()))))
- .bind(AutoPtrTokenId),
+ Finder->addMatcher(typeLoc(loc(qualType(AutoPtrType))).bind(AutoPtrTokenId),
this);
// using std::auto_ptr;
@@ -118,10 +114,13 @@ void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) {
}
SourceLocation AutoPtrLoc;
- if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>(AutoPtrTokenId)) {
+ if (const auto *PTL = Result.Nodes.getNodeAs<TypeLoc>(AutoPtrTokenId)) {
+ auto TL = *PTL;
+ if (auto QTL = TL.getAs<QualifiedTypeLoc>())
+ TL = QTL.getUnqualifiedLoc();
// std::auto_ptr<int> i;
// ^
- if (auto Loc = TL->getAs<TemplateSpecializationTypeLoc>())
+ if (auto Loc = TL.getAs<TemplateSpecializationTypeLoc>())
AutoPtrLoc = Loc.getTemplateNameLoc();
} else if (const auto *D =
Result.Nodes.getNodeAs<UsingDecl>(AutoPtrTokenId)) {
diff --git a/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp
index ff0b3213cb58f..76ea3e799aa6d 100644
--- a/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp
@@ -168,19 +168,6 @@ static DeclarationName getName(const DeclRefExpr &D) {
return D.getDecl()->getDeclName();
}
-static bool isNamedType(const ElaboratedTypeLoc &ETL) {
- if (const auto *TFT =
- ETL.getNamedTypeLoc().getTypePtr()->getAs<TypedefType>()) {
- const TypedefNameDecl *Decl = TFT->getDecl();
- return Decl->getDeclName().isIdentifier() && Decl->getName() == "type";
- }
- return false;
-}
-
-static bool isNamedType(const DependentNameTypeLoc &DTL) {
- return DTL.getTypePtr()->getIdentifier()->getName() == "type";
-}
-
namespace {
AST_POLYMORPHIC_MATCHER(isValue, AST_POLYMORPHIC_SUPPORTED_TYPES(
DeclRefExpr, DependentScopeDeclRefExpr)) {
@@ -188,10 +175,14 @@ AST_POLYMORPHIC_MATCHER(isValue, AST_POLYMORPHIC_SUPPORTED_TYPES(
return Ident && Ident->isStr("value");
}
-AST_POLYMORPHIC_MATCHER(isType,
- AST_POLYMORPHIC_SUPPORTED_TYPES(ElaboratedTypeLoc,
- DependentNameTypeLoc)) {
- return Node.getBeginLoc().isValid() && isNamedType(Node);
+AST_MATCHER(TypeLoc, isType) {
+ if (auto TL = Node.getAs<TypedefTypeLoc>()) {
+ const auto *TD = TL.getDecl();
+ return TD->getDeclName().isIdentifier() && TD->getName() == "type";
+ }
+ if (auto TL = Node.getAs<DependentNameTypeLoc>())
+ return TL.getTypePtr()->getIdentifier()->getName() == "type";
+ return false;
}
} // namespace
@@ -214,10 +205,7 @@ void TypeTraitsCheck::registerMatchers(MatchFinder *Finder) {
.bind(Bind),
this);
}
- Finder->addMatcher(mapAnyOf(elaboratedTypeLoc, dependentNameTypeLoc)
- .with(isType())
- .bind(Bind),
- this);
+ Finder->addMatcher(typeLoc(isType()).bind(Bind), this);
}
static bool isNamedDeclInStdTraitsSet(const NamedDecl *ND,
@@ -274,8 +262,8 @@ void TypeTraitsCheck::check(const MatchFinder::MatchResult &Result) {
SourceLocation EndLoc,
SourceLocation TypenameLoc) {
SourceLocation TemplateNameEndLoc;
- if (auto TSTL = QualLoc.getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
- !TSTL.isNull())
+ if (auto TSTL =
+ QualLoc.getAsTypeLoc().getAs<TemplateSpecializationTypeLoc>())
TemplateNameEndLoc = Lexer::getLocForEndOfToken(
TSTL.getTemplateNameLoc(), 0, *Result.SourceManager,
Result.Context->getLangOpts());
diff --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
index f4b63087b7234..b601620633cee 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
@@ -186,16 +186,14 @@ TypeMatcher nestedIterator() {
/// declarations and which name standard iterators for standard containers.
TypeMatcher iteratorFromUsingDeclaration() {
auto HasIteratorDecl = hasDeclaration(namedDecl(hasStdIteratorName()));
- // Types resulting from using declarations are represented by elaboratedType.
- return elaboratedType(
- // Unwrap the nested name specifier to test for one of the standard
- // containers.
- hasQualifier(specifiesType(templateSpecializationType(hasDeclaration(
- namedDecl(hasStdContainerName(), isInStdNamespace()))))),
- // the named type is what comes after the final '::' in the type. It
- // should name one of the standard iterator names.
- namesType(
- anyOf(typedefType(HasIteratorDecl), recordType(HasIteratorDecl))));
+ // Unwrap the nested name specifier to test for one of the standard
+ // containers.
+ auto Qualifier = hasQualifier(specifiesType(templateSpecializationType(
+ hasDeclaration(namedDecl(hasStdContainerName(), isInStdNamespace())))));
+ // the named type is what comes after the final '::' in the type. It should
+ // name one of the standard iterator names.
+ return anyOf(typedefType(HasIteratorDecl, Qualifier),
+ recordType(HasIteratorDecl, Qualifier));
}
/// This matcher returns declaration statements that contain variable
diff --git a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
index e9b96c4016af6..07274d0376207 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
@@ -60,9 +60,11 @@ matchEnableIfSpecializationImplTypename(TypeLoc TheType) {
Keyword != ElaboratedTypeKeyword::None)) {
return std::nullopt;
}
- TheType = Dep.getQualifierLoc().getTypeLoc();
+ TheType = Dep.getQualifierLoc().getAsTypeLoc();
if (TheType.isNull())
return std::nullopt;
+ } else {
+ return std::nullopt;
}
if (const auto SpecializationLoc =
@@ -89,9 +91,6 @@ matchEnableIfSpecializationImplTypename(TypeLoc TheType) {
static std::optional<TemplateSpecializationTypeLoc>
matchEnableIfSpecializationImplTrait(TypeLoc TheType) {
- if (const auto Elaborated = TheType.getAs<ElaboratedTypeLoc>())
- TheType = Elaborated.getNamedTypeLoc();
-
if (const auto SpecializationLoc =
TheType.getAs<TemplateSpecializationTypeLoc>()) {
diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp
index aaf24eaa33c1b..ee49d8a7cb0b0 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp
@@ -164,10 +164,10 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
auto CallEmplacy = cxxMemberCallExpr(
hasDeclaration(
functionDecl(hasAnyNameIgnoringTemplates(EmplacyFunctions))),
- on(hasTypeOrPointeeType(hasCanonicalType(hasDeclaration(
- has(typedefNameDecl(hasName("value_type"),
- hasType(type(hasUnqualifiedDesugaredType(
- recordType().bind("value_type")))))))))));
+ on(hasTypeOrPointeeType(
+ hasCanonicalType(hasDeclaration(has(typedefNameDecl(
+ hasName("value_type"),
+ hasType(hasCanonicalType(recordType().bind("value_type"))))))))));
// We can't replace push_backs of smart pointer because
// if emplacement fails (f.e. bad_alloc in vector) we will have leak of
@@ -241,17 +241,16 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
auto HasConstructExprWithValueTypeType =
has(ignoringImplicit(cxxConstructExpr(
- SoughtConstructExpr, hasType(type(hasUnqualifiedDesugaredType(
- type(equalsBoundNode("value_type"))))))));
-
- auto HasBracedInitListWithValueTypeType =
- anyOf(allOf(HasConstructInitListExpr,
- has(initListExpr(hasType(type(hasUnqualifiedDesugaredType(
- type(equalsBoundNode("value_type")))))))),
- has(cxxBindTemporaryExpr(
- HasConstructInitListExpr,
- has(initListExpr(hasType(type(hasUnqualifiedDesugaredType(
- type(equalsBoundNode("value_type"))))))))));
+ SoughtConstructExpr,
+ hasType(hasCanonicalType(type(equalsBoundNode("value_type")))))));
+
+ auto HasBracedInitListWithValueTypeType = anyOf(
+ allOf(HasConstructInitListExpr,
+ has(initListExpr(hasType(
+ hasCanonicalType(type(equalsBoundNode("value_type"))))))),
+ has(cxxBindTemporaryExpr(HasConstructInitListExpr,
+ has(initListExpr(hasType(hasCanonicalType(
+ type(equalsBoundNode("value_type")))))))));
auto HasConstructExprWithValueTypeTypeAsLastArgument = hasLastArgument(
materializeTemporaryExpr(
@@ -289,19 +288,17 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
this);
Finder->addMatcher(
- traverse(
- TK_AsIs,
- cxxMemberCallExpr(
- CallEmplacy,
- on(hasType(cxxRecordDecl(has(typedefNameDecl(
- hasName("value_type"),
- hasType(type(
- hasUnqualifiedDesugaredType(recordType(hasDeclaration(
- cxxRecordDecl(hasAnyName(SmallVector<StringRef, 2>(
- TupleTypes.begin(), TupleTypes.end()))))))))))))),
- has(MakeTuple), hasSameNumArgsAsDeclNumParams(),
- unless(isInTemplateInstantiation()))
- .bind("emplacy_call")),
+ traverse(TK_AsIs,
+ cxxMemberCallExpr(
+ CallEmplacy,
+ on(hasType(cxxRecordDecl(has(typedefNameDecl(
+ hasName("value_type"),
+ hasType(hasCanonicalType(recordType(hasDeclaration(
+ cxxRecordDecl(hasAnyName(SmallVector<StringRef, 2>(
+ TupleTypes.begin(), TupleTypes.end())))))))))))),
+ has(MakeTuple), hasSameNumArgsAsDeclNumParams(),
+ unless(isInTemplateInstantiation()))
+ .bind("emplacy_call")),
this);
}
diff --git a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp
index 52e9a9f8d49e0..7329b99e4b915 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp
@@ -89,17 +89,6 @@ findLocksInCompoundStmt(const CompoundStmt *Block,
return LockGuardGroups;
}
-static TemplateSpecializationTypeLoc
-getTemplateLockGuardTypeLoc(const TypeSourceInfo *SourceInfo) {
- const TypeLoc Loc = SourceInfo->getTypeLoc();
-
- const auto ElaboratedLoc = Loc.getAs<ElaboratedTypeLoc>();
- if (!ElaboratedLoc)
- return {};
-
- return ElaboratedLoc.getNamedTypeLoc().getAs<TemplateSpecializationTypeLoc>();
-}
-
// Find the exact source range of the 'lock_guard' token
static SourceRange getLockGuardRange(const TypeSourceInfo *SourceInfo) {
const TypeLoc LockGuardTypeLoc = SourceInfo->getTypeLoc();
@@ -110,7 +99,7 @@ static SourceRange getLockGuardRange(const TypeSourceInfo *SourceInfo) {
// Find the exact source range of the 'lock_guard' name token
static SourceRange getLockGuardNameRange(const TypeSourceInfo *SourceInfo) {
const TemplateSpecializationTypeLoc TemplateLoc =
- getTemplateLockGuardTypeLoc(SourceInfo);
+ SourceInfo->getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
if (!TemplateLoc)
return {};
@@ -136,11 +125,11 @@ void UseScopedLockCheck::registerMatchers(MatchFinder *Finder) {
const auto LockGuardClassDecl =
namedDecl(hasName("lock_guard"), isInStdNamespace());
- const auto LockGuardType = qualType(anyOf(
- hasUnqualifiedDesugaredType(
- recordType(hasDeclaration(LockGuardClassDecl))),
- elaboratedType(namesType(hasUnqualifiedDesugaredType(
- templateSpecializationType(hasDeclaration(LockGuardClassDecl)))))));
+ const auto LockGuardType =
+ qualType(anyOf(hasUnqualifiedDesugaredType(
+ recordType(hasDeclaration(LockGuardClassDecl))),
+ hasUnqualifiedDesugaredType(templateSpecializationType(
+ hasDeclaration(LockGuardClassDecl)))));
const auto LockVarDecl = varDecl(hasType(LockGuardType));
@@ -165,18 +154,16 @@ void UseScopedLockCheck::registerMatchers(MatchFinder *Finder) {
if (WarnOnUsingAndTypedef) {
// Match 'typedef std::lock_guard<std::mutex> Lock'
Finder->addMatcher(typedefDecl(unless(isExpansionInSystemHeader()),
- hasUnderlyingType(LockGuardType))
+ hasType(hasUnderlyingType(LockGuardType)))
.bind("lock-guard-typedef"),
this);
// Match 'using Lock = std::lock_guard<std::mutex>'
- Finder->addMatcher(
- typeAliasDecl(
- unless(isExpansionInSystemHeader()),
- hasType(elaboratedType(namesType(templateSpecializationType(
- hasDeclaration(LockGuardClassDecl))))))
- .bind("lock-guard-using-alias"),
- this);
+ Finder->addMatcher(typeAliasDecl(unless(isExpansionInSystemHeader()),
+ hasType(templateSpecializationType(
+ hasDeclaration(LockGuardClassDecl))))
+ .bind("lock-guard-using-alias"),
+ this);
// Match 'using std::lock_guard'
Finder->addMatcher(
@@ -288,8 +275,8 @@ void UseScopedLockCheck::diagOnSourceInfo(
const ast_matchers::MatchFinder::MatchResult &Result) {
const TypeLoc TL = LockGuardSourceInfo->getTypeLoc();
- if (const auto ElaboratedTL = TL.getAs<ElaboratedTypeLoc>()) {
- auto Diag = diag(ElaboratedTL.getBeginLoc(), UseScopedLockMessage);
+ if (const auto TTL = TL.getAs<TemplateSpecializationTypeLoc>()) {
+ auto Diag = diag(TTL.getBeginLoc(), UseScopedLockMessage);
const SourceRange LockGuardRange =
getLockGuardNameRange(LockGuardSourceInfo);
diff --git a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp
index a053c07f95ce2..2373a26fe48b4 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp
@@ -37,15 +37,13 @@ void UseTransparentFunctorsCheck::registerMatchers(MatchFinder *Finder) {
// Non-transparent functor mentioned as a template parameter. FIXIT.
Finder->addMatcher(
- loc(qualType(
- unless(elaboratedType()),
- hasDeclaration(classTemplateSpecializationDecl(
- unless(hasAnyTemplateArgument(templateArgument(refersToType(
- qualType(pointsTo(qualType(isAnyCharacter()))))))),
- hasAnyTemplateArgument(
- templateArgument(refersToType(qualType(hasDeclaration(
- TransparentFunctors))))
- .bind("Functor"))))))
+ loc(qualType(hasDeclaration(classTemplateSpecializationDecl(
+ unless(hasAnyTemplateArgument(templateArgument(refersToType(
+ qualType(pointsTo(qualType(isAnyCharacter()))))))),
+ hasAnyTemplateArgument(
+ templateArgument(refersToType(qualType(
+ hasDeclaration(TransparentFunctors))))
+ .bind("Functor"))))))
.bind("FunctorParentLoc"),
this);
diff --git a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
index 7022e9d784fa7..1c018999432e3 100644
--- a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
@@ -42,11 +42,11 @@ void NoAutomaticMoveCheck::registerMatchers(MatchFinder *Finder) {
// A matcher for a `DstT::DstT(const Src&)` where DstT also has a
// `DstT::DstT(Src&&)`.
const auto LValueRefCtor = cxxConstructorDecl(
- hasParameter(0,
- hasType(lValueReferenceType(pointee(type().bind("SrcT"))))),
+ hasParameter(0, hasType(hasCanonicalType(
+ lValueReferenceType(pointee(type().bind("SrcT")))))),
ofClass(cxxRecordDecl(hasMethod(cxxConstructorDecl(
- hasParameter(0, hasType(rValueReferenceType(
- pointee(type(equalsBoundNode("SrcT")))))))))));
+ hasParameter(0, hasType(hasCanonicalType(rValueReferenceType(
+ pointee(type(equalsBoundNode("SrcT"))))))))))));
// A matcher for `DstT::DstT(const Src&&)`, which typically comes from an
// instantiation of `template <typename U> DstT::DstT(U&&)`.
diff --git a/clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp b/clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp
index 3b4d65be7dfa1..5a3c9a4203eb9 100644
--- a/clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp
+++ b/clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp
@@ -15,10 +15,11 @@ namespace clang::tidy::portability {
void StdAllocatorConstCheck::registerMatchers(MatchFinder *Finder) {
// Match std::allocator<const T>.
- auto AllocatorConst =
+ auto AllocatorConst = qualType(hasCanonicalType(
recordType(hasDeclaration(classTemplateSpecializationDecl(
hasName("::std::allocator"),
- hasTemplateArgument(0, refersToType(qualType(isConstQualified()))))));
+ hasTemplateArgument(0,
+ refersToType(qualType(isConstQualified()))))))));
auto HasContainerName =
hasAnyName("::std::vector", "::std::deque", "::std::list",
@@ -31,8 +32,10 @@ void StdAllocatorConstCheck::registerMatchers(MatchFinder *Finder) {
// aren't caught.
Finder->addMatcher(
typeLoc(
- templateSpecializationTypeLoc(),
- loc(hasUnqualifiedDesugaredType(anyOf(
+ anyOf(templateSpecializationTypeLoc(),
+ qualifiedTypeLoc(
+ hasUnqualifiedLoc(templateSpecializationTypeLoc()))),
+ loc(qualType(anyOf(
recordType(hasDeclaration(classTemplateSpecializationDecl(
HasContainerName,
anyOf(
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 6f6b8a853a91e..718467ed02f0a 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -67,11 +67,7 @@ static QualType getNonTemplateAlias(QualType QT) {
if (!TT->getDecl()->getDescribedTemplate() &&
!TT->getDecl()->getDeclContext()->isDependentContext())
return QT;
- QT = TT->getDecl()->getUnderlyingType();
- }
- // cast to elaborated type
- else if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(QT)) {
- QT = ET->getNamedType();
+ QT = TT->desugar();
} else {
break;
}
diff --git a/clang-tools-extra/clang-tidy/utils/Matchers.cpp b/clang-tools-extra/clang-tidy/utils/Matchers.cpp
index 4974a9cdb9f4b..bd7b03eb39ad7 100644
--- a/clang-tools-extra/clang-tidy/utils/Matchers.cpp
+++ b/clang-tools-extra/clang-tidy/utils/Matchers.cpp
@@ -34,7 +34,7 @@ bool MatchesAnyListedTypeNameMatcher::matches(
PrintingPolicy PrintingPolicyWithSuppressedTag(
Finder->getASTContext().getLangOpts());
PrintingPolicyWithSuppressedTag.PrintAsCanonical = CanonicalTypes;
- PrintingPolicyWithSuppressedTag.SuppressElaboration = true;
+ PrintingPolicyWithSuppressedTag.FullyQualifiedName = true;
PrintingPolicyWithSuppressedTag.SuppressScope = false;
PrintingPolicyWithSuppressedTag.SuppressTagKeyword = true;
PrintingPolicyWithSuppressedTag.SuppressUnwrittenScope = true;
diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
index dd28806e008ed..1ef1da71cbce1 100644
--- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -323,48 +323,34 @@ class RenamerClangTidyVisitor
}
bool VisitTypedefTypeLoc(const TypedefTypeLoc &Loc) {
- Check->addUsage(Loc.getTypedefNameDecl(), Loc.getSourceRange(), SM);
+ Check->addUsage(Loc.getDecl(), Loc.getNameLoc(), SM);
return true;
}
bool VisitTagTypeLoc(const TagTypeLoc &Loc) {
- Check->addUsage(Loc.getDecl(), Loc.getSourceRange(), SM);
- return true;
- }
-
- bool VisitInjectedClassNameTypeLoc(const InjectedClassNameTypeLoc &Loc) {
- Check->addUsage(Loc.getDecl(), Loc.getSourceRange(), SM);
+ Check->addUsage(Loc.getOriginalDecl(), Loc.getNameLoc(), SM);
return true;
}
bool VisitUnresolvedUsingTypeLoc(const UnresolvedUsingTypeLoc &Loc) {
- Check->addUsage(Loc.getDecl(), Loc.getSourceRange(), SM);
+ Check->addUsage(Loc.getDecl(), Loc.getNameLoc(), SM);
return true;
}
bool VisitTemplateTypeParmTypeLoc(const TemplateTypeParmTypeLoc &Loc) {
- Check->addUsage(Loc.getDecl(), Loc.getSourceRange(), SM);
+ Check->addUsage(Loc.getDecl(), Loc.getNameLoc(), SM);
return true;
}
bool
VisitTemplateSpecializationTypeLoc(const TemplateSpecializationTypeLoc &Loc) {
const TemplateDecl *Decl =
- Loc.getTypePtr()->getTemplateName().getAsTemplateDecl();
+ Loc.getTypePtr()->getTemplateName().getAsTemplateDecl(
+ /*IgnoreDeduced=*/true);
- SourceRange Range(Loc.getTemplateNameLoc(), Loc.getTemplateNameLoc());
- if (const auto *ClassDecl = dyn_cast<TemplateDecl>(Decl)) {
+ if (const auto *ClassDecl = dyn_cast<TemplateDecl>(Decl))
if (const NamedDecl *TemplDecl = ClassDecl->getTemplatedDecl())
- Check->addUsage(TemplDecl, Range, SM);
- }
-
- return true;
- }
-
- bool VisitDependentTemplateSpecializationTypeLoc(
- const DependentTemplateSpecializationTypeLoc &Loc) {
- if (const TagDecl *Decl = Loc.getTypePtr()->getAsTagDecl())
- Check->addUsage(Decl, Loc.getSourceRange(), SM);
+ Check->addUsage(TemplDecl, Loc.getTemplateNameLoc(), SM);
return true;
}
diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index f2631e5abb6a3..218d3f7359afb 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -187,6 +187,7 @@ std::string printQualifiedName(const NamedDecl &ND) {
// include them, but at query time it's hard to find all the inline
// namespaces to query: the preamble doesn't have a dedicated list.
Policy.SuppressUnwrittenScope = true;
+ Policy.SuppressScope = true;
// (unnamed struct), not (unnamed struct at /path/to/foo.cc:42:1).
// In clangd, context is usually available and paths are mostly noise.
Policy.AnonymousTagLocations = false;
@@ -213,8 +214,7 @@ std::string printUsingNamespaceName(const ASTContext &Ctx,
std::string Name;
llvm::raw_string_ostream Out(Name);
- if (auto *Qual = D.getQualifier())
- Qual->print(Out, PP);
+ D.getQualifier().print(Out, PP);
D.getNominatedNamespaceAsWritten()->printName(Out);
return Out.str();
}
@@ -229,8 +229,7 @@ std::string printName(const ASTContext &Ctx, const NamedDecl &ND) {
// Handle 'using namespace'. They all have the same name - <using-directive>.
if (auto *UD = llvm::dyn_cast<UsingDirectiveDecl>(&ND)) {
Out << "using namespace ";
- if (auto *Qual = UD->getQualifier())
- Qual->print(Out, PP);
+ UD->getQualifier().print(Out, PP);
UD->getNominatedNamespaceAsWritten()->printName(Out);
return Out.str();
}
@@ -391,12 +390,13 @@ preferredIncludeDirective(llvm::StringRef FileName, const LangOptions &LangOpts,
}
std::string printType(const QualType QT, const DeclContext &CurContext,
- const llvm::StringRef Placeholder) {
+ const llvm::StringRef Placeholder, bool FullyQualify) {
std::string Result;
llvm::raw_string_ostream OS(Result);
PrintingPolicy PP(CurContext.getParentASTContext().getPrintingPolicy());
PP.SuppressTagKeyword = true;
PP.SuppressUnwrittenScope = true;
+ PP.FullyQualifiedName = FullyQualify;
class PrintCB : public PrintingCallbacks {
public:
@@ -439,6 +439,7 @@ QualType declaredType(const TypeDecl *D) {
if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
if (const auto *Args = CTSD->getTemplateArgsAsWritten())
return Context.getTemplateSpecializationType(
+ ElaboratedTypeKeyword::None,
TemplateName(CTSD->getSpecializedTemplate()), Args->arguments(),
/*CanonicalArgs=*/{});
return Context.getTypeDeclType(D);
diff --git a/clang-tools-extra/clangd/AST.h b/clang-tools-extra/clangd/AST.h
index fb0722d697cd0..1538d12172593 100644
--- a/clang-tools-extra/clangd/AST.h
+++ b/clang-tools-extra/clangd/AST.h
@@ -135,7 +135,8 @@ preferredIncludeDirective(llvm::StringRef FileName, const LangOptions &LangOpts,
/// Returns a QualType as string. The result doesn't contain unwritten scopes
/// like anonymous/inline namespace.
std::string printType(const QualType QT, const DeclContext &CurContext,
- llvm::StringRef Placeholder = "");
+ llvm::StringRef Placeholder = "",
+ bool FullyQualify = false);
/// Indicates if \p D is a template instantiation implicitly generated by the
/// compiler, e.g.
diff --git a/clang-tools-extra/clangd/DumpAST.cpp b/clang-tools-extra/clangd/DumpAST.cpp
index c6075e75e9a6b..54e15b2f553c6 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -346,8 +346,10 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> {
return !D || isInjectedClassName(D) ||
traverseNode("declaration", D, [&] { Base::TraverseDecl(D); });
}
- bool TraverseTypeLoc(TypeLoc TL) {
- return !TL || traverseNode("type", TL, [&] { Base::TraverseTypeLoc(TL); });
+ bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true) {
+ return !TL || traverseNode("type", TL, [&] {
+ Base::TraverseTypeLoc(TL, TraverseQualifier);
+ });
}
bool TraverseTemplateName(const TemplateName &TN) {
return traverseNode("template name", TN,
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index b1089577ba819..d9b684b3952aa 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -366,19 +366,11 @@ struct TargetFinder {
Visitor(TargetFinder &Outer, RelSet Flags) : Outer(Outer), Flags(Flags) {}
void VisitTagType(const TagType *TT) {
- Outer.add(TT->getAsTagDecl(), Flags);
- }
-
- void VisitElaboratedType(const ElaboratedType *ET) {
- Outer.add(ET->desugar(), Flags);
+ Outer.add(cast<TagType>(TT)->getOriginalDecl(), Flags);
}
void VisitUsingType(const UsingType *ET) {
- Outer.add(ET->getFoundDecl(), Flags);
- }
-
- void VisitInjectedClassNameType(const InjectedClassNameType *ICNT) {
- Outer.add(ICNT->getDecl(), Flags);
+ Outer.add(ET->getDecl(), Flags);
}
void VisitDecltypeType(const DecltypeType *DTT) {
@@ -918,13 +910,6 @@ refInTypeLoc(TypeLoc L, const HeuristicResolver *Resolver) {
DeclRelation::Alias, Resolver)});
}
- void VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
- Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
- TL.getNameLoc(),
- /*IsDecl=*/false,
- {TL.getDecl()}});
- }
-
void VisitDependentTemplateSpecializationTypeLoc(
DependentTemplateSpecializationTypeLoc L) {
Refs.push_back(
@@ -943,12 +928,12 @@ refInTypeLoc(TypeLoc L, const HeuristicResolver *Resolver) {
}
void VisitTypedefTypeLoc(TypedefTypeLoc L) {
- if (shouldSkipTypedef(L.getTypedefNameDecl()))
+ if (shouldSkipTypedef(L.getDecl()))
return;
- Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
+ Refs.push_back(ReferenceLoc{L.getQualifierLoc(),
L.getNameLoc(),
/*IsDecl=*/false,
- {L.getTypedefNameDecl()}});
+ {L.getDecl()}});
}
void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc L) {
@@ -980,17 +965,6 @@ class ExplicitReferenceCollector
return true;
}
- bool TraverseElaboratedTypeLoc(ElaboratedTypeLoc L) {
- // ElaboratedTypeLoc will reports information for its inner type loc.
- // Otherwise we loose information about inner types loc's qualifier.
- TypeLoc Inner = L.getNamedTypeLoc().getUnqualifiedLoc();
- if (L.getBeginLoc() == Inner.getBeginLoc())
- return RecursiveASTVisitor::TraverseTypeLoc(Inner);
- else
- TypeLocsToSkip.insert(Inner.getBeginLoc());
- return RecursiveASTVisitor::TraverseElaboratedTypeLoc(L);
- }
-
bool VisitStmt(Stmt *S) {
visitNode(DynTypedNode::create(*S));
return true;
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index e39d8bfcf83f3..3aac570f33478 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -169,13 +169,14 @@ HoverInfo::PrintedType printType(QualType QT, ASTContext &ASTCtx,
QT = QT->castAs<DecltypeType>()->getUnderlyingType();
HoverInfo::PrintedType Result;
llvm::raw_string_ostream OS(Result.Type);
- // Special case: if the outer type is a tag type without qualifiers, then
- // include the tag for extra clarity.
- // This isn't very idiomatic, so don't attempt it for complex cases, including
- // pointers/references, template specializations, etc.
+ // Special case: if the outer type is a canonical tag type, then include the
+ // tag for extra clarity. This isn't very idiomatic, so don't attempt it for
+ // complex cases, including pointers/references, template specializations,
+ // etc.
if (!QT.isNull() && !QT.hasQualifiers() && PP.SuppressTagKeyword) {
- if (auto *TT = llvm::dyn_cast<TagType>(QT.getTypePtr()))
- OS << TT->getDecl()->getKindName() << " ";
+ if (auto *TT = llvm::dyn_cast<TagType>(QT.getTypePtr());
+ TT && TT->isCanonicalUnqualified())
+ OS << TT->getOriginalDecl()->getKindName() << " ";
}
QT.print(OS, PP);
@@ -1002,10 +1003,11 @@ void addLayoutInfo(const NamedDecl &ND, HoverInfo &HI) {
const auto &Ctx = ND.getASTContext();
if (auto *RD = llvm::dyn_cast<RecordDecl>(&ND)) {
- if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RD->getTypeForDecl()))
+ CanQualType RT = Ctx.getCanonicalTagType(RD);
+ if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RT))
HI.Size = Size->getQuantity() * 8;
if (!RD->isDependentType() && RD->isCompleteDefinition())
- HI.Align = Ctx.getTypeAlign(RD->getTypeForDecl());
+ HI.Align = Ctx.getTypeAlign(RT);
return;
}
diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp
index 197c62c40dcf0..cd479e1b7c9bc 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -55,18 +55,24 @@ void stripLeadingUnderscores(StringRef &Name) { Name = Name.ltrim('_'); }
// getDeclForType() returns the decl responsible for Type's spelling.
// This is the inverse of ASTContext::getTypeDeclType().
-template <typename Ty, typename = decltype(((Ty *)nullptr)->getDecl())>
-const NamedDecl *getDeclForTypeImpl(const Ty *T) {
- return T->getDecl();
-}
-const NamedDecl *getDeclForTypeImpl(const void *T) { return nullptr; }
const NamedDecl *getDeclForType(const Type *T) {
switch (T->getTypeClass()) {
-#define ABSTRACT_TYPE(TY, BASE)
-#define TYPE(TY, BASE) \
- case Type::TY: \
- return getDeclForTypeImpl(llvm::cast<TY##Type>(T));
-#include "clang/AST/TypeNodes.inc"
+ case Type::Enum:
+ case Type::Record:
+ case Type::InjectedClassName:
+ return cast<TagType>(T)->getOriginalDecl();
+ case Type::TemplateSpecialization:
+ return cast<TemplateSpecializationType>(T)
+ ->getTemplateName()
+ .getAsTemplateDecl(/*IgnoreDeduced=*/true);
+ case Type::Typedef:
+ return cast<TypedefType>(T)->getDecl();
+ case Type::UnresolvedUsing:
+ return cast<UnresolvedUsingType>(T)->getDecl();
+ case Type::Using:
+ return cast<UsingType>(T)->getDecl();
+ default:
+ return nullptr;
}
llvm_unreachable("Unknown TypeClass enum");
}
@@ -81,8 +87,6 @@ llvm::StringRef getSimpleName(const NamedDecl &D) {
return getSimpleName(D.getDeclName());
}
llvm::StringRef getSimpleName(QualType T) {
- if (const auto *ET = llvm::dyn_cast<ElaboratedType>(T))
- return getSimpleName(ET->getNamedType());
if (const auto *BT = llvm::dyn_cast<BuiltinType>(T)) {
PrintingPolicy PP(LangOptions{});
PP.adjustForCPlusPlus();
diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp
index 277cb8769a1b1..a6e15fcee6bd2 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -62,7 +62,8 @@ void recordMetrics(const SelectionTree &S, const LangOptions &Lang) {
}
// Return the range covering a node and all its children.
-SourceRange getSourceRange(const DynTypedNode &N) {
+SourceRange getSourceRange(const DynTypedNode &N,
+ bool IncludeQualifier = false) {
// MemberExprs to implicitly access anonymous fields should not claim any
// tokens for themselves. Given:
// struct A { struct { int b; }; };
@@ -80,7 +81,7 @@ SourceRange getSourceRange(const DynTypedNode &N) {
? getSourceRange(DynTypedNode::create(*ME->getBase()))
: SourceRange();
}
- return N.getSourceRange();
+ return N.getSourceRange(IncludeQualifier);
}
// An IntervalSet maintains a set of disjoint subranges of an array.
@@ -643,8 +644,9 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
}
return traverseNode(X, [&] { return Base::TraverseDecl(X); });
}
- bool TraverseTypeLoc(TypeLoc X) {
- return traverseNode(&X, [&] { return Base::TraverseTypeLoc(X); });
+ bool TraverseTypeLoc(TypeLoc X, bool TraverseQualifier = true) {
+ return traverseNode(
+ &X, [&] { return Base::TraverseTypeLoc(X, TraverseQualifier); });
}
bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &X) {
return traverseNode(&X,
@@ -690,7 +692,8 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
// This means we'd never see 'int' in 'const int'! Work around that here.
// (The reason for the behavior is to avoid traversing the nested Type twice,
// but we ignore TraverseType anyway).
- bool TraverseQualifiedTypeLoc(QualifiedTypeLoc QX) {
+ bool TraverseQualifiedTypeLoc(QualifiedTypeLoc QX,
+ bool TraverseQualifier = true) {
return traverseNode<TypeLoc>(
&QX, [&] { return TraverseTypeLoc(QX.getUnqualifiedLoc()); });
}
@@ -798,7 +801,7 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
// An optimization for a common case: nodes outside macro expansions that
// don't intersect the selection may be recursively skipped.
bool canSafelySkipNode(const DynTypedNode &N) {
- SourceRange S = getSourceRange(N);
+ SourceRange S = getSourceRange(N, /*IncludeQualifier=*/true);
if (auto *TL = N.get<TypeLoc>()) {
// FIXME: TypeLoc::getBeginLoc()/getEndLoc() are pretty fragile
// heuristics. We should consider only pruning critical TypeLoc nodes, to
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index 089f8158c9aa5..731ae0fe119d0 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -1935,7 +1935,8 @@ std::vector<const CXXRecordDecl *> findRecordTypeAt(ParsedAST &AST,
// Return the type most associated with an AST node.
// This isn't precisely defined: we want "go to type" to do something useful.
-static QualType typeForNode(const SelectionTree::Node *N) {
+static QualType typeForNode(const ASTContext &Ctx,
+ const SelectionTree::Node *N) {
// If we're looking at a namespace qualifier, walk up to what it's qualifying.
// (If we're pointing at a *class* inside a NNS, N will be a TypeLoc).
while (N && N->ASTNode.get<NestedNameSpecifierLoc>())
@@ -1969,10 +1970,13 @@ static QualType typeForNode(const SelectionTree::Node *N) {
if (const Decl *D = N->ASTNode.get<Decl>()) {
struct Visitor : ConstDeclVisitor<Visitor, QualType> {
+ const ASTContext &Ctx;
+ Visitor(const ASTContext &Ctx) : Ctx(Ctx) {}
+
QualType VisitValueDecl(const ValueDecl *D) { return D->getType(); }
// Declaration of a type => that type.
QualType VisitTypeDecl(const TypeDecl *D) {
- return QualType(D->getTypeForDecl(), 0);
+ return Ctx.getTypeDeclType(D);
}
// Exception: alias declaration => the underlying type, not the alias.
QualType VisitTypedefNameDecl(const TypedefNameDecl *D) {
@@ -1982,7 +1986,7 @@ static QualType typeForNode(const SelectionTree::Node *N) {
QualType VisitTemplateDecl(const TemplateDecl *D) {
return Visit(D->getTemplatedDecl());
}
- } V;
+ } V(Ctx);
return V.Visit(D);
}
@@ -2126,7 +2130,8 @@ std::vector<LocatedSymbol> findType(ParsedAST &AST, Position Pos,
// unique_ptr<unique_ptr<T>>. Let's *not* remove them, because it gives you some
// information about the type you may have not known before
// (since unique_ptr<unique_ptr<T>> != unique_ptr<T>).
- for (const QualType& Type : unwrapFindType(typeForNode(N), AST.getHeuristicResolver()))
+ for (const QualType &Type : unwrapFindType(
+ typeForNode(AST.getASTContext(), N), AST.getHeuristicResolver()))
llvm::copy(locateSymbolForType(AST, Type, Index),
std::back_inserter(LocatedSymbols));
diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp
index cd07cbf73635c..3f900ab2aae86 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp
@@ -455,13 +455,12 @@ std::string NewFunction::renderQualifiers() const {
}
std::string NewFunction::renderDeclarationName(FunctionDeclKind K) const {
- if (DefinitionQualifier == nullptr || K != OutOfLineDefinition) {
+ if (!DefinitionQualifier || K != OutOfLineDefinition)
return Name;
- }
std::string QualifierName;
llvm::raw_string_ostream Oss(QualifierName);
- DefinitionQualifier->print(Oss, *LangOpts);
+ DefinitionQualifier.print(Oss, *LangOpts);
return llvm::formatv("{0}{1}", QualifierName, Name);
}
diff --git a/clang-tools-extra/clangd/unittests/ASTTests.cpp b/clang-tools-extra/clangd/unittests/ASTTests.cpp
index d0bc3c4d7db98..76d46bad82224 100644
--- a/clang-tools-extra/clangd/unittests/ASTTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ASTTests.cpp
@@ -421,7 +421,7 @@ TEST(ClangdAST, GetQualification) {
{
R"cpp(
namespace ns1 { namespace ns2 { void Foo(); } }
- void insert(); // ns2::Foo
+ void insert(); // ns1::ns2::Foo
namespace ns1 {
void insert(); // ns2::Foo
namespace ns2 {
@@ -429,7 +429,7 @@ TEST(ClangdAST, GetQualification) {
}
}
)cpp",
- {"ns2::", "ns2::", ""},
+ {"ns1::ns2::", "ns2::", ""},
{"ns1::"},
},
{
@@ -531,7 +531,8 @@ TEST(ClangdAST, PrintType) {
ASSERT_EQ(InsertionPoints.size(), Case.Types.size());
for (size_t I = 0, E = InsertionPoints.size(); I != E; ++I) {
const auto *DC = InsertionPoints[I];
- EXPECT_EQ(printType(AST.getASTContext().getTypeDeclType(TargetDecl), *DC),
+ EXPECT_EQ(printType(AST.getASTContext().getTypeDeclType(TargetDecl), *DC,
+ /*Placeholder=*/"", /*FullyQualify=*/true),
Case.Types[I]);
}
}
diff --git a/clang-tools-extra/clangd/unittests/DumpASTTests.cpp b/clang-tools-extra/clangd/unittests/DumpASTTests.cpp
index cb2c17ad4ef0d..5c857d0b8ae3e 100644
--- a/clang-tools-extra/clangd/unittests/DumpASTTests.cpp
+++ b/clang-tools-extra/clangd/unittests/DumpASTTests.cpp
@@ -72,15 +72,14 @@ declaration: Namespace - root
expression: BinaryOperator - +
expression: ImplicitCast - LValueToRValue
expression: DeclRef - x
- specifier: TypeSpec
+ specifier: Type
type: Record - S
expression: ImplicitCast - LValueToRValue
expression: Member - x
expression: CXXBindTemporary
expression: CXXTemporaryObject - S
- type: Elaborated
+ type: Record - S
specifier: Namespace - root::
- type: Record - S
)"},
{R"cpp(
namespace root {
@@ -104,14 +103,13 @@ declaration: Namespace - root
expression: BinaryOperator - +
expression: ImplicitCast - LValueToRValue
expression: DeclRef - x
- specifier: TypeSpec
+ specifier: Type
type: Record - S
expression: ImplicitCast - LValueToRValue
expression: Member - x
expression: CXXTemporaryObject - S
- type: Elaborated
+ type: Record - S
specifier: Namespace - root::
- type: Record - S
)"},
{R"cpp(
namespace root {
@@ -138,7 +136,7 @@ declaration: Namespace - root
type: Builtin - unsigned int
statement: Return
expression: DependentScopeDeclRef - value
- specifier: TypeSpec
+ specifier: Type
type: TemplateTypeParm - T
)"},
{R"cpp(
@@ -154,8 +152,7 @@ declaration: Var - root
expression: DeclRef - operator+
expression: MaterializeTemporary - lvalue
expression: CXXTemporaryObject - Foo
- type: Elaborated
- type: Record - Foo
+ type: Record - Foo
expression: IntegerLiteral - 42
)"},
{R"cpp(
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 4a21dafed5e95..16365300338ad 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -2893,7 +2893,7 @@ TEST(Hover, All) {
)cpp",
[](HoverInfo &HI) {
HI.Name = "this";
- HI.Definition = "const Foo<T> *";
+ HI.Definition = "const ns::Foo<T> *";
}},
{
R"cpp(// this expr for specialization class
@@ -2909,7 +2909,7 @@ TEST(Hover, All) {
)cpp",
[](HoverInfo &HI) {
HI.Name = "this";
- HI.Definition = "Foo<int> *";
+ HI.Definition = "ns::Foo<int> *";
}},
{
R"cpp(// this expr for partial specialization struct
@@ -2925,7 +2925,7 @@ TEST(Hover, All) {
)cpp",
[](HoverInfo &HI) {
HI.Name = "this";
- HI.Definition = "const Foo<int, F> *";
+ HI.Definition = "const ns::Foo<int, F> *";
}},
{
R"cpp(
@@ -3045,8 +3045,8 @@ TEST(Hover, All) {
HI.Kind = index::SymbolKind::Function;
HI.NamespaceScope = "";
HI.Definition = "MyRect foobar()";
- HI.Type = {"MyRect ()", "MyRect ()"};
- HI.ReturnType = {"MyRect", "MyRect"};
+ HI.Type = {"MyRect ()", "struct MyRect ()"};
+ HI.ReturnType = {"MyRect", "struct MyRect"};
HI.Parameters.emplace();
}},
{R"cpp(
diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index e0cd955bb1c9a..99e728c40063d 100644
--- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -1295,14 +1295,7 @@ TEST(TypeHints, NoQualifiers) {
}
}
)cpp",
- ExpectedHint{": S1", "x"},
- // FIXME: We want to suppress scope specifiers
- // here because we are into the whole
- // brevity thing, but the ElaboratedType
- // printer does not honor the SuppressScope
- // flag by design, so we need to extend the
- // PrintingPolicy to support this use case.
- ExpectedHint{": S2::Inner<int>", "y"});
+ ExpectedHint{": S1", "x"}, ExpectedHint{": Inner<int>", "y"});
}
TEST(TypeHints, Lambda) {
diff --git a/clang-tools-extra/clangd/unittests/QualityTests.cpp b/clang-tools-extra/clangd/unittests/QualityTests.cpp
index 619ea32115357..4954659a45e02 100644
--- a/clang-tools-extra/clangd/unittests/QualityTests.cpp
+++ b/clang-tools-extra/clangd/unittests/QualityTests.cpp
@@ -121,7 +121,9 @@ TEST(QualityTests, SymbolRelevanceSignalExtraction) {
SymbolRelevanceSignals Relevance;
Relevance.merge(CodeCompletionResult(&findDecl(AST, "deprecated"),
- /*Priority=*/42, nullptr, false,
+ /*Priority=*/42,
+ /*Qualifier=*/std::nullopt,
+ /*QualifierIsInformative=*/false,
/*Accessible=*/false));
EXPECT_EQ(Relevance.NameMatch, SymbolRelevanceSignals().NameMatch);
EXPECT_TRUE(Relevance.Forbidden);
@@ -487,13 +489,15 @@ TEST(QualityTests, ItemWithFixItsRankedDown) {
auto AST = Header.build();
SymbolRelevanceSignals RelevanceWithFixIt;
- RelevanceWithFixIt.merge(CodeCompletionResult(&findDecl(AST, "x"), 0, nullptr,
- false, true, {FixItHint{}}));
+ RelevanceWithFixIt.merge(CodeCompletionResult(
+ &findDecl(AST, "x"), /*Priority=*/0, /*Qualifier=*/std::nullopt,
+ /*QualifierIsInformative=*/false, /*Accessible=*/true, {FixItHint{}}));
EXPECT_TRUE(RelevanceWithFixIt.NeedsFixIts);
SymbolRelevanceSignals RelevanceWithoutFixIt;
- RelevanceWithoutFixIt.merge(
- CodeCompletionResult(&findDecl(AST, "x"), 0, nullptr, false, true, {}));
+ RelevanceWithoutFixIt.merge(CodeCompletionResult(
+ &findDecl(AST, "x"), /*Priority=*/0, /*Qualifier=*/std::nullopt,
+ /*QualifierIsInformative=*/false, /*Accessible=*/true, {}));
EXPECT_FALSE(RelevanceWithoutFixIt.NeedsFixIts);
EXPECT_LT(RelevanceWithFixIt.evaluateHeuristics(),
diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 49cc13606f4c2..6f51fa68f45b8 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -60,14 +60,10 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
NamedDecl *getMemberProvider(QualType Base) {
if (Base->isPointerType())
return getMemberProvider(Base->getPointeeType());
- // Unwrap the sugar ElaboratedType.
- if (const auto *ElTy = dyn_cast<ElaboratedType>(Base))
- return getMemberProvider(ElTy->getNamedType());
-
if (const auto *TT = dyn_cast<TypedefType>(Base))
return TT->getDecl();
if (const auto *UT = dyn_cast<UsingType>(Base))
- return UT->getFoundDecl();
+ return UT->getDecl();
// A heuristic: to resolve a template type to **only** its template name.
// We're only using this method for the base type of MemberExpr, in general
// the template provides the member, and the critical case `unique_ptr<Foo>`
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp
index b42d3fcd2b62b..35314d12b59bf 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp
@@ -165,7 +165,6 @@ FROMMACRO
class X15 : public CopyableAlias2 {
X15(const X15 &other) {}
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
- // CHECK-FIXES: X15(const X15 &other) : Copyable5(other) {}
};
class X16 : public NonCopyable {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp
index 721c55b1fb538..5dd23871b21b3 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp
@@ -69,14 +69,14 @@ template<typename T>
T qux(T Generic) {
async::Future<Units> PendingA = acquireUnits();
auto PendingB = acquireUnits();
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: unused local variable 'PendingB' of type 'a::Future<Units>' (aka 'Future<Units>') [bugprone-unused-local-non-trivial-variable]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: unused local variable 'PendingB' of type 'a::Future<Units>' (aka 'async::Future<Units>') [bugprone-unused-local-non-trivial-variable]
async::Future<Units> MustBeUsed;
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: unused local variable 'MustBeUsed' of type 'async::Future<Units>' [bugprone-unused-local-non-trivial-variable]
PendingA.get();
async::Future<T> TemplateType;
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unused local variable 'TemplateType' of type 'async::Future<T>' [bugprone-unused-local-non-trivial-variable]
a::Future<T> AliasTemplateType;
- // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unused local variable 'AliasTemplateType' of type 'a::Future<T>' (aka 'Future<T>') [bugprone-unused-local-non-trivial-variable]
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unused local variable 'AliasTemplateType' of type 'a::Future<T>' (aka 'async::Future<T>') [bugprone-unused-local-non-trivial-variable]
[[maybe_unused]] async::Future<Units> MaybeUnused;
return Generic;
}
@@ -86,7 +86,7 @@ async::Future<int> Global;
int bar(int Num) {
a::Future<Units> PendingA = acquireUnits();
a::Future<Units> PendingB = acquireUnits(); // not used at all, unused variable not fired because of destructor side effect
- // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unused local variable 'PendingB' of type 'a::Future<Units>' (aka 'Future<Units>') [bugprone-unused-local-non-trivial-variable]
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unused local variable 'PendingB' of type 'a::Future<Units>' (aka 'async::Future<Units>') [bugprone-unused-local-non-trivial-variable]
auto Num2 = PendingA.get();
auto Num3 = qux(Num);
async::Ptr<a::Future<Units>> Shared = async::Ptr<a::Future<Units>>(acquireUnits());
diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp
index 732cf5d34aca9..a38594aa94cbb 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp
@@ -43,25 +43,25 @@ template <class T>
class allocator {};
void simple(const std::vector<const char> &v, std::deque<const short> *d) {
- // CHECK-MESSAGES: [[#@LINE-1]]:24: warning: container using std::allocator<const T> is a deprecated libc++ extension; remove const for compatibility with other standard libraries
- // CHECK-MESSAGES: [[#@LINE-2]]:52: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:19: warning: container using std::allocator<const T> is a deprecated libc++ extension; remove const for compatibility with other standard libraries
+ // CHECK-MESSAGES: [[#@LINE-2]]:47: warning: container
std::list<const long> l;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
std::multiset<int *const> ms;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
std::set<const std::hash<int>> s;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
std::unordered_multiset<int *const> ums;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
std::unordered_set<const int> us;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
absl::flat_hash_set<const int> fhs;
- // CHECK-MESSAGES: [[#@LINE-1]]:9: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
using my_vector = std::vector<const int>;
- // CHECK-MESSAGES: [[#@LINE-1]]:26: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:21: warning: container
my_vector v1;
using my_vector2 = my_vector;
@@ -76,7 +76,7 @@ void simple(const std::vector<const char> &v, std::deque<const short> *d) {
template <class T>
void temp1() {
std::vector<const T> v;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
std::vector<T> neg1;
std::forward_list<const T> neg2;
@@ -87,7 +87,7 @@ template <class T>
void temp2() {
// Match std::vector<const dependent> for the uninstantiated temp2.
std::vector<const T> v;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
std::vector<T> neg1;
std::forward_list<const T> neg2;
More information about the llvm-branch-commits
mailing list