https://github.com/TPPPP72 created https://github.com/llvm/llvm-project/pull/218264
Fixed a FIXME in `Decl.h` and removed the existing heap allocation API. This is the first time making such extensive changes, so it might take some time to adjust. Assisted by Claude. >From 5778afe6c44e53f707ff96adc3e1f36231beafa4 Mon Sep 17 00:00:00 2001 From: Shengxin Pei <[email protected]> Date: Mon, 24 Aug 2026 01:16:02 +0800 Subject: [PATCH] [clang][AST][NFC] Tree-wide removal of deprecated getQualifiedNameAsString() --- .../CapturingThisInMemberVariableCheck.cpp | 4 +- .../bugprone/DanglingHandleCheck.cpp | 2 +- .../DerivedMethodShadowingBaseMethodCheck.cpp | 2 +- .../bugprone/StandaloneEmptyCheck.cpp | 4 +- .../bugprone/VirtualNearMissCheck.cpp | 3 +- .../fuchsia/TemporaryObjectsCheck.cpp | 8 +- .../clang-tidy/modernize/AvoidBindCheck.cpp | 7 +- .../clang-tidy/modernize/LoopConvertCheck.cpp | 18 +++-- .../MinMaxUseInitializerListCheck.cpp | 13 +++- .../clang-tidy/modernize/UseAutoCheck.cpp | 16 ++-- .../clang-tidy/modernize/UseEmplaceCheck.cpp | 17 +++-- .../readability/EnumInitialValueCheck.cpp | 5 +- .../readability/NamedParameterCheck.cpp | 21 +++-- clang-tools-extra/clang-tidy/utils/Matchers.h | 21 ++++- clang-tools-extra/clangd/refactor/Rename.cpp | 11 ++- .../clangd/refactor/tweaks/DefineOutline.cpp | 22 ++++-- .../include-cleaner/lib/Types.cpp | 15 ++-- clang/include/clang/AST/Decl.h | 3 - clang/include/clang/AST/StmtDataCollectors.td | 22 ++++-- clang/include/clang/ASTMatchers/ASTMatchers.h | 8 +- .../Analysis/Analyses/ThreadSafetyTraverse.h | 4 +- .../StaticAnalyzer/Checkers/SValExplainer.h | 76 +++++++++++-------- clang/lib/AST/ASTDiagnostic.cpp | 24 ++++-- clang/lib/AST/ByteCode/Function.h | 6 +- clang/lib/AST/Decl.cpp | 28 ++++--- clang/lib/AST/DeclPrinter.cpp | 4 +- clang/lib/AST/VTableBuilder.cpp | 17 ++++- clang/lib/Analysis/AnalysisDeclContext.cpp | 4 +- clang/lib/Analysis/CFG.cpp | 4 +- clang/lib/Analysis/IssueHash.cpp | 38 ++++++---- clang/lib/Analysis/LifetimeSafety/Facts.cpp | 7 +- .../LifetimeSafety/LifetimeSafety.cpp | 27 ++++--- clang/lib/Analysis/ProgramPoint.cpp | 17 +++-- clang/lib/CodeGen/CGClass.cpp | 25 ++++-- clang/lib/CodeGen/CGOpenMPRuntime.cpp | 14 ++-- clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp | 9 ++- clang/lib/Frontend/ASTConsumers.cpp | 8 +- .../Interpreter/InterpreterValuePrinter.cpp | 9 +-- clang/lib/Parse/ParseDeclCXX.cpp | 22 +++--- clang/lib/Sema/AnalysisBasedWarnings.cpp | 13 +--- clang/lib/Sema/SemaAccess.cpp | 3 +- clang/lib/Sema/SemaBoundsSafety.cpp | 14 ++-- clang/lib/Sema/SemaChecking.cpp | 14 +++- clang/lib/Sema/SemaExpr.cpp | 3 +- clang/lib/Sema/SemaOverload.cpp | 13 +++- clang/lib/Sema/SemaTemplate.cpp | 10 ++- .../Checkers/AnalysisOrderChecker.cpp | 22 ++++-- .../StaticAnalyzer/Checkers/MallocChecker.cpp | 15 ++-- .../StaticAnalyzer/Checkers/MoveChecker.cpp | 24 +++--- .../Checkers/NoOwnershipChangeVisitor.cpp | 8 +- .../RetainCountDiagnostics.cpp | 8 +- clang/lib/StaticAnalyzer/Core/MemRegion.cpp | 12 +-- clang/lib/StaticAnalyzer/Core/SVals.cpp | 2 +- .../Frontend/AnalysisConsumer.cpp | 13 +++- clang/lib/Tooling/ASTDiff/ASTDiff.cpp | 55 +++++++++----- clang/lib/Tooling/Refactoring/Lookup.cpp | 23 ++++-- .../Tooling/Refactoring/Rename/USRFinder.cpp | 17 ++++- .../Clang/CxxModuleHandler.cpp | 14 +++- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 7 +- .../NativePDB/PdbAstBuilderClang.cpp | 24 ++++-- 60 files changed, 571 insertions(+), 308 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp index a78af8aa2fea3..9b8ff04707b12 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp @@ -133,7 +133,7 @@ void CapturingThisInMemberVariableCheck::check( "'this' captured by a '%0' call and stored in a class member " "variable; disable implicit class copying/moving to prevent potential " "use-after-free") - << Callee->getQualifiedNameAsString(); + << Callee; } const auto *Field = Result.Nodes.getNodeAs<FieldDecl>("field"); @@ -142,7 +142,7 @@ void CapturingThisInMemberVariableCheck::check( diag(Field->getLocation(), "class member of type '%0' that stores captured 'this'", DiagnosticIDs::Note) - << Field->getType().getAsString(); + << Field->getType(); } } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp index c95ad2beed3a9..00d16a4b025e1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp @@ -172,7 +172,7 @@ void DanglingHandleCheck::check(const MatchFinder::MatchResult &Result) { auto *Handle = Result.Nodes.getNodeAs<CXXRecordDecl>("handle"); diag(Result.Nodes.getNodeAs<Stmt>("bad_stmt")->getBeginLoc(), "%0 outlives its value") - << Handle->getQualifiedNameAsString(); + << Handle; } } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/DerivedMethodShadowingBaseMethodCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DerivedMethodShadowingBaseMethodCheck.cpp index 904685cb8416d..bb861bb810f81 100644 --- a/clang-tools-extra/clang-tidy/bugprone/DerivedMethodShadowingBaseMethodCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/DerivedMethodShadowingBaseMethodCheck.cpp @@ -121,7 +121,7 @@ void DerivedMethodShadowingBaseMethodCheck::check( diag(ShadowingMethod->getBeginLoc(), "'%0' shadows method with the same name in class %1") - << ShadowingMethod->getQualifiedNameAsString() << BaseMethod->getParent(); + << ShadowingMethod << BaseMethod->getParent(); diag(BaseMethod->getBeginLoc(), "previous definition of %0 is here", DiagnosticIDs::Note) << ShadowingMethod; diff --git a/clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp index 1d72f3e9f387b..4fcb8b84c7444 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp @@ -200,15 +200,13 @@ void StandaloneEmptyCheck::check(const MatchFinder::MatchResult &Result) { diag(NonMemberLoc, "ignoring the result of '%0'; did you mean 'clear()'?") << dyn_cast<NamedDecl>(NonMemberCall->getCalleeDecl()) - ->getQualifiedNameAsString() << FixItHint::CreateReplacement(ReplacementRange, ReplacementText); return; } } diag(NonMemberLoc, "ignoring the result of '%0'") - << dyn_cast<NamedDecl>(NonMemberCall->getCalleeDecl()) - ->getQualifiedNameAsString(); + << dyn_cast<NamedDecl>(NonMemberCall->getCalleeDecl()); } } diff --git a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp index 07dc77b5dee0a..fa9d213f546ef 100644 --- a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp @@ -253,8 +253,7 @@ void VirtualNearMissCheck::check(const MatchFinder::MatchResult &Result) { diag(DerivedMD->getBeginLoc(), "method '%0' has a similar name and the same signature as " "virtual method '%1'; did you mean to override it?") - << DerivedMD->getQualifiedNameAsString() - << BaseMD->getQualifiedNameAsString(); + << DerivedMD << BaseMD; if (ApplyFix) Diag << FixItHint::CreateReplacement(Range, BaseMD->getName()); } diff --git a/clang-tools-extra/clang-tidy/fuchsia/TemporaryObjectsCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/TemporaryObjectsCheck.cpp index a29eda7289aa2..b0d9e4626e728 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/TemporaryObjectsCheck.cpp +++ b/clang-tools-extra/clang-tidy/fuchsia/TemporaryObjectsCheck.cpp @@ -20,8 +20,12 @@ namespace clang::tidy::fuchsia { namespace { AST_MATCHER_P(CXXRecordDecl, matchesAnyName, ArrayRef<StringRef>, Names) { - const std::string QualifiedName = Node.getQualifiedNameAsString(); - return llvm::is_contained(Names, QualifiedName); + SmallString<128> QualifiedName; + { + llvm::raw_svector_ostream OS(QualifiedName); + Node.printQualifiedName(OS); + } + return llvm::is_contained(Names, QualifiedName.str()); } } // namespace diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp index 3cf0173aaa002..f3c309a1c5a00 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp @@ -147,7 +147,12 @@ static bool isCallExprNamed(const Expr *E, StringRef Name) { const auto *ND = dyn_cast<NamedDecl>(CE->getCalleeDecl()); if (!ND) return false; - return ND->getQualifiedNameAsString() == Name; + SmallString<128> QName; + { + llvm::raw_svector_ostream OS(QName); + ND->printQualifiedName(OS); + } + return QName.str() == Name; } static void diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp index 75bf2a7325900..a25ab6b7f19a1 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp @@ -382,21 +382,25 @@ static std::optional<ContainerCall> getContainerExpr(const Expr *Call) { if (TheCall->getNumArgs() != 1) return std::nullopt; + const FunctionDecl *Callee = TheCall->getDirectCallee(); + if (!Callee) + return std::nullopt; + if (TheCall->usesADL()) { - if (TheCall->getDirectCallee() == nullptr || - !ADLNames.contains(TheCall->getDirectCallee()->getName())) + if (!ADLNames.contains(Callee->getName())) return std::nullopt; CallKind = IteratorCallKind::ICK_ADL; } else { - if (!StdNames.contains( - TheCall->getDirectCallee()->getQualifiedNameAsString())) + SmallString<128> QName; + { + llvm::raw_svector_ostream OS(QName); + Callee->printQualifiedName(OS); + } + if (!StdNames.contains(QName.str())) return std::nullopt; CallKind = IteratorCallKind::ICK_Std; } - if (TheCall->getDirectCallee() == nullptr) - return std::nullopt; - return ContainerCall{TheCall->getArg(0), TheCall->getDirectCallee()->getName(), false, CallKind}; diff --git a/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.cpp index 55f0886d12dee..a3b2e7c473ad2 100644 --- a/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.cpp @@ -133,9 +133,16 @@ generateReplacements(const MatchFinder::MatchResult &Match, continue; } - // if the nested call is not the same as the top call - if (InnerCall->getDirectCallee()->getQualifiedNameAsString() != - TopCall->getDirectCallee()->getQualifiedNameAsString()) + SmallString<128> InnerName, TopName; + { + llvm::raw_svector_ostream InnerOS(InnerName); + InnerCall->getDirectCallee()->printQualifiedName(InnerOS); + + llvm::raw_svector_ostream TopOS(TopName); + TopCall->getDirectCallee()->printQualifiedName(TopOS); + } + + if (InnerName.str() != TopName.str()) continue; const FindArgsResult InnerResult = findArgs(InnerCall); diff --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp index 6c873e3f80004..8d211b39b52f6 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp @@ -432,11 +432,17 @@ void UseAutoCheck::replaceExpr( const StringRef Auto = ShouldReplenishVariableName ? (RemoveStars ? "auto " : "auto *") : (RemoveStars ? "auto " : "auto"); - const std::string ReplenishedVariableName = - ShouldReplenishVariableName ? FirstDecl->getQualifiedNameAsString() : ""; - const std::string Replacement = - (Auto + StringRef{ReplenishedVariableName}).str(); - Diag << FixItHint::CreateReplacement(Range, Replacement) << StarRemovals; + + SmallString<128> Replacement; + { + llvm::raw_svector_ostream OS(Replacement); + OS << Auto; + if (ShouldReplenishVariableName) + FirstDecl->printQualifiedName(OS); + } + + Diag << FixItHint::CreateReplacement(Range, Replacement.str()) + << StarRemovals; } void UseAutoCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp index 8ec123fc476ff..bb685b6569498 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp @@ -23,20 +23,25 @@ AST_MATCHER_P(InitListExpr, initCountLeq, unsigned, N) { // containers. AST_MATCHER_P(NamedDecl, hasAnyNameIgnoringTemplates, std::vector<StringRef>, Names) { - const std::string FullName = "::" + Node.getQualifiedNameAsString(); + SmallString<128> FullName; + { + llvm::raw_svector_ostream OS(FullName); + OS << "::"; + Node.printQualifiedName(OS); + } // This loop removes template specifiers by only keeping characters not within // template brackets. We keep a depth count to handle nested templates. For // example, it'll transform a::b<c<d>>::e<f> to simply a::b::e. - std::string FullNameTrimmed; + SmallString<128> FullNameTrimmed; int Depth = 0; - for (const auto &Character : FullName) - if (Character == '<') + for (char C : FullName) + if (C == '<') ++Depth; - else if (Character == '>') + else if (C == '>') --Depth; else if (Depth == 0) - FullNameTrimmed.append(1, Character); + FullNameTrimmed.push_back(C); // This loop is taken from HasNameMatcher::matchesNodeFullSlow in // clang/lib/ASTMatchers/ASTMatchersInternal.cpp and checks whether diff --git a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp index 620c5bece4eba..2b97c813c72b9 100644 --- a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp @@ -153,7 +153,10 @@ static std::string getName(const EnumDecl *Decl) { if (!Decl->getDeclName()) return "<unnamed>"; - return Decl->getQualifiedNameAsString(); + SmallString<128> Name; + llvm::raw_svector_ostream OS(Name); + Decl->printQualifiedName(OS); + return std::string(Name.str()); } EnumInitialValueCheck::EnumInitialValueCheck(StringRef Name, diff --git a/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp b/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp index 07d1bbeccbc16..0195e174003ef 100644 --- a/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp @@ -100,10 +100,15 @@ void NamedParameterCheck::check(const MatchFinder::MatchResult &Result) { continue; // Skip gmock testing::Unused parameters. - if (const auto *Typedef = Parm->getType()->getAs<TypedefType>(); - Typedef && - Typedef->getDecl()->getQualifiedNameAsString() == "testing::Unused") - continue; + if (const auto *Typedef = Parm->getType()->getAs<TypedefType>()) { + SmallString<64> TypedefQName; + { + llvm::raw_svector_ostream OS(TypedefQName); + Typedef->getDecl()->printQualifiedName(OS); + } + if (TypedefQName.str() == "testing::Unused") + continue; + } // Skip std::nullptr_t. if (Parm->getType().getCanonicalType()->isNullPtrType()) @@ -113,8 +118,12 @@ void NamedParameterCheck::check(const MatchFinder::MatchResult &Result) { // tag dispatch types). if (const auto *Record = Parm->getType().getCanonicalType()->getAsCXXRecordDecl()) { - const std::string QName = Record->getQualifiedNameAsString(); - if (llvm::is_contained(IgnoredTypes, QName)) + SmallString<128> QName; + { + llvm::raw_svector_ostream OS(QName); + Record->printQualifiedName(OS); + } + if (llvm::is_contained(IgnoredTypes, QName.str())) continue; } diff --git a/clang-tools-extra/clang-tidy/utils/Matchers.h b/clang-tools-extra/clang-tidy/utils/Matchers.h index e04da47322623..2e37d03cb31f4 100644 --- a/clang-tools-extra/clang-tidy/utils/Matchers.h +++ b/clang-tools-extra/clang-tidy/utils/Matchers.h @@ -107,10 +107,23 @@ class MatchesAnyListedRegexNameMatcher bool match(const NamedDecl &ND) const { switch (Mode) { - case MatchMode::MatchQualified: - return Regex.match(ND.getQualifiedNameAsString()); - case MatchMode::MatchFullyQualified: - return Regex.match("::" + ND.getQualifiedNameAsString()); + case MatchMode::MatchQualified: { + SmallString<128> QName; + { + llvm::raw_svector_ostream OS(QName); + ND.printQualifiedName(OS); + } + return Regex.match(QName.str()); + } + case MatchMode::MatchFullyQualified: { + SmallString<128> QName; + { + llvm::raw_svector_ostream OS(QName); + OS << "::"; + ND.printQualifiedName(OS); + } + return Regex.match(QName.str()); + } default: if (const IdentifierInfo *II = ND.getIdentifier()) return Regex.match(II->getName()); diff --git a/clang-tools-extra/clangd/refactor/Rename.cpp b/clang-tools-extra/clangd/refactor/Rename.cpp index c56375b1a98d3..cccdc73b055ae 100644 --- a/clang-tools-extra/clangd/refactor/Rename.cpp +++ b/clang-tools-extra/clangd/refactor/Rename.cpp @@ -898,9 +898,14 @@ findOccurrencesOutsideFile(const NamedDecl &RenameDecl, if (AffectedFiles.size() >= MaxLimitFiles) return error("The number of affected files exceeds the max limit {0}", MaxLimitFiles); - if (HasMore) - return error("The symbol {0} has too many occurrences", - RenameDecl.getQualifiedNameAsString()); + if (HasMore) { + SmallString<128> QName; + { + llvm::raw_svector_ostream OS(QName); + RenameDecl.printQualifiedName(OS); + } + return error("The symbol {0} has too many occurrences", QName.str()); + } // Sort and deduplicate the results, in case that index returns duplications. for (auto &FileAndOccurrences : AffectedFiles) { auto &Ranges = FileAndOccurrences.getValue(); diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp index dcc417b5f7d8c..613e0d2cb039c 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -84,13 +84,14 @@ findContextForNS(llvm::StringRef TargetNS, const DeclContext *CurContext) { } // Otherwise we need to drop any trailing namespaces from CurContext until // we reach TargetNS. - std::string TargetContextNS = - CurContext->isNamespace() - ? llvm::cast<NamespaceDecl>(CurContext)->getQualifiedNameAsString() - : ""; - TargetContextNS.append("::"); + SmallString<128> TargetContextNSBuf; + if (const auto *NS = llvm::dyn_cast<NamespaceDecl>(CurContext)) { + llvm::raw_svector_ostream OS(TargetContextNSBuf); + NS->printQualifiedName(OS); + } + TargetContextNSBuf.append("::"); - llvm::StringRef CurrentContextNS(TargetContextNS); + llvm::StringRef CurrentContextNS(TargetContextNSBuf.str()); // If TargetNS is not a prefix of CurrentContext, there's no way to reach // it. if (!CurrentContextNS.starts_with(TargetNS)) @@ -600,8 +601,13 @@ class DefineOutline : public Tweak { Offset = P->Offset; EnclosingNamespace = P->EnclosingNamespace; } else { - auto Region = getEligiblePoints( - Contents, Source->getQualifiedNameAsString(), Sel.AST->getLangOpts()); + SmallString<128> SourceQName; + { + llvm::raw_svector_ostream OS(SourceQName); + Source->printQualifiedName(OS); + } + auto Region = getEligiblePoints(Contents, SourceQName.str(), + Sel.AST->getLangOpts()); assert(!Region.EligiblePoints.empty()); EnclosingNamespaceName = Region.EnclosingNamespace; InsertionPos = Region.EligiblePoints.back(); diff --git a/clang-tools-extra/include-cleaner/lib/Types.cpp b/clang-tools-extra/include-cleaner/lib/Types.cpp index d7635c258e522..715d9d2a631b0 100644 --- a/clang-tools-extra/include-cleaner/lib/Types.cpp +++ b/clang-tools-extra/include-cleaner/lib/Types.cpp @@ -25,9 +25,12 @@ std::string Symbol::name() const { switch (kind()) { case include_cleaner::Symbol::Macro: return macro().Name->getName().str(); - case include_cleaner::Symbol::Declaration: - return llvm::dyn_cast<NamedDecl>(&declaration()) - ->getQualifiedNameAsString(); + case include_cleaner::Symbol::Declaration: { + SmallString<128> Name; + llvm::raw_svector_ostream OS(Name); + llvm::cast<NamedDecl>(&declaration())->printQualifiedName(OS); + return std::string(Name.str()); + } } llvm_unreachable("Unknown symbol kind"); } @@ -35,8 +38,10 @@ std::string Symbol::name() const { llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) { switch (S.kind()) { case Symbol::Declaration: - if (const auto *ND = llvm::dyn_cast<NamedDecl>(&S.declaration())) - return OS << ND->getQualifiedNameAsString(); + if (const auto *ND = llvm::dyn_cast<NamedDecl>(&S.declaration())) { + ND->printQualifiedName(OS); + return OS; + } return OS << S.declaration().getDeclKindName(); case Symbol::Macro: return OS << S.macro().Name->getName(); diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 92050d635e2e0..bfdafb32a9306 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -361,9 +361,6 @@ class NamedDecl : public Decl { void printNestedNameSpecifier(raw_ostream &OS, const PrintingPolicy &Policy) const; - // FIXME: Remove string version. - std::string getQualifiedNameAsString() const; - /// Appends a human-readable name for this declaration into the given stream. /// /// This is the method invoked by Sema when displaying a NamedDecl diff --git a/clang/include/clang/AST/StmtDataCollectors.td b/clang/include/clang/AST/StmtDataCollectors.td index abf4b5f34d349..ce6e20b0629c7 100644 --- a/clang/include/clang/AST/StmtDataCollectors.td +++ b/clang/include/clang/AST/StmtDataCollectors.td @@ -46,19 +46,22 @@ class CallExpr { // If the function is a template specialization, we also need to handle // the template arguments as they are not included in the qualified name. if (auto Args = D->getTemplateSpecializationArgs()) { - std::string ArgString; - - // Print all template arguments into ArgString - llvm::raw_string_ostream OS(ArgString); + SmallString<256> ArgString; + llvm::raw_svector_ostream OS(ArgString); for (unsigned i = 0; i < Args->size(); ++i) { Args->get(i).print(Context.getLangOpts(), OS, /*IncludeType*/ true); // Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'. OS << '\n'; } - addData(ArgString); + addData(ArgString.str()); + } + SmallString<128> QualName; + { + llvm::raw_svector_ostream OS(QualName); + D->printQualifiedName(OS); } - addData(D->getQualifiedNameAsString()); + addData(QualName.str()); } }]; } @@ -66,7 +69,12 @@ class CallExpr { //--- Value references ---------------------------------------------------// class DeclRefExpr { code Code = [{ - addData(S->getDecl()->getQualifiedNameAsString()); + SmallString<128> QualName; + { + llvm::raw_svector_ostream OS(QualName); + S->getDecl()->printQualifiedName(OS); + } + addData(QualName.str()); }]; } class MemberExpr { diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 43cbeb3b40eac..39140dd657bb4 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -58,7 +58,6 @@ #include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/LambdaCapture.h" -#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/OpenMPClause.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/ParentMapContext.h" @@ -76,7 +75,6 @@ #include "clang/Basic/AttrKinds.h" #include "clang/Basic/BuiltinTraits.h" #include "clang/Basic/ExceptionSpecificationType.h" -#include "clang/Basic/FileManager.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceManager.h" @@ -86,7 +84,6 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Regex.h" #include <cassert> @@ -3247,7 +3244,10 @@ extern const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef, /// namespace foo { namespace bar { class X; } } /// \endcode AST_MATCHER_REGEX(NamedDecl, matchesName, RegExp) { - std::string FullNameString = "::" + Node.getQualifiedNameAsString(); + SmallString<128> FullNameString; + llvm::raw_svector_ostream OS(FullNameString); + OS << "::"; + Node.printQualifiedName(OS); return RegExp->match(FullNameString); } diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h index 3c14716ff7156..160f906ab024e 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h @@ -22,9 +22,7 @@ #include "clang/Analysis/Analyses/ThreadSafetyUtil.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/Casting.h" #include <cstdint> -#include <ostream> namespace clang { namespace threadSafety { @@ -659,7 +657,7 @@ class PrettyPrinter { if (isa<Wildcard>(E->record())) { // handle existentials SS << "&"; - SS << E->clangDecl()->getQualifiedNameAsString(); + E->clangDecl()->printQualifiedName(SS); return; } } diff --git a/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h b/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h index 6c1025ecc7f4d..a8223276cb3e2 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h +++ b/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h @@ -114,9 +114,15 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> { std::string VisitSymbolRegionValue(const SymbolRegionValue *S) { const MemRegion *R = S->getRegion(); // Special handling for argument values. - if (auto V = dyn_cast<VarRegion>(R)) - if (auto D = dyn_cast<ParmVarDecl>(V->getDecl())) - return "argument '" + D->getQualifiedNameAsString() + "'"; + if (const auto *V = dyn_cast<VarRegion>(R)) { + if (const auto *D = dyn_cast<ParmVarDecl>(V->getDecl())) { + SmallString<128> QualName; + llvm::raw_svector_ostream OS(QualName); + D->printQualifiedName(OS); + return "argument '" + std::string(QualName.str()) + "'"; + } + } + return "initial value of " + Visit(R); } @@ -216,19 +222,20 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> { std::string VisitNonParamVarRegion(const NonParamVarRegion *R) { const VarDecl *VD = R->getDecl(); - std::string Name = VD->getQualifiedNameAsString(); + SmallString<128> QualName; + llvm::raw_svector_ostream OS(QualName); + VD->printQualifiedName(OS); if (isa<ParmVarDecl>(VD)) - return "parameter '" + Name + "'"; - else if (VD->hasAttr<BlocksAttr>()) - return "block variable '" + Name + "'"; - else if (VD->hasLocalStorage()) - return "local variable '" + Name + "'"; - else if (VD->isStaticLocal()) - return "static local variable '" + Name + "'"; - else if (VD->hasGlobalStorage()) - return "global variable '" + Name + "'"; - else - llvm_unreachable("A variable is either local or global"); + return "parameter '" + std::string(QualName.str()) + "'"; + if (VD->hasAttr<BlocksAttr>()) + return "block variable '" + std::string(QualName.str()) + "'"; + if (VD->hasLocalStorage()) + return "local variable '" + std::string(QualName.str()) + "'"; + if (VD->isStaticLocal()) + return "static local variable '" + std::string(QualName.str()) + "'"; + if (VD->hasGlobalStorage()) + return "global variable '" + std::string(QualName.str()) + "'"; + llvm_unreachable("A variable is either local or global"); } std::string VisitObjCIvarRegion(const ObjCIvarRegion *R) { @@ -247,8 +254,11 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> { } std::string VisitCXXBaseObjectRegion(const CXXBaseObjectRegion *R) { - return "base object '" + R->getDecl()->getQualifiedNameAsString() + - "' inside " + Visit(R->getSuperRegion()); + SmallString<128> QualName; + llvm::raw_svector_ostream OS(QualName); + R->getDecl()->printQualifiedName(OS); + return "base object '" + std::string(QualName) + "' inside " + + Visit(R->getSuperRegion()); } std::string VisitParamVarRegion(const ParamVarRegion *R) { @@ -256,24 +266,30 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> { llvm::raw_string_ostream OS(Str); const ParmVarDecl *PVD = R->getDecl(); - std::string Name = PVD->getQualifiedNameAsString(); - if (!Name.empty()) { - OS << "parameter '" << Name << "'"; - return std::string(OS.str()); + if (!PVD->getDeclName().isEmpty()) { + SmallString<64> Str; + llvm::raw_svector_ostream OS(Str); + OS << "parameter '"; + PVD->printQualifiedName(OS); + OS << "'"; + return std::string(Str); } unsigned Index = R->getIndex() + 1; OS << Index << llvm::getOrdinalSuffix(Index) << " parameter of "; const Decl *Parent = R->getStackFrame()->getDecl(); - if (const auto *FD = dyn_cast<FunctionDecl>(Parent)) - OS << "function '" << FD->getQualifiedNameAsString() << "()'"; - else if (const auto *CD = dyn_cast<CXXConstructorDecl>(Parent)) - OS << "C++ constructor '" << CD->getQualifiedNameAsString() << "()'"; - else if (const auto *MD = dyn_cast<ObjCMethodDecl>(Parent)) { - if (MD->isClassMethod()) - OS << "Objective-C method '+" << MD->getQualifiedNameAsString() << "'"; - else - OS << "Objective-C method '-" << MD->getQualifiedNameAsString() << "'"; + if (const auto *FD = dyn_cast<FunctionDecl>(Parent)) { + OS << "function '"; + FD->printQualifiedName(OS); + OS << "()'"; + } else if (const auto *CD = dyn_cast<CXXConstructorDecl>(Parent)) { + OS << "C++ constructor '"; + CD->printQualifiedName(OS); + OS << "()'"; + } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(Parent)) { + OS << "Objective-C method '" << (MD->isClassMethod() ? '+' : '-'); + MD->printQualifiedName(OS); + OS << "'"; } else if (isa<BlockDecl>(Parent)) { if (cast<BlockDecl>(Parent)->isConversionFromLambda()) OS << "lambda"; diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 0925fbdcbaeb7..66228956e92ff 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -1805,12 +1805,26 @@ class TemplateDiff { bool FromDefault, bool ToDefault, bool Same) { assert((FromTD || ToTD) && "Only one template argument may be missing."); - std::string FromName = - std::string(FromTD ? FromTD->getName() : "(no argument)"); - std::string ToName = std::string(ToTD ? ToTD->getName() : "(no argument)"); + SmallString<128> FromNameBuffer, ToNameBuffer; + StringRef FromName = "(no argument)"; + StringRef ToName = "(no argument)"; + + if (FromTD) + FromName = FromTD->getName(); + if (ToTD) + ToName = ToTD->getName(); + if (FromTD && ToTD && FromName == ToName) { - FromName = FromTD->getQualifiedNameAsString(); - ToName = ToTD->getQualifiedNameAsString(); + { + llvm::raw_svector_ostream OS(FromNameBuffer); + FromTD->printQualifiedName(OS); + } + { + llvm::raw_svector_ostream OS(ToNameBuffer); + ToTD->printQualifiedName(OS); + } + FromName = FromNameBuffer; + ToName = ToNameBuffer; } if (Same) { diff --git a/clang/lib/AST/ByteCode/Function.h b/clang/lib/AST/ByteCode/Function.h index 9742a16b50f2c..1b0739fdd7a39 100644 --- a/clang/lib/AST/ByteCode/Function.h +++ b/clang/lib/AST/ByteCode/Function.h @@ -144,7 +144,11 @@ class Function final { if (!Source || !getDecl()) return "<<expr>>"; - return getDecl()->getQualifiedNameAsString(); + SmallString<128> Buffer; + llvm::raw_svector_ostream OS(Buffer); + getDecl()->printQualifiedName(OS); + + return std::string(Buffer.str()); } /// Returns a parameter descriptor. diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 0894097333d73..814fe8731f5ec 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1681,13 +1681,6 @@ void NamedDecl::printName(raw_ostream &OS) const { printName(OS, getASTContext().getPrintingPolicy()); } -std::string NamedDecl::getQualifiedNameAsString() const { - std::string QualName; - llvm::raw_string_ostream OS(QualName); - printQualifiedName(OS, getASTContext().getPrintingPolicy()); - return QualName; -} - void NamedDecl::printQualifiedName(raw_ostream &OS) const { printQualifiedName(OS, getASTContext().getPrintingPolicy()); } @@ -5446,21 +5439,32 @@ bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const { else if (NoSanitizeList.containsLocation(EnabledAsanMask, getLocation(), "field-padding")) ReasonToReject = 6; // is in an excluded file. - else if (NoSanitizeList.containsType( - EnabledAsanMask, getQualifiedNameAsString(), "field-padding")) - ReasonToReject = 7; // The type is excluded. + + SmallString<128> QualifiedName; + auto getQualName = [this, &QualifiedName]() -> StringRef { + if (QualifiedName.empty()) { + llvm::raw_svector_ostream OS(QualifiedName); + printQualifiedName(OS); + } + return QualifiedName; + }; + + if (ReasonToReject < 0 && + NoSanitizeList.containsType(EnabledAsanMask, getQualName(), + "field-padding")) + ReasonToReject = 7; // The type is excluded. if (EmitRemark) { if (ReasonToReject >= 0) Context.getDiagnostics().Report( getLocation(), diag::remark_sanitize_address_insert_extra_padding_rejected) - << getQualifiedNameAsString() << ReasonToReject; + << getQualName() << ReasonToReject; else Context.getDiagnostics().Report( getLocation(), diag::remark_sanitize_address_insert_extra_padding_accepted) - << getQualifiedNameAsString(); + << getQualName(); } return ReasonToReject < 0; } diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 1312ffd080342..14c45ab00c808 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -716,10 +716,10 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { SubPolicy.SuppressSpecifiers = false; std::string Proto; + llvm::raw_string_ostream OS(Proto); if (Policy.FullyQualifiedName) { - Proto += D->getQualifiedNameAsString(); + D->printQualifiedName(OS, SubPolicy); } else { - llvm::raw_string_ostream OS(Proto); if (!Policy.SuppressScope) D->getQualifier().print(OS, Policy); D->getNameInfo().printName(OS, Policy); diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp index 3c05d4b22b03e..c9d9f0a6fbeda 100644 --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -2132,7 +2132,13 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { assert(I.second.getBaseOffset() == BaseOffset && "Invalid base offset!"); const CXXRecordDecl *RD = I.second.getBase(); - ClassNames.insert(RD->getQualifiedNameAsString()); + + SmallString<128> NameBuffer; + { + llvm::raw_svector_ostream OS(NameBuffer); + RD->printQualifiedName(OS); + } + ClassNames.emplace(NameBuffer.str()); } for (const std::string &Name : ClassNames) { @@ -2154,9 +2160,12 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { std::map<std::string, CharUnits> ClassNamesAndOffsets; for (const auto &I : VBaseOffsetOffsets) { - std::string ClassName = I.first->getQualifiedNameAsString(); - CharUnits OffsetOffset = I.second; - ClassNamesAndOffsets.insert(std::make_pair(ClassName, OffsetOffset)); + SmallString<128> ClassNameBuffer; + { + llvm::raw_svector_ostream OS(ClassNameBuffer); + I.first->printQualifiedName(OS); + } + ClassNamesAndOffsets.emplace(ClassNameBuffer.str(), I.second); } Out << "Virtual base offset offsets for '"; diff --git a/clang/lib/Analysis/AnalysisDeclContext.cpp b/clang/lib/Analysis/AnalysisDeclContext.cpp index 649035c46d019..17dd7a3d6f411 100644 --- a/clang/lib/Analysis/AnalysisDeclContext.cpp +++ b/clang/lib/Analysis/AnalysisDeclContext.cpp @@ -340,7 +340,7 @@ std::string AnalysisDeclContext::getFunctionName(const Decl *D) { const ASTContext &Ctx = D->getASTContext(); if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { - OS << FD->getQualifiedNameAsString(); + FD->printQualifiedName(OS); // In C++, there are overloads. @@ -474,7 +474,7 @@ void StackFrame::printJson( << "{ \"lctx_id\": " << SF.getID() << ", \"location_context\": \""; Out << '#' << Idx << " Call\", \"calling\": \""; if (const auto *D = dyn_cast<NamedDecl>(SF.getDecl())) - Out << D->getQualifiedNameAsString(); + D->printQualifiedName(Out, PP); else Out << "anonymous code"; diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 5263114ebca28..ce80c4951bc45 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -6116,14 +6116,14 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper, case CFGElement::Kind::ScopeBegin: OS << "CFGScopeBegin("; if (const VarDecl *VD = E.castAs<CFGScopeBegin>().getVarDecl()) - OS << VD->getQualifiedNameAsString(); + VD->printQualifiedName(OS); OS << ")"; break; case CFGElement::Kind::ScopeEnd: OS << "CFGScopeEnd("; if (const VarDecl *VD = E.castAs<CFGScopeEnd>().getVarDecl()) - OS << VD->getQualifiedNameAsString(); + VD->printQualifiedName(OS); OS << ")"; break; diff --git a/clang/lib/Analysis/IssueHash.cpp b/clang/lib/Analysis/IssueHash.cpp index 6f97b1964550f..a3d9f49ff4d74 100644 --- a/clang/lib/Analysis/IssueHash.cpp +++ b/clang/lib/Analysis/IssueHash.cpp @@ -29,6 +29,7 @@ static std::string GetSignature(const FunctionDecl *Target) { if (!Target) return ""; std::string Signature; + llvm::raw_string_ostream OS(Signature); // When a flow sensitive bug happens in templated code we should not generate // distinct hash value for every instantiation. Use the signature from the @@ -38,19 +39,25 @@ static std::string GetSignature(const FunctionDecl *Target) { Target = InstantiatedFrom; if (!isa<CXXConstructorDecl>(Target) && !isa<CXXDestructorDecl>(Target) && - !isa<CXXConversionDecl>(Target)) - Signature.append(Target->getReturnType().getAsString()).append(" "); - Signature.append(Target->getQualifiedNameAsString()).append("("); + !isa<CXXConversionDecl>(Target)) { + Target->getReturnType().print( + OS, PrintingPolicy(Target->getASTContext().getLangOpts())); + OS << ' '; + } + + Target->printQualifiedName(OS); + OS << '('; for (int i = 0, paramsCount = Target->getNumParams(); i < paramsCount; ++i) { if (i) - Signature.append(", "); - Signature.append(Target->getParamDecl(i)->getType().getAsString()); + OS << ", "; + Target->getParamDecl(i)->getType().print( + OS, PrintingPolicy(Target->getASTContext().getLangOpts())); } if (Target->isVariadic()) - Signature.append(", ..."); - Signature.append(")"); + OS << ", ..."; + OS << ')'; const auto *TargetT = llvm::dyn_cast_or_null<FunctionType>(Target->getType().getTypePtr()); @@ -59,20 +66,20 @@ static std::string GetSignature(const FunctionDecl *Target) { return Signature; if (TargetT->isConst()) - Signature.append(" const"); + OS << " const"; if (TargetT->isVolatile()) - Signature.append(" volatile"); + OS << " volatile"; if (TargetT->isRestrict()) - Signature.append(" restrict"); + OS << " restrict"; if (const auto *TargetPT = dyn_cast_or_null<FunctionProtoType>(Target->getType().getTypePtr())) { switch (TargetPT->getRefQualifier()) { case RQ_LValue: - Signature.append(" &"); + OS << " &"; break; case RQ_RValue: - Signature.append(" &&"); + OS << " &&"; break; default: break; @@ -87,7 +94,12 @@ static std::string GetEnclosingDeclContextSignature(const Decl *EnclosingDecl) { if (const auto *FD = dyn_cast<FunctionDecl>(ND)) // To distinguish overloads we need to use the signature. return GetSignature(FD); - return ND->getQualifiedNameAsString(); + SmallString<128> QualName; + { + llvm::raw_svector_ostream OS(QualName); + ND->printQualifiedName(OS); + } + return std::string(QualName.str()); } return ""; } diff --git a/clang/lib/Analysis/LifetimeSafety/Facts.cpp b/clang/lib/Analysis/LifetimeSafety/Facts.cpp index a56774327731c..bacce14a61f30 100644 --- a/clang/lib/Analysis/LifetimeSafety/Facts.cpp +++ b/clang/lib/Analysis/LifetimeSafety/Facts.cpp @@ -213,8 +213,11 @@ void FactManager::dump(const CFG &Cfg, AnalysisDeclContext &AC, llvm::dbgs() << " Lifetime Analysis Facts:\n"; llvm::dbgs() << "==========================================\n"; if (const Decl *D = AC.getDecl()) - if (const auto *ND = dyn_cast<NamedDecl>(D)) - llvm::dbgs() << "Function: " << ND->getQualifiedNameAsString() << "\n"; + if (const auto *ND = dyn_cast<NamedDecl>(D)) { + llvm::dbgs() << "Function: "; + ND->printQualifiedName(llvm::dbgs()); + llvm::dbgs() << "\n"; + } // Print blocks in the order as they appear in code for a stable ordering. for (const CFGBlock *B : *AC.getAnalysis<PostOrderCFGView>()) { llvm::dbgs() << " Block B" << B->getBlockID() << ":\n"; diff --git a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp index 798812327d3ab..8fce2c8a0cad2 100644 --- a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp +++ b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp @@ -37,11 +37,14 @@ namespace internal { static void DebugOnlyFunction(AnalysisDeclContext &AC, const CFG &Cfg, FactManager &FactMgr, const LoanPropagationAnalysis *LPA) { - std::string Name; + SmallString<128> Name; if (const Decl *D = AC.getDecl()) { - if (const auto *ND = dyn_cast<NamedDecl>(D)) - Name = ND->getQualifiedNameAsString(); - }; + if (const auto *ND = dyn_cast<NamedDecl>(D)) { + llvm::raw_svector_ostream OS(Name); + ND->printQualifiedName(OS); + } + } + DEBUG_WITH_TYPE(Name.c_str(), AC.getDecl()->dumpColor()); DEBUG_WITH_TYPE(Name.c_str(), Cfg.dump(AC.getASTContext().getLangOpts(), /*ShowColors=*/true)); @@ -60,13 +63,15 @@ void LifetimeSafetyAnalysis::run() { const CFG &Cfg = *AC.getCFG(); if (LSOpts.MaxCFGBlocks > 0 && Cfg.getNumBlockIDs() > LSOpts.MaxCFGBlocks) { DEBUG_WITH_TYPE( - "LifetimeSafety", std::string FuncName = "<unknown>"; - if (const Decl *D = AC.getDecl()) if (const auto *ND = - dyn_cast<NamedDecl>(D)) - FuncName = ND->getQualifiedNameAsString(); - llvm::dbgs() << "LifetimeSafety: Skipping function " << FuncName - << "due to large CFG: " << Cfg.getNumBlockIDs() - << " blocks (threshold: " << LSOpts.MaxCFGBlocks << ")\n"); + "LifetimeSafety", llvm::dbgs() << "LifetimeSafety: Skipping function "; + if (const Decl *D = AC.getDecl()) { + if (const auto *ND = dyn_cast<NamedDecl>(D)) + ND->printQualifiedName(llvm::dbgs()); + else + llvm::dbgs() << "<unknown>"; + } else { llvm::dbgs() << "<unknown>"; } llvm::dbgs() + << " due to large CFG: " << Cfg.getNumBlockIDs() + << " blocks (threshold: " << LSOpts.MaxCFGBlocks << ")\n"); return; } diff --git a/clang/lib/Analysis/ProgramPoint.cpp b/clang/lib/Analysis/ProgramPoint.cpp index bca2581d923b6..6acae66564700 100644 --- a/clang/lib/Analysis/ProgramPoint.cpp +++ b/clang/lib/Analysis/ProgramPoint.cpp @@ -224,24 +224,25 @@ void ProgramPoint::printJson(llvm::raw_ostream &Out, const char *NL) const { break; case ProgramPoint::LifetimeEndKind: - Out << "LifetimeEnd\", \"var\": \"" - << castAs<LifetimeEnd>().getDecl()->getNameAsString() << '\"'; + Out << "LifetimeEnd\", \"var\": \""; + castAs<LifetimeEnd>().getDecl()->printName(Out); + Out << '\"'; break; case ProgramPoint::PreImplicitCallKind: { ImplicitCallPoint PC = castAs<ImplicitCallPoint>(); - Out << "PreCall\", \"decl\": \"" - << PC.getDecl()->getAsFunction()->getQualifiedNameAsString() - << "\", \"location\": "; + Out << "PreCall\", \"decl\": \""; + PC.getDecl()->getAsFunction()->printQualifiedName(Out, PP); + Out << "\", \"location\": "; printSourceLocationAsJson(Out, PC.getLocation(), SM); break; } case ProgramPoint::PostImplicitCallKind: { ImplicitCallPoint PC = castAs<ImplicitCallPoint>(); - Out << "PostCall\", \"decl\": \"" - << PC.getDecl()->getAsFunction()->getQualifiedNameAsString() - << "\", \"location\": "; + Out << "PostCall\", \"decl\": \""; + PC.getDecl()->getAsFunction()->printQualifiedName(Out, PP); + Out << "\", \"location\": "; printSourceLocationAsJson(Out, PC.getLocation(), SM); break; } diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 9c0c1cbdeb219..946e5860474c5 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -3033,9 +3033,14 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD, auto [M, SSK] = SanitizerInfoFromCFICheckKind(TCK); - std::string TypeName = RD->getQualifiedNameAsString(); + SmallString<128> TypeName; + { + llvm::raw_svector_ostream OS(TypeName); + RD->printQualifiedName(OS); + } + if (getContext().getNoSanitizeList().containsType( - SanitizerMask::bitPosToMask(M), TypeName)) + SanitizerMask::bitPosToMask(M), TypeName.str())) return; EmitSanitizerStatReport(SSK); @@ -3087,9 +3092,13 @@ bool CodeGenFunction::ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD) { !CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIVCall)) return false; - std::string TypeName = RD->getQualifiedNameAsString(); + SmallString<128> TypeName; + { + llvm::raw_svector_ostream OS(TypeName); + RD->printQualifiedName(OS); + } return !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall, - TypeName); + TypeName.str()); } llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad( @@ -3114,10 +3123,14 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad( llvm::Value *CheckResult = Builder.CreateExtractValue(CheckedLoad, 1); - std::string TypeName = RD->getQualifiedNameAsString(); + SmallString<128> TypeName; + { + llvm::raw_svector_ostream OS(TypeName); + RD->printQualifiedName(OS); + } if (SanOpts.has(SanitizerKind::CFIVCall) && !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall, - TypeName)) { + TypeName.str())) { EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler, {}, {}); } diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 26aaef9d331c0..7235f23bfa35e 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -1376,7 +1376,7 @@ static StringRef getIdentStringFromSourceLocation(CodeGenFunction &CGF, OS << PLoc.getFilename(); OS << ";"; if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl)) - OS << FD->getQualifiedNameAsString(); + FD->printQualifiedName(OS); OS << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;"; return OS.str(); } @@ -1391,15 +1391,19 @@ llvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF, Loc.isInvalid()) { SrcLocStr = OMPBuilder.getOrCreateDefaultSrcLocStr(SrcLocStrSize); } else { - std::string FunctionName; - std::string FileName; - if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl)) - FunctionName = FD->getQualifiedNameAsString(); + SmallString<128> FunctionName; + if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl)) { + llvm::raw_svector_ostream OS(FunctionName); + FD->printQualifiedName(OS); + } + PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc); + std::string FileName; if (auto *DbgInfo = CGF.getDebugInfo()) FileName = DbgInfo->remapDIPath(PLoc.getFilename()); else FileName = PLoc.getFilename(); + unsigned Line = PLoc.getLine(); unsigned Column = PLoc.getColumn(); SrcLocStr = OMPBuilder.getOrCreateSrcLocStr(FunctionName, FileName, Line, diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp index b09fc4c91df2a..c7b660fb8d2ec 100644 --- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp +++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp @@ -96,8 +96,13 @@ HLSLBufferLayoutBuilder::layOutStruct(const RecordType *RT, // Create the layout struct type; anonymous structs have empty name but // non-empty qualified name const auto *Decl = RT->castAsCXXRecordDecl(); - std::string Name = - Decl->getName().empty() ? "anon" : Decl->getQualifiedNameAsString(); + SmallString<64> Name; + if (Decl->getName().empty()) { + Name = "anon"; + } else { + llvm::raw_svector_ostream OS(Name); + Decl->printQualifiedName(OS); + } llvm::StructType *NewTy = llvm::StructType::create(Layout, Name, /*isPacked=*/true); diff --git a/clang/lib/Frontend/ASTConsumers.cpp b/clang/lib/Frontend/ASTConsumers.cpp index 40995e32b67fa..adb9b766b10a8 100644 --- a/clang/lib/Frontend/ASTConsumers.cpp +++ b/clang/lib/Frontend/ASTConsumers.cpp @@ -79,8 +79,12 @@ namespace { private: std::string getName(Decl *D) { - if (isa<NamedDecl>(D)) - return cast<NamedDecl>(D)->getQualifiedNameAsString(); + if (auto *ND = dyn_cast_or_null<NamedDecl>(D)) { + SmallString<64> Name; + llvm::raw_svector_ostream OS(Name); + ND->printQualifiedName(OS); + return std::string(Name.str()); + } return ""; } bool filterMatches(Decl *D) { diff --git a/clang/lib/Interpreter/InterpreterValuePrinter.cpp b/clang/lib/Interpreter/InterpreterValuePrinter.cpp index 79f1e2b6571c6..b9bb100e07de9 100644 --- a/clang/lib/Interpreter/InterpreterValuePrinter.cpp +++ b/clang/lib/Interpreter/InterpreterValuePrinter.cpp @@ -21,14 +21,11 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Sema.h" - #include "llvm/Support/Error.h" #include "llvm/Support/raw_ostream.h" - #include <cassert> #include <cmath> #include <cstdarg> -#include <sstream> #include <string> #define DEBUG_TYPE "interp-value" @@ -40,7 +37,7 @@ static std::string DeclTypeToString(const QualType &QT, NamedDecl *D) { llvm::raw_string_ostream SS(Str); if (QT.hasQualifiers()) SS << QT.getQualifiers().getAsString() << " "; - SS << D->getQualifiedNameAsString(); + D->printQualifiedName(SS); return Str; } @@ -109,7 +106,9 @@ static std::string EnumToString(const Value &V) { if (I->getInitVal() == AP) { if (!IsFirst) SS << " ? "; - SS << "(" + I->getQualifiedNameAsString() << ")"; + SS << "("; + I->printQualifiedName(SS); + SS << ")"; IsFirst = false; } } diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 0bdea354c2406..ed55c0efc72f1 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -3510,11 +3510,15 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, TagType == DeclSpec::TST_union || TagType == DeclSpec::TST_class) && "Invalid TagType!"); - llvm::TimeTraceScope TimeScope("ParseClass", [&]() { - if (auto *TD = dyn_cast_or_null<NamedDecl>(TagDecl)) - return TD->getQualifiedNameAsString(); - return std::string("<anonymous>"); - }); + SmallString<128> NameBuf; + if (auto *TD = dyn_cast_or_null<NamedDecl>(TagDecl)) { + llvm::raw_svector_ostream OS(NameBuf); + TD->printQualifiedName(OS); + } else { + NameBuf = "<anonymous>"; + } + + llvm::TimeTraceScope TimeScope("ParseClass", NameBuf); PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc, "parsing struct/union/class body"); @@ -3529,13 +3533,9 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, NonNestedClass = false; // The Microsoft extension __interface does not permit nested classes. - if (getCurrentClass().IsInterface) { + if (getCurrentClass().IsInterface) Diag(RecordLoc, diag::err_invalid_member_in_interface) - << /*ErrorType=*/6 - << (isa<NamedDecl>(TagDecl) - ? cast<NamedDecl>(TagDecl)->getQualifiedNameAsString() - : "(anonymous)"); - } + << /*ErrorType=*/6 << dyn_cast_or_null<NamedDecl>(TagDecl); break; } diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index d0500a6defd64..afa18ad632d7b 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -14,7 +14,6 @@ #include "clang/Sema/AnalysisBasedWarnings.h" #include "SemaLifetimeSafety.h" -#include "TypeLocBuilder.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" @@ -47,7 +46,6 @@ #include "clang/Basic/SourceManager.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/ScopeInfo.h" -#include "clang/Sema/SemaInternal.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" @@ -2595,14 +2593,11 @@ class UnsafeBufferUsageReporter : public UnsafeBufferUsageHandler { Loc = CtorExpr->getLocation(); Range = CtorExpr->getSourceRange(); - std::string ContainerName = "std::span"; - if (auto *TD = CtorExpr->getConstructor()->getParent()) { - // This will provide "std::span" if it's in the std namespace - ContainerName = TD->getQualifiedNameAsString(); - } - // FIX: Pass the container name to fill the %0 parameter - S.Diag(Loc, diag::warn_unsafe_buffer_usage_in_container) << ContainerName; + if (const auto *TD = CtorExpr->getConstructor()->getParent()) + S.Diag(Loc, diag::warn_unsafe_buffer_usage_in_container) << TD; + else + S.Diag(Loc, diag::warn_unsafe_buffer_usage_in_container) << "std::span"; if (IsRelatedToDecl) { assert(!SuggestSuggestions && diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index cc2af8feb3794..acf2ba04b2b06 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -1876,8 +1876,7 @@ static bool IsMicrosoftUsingDeclarationAccessBug(Sema& S, (OrigDecl->getAccess() == AS_public || OrigDecl->getAccess() == AS_protected)) { S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible) - << UD->getQualifiedNameAsString() - << OrigDecl->getQualifiedNameAsString(); + << UD << OrigDecl; return true; } } diff --git a/clang/lib/Sema/SemaBoundsSafety.cpp b/clang/lib/Sema/SemaBoundsSafety.cpp index 066dab2f0bef2..7dc80b8b35037 100644 --- a/clang/lib/Sema/SemaBoundsSafety.cpp +++ b/clang/lib/Sema/SemaBoundsSafety.cpp @@ -320,17 +320,17 @@ static bool CheckAssignmentToCountAttrPtrWithIncompletePointeeTy( if (!CATy) return true; - std::string AssigneeStr; + SmallString<64> AssigneeBuf; if (Assignee) { - if (ShowFullyQualifiedAssigneeName) { - AssigneeStr = Assignee->getQualifiedNameAsString(); - } else { - AssigneeStr = Assignee->getNameAsString(); - } + llvm::raw_svector_ostream OS(AssigneeBuf); + if (ShowFullyQualifiedAssigneeName) + Assignee->printQualifiedName(OS); + else + Assignee->printName(OS); } S.Diag(Loc, diag::err_counted_by_on_incomplete_type_on_assign) - << static_cast<int>(Action) << AssigneeStr << (AssigneeStr.size() > 0) + << static_cast<int>(Action) << AssigneeBuf << !AssigneeBuf.empty() << isa<ImplicitValueInitExpr>(RHSExpr) << LHSTy << CATy->getAttributeName(/*WithMacroPrefix=*/true) << PointeeTy << CATy->isOrNull() << RHSExpr->getSourceRange(); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 7f3ccea82e8af..30568c4da03ca 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -11578,8 +11578,14 @@ void CheckFreeArgumentsCast(Sema &S, const std::string &CalleeName, } // namespace void Sema::CheckFreeArguments(const CallExpr *E) { - const std::string CalleeName = - cast<FunctionDecl>(E->getCalleeDecl())->getQualifiedNameAsString(); + const auto *FD = cast<FunctionDecl>(E->getCalleeDecl()); + + SmallString<64> CalleeNameBuf; + { + llvm::raw_svector_ostream OS(CalleeNameBuf); + FD->printQualifiedName(OS); + } + std::string CalleeName = CalleeNameBuf.str().str(); { // Prefer something that doesn't involve a cast to make things simpler. const Expr *Arg = E->getArg(0)->IgnoreParenCasts(); @@ -11599,13 +11605,13 @@ void Sema::CheckFreeArguments(const CallExpr *E) { if (const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) { Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object) - << CalleeName << 0 /*object: */ << Label->getLabel()->getIdentifier(); + << FD << 0 /*object: */ << Label->getLabel()->getIdentifier(); return; } if (isa<BlockExpr>(Arg)) { Diag(Arg->getBeginLoc(), diag::warn_free_nonheap_object) - << CalleeName << 1 /*object: block*/; + << FD << 1 /*object: block*/; return; } } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2b524a956ecc4..0d5aed12544ee 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6760,8 +6760,7 @@ static void DiagnosedUnqualifiedCallsToStdFunctions(Sema &S, return; S.Diag(DRE->getLocation(), diag::warn_unqualified_call_to_std_cast_function) - << FD->getQualifiedNameAsString() - << FixItHint::CreateInsertion(DRE->getLocation(), "std::"); + << FD << FixItHint::CreateInsertion(DRE->getLocation(), "std::"); } ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 81bc6c68f377d..80b0ae6c08f0d 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -12,7 +12,6 @@ #include "CheckExprLifetime.h" #include "clang/AST/ASTContext.h" -#include "clang/AST/ASTDiagnostic.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" @@ -14681,9 +14680,15 @@ static bool DiagnoseTwoPhaseLookup( // Never suggest declaring a function within a namespace with a // reserved name, like __gnu_cxx. NamespaceDecl *NS = dyn_cast<NamespaceDecl>(*it); - if (NS && - NS->getQualifiedNameAsString().find("__") != std::string::npos) - continue; + if (NS) { + SmallString<64> QualName; + { + llvm::raw_svector_ostream OS(QualName); + NS->printQualifiedName(OS); + } + if (QualName.str().contains("__")) + continue; + } SuggestedNamespaces.insert(*it); } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 67289855685db..512052c0f3d96 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3379,11 +3379,15 @@ static bool isInVkNamespace(const RecordType *RT) { if (!DC) return false; - NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC); - if (!ND) + const auto *VkND = dyn_cast<NamespaceDecl>(DC); + if (!VkND || VkND->getName() != "vk") return false; - return ND->getQualifiedNameAsString() == "hlsl::vk"; + const auto *HlslND = dyn_cast<NamespaceDecl>(VkND->getDeclContext()); + if (!HlslND || HlslND->getName() != "hlsl") + return false; + + return HlslND->getDeclContext()->isTranslationUnit(); } static SpirvOperand checkHLSLSpirvTypeOperand(Sema &SemaRef, diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp index d3e4a3a634764..0ce9780cf3fa0 100644 --- a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -124,8 +124,12 @@ class AnalysisOrderChecker bool evalCall(const CallEvent &Call, CheckerContext &C) const { if (isCallbackEnabled(C, "EvalCall")) { llvm::errs() << "EvalCall"; - if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl())) - llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')'; + if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl())) { + llvm::errs() << " ("; + ND->printQualifiedName(llvm::errs()); + llvm::errs() << ')'; + } + llvm::errs() << " {argno: " << Call.getNumArgs() << '}'; llvm::errs() << " [" << Call.getKindAsString() << ']'; llvm::errs() << '\n'; @@ -138,8 +142,11 @@ class AnalysisOrderChecker void checkPreCall(const CallEvent &Call, CheckerContext &C) const { if (isCallbackEnabled(C, "PreCall")) { llvm::errs() << "PreCall"; - if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl())) - llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')'; + if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl())) { + llvm::errs() << " ("; + ND->printQualifiedName(llvm::errs()); + llvm::errs() << ')'; + } llvm::errs() << " [" << Call.getKindAsString() << ']'; llvm::errs() << '\n'; } @@ -148,8 +155,11 @@ class AnalysisOrderChecker void checkPostCall(const CallEvent &Call, CheckerContext &C) const { if (isCallbackEnabled(C, "PostCall")) { llvm::errs() << "PostCall"; - if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl())) - llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')'; + if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl())) { + llvm::errs() << " ("; + ND->printQualifiedName(llvm::errs()); + llvm::errs() << ')'; + } llvm::errs() << " [" << Call.getKindAsString() << ']'; llvm::errs() << '\n'; } diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 5ee5601a9319a..029c3df4fdc51 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -3857,18 +3857,21 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( return true; } - if (FName == "postEvent" && - FD->getQualifiedNameAsString() == "QCoreApplication::postEvent") { + auto IsInClass = [](const FunctionDecl *FD, StringRef ClassName) { + if (const auto *RD = dyn_cast<CXXRecordDecl>(FD->getDeclContext())) + return RD->getName() == ClassName; + return false; + }; + + if (FName == "postEvent" && IsInClass(FD, "QCoreApplication")) { return true; } - if (FName == "connectImpl" && - FD->getQualifiedNameAsString() == "QObject::connectImpl") { + if (FName == "connectImpl" && IsInClass(FD, "QObject")) { return true; } - if (FName == "singleShotImpl" && - FD->getQualifiedNameAsString() == "QTimer::singleShotImpl") { + if (FName == "singleShotImpl" && IsInClass(FD, "QTimer")) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp index 9c616a2d17783..e669b25e83a3b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp @@ -662,7 +662,7 @@ void MoveChecker::explainObject(ProgramStateRef State, llvm::raw_ostream &OS, MisuseKind MK) const { // We may need a leading space every time we actually explain anything, // and we never know if we are to explain anything until we try. - if (const auto DR = + if (const auto *DR = dyn_cast_or_null<DeclRegion>(unwrapRValueReferenceIndirection(MR))) { const auto *RegionDecl = cast<NamedDecl>(DR->getDecl()); OS << " '" << RegionDecl->getDeclName() << "'"; @@ -670,18 +670,20 @@ void MoveChecker::explainObject(ProgramStateRef State, llvm::raw_ostream &OS, ObjectKind OK = classifyObject(State, MR, RD); switch (OK.StdKind) { - case SK_NonStd: - case SK_Safe: + case SK_NonStd: + case SK_Safe: + break; + case SK_SmartPtr: + if (MK != MK_Dereference) break; - case SK_SmartPtr: - if (MK != MK_Dereference) - break; - // We only care about the type if it's a dereference. - [[fallthrough]]; - case SK_Unsafe: - OS << " of type '" << RD->getQualifiedNameAsString() << "'"; - break; + // We only care about the type if it's a dereference. + [[fallthrough]]; + case SK_Unsafe: + OS << " of type '"; + RD->printQualifiedName(OS); + OS << "'"; + break; }; } diff --git a/clang/lib/StaticAnalyzer/Checkers/NoOwnershipChangeVisitor.cpp b/clang/lib/StaticAnalyzer/Checkers/NoOwnershipChangeVisitor.cpp index 3583e7b2aa6f8..756f6cf4157f2 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NoOwnershipChangeVisitor.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NoOwnershipChangeVisitor.cpp @@ -63,8 +63,12 @@ LLVM_DUMP_METHOD std::string NoOwnershipChangeVisitor::getFunctionName(const ExplodedNode *CallEnterN) { if (const CallExpr *CE = llvm::dyn_cast_or_null<CallExpr>( CallEnterN->getLocationAs<CallEnter>()->getCallExpr())) - if (const FunctionDecl *FD = CE->getDirectCallee()) - return FD->getQualifiedNameAsString(); + if (const FunctionDecl *FD = CE->getDirectCallee()) { + SmallString<128> Name; + llvm::raw_svector_ostream OS(Name); + FD->printQualifiedName(OS); + return std::string(Name.str()); + } return ""; } diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp index 59d11c4d8ae2c..4b0c6b60f84ed 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp @@ -173,9 +173,13 @@ static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt, FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl()); if (const auto *MD = dyn_cast<CXXMethodDecl>(CE->getCalleeDecl())) { - os << "Call to method '" << MD->getQualifiedNameAsString() << '\''; + os << "Call to method '"; + MD->printQualifiedName(os); + os << '\''; } else if (FD) { - os << "Call to function '" << FD->getQualifiedNameAsString() << '\''; + os << "Call to function '"; + FD->printQualifiedName(os); + os << '\''; } else { os << "function call"; } diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp index 36a71d510b902..7d65ff51f3f7c 100644 --- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -211,18 +211,20 @@ const ParmVarDecl *ParamVarRegion::getDecl() const { if (const auto *FD = dyn_cast<FunctionDecl>(D)) { assert(Index < FD->param_size()); return FD->parameters()[Index]; - } else if (const auto *BD = dyn_cast<BlockDecl>(D)) { + } + if (const auto *BD = dyn_cast<BlockDecl>(D)) { assert(Index < BD->param_size()); return BD->parameters()[Index]; - } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) { + } + if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) { assert(Index < MD->param_size()); return MD->parameters()[Index]; - } else if (const auto *CD = dyn_cast<CXXConstructorDecl>(D)) { + } + if (const auto *CD = dyn_cast<CXXConstructorDecl>(D)) { assert(Index < CD->param_size()); return CD->parameters()[Index]; - } else { - llvm_unreachable("Unexpected Decl kind!"); } + llvm_unreachable("Unexpected Decl kind!"); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Core/SVals.cpp b/clang/lib/StaticAnalyzer/Core/SVals.cpp index 483e62d4a9a7e..6f92683501e3f 100644 --- a/clang/lib/StaticAnalyzer/Core/SVals.cpp +++ b/clang/lib/StaticAnalyzer/Core/SVals.cpp @@ -355,7 +355,7 @@ void NonLoc::dumpToStream(raw_ostream &os) const { const nonloc::PointerToMember &CastRes = castAs<nonloc::PointerToMember>(); if (CastRes.getDecl()) - os << "|" << CastRes.getDecl()->getQualifiedNameAsString() << "|"; + os << "|" << CastRes.getDecl() << "|"; bool first = true; for (const auto &I : CastRes) { if (first) { diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index ce44fcd240ffa..2c71769f4b646 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -373,9 +373,16 @@ class AnalysisConsumer : public AnalysisASTConsumer, std::string timeTraceScopeDeclName(StringRef FunName, const Decl *D) { if (llvm::timeTraceProfilerEnabled()) { - if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) - return (FunName + " " + ND->getQualifiedNameAsString()).str(); - return (FunName + " <anonymous> ").str(); + SmallString<128> NameBuf; + llvm::raw_svector_ostream OS(NameBuf); + + OS << FunName << " "; + if (const auto *ND = dyn_cast_or_null<NamedDecl>(D)) + ND->printQualifiedName(OS); + else + OS << "<anonymous>"; + + return std::string(NameBuf.str()); } return ""; } diff --git a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp index 7ca789bba9c02..5466cc55c260f 100644 --- a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp +++ b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp @@ -358,23 +358,36 @@ int SyntaxTree::Impl::findPositionInParent(NodeId Id, bool Shifted) const { std::string SyntaxTree::Impl::getRelativeName(const NamedDecl *ND, const DeclContext *Context) const { - std::string Val = ND->getQualifiedNameAsString(); - std::string ContextPrefix; - if (!Context) - return Val; - if (auto *Namespace = dyn_cast<NamespaceDecl>(Context)) - ContextPrefix = Namespace->getQualifiedNameAsString(); - else if (auto *Record = dyn_cast<RecordDecl>(Context)) - ContextPrefix = Record->getQualifiedNameAsString(); - else if (AST.getLangOpts().CPlusPlus11) - if (auto *Tag = dyn_cast<TagDecl>(Context)) - ContextPrefix = Tag->getQualifiedNameAsString(); - // Strip the qualifier, if Val refers to something in the current scope. - // But leave one leading ':' in place, so that we know that this is a - // relative path. - if (!ContextPrefix.empty() && StringRef(Val).starts_with(ContextPrefix)) - Val = Val.substr(ContextPrefix.size() + 1); - return Val; + SmallString<128> ValBuf; + { + llvm::raw_svector_ostream OS(ValBuf); + ND->printQualifiedName(OS); + } + + if (Context) { + if (const auto *ContextND = dyn_cast<NamedDecl>(Context)) { + if (isa<NamespaceDecl>(Context) || isa<RecordDecl>(Context) || + (AST.getLangOpts().CPlusPlus11 && isa<TagDecl>(Context))) { + + SmallString<128> ContextPrefixBuf; + { + llvm::raw_svector_ostream OS(ContextPrefixBuf); + ContextND->printQualifiedName(OS); + } + + StringRef Val = ValBuf.str(); + StringRef ContextPrefix = ContextPrefixBuf.str(); + + // Strip the qualifier, if Val refers to something in the current scope. + // But leave one leading ':' in place, so that we know that this is a + // relative path. + if (!ContextPrefix.empty() && Val.starts_with(ContextPrefix)) + return std::string(Val.substr(ContextPrefix.size() + 1)); + } + } + } + + return std::string(ValBuf.str()); } std::string SyntaxTree::Impl::getRelativeName(const NamedDecl *ND) const { @@ -691,8 +704,12 @@ StringRef Node::getTypeLabel() const { return getType().asStringRef(); } std::optional<std::string> Node::getQualifiedIdentifier() const { if (auto *ND = ASTNode.get<NamedDecl>()) { - if (ND->getDeclName().isIdentifier()) - return ND->getQualifiedNameAsString(); + if (ND->getDeclName().isIdentifier()) { + SmallString<128> Buf; + llvm::raw_svector_ostream OS(Buf); + ND->printQualifiedName(OS); + return std::string(Buf.str()); + } } return std::nullopt; } diff --git a/clang/lib/Tooling/Refactoring/Lookup.cpp b/clang/lib/Tooling/Refactoring/Lookup.cpp index dedde860516ab..2a6ffc2271518 100644 --- a/clang/lib/Tooling/Refactoring/Lookup.cpp +++ b/clang/lib/Tooling/Refactoring/Lookup.cpp @@ -62,11 +62,11 @@ usingFromDifferentCanonicalNamespace(const DeclContext *FromContext, if (UseNamespaces.size() < FromNamespaces.size()) return false; unsigned Diff = UseNamespaces.size() - FromNamespaces.size(); - auto FromIter = FromNamespaces.begin(); + auto *FromIter = FromNamespaces.begin(); // Only compare `FromNamespaces` with namespaces in `UseNamespaces` that can // collide, i.e. the top N namespaces where N is the number of namespaces in // `FromNamespaces`. - auto UseIter = UseNamespaces.begin() + Diff; + auto *UseIter = UseNamespaces.begin() + Diff; for (; FromIter != FromNamespaces.end() && UseIter != UseNamespaces.end(); ++FromIter, ++UseIter) { // Literally the same namespace, not a collision. @@ -96,8 +96,13 @@ static StringRef getBestNamespaceSubstr(const DeclContext *DeclA, // Otherwise strip off redundant namespace qualifications from the new name. // We use the fully qualified name of the namespace and remove that part // from NewName if it has an identical prefix. - std::string NS = - "::" + cast<NamespaceDecl>(DeclA)->getQualifiedNameAsString() + "::"; + SmallString<128> NS; + { + llvm::raw_svector_ostream OS(NS); + OS << "::"; + cast<NamespaceDecl>(DeclA)->printQualifiedName(OS); + OS << "::"; + } if (NewName.consume_front(NS)) return NewName; @@ -145,15 +150,21 @@ static std::string disambiguateSpellingInScope(StringRef Spelling, for (const auto *NS : EnclosingNamespaces) { auto LookupRes = NS->lookup(DeclarationName(&AST.Idents.get(Head))); if (!LookupRes.empty()) { - for (const NamedDecl *Res : LookupRes) + for (const NamedDecl *Res : LookupRes) { // If `Res` is not visible in `UseLoc`, we don't consider it // ambiguous. For example, a reference in a header file should not be // affected by a potentially ambiguous name in some file that includes // the header. - if (!TrimmedQName.starts_with(Res->getQualifiedNameAsString()) && + SmallString<128> ResQName; + { + llvm::raw_svector_ostream OS(ResQName); + Res->printQualifiedName(OS); + } + if (!TrimmedQName.starts_with(ResQName.str()) && SM.isBeforeInTranslationUnit( SM.getSpellingLoc(Res->getLocation()), UseLoc)) return true; + } } } return false; diff --git a/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp b/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp index 66902614488a7..1f52a624aac6d 100644 --- a/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp +++ b/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp @@ -106,10 +106,21 @@ class NamedDeclFindingVisitor bool VisitNamedDecl(const NamedDecl *ND) { if (!ND) return true; - // Fully qualified name is used to find the declaration. - if (Name != ND->getQualifiedNameAsString() && - Name != "::" + ND->getQualifiedNameAsString()) + + SmallString<128> QNameBuf; + { + llvm::raw_svector_ostream OS(QNameBuf); + ND->printQualifiedName(OS); + } + + StringRef QName = QNameBuf.str(); + StringRef TargetName = Name; + + TargetName.consume_front("::"); + + if (TargetName != QName) return true; + Result = ND; return false; } diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp b/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp index 9381a29f56f43..70902f3cdc797 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp @@ -12,6 +12,7 @@ #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "clang/Sema/Lookup.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/Error.h" #include <optional> @@ -100,8 +101,8 @@ struct MissingDeclContext : public llvm::ErrorInfo<MissingDeclContext> { static char ID; - MissingDeclContext(DeclContext *context, std::string error) - : m_context(context), m_error(error) {} + MissingDeclContext(DeclContext *context, llvm::Twine error) + : m_context(context), m_error(error.str()) {} DeclContext *m_context; std::string m_error; @@ -148,9 +149,14 @@ getEqualLocalDeclContext(Sema &sema, DeclContext *foreign_ctxt) { if (DeclContext *DC = llvm::dyn_cast<DeclContext>(named_decl)) return DC->getPrimaryContext(); } + SmallString<128> Msg; + { + llvm::raw_svector_ostream OS(Msg); + OS << "Couldn't find namespace "; + ns->printQualifiedName(OS); + } return llvm::make_error<MissingDeclContext>( - foreign_ctxt, - "Couldn't find namespace " + ns->getQualifiedNameAsString()); + foreign_ctxt, "Couldn't find namespace " + Msg.str()); } return llvm::make_error<MissingDeclContext>(foreign_ctxt, "Unknown context "); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index b60f1d9e41958..92cb4c6faa6fd 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2950,9 +2950,14 @@ void DWARFASTParserClang::CreateStaticMemberVariable( llvm::Expected<llvm::APInt> const_value_or_err = ExtractIntFromFormValue(ct, *attrs.const_value_form); if (!const_value_or_err) { + clang::SmallString<128> QName; + { + llvm::raw_svector_ostream OS(QName); + v->printQualifiedName(OS); + } LLDB_LOG_ERROR(log, const_value_or_err.takeError(), "Failed to add const value to variable {1}: {0}", - v->getQualifiedNameAsString()); + QName.str()); return; } diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp index 6d4af9ec6bf95..02b179ab08c35 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp @@ -1219,11 +1219,13 @@ PdbAstBuilderClang::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { clang::DeclContext *parent = GetParentClangDeclContext(PdbSymUid(func_id)); if (!parent) return nullptr; - std::string context_name; - if (clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(parent)) { - context_name = ns->getQualifiedNameAsString(); - } else if (clang::TagDecl *tag = llvm::dyn_cast<clang::TagDecl>(parent)) { - context_name = tag->getQualifiedNameAsString(); + clang::SmallString<128> context_name_buf; + if (const auto *parent_nd = llvm::dyn_cast<clang::NamedDecl>(parent)) { + if (llvm::isa<clang::NamespaceDecl>(parent) || + llvm::isa<clang::TagDecl>(parent)) { + llvm::raw_svector_ostream OS(context_name_buf); + parent_nd->printQualifiedName(OS); + } } SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( @@ -1255,8 +1257,9 @@ PdbAstBuilderClang::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { CompilerType func_ct = ToCompilerType(qt); llvm::StringRef proc_name = proc.Name; - if (!context_name.empty() && !(proc_name.consume_front(context_name) && - proc_name.consume_front("::"))) { + if (!context_name_buf.empty() && + !(proc_name.consume_front(context_name_buf) && + proc_name.consume_front("::"))) { // If we have some context, but the function name doesn't start with it, use // the basename. MSVCUndecoratedNameParser parser(proc.Name); @@ -1516,7 +1519,12 @@ void PdbAstBuilderClang::ParseNamespace(clang::DeclContext &context) { clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(&context); if (m_parsed_namespaces.contains(ns)) return; - std::string qname = ns->getQualifiedNameAsString(); + clang::SmallString<128> qname_buf; + { + llvm::raw_svector_ostream OS(qname_buf); + ns->printQualifiedName(OS); + } + llvm::StringRef qname = qname_buf.str(); SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( m_clang.GetSymbolFile()->GetBackingSymbolFile()); PdbIndex &index = pdb->GetIndex(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
