From 07134c3a595386732fb7c7b86d725bfccf885820 Mon Sep 17 00:00:00 2001 From: Matheus Izvekov 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(T); + return isa(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 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 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("enable_if"); - const auto *ElaboratedLoc = - Result.Nodes.getNodeAs("elaborated"); const auto *EnableIfSpecializationLoc = Result.Nodes.getNodeAs( "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("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("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(X)->getDecl(), + cast(Y)->getDecl()); + case Type::Pointer: + return sameTypeAsWritten(cast(X)->getPointeeType(), + cast(Y)->getPointeeType()); + case Type::RValueReference: + case Type::LValueReference: + return sameTypeAsWritten(cast(X)->getPointeeType(), + cast(Y)->getPointeeType()); + default: + return true; + } +} + void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) { const auto *CastExpr = Result.Nodes.getNodeAs("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(Src)) - Src = ElTy->getNamedType(); - if (const auto *ElTy = dyn_cast(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")->getSourceRange()); + TypeLoc TL = *Result.Nodes.getNodeAs("typeloc"); + if (auto QTL = TL.getAs()) + TL = QTL.getUnqualifiedLoc(); + + if (auto TTL = TL.getAs()) + return CharSourceRange::getTokenRange(TTL.getNameLoc()); + return CharSourceRange::getTokenRange(TL.castAs().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(Left)->getDeclName() != cast(Right)->getDeclName()) return false; - return areEquivalentNameSpecifier( - cast(Left)->getQualifier(), - cast(Right)->getQualifier()); + return cast(Left)->getQualifier() == + cast(Right)->getQualifier(); case Stmt::DeclRefExprClass: return cast(Left)->getDecl() == cast(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 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"); - SourceLocation IoStateLoc = TL->getBeginLoc(); + TypeLoc TL = *Result.Nodes.getNodeAs("TypeLoc"); + if (auto QTL = TL.getAs()) + TL = QTL.getUnqualifiedLoc(); + SourceLocation IoStateLoc = TL.castAs().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 a; // ^~~~~~~~~~~~~ @@ -58,11 +58,7 @@ void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) { // // std::auto_ptr fn(std::auto_ptr); // ^~~~~~~~~~~~~ ^~~~~~~~~~~~~ - 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(AutoPtrTokenId)) { + if (const auto *PTL = Result.Nodes.getNodeAs(AutoPtrTokenId)) { + auto TL = *PTL; + if (auto QTL = TL.getAs()) + TL = QTL.getUnqualifiedLoc(); // std::auto_ptr i; // ^ - if (auto Loc = TL->getAs()) + if (auto Loc = TL.getAs()) AutoPtrLoc = Loc.getTemplateNameLoc(); } else if (const auto *D = Result.Nodes.getNodeAs(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()) { - 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()) { + const auto *TD = TL.getDecl(); + return TD->getDeclName().isIdentifier() && TD->getName() == "type"; + } + if (auto TL = Node.getAs()) + 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(); - !TSTL.isNull()) + if (auto TSTL = + QualLoc.getAsTypeLoc().getAs()) 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 matchEnableIfSpecializationImplTrait(TypeLoc TheType) { - if (const auto Elaborated = TheType.getAs()) - TheType = Elaborated.getNamedTypeLoc(); - if (const auto SpecializationLoc = TheType.getAs()) { 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( - 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( + 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(); - if (!ElaboratedLoc) - return {}; - - return ElaboratedLoc.getNamedTypeLoc().getAs(); -} - // 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(); 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 Lock' Finder->addMatcher(typedefDecl(unless(isExpansionInSystemHeader()), - hasUnderlyingType(LockGuardType)) + hasType(hasUnderlyingType(LockGuardType))) .bind("lock-guard-typedef"), this); // Match 'using Lock = std::lock_guard' - 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()) { - auto Diag = diag(ElaboratedTL.getBeginLoc(), UseScopedLockMessage); + if (const auto TTL = TL.getAs()) { + 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 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. - 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(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(Decl)) { + if (const auto *ClassDecl = dyn_cast(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 - . if (auto *UD = llvm::dyn_cast(&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(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 { 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(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()->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(QT.getTypePtr())) - OS << TT->getDecl()->getKindName() << " "; + if (auto *TT = llvm::dyn_cast(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(&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 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(T)); -#include "clang/AST/TypeNodes.inc" + case Type::Enum: + case Type::Record: + case Type::InjectedClassName: + return cast(T)->getOriginalDecl(); + case Type::TemplateSpecialization: + return cast(T) + ->getTemplateName() + .getAsTemplateDecl(/*IgnoreDeduced=*/true); + case Type::Typedef: + return cast(T)->getDecl(); + case Type::UnresolvedUsing: + return cast(T)->getDecl(); + case Type::Using: + return cast(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(T)) - return getSimpleName(ET->getNamedType()); if (const auto *BT = llvm::dyn_cast(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 { } 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 { // 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( &QX, [&] { return TraverseTypeLoc(QX.getUnqualifiedLoc()); }); } @@ -798,7 +801,7 @@ class SelectionVisitor : public RecursiveASTVisitor { // 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()) { // 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 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()) @@ -1969,10 +1970,13 @@ static QualType typeForNode(const SelectionTree::Node *N) { if (const Decl *D = N->ASTNode.get()) { struct Visitor : ConstDeclVisitor { + 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 findType(ParsedAST &AST, Position Pos, // unique_ptr>. 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). - 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 *"; + HI.Definition = "const ns::Foo *"; }}, { R"cpp(// this expr for specialization class @@ -2909,7 +2909,7 @@ TEST(Hover, All) { )cpp", [](HoverInfo &HI) { HI.Name = "this"; - HI.Definition = "Foo *"; + HI.Definition = "ns::Foo *"; }}, { 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 *"; + HI.Definition = "const ns::Foo *"; }}, { 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", "y"}); + ExpectedHint{": S1", "x"}, ExpectedHint{": Inner", "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 { NamedDecl *getMemberProvider(QualType Base) { if (Base->isPointerType()) return getMemberProvider(Base->getPointeeType()); - // Unwrap the sugar ElaboratedType. - if (const auto *ElTy = dyn_cast(Base)) - return getMemberProvider(ElTy->getNamedType()); - if (const auto *TT = dyn_cast(Base)) return TT->getDecl(); if (const auto *UT = dyn_cast(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` 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 T qux(T Generic) { async::Future PendingA = acquireUnits(); auto PendingB = acquireUnits(); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: unused local variable 'PendingB' of type 'a::Future' (aka 'Future') [bugprone-unused-local-non-trivial-variable] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: unused local variable 'PendingB' of type 'a::Future' (aka 'async::Future') [bugprone-unused-local-non-trivial-variable] async::Future MustBeUsed; // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: unused local variable 'MustBeUsed' of type 'async::Future' [bugprone-unused-local-non-trivial-variable] PendingA.get(); async::Future TemplateType; // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unused local variable 'TemplateType' of type 'async::Future' [bugprone-unused-local-non-trivial-variable] a::Future AliasTemplateType; - // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unused local variable 'AliasTemplateType' of type 'a::Future' (aka 'Future') [bugprone-unused-local-non-trivial-variable] + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unused local variable 'AliasTemplateType' of type 'a::Future' (aka 'async::Future') [bugprone-unused-local-non-trivial-variable] [[maybe_unused]] async::Future MaybeUnused; return Generic; } @@ -86,7 +86,7 @@ async::Future Global; int bar(int Num) { a::Future PendingA = acquireUnits(); a::Future 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' (aka 'Future') [bugprone-unused-local-non-trivial-variable] + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unused local variable 'PendingB' of type 'a::Future' (aka 'async::Future') [bugprone-unused-local-non-trivial-variable] auto Num2 = PendingA.get(); auto Num3 = qux(Num); async::Ptr> Shared = async::Ptr>(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 allocator {}; void simple(const std::vector &v, std::deque *d) { - // CHECK-MESSAGES: [[#@LINE-1]]:24: warning: container using std::allocator 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 is a deprecated libc++ extension; remove const for compatibility with other standard libraries + // CHECK-MESSAGES: [[#@LINE-2]]:47: warning: container std::list l; - // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container + // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container std::multiset ms; - // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container + // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container std::set> s; - // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container + // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container std::unordered_multiset ums; - // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container + // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container std::unordered_set us; - // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container + // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container absl::flat_hash_set fhs; - // CHECK-MESSAGES: [[#@LINE-1]]:9: warning: container + // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container using my_vector = std::vector; - // 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 &v, std::deque *d) { template void temp1() { std::vector v; - // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container + // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container std::vector neg1; std::forward_list neg2; @@ -87,7 +87,7 @@ template void temp2() { // Match std::vector for the uninstantiated temp2. std::vector v; - // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container + // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container std::vector neg1; std::forward_list neg2;