[clang-tools-extra] 13e5faf - [clangd] Fix buildbot breakages from stemming from 64366d4935d3c56ce5906a321edb2e91d4f886bc

2023-09-11 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-09-11T08:30:06Z
New Revision: 13e5fafb5548caf52fc067ec443604d20bf60684

URL: 
https://github.com/llvm/llvm-project/commit/13e5fafb5548caf52fc067ec443604d20bf60684
DIFF: 
https://github.com/llvm/llvm-project/commit/13e5fafb5548caf52fc067ec443604d20bf60684.diff

LOG: [clangd] Fix buildbot breakages from stemming from 
64366d4935d3c56ce5906a321edb2e91d4f886bc

Added: 


Modified: 
clang-tools-extra/clangd/index/SymbolCollector.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp 
b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index 699370fe1adf3af..8fe1146bc2752c3 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -943,7 +943,7 @@ void SymbolCollector::finish() {
 // FIXME: Get rid of this once include-cleaner has support for system
 // headers.
 if (auto Canonical =
-HeaderFileURIs->mapCanonical(H.physical()->getName());
+HeaderFileURIs->mapCanonical(H.physical().getName());
 !Canonical.empty())
   SpellingIt->second = Canonical;
 // For physical files, prefer URIs as spellings might change
@@ -951,7 +951,7 @@ void SymbolCollector::finish() {
 else if (tooling::isSelfContainedHeader(H.physical(), SM,
 PP->getHeaderSearchInfo()))
   SpellingIt->second =
-  HeaderFileURIs->toURI(H.physical()->getLastRef());
+  HeaderFileURIs->toURI(H.physical());
   } else {
 SpellingIt->second = include_cleaner::spellHeader(
 {H, PP->getHeaderSearchInfo(),



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 64366d4 - [clangd] Rollforward include-cleaner library usage in symbol collector.

2023-09-11 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-09-11T07:57:35Z
New Revision: 64366d4935d3c56ce5906a321edb2e91d4f886bc

URL: 
https://github.com/llvm/llvm-project/commit/64366d4935d3c56ce5906a321edb2e91d4f886bc
DIFF: 
https://github.com/llvm/llvm-project/commit/64366d4935d3c56ce5906a321edb2e91d4f886bc.diff

LOG: [clangd] Rollforward include-cleaner library usage in symbol collector.

Differential Revision: https://reviews.llvm.org/D156659

Added: 


Modified: 
clang-tools-extra/clangd/index/SymbolCollector.cpp
clang-tools-extra/clangd/index/SymbolCollector.h
clang-tools-extra/clangd/unittests/FileIndexTests.cpp
clang-tools-extra/clangd/unittests/IndexActionTests.cpp
clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp 
b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index e843413601f5a29..699370fe1adf3af 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -821,25 +821,45 @@ void SymbolCollector::setIncludeLocation(const Symbol , 
SourceLocation DefLoc,
   // Use the expansion location to get the #include header since this is
   // where the symbol is exposed.
   IncludeFiles[S.ID] = SM.getDecomposedExpansionLoc(DefLoc).first;
+
+  // We update providers for a symbol with each occurence, as SymbolCollector
+  // might run while parsing, rather than at the end of a translation unit.
+  // Hence we see more and more redecls over time.
+  auto [It, Inserted] = SymbolProviders.try_emplace(S.ID);
+  auto Headers =
+  include_cleaner::headersForSymbol(Sym, SM, Opts.PragmaIncludes);
+  if (Headers.empty())
+return;
+
+  auto *HeadersIter = Headers.begin();
+  include_cleaner::Header H = *HeadersIter;
+  while (HeadersIter != Headers.end() &&
+ H.kind() == include_cleaner::Header::Physical &&
+ !tooling::isSelfContainedHeader(H.physical(), SM,
+ PP->getHeaderSearchInfo())) {
+H = *HeadersIter;
+HeadersIter++;
+  }
+  It->second = H;
 }
 
 llvm::StringRef getStdHeader(const Symbol *S, const LangOptions ) {
   tooling::stdlib::Lang Lang = tooling::stdlib::Lang::CXX;
-if (LangOpts.C11)
-  Lang = tooling::stdlib::Lang::C;
-else if(!LangOpts.CPlusPlus)
-  return "";
-
-if (S->Scope == "std::" && S->Name == "move") {
-  if (!S->Signature.contains(','))
-return "";
-  return "";
-}
-   
-if (auto StdSym = tooling::stdlib::Symbol::named(S->Scope, S->Name, Lang))
- if (auto Header = StdSym->header())
-   return Header->name();
+  if (LangOpts.C11)
+Lang = tooling::stdlib::Lang::C;
+  else if(!LangOpts.CPlusPlus)
 return "";
+
+  if (S->Scope == "std::" && S->Name == "move") {
+if (!S->Signature.contains(','))
+  return "";
+return "";
+  }
+
+  if (auto StdSym = tooling::stdlib::Symbol::named(S->Scope, S->Name, Lang))
+if (auto Header = StdSym->header())
+  return Header->name();
+  return "";
 }
 
 void SymbolCollector::finish() {
@@ -865,13 +885,16 @@ void SymbolCollector::finish() {
 }
   }
   llvm::DenseMap FileToContainsImportsOrObjC;
+  llvm::DenseMap HeaderSpelling;
   // Fill in IncludeHeaders.
   // We delay this until end of TU so header guards are all resolved.
-  for (const auto &[SID, FID] : IncludeFiles) {
+  for (const auto &[SID, OptionalProvider] : SymbolProviders) {
 const Symbol *S = Symbols.find(SID);
 if (!S)
   continue;
+assert(IncludeFiles.find(SID) != IncludeFiles.end());
 
+const auto FID = IncludeFiles.at(SID);
 // Determine if the FID is #include'd or #import'ed.
 Symbol::IncludeDirective Directives = Symbol::Invalid;
 auto CollectDirectives = shouldCollectIncludePath(S->SymInfo.Kind);
@@ -891,20 +914,61 @@ void SymbolCollector::finish() {
 if (Directives == Symbol::Invalid)
   continue;
 
-// FIXME: Use the include-cleaner library instead.
-llvm::StringRef IncludeHeader = getStdHeader(S, ASTCtx->getLangOpts());
-if (IncludeHeader.empty())
-  IncludeHeader = HeaderFileURIs->getIncludeHeader(FID);
+// Use the include location-based logic for Objective-C symbols.
+if (Directives & Symbol::Import) {
+  llvm::StringRef IncludeHeader = getStdHeader(S, ASTCtx->getLangOpts());
+  if (IncludeHeader.empty())
+IncludeHeader = HeaderFileURIs->getIncludeHeader(FID);
+
+  if (!IncludeHeader.empty()) {
+auto NewSym = *S;
+NewSym.IncludeHeaders.push_back({IncludeHeader, 1, Directives});
+Symbols.insert(NewSym);
+  }
+  // FIXME: use providers from include-cleaner library once it's polished
+  // for Objective-C.
+  continue;
+}
+
+assert(Directives == Symbol::Include);
+// For #include's, use the providers computed by the include-cleaner
+// library.
+if 

[clang-tools-extra] 43c2036 - [include-cleaner][clangd][clang-tidy] Ignore resource dir during include-cleaner analysis.

2023-09-07 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-09-07T11:39:18Z
New Revision: 43c20367f417410a736959d4ae53f374e0d5b500

URL: 
https://github.com/llvm/llvm-project/commit/43c20367f417410a736959d4ae53f374e0d5b500
DIFF: 
https://github.com/llvm/llvm-project/commit/43c20367f417410a736959d4ae53f374e0d5b500.diff

LOG: [include-cleaner][clangd][clang-tidy] Ignore resource dir during 
include-cleaner analysis.

Differential Revision: https://reviews.llvm.org/D157610

Added: 


Modified: 
clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
clang-tools-extra/include-cleaner/lib/Analysis.cpp
clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp 
b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
index 8d5f400acfef8bc..8e460cb38826eb1 100644
--- a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
@@ -26,6 +26,7 @@
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Format/Format.h"
+#include "clang/Lex/HeaderSearchOptions.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Tooling/Core/Replacement.h"
 #include "clang/Tooling/Inclusions/HeaderIncludes.h"
@@ -119,6 +120,8 @@ void IncludeCleanerCheck::check(const 
MatchFinder::MatchResult ) {
 MainFileDecls.push_back(D);
   }
   llvm::DenseSet SeenSymbols;
+  const DirectoryEntry *ResourceDir =
+  PP->getHeaderSearchInfo().getModuleMap().getBuiltinDir();
   // FIXME: Find a way to have less code duplication between include-cleaner
   // analysis implementation and the below code.
   walkUsed(MainFileDecls, RecordedPreprocessor.MacroReferences, ,
@@ -141,8 +144,11 @@ void IncludeCleanerCheck::check(const 
MatchFinder::MatchResult ) {
  bool Satisfied = false;
  for (const include_cleaner::Header  : Providers) {
if (H.kind() == include_cleaner::Header::Physical &&
-   H.physical() == MainFile)
+   (H.physical() == MainFile ||
+H.physical()->getDir() == ResourceDir)) {
  Satisfied = true;
+ continue;
+   }
 
for (const include_cleaner::Include *I :
 RecordedPreprocessor.Includes.match(H)) {
@@ -159,7 +165,7 @@ void IncludeCleanerCheck::check(const 
MatchFinder::MatchResult ) {
   std::vector Unused;
   for (const include_cleaner::Include  :
RecordedPreprocessor.Includes.all()) {
-if (Used.contains() || !I.Resolved)
+if (Used.contains() || !I.Resolved || I.Resolved->getDir() == 
ResourceDir)
   continue;
 if (RecordedPI.shouldKeep(*I.Resolved))
   continue;

diff  --git a/clang-tools-extra/clangd/IncludeCleaner.cpp 
b/clang-tools-extra/clangd/IncludeCleaner.cpp
index 1fcb5c7228fb639..a6e01eb72821d22 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.cpp
+++ b/clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -75,6 +75,11 @@ bool mayConsiderUnused(const Inclusion , ParsedAST ,
   auto FE = AST.getSourceManager().getFileManager().getFileRef(
   AST.getIncludeStructure().getRealPath(HID));
   assert(FE);
+  if (FE->getDir() == AST.getPreprocessor()
+  .getHeaderSearchInfo()
+  .getModuleMap()
+  .getBuiltinDir()) 
+return false;
   if (PI && PI->shouldKeep(*FE))
 return false;
   // FIXME(kirillbobyrev): We currently do not support the umbrella headers.
@@ -392,6 +397,10 @@ IncludeCleanerFindings 
computeIncludeCleanerFindings(ParsedAST ) {
   std::vector MissingIncludes;
   llvm::DenseSet Used;
   trace::Span Tracer("include_cleaner::walkUsed");
+  const DirectoryEntry *ResourceDir = AST.getPreprocessor()
+.getHeaderSearchInfo()
+.getModuleMap()
+.getBuiltinDir();
   include_cleaner::walkUsed(
   AST.getLocalTopLevelDecls(), /*MacroRefs=*/Macros,
   AST.getPragmaIncludes().get(), AST.getPreprocessor(),
@@ -400,7 +409,8 @@ IncludeCleanerFindings 
computeIncludeCleanerFindings(ParsedAST ) {
 bool Satisfied = false;
 for (const auto  : Providers) {
   if (H.kind() == include_cleaner::Header::Physical &&
-  (H.physical() == MainFile || H.physical() == PreamblePatch)) {
+  (H.physical() == MainFile || H.physical() == PreamblePatch ||
+   H.physical()->getLastRef().getDir() == ResourceDir)) {
 Satisfied = true;
 continue;
   }

diff  --git a/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test 

[clang] 6258912 - [clangd][clang-tidy] Add missing symbols to the symbol map.

2023-09-06 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-09-06T13:42:12Z
New Revision: 6258912880876edd44944e130aef01b33480168b

URL: 
https://github.com/llvm/llvm-project/commit/6258912880876edd44944e130aef01b33480168b
DIFF: 
https://github.com/llvm/llvm-project/commit/6258912880876edd44944e130aef01b33480168b.diff

LOG: [clangd][clang-tidy] Add missing symbols to the symbol map.

Differential Revision: https://reviews.llvm.org/D159462

Added: 


Modified: 
clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc

Removed: 




diff  --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc 
b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc
index 77578baef80a1ce..165c1fc2eebc2c3 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc
@@ -364,6 +364,8 @@ SYMBOL(make_integer_sequence, std::, )
 // Remove when the generator starts producing them.
 SYMBOL(make_any, std::, )
 SYMBOL(any_cast, std::, )
+SYMBOL(div, std::, )
+SYMBOL(abort, std::, )
 
 // The std::placeholder symbols (_1, ..., _N) are listed in the cppreference
 // placeholder.html, but the index only contains a single entry with "_1, _2, 
..., _N"



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] d71adeb - [include-cleaner] Map the 4-argument move overload to the algorithm header.

2023-09-06 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-09-06T11:38:56Z
New Revision: d71adebb9fb875a5fd23acdbe0cf0799092fa4ca

URL: 
https://github.com/llvm/llvm-project/commit/d71adebb9fb875a5fd23acdbe0cf0799092fa4ca
DIFF: 
https://github.com/llvm/llvm-project/commit/d71adebb9fb875a5fd23acdbe0cf0799092fa4ca.diff

LOG: [include-cleaner] Map the 4-argument move overload to the algorithm header.

Differential Revision: https://reviews.llvm.org/D159463

Added: 


Modified: 
clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp

Removed: 




diff  --git a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp 
b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
index f9438a2c8c49e48..f46dae3b3d50cbb 100644
--- a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
+++ b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
@@ -125,8 +125,10 @@ headerForAmbiguousStdSymbol(const NamedDecl *ND) {
 if (FD->getNumParams() == 1)
   // move(T&& t)
   return tooling::stdlib::Header::named("");
-if (FD->getNumParams() == 3)
+if (FD->getNumParams() == 3 || FD->getNumParams() == 4)
   // move(InputIt first, InputIt last, OutputIt dest);
+  // move(ExecutionPolicy&& policy, ForwardIt1 first,
+  // ForwardIt1 last, ForwardIt2 d_first);
   return tooling::stdlib::Header::named("");
   } else if (FName == "remove") {
 if (FD->getNumParams() == 1)

diff  --git a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
index be97eb13a704eef..b8f30c25e5c11b2 100644
--- a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -546,6 +546,16 @@ TEST_F(HeadersForSymbolTest, AmbiguousStdSymbols) {
   "move",
   "",
   },
+  {
+  R"cpp(
+namespace std {
+ template
+ ForwardIt2 move(ExecutionPolicy&& policy,
+ ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first);
+})cpp",
+  "move",
+  "",
+  },
   {
   R"cpp(
 namespace std {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] c3ad4b7 - [include-cleaner] Follow `IWYU pragma: export` links transitively.

2023-08-09 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-08-09T12:10:13Z
New Revision: c3ad4b7636022db387e33ab03247a93aa63d7488

URL: 
https://github.com/llvm/llvm-project/commit/c3ad4b7636022db387e33ab03247a93aa63d7488
DIFF: 
https://github.com/llvm/llvm-project/commit/c3ad4b7636022db387e33ab03247a93aa63d7488.diff

LOG: [include-cleaner] Follow `IWYU pragma: export` links transitively.

Differential Revision: https://reviews.llvm.org/D157395

Added: 


Modified: 
clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
clang-tools-extra/include-cleaner/lib/Record.cpp
clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp

Removed: 




diff  --git a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp 
b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
index a1d9d3b5fb2154..f9438a2c8c49e4 100644
--- a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
+++ b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
@@ -25,6 +25,8 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ErrorHandling.h"
 #include 
+#include 
+#include 
 #include 
 
 namespace clang::include_cleaner {
@@ -188,13 +190,13 @@ llvm::SmallVector> findHeaders(const 
SymbolLocation ,
 if (!PI)
   return {{FE, Hints::PublicHeader | Hints::OriginHeader}};
 bool IsOrigin = true;
+std::queue Exporters;
 while (FE) {
   Results.emplace_back(FE,
isPublicHeader(FE, *PI) |
(IsOrigin ? Hints::OriginHeader : Hints::None));
-  // FIXME: compute transitive exporter headers.
   for (const auto *Export : PI->getExporters(FE, SM.getFileManager()))
-Results.emplace_back(Export, isPublicHeader(Export, *PI));
+Exporters.push(Export);
 
   if (auto Verbatim = PI->getPublic(FE); !Verbatim.empty()) {
 Results.emplace_back(Verbatim,
@@ -209,6 +211,20 @@ llvm::SmallVector> findHeaders(const 
SymbolLocation ,
   FE = SM.getFileEntryForID(FID);
   IsOrigin = false;
 }
+// Now traverse provider trees rooted at exporters.
+// Note that we only traverse export edges, and ignore private -> public
+// mappings, as those pragmas apply to exporter, and not the main provider
+// being exported in this header.
+std::set SeenExports;
+while (!Exporters.empty()) {
+  auto *Export = Exporters.front();
+  Exporters.pop();
+  if (!SeenExports.insert(Export).second) // In case of cyclic exports
+continue;
+  Results.emplace_back(Export, isPublicHeader(Export, *PI));
+  for (const auto *Export : PI->getExporters(Export, SM.getFileManager()))
+Exporters.push(Export);
+}
 return Results;
   }
   case SymbolLocation::Standard: {

diff  --git a/clang-tools-extra/include-cleaner/lib/Record.cpp 
b/clang-tools-extra/include-cleaner/lib/Record.cpp
index 62eaa16dbf3373..d7237325f701bb 100644
--- a/clang-tools-extra/include-cleaner/lib/Record.cpp
+++ b/clang-tools-extra/include-cleaner/lib/Record.cpp
@@ -12,6 +12,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclGroup.h"
 #include "clang/Basic/FileEntry.h"
+#include "clang/Basic/FileManager.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
@@ -24,16 +25,21 @@
 #include "clang/Tooling/Inclusions/HeaderAnalysis.h"
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem/UniqueID.h"
 #include "llvm/Support/StringSaver.h"
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 

diff  --git a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
index cbe1f67d9bf7e5..be97eb13a704ee 100644
--- a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -481,6 +481,55 @@ TEST_F(HeadersForSymbolTest, 
PublicOverPrivateWithoutUmbrella) {
   ElementsAre(physicalHeader("bar.h"), physicalHeader("foo.h")));
 }
 
+TEST_F(HeadersForSymbolTest, IWYUTransitiveExport) {
+  Inputs.Code = R"cpp(
+#include "export1.h"
+  )cpp";
+  Inputs.ExtraFiles["export1.h"] = guard(R"cpp(
+#include "export2.h" // IWYU pragma: export
+  )cpp");
+  Inputs.ExtraFiles["export2.h"] = guard(R"cpp(
+#include "foo.h" // IWYU pragma: export
+  )cpp");
+  Inputs.ExtraFiles["foo.h"] = guard(R"cpp(
+struct foo {};
+  )cpp");
+  buildAST();
+  EXPECT_THAT(headersForFoo(),
+  ElementsAre(physicalHeader("foo.h"), physicalHeader("export1.h"),
+

[clang] 8a5c0cc - [clangd][clang-tidy][std_symbol_map] Add missing symbol.

2023-08-07 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-08-07T08:41:58Z
New Revision: 8a5c0ccee2938dfec0082024aea664e7338adbe7

URL: 
https://github.com/llvm/llvm-project/commit/8a5c0ccee2938dfec0082024aea664e7338adbe7
DIFF: 
https://github.com/llvm/llvm-project/commit/8a5c0ccee2938dfec0082024aea664e7338adbe7.diff

LOG: [clangd][clang-tidy][std_symbol_map] Add missing symbol.

Differential Revision: https://reviews.llvm.org/D157256

Added: 


Modified: 
clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc

Removed: 




diff  --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc 
b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc
index aa0bc50445f473..77578baef80a1c 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc
@@ -363,6 +363,7 @@ SYMBOL(make_integer_sequence, std::, )
 // Symbols missing from the generated symbol map as reported by users.
 // Remove when the generator starts producing them.
 SYMBOL(make_any, std::, )
+SYMBOL(any_cast, std::, )
 
 // The std::placeholder symbols (_1, ..., _N) are listed in the cppreference
 // placeholder.html, but the index only contains a single entry with "_1, _2, 
..., _N"



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 5d49276 - [clangd][clang-tidy][stdlib] Add a missing symbol to the mapping.

2023-08-04 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-08-04T14:15:01Z
New Revision: 5d492766a8fbfadb39c9830ebb64137edddfe0e5

URL: 
https://github.com/llvm/llvm-project/commit/5d492766a8fbfadb39c9830ebb64137edddfe0e5
DIFF: 
https://github.com/llvm/llvm-project/commit/5d492766a8fbfadb39c9830ebb64137edddfe0e5.diff

LOG: [clangd][clang-tidy][stdlib] Add a missing symbol to the mapping.

Differential Revision: https://reviews.llvm.org/D157093

Added: 


Modified: 
clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc

Removed: 




diff  --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc 
b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc
index ae620a0b995816..aa0bc50445f473 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc
@@ -360,6 +360,10 @@ SYMBOL(index_sequence_for, std::, )
 SYMBOL(make_index_sequence, std::, )
 SYMBOL(make_integer_sequence, std::, )
 
+// Symbols missing from the generated symbol map as reported by users.
+// Remove when the generator starts producing them.
+SYMBOL(make_any, std::, )
+
 // The std::placeholder symbols (_1, ..., _N) are listed in the cppreference
 // placeholder.html, but the index only contains a single entry with "_1, _2, 
..., _N"
 // text, which are not handled by the script.



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 3c6a7b0 - [clangd] Revert the symbol collector behavior to old pre-include-cleaner-library behavior due to a regression.

2023-07-27 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-07-27T10:34:35Z
New Revision: 3c6a7b0045afe9a230346e476bf07f88c145fdb5

URL: 
https://github.com/llvm/llvm-project/commit/3c6a7b0045afe9a230346e476bf07f88c145fdb5
DIFF: 
https://github.com/llvm/llvm-project/commit/3c6a7b0045afe9a230346e476bf07f88c145fdb5.diff

LOG: [clangd] Revert the symbol collector behavior to old 
pre-include-cleaner-library behavior due to a regression.

Differential Revision: https://reviews.llvm.org/D156403

Added: 


Modified: 
clang-tools-extra/clangd/index/SymbolCollector.cpp
clang-tools-extra/clangd/index/SymbolCollector.h
clang-tools-extra/clangd/unittests/FileIndexTests.cpp
clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp 
b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index e9522171d70b75..c9a211b9c4fc2c 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -36,6 +36,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/Token.h"
 #include "clang/Tooling/Inclusions/HeaderAnalysis.h"
+#include "clang/Tooling/Inclusions/StandardLibrary.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
@@ -836,14 +837,25 @@ void SymbolCollector::setIncludeLocation(const Symbol , 
SourceLocation DefLoc,
   // Use the expansion location to get the #include header since this is
   // where the symbol is exposed.
   IncludeFiles[S.ID] = SM.getDecomposedExpansionLoc(DefLoc).first;
+}
 
-  auto [It, Inserted] = SymbolProviders.try_emplace(S.ID);
-  if (Inserted) {
-auto Headers =
-include_cleaner::headersForSymbol(Sym, SM, Opts.PragmaIncludes);
-if (!Headers.empty())
-  It->second = Headers.front();
-  }
+llvm::StringRef getStdHeader(const Symbol *S, const LangOptions ) {
+  tooling::stdlib::Lang Lang = tooling::stdlib::Lang::CXX;
+if (LangOpts.C11)
+  Lang = tooling::stdlib::Lang::C;
+else if(!LangOpts.CPlusPlus)
+  return "";
+
+if (S->Scope == "std::" && S->Name == "move") {
+  if (!S->Signature.contains(','))
+return "";
+  return "";
+}
+   
+if (auto StdSym = tooling::stdlib::Symbol::named(S->Scope, S->Name, Lang))
+ if (auto Header = StdSym->header())
+   return Header->name();
+return "";
 }
 
 void SymbolCollector::finish() {
@@ -869,16 +881,13 @@ void SymbolCollector::finish() {
 }
   }
   llvm::DenseMap FileToContainsImportsOrObjC;
-  llvm::DenseMap HeaderSpelling;
   // Fill in IncludeHeaders.
   // We delay this until end of TU so header guards are all resolved.
-  for (const auto &[SID, OptionalProvider] : SymbolProviders) {
+  for (const auto &[SID, FID] : IncludeFiles) {
 const Symbol *S = Symbols.find(SID);
 if (!S)
   continue;
-assert(IncludeFiles.find(SID) != IncludeFiles.end());
 
-const auto FID = IncludeFiles.at(SID);
 // Determine if the FID is #include'd or #import'ed.
 Symbol::IncludeDirective Directives = Symbol::Invalid;
 auto CollectDirectives = shouldCollectIncludePath(S->SymInfo.Kind);
@@ -898,54 +907,20 @@ void SymbolCollector::finish() {
 if (Directives == Symbol::Invalid)
   continue;
 
-// Use the include location-based logic for Objective-C symbols.
-if (Directives & Symbol::Import) {
-  if (auto IncludeHeader = HeaderFileURIs->getIncludeHeader(FID);
-  !IncludeHeader.empty()) {
-auto NewSym = *S;
-NewSym.IncludeHeaders.push_back({IncludeHeader, 1, Directives});
-Symbols.insert(NewSym);
-  }
-  // FIXME: use providers from include-cleaner library once it's polished
-  // for Objective-C.
-  continue;
-}
-
-assert(Directives == Symbol::Include);
-// For #include's, use the providers computed by the include-cleaner
-// library.
-if (!OptionalProvider)
-  continue;
-const auto  = *OptionalProvider;
-const auto [SpellingIt, Inserted] = HeaderSpelling.try_emplace(H);
-if (Inserted) {
-  auto  = ASTCtx->getSourceManager();
-  if (H.kind() == include_cleaner::Header::Kind::Physical) {
-if (auto Canonical =
-HeaderFileURIs->mapCanonical(H.physical()->getName());
-!Canonical.empty())
-  SpellingIt->second = Canonical;
-else if (tooling::isSelfContainedHeader(H.physical(), SM,
-PP->getHeaderSearchInfo()))
-  SpellingIt->second =
-  HeaderFileURIs->toURI(H.physical()->getLastRef());
-  } else {
-SpellingIt->second = include_cleaner::spellHeader(
-{H, PP->getHeaderSearchInfo(),
- SM.getFileEntryForID(SM.getMainFileID())});
-  }
-}
+// FIXME: Use the include-cleaner library instead.
+llvm::StringRef IncludeHeader = 

[clang-tools-extra] 1f7c7d4 - [clangd] Update symbol collector to use include-cleaner.

2023-07-19 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-07-19T13:47:02Z
New Revision: 1f7c7d4bdd7b847d82b19bcd097029fabb449b90

URL: 
https://github.com/llvm/llvm-project/commit/1f7c7d4bdd7b847d82b19bcd097029fabb449b90
DIFF: 
https://github.com/llvm/llvm-project/commit/1f7c7d4bdd7b847d82b19bcd097029fabb449b90.diff

LOG: [clangd] Update symbol collector to use include-cleaner.

Differential Revision: https://reviews.llvm.org/D152900

Added: 


Modified: 
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/ParsedAST.cpp
clang-tools-extra/clangd/ParsedAST.h
clang-tools-extra/clangd/Preamble.cpp
clang-tools-extra/clangd/Preamble.h
clang-tools-extra/clangd/TUScheduler.cpp
clang-tools-extra/clangd/TUScheduler.h
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/index/CanonicalIncludes.cpp
clang-tools-extra/clangd/index/CanonicalIncludes.h
clang-tools-extra/clangd/index/FileIndex.cpp
clang-tools-extra/clangd/index/FileIndex.h
clang-tools-extra/clangd/index/IndexAction.cpp
clang-tools-extra/clangd/index/SymbolCollector.cpp
clang-tools-extra/clangd/index/SymbolCollector.h
clang-tools-extra/clangd/tool/Check.cpp
clang-tools-extra/clangd/unittests/CanonicalIncludesTests.cpp
clang-tools-extra/clangd/unittests/FileIndexTests.cpp
clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
clang-tools-extra/clangd/unittests/TestTU.cpp
clang-tools-extra/clangd/unittests/TestWorkspace.cpp
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index 1451adcbf4d4fe..af002e0cb2d689 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -23,7 +23,7 @@
 #include "SourceCode.h"
 #include "TUScheduler.h"
 #include "XRefs.h"
-#include "index/CanonicalIncludes.h"
+#include "clang-include-cleaner/Record.h"
 #include "index/FileIndex.h"
 #include "index/Merge.h"
 #include "index/StdLib.h"
@@ -53,6 +53,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace clang {
 namespace clangd {
@@ -69,13 +70,13 @@ struct UpdateIndexCallbacks : public ParsingCallbacks {
const ThreadsafeFS , AsyncTaskRunner *Tasks,
bool CollectInactiveRegions,
const ClangdServer::Options )
-  : FIndex(FIndex), ServerCallbacks(ServerCallbacks),
-TFS(TFS), Stdlib{std::make_shared()}, Tasks(Tasks),
+  : FIndex(FIndex), ServerCallbacks(ServerCallbacks), TFS(TFS),
+Stdlib{std::make_shared()}, Tasks(Tasks),
 CollectInactiveRegions(CollectInactiveRegions), Opts(Opts) {}
 
   void onPreambleAST(
   PathRef Path, llvm::StringRef Version, CapturedASTCtx ASTCtx,
-  const std::shared_ptr CanonIncludes) override {
+  std::shared_ptr PI) override {
 
 if (!FIndex)
   return;
@@ -87,11 +88,10 @@ struct UpdateIndexCallbacks : public ParsingCallbacks {
 
 // FIndex outlives the UpdateIndexCallbacks.
 auto Task = [FIndex(FIndex), Path(Path.str()), Version(Version.str()),
- ASTCtx(std::move(ASTCtx)),
- CanonIncludes(CanonIncludes)]() mutable {
+ ASTCtx(std::move(ASTCtx)), PI(std::move(PI))]() mutable {
   trace::Span Tracer("PreambleIndexing");
   FIndex->updatePreamble(Path, Version, ASTCtx.getASTContext(),
- ASTCtx.getPreprocessor(), *CanonIncludes);
+ ASTCtx.getPreprocessor(), *PI);
 };
 
 if (Opts.AsyncPreambleIndexing && Tasks) {

diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index fbd0be07961651..ceae563131c13f 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -21,7 +21,6 @@
 #include "clang-include-cleaner/IncludeSpeller.h"
 #include "clang-include-cleaner/Types.h"
 #include "index/SymbolCollector.h"
-#include "support/Logger.h"
 #include "support/Markup.h"
 #include "support/Trace.h"
 #include "clang/AST/ASTContext.h"
@@ -1190,7 +1189,7 @@ void maybeAddSymbolProviders(ParsedAST , HoverInfo 
,
 
   const SourceManager  = AST.getSourceManager();
   llvm::SmallVector RankedProviders =
-  include_cleaner::headersForSymbol(Sym, SM, AST.getPragmaIncludes());
+  include_cleaner::headersForSymbol(Sym, SM, 
AST.getPragmaIncludes().get());
   if (RankedProviders.empty())
 return;
 
@@ -1254,7 +1253,7 @@ void maybeAddUsedSymbols(ParsedAST , HoverInfo , 
const Inclusion ) {
   llvm::DenseSet UsedSymbols;
   include_cleaner::walkUsed(
   AST.getLocalTopLevelDecls(), collectMacroReferences(AST),
-  AST.getPragmaIncludes(), SM,
+ 

[clang-tools-extra] 22605f5 - [clangd] Make an include always refer to itself. Background: clang-review expects all referents to have definition, declaration or reference(s).

2023-07-19 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-07-19T08:32:53Z
New Revision: 22605f5f1bf8a6e4a18171ea76e8fcfa7fa783fd

URL: 
https://github.com/llvm/llvm-project/commit/22605f5f1bf8a6e4a18171ea76e8fcfa7fa783fd
DIFF: 
https://github.com/llvm/llvm-project/commit/22605f5f1bf8a6e4a18171ea76e8fcfa7fa783fd.diff

LOG: [clangd] Make an include always refer to itself. Background: clang-review 
expects all referents to have definition, declaration or reference(s).

Differential Revision: https://reviews.llvm.org/D155614

Added: 


Modified: 
clang-tools-extra/clangd/XRefs.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/XRefs.cpp 
b/clang-tools-extra/clangd/XRefs.cpp
index 29ce1f3e0d0e3b..80a7d028ddf902 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -1367,9 +1367,6 @@ maybeFindIncludeReferences(ParsedAST , Position Pos,
   rangeTillEOL(SM.getBufferData(SM.getMainFileID()), Inc.HashOffset);
   Result.Loc.uri = URIMainFile;
   Results.References.push_back(std::move(Result));
-
-  if (Results.References.empty())
-return std::nullopt;
   return Results;
 }
 } // namespace



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 96e5079 - [clangd] Fix the range for include reference to itself.

2023-07-14 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-07-14T12:51:14Z
New Revision: 96e50797d6ea39d561fc90511152fd30b77c1e62

URL: 
https://github.com/llvm/llvm-project/commit/96e50797d6ea39d561fc90511152fd30b77c1e62
DIFF: 
https://github.com/llvm/llvm-project/commit/96e50797d6ea39d561fc90511152fd30b77c1e62.diff

LOG: [clangd] Fix the range for include reference to itself.

Differential Revision: https://reviews.llvm.org/D155215

Added: 


Modified: 
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h
clang-tools-extra/clangd/SourceCode.cpp
clang-tools-extra/clangd/SourceCode.h
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/unittests/XRefsTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/IncludeCleaner.cpp 
b/clang-tools-extra/clangd/IncludeCleaner.cpp
index 2a8499dade84c0..9a910e5850a9f1 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.cpp
+++ b/clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -60,20 +60,6 @@ void setIncludeCleanerAnalyzesStdlib(bool B) { AnalyzeStdlib 
= B; }
 
 namespace {
 
-// Returns the range starting at '#' and ending at EOL. Escaped newlines are 
not
-// handled.
-clangd::Range getDiagnosticRange(llvm::StringRef Code, unsigned HashOffset) {
-  clangd::Range Result;
-  Result.end = Result.start = offsetToPosition(Code, HashOffset);
-
-  // Span the warning until the EOL or EOF.
-  Result.end.character +=
-  lspLength(Code.drop_front(HashOffset).take_until([](char C) {
-return C == '\n' || C == '\r';
-  }));
-  return Result;
-}
-
 bool isIgnored(llvm::StringRef HeaderPath, HeaderFilter IgnoreHeaders) {
   // Convert the path to Unix slashes and try to match against the filter.
   llvm::SmallString<64> NormalizedPath(HeaderPath);
@@ -224,7 +210,7 @@ std::vector generateUnusedIncludeDiagnostics(
 D.InsideMainFile = true;
 D.Severity = DiagnosticsEngine::Warning;
 D.Tags.push_back(Unnecessary);
-D.Range = getDiagnosticRange(Code, Inc->HashOffset);
+D.Range = rangeTillEOL(Code, Inc->HashOffset);
 // FIXME(kirillbobyrev): Removing inclusion might break the code if the
 // used headers are only reachable transitively through this one. Suggest
 // including them directly instead.

diff  --git a/clang-tools-extra/clangd/IncludeCleaner.h 
b/clang-tools-extra/clangd/IncludeCleaner.h
index edd89777faf3d0..b1acbdd5484345 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.h
+++ b/clang-tools-extra/clangd/IncludeCleaner.h
@@ -21,6 +21,7 @@
 #include "Diagnostics.h"
 #include "Headers.h"
 #include "ParsedAST.h"
+#include "Protocol.h"
 #include "clang-include-cleaner/Types.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Tooling/Syntax/Tokens.h"

diff  --git a/clang-tools-extra/clangd/SourceCode.cpp 
b/clang-tools-extra/clangd/SourceCode.cpp
index 474570cb6459f7..eb0a578b0f4a12 100644
--- a/clang-tools-extra/clangd/SourceCode.cpp
+++ b/clang-tools-extra/clangd/SourceCode.cpp
@@ -1242,5 +1242,17 @@ SourceLocation 
translatePreamblePatchLocation(SourceLocation Loc,
   }
   return Loc;
 }
+
+clangd::Range rangeTillEOL(llvm::StringRef Code, unsigned HashOffset) {
+  clangd::Range Result;
+  Result.end = Result.start = offsetToPosition(Code, HashOffset);
+
+  // Span the warning until the EOL or EOF.
+  Result.end.character +=
+  lspLength(Code.drop_front(HashOffset).take_until([](char C) {
+return C == '\n' || C == '\r';
+  }));
+  return Result;
+}
 } // namespace clangd
 } // namespace clang

diff  --git a/clang-tools-extra/clangd/SourceCode.h 
b/clang-tools-extra/clangd/SourceCode.h
index 3ba6f8b80ef373..a1bb44c1761202 100644
--- a/clang-tools-extra/clangd/SourceCode.h
+++ b/clang-tools-extra/clangd/SourceCode.h
@@ -337,6 +337,10 @@ inline bool isReservedName(llvm::StringRef Name) {
 /// using presumed locations. Returns \p Loc if it isn't inside preamble patch.
 SourceLocation translatePreamblePatchLocation(SourceLocation Loc,
   const SourceManager );
+
+/// Returns the range starting at offset and spanning the whole line. Escaped
+/// newlines are not handled.
+clangd::Range rangeTillEOL(llvm::StringRef Code, unsigned HashOffset);
 } // namespace clangd
 } // namespace clang
 #endif

diff  --git a/clang-tools-extra/clangd/XRefs.cpp 
b/clang-tools-extra/clangd/XRefs.cpp
index b608296deefad5..29ce1f3e0d0e3b 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -1362,10 +1362,9 @@ maybeFindIncludeReferences(ParsedAST , Position Pos,
 return std::nullopt;
 
   // Add the #include line to the references list.
-  auto IncludeLen = std::string{"#include"}.length() + Inc.Written.length() + 
1;
   ReferencesResult::Reference Result;
-  Result.Loc.range = clangd::Range{Position{Inc.HashLine, 0},
-   Position{Inc.HashLine, (int)IncludeLen}};
+  

[clang-tools-extra] 7322f2d - [clangd] Use canonical path as resolved path for includes.

2023-07-11 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-07-11T15:36:20Z
New Revision: 7322f2d5ed547f7281af2d79a229f6620b1708ac

URL: 
https://github.com/llvm/llvm-project/commit/7322f2d5ed547f7281af2d79a229f6620b1708ac
DIFF: 
https://github.com/llvm/llvm-project/commit/7322f2d5ed547f7281af2d79a229f6620b1708ac.diff

LOG: [clangd] Use canonical path as resolved path for includes.

Differential Revision: https://reviews.llvm.org/D154962

Added: 


Modified: 
clang-tools-extra/clangd/Headers.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Headers.cpp 
b/clang-tools-extra/clangd/Headers.cpp
index f1838931f5a4d2..c3414571170b72 100644
--- a/clang-tools-extra/clangd/Headers.cpp
+++ b/clang-tools-extra/clangd/Headers.cpp
@@ -21,6 +21,7 @@
 #include "llvm/Support/Path.h"
 #include 
 #include 
+#include 
 
 namespace clang {
 namespace clangd {
@@ -53,8 +54,9 @@ class IncludeStructure::RecordHeaders : public PPCallbacks {
   auto  = Out->MainFileIncludes.back();
   Inc.Written =
   (IsAngled ? "<" + FileName + ">" : "\"" + FileName + "\"").str();
-  Inc.Resolved =
-  std::string(File ? File->getFileEntry().tryGetRealPathName() : "");
+  Inc.Resolved = std::string(
+  File ? getCanonicalPath(*File, SM.getFileManager()).value_or("")
+   : "");
   Inc.HashOffset = SM.getFileOffset(HashLoc);
   Inc.HashLine =
   SM.getLineNumber(SM.getFileID(HashLoc), Inc.HashOffset) - 1;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] c9888dc - [clangd] Skip function parameter decls when evaluating variables on hover.

2023-06-16 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-06-16T12:09:28Z
New Revision: c9888dce44748bfbf3719351c3feb3359eaba017

URL: 
https://github.com/llvm/llvm-project/commit/c9888dce44748bfbf3719351c3feb3359eaba017
DIFF: 
https://github.com/llvm/llvm-project/commit/c9888dce44748bfbf3719351c3feb3359eaba017.diff

LOG: [clangd] Skip function parameter decls when evaluating variables on hover.

Differential Revision: https://reviews.llvm.org/D153015

Added: 


Modified: 
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index d7a249c6bc21f..5184fcbe4b581 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -659,7 +659,7 @@ HoverInfo getHoverContents(const NamedDecl *D, const 
PrintingPolicy ,
 HI.Type = printType(TAT->getTemplatedDecl()->getUnderlyingType(), Ctx, PP);
 
   // Fill in value with evaluated initializer if possible.
-  if (const auto *Var = dyn_cast(D)) {
+  if (const auto *Var = dyn_cast(D); Var && !Var->isInvalidDecl()) {
 if (const Expr *Init = Var->getInit())
   HI.Value = printExprValue(Init, Ctx);
   } else if (const auto *ECD = dyn_cast(D)) {

diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp 
b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 583310f29b63f..5338a680b787a 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -22,6 +22,7 @@
 
 #include "gtest/gtest.h"
 #include 
+#include 
 #include 
 #include 
 
@@ -3722,6 +3723,34 @@ TEST(Hover, ForwardStructNoCrash) {
   EXPECT_EQ(*HI->Value, "");
 }
 
+TEST(Hover, FunctionParameterDefaulValueNotEvaluatedOnInvalidDecls) {
+  struct {
+const char *const Code;
+const std::optional HoverValue;
+  } Cases[] = {
+  {R"cpp(
+// error-ok testing behavior on invalid decl
+class Foo {};
+void foo(Foo p^aram = nullptr);
+)cpp",
+   std::nullopt},
+  {R"cpp(
+class Foo {};
+void foo(Foo *p^aram = nullptr);
+)cpp",
+   "nullptr"},
+  };
+
+  for (const auto  : Cases) {
+Annotations T(C.Code);
+TestTU TU = TestTU::withCode(T.code());
+auto AST = TU.build();
+auto HI = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
+ASSERT_TRUE(HI);
+ASSERT_EQ(HI->Value, C.HoverValue);
+  }
+}
+
 TEST(Hover, DisableShowAKA) {
   Annotations T(R"cpp(
 using m_int = int;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 6a6c7ed - [clangd] Use include_cleaner spelling strategies in clangd.

2023-06-14 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-06-14T14:06:35Z
New Revision: 6a6c7ed5cd8d1a7e0991128e46abfd2b7d95f8e8

URL: 
https://github.com/llvm/llvm-project/commit/6a6c7ed5cd8d1a7e0991128e46abfd2b7d95f8e8
DIFF: 
https://github.com/llvm/llvm-project/commit/6a6c7ed5cd8d1a7e0991128e46abfd2b7d95f8e8.diff

LOG: [clangd] Use include_cleaner spelling strategies in clangd.

Differential Revision: https://reviews.llvm.org/D152913

Added: 


Modified: 
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h

Removed: 




diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index 0ae70dd121ebf..d7a249c6bc21f 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -18,6 +18,7 @@
 #include "Selection.h"
 #include "SourceCode.h"
 #include "clang-include-cleaner/Analysis.h"
+#include "clang-include-cleaner/IncludeSpeller.h"
 #include "clang-include-cleaner/Types.h"
 #include "index/SymbolCollector.h"
 #include "support/Logger.h"
@@ -1223,7 +1224,9 @@ void maybeAddSymbolProviders(ParsedAST , HoverInfo 
,
 // on local variables, etc.
 return;
 
-  HI.Provider = spellHeader(AST, SM.getFileEntryForID(SM.getMainFileID()), H);
+  HI.Provider = include_cleaner::spellHeader(
+  {H, AST.getPreprocessor().getHeaderSearchInfo(),
+   SM.getFileEntryForID(SM.getMainFileID())});
 }
 
 // FIXME: similar functions are present in FindHeaders.cpp (symbolName)

diff  --git a/clang-tools-extra/clangd/IncludeCleaner.cpp 
b/clang-tools-extra/clangd/IncludeCleaner.cpp
index 95585a61c023d..95f6064b769a7 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.cpp
+++ b/clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -182,8 +182,9 @@ std::vector generateMissingIncludeDiagnostics(
   continue;
 }
 
-std::string Spelling =
-spellHeader(AST, MainFile, SymbolWithMissingInclude.Providers.front());
+std::string Spelling = include_cleaner::spellHeader(
+{SymbolWithMissingInclude.Providers.front(),
+ AST.getPreprocessor().getHeaderSearchInfo(), MainFile});
 
 llvm::StringRef HeaderRef{Spelling};
 bool Angled = HeaderRef.starts_with("<");
@@ -412,22 +413,6 @@ convertIncludes(const SourceManager ,
   return ConvertedIncludes;
 }
 
-std::string spellHeader(ParsedAST , const FileEntry *MainFile,
-include_cleaner::Header Provider) {
-  if (Provider.kind() == include_cleaner::Header::Physical) {
-if (auto CanonicalPath =
-getCanonicalPath(Provider.physical()->getLastRef(),
- AST.getSourceManager().getFileManager())) {
-  std::string SpelledHeader =
-  llvm::cantFail(URI::includeSpelling(URI::create(*CanonicalPath)));
-  if (!SpelledHeader.empty())
-return SpelledHeader;
-}
-  }
-  return include_cleaner::spellHeader(
-  {Provider, AST.getPreprocessor().getHeaderSearchInfo(), MainFile});
-}
-
 IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST ) {
   // Interaction is only polished for C/CPP.
   if (AST.getLangOpts().ObjC)

diff  --git a/clang-tools-extra/clangd/IncludeCleaner.h 
b/clang-tools-extra/clangd/IncludeCleaner.h
index 58849846e0df7..edd89777faf3d 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.h
+++ b/clang-tools-extra/clangd/IncludeCleaner.h
@@ -75,11 +75,6 @@ include_cleaner::Includes
 convertIncludes(const SourceManager ,
 const llvm::ArrayRef Includes);
 
-/// Determines the header spelling of an include-cleaner header
-/// representation. The spelling contains the ""<> characters.
-std::string spellHeader(ParsedAST , const FileEntry *MainFile,
-include_cleaner::Header Provider);
-
 std::vector
 collectMacroReferences(ParsedAST );
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] cd5fcea - [clangd] Revert to older include spelling approach.

2023-06-05 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-06-05T15:18:28Z
New Revision: cd5fcea6d4c70a7328ca9538c9098d9f5af69682

URL: 
https://github.com/llvm/llvm-project/commit/cd5fcea6d4c70a7328ca9538c9098d9f5af69682
DIFF: 
https://github.com/llvm/llvm-project/commit/cd5fcea6d4c70a7328ca9538c9098d9f5af69682.diff

LOG: [clangd] Revert to older include spelling approach.

Added: 


Modified: 
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h

Removed: 




diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index 80303267b31a0..d1f6f3a7b06c0 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -18,7 +18,6 @@
 #include "Selection.h"
 #include "SourceCode.h"
 #include "clang-include-cleaner/Analysis.h"
-#include "clang-include-cleaner/IncludeSpeller.h"
 #include "clang-include-cleaner/Types.h"
 #include "index/SymbolCollector.h"
 #include "support/Logger.h"
@@ -1223,9 +1222,7 @@ void maybeAddSymbolProviders(ParsedAST , HoverInfo 
,
 // on local variables, etc.
 return;
 
-  HI.Provider = include_cleaner::spellHeader(
-  {H, AST.getPreprocessor().getHeaderSearchInfo(),
-   SM.getFileEntryForID(SM.getMainFileID())});
+  HI.Provider = spellHeader(AST, SM.getFileEntryForID(SM.getMainFileID()), H);
 }
 
 // FIXME: similar functions are present in FindHeaders.cpp (symbolName)

diff  --git a/clang-tools-extra/clangd/IncludeCleaner.cpp 
b/clang-tools-extra/clangd/IncludeCleaner.cpp
index c9d32a00fc15f..fa30592e75807 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.cpp
+++ b/clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -198,9 +198,9 @@ std::vector generateMissingIncludeDiagnostics(
   continue;
 }
 
-std::string Spelling = include_cleaner::spellHeader(
-{SymbolWithMissingInclude.Providers.front(),
- AST.getPreprocessor().getHeaderSearchInfo(), MainFile});
+std::string Spelling =
+spellHeader(AST, MainFile, SymbolWithMissingInclude.Providers.front());
+
 llvm::StringRef HeaderRef{Spelling};
 bool Angled = HeaderRef.starts_with("<");
 // We might suggest insertion of an existing include in edge cases, e.g.,
@@ -334,6 +334,22 @@ convertIncludes(const SourceManager ,
   return ConvertedIncludes;
 }
 
+std::string spellHeader(ParsedAST , const FileEntry *MainFile,
+include_cleaner::Header Provider) {
+  if (Provider.kind() == include_cleaner::Header::Physical) {
+if (auto CanonicalPath =
+getCanonicalPath(Provider.physical()->getLastRef(),
+ AST.getSourceManager().getFileManager())) {
+  std::string SpelledHeader =
+  llvm::cantFail(URI::includeSpelling(URI::create(*CanonicalPath)));
+  if (!SpelledHeader.empty())
+return SpelledHeader;
+}
+  }
+  return include_cleaner::spellHeader(
+  {Provider, AST.getPreprocessor().getHeaderSearchInfo(), MainFile});
+}
+
 std::vector
 getUnused(ParsedAST ,
   const llvm::DenseSet ,

diff  --git a/clang-tools-extra/clangd/IncludeCleaner.h 
b/clang-tools-extra/clangd/IncludeCleaner.h
index c4051b30ca317..675c05a53d5f8 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.h
+++ b/clang-tools-extra/clangd/IncludeCleaner.h
@@ -74,6 +74,11 @@ include_cleaner::Includes
 convertIncludes(const SourceManager ,
 const llvm::ArrayRef Includes);
 
+/// Determines the header spelling of an include-cleaner header
+/// representation. The spelling contains the ""<> characters.
+std::string spellHeader(ParsedAST , const FileEntry *MainFile,
+include_cleaner::Header Provider);
+
 std::vector
 collectMacroReferences(ParsedAST );
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 90c5fe9 - [include-cleaner] Allow multiple strategies for spelling includes.

2023-06-05 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-06-05T09:47:12Z
New Revision: 90c5fe982190b826aab90c93db9ce0f7e25d

URL: 
https://github.com/llvm/llvm-project/commit/90c5fe982190b826aab90c93db9ce0f7e25d
DIFF: 
https://github.com/llvm/llvm-project/commit/90c5fe982190b826aab90c93db9ce0f7e25d.diff

LOG: [include-cleaner] Allow multiple strategies for spelling includes.

Summary:

Reviewers:

Subscribers:

Differential Revision: https://reviews.llvm.org/D150185

Added: 

clang-tools-extra/include-cleaner/include/clang-include-cleaner/IncludeSpeller.h
clang-tools-extra/include-cleaner/lib/IncludeSpeller.cpp
clang-tools-extra/include-cleaner/unittests/IncludeSpellerTest.cpp

Modified: 
clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
clang-tools-extra/include-cleaner/lib/Analysis.cpp
clang-tools-extra/include-cleaner/lib/CMakeLists.txt
clang-tools-extra/include-cleaner/unittests/CMakeLists.txt

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp 
b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
index c7aca83f2ca8c..49e7581d801d9 100644
--- a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
@@ -12,6 +12,7 @@
 #include "../ClangTidyOptions.h"
 #include "../utils/OptionsUtils.h"
 #include "clang-include-cleaner/Analysis.h"
+#include "clang-include-cleaner/IncludeSpeller.h"
 #include "clang-include-cleaner/Record.h"
 #include "clang-include-cleaner/Types.h"
 #include "clang/AST/ASTContext.h"
@@ -180,7 +181,7 @@ void IncludeCleanerCheck::check(const 
MatchFinder::MatchResult ) {
  FileStyle->IncludeStyle);
   for (const auto  : Missing) {
 std::string Spelling =
-include_cleaner::spellHeader(Inc.Missing, *HS, MainFile);
+include_cleaner::spellHeader({Inc.Missing, *HS, MainFile});
 bool Angled = llvm::StringRef{Spelling}.starts_with("<");
 // We might suggest insertion of an existing include in edge cases, e.g.,
 // include is present in a PP-disabled region, or spelling of the header

diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index d1f6f3a7b06c0..80303267b31a0 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -18,6 +18,7 @@
 #include "Selection.h"
 #include "SourceCode.h"
 #include "clang-include-cleaner/Analysis.h"
+#include "clang-include-cleaner/IncludeSpeller.h"
 #include "clang-include-cleaner/Types.h"
 #include "index/SymbolCollector.h"
 #include "support/Logger.h"
@@ -1222,7 +1223,9 @@ void maybeAddSymbolProviders(ParsedAST , HoverInfo 
,
 // on local variables, etc.
 return;
 
-  HI.Provider = spellHeader(AST, SM.getFileEntryForID(SM.getMainFileID()), H);
+  HI.Provider = include_cleaner::spellHeader(
+  {H, AST.getPreprocessor().getHeaderSearchInfo(),
+   SM.getFileEntryForID(SM.getMainFileID())});
 }
 
 // FIXME: similar functions are present in FindHeaders.cpp (symbolName)

diff  --git a/clang-tools-extra/clangd/IncludeCleaner.cpp 
b/clang-tools-extra/clangd/IncludeCleaner.cpp
index a3e08bc56b31d..c9d32a00fc15f 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.cpp
+++ b/clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -16,6 +16,7 @@
 #include "SourceCode.h"
 #include "URI.h"
 #include "clang-include-cleaner/Analysis.h"
+#include "clang-include-cleaner/IncludeSpeller.h"
 #include "clang-include-cleaner/Record.h"
 #include "clang-include-cleaner/Types.h"
 #include "support/Logger.h"
@@ -197,8 +198,9 @@ std::vector generateMissingIncludeDiagnostics(
   continue;
 }
 
-std::string Spelling =
-spellHeader(AST, MainFile, SymbolWithMissingInclude.Providers.front());
+std::string Spelling = include_cleaner::spellHeader(
+{SymbolWithMissingInclude.Providers.front(),
+ AST.getPreprocessor().getHeaderSearchInfo(), MainFile});
 llvm::StringRef HeaderRef{Spelling};
 bool Angled = HeaderRef.starts_with("<");
 // We might suggest insertion of an existing include in edge cases, e.g.,
@@ -332,21 +334,6 @@ convertIncludes(const SourceManager ,
   return ConvertedIncludes;
 }
 
-std::string spellHeader(ParsedAST , const FileEntry *MainFile,
-include_cleaner::Header Provider) {
-  if (Provider.kind() == include_cleaner::Header::Physical) {
-if (auto CanonicalPath = 
getCanonicalPath(Provider.physical()->getLastRef(),
-  
AST.getSourceManager().getFileManager())) {
-  std::string SpelledHeader =
-  llvm::cantFail(URI::includeSpelling(URI::create(*CanonicalPath)));
-  if 

[clang-tools-extra] 5c2072e - [clang-tidy] Fix docs.

2023-06-02 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-06-02T15:31:55Z
New Revision: 5c2072e74b42d55e8bf7a9c8fee8800bad591f12

URL: 
https://github.com/llvm/llvm-project/commit/5c2072e74b42d55e8bf7a9c8fee8800bad591f12
DIFF: 
https://github.com/llvm/llvm-project/commit/5c2072e74b42d55e8bf7a9c8fee8800bad591f12.diff

LOG: [clang-tidy] Fix docs.

Added: 


Modified: 
clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst

Removed: 




diff  --git a/clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst 
b/clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
index 30865680ac023..3246fea78cd42 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
@@ -10,6 +10,7 @@ Findings correspond to 
https://clangd.llvm.org/design/include-cleaner.
 Example:
 
 .. code-block:: c++
+   
// foo.h
class Foo{};
// bar.h



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] c28506b - [clang-tidy] Implement an include-cleaner check.

2023-06-02 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-06-02T15:21:20Z
New Revision: c28506ba4b6961950849f8fdecd0cf7e503a14f9

URL: 
https://github.com/llvm/llvm-project/commit/c28506ba4b6961950849f8fdecd0cf7e503a14f9
DIFF: 
https://github.com/llvm/llvm-project/commit/c28506ba4b6961950849f8fdecd0cf7e503a14f9.diff

LOG: [clang-tidy] Implement an include-cleaner check.

Differential Revision: https://reviews.llvm.org/D148793

Added: 
clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/bar.h
clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/baz.h
clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/foo.h
clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/private.h
clang-tools-extra/test/clang-tidy/checkers/misc/include-cleaner.cpp
clang-tools-extra/test/clang-tidy/checkers/misc/system/string.h
clang-tools-extra/test/clang-tidy/checkers/misc/system/vector.h
clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp

Modified: 
clang-tools-extra/clang-tidy/misc/CMakeLists.txt
clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
clang-tools-extra/clangd/TidyProvider.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h
clang-tools-extra/include-cleaner/lib/Record.cpp
clang-tools-extra/unittests/clang-tidy/CMakeLists.txt

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
index a72362906e0b8..1703ff82b942d 100644
--- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -7,6 +7,7 @@ setup_host_tool(clang-tidy-confusable-chars-gen 
CLANG_TIDY_CONFUSABLE_CHARS_GEN
 
 add_subdirectory(ConfusableTable)
 
+include_directories(BEFORE 
"${CMAKE_CURRENT_SOURCE_DIR}/../../include-cleaner/include")
 
 add_custom_command(
 OUTPUT Confusables.inc
@@ -19,6 +20,7 @@ add_clang_library(clangTidyMiscModule
   ConstCorrectnessCheck.cpp
   DefinitionsInHeadersCheck.cpp
   ConfusableIdentifierCheck.cpp
+  IncludeCleanerCheck.cpp
   MiscTidyModule.cpp
   MisleadingBidirectional.cpp
   MisleadingIdentifier.cpp
@@ -53,6 +55,7 @@ clang_target_link_libraries(clangTidyMiscModule
   clangAST
   clangASTMatchers
   clangBasic
+  clangIncludeCleaner
   clangLex
   clangSerialization
   clangTooling

diff  --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp 
b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
new file mode 100644
index 0..c7aca83f2ca8c
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
@@ -0,0 +1,202 @@
+//===--- IncludeCleanerCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "IncludeCleanerCheck.h"
+#include "../ClangTidyCheck.h"
+#include "../ClangTidyDiagnosticConsumer.h"
+#include "../ClangTidyOptions.h"
+#include "../utils/OptionsUtils.h"
+#include "clang-include-cleaner/Analysis.h"
+#include "clang-include-cleaner/Record.h"
+#include "clang-include-cleaner/Types.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileEntry.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Format/Format.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "clang/Tooling/Inclusions/HeaderIncludes.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Regex.h"
+#include 
+#include 
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::misc {
+
+namespace {
+struct MissingIncludeInfo {
+  SourceLocation SymRefLocation;
+  include_cleaner::Header Missing;
+};
+} // namespace
+
+IncludeCleanerCheck::IncludeCleanerCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  IgnoreHeaders(utils::options::parseStringList(
+  Options.getLocalOrGlobal("IgnoreHeaders", ""))) {
+  for (const auto  : IgnoreHeaders) {
+if 

[clang] 6b50e87 - [clang] Fix label (de-)serialization in ASM statements.

2023-05-22 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-05-22T15:53:45Z
New Revision: 6b50e87f21e131fb75d234acaa69b2386e3b6006

URL: 
https://github.com/llvm/llvm-project/commit/6b50e87f21e131fb75d234acaa69b2386e3b6006
DIFF: 
https://github.com/llvm/llvm-project/commit/6b50e87f21e131fb75d234acaa69b2386e3b6006.diff

LOG: [clang] Fix label (de-)serialization in ASM statements.

Differential Revision: https://reviews.llvm.org/D151073

Added: 
clang/test/PCH/asm-label.cpp

Modified: 
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp

Removed: 




diff  --git a/clang/lib/Serialization/ASTReaderStmt.cpp 
b/clang/lib/Serialization/ASTReaderStmt.cpp
index a96b1a2fa4f31..c3ccb6744ff61 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -400,8 +400,10 @@ void ASTStmtReader::VisitGCCAsmStmt(GCCAsmStmt *S) {
 Clobbers.push_back(cast_or_null(Record.readSubStmt()));
 
   // Labels
-  for (unsigned I = 0, N = NumLabels; I != N; ++I)
+  for (unsigned I = 0, N = NumLabels; I != N; ++I) {
+Names.push_back(Record.readIdentifier());
 Exprs.push_back(Record.readSubStmt());
+  }
 
   S->setOutputsAndInputsAndClobbers(Record.getContext(),
 Names.data(), Constraints.data(),

diff  --git a/clang/lib/Serialization/ASTWriterStmt.cpp 
b/clang/lib/Serialization/ASTWriterStmt.cpp
index 363f7569acd3e..9739d0b37fba1 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -317,7 +317,10 @@ void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) {
 Record.AddStmt(S->getClobberStringLiteral(I));
 
   // Labels
-  for (auto *E : S->labels()) Record.AddStmt(E);
+  for (unsigned I = 0, N = S->getNumLabels(); I != N; ++I) {
+Record.AddIdentifierRef(S->getLabelIdentifier(I));
+Record.AddStmt(S->getLabelExpr(I));
+  }
 
   Code = serialization::STMT_GCCASM;
 }

diff  --git a/clang/test/PCH/asm-label.cpp b/clang/test/PCH/asm-label.cpp
new file mode 100644
index 0..dd68c11409ff5
--- /dev/null
+++ b/clang/test/PCH/asm-label.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -emit-pch %s -o %t
+// RUN: %clang_cc1 -include-pch %t %s -verify
+#ifndef HEADER_H
+#define HEADER_H
+template 
+void MyMethod() {
+  void *bar;
+  some_path:
+  asm goto
+  (
+  "mov %w[foo], %w[foo]"
+  : [foo] "=r"(bar)
+  : [foo2] "r"(bar), [foo3] "r"(bar), [foo4] "r"(bar)
+  : 
+  : some_path
+  );
+  }
+#else
+void test() {
+ MyMethod();
+// expected-no-diagnostics
+}
+#endif



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D150668: Add doc link to missing include diagnostics.

2023-05-16 Thread Viktoriia Bakalova via cfe-commits
Thanks, I'm on it. Should be fixed within minutes.

On Tue, May 16, 2023 at 6:47 PM Nico Weber via Phabricator <
revi...@reviews.llvm.org> wrote:

> thakis added a comment.
>
> This seems to break tests: http://45.33.8.238/linux/107099/step_9.txt
>
> Please take a look, and revert for now if it takes a while to fix.
>
>
> Repository:
>   rG LLVM Github Monorepo
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D150668/new/
>
> https://reviews.llvm.org/D150668
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 76941b6 - [clangd] Fix test.

2023-05-16 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-05-16T16:50:56Z
New Revision: 76941b68ecd9a1f9ca337774b4082c2ca7577450

URL: 
https://github.com/llvm/llvm-project/commit/76941b68ecd9a1f9ca337774b4082c2ca7577450
DIFF: 
https://github.com/llvm/llvm-project/commit/76941b68ecd9a1f9ca337774b4082c2ca7577450.diff

LOG: [clangd] Fix test.

Added: 


Modified: 
clang-tools-extra/clangd/test/include-cleaner-batch-fix.test

Removed: 




diff  --git a/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test 
b/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
index cfc84ad27a2b..bf9e5abca833 100644
--- a/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
+++ b/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
@@ -33,6 +33,9 @@
 # CHECK-NEXT: "diagnostics": [
 # CHECK-NEXT:   {
 # CHECK-NEXT: "code": "missing-includes",
+# CHECK-NEXT: "codeDescription": {
+# CHECK-NEXT:   "href": 
"https://clangd.llvm.org/guides/include-cleaner;
+# CHECK-NEXT: },
 # CHECK-NEXT: "message": "No header providing \"Foo\" is directly 
included (fixes available)",
 # CHECK-NEXT: "range": {
 # CHECK-NEXT:   "end": {
@@ -49,6 +52,9 @@
 # CHECK-NEXT:   },
 # CHECK-NEXT:   {
 # CHECK-NEXT: "code": "missing-includes",
+# CHECK-NEXT: "codeDescription": {
+# CHECK-NEXT:   "href": 
"https://clangd.llvm.org/guides/include-cleaner;
+# CHECK-NEXT: },
 # CHECK-NEXT: "message": "No header providing \"Bar\" is directly 
included (fixes available)",
 # CHECK-NEXT: "range": {
 # CHECK-NEXT:   "end": {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 5cb2770 - Add doc link to missing include diagnostics.

2023-05-16 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-05-16T16:10:58Z
New Revision: 5cb2770bd714105f5d65234b949ded0430604209

URL: 
https://github.com/llvm/llvm-project/commit/5cb2770bd714105f5d65234b949ded0430604209
DIFF: 
https://github.com/llvm/llvm-project/commit/5cb2770bd714105f5d65234b949ded0430604209.diff

LOG: Add doc link to missing include diagnostics.

Differential Revision: https://reviews.llvm.org/D150668

Added: 


Modified: 
clang-tools-extra/clangd/Diagnostics.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Diagnostics.cpp 
b/clang-tools-extra/clangd/Diagnostics.cpp
index d1726142c5de..b708f9c3d3b0 100644
--- a/clang-tools-extra/clangd/Diagnostics.cpp
+++ b/clang-tools-extra/clangd/Diagnostics.cpp
@@ -918,7 +918,7 @@ std::optional 
getDiagnosticDocURI(Diag::DiagSource Source,
 .str();
   }
   case Diag::Clangd:
-if (Name == "unused-includes")
+if (Name == "unused-includes" || Name == "missing-includes")
   return {"https://clangd.llvm.org/guides/include-cleaner"};
 break;
   case Diag::ClangdConfig:



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 9e9b1ef - [clangd] Implement cross reference request for #include lines.

2023-04-20 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-04-20T07:11:48Z
New Revision: 9e9b1effac34b75d22483955187b94418c12ebce

URL: 
https://github.com/llvm/llvm-project/commit/9e9b1effac34b75d22483955187b94418c12ebce
DIFF: 
https://github.com/llvm/llvm-project/commit/9e9b1effac34b75d22483955187b94418c12ebce.diff

LOG: [clangd] Implement cross reference request for #include lines.

Differential Revision: https://reviews.llvm.org/D147044

Added: 


Modified: 
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
clang-tools-extra/clangd/unittests/XRefsTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index 6a56553318b84..3eb0900715744 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -1172,20 +1172,12 @@ void maybeAddUsedSymbols(ParsedAST , HoverInfo , 
const Inclusion ) {
 UsedSymbols.contains(Ref.Target))
   return;
 
-for (const include_cleaner::Header  : Providers) {
-  auto MatchingIncludes = ConvertedMainFileIncludes.match(H);
-  // No match for this provider in the main file.
-  if (MatchingIncludes.empty())
-continue;
-
-  // Check if the hovered include matches this provider.
-  if (!HoveredInclude.match(H).empty())
-UsedSymbols.insert(Ref.Target);
-
-  // Don't look for rest of the providers once we've found a match
-  // in the main file.
-  break;
-}
+auto Provider =
+firstMatchedProvider(ConvertedMainFileIncludes, Providers);
+if (!Provider || HoveredInclude.match(*Provider).empty())
+  return;
+
+UsedSymbols.insert(Ref.Target);
   });
 
   for (const auto  : UsedSymbols)

diff  --git a/clang-tools-extra/clangd/IncludeCleaner.cpp 
b/clang-tools-extra/clangd/IncludeCleaner.cpp
index 168471a603ea4..d15dd70efdb70 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.cpp
+++ b/clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -444,5 +444,15 @@ std::vector issueIncludeCleanerDiagnostics(ParsedAST 
,
   return Result;
 }
 
+std::optional
+firstMatchedProvider(const include_cleaner::Includes ,
+ llvm::ArrayRef Providers) {
+  for (const auto  : Providers) {
+if (!Includes.match(H).empty())
+  return H;
+  }
+  // No match for this provider in the includes list.
+  return std::nullopt;
+}
 } // namespace clangd
 } // namespace clang

diff  --git a/clang-tools-extra/clangd/IncludeCleaner.h 
b/clang-tools-extra/clangd/IncludeCleaner.h
index 035142c186b80..675c05a53d5f8 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.h
+++ b/clang-tools-extra/clangd/IncludeCleaner.h
@@ -81,6 +81,11 @@ std::string spellHeader(ParsedAST , const FileEntry 
*MainFile,
 
 std::vector
 collectMacroReferences(ParsedAST );
+
+/// Find the first provider in the list that is matched by the includes.
+std::optional
+firstMatchedProvider(const include_cleaner::Includes ,
+ llvm::ArrayRef Providers);
 } // namespace clangd
 } // namespace clang
 

diff  --git a/clang-tools-extra/clangd/XRefs.cpp 
b/clang-tools-extra/clangd/XRefs.cpp
index 23dd72d43d3bb..51a3ef894c540 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -9,13 +9,17 @@
 #include "AST.h"
 #include "FindSymbols.h"
 #include "FindTarget.h"
+#include "Headers.h"
 #include "HeuristicResolver.h"
+#include "IncludeCleaner.h"
 #include "ParsedAST.h"
 #include "Protocol.h"
 #include "Quality.h"
 #include "Selection.h"
 #include "SourceCode.h"
 #include "URI.h"
+#include "clang-include-cleaner/Analysis.h"
+#include "clang-include-cleaner/Types.h"
 #include "index/Index.h"
 #include "index/Merge.h"
 #include "index/Relation.h"
@@ -48,6 +52,7 @@
 #include "clang/Index/IndexingAction.h"
 #include "clang/Index/IndexingOptions.h"
 #include "clang/Index/USRGeneration.h"
+#include "clang/Lex/Lexer.h"
 #include "clang/Tooling/Syntax/Tokens.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
@@ -61,6 +66,7 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
+#include 
 #include 
 
 namespace clang {
@@ -1310,6 +1316,63 @@ stringifyContainerForMainFileRef(const Decl *Container) {
 return printQualifiedName(*ND);
   return {};
 }
+
+std::optional
+maybeFindIncludeReferences(ParsedAST , Position Pos,
+   URIForFile URIMainFile) {
+  const auto  = AST.getIncludeStructure().MainFileIncludes;
+  auto IncludeOnLine = llvm::find_if(Includes, [](const Inclusion ) {
+return Inc.HashLine == Pos.line;
+  });
+  if (IncludeOnLine == Includes.end())
+return 

[clang-tools-extra] 2fccca8 - [clangd] Fix build by replacing unsigned long with std::vector::size_type.

2023-03-28 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-28T14:16:50Z
New Revision: 2fccca8d743613fac4d68f7b14799a672394f64b

URL: 
https://github.com/llvm/llvm-project/commit/2fccca8d743613fac4d68f7b14799a672394f64b
DIFF: 
https://github.com/llvm/llvm-project/commit/2fccca8d743613fac4d68f7b14799a672394f64b.diff

LOG: [clangd] Fix build by replacing unsigned long with std::vector::size_type.

Added: 


Modified: 
clang-tools-extra/clangd/Hover.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index b399a12cd90c..af4fbe58b864 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -1451,7 +1451,7 @@ markup::Document HoverInfo::present() const {
 markup::Paragraph  = Output.addParagraph();
 P.appendText("provides ");
 
-const unsigned long SymbolNamesLimit = 5;
+const std::vector::size_type SymbolNamesLimit = 5;
 auto Front =
 llvm::ArrayRef(UsedSymbolNames)
 .take_front(std::min(UsedSymbolNames.size(), SymbolNamesLimit));



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 655baae - [clangd] Show used symbols on #include line hover.

2023-03-28 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-28T14:05:34Z
New Revision: 655baae2af0b805a1c3e6d6338a32de05e342357

URL: 
https://github.com/llvm/llvm-project/commit/655baae2af0b805a1c3e6d6338a32de05e342357
DIFF: 
https://github.com/llvm/llvm-project/commit/655baae2af0b805a1c3e6d6338a32de05e342357.diff

LOG: [clangd] Show used symbols on #include line hover.

Differential Revision: https://reviews.llvm.org/D146244

Added: 


Modified: 
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/Hover.h
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h
clang-tools-extra/clangd/unittests/HoverTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index 27663991a7f3c..b399a12cd90cf 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -12,6 +12,7 @@
 #include "CodeCompletionStrings.h"
 #include "Config.h"
 #include "FindTarget.h"
+#include "Headers.h"
 #include "IncludeCleaner.h"
 #include "ParsedAST.h"
 #include "Selection.h"
@@ -38,11 +39,15 @@
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/CharInfo.h"
+#include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Index/IndexSymbol.h"
 #include "clang/Tooling/Syntax/Tokens.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
@@ -52,6 +57,7 @@
 #include "llvm/Support/Format.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Support/raw_ostream.h"
+#include 
 #include 
 #include 
 #include 
@@ -1134,11 +1140,66 @@ void maybeAddSymbolProviders(ParsedAST , HoverInfo 
,
   HI.Provider = spellHeader(AST, SM.getFileEntryForID(SM.getMainFileID()), H);
 }
 
+// FIXME: similar functions are present in FindHeaders.cpp (symbolName)
+// and IncludeCleaner.cpp (getSymbolName). Introduce a name() method into
+// include_cleaner::Symbol instead.
+std::string getSymbolName(include_cleaner::Symbol Sym) {
+  std::string Name;
+  switch (Sym.kind()) {
+  case include_cleaner::Symbol::Declaration:
+if (const auto *ND = llvm::dyn_cast(()))
+  Name = ND->getDeclName().getAsString();
+break;
+  case include_cleaner::Symbol::Macro:
+Name = Sym.macro().Name->getName();
+break;
+  }
+  return Name;
+}
+
+void maybeAddUsedSymbols(ParsedAST , HoverInfo , const Inclusion ) {
+  const SourceManager  = AST.getSourceManager();
+  const auto  =
+  convertIncludes(SM, AST.getIncludeStructure().MainFileIncludes);
+  const auto  = convertIncludes(SM, llvm::ArrayRef{Inc});
+  llvm::DenseSet UsedSymbols;
+  include_cleaner::walkUsed(
+  AST.getLocalTopLevelDecls(), collectMacroReferences(AST),
+  AST.getPragmaIncludes(), SM,
+  [&](const include_cleaner::SymbolReference ,
+  llvm::ArrayRef Providers) {
+if (Ref.RT != include_cleaner::RefType::Explicit ||
+UsedSymbols.find(Ref.Target) != UsedSymbols.end())
+  return;
+
+for (const include_cleaner::Header  : Providers) {
+  auto MatchingIncludes = ConvertedMainFileIncludes.match(H);
+  // No match for this provider in the main file.
+  if (MatchingIncludes.empty())
+continue;
+
+  // Check if the hovered include matches this provider.
+  if (!HoveredInclude.match(H).empty())
+UsedSymbols.insert(Ref.Target);
+
+  // Don't look for rest of the providers once we've found a match
+  // in the main file.
+  break;
+}
+  });
+
+  for (const auto  : UsedSymbols)
+HI.UsedSymbolNames.push_back(getSymbolName(UsedSymbolDecl));
+  llvm::sort(HI.UsedSymbolNames);
+}
+
 } // namespace
 
 std::optional getHover(ParsedAST , Position Pos,
   const format::FormatStyle ,
   const SymbolIndex *Index) {
+  static constexpr trace::Metric HoverCountMetric(
+  "hover", trace::Metric::Counter, "case");
   PrintingPolicy PP =
   getPrintingPolicy(AST.getASTContext().getPrintingPolicy());
   const SourceManager  = AST.getSourceManager();
@@ -1157,12 +1218,14 @@ std::optional getHover(ParsedAST , 
Position Pos,
   for (const auto  : AST.getIncludeStructure().MainFileIncludes) {
 if (Inc.Resolved.empty() || Inc.HashLine != Pos.line)
   continue;
+HoverCountMetric.record(1, "include");
 HoverInfo HI;
 HI.Name = std::string(llvm::sys::path::filename(Inc.Resolved));
 // FIXME: We don't have a fitting value for Kind.
 HI.Definition =
 URIForFile::canonicalize(Inc.Resolved, AST.tuPath()).file().str();
 HI.DefinitionLanguage = "";
+

[clang-tools-extra] 481f888 - [clangd] Use expansion location for missing include diagnostics.

2023-03-27 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-27T14:26:12Z
New Revision: 481f88853685bcf604c79059e890553831588e8b

URL: 
https://github.com/llvm/llvm-project/commit/481f88853685bcf604c79059e890553831588e8b
DIFF: 
https://github.com/llvm/llvm-project/commit/481f88853685bcf604c79059e890553831588e8b.diff

LOG: [clangd] Use expansion location for missing include diagnostics.

Differential Revision: https://reviews.llvm.org/D146727

Added: 


Modified: 
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
clang-tools-extra/include-cleaner/lib/Analysis.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/IncludeCleaner.cpp 
b/clang-tools-extra/clangd/IncludeCleaner.cpp
index ab7c05eb834c0..8a433b0fe88d7 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.cpp
+++ b/clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -78,7 +78,6 @@ clangd::Range getDiagnosticRange(llvm::StringRef Code, 
unsigned HashOffset) {
   return Result;
 }
 
-
 bool isFilteredByConfig(const Config , llvm::StringRef HeaderPath) {
   // Convert the path to Unix slashes and try to match against the filter.
   llvm::SmallString<64> NormalizedPath(HeaderPath);
@@ -390,15 +389,17 @@ IncludeCleanerFindings 
computeIncludeCleanerFindings(ParsedAST ) {
 Ref.RT != include_cleaner::RefType::Explicit)
   return;
 
-auto  = AST.getTokens();
-auto SpelledForExpanded =
-Tokens.spelledForExpanded(Tokens.expandedTokens(Ref.RefLocation));
-if (!SpelledForExpanded)
-  return;
-
-auto Range = syntax::Token::range(SM, SpelledForExpanded->front(),
-  SpelledForExpanded->back());
-MissingIncludeDiagInfo DiagInfo{Ref.Target, Range, Providers};
+// We actually always want to map usages to their spellings, but
+// spelling locations can point into preamble section. Using these
+// offsets could lead into crashes in presence of stale preambles. 
Hence
+// we use "getFileLoc" instead to make sure it always points into main
+// file.
+// FIXME: Use presumed locations to map such usages back to patched
+// locations safely.
+auto Loc = SM.getFileLoc(Ref.RefLocation);
+const auto *Token = AST.getTokens().spelledTokenAt(Loc);
+MissingIncludeDiagInfo DiagInfo{Ref.Target, Token->range(SM),
+Providers};
 MissingIncludes.push_back(std::move(DiagInfo));
   });
   std::vector UnusedIncludes =

diff  --git a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp 
b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
index 69b4e07439c38..de45da02bfe87 100644
--- a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
+++ b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
@@ -178,27 +178,39 @@ TEST(IncludeCleaner, GenerateMissingHeaderDiags) {
   WithContextValue Ctx(Config::Key, std::move(Cfg));
   Annotations MainFile(R"cpp(
 #include "a.h"
+#include "all.h"
 $insert_b[[]]#include "baz.h"
 #include "dir/c.h"
-$insert_d[[]]#include "fuzz.h"
+$insert_d[[]]$insert_foo[[]]#include "fuzz.h"
 #include "header.h"
 $insert_foobar[[]]#include 
 $insert_f[[]]$insert_vector[[]]
 
-void foo() {
-  $b[[b]]();
+#define DEF(X) const Foo *X;
+#define BAZ(X) const X x
 
-  ns::$bar[[Bar]] bar;
-  bar.d();
-  $f[[f]](); 
+  void foo() {
+$b[[b]]();
 
-  // this should not be diagnosed, because it's ignored in the config
-  buzz(); 
+ns::$bar[[Bar]] bar;
+bar.d();
+$f[[f]](); 
 
-  $foobar[[foobar]]();
+// this should not be diagnosed, because it's ignored in the config
+buzz(); 
 
-  std::$vector[[vector]] v;
-})cpp");
+$foobar[[foobar]]();
+
+std::$vector[[vector]] v;
+
+int var = $FOO[[FOO]];
+
+$DEF[[DEF]](a);
+
+$BAR[[BAR]](b);
+
+BAZ($Foo[[Foo]]);
+})cpp");
 
   TestTU TU;
   TU.Filename = "foo.cpp";
@@ -225,6 +237,13 @@ TEST(IncludeCleaner, GenerateMissingHeaderDiags) {
   namespace std { class vector {}; }
   )cpp");
 
+  TU.AdditionalFiles["all.h"] = guard("#include \"foo.h\"");
+  TU.AdditionalFiles["foo.h"] = guard(R"cpp(
+#define BAR(x) Foo *x
+#define FOO 1
+struct Foo{}; 
+  )cpp");
+
   TU.Code = MainFile.code();
   ParsedAST AST = TU.build();
 
@@ -254,7 +273,23 @@ TEST(IncludeCleaner, GenerateMissingHeaderDiags) {
   Diag(MainFile.range("vector"),
"No header providing \"std::vector\" is directly included"),
   withFix(Fix(MainFile.range("insert_vector"),
-  "#include \n", "#include ");
+  "#include \n", "#include "))),
+  AllOf(Diag(MainFile.range("FOO"),
+ "No header providing \"FOO\" is directly included"),
+

[clang-tools-extra] 40e5d21 - [clangd] Fix indentation in HoverTests.cpp

2023-03-23 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-23T17:27:10Z
New Revision: 40e5d212cffd2b87f688dd441cd7c7f4084d407d

URL: 
https://github.com/llvm/llvm-project/commit/40e5d212cffd2b87f688dd441cd7c7f4084d407d
DIFF: 
https://github.com/llvm/llvm-project/commit/40e5d212cffd2b87f688dd441cd7c7f4084d407d.diff

LOG: [clangd] Fix indentation in HoverTests.cpp

Added: 


Modified: 
clang-tools-extra/clangd/unittests/HoverTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp 
b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 6ee938420403..728f5444014d 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -2892,50 +2892,50 @@ TEST(Hover, Providers) {
 const char *Code;
 const std::function ExpectedBuilder;
   } Cases[] = {{R"cpp(
-struct Foo {}; 
-Foo F = Fo^o{};
-  )cpp",
+  struct Foo {}; 
+  Foo F = Fo^o{};
+)cpp",
 [](HoverInfo ) { HI.Provider = ""; }},
{R"cpp(
-#include "foo.h"   
-Foo F = Fo^o{};
-  )cpp",
+  #include "foo.h"   
+  Foo F = Fo^o{};
+)cpp",
 [](HoverInfo ) { HI.Provider = "\"foo.h\""; }},
{R"cpp(
-#include "all.h"  
-Foo F = Fo^o{};
-  )cpp",
+  #include "all.h"  
+  Foo F = Fo^o{};
+)cpp",
 [](HoverInfo ) { HI.Provider = "\"foo.h\""; }},
{R"cpp(
-#define FOO 5
-int F = ^FOO;
-  )cpp",
+  #define FOO 5
+  int F = ^FOO;
+)cpp",
 [](HoverInfo ) { HI.Provider = ""; }},
{R"cpp(
-#include "foo.h"
-int F = ^FOO;
-  )cpp",
+  #include "foo.h"
+  int F = ^FOO;
+)cpp",
 [](HoverInfo ) { HI.Provider = "\"foo.h\""; }},
{R"cpp(
-#include "all.h"
-int F = ^FOO;
-  )cpp",
+  #include "all.h"
+  int F = ^FOO;
+)cpp",
 [](HoverInfo ) { HI.Provider = "\"foo.h\""; }},
{R"cpp(
-#include "foo.h"
-Foo A;
-Foo B;
-Foo C = A ^+ B;
-  )cpp",
+  #include "foo.h"
+  Foo A;
+  Foo B;
+  Foo C = A ^+ B;
+)cpp",
 [](HoverInfo ) { HI.Provider = "\"foo.h\""; }},
// Hover selects the underlying decl of the using decl
{R"cpp(
-#include "foo.h"
-namespace ns {
-  using ::Foo;
-}
-ns::F^oo d;
-  )cpp",
+  #include "foo.h"
+  namespace ns {
+using ::Foo;
+  }
+  ns::F^oo d;
+)cpp",
 [](HoverInfo ) { HI.Provider = "\"foo.h\""; }}};
 
   for (const auto  : Cases) {
@@ -2946,10 +2946,10 @@ TEST(Hover, Providers) {
 TU.Filename = "foo.cpp";
 TU.Code = Code.code();
 TU.AdditionalFiles["foo.h"] = guard(R"cpp(
-#define FOO 1
-class Foo {};
-Foo& operator+(const Foo, 
const Foo);
-  )cpp");
+  #define FOO 1
+  class Foo {};
+  Foo& operator+(const Foo, const Foo);
+)cpp");
 TU.AdditionalFiles["all.h"] = guard("#include \"foo.h\"");
 
 auto AST = TU.build();



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 2bececb - [clangd] Add provider info on symbol hover.

2023-03-23 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-23T16:21:51Z
New Revision: 2bececb8bed1f8fcd8d54dba831ceb117717bfcc

URL: 
https://github.com/llvm/llvm-project/commit/2bececb8bed1f8fcd8d54dba831ceb117717bfcc
DIFF: 
https://github.com/llvm/llvm-project/commit/2bececb8bed1f8fcd8d54dba831ceb117717bfcc.diff

LOG: [clangd] Add provider info on symbol hover.

Differential Revision: https://reviews.llvm.org/D144976

Added: 


Modified: 
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/Hover.h
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h
clang-tools-extra/clangd/Preamble.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
clang-tools-extra/include-cleaner/lib/AnalysisInternal.h

Removed: 




diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index c5436141adbf..e240c22259f3 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -12,11 +12,16 @@
 #include "CodeCompletionStrings.h"
 #include "Config.h"
 #include "FindTarget.h"
+#include "IncludeCleaner.h"
 #include "ParsedAST.h"
 #include "Selection.h"
 #include "SourceCode.h"
+#include "clang-include-cleaner/Analysis.h"
+#include "clang-include-cleaner/Types.h"
 #include "index/SymbolCollector.h"
+#include "support/Logger.h"
 #include "support/Markup.h"
+#include "support/Trace.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/ASTTypeTraits.h"
@@ -43,11 +48,13 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
 #include 
+#include 
 
 namespace clang {
 namespace clangd {
@@ -1084,6 +1091,49 @@ const NamedDecl *pickDeclToUse(llvm::ArrayRef Candidates) {
   return Candidates.front();
 }
 
+void maybeAddSymbolProviders(ParsedAST , HoverInfo ,
+ include_cleaner::Symbol Sym) {
+  trace::Span Tracer("Hover::maybeAddSymbolProviders");
+
+  const SourceManager  = AST.getSourceManager();
+  llvm::SmallVector RankedProviders =
+  include_cleaner::headersForSymbol(Sym, SM, AST.getPragmaIncludes());
+  if (RankedProviders.empty())
+return;
+
+  std::string Result;
+  include_cleaner::Includes ConvertedIncludes =
+  convertIncludes(SM, AST.getIncludeStructure().MainFileIncludes);
+  for (const auto  : RankedProviders) {
+if (P.kind() == include_cleaner::Header::Physical &&
+P.physical() == SM.getFileEntryForID(SM.getMainFileID()))
+  // Main file ranked higher than any #include'd file
+  break;
+
+// Pick the best-ranked #include'd provider
+auto Matches = ConvertedIncludes.match(P);
+if (!Matches.empty()) {
+  Result = Matches[0]->quote();
+  break;
+}
+  }
+
+  if (!Result.empty()) {
+HI.Provider = std::move(Result);
+return;
+  }
+
+  // Pick the best-ranked non-#include'd provider
+  const auto  = RankedProviders.front();
+  if (H.kind() == include_cleaner::Header::Physical &&
+  H.physical() == SM.getFileEntryForID(SM.getMainFileID()))
+// Do not show main file as provider, otherwise we'll show provider info
+// on local variables, etc.
+return;
+
+  HI.Provider = spellHeader(AST, SM.getFileEntryForID(SM.getMainFileID()), H);
+}
+
 } // namespace
 
 std::optional getHover(ParsedAST , Position Pos,
@@ -1131,6 +1181,12 @@ std::optional getHover(ParsedAST , 
Position Pos,
   HighlightRange = Tok.range(SM).toCharRange(SM);
   if (auto M = locateMacroAt(Tok, AST.getPreprocessor())) {
 HI = getHoverContents(*M, Tok, AST);
+if (auto DefLoc = M->Info->getDefinitionLoc(); DefLoc.isValid()) {
+  include_cleaner::Macro IncludeCleanerMacro{
+  AST.getPreprocessor().getIdentifierInfo(Tok.text(SM)), DefLoc};
+  maybeAddSymbolProviders(AST, *HI,
+  
include_cleaner::Symbol{IncludeCleanerMacro});
+}
 break;
   }
 } else if (Tok.kind() == tok::kw_auto || Tok.kind() == tok::kw_decltype) {
@@ -1168,6 +1224,7 @@ std::optional getHover(ParsedAST , 
Position Pos,
 if (!HI->Value)
   HI->Value = printExprValue(N, AST.getASTContext());
 maybeAddCalleeArgInfo(N, *HI, PP);
+maybeAddSymbolProviders(AST, *HI, include_cleaner::Symbol{*DeclToUse});
   } else if (const Expr *E = N->ASTNode.get()) {
 HI = getHoverContents(N, E, AST, PP, Index);
   } else if (const Attr *A = N->ASTNode.get()) {
@@ -1217,6 +1274,14 @@ markup::Document HoverInfo::present() const {
   assert(!Name.empty() && "hover triggered on a nameless symbol");
   Header.appendCode(Name);
 
+  if 

[clang-tools-extra] 2e82eb1 - Re-land [clangd] Add support for missing includes analysis.

2023-03-08 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-08T13:29:52Z
New Revision: 2e82eb1f74aa268473c9eca27c3b8ddc91917a13

URL: 
https://github.com/llvm/llvm-project/commit/2e82eb1f74aa268473c9eca27c3b8ddc91917a13
DIFF: 
https://github.com/llvm/llvm-project/commit/2e82eb1f74aa268473c9eca27c3b8ddc91917a13.diff

LOG: Re-land [clangd] Add support for missing includes analysis.

This reverts commit fd8c9ef20a9519dccd5b8178b29ed4574285d36f.

Differential Revision: https://reviews.llvm.org/D145577

Added: 


Modified: 
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/ConfigYAML.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h
clang-tools-extra/clangd/ParsedAST.cpp
clang-tools-extra/clangd/Preamble.cpp
clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
clang-tools-extra/clangd/unittests/PreambleTests.cpp
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
clang-tools-extra/include-cleaner/lib/Analysis.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Config.h 
b/clang-tools-extra/clangd/Config.h
index dffd54b01c459..ab346aab0e8ac 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -88,11 +88,12 @@ struct Config {
 bool StandardLibrary = true;
   } Index;
 
-  enum class UnusedIncludesPolicy {
-/// Diagnose unused includes.
+  enum class IncludesPolicy {
+/// Diagnose missing and unused includes.
 Strict,
 None,
-/// The same as Strict, but using the include-cleaner library.
+/// The same as Strict, but using the include-cleaner library for
+/// unused includes.
 Experiment,
   };
   /// Controls warnings and errors when parsing code.
@@ -107,11 +108,12 @@ struct Config {
   llvm::StringMap CheckOptions;
 } ClangTidy;
 
-UnusedIncludesPolicy UnusedIncludes = UnusedIncludesPolicy::None;
-
 /// Enable emitting diagnostics using stale preambles.
 bool AllowStalePreamble = false;
 
+IncludesPolicy UnusedIncludes = IncludesPolicy::None;
+IncludesPolicy MissingIncludes = IncludesPolicy::None;
+
 /// IncludeCleaner will not diagnose usages of these headers matched by
 /// these regexes.
 struct {

diff  --git a/clang-tools-extra/clangd/ConfigCompile.cpp 
b/clang-tools-extra/clangd/ConfigCompile.cpp
index 18de6e4d5c3b6..2f0ef892131ca 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -431,16 +431,16 @@ struct FragmentCompiler {
   });
 
 if (F.UnusedIncludes)
-  if (auto Val =
-  compileEnum("UnusedIncludes",
-**F.UnusedIncludes)
-  .map("Strict", Config::UnusedIncludesPolicy::Strict)
-  .map("Experiment", Config::UnusedIncludesPolicy::Experiment)
-  .map("None", Config::UnusedIncludesPolicy::None)
-  .value())
+  if (auto Val = compileEnum("UnusedIncludes",
+ **F.UnusedIncludes)
+ .map("Strict", Config::IncludesPolicy::Strict)
+ .map("Experiment", Config::IncludesPolicy::Experiment)
+ .map("None", Config::IncludesPolicy::None)
+ .value())
 Out.Apply.push_back([Val](const Params &, Config ) {
   C.Diagnostics.UnusedIncludes = *Val;
 });
+
 if (F.AllowStalePreamble) {
   if (auto Val = F.AllowStalePreamble)
 Out.Apply.push_back([Val](const Params &, Config ) {
@@ -448,6 +448,16 @@ struct FragmentCompiler {
 });
 }
 
+if (F.MissingIncludes)
+  if (auto Val = compileEnum("MissingIncludes",
+ **F.MissingIncludes)
+ .map("Strict", Config::IncludesPolicy::Strict)
+ .map("None", Config::IncludesPolicy::None)
+ .value())
+Out.Apply.push_back([Val](const Params &, Config ) {
+  C.Diagnostics.MissingIncludes = *Val;
+});
+
 compile(std::move(F.Includes));
 compile(std::move(F.ClangTidy));
   }

diff  --git a/clang-tools-extra/clangd/ConfigFragment.h 
b/clang-tools-extra/clangd/ConfigFragment.h
index a5597596196fa..956e8a8599446 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -221,7 +221,7 @@ struct Fragment {
 /// This often has other advantages, such as skipping some analysis.
 std::vector> Suppress;
 
-/// Controls how clangd will correct "unnecessary #include 

[clang-tools-extra] fd8c9ef - Revert "Re-land [clangd] Add support for missing includes analysis."

2023-03-08 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-08T12:34:15Z
New Revision: fd8c9ef20a9519dccd5b8178b29ed4574285d36f

URL: 
https://github.com/llvm/llvm-project/commit/fd8c9ef20a9519dccd5b8178b29ed4574285d36f
DIFF: 
https://github.com/llvm/llvm-project/commit/fd8c9ef20a9519dccd5b8178b29ed4574285d36f.diff

LOG: Revert "Re-land [clangd] Add support for missing includes analysis."

This reverts commit 85a5c17b66768353b7fff717904e42805bb6a547.

Added: 


Modified: 
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/ConfigYAML.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h
clang-tools-extra/clangd/ParsedAST.cpp
clang-tools-extra/clangd/Preamble.cpp
clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
clang-tools-extra/clangd/unittests/PreambleTests.cpp
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
clang-tools-extra/include-cleaner/lib/Analysis.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Config.h 
b/clang-tools-extra/clangd/Config.h
index ab346aab0e8ac..dffd54b01c459 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -88,12 +88,11 @@ struct Config {
 bool StandardLibrary = true;
   } Index;
 
-  enum class IncludesPolicy {
-/// Diagnose missing and unused includes.
+  enum class UnusedIncludesPolicy {
+/// Diagnose unused includes.
 Strict,
 None,
-/// The same as Strict, but using the include-cleaner library for
-/// unused includes.
+/// The same as Strict, but using the include-cleaner library.
 Experiment,
   };
   /// Controls warnings and errors when parsing code.
@@ -108,12 +107,11 @@ struct Config {
   llvm::StringMap CheckOptions;
 } ClangTidy;
 
+UnusedIncludesPolicy UnusedIncludes = UnusedIncludesPolicy::None;
+
 /// Enable emitting diagnostics using stale preambles.
 bool AllowStalePreamble = false;
 
-IncludesPolicy UnusedIncludes = IncludesPolicy::None;
-IncludesPolicy MissingIncludes = IncludesPolicy::None;
-
 /// IncludeCleaner will not diagnose usages of these headers matched by
 /// these regexes.
 struct {

diff  --git a/clang-tools-extra/clangd/ConfigCompile.cpp 
b/clang-tools-extra/clangd/ConfigCompile.cpp
index 2f0ef892131ca..18de6e4d5c3b6 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -431,16 +431,16 @@ struct FragmentCompiler {
   });
 
 if (F.UnusedIncludes)
-  if (auto Val = compileEnum("UnusedIncludes",
- **F.UnusedIncludes)
- .map("Strict", Config::IncludesPolicy::Strict)
- .map("Experiment", Config::IncludesPolicy::Experiment)
- .map("None", Config::IncludesPolicy::None)
- .value())
+  if (auto Val =
+  compileEnum("UnusedIncludes",
+**F.UnusedIncludes)
+  .map("Strict", Config::UnusedIncludesPolicy::Strict)
+  .map("Experiment", Config::UnusedIncludesPolicy::Experiment)
+  .map("None", Config::UnusedIncludesPolicy::None)
+  .value())
 Out.Apply.push_back([Val](const Params &, Config ) {
   C.Diagnostics.UnusedIncludes = *Val;
 });
-
 if (F.AllowStalePreamble) {
   if (auto Val = F.AllowStalePreamble)
 Out.Apply.push_back([Val](const Params &, Config ) {
@@ -448,16 +448,6 @@ struct FragmentCompiler {
 });
 }
 
-if (F.MissingIncludes)
-  if (auto Val = compileEnum("MissingIncludes",
- **F.MissingIncludes)
- .map("Strict", Config::IncludesPolicy::Strict)
- .map("None", Config::IncludesPolicy::None)
- .value())
-Out.Apply.push_back([Val](const Params &, Config ) {
-  C.Diagnostics.MissingIncludes = *Val;
-});
-
 compile(std::move(F.Includes));
 compile(std::move(F.ClangTidy));
   }

diff  --git a/clang-tools-extra/clangd/ConfigFragment.h 
b/clang-tools-extra/clangd/ConfigFragment.h
index 956e8a8599446..a5597596196fa 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -221,7 +221,7 @@ struct Fragment {
 /// This often has other advantages, such as skipping some analysis.
 std::vector> Suppress;
 
-/// Controls how clangd will correct "unnecessary" #include directives.
+/// Controls how clangd will 

[clang-tools-extra] 46447e0 - Revert "Revert "Re-land [clangd] Add support for missing includes analysis.""

2023-03-08 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-08T12:27:17Z
New Revision: 46447e0ba2e31f4da55c59794caa3200c990c535

URL: 
https://github.com/llvm/llvm-project/commit/46447e0ba2e31f4da55c59794caa3200c990c535
DIFF: 
https://github.com/llvm/llvm-project/commit/46447e0ba2e31f4da55c59794caa3200c990c535.diff

LOG: Revert "Revert "Re-land [clangd] Add support for missing includes 
analysis.""

This reverts commit 9814b4d07f614e83e7a244f74fc562f2b5cc9b15.

Added: 


Modified: 
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/ConfigYAML.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h
clang-tools-extra/clangd/ParsedAST.cpp
clang-tools-extra/clangd/Preamble.cpp
clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
clang-tools-extra/clangd/unittests/PreambleTests.cpp
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
clang-tools-extra/include-cleaner/lib/Analysis.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Config.h 
b/clang-tools-extra/clangd/Config.h
index dffd54b01c459..ab346aab0e8ac 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -88,11 +88,12 @@ struct Config {
 bool StandardLibrary = true;
   } Index;
 
-  enum class UnusedIncludesPolicy {
-/// Diagnose unused includes.
+  enum class IncludesPolicy {
+/// Diagnose missing and unused includes.
 Strict,
 None,
-/// The same as Strict, but using the include-cleaner library.
+/// The same as Strict, but using the include-cleaner library for
+/// unused includes.
 Experiment,
   };
   /// Controls warnings and errors when parsing code.
@@ -107,11 +108,12 @@ struct Config {
   llvm::StringMap CheckOptions;
 } ClangTidy;
 
-UnusedIncludesPolicy UnusedIncludes = UnusedIncludesPolicy::None;
-
 /// Enable emitting diagnostics using stale preambles.
 bool AllowStalePreamble = false;
 
+IncludesPolicy UnusedIncludes = IncludesPolicy::None;
+IncludesPolicy MissingIncludes = IncludesPolicy::None;
+
 /// IncludeCleaner will not diagnose usages of these headers matched by
 /// these regexes.
 struct {

diff  --git a/clang-tools-extra/clangd/ConfigCompile.cpp 
b/clang-tools-extra/clangd/ConfigCompile.cpp
index 18de6e4d5c3b6..2f0ef892131ca 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -431,16 +431,16 @@ struct FragmentCompiler {
   });
 
 if (F.UnusedIncludes)
-  if (auto Val =
-  compileEnum("UnusedIncludes",
-**F.UnusedIncludes)
-  .map("Strict", Config::UnusedIncludesPolicy::Strict)
-  .map("Experiment", Config::UnusedIncludesPolicy::Experiment)
-  .map("None", Config::UnusedIncludesPolicy::None)
-  .value())
+  if (auto Val = compileEnum("UnusedIncludes",
+ **F.UnusedIncludes)
+ .map("Strict", Config::IncludesPolicy::Strict)
+ .map("Experiment", Config::IncludesPolicy::Experiment)
+ .map("None", Config::IncludesPolicy::None)
+ .value())
 Out.Apply.push_back([Val](const Params &, Config ) {
   C.Diagnostics.UnusedIncludes = *Val;
 });
+
 if (F.AllowStalePreamble) {
   if (auto Val = F.AllowStalePreamble)
 Out.Apply.push_back([Val](const Params &, Config ) {
@@ -448,6 +448,16 @@ struct FragmentCompiler {
 });
 }
 
+if (F.MissingIncludes)
+  if (auto Val = compileEnum("MissingIncludes",
+ **F.MissingIncludes)
+ .map("Strict", Config::IncludesPolicy::Strict)
+ .map("None", Config::IncludesPolicy::None)
+ .value())
+Out.Apply.push_back([Val](const Params &, Config ) {
+  C.Diagnostics.MissingIncludes = *Val;
+});
+
 compile(std::move(F.Includes));
 compile(std::move(F.ClangTidy));
   }

diff  --git a/clang-tools-extra/clangd/ConfigFragment.h 
b/clang-tools-extra/clangd/ConfigFragment.h
index a5597596196fa..956e8a8599446 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -221,7 +221,7 @@ struct Fragment {
 /// This often has other advantages, such as skipping some analysis.
 std::vector> Suppress;
 
-/// Controls how clangd will correct "unnecessary #include directives.
+/// Controls how clangd 

[clang-tools-extra] df92d79 - Revert "Re-land [clangd] Add support for missing includes analysis."

2023-03-08 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-08T12:29:43Z
New Revision: df92d7911b9ce0221ebf60a937da3e9101150bc1

URL: 
https://github.com/llvm/llvm-project/commit/df92d7911b9ce0221ebf60a937da3e9101150bc1
DIFF: 
https://github.com/llvm/llvm-project/commit/df92d7911b9ce0221ebf60a937da3e9101150bc1.diff

LOG: Revert "Re-land [clangd] Add support for missing includes analysis."

This reverts commit 7bd56ddaeeb578331d3dfc0c4a2fe2727d0d1861.

Added: 


Modified: 
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp 
b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
index 85ac00a89e5c..2e18c18a2662 100644
--- a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
+++ b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
@@ -461,7 +461,7 @@ TEST(IncludeCleaner, GenerateMissingHeaderDiags) {
   Config Cfg;
   Cfg.Diagnostics.MissingIncludes = Config::IncludesPolicy::Strict;
   Cfg.Diagnostics.Includes.IgnoreHeader = {[](llvm::StringRef Header) {
-return Header.ends_with("buzz.h");
+return Header == testPath("buzz.h", llvm::sys::path::Style::posix);
   }};
   WithContextValue Ctx(Config::Key, std::move(Cfg));
   Annotations MainFile(R"cpp(



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 9814b4d - Revert "Re-land [clangd] Add support for missing includes analysis."

2023-03-08 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-08T12:24:51Z
New Revision: 9814b4d07f614e83e7a244f74fc562f2b5cc9b15

URL: 
https://github.com/llvm/llvm-project/commit/9814b4d07f614e83e7a244f74fc562f2b5cc9b15
DIFF: 
https://github.com/llvm/llvm-project/commit/9814b4d07f614e83e7a244f74fc562f2b5cc9b15.diff

LOG: Revert "Re-land [clangd] Add support for missing includes analysis."

This reverts commit 85a5c17b66768353b7fff717904e42805bb6a547.

Added: 


Modified: 
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/ConfigYAML.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h
clang-tools-extra/clangd/ParsedAST.cpp
clang-tools-extra/clangd/Preamble.cpp
clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
clang-tools-extra/clangd/unittests/PreambleTests.cpp
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
clang-tools-extra/include-cleaner/lib/Analysis.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Config.h 
b/clang-tools-extra/clangd/Config.h
index ab346aab0e8ac..dffd54b01c459 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -88,12 +88,11 @@ struct Config {
 bool StandardLibrary = true;
   } Index;
 
-  enum class IncludesPolicy {
-/// Diagnose missing and unused includes.
+  enum class UnusedIncludesPolicy {
+/// Diagnose unused includes.
 Strict,
 None,
-/// The same as Strict, but using the include-cleaner library for
-/// unused includes.
+/// The same as Strict, but using the include-cleaner library.
 Experiment,
   };
   /// Controls warnings and errors when parsing code.
@@ -108,12 +107,11 @@ struct Config {
   llvm::StringMap CheckOptions;
 } ClangTidy;
 
+UnusedIncludesPolicy UnusedIncludes = UnusedIncludesPolicy::None;
+
 /// Enable emitting diagnostics using stale preambles.
 bool AllowStalePreamble = false;
 
-IncludesPolicy UnusedIncludes = IncludesPolicy::None;
-IncludesPolicy MissingIncludes = IncludesPolicy::None;
-
 /// IncludeCleaner will not diagnose usages of these headers matched by
 /// these regexes.
 struct {

diff  --git a/clang-tools-extra/clangd/ConfigCompile.cpp 
b/clang-tools-extra/clangd/ConfigCompile.cpp
index 2f0ef892131ca..18de6e4d5c3b6 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -431,16 +431,16 @@ struct FragmentCompiler {
   });
 
 if (F.UnusedIncludes)
-  if (auto Val = compileEnum("UnusedIncludes",
- **F.UnusedIncludes)
- .map("Strict", Config::IncludesPolicy::Strict)
- .map("Experiment", Config::IncludesPolicy::Experiment)
- .map("None", Config::IncludesPolicy::None)
- .value())
+  if (auto Val =
+  compileEnum("UnusedIncludes",
+**F.UnusedIncludes)
+  .map("Strict", Config::UnusedIncludesPolicy::Strict)
+  .map("Experiment", Config::UnusedIncludesPolicy::Experiment)
+  .map("None", Config::UnusedIncludesPolicy::None)
+  .value())
 Out.Apply.push_back([Val](const Params &, Config ) {
   C.Diagnostics.UnusedIncludes = *Val;
 });
-
 if (F.AllowStalePreamble) {
   if (auto Val = F.AllowStalePreamble)
 Out.Apply.push_back([Val](const Params &, Config ) {
@@ -448,16 +448,6 @@ struct FragmentCompiler {
 });
 }
 
-if (F.MissingIncludes)
-  if (auto Val = compileEnum("MissingIncludes",
- **F.MissingIncludes)
- .map("Strict", Config::IncludesPolicy::Strict)
- .map("None", Config::IncludesPolicy::None)
- .value())
-Out.Apply.push_back([Val](const Params &, Config ) {
-  C.Diagnostics.MissingIncludes = *Val;
-});
-
 compile(std::move(F.Includes));
 compile(std::move(F.ClangTidy));
   }

diff  --git a/clang-tools-extra/clangd/ConfigFragment.h 
b/clang-tools-extra/clangd/ConfigFragment.h
index 956e8a8599446..a5597596196fa 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -221,7 +221,7 @@ struct Fragment {
 /// This often has other advantages, such as skipping some analysis.
 std::vector> Suppress;
 
-/// Controls how clangd will correct "unnecessary" #include directives.
+/// Controls how clangd will 

[clang-tools-extra] 7bd56dd - Re-land [clangd] Add support for missing includes analysis.

2023-03-08 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-08T12:19:17Z
New Revision: 7bd56ddaeeb578331d3dfc0c4a2fe2727d0d1861

URL: 
https://github.com/llvm/llvm-project/commit/7bd56ddaeeb578331d3dfc0c4a2fe2727d0d1861
DIFF: 
https://github.com/llvm/llvm-project/commit/7bd56ddaeeb578331d3dfc0c4a2fe2727d0d1861.diff

LOG: Re-land [clangd] Add support for missing includes analysis.

This reverts commit 2eb5ac99a76dbbf8ac68c538211fabeaa5ac0bfd.

Differential Revision: https://reviews.llvm.org/D145576

Added: 


Modified: 
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp 
b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
index 2e18c18a2662..85ac00a89e5c 100644
--- a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
+++ b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
@@ -461,7 +461,7 @@ TEST(IncludeCleaner, GenerateMissingHeaderDiags) {
   Config Cfg;
   Cfg.Diagnostics.MissingIncludes = Config::IncludesPolicy::Strict;
   Cfg.Diagnostics.Includes.IgnoreHeader = {[](llvm::StringRef Header) {
-return Header == testPath("buzz.h", llvm::sys::path::Style::posix);
+return Header.ends_with("buzz.h");
   }};
   WithContextValue Ctx(Config::Key, std::move(Cfg));
   Annotations MainFile(R"cpp(



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 85a5c17 - Re-land [clangd] Add support for missing includes analysis.

2023-03-08 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-08T11:02:12Z
New Revision: 85a5c17b66768353b7fff717904e42805bb6a547

URL: 
https://github.com/llvm/llvm-project/commit/85a5c17b66768353b7fff717904e42805bb6a547
DIFF: 
https://github.com/llvm/llvm-project/commit/85a5c17b66768353b7fff717904e42805bb6a547.diff

LOG: Re-land [clangd] Add support for missing includes analysis.

This reverts commit 2eb5ac99a76dbbf8ac68c538211fabeaa5ac0bfd.

Added: 


Modified: 
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/ConfigYAML.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h
clang-tools-extra/clangd/ParsedAST.cpp
clang-tools-extra/clangd/Preamble.cpp
clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
clang-tools-extra/clangd/unittests/PreambleTests.cpp
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
clang-tools-extra/include-cleaner/lib/Analysis.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Config.h 
b/clang-tools-extra/clangd/Config.h
index dffd54b01c459..ab346aab0e8ac 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -88,11 +88,12 @@ struct Config {
 bool StandardLibrary = true;
   } Index;
 
-  enum class UnusedIncludesPolicy {
-/// Diagnose unused includes.
+  enum class IncludesPolicy {
+/// Diagnose missing and unused includes.
 Strict,
 None,
-/// The same as Strict, but using the include-cleaner library.
+/// The same as Strict, but using the include-cleaner library for
+/// unused includes.
 Experiment,
   };
   /// Controls warnings and errors when parsing code.
@@ -107,11 +108,12 @@ struct Config {
   llvm::StringMap CheckOptions;
 } ClangTidy;
 
-UnusedIncludesPolicy UnusedIncludes = UnusedIncludesPolicy::None;
-
 /// Enable emitting diagnostics using stale preambles.
 bool AllowStalePreamble = false;
 
+IncludesPolicy UnusedIncludes = IncludesPolicy::None;
+IncludesPolicy MissingIncludes = IncludesPolicy::None;
+
 /// IncludeCleaner will not diagnose usages of these headers matched by
 /// these regexes.
 struct {

diff  --git a/clang-tools-extra/clangd/ConfigCompile.cpp 
b/clang-tools-extra/clangd/ConfigCompile.cpp
index 18de6e4d5c3b6..2f0ef892131ca 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -431,16 +431,16 @@ struct FragmentCompiler {
   });
 
 if (F.UnusedIncludes)
-  if (auto Val =
-  compileEnum("UnusedIncludes",
-**F.UnusedIncludes)
-  .map("Strict", Config::UnusedIncludesPolicy::Strict)
-  .map("Experiment", Config::UnusedIncludesPolicy::Experiment)
-  .map("None", Config::UnusedIncludesPolicy::None)
-  .value())
+  if (auto Val = compileEnum("UnusedIncludes",
+ **F.UnusedIncludes)
+ .map("Strict", Config::IncludesPolicy::Strict)
+ .map("Experiment", Config::IncludesPolicy::Experiment)
+ .map("None", Config::IncludesPolicy::None)
+ .value())
 Out.Apply.push_back([Val](const Params &, Config ) {
   C.Diagnostics.UnusedIncludes = *Val;
 });
+
 if (F.AllowStalePreamble) {
   if (auto Val = F.AllowStalePreamble)
 Out.Apply.push_back([Val](const Params &, Config ) {
@@ -448,6 +448,16 @@ struct FragmentCompiler {
 });
 }
 
+if (F.MissingIncludes)
+  if (auto Val = compileEnum("MissingIncludes",
+ **F.MissingIncludes)
+ .map("Strict", Config::IncludesPolicy::Strict)
+ .map("None", Config::IncludesPolicy::None)
+ .value())
+Out.Apply.push_back([Val](const Params &, Config ) {
+  C.Diagnostics.MissingIncludes = *Val;
+});
+
 compile(std::move(F.Includes));
 compile(std::move(F.ClangTidy));
   }

diff  --git a/clang-tools-extra/clangd/ConfigFragment.h 
b/clang-tools-extra/clangd/ConfigFragment.h
index a5597596196fa..956e8a8599446 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -221,7 +221,7 @@ struct Fragment {
 /// This often has other advantages, such as skipping some analysis.
 std::vector> Suppress;
 
-/// Controls how clangd will correct "unnecessary #include directives.
+/// Controls how clangd will correct 

[clang-tools-extra] 38b9fb5 - [clangd] Add support for missing includes analysis.

2023-03-07 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-03-07T16:07:19Z
New Revision: 38b9fb5a129db3e086610d53b534833273c5b4d0

URL: 
https://github.com/llvm/llvm-project/commit/38b9fb5a129db3e086610d53b534833273c5b4d0
DIFF: 
https://github.com/llvm/llvm-project/commit/38b9fb5a129db3e086610d53b534833273c5b4d0.diff

LOG: [clangd] Add support for missing includes analysis.

Differential Revision: https://reviews.llvm.org/D143496

Added: 


Modified: 
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/ConfigYAML.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/IncludeCleaner.h
clang-tools-extra/clangd/ParsedAST.cpp
clang-tools-extra/clangd/Preamble.cpp
clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
clang-tools-extra/clangd/unittests/PreambleTests.cpp
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
clang-tools-extra/include-cleaner/lib/Analysis.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Config.h 
b/clang-tools-extra/clangd/Config.h
index dffd54b01c459..ab346aab0e8ac 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -88,11 +88,12 @@ struct Config {
 bool StandardLibrary = true;
   } Index;
 
-  enum class UnusedIncludesPolicy {
-/// Diagnose unused includes.
+  enum class IncludesPolicy {
+/// Diagnose missing and unused includes.
 Strict,
 None,
-/// The same as Strict, but using the include-cleaner library.
+/// The same as Strict, but using the include-cleaner library for
+/// unused includes.
 Experiment,
   };
   /// Controls warnings and errors when parsing code.
@@ -107,11 +108,12 @@ struct Config {
   llvm::StringMap CheckOptions;
 } ClangTidy;
 
-UnusedIncludesPolicy UnusedIncludes = UnusedIncludesPolicy::None;
-
 /// Enable emitting diagnostics using stale preambles.
 bool AllowStalePreamble = false;
 
+IncludesPolicy UnusedIncludes = IncludesPolicy::None;
+IncludesPolicy MissingIncludes = IncludesPolicy::None;
+
 /// IncludeCleaner will not diagnose usages of these headers matched by
 /// these regexes.
 struct {

diff  --git a/clang-tools-extra/clangd/ConfigCompile.cpp 
b/clang-tools-extra/clangd/ConfigCompile.cpp
index 18de6e4d5c3b6..2f0ef892131ca 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -431,16 +431,16 @@ struct FragmentCompiler {
   });
 
 if (F.UnusedIncludes)
-  if (auto Val =
-  compileEnum("UnusedIncludes",
-**F.UnusedIncludes)
-  .map("Strict", Config::UnusedIncludesPolicy::Strict)
-  .map("Experiment", Config::UnusedIncludesPolicy::Experiment)
-  .map("None", Config::UnusedIncludesPolicy::None)
-  .value())
+  if (auto Val = compileEnum("UnusedIncludes",
+ **F.UnusedIncludes)
+ .map("Strict", Config::IncludesPolicy::Strict)
+ .map("Experiment", Config::IncludesPolicy::Experiment)
+ .map("None", Config::IncludesPolicy::None)
+ .value())
 Out.Apply.push_back([Val](const Params &, Config ) {
   C.Diagnostics.UnusedIncludes = *Val;
 });
+
 if (F.AllowStalePreamble) {
   if (auto Val = F.AllowStalePreamble)
 Out.Apply.push_back([Val](const Params &, Config ) {
@@ -448,6 +448,16 @@ struct FragmentCompiler {
 });
 }
 
+if (F.MissingIncludes)
+  if (auto Val = compileEnum("MissingIncludes",
+ **F.MissingIncludes)
+ .map("Strict", Config::IncludesPolicy::Strict)
+ .map("None", Config::IncludesPolicy::None)
+ .value())
+Out.Apply.push_back([Val](const Params &, Config ) {
+  C.Diagnostics.MissingIncludes = *Val;
+});
+
 compile(std::move(F.Includes));
 compile(std::move(F.ClangTidy));
   }

diff  --git a/clang-tools-extra/clangd/ConfigFragment.h 
b/clang-tools-extra/clangd/ConfigFragment.h
index a5597596196fa..956e8a8599446 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -221,7 +221,7 @@ struct Fragment {
 /// This often has other advantages, such as skipping some analysis.
 std::vector> Suppress;
 
-/// Controls how clangd will correct "unnecessary #include directives.
+/// Controls how clangd will correct "unnecessary" #include 

[clang-tools-extra] e028c97 - Move the BySpelling map to IncludeStructure.

2023-02-23 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-02-23T17:11:31Z
New Revision: e028c9742897cc14c47c426893fb40f571f6fad6

URL: 
https://github.com/llvm/llvm-project/commit/e028c9742897cc14c47c426893fb40f571f6fad6
DIFF: 
https://github.com/llvm/llvm-project/commit/e028c9742897cc14c47c426893fb40f571f6fad6.diff

LOG: Move the BySpelling map to IncludeStructure.

Differential Revision: https://reviews.llvm.org/D143509

Added: 


Modified: 
clang-tools-extra/clangd/Headers.cpp
clang-tools-extra/clangd/Headers.h
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/unittests/HeadersTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Headers.cpp 
b/clang-tools-extra/clangd/Headers.cpp
index 3e5fefb07130..7000c1cbf451 100644
--- a/clang-tools-extra/clangd/Headers.cpp
+++ b/clang-tools-extra/clangd/Headers.cpp
@@ -16,6 +16,7 @@
 #include "clang/Lex/PPCallbacks.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Tooling/Inclusions/HeaderAnalysis.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Path.h"
 #include 
@@ -73,6 +74,8 @@ class IncludeStructure::RecordHeaders : public PPCallbacks,
   IDs.push_back(HID);
   }
   }
+  Out->MainFileIncludesBySpelling.try_emplace(Inc.Written)
+  .first->second.push_back(Out->MainFileIncludes.size() - 1);
 }
 
 // Record include graph (not just for main-file includes)
@@ -294,6 +297,14 @@ IncludeStructure::includeDepth(HeaderID Root) const {
   return Result;
 }
 
+llvm::SmallVector
+IncludeStructure::mainFileIncludesWithSpelling(llvm::StringRef Spelling) const 
{
+  llvm::SmallVector Includes;
+  for (auto Idx : MainFileIncludesBySpelling.lookup(Spelling))
+Includes.push_back([Idx]);
+  return Includes;
+}
+
 void IncludeInserter::addExisting(const Inclusion ) {
   IncludedHeaders.insert(Inc.Written);
   if (!Inc.Resolved.empty())

diff  --git a/clang-tools-extra/clangd/Headers.h 
b/clang-tools-extra/clangd/Headers.h
index 8a5b885a680e..a21ea851831a 100644
--- a/clang-tools-extra/clangd/Headers.h
+++ b/clang-tools-extra/clangd/Headers.h
@@ -155,13 +155,16 @@ class IncludeStructure {
 return !NonSelfContained.contains(ID);
   }
 
-  bool hasIWYUExport(HeaderID ID) const {
-return HasIWYUExport.contains(ID);
-  }
+  bool hasIWYUExport(HeaderID ID) const { return HasIWYUExport.contains(ID); }
 
   // Return all transitively reachable files.
   llvm::ArrayRef allHeaders() const { return RealPathNames; }
 
+  // Returns includes inside the main file with the given spelling.
+  // Spelling should include brackets or quotes, e.g. .
+  llvm::SmallVector
+  mainFileIncludesWithSpelling(llvm::StringRef Spelling) const;
+
   // Return all transitively reachable files, and their minimum include depth.
   // All transitive includes (absolute paths), with their minimum include 
depth.
   // Root --> 0, #included file --> 1, etc.
@@ -202,6 +205,10 @@ class IncludeStructure {
   // Contains a set of headers that have either "IWYU pragma: export" or "IWYU
   // pragma: begin_exports".
   llvm::DenseSet HasIWYUExport;
+
+  // Maps written includes to indices in MainFileInclude for easier lookup by
+  // spelling.
+  llvm::StringMap> MainFileIncludesBySpelling;
 };
 
 // Calculates insertion edit for including a new header in a file.

diff  --git a/clang-tools-extra/clangd/IncludeCleaner.cpp 
b/clang-tools-extra/clangd/IncludeCleaner.cpp
index 5a7df2fc33f6..d9804abd82ee 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.cpp
+++ b/clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -85,7 +85,7 @@ class ReferencedLocationCrawler
 // Using templateName case is handled by the override TraverseTemplateName.
 if (TST->getTemplateName().getKind() == TemplateName::UsingTemplate)
   return true;
-add(TST->getAsCXXRecordDecl());  // Specialization
+add(TST->getAsCXXRecordDecl()); // Specialization
 return true;
   }
 
@@ -474,22 +474,16 @@ std::vector 
computeUnusedIncludes(ParsedAST ) {
   translateToHeaderIDs(ReferencedFiles, AST.getIncludeStructure(), SM);
   return getUnused(AST, ReferencedHeaders, ReferencedFiles.SpelledUmbrellas);
 }
-std::vector computeUnusedIncludesExperimental(ParsedAST 
) {
-   const auto  = AST.getSourceManager();
-   const auto  = AST.getIncludeStructure();
-   // FIXME: this map should probably be in IncludeStructure.
-   llvm::StringMap> BySpelling;
-   for (const auto  : Includes.MainFileIncludes) {
-if (Inc.HeaderID)
-  BySpelling.try_emplace(Inc.Written)
-  .first->second.push_back(
-  static_cast(*Inc.HeaderID));
-   }
-   // FIXME: !!this is a hacky way to collect macro references.
-   std::vector Macros;
-auto& PP = AST.getPreprocessor();
-   for (const syntax::Token  :
-AST.getTokens().spelledTokens(SM.getMainFileID())) {
+std::vector

[clang] e74f9e7 - [include-mapping] Parse zombie_names.html into a removed symbols map.

2023-01-20 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-01-20T08:53:31Z
New Revision: e74f9e7885078e7c847b2672a70b6743731aa53a

URL: 
https://github.com/llvm/llvm-project/commit/e74f9e7885078e7c847b2672a70b6743731aa53a
DIFF: 
https://github.com/llvm/llvm-project/commit/e74f9e7885078e7c847b2672a70b6743731aa53a.diff

LOG: [include-mapping] Parse zombie_names.html into a removed symbols map.

Differential Revision: https://reviews.llvm.org/D141855

Added: 


Modified: 
clang/tools/include-mapping/gen_std.py

Removed: 




diff  --git a/clang/tools/include-mapping/gen_std.py 
b/clang/tools/include-mapping/gen_std.py
index f494ff0b88679..db70771e0f52b 100755
--- a/clang/tools/include-mapping/gen_std.py
+++ b/clang/tools/include-mapping/gen_std.py
@@ -28,9 +28,11 @@
  get a "cppreference/reference" directory.
   4. Run the command:
// Generate C++ symbols
-   python3 gen_std.py -cppreference cppreference/reference -language=cpp > 
StdSymbolMap.inc
+   python3 gen_std.py -cppreference cppreference/reference -symbols=cpp > 
StdSymbolMap.inc
+   // Generate C++ removed symbols
+   python3 gen_std.py -cppreference cppreference/reference 
-symbols=cpp_removed > RemovedSymbolMap.inc
// Generate C symbols
-   python3 gen_std.py -cppreference cppreference/reference -language=c > 
CSymbolMap.inc
+   python3 gen_std.py -cppreference cppreference/reference -symbols=c > 
CSymbolMap.inc
 """
 
 
@@ -60,16 +62,16 @@ def ParseArg():
   help='path to the cppreference offline HTML directory',
   required=True
  )
-  parser.add_argument('-language',
+  parser.add_argument('-symbols',
   default='cpp',
-  help='Generate c or cpp symbols',
-  required=True)
+  help='Generate c or cpp (removed) symbols. One of {cpp, 
c, cpp_removed}.',
+  required=True) 
   return parser.parse_args()
 
 
 def main():
   args = ParseArg()
-  if args.language == 'cpp':
+  if args.symbols == 'cpp':
 page_root = os.path.join(args.cppreference, "en", "cpp")
 symbol_index_root = os.path.join(page_root, "symbol_index")
 parse_pages =  [
@@ -87,22 +89,26 @@ def main():
   (symbol_index_root, "regex_constants.html", "std::regex_constants::"),
   (symbol_index_root, "this_thread.html", "std::this_thread::"),
 ]
-  elif args.language == 'c':
+  elif args.symbols == 'cpp_removed':
+page_root = os.path.join(args.cppreference, "en", "cpp")
+symbol_index_root = os.path.join(page_root, "symbol_index")
+parse_pages = [(symbol_index_root, "zombie_names.html", "std::")]
+  elif args.symbols == 'c':
 page_root = os.path.join(args.cppreference, "en", "c")
 symbol_index_root = page_root
-parse_pages = [(page_root, "index.html", None)]
-
+parse_pages = [(page_root, "index.html", None)]  
+
   if not os.path.exists(symbol_index_root):
 exit("Path %s doesn't exist!" % symbol_index_root)
 
   symbols = cppreference_parser.GetSymbols(parse_pages)
-
+  
   # We don't have version information from the unzipped offline HTML files.
   # so we use the modified time of the symbol_index.html as the version.
   index_page_path = os.path.join(page_root, "index.html")
   cppreference_modified_date = datetime.datetime.fromtimestamp(
 os.stat(index_page_path).st_mtime).strftime('%Y-%m-%d')
-  print(CODE_PREFIX % (args.language.upper(), cppreference_modified_date))
+  print(CODE_PREFIX % (args.symbols.upper(), cppreference_modified_date))
   for symbol in symbols:
 if len(symbol.headers) == 1:
   # SYMBOL(unqualified_name, namespace, header)



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 0aaeb25 - [include-mapping] Fix gen_std.py test

2023-01-18 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-01-18T13:07:41Z
New Revision: 0aaeb25525ecbc667a9029a4be0d87085392954a

URL: 
https://github.com/llvm/llvm-project/commit/0aaeb25525ecbc667a9029a4be0d87085392954a
DIFF: 
https://github.com/llvm/llvm-project/commit/0aaeb25525ecbc667a9029a4be0d87085392954a.diff

LOG: [include-mapping] Fix gen_std.py test

Differential Revision: https://reviews.llvm.org/D141944

Added: 


Modified: 
clang/tools/include-mapping/test.py

Removed: 




diff  --git a/clang/tools/include-mapping/test.py 
b/clang/tools/include-mapping/test.py
index 9fad952b2e97c..507e462e75273 100755
--- a/clang/tools/include-mapping/test.py
+++ b/clang/tools/include-mapping/test.py
@@ -24,11 +24,11 @@ def testParseIndexPage(self):
 
 actual = _ParseIndexPage(html)
 expected = [
-  ("abs", "abs.html", True),
-  ("abs", "complex/abs.html", True),
-  ("acos", "acos.html", False),
-  ("acosh", "acosh.html", False),
-  ("as_bytes", "as_bytes.html", False),
+  ("abs", "abs.html", 'int'),
+  ("abs", "complex/abs.html", 'std::complex'),
+  ("acos", "acos.html", None),
+  ("acosh", "acosh.html", None),
+  ("as_bytes", "as_bytes.html", None),
 ]
 self.assertEqual(len(actual), len(expected))
 for i in range(0, len(actual)):



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] ed00101 - [include-mapping] Print an error message in case the symbol index points to a non-existent page.

2023-01-12 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-01-12T15:59:32Z
New Revision: ed001018a02b3d8da699317cad7f7727d126f01d

URL: 
https://github.com/llvm/llvm-project/commit/ed001018a02b3d8da699317cad7f7727d126f01d
DIFF: 
https://github.com/llvm/llvm-project/commit/ed001018a02b3d8da699317cad7f7727d126f01d.diff

LOG: [include-mapping] Print an error message in case the symbol index points 
to a non-existent page.

Fix: https://github.com/llvm/llvm-project/issues/59610
Differential Revision: https://reviews.llvm.org/D141611

Added: 


Modified: 
clang/tools/include-mapping/cppreference_parser.py

Removed: 




diff  --git a/clang/tools/include-mapping/cppreference_parser.py 
b/clang/tools/include-mapping/cppreference_parser.py
index 137d310491bd1..759269bffaa96 100644
--- a/clang/tools/include-mapping/cppreference_parser.py
+++ b/clang/tools/include-mapping/cppreference_parser.py
@@ -145,6 +145,9 @@ def _GetSymbols(pool, root_dir, index_page_name, namespace, 
variants_to_accept):
   if os.path.isfile(path):
 results.append((symbol_name,
   pool.apply_async(_ReadSymbolPage, (path, symbol_name
+  else:
+sys.stderr.write("Discarding information for symbol: %s. Page %s does 
not exist.\n" 
+  % (symbol_name, path))
 
 # Build map from symbol name to a set of headers.
 symbol_headers = collections.defaultdict(set)



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 301123c - [include-mapping] Fix parsing of html_book_20190607.zip (https://en.cppreference.com/w/File:html_book_20190607.zip). Skip entries that have been added to the index (C++20 symbols), b

2023-01-12 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-01-12T09:48:27Z
New Revision: 301123c7a8b5f5dd415e336ff933576279b0e868

URL: 
https://github.com/llvm/llvm-project/commit/301123c7a8b5f5dd415e336ff933576279b0e868
DIFF: 
https://github.com/llvm/llvm-project/commit/301123c7a8b5f5dd415e336ff933576279b0e868.diff

LOG: [include-mapping] Fix parsing of html_book_20190607.zip 
(https://en.cppreference.com/w/File:html_book_20190607.zip). Skip entries that 
have been added to the index (C++20 symbols), but the corresponding pages for 
which have not been created yet.

Differential Revision: https://reviews.llvm.org/D141509

Added: 


Modified: 
clang/tools/include-mapping/cppreference_parser.py

Removed: 




diff  --git a/clang/tools/include-mapping/cppreference_parser.py 
b/clang/tools/include-mapping/cppreference_parser.py
index e56c8a5f1331a..137d310491bd1 100644
--- a/clang/tools/include-mapping/cppreference_parser.py
+++ b/clang/tools/include-mapping/cppreference_parser.py
@@ -142,7 +142,8 @@ def _GetSymbols(pool, root_dir, index_page_name, namespace, 
variants_to_accept):
   if variant and variant not in variants_for_symbol:
 continue
   path = os.path.join(root_dir, symbol_page_path)
-  results.append((symbol_name,
+  if os.path.isfile(path):
+results.append((symbol_name,
   pool.apply_async(_ReadSymbolPage, (path, symbol_name
 
 # Build map from symbol name to a set of headers.



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 83c5040 - [include-mapping] Fix the instructions for running stdlib recognizer. Mention python command explicitly. Remove angle brackets.

2023-01-11 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-01-11T11:35:53Z
New Revision: 83c5040f6f3234a1fbf705b4aebe3ec1cf9d3bf6

URL: 
https://github.com/llvm/llvm-project/commit/83c5040f6f3234a1fbf705b4aebe3ec1cf9d3bf6
DIFF: 
https://github.com/llvm/llvm-project/commit/83c5040f6f3234a1fbf705b4aebe3ec1cf9d3bf6.diff

LOG: [include-mapping] Fix the instructions for running stdlib recognizer. 
Mention python command explicitly. Remove angle brackets.

Differential Revision: https://reviews.llvm.org/D141477

Added: 


Modified: 
clang/tools/include-mapping/gen_std.py

Removed: 




diff  --git a/clang/tools/include-mapping/gen_std.py 
b/clang/tools/include-mapping/gen_std.py
index f3dabe13471fb..f494ff0b88679 100755
--- a/clang/tools/include-mapping/gen_std.py
+++ b/clang/tools/include-mapping/gen_std.py
@@ -24,13 +24,13 @@

https://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-beautiful-soup
   2. Download cppreference offline HTML files (e.g. html_book_20181028.zip) at
https://en.cppreference.com/w/Cppreference:Archives
-  3. Unzip the zip file from step 2 to directory , you should
- get a "reference" directory in 
+  3. Unzip the zip file from step 2 (e.g., to a "cppreference" directory). You 
should
+ get a "cppreference/reference" directory.
   4. Run the command:
// Generate C++ symbols
-   gen_std.py -cppreference  -language=cpp > 
StdSymbolMap.inc
+   python3 gen_std.py -cppreference cppreference/reference -language=cpp > 
StdSymbolMap.inc
// Generate C symbols
-   gen_std.py -cppreference  -language=c > 
CSymbolMap.inc
+   python3 gen_std.py -cppreference cppreference/reference -language=c > 
CSymbolMap.inc
 """
 
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] de81dc8 - [include-cleaner] Filter template instantiations from AST roots.

2023-01-09 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2023-01-09T12:54:20Z
New Revision: de81dc8fdf2764fb14a3c70e5e845cfd7f3b366c

URL: 
https://github.com/llvm/llvm-project/commit/de81dc8fdf2764fb14a3c70e5e845cfd7f3b366c
DIFF: 
https://github.com/llvm/llvm-project/commit/de81dc8fdf2764fb14a3c70e5e845cfd7f3b366c.diff

LOG: [include-cleaner] Filter template instantiations from AST roots.

Fix: https://github.com/llvm/llvm-project/issues/59825
Differential Revision: https://reviews.llvm.org/D141271

Added: 


Modified: 
clang-tools-extra/include-cleaner/lib/Record.cpp
clang-tools-extra/include-cleaner/unittests/RecordTest.cpp

Removed: 




diff  --git a/clang-tools-extra/include-cleaner/lib/Record.cpp 
b/clang-tools-extra/include-cleaner/lib/Record.cpp
index ab5a2415cbf9..4df65959011c 100644
--- a/clang-tools-extra/include-cleaner/lib/Record.cpp
+++ b/clang-tools-extra/include-cleaner/lib/Record.cpp
@@ -12,6 +12,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclGroup.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Specifiers.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/PPCallbacks.h"
@@ -352,6 +353,14 @@ bool PragmaIncludes::isPrivate(const FileEntry *FE) const {
   return IWYUPublic.find(FE->getUniqueID()) != IWYUPublic.end();
 }
 
+namespace {
+template  bool isImplicitTemplateSpecialization(const Decl *D) {
+  if (const auto *TD = dyn_cast(D))
+return TD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation;
+  return false;
+}
+} // namespace
+
 std::unique_ptr RecordedAST::record() {
   class Recorder : public ASTConsumer {
 RecordedAST *Out;
@@ -364,7 +373,11 @@ std::unique_ptr RecordedAST::record() {
   for (Decl *D : DG) {
 if (!SM.isWrittenInMainFile(SM.getExpansionLoc(D->getLocation(
   continue;
-// FIXME: Filter out certain Obj-C and template-related decls.
+if (isImplicitTemplateSpecialization(D) ||
+isImplicitTemplateSpecialization(D) ||
+isImplicitTemplateSpecialization(D))
+  continue;
+// FIXME: Filter out certain Obj-C as well.
 Out->Roots.push_back(D);
   }
   return ASTConsumer::HandleTopLevelDecl(DG);

diff  --git a/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
index 919d6bdc0d68..cc99146c4419 100644
--- a/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
@@ -101,6 +101,29 @@ TEST_F(RecordASTTest, Macros) {
   EXPECT_THAT(Recorded.Roots, testing::ElementsAre(named("x")));
 }
 
+// Decl from template instantiation is filtered out from roots.
+TEST_F(RecordASTTest, ImplicitTemplates) {
+  Inputs.ExtraFiles["dispatch.h"] = R"cpp(
+  struct A {
+static constexpr int value = 1;
+  };
+  template 
+  int dispatch() {
+return Getter::template get();
+  }
+  )cpp";
+  Inputs.Code = R"cpp(
+  #include "dispatch.h"  
+  struct MyGetter {
+template  static int get() { return T::value; }
+  };
+  int v = dispatch();
+  )cpp";
+  auto AST = build();
+  EXPECT_THAT(Recorded.Roots,
+  testing::ElementsAre(named("MyGetter"), named("v")));
+}
+
 class RecordPPTest : public ::testing::Test {
 protected:
   TestInputs Inputs;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 81c3739 - [include-cleaner] Use expansion locations for macros.

2022-12-19 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2022-12-19T14:18:16Z
New Revision: 81c3739156fe2e98160fb4364ed78edacc293a68

URL: 
https://github.com/llvm/llvm-project/commit/81c3739156fe2e98160fb4364ed78edacc293a68
DIFF: 
https://github.com/llvm/llvm-project/commit/81c3739156fe2e98160fb4364ed78edacc293a68.diff

LOG: [include-cleaner] Use expansion locations for macros.

Use expansion locations for target symbol decls when finding headers for macros.
Fix: https://github.com/llvm/llvm-project/issues/59392
Differential Revision: https://reviews.llvm.org/D139716

Added: 


Modified: 
clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp

Removed: 




diff  --git a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp 
b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
index b9e6e29a00667..8f38c95375fc3 100644
--- a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
+++ b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
@@ -18,8 +18,7 @@ llvm::SmallVector findHeaders(const SymbolLocation 
,
   llvm::SmallVector Results;
   switch (Loc.kind()) {
   case SymbolLocation::Physical: {
-// FIXME: Handle macro locations.
-FileID FID = SM.getFileID(Loc.physical());
+FileID FID = SM.getFileID(SM.getExpansionLoc(Loc.physical()));
 const FileEntry *FE = SM.getFileEntryForID(FID);
 if (!PI) {
   return FE ? llvm::SmallVector{Header(FE)}

diff  --git a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
index d1a21ab685346..ad5961699834c 100644
--- a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -7,11 +7,17 @@
 
//===--===//
 
 #include "AnalysisInternal.h"
+#include "clang-include-cleaner/Analysis.h"
 #include "clang-include-cleaner/Record.h"
+#include "clang-include-cleaner/Types.h"
+#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/FileEntry.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Testing/TestAST.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Testing/Support/Annotations.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
@@ -31,7 +37,7 @@ class FindHeadersTest : public testing::Test {
   std::unique_ptr AST;
   FindHeadersTest() {
 Inputs.MakeAction = [this] {
-  struct Hook : public PreprocessOnlyAction {
+  struct Hook : public SyntaxOnlyAction {
   public:
 Hook(PragmaIncludes *Out) : Out(Out) {}
 bool BeginSourceFileAction(clang::CompilerInstance ) override {
@@ -153,5 +159,60 @@ TEST_F(FindHeadersTest, NonSelfContainedTraverseExporter) {
physicalHeader("exporter.h")));
 }
 
+TEST_F(FindHeadersTest, TargetIsExpandedFromMacroInHeader) {
+  struct CustomVisitor : RecursiveASTVisitor {
+const Decl *Out = nullptr;
+bool VisitNamedDecl(const NamedDecl *ND) {
+  if (ND->getName() == "FLAG_foo" || ND->getName() == "Foo") {
+EXPECT_TRUE(Out == nullptr);
+Out = ND;
+  }
+  return true;
+}
+  };
+
+  struct {
+llvm::StringRef MacroHeader;
+llvm::StringRef DeclareHeader;
+  } TestCases[] = {
+  {/*MacroHeader=*/R"cpp(
+#define DEFINE_CLASS(name) class name {};
+  )cpp",
+   /*DeclareHeader=*/R"cpp(
+#include "macro.h"
+DEFINE_CLASS(Foo)
+  )cpp"},
+  {/*MacroHeader=*/R"cpp(
+#define DEFINE_Foo class Foo {};
+  )cpp",
+   /*DeclareHeader=*/R"cpp(
+#include "macro.h"
+DEFINE_Foo
+  )cpp"},
+  {/*MacroHeader=*/R"cpp(
+#define DECLARE_FLAGS(name) extern int FLAG_##name
+  )cpp",
+   /*DeclareHeader=*/R"cpp(
+#include "macro.h"
+DECLARE_FLAGS(foo);
+  )cpp"},
+  };
+
+  for (const auto  : TestCases) {
+Inputs.Code = R"cpp(#include "declare.h")cpp";
+Inputs.ExtraFiles["declare.h"] = guard(T.DeclareHeader);
+Inputs.ExtraFiles["macro.h"] = guard(T.MacroHeader);
+buildAST();
+
+CustomVisitor Visitor;
+Visitor.TraverseDecl(AST->context().getTranslationUnitDecl());
+
+llvm::SmallVector Headers = clang::include_cleaner::findHeaders(
+Visitor.Out->getLocation(), AST->sourceManager(),
+/*PragmaIncludes=*/nullptr);
+EXPECT_THAT(Headers, UnorderedElementsAre(physicalHeader("declare.h")));
+  }
+}
+
 } // namespace
 } // namespace clang::include_cleaner



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 0e54581 - [include-cleaner] Handle dependent type members in AST.

2022-12-19 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2022-12-19T12:45:41Z
New Revision: 0e545816a9e582af29ea4b9441fea8ed376cf52a

URL: 
https://github.com/llvm/llvm-project/commit/0e545816a9e582af29ea4b9441fea8ed376cf52a
DIFF: 
https://github.com/llvm/llvm-project/commit/0e545816a9e582af29ea4b9441fea8ed376cf52a.diff

LOG: [include-cleaner] Handle dependent type members in AST.

Handles dependent type members in AST.

Fix: https://github.com/llvm/llvm-project/issues/59354
Differential Revision: https://reviews.llvm.org/D139409

Added: 


Modified: 
clang-tools-extra/include-cleaner/lib/WalkAST.cpp
clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp

Removed: 




diff  --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp 
b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 639add8f5c4be..cf2373d43389d 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -84,6 +84,10 @@ class ASTWalker : public RecursiveASTVisitor {
 report(E->getMemberLoc(), getMemberProvider(Type));
 return true;
   }
+  bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
+report(E->getMemberLoc(), getMemberProvider(E->getBaseType()));
+return true;
+  }
 
   bool VisitCXXConstructExpr(CXXConstructExpr *E) {
 report(E->getLocation(), E->getConstructor(),

diff  --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
index cb41ebb35cd58..2a2fbc438ab9b 100644
--- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -229,6 +229,13 @@ TEST(WalkAST, MemberExprs) {
   namespace ns { template struct Foo { int a; }; }
   using ns::$explicit^Foo;)cpp",
"void k(Foo b) { b.^a; }");
+  // Test the dependent-type case (CXXDependentScopeMemberExpr)
+  testWalk("template struct $explicit^Base { void method(); };",
+   "template void k(Base t) { t.^method(); }");
+  testWalk("template struct $explicit^Base { void method(); };",
+   "template void k(Base& t) { t.^method(); }");
+  testWalk("template struct $explicit^Base { void method(); };",
+   "template void k(Base* t) { t->^method(); }");
 }
 
 TEST(WalkAST, ConstructExprs) {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] d03e9f8 - [include-cleaner] Handle base class member access from derived class.

2022-12-08 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2022-12-08T10:39:18Z
New Revision: d03e9f8fb0741a510308be09b29a13d0a66a6e41

URL: 
https://github.com/llvm/llvm-project/commit/d03e9f8fb0741a510308be09b29a13d0a66a6e41
DIFF: 
https://github.com/llvm/llvm-project/commit/d03e9f8fb0741a510308be09b29a13d0a66a6e41.diff

LOG: [include-cleaner] Handle base class member access from derived class.

Fix: https://github.com/llvm/llvm-project/issues/59251
Differential Revision: https://reviews.llvm.org/D139087

Added: 


Modified: 
clang-tools-extra/include-cleaner/lib/WalkAST.cpp
clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp

Removed: 




diff  --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp 
b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 7fb3f5697b7e..ff15e62efdfd 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -44,6 +44,12 @@ class ASTWalker : public RecursiveASTVisitor {
 Callback(Loc, *cast(ND->getCanonicalDecl()), RT);
   }
 
+  NamedDecl *resolveType(QualType Type) {
+if (Type->isPointerType())
+  Type = Type->getPointeeType();
+return Type->getAsRecordDecl();
+  }
+
 public:
   ASTWalker(DeclCallback Callback) : Callback(Callback) {}
 
@@ -53,7 +59,12 @@ class ASTWalker : public RecursiveASTVisitor {
   }
 
   bool VisitMemberExpr(MemberExpr *E) {
-report(E->getMemberLoc(), E->getFoundDecl().getDecl());
+// A member expr implies a usage of the class type
+// (e.g., to prevent inserting a header of base class when using base
+// members from a derived object).
+// FIXME: support dependent types, e.g., "std::vector().size()".
+QualType Type = E->getBase()->IgnoreImpCasts()->getType();
+report(E->getMemberLoc(), resolveType(Type));
 return true;
   }
 

diff  --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
index d9cf84dc7abe..551eb66bcdef 100644
--- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -180,10 +180,22 @@ TEST(WalkAST, TemplateNames) {
 }
 
 TEST(WalkAST, MemberExprs) {
-  testWalk("struct S { void $explicit^foo(); };", "void foo() { S{}.^foo(); 
}");
+  testWalk("struct $explicit^S { void foo(); };", "void foo() { S{}.^foo(); 
}");
   testWalk(
-  "struct S { void foo(); }; struct X : S { using S::$explicit^foo; };",
+  "struct S { void foo(); }; struct $explicit^X : S { using S::foo; };",
   "void foo() { X{}.^foo(); }");
+  testWalk("struct Base { int a; }; struct $explicit^Derived : public Base 
{};",
+   "void fun(Derived d) { d.^a; }");
+  testWalk("struct Base { int a; }; struct $explicit^Derived : public Base 
{};",
+   "void fun(Derived* d) { d->^a; }");
+  testWalk("struct Base { int a; }; struct $explicit^Derived : public Base 
{};",
+   "void fun(Derived& d) { d.^a; }");
+  testWalk("struct Base { int a; }; struct $explicit^Derived : public Base 
{};",
+   "void fun() { Derived().^a; }");
+  testWalk("struct Base { int a; }; struct $explicit^Derived : public Base 
{};",
+   "Derived foo(); void fun() { foo().^a; }");
+  testWalk("struct Base { int a; }; struct $explicit^Derived : public Base 
{};",
+   "Derived& foo(); void fun() { foo().^a; }");
 }
 
 TEST(WalkAST, ConstructExprs) {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 45659b3 - [include-cleaner] Remove filtering from UsingDecl visit.

2022-12-08 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2022-12-08T10:23:55Z
New Revision: 45659b3bd98ea3b8ce13516bcf719669b934b9ba

URL: 
https://github.com/llvm/llvm-project/commit/45659b3bd98ea3b8ce13516bcf719669b934b9ba
DIFF: 
https://github.com/llvm/llvm-project/commit/45659b3bd98ea3b8ce13516bcf719669b934b9ba.diff

LOG: [include-cleaner] Remove filtering from UsingDecl visit.

Removes filtering from the VisitUsingDecl method for implementation files.

Differential Revision: https://reviews.llvm.org/D138821

Added: 


Modified: 
clang-tools-extra/include-cleaner/lib/WalkAST.cpp
clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp

Removed: 




diff  --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp 
b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 3d338cd59b282..7fb3f5697b7ed 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -16,7 +16,6 @@
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Casting.h"
 
@@ -27,10 +26,6 @@ using DeclCallback =
 
 class ASTWalker : public RecursiveASTVisitor {
   DeclCallback Callback;
-  // Whether we're traversing declarations coming from a header file.
-  // This helps figure out whether certain symbols can be assumed as unused
-  // (e.g. overloads brought into an implementation file, but not used).
-  bool IsHeader = false;
 
   bool handleTemplateName(SourceLocation Loc, TemplateName TN) {
 // For using-templates, only mark the alias.
@@ -50,8 +45,7 @@ class ASTWalker : public RecursiveASTVisitor {
   }
 
 public:
-  ASTWalker(DeclCallback Callback, bool IsHeader)
-  : Callback(Callback), IsHeader(IsHeader) {}
+  ASTWalker(DeclCallback Callback) : Callback(Callback) {}
 
   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
 report(DRE->getLocation(), DRE->getFoundDecl());
@@ -82,10 +76,6 @@ class ASTWalker : public RecursiveASTVisitor {
 for (const auto *Shadow : UD->shadows()) {
   auto *TD = Shadow->getTargetDecl();
   auto IsUsed = TD->isUsed() || TD->isReferenced();
-  // We ignore unused overloads inside implementation files, as the ones in
-  // headers might still be used by the dependents of the header.
-  if (!IsUsed && !IsHeader)
-continue;
   report(UD->getLocation(), TD,
  IsUsed ? RefType::Explicit : RefType::Ambiguous);
 }
@@ -151,14 +141,7 @@ class ASTWalker : public RecursiveASTVisitor {
 } // namespace
 
 void walkAST(Decl , DeclCallback Callback) {
-  auto  = Root.getASTContext();
-  auto  = AST.getSourceManager();
-  // If decl isn't written in main file, assume it's coming from an include,
-  // hence written in a header.
-  bool IsRootedAtHeader =
-  AST.getLangOpts().IsHeaderFile ||
-  !SM.isWrittenInMainFile(SM.getSpellingLoc(Root.getLocation()));
-  ASTWalker(Callback, IsRootedAtHeader).TraverseDecl();
+  ASTWalker(Callback).TraverseDecl();
 }
 
 } // namespace clang::include_cleaner

diff  --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
index 17d13018d1522..d9cf84dc7abe9 100644
--- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -26,7 +26,6 @@ namespace clang::include_cleaner {
 namespace {
 
 // Specifies a test of which symbols are referenced by a piece of code.
-// If `// c++-header` is present, treats referencing code as a header file.
 // Target should contain points annotated with the reference kind.
 // Example:
 //   Target:  int $explicit^foo();
@@ -41,8 +40,6 @@ void testWalk(llvm::StringRef TargetCode, llvm::StringRef 
ReferencingCode) {
   Inputs.ExtraArgs.push_back("-include");
   Inputs.ExtraArgs.push_back("target.h");
   Inputs.ExtraArgs.push_back("-std=c++17");
-  if (Referencing.code().contains("// c++-header\n"))
-Inputs.ExtraArgs.push_back("-xc++-header");
   TestAST AST(Inputs);
   const auto  = AST.sourceManager();
 
@@ -88,12 +85,10 @@ void testWalk(llvm::StringRef TargetCode, llvm::StringRef 
ReferencingCode) {
 auto RTStr = llvm::to_string(RT);
 for (auto Expected : Target.points(RTStr))
   if (!llvm::is_contained(ReferencedOffsets[RT], Expected))
-DiagnosePoint("location not marked used with type " + RTStr,
-  Expected);
+DiagnosePoint("location not marked used with type " + RTStr, Expected);
 for (auto Actual : ReferencedOffsets[RT])
   if (!llvm::is_contained(Target.points(RTStr), Actual))
-DiagnosePoint("location unexpectedly used with type " + RTStr,
-  Actual);
+DiagnosePoint("location unexpectedly used with type " + RTStr, Actual);
   }
 
   // If there were any 
diff 

[clang-tools-extra] 7452e05 - [include-cleaner] Implement IWYU begin_keep/end_keep pragma support.

2022-11-29 Thread Viktoriia Bakalova via cfe-commits

Author: Viktoriia Bakalova
Date: 2022-11-29T14:51:20Z
New Revision: 7452e053e5921113ef59ccab04acc0999bf2ecc2

URL: 
https://github.com/llvm/llvm-project/commit/7452e053e5921113ef59ccab04acc0999bf2ecc2
DIFF: 
https://github.com/llvm/llvm-project/commit/7452e053e5921113ef59ccab04acc0999bf2ecc2.diff

LOG: [include-cleaner] Implement IWYU begin_keep/end_keep pragma support.

Implement support for begin_keep/end_keep pragmas.

Differential Revision: https://reviews.llvm.org/D138797

Added: 


Modified: 
clang-tools-extra/include-cleaner/lib/Record.cpp
clang-tools-extra/include-cleaner/unittests/RecordTest.cpp

Removed: 




diff  --git a/clang-tools-extra/include-cleaner/lib/Record.cpp 
b/clang-tools-extra/include-cleaner/lib/Record.cpp
index ac3315abb882c..5a9ec6d0aadcf 100644
--- a/clang-tools-extra/include-cleaner/lib/Record.cpp
+++ b/clang-tools-extra/include-cleaner/lib/Record.cpp
@@ -187,9 +187,7 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, 
public CommentHandler {
 FileID HashFID = SM.getFileID(HashLoc);
 int HashLine = SM.getLineNumber(HashFID, SM.getFileOffset(HashLoc));
 checkForExport(HashFID, HashLine, File ? >getFileEntry() : nullptr);
-
-if (InMainFile && LastPragmaKeepInMainFileLine == HashLine)
-  Out->ShouldKeep.insert(HashLine);
+checkForKeep(HashLine);
   }
 
   void checkForExport(FileID IncludingFile, int HashLine,
@@ -213,6 +211,18 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, 
public CommentHandler {
   ExportStack.pop_back();
   }
 
+  void checkForKeep(int HashLine) {
+if (!InMainFile || KeepStack.empty())
+  return;
+KeepPragma  = KeepStack.back();
+// Check if the current include is covered by a keep pragma.
+if ((Top.Block && HashLine > Top.SeenAtLine) || Top.SeenAtLine == HashLine)
+  Out->ShouldKeep.insert(HashLine);
+
+if (!Top.Block)
+  KeepStack.pop_back(); // Pop immediately for single-line keep pragma.
+  }
+
   bool HandleComment(Preprocessor , SourceRange Range) override {
 auto  = PP.getSourceManager();
 auto Pragma =
@@ -257,23 +267,14 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, 
public CommentHandler {
 }
 
 if (InMainFile) {
-  if (!Pragma->startswith("keep"))
-return false;
-  // Given:
-  //
-  // #include "foo.h"
-  // #include "bar.h" // IWYU pragma: keep
-  //
-  // The order in which the callbacks will be triggered:
-  //
-  // 1. InclusionDirective("foo.h")
-  // 2. handleCommentInMainFile("// IWYU pragma: keep")
-  // 3. InclusionDirective("bar.h")
-  //
-  // This code stores the last location of "IWYU pragma: keep" comment in
-  // the main file, so that when next InclusionDirective is called, it will
-  // know that the next inclusion is behind the IWYU pragma.
-  LastPragmaKeepInMainFileLine = CommentLine;
+  if (Pragma->startswith("keep")) {
+KeepStack.push_back({CommentLine, false});
+  } else if (Pragma->starts_with("begin_keep")) {
+KeepStack.push_back({CommentLine, true});
+  } else if (Pragma->starts_with("end_keep") && !KeepStack.empty()) {
+assert(KeepStack.back().Block);
+KeepStack.pop_back();
+  }
 }
 return false;
   }
@@ -288,8 +289,7 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, 
public CommentHandler {
   llvm::BumpPtrAllocator Arena;
   /// Intern table for strings. Contents are on the arena.
   llvm::StringSaver UniqueStrings;
-  // Track the last line "IWYU pragma: keep" was seen in the main file, 
1-based.
-  int LastPragmaKeepInMainFileLine = -1;
+
   struct ExportPragma {
 // The line number where we saw the begin_exports or export pragma.
 int SeenAtLine = 0; // 1-based line number.
@@ -303,6 +303,16 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, 
public CommentHandler {
   };
   // A stack for tracking all open begin_exports or single-line export.
   std::vector ExportStack;
+
+  struct KeepPragma {
+// The line number where we saw the begin_keep or keep pragma.
+int SeenAtLine = 0; // 1-based line number.
+// true if it is a block begin/end_keep pragma; false if it is a
+// single-line keep pragma.
+bool Block = false;
+  };
+  // A stack for tracking all open begin_keep pragmas or single-line keeps.
+  std::vector KeepStack;
 };
 
 void PragmaIncludes::record(const CompilerInstance ) {

diff  --git a/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
index 0cc163751fd70..1076891473431 100644
--- a/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
@@ -311,35 +311,68 @@ class PragmaIncludeTest : public ::testing::Test {
 };
 
 TEST_F(PragmaIncludeTest, IWYUKeep) {
-  Inputs.Code = R"cpp(// Line 1
-