diff --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp --- a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp @@ -45,7 +45,7 @@ namespace { struct MissingIncludeInfo { - SourceLocation SymRefLocation; + include_cleaner::SymbolReference SymRef; include_cleaner::Header Missing; }; } // namespace @@ -134,7 +134,7 @@ if (!Satisfied && !Providers.empty() && Ref.RT == include_cleaner::RefType::Explicit && !shouldIgnore(Providers.front())) - Missing.push_back({Ref.RefLocation, Providers.front()}); + Missing.push_back({Ref, Providers.front()}); }); std::vector Unused; @@ -190,9 +190,9 @@ if (auto Replacement = HeaderIncludes.insert(llvm::StringRef{Spelling}.trim("\"<>"), Angled, tooling::IncludeDirective::Include)) - diag(SM->getSpellingLoc(Inc.SymRefLocation), - "no header providing %0 is directly included") - << Spelling + diag(SM->getSpellingLoc(Inc.SymRef.RefLocation), + "no header providing \"%0\" is directly included") + << Inc.SymRef.Target.name() << FixItHint::CreateInsertion( SM->getComposedLoc(SM->getMainFileID(), Replacement->getOffset()), diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -144,17 +144,6 @@ llvm_unreachable("Unknown header kind"); } -std::string getSymbolName(const include_cleaner::Symbol &Sym) { - switch (Sym.kind()) { - case include_cleaner::Symbol::Macro: - return Sym.macro().Name->getName().str(); - case include_cleaner::Symbol::Declaration: - return llvm::dyn_cast(&Sym.declaration()) - ->getQualifiedNameAsString(); - } - llvm_unreachable("Unknown symbol kind"); -} - std::vector generateMissingIncludeDiagnostics( ParsedAST &AST, llvm::ArrayRef MissingIncludes, llvm::StringRef Code, HeaderFilter IgnoreHeaders) { @@ -199,7 +188,7 @@ Diag &D = Result.emplace_back(); D.Message = llvm::formatv("No header providing \"{0}\" is directly included", - getSymbolName(SymbolWithMissingInclude.Symbol)); + SymbolWithMissingInclude.Symbol.name()); D.Name = "missing-includes"; D.Source = Diag::DiagSource::Clangd; D.File = AST.tuPath(); diff --git a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h --- a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h +++ b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h @@ -67,6 +67,7 @@ const Decl &declaration() const { return *std::get(Storage); } struct Macro macro() const { return std::get(Storage); } + std::string name() const; private: // Order must match Kind enum! diff --git a/clang-tools-extra/include-cleaner/lib/Types.cpp b/clang-tools-extra/include-cleaner/lib/Types.cpp --- a/clang-tools-extra/include-cleaner/lib/Types.cpp +++ b/clang-tools-extra/include-cleaner/lib/Types.cpp @@ -15,6 +15,17 @@ namespace clang::include_cleaner { +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(&declaration()) + ->getQualifiedNameAsString(); + } + llvm_unreachable("Unknown symbol kind"); +} + llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) { switch (S.kind()) { case Symbol::Declaration: diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/include-cleaner.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/include-cleaner.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/misc/include-cleaner.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/include-cleaner.cpp @@ -10,8 +10,8 @@ // CHECK-FIXES: {{^}} int BarResult = bar(); int BazResult = baz(); -// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: no header providing "baz.h" is directly included [misc-include-cleaner] +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: no header providing "baz" is directly included [misc-include-cleaner] std::string HelloString; -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: no header providing is directly included [misc-include-cleaner] +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: no header providing "std::string" is directly included [misc-include-cleaner] int FooBarResult = foobar(); -// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: no header providing "public.h" is directly included [misc-include-cleaner] +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: no header providing "foobar" is directly included [misc-include-cleaner]