[PATCH] D153769: [clangd] Implement the 'Organize Imports' source action. Fix include-cleaner findings in batch.

2023-10-02 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/ClangdLSPServer.cpp:810-815
+  Server->applyTweak(Args.tweakID,
+ {Args.file.file().str(),
+  Args.selection,
+  Args.requestedActionKinds,
+  {},
+  {}},

this is kind of hard to read



Comment at: clang-tools-extra/clangd/ParsedAST.h:124
+  PreambleBounds getPreambleBounds() const {
+return Preamble->Preamble.getBounds();
+  }

Unfortunately this won't work in presence of stale preambles. You can use the 
"patched bounds" we calculate when building a parsedast in 
https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/clangd/ParsedAST.cpp#L646;
 store it in `ParsedAST` in a new field, and return it here.



Comment at: clang-tools-extra/clangd/refactor/Tweak.h:74
+/// code action request context.
+std::vector RequestedActionKinds;
 // FIXME: provide a way to get sources and ASTs for other files.

prefer `llvm::ArrayRef` here, `Selection`s are not passed in 
between threads. So no need to make an extra copy when creating one.



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:52
+return false;
+  if (std::find(Inputs.RequestedActionKinds.begin(),
+Inputs.RequestedActionKinds.end(),

nit: llvm::find(Inputs.RequestedActionKinds, CodeAction::SOURCE_KIND)



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:56
+return true;
+  if (Inputs.RequestedActionKinds.empty())
+// To accommodate clients without knowledge of source actions, we trigger

nit:
```
if (!Inputs.RequestedActionKinds.empty())
  return llvm::find(Inputs.RequestedActionKinds, CodeAction::SOURCE_KIND) != 
Inputs.RequestedActionKinds.end();
// To accommodate clients without knowledge of source actions, we trigger
// without checking code action kinds when inside the preamble region.
return Inputs.SelectionEnd <= Inputs.AST->getPreambleBounds().Size;
```



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:68
+  tooling::Replacements Replacements;
+  for (const auto *Inc : Findings.UnusedIncludes)
+llvm::cantFail(Replacements.add(

we should respect `Config::Diagnostics::Includes::IgnoreHeader` here, similar 
to finding integration, similarly for missing include fixes.



Comment at: clang-tools-extra/clangd/unittests/ClangdTests.cpp:1307
+  Server.applyTweak(
+  TweakID, {FooCpp, {}, {}, {}, {}}, [&](llvm::Expected E) {
+ASSERT_TRUE(static_cast(E));

nit: Again extracting CodeActionInputs, setting filename explicitly and passing 
that into the call would be great here.



Comment at: 
clang-tools-extra/clangd/unittests/tweaks/OrganizeImportsTests.cpp:35-41
+   {
+   R"cpp(
+#include "Te^stTU.h"
+)cpp",
+   true,
+   {}},
+   {"void foo(^) {}", false, {}}};

nit: you can use EXPECT_AVAILABLE and EXPECT_UNAVAILABLE directly for these two 
cases



Comment at: clang-tools-extra/clangd/unittests/tweaks/TweakTesting.h:101
+  bool isAvailable(WrappedAST &, llvm::Annotations::Range,
+   const std::vector & = {}) const;
   // Return code re-decorated with a single point/range.

type is not really giving any ideas what the parameter is about here, can you 
name it ?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153769/new/

https://reviews.llvm.org/D153769

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


[PATCH] D153769: [clangd] Implement the 'Organize Imports' source action. Fix include-cleaner findings in batch.

2023-09-12 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

FYI, i don't think you uploaded the new version of the patch




Comment at: clang-tools-extra/clangd/ClangdServer.cpp:752
   auto Action = [File = File.str(), Sel, TweakID = TweakID.str(),
- CB = std::move(CB),
+ CB = std::move(CB), ActionKinds,
  this](Expected InpAST) mutable {

VitaNuo wrote:
> kadircet wrote:
> > we're capturing `ActionKinds` as a reference, but Action is going to 
> > execute async. you can instead change the input to be 
> > `llvm::ArrayRef ActionKinds` and capture it by value with 
> > `ActionKinds = ActionKinds.vec()`
> > 
> > nit: even better if you just changed the signature here to look like 
> > `applyTweak(std::string TweakID, CodeActionInputs Inputs, 
> > Callback CB)`, as we want to consume all of these by value 
> > anyways. Then you can just move `TweakID` and `Inputs` into the `Action`.
> Ok, I can change the signature, but it seems like I still need to move 
> individual members of `CodeActionInputs` into the callback separately. `File` 
> cannot be moved, since it's also needed after the callback as an argument to 
> `runWithAST`.
yeah, it's fine to make a copy



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:56
+return false;
+  Range PreambleRange;
+  PreambleRange.start =

VitaNuo wrote:
> kadircet wrote:
> > kadircet wrote:
> > > relying on `MainFileIncludes` for preamble range is not correct in 
> > > general. we can have includes way down inside the main file that'll be 
> > > part of this vector, but not preamble (also it's not sorted explicitly).
> > > 
> > > we should instead use `ComputePreambleBounds` (nit: we can also store it 
> > > in ParsedAST, instead of relexing the file one more time with each 
> > > CodeAction request)
> > Having a comment for reason would also be helpful, something like `To 
> > accommodate clients without knowledge of source actions, we trigger without 
> > checking code action kinds when inside the preamble region`.
> > nit: we can also store it in ParsedAST
> 
> Seems like the data is already there, I just need to expose it.
> > nit: we can also store it in ParsedAST
> Seems like the data is already there, I just need to expose it.

not really, we calculate bounds when building a `ParsedAST` but we don't store 
it anywhere.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153769/new/

https://reviews.llvm.org/D153769

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


[PATCH] D153769: [clangd] Implement the 'Organize Imports' source action. Fix include-cleaner findings in batch.

2023-09-11 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/ClangdServer.cpp:752
   auto Action = [File = File.str(), Sel, TweakID = TweakID.str(),
- CB = std::move(CB),
+ CB = std::move(CB), ActionKinds,
  this](Expected InpAST) mutable {

we're capturing `ActionKinds` as a reference, but Action is going to execute 
async. you can instead change the input to be `llvm::ArrayRef 
ActionKinds` and capture it by value with `ActionKinds = ActionKinds.vec()`

nit: even better if you just changed the signature here to look like 
`applyTweak(std::string TweakID, CodeActionInputs Inputs, 
Callback CB)`, as we want to consume all of these by value 
anyways. Then you can just move `TweakID` and `Inputs` into the `Action`.



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:49
+bool OrganizeImports::prepare(const Tweak::Selection ) {
+  if (std::find(Inputs.RequestedActionKinds.begin(),
+Inputs.RequestedActionKinds.end(),

can we also bail out for ObjC



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:56
+return false;
+  Range PreambleRange;
+  PreambleRange.start =

relying on `MainFileIncludes` for preamble range is not correct in general. we 
can have includes way down inside the main file that'll be part of this vector, 
but not preamble (also it's not sorted explicitly).

we should instead use `ComputePreambleBounds` (nit: we can also store it in 
ParsedAST, instead of relexing the file one more time with each CodeAction 
request)



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:56
+return false;
+  Range PreambleRange;
+  PreambleRange.start =

kadircet wrote:
> relying on `MainFileIncludes` for preamble range is not correct in general. 
> we can have includes way down inside the main file that'll be part of this 
> vector, but not preamble (also it's not sorted explicitly).
> 
> we should instead use `ComputePreambleBounds` (nit: we can also store it in 
> ParsedAST, instead of relexing the file one more time with each CodeAction 
> request)
Having a comment for reason would also be helpful, something like `To 
accommodate clients without knowledge of source actions, we trigger without 
checking code action kinds when inside the preamble region`.



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:63
+offsetToPosition(Inputs.Code, Inputs.SelectionEnd)};
+  return SelectionRange.start <= PreambleRange.end &&
+ PreambleRange.start <= SelectionRange.end;

we should also make sure that `RequestedActionKinds` is empty in this case. 
Because we don't want to offer a code action of kind Source, if user is 
explicitly asking for some other kind(s).



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:72
+  for (const auto *Inc : Findings.UnusedIncludes)
+if (auto Err = Replacements.add(
+tooling::Replacement{MainFilePath, UINT_MAX, 1, Inc->Written}))

nit: insertions of Replacements with offset `UINT_MAX` can't fail. so you just 
wrap this inside `llvm::cantFail` instead.



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:87
+ SM.getFileEntryForID(SM.getMainFileID())});
+if (auto Err = Replacements.add(tooling::Replacement{
+MainFilePath, UINT_MAX, 0, "#include " + Spelling}))

same here for never failing



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:92
+
+  if (Replacements.empty())
+return Tweak::Effect{"No edits to apply.", {}};

i think we should perform this check on `Final` instead (as replacements can 
still go empty after cleanups, and empty set of replacements will result in an 
empty set anyways)



Comment at: 
clang-tools-extra/clangd/unittests/tweaks/OrganizeImportsTests.cpp:19
+
+TEST_F(OrganizeImportsTest, All) {
+  Header = "void foo();";

can you also add some availability tests ?



Comment at: clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp:73
+Tweak::Selection S(Index, AST, Range.Begin, Range.End, std::move(ST),
+   FS, {std::string{CodeAction::SOURCE_KIND}});
+if (auto T = prepareTweak(TweakID, S, nullptr)) {

ATM this is passing SOURCE_KIND for all tweaks, which is conceptually wrong. 
can you instead take this in as a parameter?

for `TweakTest::apply`, we can default it to be an empty vector, and just 
update `OrganizeImportsTests` to pass `{CodeAction::SOURCE_KIND}`;
for `TweakTest::isAvailable`, we can update `EXPECT_AVAILABLE_` to pass in `{}` 
and call `isAvailable` directly in `OrganizeImportsTests` 

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

2023-09-10 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156659/new/

https://reviews.llvm.org/D156659

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


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

2023-09-07 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:828
-  tooling::stdlib::Lang Lang = tooling::stdlib::Lang::CXX;
-if (LangOpts.C11)
-  Lang = tooling::stdlib::Lang::C;

sorry i got confused, this also works for ObjC, not just ObjC++. we set C-like 
features for ObjectiveC. can you just restore as-is?



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:919
+  if (IncludeHeader.empty())
+HeaderFileURIs->getIncludeHeader(FID);
+

i guess LHS of the assignment got dropped by mistake?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156659/new/

https://reviews.llvm.org/D156659

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


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

2023-09-07 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:912
+if (Directives & Symbol::Import) {
+  if (auto IncludeHeader = HeaderFileURIs->getIncludeHeader(FID);
+  !IncludeHeader.empty()) {

VitaNuo wrote:
> kadircet wrote:
> > we should keep the `getStdHeaders` logic for objc
> `getStdHeaders` returns empty string for Obj-C, are you sure you meant it?
it reads a little bit weird, but it still actually works, for objective-c++ to 
be more specific. as we'll have `LangOpts.CPlusPlus` set for objc++


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156659/new/

https://reviews.llvm.org/D156659

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


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

2023-09-07 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

thanks!




Comment at: clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp:587
+  TU.ExtraArgs.push_back(testPath("resources"));
+  TU.AdditionalFiles["resources/include/amintrin.h"] = "";
+  TU.AdditionalFiles["resources/include/imintrin.h"] = guard(R"cpp(

nit: also wrap contents in `guard()` here to make sure we're not testing 
multiple things here (i.e. behavior for non-self-contained headers)



Comment at: clang-tools-extra/include-cleaner/lib/Analysis.cpp:100
  Satisfied = true;
+ continue;
+   }

now we're not going to put matching includes into the `Used` set. i know we're 
going to filter them put from the final output in the next loop, but still 
better to keep normal track of `Used` i believe



Comment at: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp:286
+  )cpp";
+  Inputs.ExtraFiles["resources/include/amintrin.h"] = "";
+  Inputs.ExtraFiles["resources/include/emintrin.h"] = guard(R"cpp(

again lets make this self-contained


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157610/new/

https://reviews.llvm.org/D157610

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


[PATCH] D158566: Add CLANGD_INCLUDE_TESTS as a separate flag to control clangd tests

2023-09-06 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

hi @hiraditya , i believe your issues should disappear starting with 
9a26d2c6d35f574d7a4b06a5a22f8a1c063cb664 
. LMK if 
you're still facing problems and want to move forward with such a patch


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158566/new/

https://reviews.llvm.org/D158566

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


[PATCH] D159441: [include-cleaner] Weaken signal for boosting preferred headers

2023-09-06 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG73b2c86d95dc: [include-cleaner] Weaken signal for boosting 
preferred headers (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159441/new/

https://reviews.llvm.org/D159441

Files:
  clang-tools-extra/include-cleaner/lib/TypesInternal.h
  clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp


Index: clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -344,7 +344,7 @@
 }
 
 TEST_F(HeadersForSymbolTest, Ranking) {
-  // Sorting is done over (canonical, public, complete, origin)-tuple.
+  // Sorting is done over (public, complete, canonical, origin)-tuple.
   Inputs.Code = R"cpp(
 #include "private.h"
 #include "public.h"
@@ -363,11 +363,11 @@
   )cpp");
   Inputs.ExtraFiles["public_complete.h"] = guard("struct foo {};");
   buildAST();
-  EXPECT_THAT(headersForFoo(), ElementsAre(Header("\"canonical.h\""),
-   physicalHeader("public_complete.h"),
-   physicalHeader("public.h"),
-   physicalHeader("exporter.h"),
-   physicalHeader("private.h")));
+  EXPECT_THAT(headersForFoo(),
+  ElementsAre(physicalHeader("public_complete.h"),
+  Header("\"canonical.h\""), 
physicalHeader("public.h"),
+  physicalHeader("exporter.h"),
+  physicalHeader("private.h")));
 }
 
 TEST_F(HeadersForSymbolTest, PreferPublicOverComplete) {
@@ -391,14 +391,11 @@
 #include "public_complete.h"
 #include "test/foo.fwd.h"
   )cpp";
-  Inputs.ExtraFiles["public_complete.h"] = guard(R"cpp(
-struct foo {};
-  )cpp");
+  Inputs.ExtraFiles["public_complete.h"] = guard("struct foo {};");
   Inputs.ExtraFiles["test/foo.fwd.h"] = guard("struct foo;");
   buildAST();
-  EXPECT_THAT(headersForFoo(),
-  ElementsAre(physicalHeader("test/foo.fwd.h"),
-  physicalHeader("public_complete.h")));
+  EXPECT_THAT(headersForFoo(), ElementsAre(physicalHeader("public_complete.h"),
+   physicalHeader("test/foo.fwd.h")));
 }
 
 TEST_F(HeadersForSymbolTest, MainFile) {
Index: clang-tools-extra/include-cleaner/lib/TypesInternal.h
===
--- clang-tools-extra/include-cleaner/lib/TypesInternal.h
+++ clang-tools-extra/include-cleaner/lib/TypesInternal.h
@@ -66,13 +66,13 @@
   /// Symbol is directly originating from this header, rather than being
   /// exported or included transitively.
   OriginHeader = 1 << 0,
-  /// Provides a generally-usable definition for the symbol. (a function decl,
-  /// or class definition and not a forward declaration of a template).
-  CompleteSymbol = 1 << 1,
   /// Header providing the symbol is explicitly marked as preferred, with an
   /// IWYU private pragma that points at this provider or header and symbol has
   /// ~the same name.
-  PreferredHeader = 1 << 2,
+  PreferredHeader = 1 << 1,
+  /// Provides a generally-usable definition for the symbol. (a function decl,
+  /// or class definition and not a forward declaration of a template).
+  CompleteSymbol = 1 << 2,
   /// Symbol is provided by a public file. Only absent in the cases where file
   /// is explicitly marked as such, non self-contained or IWYU private
   /// pragmas.


Index: clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -344,7 +344,7 @@
 }
 
 TEST_F(HeadersForSymbolTest, Ranking) {
-  // Sorting is done over (canonical, public, complete, origin)-tuple.
+  // Sorting is done over (public, complete, canonical, origin)-tuple.
   Inputs.Code = R"cpp(
 #include "private.h"
 #include "public.h"
@@ -363,11 +363,11 @@
   )cpp");
   Inputs.ExtraFiles["public_complete.h"] = guard("struct foo {};");
   buildAST();
-  EXPECT_THAT(headersForFoo(), ElementsAre(Header("\"canonical.h\""),
-   physicalHeader("public_complete.h"),
-   physicalHeader("public.h"),
-   physicalHeader("exporter.h"),
-   physicalHeader("private.h")));
+  EXPECT_THAT(headersForFoo(),
+  ElementsAre(physicalHeader("public_complete.h"),
+  Header("\"canonical.h\""), physicalHeader("public.h"),
+  

[PATCH] D159441: [include-cleaner] Weaken signal for boosting preferred headers

2023-09-06 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

see also https://github.com/llvm/llvm-project/issues/62172


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159441/new/

https://reviews.llvm.org/D159441

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


[PATCH] D159263: [clang-tidy] misc-include-cleaner: avoid duplicated fixes

2023-09-05 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

In D159263#4638199 , @danix800 wrote:

> If we have further plans from upstream on these checker/clang-format related 
> logic, I can wait and abandon this revision.

Not at the moment, so please don't!

> Or if such issue does need fixing then coud you take a look at the previous 
> diff 1 
> which uses an internal set to prevent this issue?

Yes, I think that approach makes sense. But we should make it conditional on 
`areDiagsSelfContained` (basically de-duplicate only when diags are not self 
contained).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159263/new/

https://reviews.llvm.org/D159263

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


[PATCH] D159263: [clang-tidy] misc-include-cleaner: avoid duplicated fixes

2023-09-05 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

Thanks a lot for the patch @danix800 !

I initially was rather focused on behavior of this check in workflows that 
require seeing "self-contained-diags", but also I rather see the bulk-apply use 
cases as always requiring clang-format afterwards. Hence didn't really try to 
polish that use case a lot, but I believe changes in this patch improve those 
use cases reasonably. But users do still need to run clang-format afterwards, 
e.g. if we first generate a finding that inserts "b.h" and then "a.h", they'll 
be in wrong order. So this is only fixing  some cases. If you'd like to work on 
a more complete approach, we can prepare all the edits in a single 
`tooling::Replacements` and run `clang::format::cleanupAroundReplacements` on 
top of it to generate proper edits, and emit FixIts with those merged 
replacements. Note that this still won't be enough in all cases, as there can 
be other checks that emit fixes that are touching includes :/

Regarding usage of `IncludeInserter`; we were deliberately not using 
`IncludeInserter` here, as it has slightly different semantics to 
`HeaderIncludes`, which is used by all the other applications of 
include-cleaner when producing edits. That way it's easier for us to reason 
about the behavior in various places (and also to fix them). But moreover, 
`HeaderIncludes` uses clang-format config to figure out include-styles and 
works with a bigger set of projects without requiring extra configurations 
(hence this patch will actually be a regression for those). Therefore can you 
keep using `HeaderIncludes`, while skipping generation of duplicate fixits when 
we're in non-self-contained-diags mode (assuming you don't want to generalize 
the approach as I explained above).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159263/new/

https://reviews.llvm.org/D159263

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


[PATCH] D159441: [include-cleaner] Weaken signal for boosting preferred headers

2023-09-05 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added a reviewer: sammccall.
Herald added a project: All.
kadircet requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Putting preferred header signal above completeness implied we would
uprank forward declarations above complete ones in certain cases.

This can be desired in cases where:

- Complete definition is private. But this case is already governed by 
publicness signal.
- The library indeed intends to provide a forward declaring interface, like 
iosfwd vs ostream.

In all other cases, upranking is undesired as it means we've picked up prefered
headerness signal by mistake from an unrelated declaration to the library.

This change regresses the behavior for libraries that intentionally provide a
forward declaring interface. But that wasn't something we intended to support
explicitly, it was working incidentally when the forward declaring header had a
similar name to the symbol. Moreover, include-cleaner deliberately discourages
forward-declarations, so not working in this case is also more aligned with rest
of the components.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D159441

Files:
  clang-tools-extra/include-cleaner/lib/TypesInternal.h
  clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp


Index: clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -344,7 +344,7 @@
 }
 
 TEST_F(HeadersForSymbolTest, Ranking) {
-  // Sorting is done over (canonical, public, complete, origin)-tuple.
+  // Sorting is done over (public, complete, canonical, origin)-tuple.
   Inputs.Code = R"cpp(
 #include "private.h"
 #include "public.h"
@@ -363,11 +363,11 @@
   )cpp");
   Inputs.ExtraFiles["public_complete.h"] = guard("struct foo {};");
   buildAST();
-  EXPECT_THAT(headersForFoo(), ElementsAre(Header("\"canonical.h\""),
-   physicalHeader("public_complete.h"),
-   physicalHeader("public.h"),
-   physicalHeader("exporter.h"),
-   physicalHeader("private.h")));
+  EXPECT_THAT(headersForFoo(),
+  ElementsAre(physicalHeader("public_complete.h"),
+  Header("\"canonical.h\""), 
physicalHeader("public.h"),
+  physicalHeader("exporter.h"),
+  physicalHeader("private.h")));
 }
 
 TEST_F(HeadersForSymbolTest, PreferPublicOverComplete) {
@@ -391,14 +391,11 @@
 #include "public_complete.h"
 #include "test/foo.fwd.h"
   )cpp";
-  Inputs.ExtraFiles["public_complete.h"] = guard(R"cpp(
-struct foo {};
-  )cpp");
+  Inputs.ExtraFiles["public_complete.h"] = guard("struct foo {};");
   Inputs.ExtraFiles["test/foo.fwd.h"] = guard("struct foo;");
   buildAST();
-  EXPECT_THAT(headersForFoo(),
-  ElementsAre(physicalHeader("test/foo.fwd.h"),
-  physicalHeader("public_complete.h")));
+  EXPECT_THAT(headersForFoo(), ElementsAre(physicalHeader("public_complete.h"),
+   physicalHeader("test/foo.fwd.h")));
 }
 
 TEST_F(HeadersForSymbolTest, MainFile) {
Index: clang-tools-extra/include-cleaner/lib/TypesInternal.h
===
--- clang-tools-extra/include-cleaner/lib/TypesInternal.h
+++ clang-tools-extra/include-cleaner/lib/TypesInternal.h
@@ -66,13 +66,13 @@
   /// Symbol is directly originating from this header, rather than being
   /// exported or included transitively.
   OriginHeader = 1 << 0,
-  /// Provides a generally-usable definition for the symbol. (a function decl,
-  /// or class definition and not a forward declaration of a template).
-  CompleteSymbol = 1 << 1,
   /// Header providing the symbol is explicitly marked as preferred, with an
   /// IWYU private pragma that points at this provider or header and symbol has
   /// ~the same name.
-  PreferredHeader = 1 << 2,
+  PreferredHeader = 1 << 1,
+  /// Provides a generally-usable definition for the symbol. (a function decl,
+  /// or class definition and not a forward declaration of a template).
+  CompleteSymbol = 1 << 2,
   /// Symbol is provided by a public file. Only absent in the cases where file
   /// is explicitly marked as such, non self-contained or IWYU private
   /// pragmas.


Index: clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -344,7 +344,7 @@
 }
 
 TEST_F(HeadersForSymbolTest, Ranking) {
-  // 

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

2023-09-05 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:840
 
-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 "";
+  auto [It, Inserted] = SymbolProviders.try_emplace(S.ID);
+  auto Headers =

can you add a comment here saying, `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.`



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:912
+if (Directives & Symbol::Import) {
+  if (auto IncludeHeader = HeaderFileURIs->getIncludeHeader(FID);
+  !IncludeHeader.empty()) {

we should keep the `getStdHeaders` logic for objc



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:934
+if (auto Canonical =
+HeaderFileURIs->mapCanonical(H.physical()->getName());
+!Canonical.empty())

can you add a `// FIXME: Get rid of this once include-cleaner has support for 
system headers.` to this branch



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:937
+  SpellingIt->second = Canonical;
+else if (tooling::isSelfContainedHeader(H.physical(), SM,
+PP->getHeaderSearchInfo()))

again a comment saying `For physical files, prefer URIs as spellings might 
change depending on the translation unit.`



Comment at: clang-tools-extra/include-cleaner/lib/FindHeaders.cpp:127
+if (FD->getNumParams() == 3 || FD->getNumParams() == 4)
   // move(InputIt first, InputIt last, OutputIt dest);
   return tooling::stdlib::Header::named("");

can you also add comment `move(ExecutionPolicy&& policy, ForwardIt1 first, 
ForwardIt1 last, ForwardIt2 d_first );` and move this change into a separate 
patch with a test case in 
clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp?



Comment at: clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc:365
+// Remove them when the cause(s) are identified.
+SYMBOL(div, std::, )
+SYMBOL(abort, std::, )

can you move this into a separate patch?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156659/new/

https://reviews.llvm.org/D156659

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


[PATCH] D159363: [clangd] SIGSEGV at clangd: DiagnosticConsumer Is Used After Free

2023-09-04 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

thanks, the fix LGTM as well.

but i wonder how this surfaces, to make sure we're taking necessary precautions 
in the future. we definitely have a dangling reference, which isn't great. but 
it's surprising that we access diags consumer during indexing.
I assume it's about the modules setup you're running clangd in. Do you have any 
stack traces that shows the execution path? my assumption is, this triggers 
when clangd ends up deserializing some symbols from a module. If these end up 
being important diagnostics, we might want to figure out how to emit 
diagnostics from these stages as well.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159363/new/

https://reviews.llvm.org/D159363

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


[PATCH] D159363: [clangd] SIGSEGV at clangd: DiagnosticConsumer Is Used After Free

2023-09-04 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

thanks, the fix LGTM as well.

but i wonder how this surfaces, to make sure we're taking necessary precautions 
in the future. we definitely have a dangling reference, which isn't great. but 
it's surprising that we access diags consumer during indexing.
I assume it's about the modules setup you're running clangd in. Do you have any 
stack traces that shows the execution path? my assumption is, this triggers 
when clangd ends up deserializing some symbols from a module. If these end up 
being important diagnostics, we might want to figure out how to emit 
diagnostics from these stages as well.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159363/new/

https://reviews.llvm.org/D159363

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


[PATCH] D158566: Add CLANGD_INCLUDE_TESTS as a separate flag to control clangd tests

2023-09-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

In D158566#4616417 , @ilya-biryukov 
wrote:

> Open question: I also feel like the best option here is to fix the tests, but 
> I'm not sure how hard that would be. @sammccall any thoughts?
> I suspect the particular tests are flaky is because they rely on timeouts, 
> not sure it's easy to disentangle them. Therefore, some workaround seems 
> reasonable

FWIW, i've put some details in 
https://github.com/llvm/llvm-project/issues/64964#issuecomment-1702249740 and 
we had some previous discussions but unfortunately these tests have timeouts as 
a "poor-mans-deadlock-detection". i don't think we can get rid of the timeouts, 
without sacrificing that detection.
I can't remember how misleading buildbot outputs were, when deadlocks happened, 
before we introduced timeouts though. So one alternative is let the buildbots 
hang instead.

---

Regarding the approach in this patch, I don't feel strongly about it but I 
don't think it's a good idea to let people build clangd, without testing it on 
environments they care about. They might suppress legitimate issues. (there's 
also some value though, e.g. maybe they already performed testing before, and 
don't want to run tests again, but in such a scenario we've non-check 
equivalents of targets to only run builds).

Are you building clangd deliberately or is it just being pulled in via 
check-clang-tools? If you don't want to ship clangd with your toolchain at all, 
I think it's better to set `CLANG_ENABLE_CLANGD` to `OFF`.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158566/new/

https://reviews.llvm.org/D158566

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


[PATCH] D159338: [clangd][tests] Bump timeouts in TUSchedulerTests to 60 secs

2023-09-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG16b8b3e59f7e: [clangd][tests] Bump timeouts in 
TUSchedulerTests to 60 secs (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159338/new/

https://reviews.llvm.org/D159338

Files:
  clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp

Index: clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
===
--- clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
+++ clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
@@ -251,7 +251,7 @@
 [&](std::vector) { ++CallbackCount; });
 Ready.notify();
 
-ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   }
   EXPECT_EQ(2, CallbackCount);
 }
@@ -274,7 +274,7 @@
   Notification N;
   updateWithDiags(S, Path, "auto (timed out)", WantDiagnostics::Auto,
   [&](std::vector) { N.notify(); });
-  EXPECT_TRUE(N.wait(timeoutSeconds(5)));
+  EXPECT_TRUE(N.wait(timeoutSeconds(60)));
 
   // Once we start shutting down the TUScheduler, this one becomes a dead write.
   updateWithDiags(S, Path, "auto (discarded)", WantDiagnostics::Auto,
@@ -340,7 +340,7 @@
 Read("R3")();
 Proceed.notify();
 
-ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   }
   EXPECT_THAT(DiagsSeen, ElementsAre("U2", "U3"))
   << "U1 and all dependent reads were cancelled. "
@@ -361,7 +361,7 @@
   // We expect invalidation logic to not crash by trying to invalidate a running
   // request.
   S.update(Path, getInputs(Path, ""), WantDiagnostics::Auto);
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   S.runWithAST(
   "invalidatable-but-running", Path,
   [&](llvm::Expected AST) {
@@ -373,7 +373,7 @@
   StartedRunning.wait();
   S.update(Path, getInputs(Path, ""), WantDiagnostics::Auto);
   ScheduledChange.notify();
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
 }
 
 TEST_F(TUSchedulerTests, Invalidation) {
@@ -429,7 +429,7 @@
   },
   TUScheduler::InvalidateOnUpdate);
   Start.notify();
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
 
   EXPECT_EQ(2, Builds.load()) << "Middle build should be skipped";
   EXPECT_EQ(4, Actions.load()) << "All actions should run (some with error)";
@@ -462,7 +462,7 @@
 ADD_FAILURE() << "Shouldn't build, identical to previous";
   });
   Start.notify();
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
 
   EXPECT_EQ(1, Actions.load()) << "All actions should run";
 }
@@ -569,7 +569,7 @@
 }
   }
 }
-ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   } // TUScheduler destructor waits for all operations to finish.
 
   std::lock_guard Lock(Mut);
@@ -611,7 +611,7 @@
   // one that the cache will evict.
   updateWithCallback(S, Foo, SourceContents, WantDiagnostics::Yes,
  []() { ++BuiltASTCounter; });
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   ASSERT_EQ(BuiltASTCounter.load(), 1);
   EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "hit"), SizeIs(0));
   EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "miss"), SizeIs(1));
@@ -622,7 +622,7 @@
  []() { ++BuiltASTCounter; });
   updateWithCallback(S, Baz, SourceContents, WantDiagnostics::Yes,
  []() { ++BuiltASTCounter; });
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   ASSERT_EQ(BuiltASTCounter.load(), 3);
   EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "hit"), SizeIs(0));
   EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "miss"), SizeIs(2));
@@ -633,7 +633,7 @@
   // Access the old file again.
   updateWithCallback(S, Foo, OtherSourceContents, WantDiagnostics::Yes,
  []() { ++BuiltASTCounter; });
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   ASSERT_EQ(BuiltASTCounter.load(), 4);
   EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "hit"), SizeIs(0));
   EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "miss"), SizeIs(1));
@@ -659,16 +659,16 @@
 
   // After opening Foo then Bar, AST cache contains Bar.
   S.update(Foo, FooInputs, WantDiagnostics::Auto);
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   S.update(Bar, BarInputs, WantDiagnostics::Auto);
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  

[PATCH] D159337: [clangd][tests] Assert for idleness of scheduler

2023-09-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG69feef0e8277: [clangd][tests] Assert for idleness of 
scheduler (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159337/new/

https://reviews.llvm.org/D159337

Files:
  clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp


Index: clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
===
--- clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
+++ clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
@@ -1307,7 +1307,7 @@
   ASSERT_THAT(BlockForDiags(PI), testing::Pair("1", "3"));
 
   UnblockPreamble.notify();
-  S.blockUntilIdle(timeoutSeconds(5));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(5)));
 
   // Make sure that we have eventual consistency.
   EXPECT_THAT(Collector.diagVersions().back(), Pair(PI.Version, PI.Version));
@@ -1316,7 +1316,7 @@
   PI.Version = "4";
   PI.Contents = "#define FOO\n" + PI.Version;
   S.update(File, PI, WantDiagnostics::No);
-  S.blockUntilIdle(timeoutSeconds(5));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(5)));
   EXPECT_THAT(Collector.diagVersions().back(), Pair("3", "3"));
 }
 


Index: clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
===
--- clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
+++ clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
@@ -1307,7 +1307,7 @@
   ASSERT_THAT(BlockForDiags(PI), testing::Pair("1", "3"));
 
   UnblockPreamble.notify();
-  S.blockUntilIdle(timeoutSeconds(5));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(5)));
 
   // Make sure that we have eventual consistency.
   EXPECT_THAT(Collector.diagVersions().back(), Pair(PI.Version, PI.Version));
@@ -1316,7 +1316,7 @@
   PI.Version = "4";
   PI.Contents = "#define FOO\n" + PI.Version;
   S.update(File, PI, WantDiagnostics::No);
-  S.blockUntilIdle(timeoutSeconds(5));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(5)));
   EXPECT_THAT(Collector.diagVersions().back(), Pair("3", "3"));
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D159338: [clangd][tests] Bump timeouts in TUSchedulerTests to 60 secs

2023-09-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added reviewers: sammccall, nridge.
Herald added subscribers: arphaman, javed.absar.
Herald added a project: All.
kadircet requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

There are some slow/congested bots, that can't go idle in 10 secs, see 
https://github.com/llvm/llvm-project/issues/64964


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D159338

Files:
  clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp

Index: clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
===
--- clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
+++ clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
@@ -251,7 +251,7 @@
 [&](std::vector) { ++CallbackCount; });
 Ready.notify();
 
-ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   }
   EXPECT_EQ(2, CallbackCount);
 }
@@ -274,7 +274,7 @@
   Notification N;
   updateWithDiags(S, Path, "auto (timed out)", WantDiagnostics::Auto,
   [&](std::vector) { N.notify(); });
-  EXPECT_TRUE(N.wait(timeoutSeconds(5)));
+  EXPECT_TRUE(N.wait(timeoutSeconds(60)));
 
   // Once we start shutting down the TUScheduler, this one becomes a dead write.
   updateWithDiags(S, Path, "auto (discarded)", WantDiagnostics::Auto,
@@ -340,7 +340,7 @@
 Read("R3")();
 Proceed.notify();
 
-ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   }
   EXPECT_THAT(DiagsSeen, ElementsAre("U2", "U3"))
   << "U1 and all dependent reads were cancelled. "
@@ -361,7 +361,7 @@
   // We expect invalidation logic to not crash by trying to invalidate a running
   // request.
   S.update(Path, getInputs(Path, ""), WantDiagnostics::Auto);
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   S.runWithAST(
   "invalidatable-but-running", Path,
   [&](llvm::Expected AST) {
@@ -373,7 +373,7 @@
   StartedRunning.wait();
   S.update(Path, getInputs(Path, ""), WantDiagnostics::Auto);
   ScheduledChange.notify();
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
 }
 
 TEST_F(TUSchedulerTests, Invalidation) {
@@ -429,7 +429,7 @@
   },
   TUScheduler::InvalidateOnUpdate);
   Start.notify();
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
 
   EXPECT_EQ(2, Builds.load()) << "Middle build should be skipped";
   EXPECT_EQ(4, Actions.load()) << "All actions should run (some with error)";
@@ -462,7 +462,7 @@
 ADD_FAILURE() << "Shouldn't build, identical to previous";
   });
   Start.notify();
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
 
   EXPECT_EQ(1, Actions.load()) << "All actions should run";
 }
@@ -569,7 +569,7 @@
 }
   }
 }
-ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   } // TUScheduler destructor waits for all operations to finish.
 
   std::lock_guard Lock(Mut);
@@ -611,7 +611,7 @@
   // one that the cache will evict.
   updateWithCallback(S, Foo, SourceContents, WantDiagnostics::Yes,
  []() { ++BuiltASTCounter; });
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   ASSERT_EQ(BuiltASTCounter.load(), 1);
   EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "hit"), SizeIs(0));
   EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "miss"), SizeIs(1));
@@ -622,7 +622,7 @@
  []() { ++BuiltASTCounter; });
   updateWithCallback(S, Baz, SourceContents, WantDiagnostics::Yes,
  []() { ++BuiltASTCounter; });
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   ASSERT_EQ(BuiltASTCounter.load(), 3);
   EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "hit"), SizeIs(0));
   EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "miss"), SizeIs(2));
@@ -633,7 +633,7 @@
   // Access the old file again.
   updateWithCallback(S, Foo, OtherSourceContents, WantDiagnostics::Yes,
  []() { ++BuiltASTCounter; });
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60)));
   ASSERT_EQ(BuiltASTCounter.load(), 4);
   EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "hit"), SizeIs(0));
   EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "miss"), SizeIs(1));
@@ -659,16 +659,16 @@
 
   // After opening Foo then Bar, AST cache contains Bar.
   S.update(Foo, FooInputs, WantDiagnostics::Auto);
-  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
+  

[PATCH] D159337: [clangd][tests] Assert for idleness of scheduler

2023-09-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added reviewers: sammccall, nridge.
Herald added subscribers: arphaman, javed.absar.
Herald added a project: All.
kadircet requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

We could fail going idle in 5 seconds and get spurious errors
afterwards. See https://github.com/llvm/llvm-project/issues/64964.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D159337

Files:
  clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp


Index: clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
===
--- clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
+++ clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
@@ -1307,7 +1307,7 @@
   ASSERT_THAT(BlockForDiags(PI), testing::Pair("1", "3"));
 
   UnblockPreamble.notify();
-  S.blockUntilIdle(timeoutSeconds(5));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(5)));
 
   // Make sure that we have eventual consistency.
   EXPECT_THAT(Collector.diagVersions().back(), Pair(PI.Version, PI.Version));
@@ -1316,7 +1316,7 @@
   PI.Version = "4";
   PI.Contents = "#define FOO\n" + PI.Version;
   S.update(File, PI, WantDiagnostics::No);
-  S.blockUntilIdle(timeoutSeconds(5));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(5)));
   EXPECT_THAT(Collector.diagVersions().back(), Pair("3", "3"));
 }
 


Index: clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
===
--- clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
+++ clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp
@@ -1307,7 +1307,7 @@
   ASSERT_THAT(BlockForDiags(PI), testing::Pair("1", "3"));
 
   UnblockPreamble.notify();
-  S.blockUntilIdle(timeoutSeconds(5));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(5)));
 
   // Make sure that we have eventual consistency.
   EXPECT_THAT(Collector.diagVersions().back(), Pair(PI.Version, PI.Version));
@@ -1316,7 +1316,7 @@
   PI.Version = "4";
   PI.Contents = "#define FOO\n" + PI.Version;
   S.update(File, PI, WantDiagnostics::No);
-  S.blockUntilIdle(timeoutSeconds(5));
+  ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(5)));
   EXPECT_THAT(Collector.diagVersions().back(), Pair("3", "3"));
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157963: [clang-format] Annotate constructor/destructor names

2023-08-28 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

In D157963#4621206 , 
@HazardyKnusperkeks wrote:

> @kadircet shouldn't you at least say why it got reverted? Even better state 
> your problem and give a chance to fix before you revert?

Hi, https://reviews.llvm.org/rG7590b7657004b33b1a12b05f8e9174db3e192f8c already 
has that context.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157963/new/

https://reviews.llvm.org/D157963

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


[PATCH] D158515: [include-cleaner] Make handling of enum constants similar to members

2023-08-28 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
kadircet marked 2 inline comments as done.
Closed by commit rGab090e9e49ff: [include-cleaner] Make handling of enum 
constants similar to members (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158515/new/

https://reviews.llvm.org/D158515

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


Index: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -50,7 +50,7 @@
   Inputs.ExtraFiles["target.h"] = Target.code().str();
   Inputs.ExtraArgs.push_back("-include");
   Inputs.ExtraArgs.push_back("target.h");
-  Inputs.ExtraArgs.push_back("-std=c++17");
+  Inputs.ExtraArgs.push_back("-std=c++20");
   TestAST AST(Inputs);
   const auto  = AST.sourceManager();
 
@@ -114,7 +114,7 @@
   testWalk("int $explicit^x;", "int y = ^x;");
   testWalk("int $explicit^foo();", "int y = ^foo();");
   testWalk("namespace ns { int $explicit^x; }", "int y = ns::^x;");
-  testWalk("struct $implicit^S { static int x; };", "int y = S::^x;");
+  testWalk("struct S { static int x; };", "int y = S::^x;");
   // Canonical declaration only.
   testWalk("extern int $explicit^x; int x;", "int y = ^x;");
   // Return type of `foo` isn't used.
@@ -309,6 +309,14 @@
 namespace ns { using ::$explicit^Foo; }
 template<> struct ns::Foo {};)cpp",
"ns::^Foo x;");
+  testWalk(R"cpp(
+namespace ns { enum class foo { bar }; }
+using ns::foo;)cpp",
+   "auto x = foo::^bar;");
+  testWalk(R"cpp(
+namespace ns { enum foo { bar }; }
+using ns::foo::$explicit^bar;)cpp",
+   "auto x = ^bar;");
 }
 
 TEST(WalkAST, Using) {
@@ -338,6 +346,8 @@
 }
 using ns::$explicit^Y;)cpp",
"^Y x;");
+  testWalk("namespace ns { enum E {A}; } using enum ns::$explicit^E;",
+   "auto x = ^A;");
 }
 
 TEST(WalkAST, Namespaces) {
@@ -399,10 +409,10 @@
 }
 
 TEST(WalkAST, MemberExprs) {
-  testWalk("struct $implicit^S { static int f; };", "void foo() { S::^f; }");
-  testWalk("struct B { static int f; }; struct $implicit^S : B {};",
+  testWalk("struct S { static int f; };", "void foo() { S::^f; }");
+  testWalk("struct B { static int f; }; struct S : B {};",
"void foo() { S::^f; }");
-  testWalk("struct B { static void f(); }; struct $implicit^S : B {};",
+  testWalk("struct B { static void f(); }; struct S : B {};",
"void foo() { S::^f; }");
   testWalk("struct B { static void f(); }; ",
"struct S : B { void foo() { ^f(); } };");
Index: clang-tools-extra/include-cleaner/lib/WalkAST.cpp
===
--- clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -126,13 +126,22 @@
   }
 
   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
-// Static class members are handled here, as they don't produce 
MemberExprs.
-if (DRE->getFoundDecl()->isCXXClassMember()) {
-  if (auto *Qual = DRE->getQualifier())
-report(DRE->getLocation(), Qual->getAsRecordDecl(), RefType::Implicit);
-} else {
-  report(DRE->getLocation(), DRE->getFoundDecl());
+auto *FD = DRE->getFoundDecl();
+// For refs to non-meber-like decls, use the found decl.
+// For member-like decls, we should have a reference from the qualifier to
+// the container decl instead, which is preferred as it'll handle
+// aliases/exports properly.
+if (!FD->isCXXClassMember() && !llvm::isa(FD)) {
+  report(DRE->getLocation(), FD);
+  return true;
 }
+// If the ref is without a qualifier, and is a member, ignore it. As it is
+// available in current context due to some other construct (e.g. base
+// specifiers, using decls) that has to spell the name explicitly.
+// If it's an enum constant, it must be due to prior decl. Report 
references
+// to it instead.
+if (llvm::isa(FD) && !DRE->hasQualifier())
+  report(DRE->getLocation(), FD);
 return true;
   }
 


Index: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -50,7 +50,7 @@
   Inputs.ExtraFiles["target.h"] = Target.code().str();
   Inputs.ExtraArgs.push_back("-include");
   Inputs.ExtraArgs.push_back("target.h");
-  Inputs.ExtraArgs.push_back("-std=c++17");
+  Inputs.ExtraArgs.push_back("-std=c++20");
   TestAST AST(Inputs);
   const auto  = AST.sourceManager();
 
@@ -114,7 +114,7 @@
   testWalk("int $explicit^x;", "int y = ^x;");
   testWalk("int 

[PATCH] D158515: [include-cleaner] Make handling of enum constants similar to members

2023-08-22 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet updated this revision to Diff 552392.
kadircet added a comment.

- Change to c++20


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158515/new/

https://reviews.llvm.org/D158515

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


Index: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -50,7 +50,7 @@
   Inputs.ExtraFiles["target.h"] = Target.code().str();
   Inputs.ExtraArgs.push_back("-include");
   Inputs.ExtraArgs.push_back("target.h");
-  Inputs.ExtraArgs.push_back("-std=c++17");
+  Inputs.ExtraArgs.push_back("-std=c++20");
   TestAST AST(Inputs);
   const auto  = AST.sourceManager();
 
@@ -114,7 +114,7 @@
   testWalk("int $explicit^x;", "int y = ^x;");
   testWalk("int $explicit^foo();", "int y = ^foo();");
   testWalk("namespace ns { int $explicit^x; }", "int y = ns::^x;");
-  testWalk("struct $implicit^S { static int x; };", "int y = S::^x;");
+  testWalk("struct S { static int x; };", "int y = S::^x;");
   // Canonical declaration only.
   testWalk("extern int $explicit^x; int x;", "int y = ^x;");
   // Return type of `foo` isn't used.
@@ -309,6 +309,14 @@
 namespace ns { using ::$explicit^Foo; }
 template<> struct ns::Foo {};)cpp",
"ns::^Foo x;");
+  testWalk(R"cpp(
+namespace ns { enum class foo { bar }; }
+using ns::foo;)cpp",
+   "auto x = foo::^bar;");
+  testWalk(R"cpp(
+namespace ns { enum foo { bar }; }
+using ns::foo::$explicit^bar;)cpp",
+   "auto x = ^bar;");
 }
 
 TEST(WalkAST, Using) {
@@ -338,6 +346,8 @@
 }
 using ns::$explicit^Y;)cpp",
"^Y x;");
+  testWalk("namespace ns { enum E {A}; } using enum ns::$explicit^E;",
+   "auto x = ^A;");
 }
 
 TEST(WalkAST, Namespaces) {
@@ -399,10 +409,10 @@
 }
 
 TEST(WalkAST, MemberExprs) {
-  testWalk("struct $implicit^S { static int f; };", "void foo() { S::^f; }");
-  testWalk("struct B { static int f; }; struct $implicit^S : B {};",
+  testWalk("struct S { static int f; };", "void foo() { S::^f; }");
+  testWalk("struct B { static int f; }; struct S : B {};",
"void foo() { S::^f; }");
-  testWalk("struct B { static void f(); }; struct $implicit^S : B {};",
+  testWalk("struct B { static void f(); }; struct S : B {};",
"void foo() { S::^f; }");
   testWalk("struct B { static void f(); }; ",
"struct S : B { void foo() { ^f(); } };");
Index: clang-tools-extra/include-cleaner/lib/WalkAST.cpp
===
--- clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -126,13 +126,22 @@
   }
 
   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
-// Static class members are handled here, as they don't produce 
MemberExprs.
-if (DRE->getFoundDecl()->isCXXClassMember()) {
-  if (auto *Qual = DRE->getQualifier())
-report(DRE->getLocation(), Qual->getAsRecordDecl(), RefType::Implicit);
-} else {
-  report(DRE->getLocation(), DRE->getFoundDecl());
+auto *FD = DRE->getFoundDecl();
+// For refs to non-meber-like decls, use the found decl.
+// For member-like decls, we should have a reference from the qualifier to
+// the container decl instead, which is preferred as it'll handle
+// aliases/exports properly.
+if (!FD->isCXXClassMember() && !llvm::isa(FD)) {
+  report(DRE->getLocation(), FD);
+  return true;
 }
+// If the ref is without a qualifier, and is a member, ignore it. As it is
+// available in current context due to some other construct (e.g. base
+// specifiers, using decls) that has to spell the name explicitly.
+// If it's an enum constant, it must be due to prior decl. Report 
references
+// to it instead.
+if (llvm::isa(FD) && !DRE->hasQualifier())
+  report(DRE->getLocation(), FD);
 return true;
   }
 


Index: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -50,7 +50,7 @@
   Inputs.ExtraFiles["target.h"] = Target.code().str();
   Inputs.ExtraArgs.push_back("-include");
   Inputs.ExtraArgs.push_back("target.h");
-  Inputs.ExtraArgs.push_back("-std=c++17");
+  Inputs.ExtraArgs.push_back("-std=c++20");
   TestAST AST(Inputs);
   const auto  = AST.sourceManager();
 
@@ -114,7 +114,7 @@
   testWalk("int $explicit^x;", "int y = ^x;");
   testWalk("int $explicit^foo();", "int y = ^foo();");
   testWalk("namespace ns { int $explicit^x; }", "int y = ns::^x;");
-  testWalk("struct $implicit^S { static int x; };", 

[PATCH] D158515: [include-cleaner] Make handling of enum constants similar to members

2023-08-22 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet updated this revision to Diff 552391.
kadircet added a comment.

- Add test for using enums
- Drop implicit references from qualified names to their containers, as we 
should already have explicit references from the spelling of the qualifier.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158515/new/

https://reviews.llvm.org/D158515

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


Index: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -114,7 +114,7 @@
   testWalk("int $explicit^x;", "int y = ^x;");
   testWalk("int $explicit^foo();", "int y = ^foo();");
   testWalk("namespace ns { int $explicit^x; }", "int y = ns::^x;");
-  testWalk("struct $implicit^S { static int x; };", "int y = S::^x;");
+  testWalk("struct S { static int x; };", "int y = S::^x;");
   // Canonical declaration only.
   testWalk("extern int $explicit^x; int x;", "int y = ^x;");
   // Return type of `foo` isn't used.
@@ -309,6 +309,14 @@
 namespace ns { using ::$explicit^Foo; }
 template<> struct ns::Foo {};)cpp",
"ns::^Foo x;");
+  testWalk(R"cpp(
+namespace ns { enum class foo { bar }; }
+using ns::foo;)cpp",
+   "auto x = foo::^bar;");
+  testWalk(R"cpp(
+namespace ns { enum foo { bar }; }
+using ns::foo::$explicit^bar;)cpp",
+   "auto x = ^bar;");
 }
 
 TEST(WalkAST, Using) {
@@ -338,6 +346,8 @@
 }
 using ns::$explicit^Y;)cpp",
"^Y x;");
+  testWalk("namespace ns { enum E {A}; } using enum ns::$explicit^E;",
+   "auto x = ^A;");
 }
 
 TEST(WalkAST, Namespaces) {
@@ -399,10 +409,10 @@
 }
 
 TEST(WalkAST, MemberExprs) {
-  testWalk("struct $implicit^S { static int f; };", "void foo() { S::^f; }");
-  testWalk("struct B { static int f; }; struct $implicit^S : B {};",
+  testWalk("struct S { static int f; };", "void foo() { S::^f; }");
+  testWalk("struct B { static int f; }; struct S : B {};",
"void foo() { S::^f; }");
-  testWalk("struct B { static void f(); }; struct $implicit^S : B {};",
+  testWalk("struct B { static void f(); }; struct S : B {};",
"void foo() { S::^f; }");
   testWalk("struct B { static void f(); }; ",
"struct S : B { void foo() { ^f(); } };");
Index: clang-tools-extra/include-cleaner/lib/WalkAST.cpp
===
--- clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -126,13 +126,22 @@
   }
 
   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
-// Static class members are handled here, as they don't produce 
MemberExprs.
-if (DRE->getFoundDecl()->isCXXClassMember()) {
-  if (auto *Qual = DRE->getQualifier())
-report(DRE->getLocation(), Qual->getAsRecordDecl(), RefType::Implicit);
-} else {
-  report(DRE->getLocation(), DRE->getFoundDecl());
+auto *FD = DRE->getFoundDecl();
+// For refs to non-meber-like decls, use the found decl.
+// For member-like decls, we should have a reference from the qualifier to
+// the container decl instead, which is preferred as it'll handle
+// aliases/exports properly.
+if (!FD->isCXXClassMember() && !llvm::isa(FD)) {
+  report(DRE->getLocation(), FD);
+  return true;
 }
+// If the ref is without a qualifier, and is a member, ignore it. As it is
+// available in current context due to some other construct (e.g. base
+// specifiers, using decls) that has to spell the name explicitly.
+// If it's an enum constant, it must be due to prior decl. Report 
references
+// to it instead.
+if (llvm::isa(FD) && !DRE->hasQualifier())
+  report(DRE->getLocation(), FD);
 return true;
   }
 


Index: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -114,7 +114,7 @@
   testWalk("int $explicit^x;", "int y = ^x;");
   testWalk("int $explicit^foo();", "int y = ^foo();");
   testWalk("namespace ns { int $explicit^x; }", "int y = ns::^x;");
-  testWalk("struct $implicit^S { static int x; };", "int y = S::^x;");
+  testWalk("struct S { static int x; };", "int y = S::^x;");
   // Canonical declaration only.
   testWalk("extern int $explicit^x; int x;", "int y = ^x;");
   // Return type of `foo` isn't used.
@@ -309,6 +309,14 @@
 namespace ns { using ::$explicit^Foo; }
 template<> struct ns::Foo {};)cpp",
"ns::^Foo x;");
+  testWalk(R"cpp(
+namespace ns { enum class foo { bar }; }
+using ns::foo;)cpp",
+   "auto x = 

[PATCH] D158426: [clangd] Bump timeouts for LSPServerTests

2023-08-22 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG8c21544286a0: [clangd] Bump timeouts for LSPServerTests 
(authored by kadircet).

Changed prior to commit:
  https://reviews.llvm.org/D158426?vs=552284=552354#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158426/new/

https://reviews.llvm.org/D158426

Files:
  clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
  clang-tools-extra/clangd/unittests/LSPClient.cpp
  clang-tools-extra/clangd/unittests/LSPClient.h

Index: clang-tools-extra/clangd/unittests/LSPClient.h
===
--- clang-tools-extra/clangd/unittests/LSPClient.h
+++ clang-tools-extra/clangd/unittests/LSPClient.h
@@ -9,12 +9,14 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H
 
+#include "llvm/ADT/StringRef.h"
+#include 
 #include 
 #include 
-#include 
-#include 
+#include 
 #include 
 #include 
+#include 
 
 namespace clang {
 namespace clangd {
@@ -32,7 +34,7 @@
   class CallResult {
   public:
 ~CallResult();
-// Blocks up to 10 seconds for the result to be ready.
+// Blocks up to 60 seconds for the result to be ready.
 // Records a test failure if there was no reply.
 llvm::Expected take();
 // Like take(), but records a test failure if the result was an error.
Index: clang-tools-extra/clangd/unittests/LSPClient.cpp
===
--- clang-tools-extra/clangd/unittests/LSPClient.cpp
+++ clang-tools-extra/clangd/unittests/LSPClient.cpp
@@ -12,21 +12,36 @@
 #include "Transport.h"
 #include "support/Logger.h"
 #include "support/Threading.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/JSON.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include "gtest/gtest.h"
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 namespace clang {
 namespace clangd {
 
 llvm::Expected clang::clangd::LSPClient::CallResult::take() {
   std::unique_lock Lock(Mu);
-  if (!clangd::wait(Lock, CV, timeoutSeconds(10),
+  static constexpr size_t TimeoutSecs = 60;
+  if (!clangd::wait(Lock, CV, timeoutSeconds(TimeoutSecs),
 [this] { return Value.has_value(); })) {
-ADD_FAILURE() << "No result from call after 10 seconds!";
+ADD_FAILURE() << "No result from call after " << TimeoutSecs << " seconds!";
 return llvm::json::Value(nullptr);
   }
   auto Res = std::move(*Value);
Index: clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
===
--- clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
+++ clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
@@ -8,19 +8,38 @@
 
 #include "Annotations.h"
 #include "ClangdLSPServer.h"
+#include "ClangdServer.h"
+#include "ConfigProvider.h"
+#include "Diagnostics.h"
+#include "FeatureModule.h"
+#include "LSPBinder.h"
 #include "LSPClient.h"
-#include "Protocol.h"
 #include "TestFS.h"
+#include "support/Function.h"
 #include "support/Logger.h"
 #include "support/TestTracer.h"
+#include "support/Threading.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/FunctionExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/JSON.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Testing/Support/Error.h"
 #include "llvm/Testing/Support/SupportHelpers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
+#include 
+#include 
 
 namespace clang {
 namespace clangd {
@@ -358,7 +377,7 @@
   Client.notify("increment", nullptr);
   Client.notify("increment", nullptr);
   Client.notify("increment", nullptr);
-  EXPECT_THAT_EXPECTED(Client.call("sync", nullptr).take(), Succeeded());
+  Client.sync();
   EXPECT_EQ(3, FeatureModules.get()->getSync());
   // Throw some work on the queue to make sure shutdown blocks on it.
   Client.notify("increment", nullptr);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D158515: [include-cleaner] Make handling of enum constants similar to members

2023-08-22 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added a reviewer: sammccall.
Herald added a project: All.
kadircet requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

We were treating enum constants more like regular decls, which results
in ignoring type aliases/exports.
This patch brings the handling to be closer to member-like decls, with
one caveat. When we encounter reference to an enum constant we still
report an explicit reference to the particular enum constant, as
otherwise we might not see any references to the enum itself.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D158515

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


Index: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -309,6 +309,14 @@
 namespace ns { using ::$explicit^Foo; }
 template<> struct ns::Foo {};)cpp",
"ns::^Foo x;");
+  testWalk(R"cpp(
+namespace ns { enum class foo { bar }; }
+using ns::$implicit^foo;)cpp",
+   "auto x = foo::^bar;");
+  testWalk(R"cpp(
+namespace ns { enum foo { bar }; }
+using ns::foo::$explicit^bar;)cpp",
+   "auto x = ^bar;");
 }
 
 TEST(WalkAST, Using) {
Index: clang-tools-extra/include-cleaner/lib/WalkAST.cpp
===
--- clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -126,13 +126,27 @@
   }
 
   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
-// Static class members are handled here, as they don't produce 
MemberExprs.
-if (DRE->getFoundDecl()->isCXXClassMember()) {
-  if (auto *Qual = DRE->getQualifier())
-report(DRE->getLocation(), Qual->getAsRecordDecl(), RefType::Implicit);
-} else {
-  report(DRE->getLocation(), DRE->getFoundDecl());
+auto *FD = DRE->getFoundDecl();
+// For refs to non-meber-like decls, use the found decl.
+if (!FD->isCXXClassMember() && !llvm::isa(FD)) {
+  report(DRE->getLocation(), FD);
+  return true;
+}
+// For refs to member-like decls, report an implicit ref to the container.
+if (auto *Qual = DRE->getQualifier()) {
+  if (auto *Ty = Qual->getAsType()) {
+report(DRE->getLocation(), getMemberProvider(QualType(Ty, 0)),
+   RefType::Implicit);
+  }
+  return true;
 }
+// If the ref is without a qualifier, and is a member, ignore it. As it is
+// available in current context due to some other construct (e.g. base
+// specifiers, using decls) that has to spell the name explicitly.
+// If it's an enum constant, it must be due to prior decl. Report 
references
+// to it instead.
+if (llvm::isa(FD))
+  report(DRE->getLocation(), FD);
 return true;
   }
 


Index: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -309,6 +309,14 @@
 namespace ns { using ::$explicit^Foo; }
 template<> struct ns::Foo {};)cpp",
"ns::^Foo x;");
+  testWalk(R"cpp(
+namespace ns { enum class foo { bar }; }
+using ns::$implicit^foo;)cpp",
+   "auto x = foo::^bar;");
+  testWalk(R"cpp(
+namespace ns { enum foo { bar }; }
+using ns::foo::$explicit^bar;)cpp",
+   "auto x = ^bar;");
 }
 
 TEST(WalkAST, Using) {
Index: clang-tools-extra/include-cleaner/lib/WalkAST.cpp
===
--- clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -126,13 +126,27 @@
   }
 
   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
-// Static class members are handled here, as they don't produce MemberExprs.
-if (DRE->getFoundDecl()->isCXXClassMember()) {
-  if (auto *Qual = DRE->getQualifier())
-report(DRE->getLocation(), Qual->getAsRecordDecl(), RefType::Implicit);
-} else {
-  report(DRE->getLocation(), DRE->getFoundDecl());
+auto *FD = DRE->getFoundDecl();
+// For refs to non-meber-like decls, use the found decl.
+if (!FD->isCXXClassMember() && !llvm::isa(FD)) {
+  report(DRE->getLocation(), FD);
+  return true;
+}
+// For refs to member-like decls, report an implicit ref to the container.
+if (auto *Qual = DRE->getQualifier()) {
+  if (auto *Ty = Qual->getAsType()) {
+report(DRE->getLocation(), getMemberProvider(QualType(Ty, 0)),
+   RefType::Implicit);
+  }
+  return true;
 }
+// If the ref is without a qualifier, and is 

[PATCH] D158426: [clangd] Bump timeouts for LSPServerTests

2023-08-22 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet updated this revision to Diff 552284.
kadircet marked 2 inline comments as done.
kadircet added a comment.

- Just bump the timeouts


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158426/new/

https://reviews.llvm.org/D158426

Files:
  clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
  clang-tools-extra/clangd/unittests/LSPClient.cpp
  clang-tools-extra/clangd/unittests/LSPClient.h

Index: clang-tools-extra/clangd/unittests/LSPClient.h
===
--- clang-tools-extra/clangd/unittests/LSPClient.h
+++ clang-tools-extra/clangd/unittests/LSPClient.h
@@ -9,12 +9,14 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H
 
+#include "llvm/ADT/StringRef.h"
+#include 
 #include 
 #include 
-#include 
-#include 
+#include 
 #include 
 #include 
+#include 
 
 namespace clang {
 namespace clangd {
@@ -32,7 +34,8 @@
   class CallResult {
   public:
 ~CallResult();
-// Blocks up to 10 seconds for the result to be ready.
+// Blocks up to \p TimeoutSeconds seconds for the result to be ready. If \p
+// TimeoutSeconds is zero, blocks indefinitely.
 // Records a test failure if there was no reply.
 llvm::Expected take();
 // Like take(), but records a test failure if the result was an error.
Index: clang-tools-extra/clangd/unittests/LSPClient.cpp
===
--- clang-tools-extra/clangd/unittests/LSPClient.cpp
+++ clang-tools-extra/clangd/unittests/LSPClient.cpp
@@ -12,19 +12,32 @@
 #include "Transport.h"
 #include "support/Logger.h"
 #include "support/Threading.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/JSON.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include "gtest/gtest.h"
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 namespace clang {
 namespace clangd {
 
 llvm::Expected clang::clangd::LSPClient::CallResult::take() {
   std::unique_lock Lock(Mu);
-  if (!clangd::wait(Lock, CV, timeoutSeconds(10),
+  if (!clangd::wait(Lock, CV, timeoutSeconds(60),
 [this] { return Value.has_value(); })) {
 ADD_FAILURE() << "No result from call after 10 seconds!";
 return llvm::json::Value(nullptr);
Index: clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
===
--- clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
+++ clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
@@ -8,19 +8,38 @@
 
 #include "Annotations.h"
 #include "ClangdLSPServer.h"
+#include "ClangdServer.h"
+#include "ConfigProvider.h"
+#include "Diagnostics.h"
+#include "FeatureModule.h"
+#include "LSPBinder.h"
 #include "LSPClient.h"
-#include "Protocol.h"
 #include "TestFS.h"
+#include "support/Function.h"
 #include "support/Logger.h"
 #include "support/TestTracer.h"
+#include "support/Threading.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/FunctionExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/JSON.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Testing/Support/Error.h"
 #include "llvm/Testing/Support/SupportHelpers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
+#include 
+#include 
 
 namespace clang {
 namespace clangd {
@@ -358,7 +377,7 @@
   Client.notify("increment", nullptr);
   Client.notify("increment", nullptr);
   Client.notify("increment", nullptr);
-  EXPECT_THAT_EXPECTED(Client.call("sync", nullptr).take(), Succeeded());
+  Client.sync();
   EXPECT_EQ(3, FeatureModules.get()->getSync());
   // Throw some work on the queue to make sure shutdown blocks on it.
   Client.notify("increment", nullptr);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D158426: [clangd] Bump timeouts for LSPServerTests

2023-08-21 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added reviewers: sammccall, nridge.
Herald added a subscriber: arphaman.
Herald added a project: All.
kadircet requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

We seem to be hitting limits in some windows build bots, see
https://github.com/clangd/clangd/issues/1712#issuecomment-1686478931.

So bumping the timeouts to 60 seconds and completely dropping them for sync
requests. As mentioned in the comment above, this should improve things,
considering even the tests that don't touch any complicated scheduler is
failing.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D158426

Files:
  clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
  clang-tools-extra/clangd/unittests/LSPClient.cpp
  clang-tools-extra/clangd/unittests/LSPClient.h

Index: clang-tools-extra/clangd/unittests/LSPClient.h
===
--- clang-tools-extra/clangd/unittests/LSPClient.h
+++ clang-tools-extra/clangd/unittests/LSPClient.h
@@ -9,12 +9,14 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H
 
+#include "llvm/ADT/StringRef.h"
+#include 
 #include 
 #include 
-#include 
-#include 
+#include 
 #include 
 #include 
+#include 
 
 namespace clang {
 namespace clangd {
@@ -32,11 +34,12 @@
   class CallResult {
   public:
 ~CallResult();
-// Blocks up to 10 seconds for the result to be ready.
+// Blocks up to \p TimeoutSeconds seconds for the result to be ready. If \p
+// TimeoutSeconds is zero, blocks indefinitely.
 // Records a test failure if there was no reply.
-llvm::Expected take();
+llvm::Expected take(float TimeoutSeconds = 60);
 // Like take(), but records a test failure if the result was an error.
-llvm::json::Value takeValue();
+llvm::json::Value takeValue(float TimeoutSeconds = 60);
 
   private:
 // Should be called once to provide the value.
Index: clang-tools-extra/clangd/unittests/LSPClient.cpp
===
--- clang-tools-extra/clangd/unittests/LSPClient.cpp
+++ clang-tools-extra/clangd/unittests/LSPClient.cpp
@@ -12,19 +12,36 @@
 #include "Transport.h"
 #include "support/Logger.h"
 #include "support/Threading.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/JSON.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include "gtest/gtest.h"
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 namespace clang {
 namespace clangd {
 
-llvm::Expected clang::clangd::LSPClient::CallResult::take() {
+llvm::Expected
+clang::clangd::LSPClient::CallResult::take(float TimeoutSeconds) {
   std::unique_lock Lock(Mu);
-  if (!clangd::wait(Lock, CV, timeoutSeconds(10),
+  if (!clangd::wait(Lock, CV,
+timeoutSeconds(TimeoutSeconds
+   ? std::optional(TimeoutSeconds)
+   : std::nullopt),
 [this] { return Value.has_value(); })) {
 ADD_FAILURE() << "No result from call after 10 seconds!";
 return llvm::json::Value(nullptr);
@@ -34,8 +51,8 @@
   return Res;
 }
 
-llvm::json::Value LSPClient::CallResult::takeValue() {
-  auto ExpValue = take();
+llvm::json::Value LSPClient::CallResult::takeValue(float TimeoutSeconds) {
+  auto ExpValue = take(TimeoutSeconds);
   if (!ExpValue) {
 ADD_FAILURE() << "takeValue(): " << llvm::toString(ExpValue.takeError());
 return llvm::json::Value(nullptr);
@@ -197,7 +214,10 @@
   notify("textDocument/didClose", Obj{{"textDocument", documentID(Path)}});
 }
 
-void LSPClient::sync() { call("sync", nullptr).takeValue(); }
+void LSPClient::sync() {
+  // Sync should already be implemented with a timeout, so don't timeout.
+  call("sync", nullptr).takeValue(0);
+}
 
 std::optional>
 LSPClient::diagnostics(llvm::StringRef Path) {
Index: clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
===
--- clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
+++ clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
@@ -8,19 +8,38 @@
 
 #include "Annotations.h"
 #include "ClangdLSPServer.h"
+#include "ClangdServer.h"
+#include "ConfigProvider.h"
+#include "Diagnostics.h"
+#include "FeatureModule.h"
+#include "LSPBinder.h"
 #include "LSPClient.h"
-#include "Protocol.h"
 #include "TestFS.h"
+#include "support/Function.h"
 #include "support/Logger.h"
 #include "support/TestTracer.h"
+#include "support/Threading.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/FunctionExtras.h"
 #include 

[PATCH] D158269: [clang] Prevent possible use-after-free

2023-08-18 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
kadircet marked an inline comment as done.
Closed by commit rG851c248dfcdb: [clang] Prevent possible use-after-free 
(authored by kadircet).

Changed prior to commit:
  https://reviews.llvm.org/D158269?vs=551471=551507#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158269/new/

https://reviews.llvm.org/D158269

Files:
  clang/lib/Parse/ParseObjc.cpp
  clang/test/Parser/objc-delayed-method-use-after-free.m


Index: clang/test/Parser/objc-delayed-method-use-after-free.m
===
--- /dev/null
+++ clang/test/Parser/objc-delayed-method-use-after-free.m
@@ -0,0 +1,13 @@
+// Make sure we don't trigger use-after-free when we encounter a code 
completion
+// token inside a objc method.
+@interface Foo
+@end
+
+@implementation Foo
+- (void)foo {
+
+// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class 
-code-completion-at=%s:%(line-1):1 %s | FileCheck %s
+// CHECK: COMPLETION: self : [#Foo *#]self
+  [self foo];
+}
+@end
Index: clang/lib/Parse/ParseObjc.cpp
===
--- clang/lib/Parse/ParseObjc.cpp
+++ clang/lib/Parse/ParseObjc.cpp
@@ -3764,6 +3764,8 @@
   while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
 ConsumeAnyToken();
   }
-  // Clean up the remaining EOF token.
-  ConsumeAnyToken();
+  // Clean up the remaining EOF token, only if it's inserted by us. Otherwise
+  // this might be code-completion token, which must be propagated to callers.
+  if (Tok.is(tok::eof) && Tok.getEofData() == MCDecl)
+ConsumeAnyToken();
 }


Index: clang/test/Parser/objc-delayed-method-use-after-free.m
===
--- /dev/null
+++ clang/test/Parser/objc-delayed-method-use-after-free.m
@@ -0,0 +1,13 @@
+// Make sure we don't trigger use-after-free when we encounter a code completion
+// token inside a objc method.
+@interface Foo
+@end
+
+@implementation Foo
+- (void)foo {
+
+// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -code-completion-at=%s:%(line-1):1 %s | FileCheck %s
+// CHECK: COMPLETION: self : [#Foo *#]self
+  [self foo];
+}
+@end
Index: clang/lib/Parse/ParseObjc.cpp
===
--- clang/lib/Parse/ParseObjc.cpp
+++ clang/lib/Parse/ParseObjc.cpp
@@ -3764,6 +3764,8 @@
   while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
 ConsumeAnyToken();
   }
-  // Clean up the remaining EOF token.
-  ConsumeAnyToken();
+  // Clean up the remaining EOF token, only if it's inserted by us. Otherwise
+  // this might be code-completion token, which must be propagated to callers.
+  if (Tok.is(tok::eof) && Tok.getEofData() == MCDecl)
+ConsumeAnyToken();
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157905: [include-cleaner] Filter references to identity macros

2023-08-18 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
kadircet marked an inline comment as done.
Closed by commit rG90ecadde62f3: [include-cleaner] Filter references to 
identity macros (authored by kadircet).

Changed prior to commit:
  https://reviews.llvm.org/D157905?vs=550790=551477#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157905/new/

https://reviews.llvm.org/D157905

Files:
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
  clang-tools-extra/clangd/Hover.cpp
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/clangd/XRefs.cpp
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
  clang-tools-extra/include-cleaner/lib/Analysis.cpp
  clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp
  clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp

Index: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
@@ -66,8 +66,9 @@
   }
 
   std::multimap>
-  offsetToProviders(TestAST , SourceManager ,
+  offsetToProviders(TestAST ,
 llvm::ArrayRef MacroRefs = {}) {
+const auto  = AST.sourceManager();
 llvm::SmallVector TopLevelDecls;
 for (Decl *D : AST.context().getTranslationUnitDecl()->decls()) {
   if (!SM.isWrittenInMainFile(SM.getExpansionLoc(D->getLocation(
@@ -75,7 +76,7 @@
   TopLevelDecls.emplace_back(D);
 }
 std::multimap> OffsetToProviders;
-walkUsed(TopLevelDecls, MacroRefs, , SM,
+walkUsed(TopLevelDecls, MacroRefs, , AST.preprocessor(),
  [&](const SymbolReference , llvm::ArrayRef Providers) {
auto [FID, Offset] = SM.getDecomposedLoc(Ref.RefLocation);
if (FID != SM.getMainFileID())
@@ -118,7 +119,7 @@
   auto VectorSTL = Header(*tooling::stdlib::Header::named(""));
   auto UtilitySTL = Header(*tooling::stdlib::Header::named(""));
   EXPECT_THAT(
-  offsetToProviders(AST, SM),
+  offsetToProviders(AST),
   UnorderedElementsAre(
   Pair(Code.point("bar"), UnorderedElementsAre(MainFile)),
   Pair(Code.point("private"),
@@ -155,7 +156,7 @@
   auto HeaderFile2 = Header(AST.fileManager().getFile("header2.h").get());
   auto MainFile = Header(SM.getFileEntryForID(SM.getMainFileID()));
   EXPECT_THAT(
-  offsetToProviders(AST, SM),
+  offsetToProviders(AST),
   Contains(Pair(Code.point("foo"),
 UnorderedElementsAre(HeaderFile1, HeaderFile2, MainFile;
 }
@@ -171,19 +172,19 @@
   Inputs.ExtraFiles["hdr.h"] = Hdr.code();
   TestAST AST(Inputs);
   auto  = AST.sourceManager();
+  auto  = AST.preprocessor();
   const auto *HdrFile = SM.getFileManager().getFile("hdr.h").get();
   auto MainFile = Header(SM.getFileEntryForID(SM.getMainFileID()));
 
   auto HdrID = SM.translateFile(HdrFile);
 
-  IdentifierTable Idents;
-  Symbol Answer1 =
-  Macro{("ANSWER"), SM.getComposedLoc(HdrID, Hdr.point())};
-  Symbol Answer2 =
-  Macro{("ANSWER"), SM.getComposedLoc(HdrID, Hdr.point())};
+  Symbol Answer1 = Macro{PP.getIdentifierInfo("ANSWER"),
+ SM.getComposedLoc(HdrID, Hdr.point())};
+  Symbol Answer2 = Macro{PP.getIdentifierInfo("ANSWER"),
+ SM.getComposedLoc(HdrID, Hdr.point())};
   EXPECT_THAT(
   offsetToProviders(
-  AST, SM,
+  AST,
   {SymbolReference{
Answer1, SM.getComposedLoc(SM.getMainFileID(), Code.point("1")),
RefType::Explicit},
@@ -240,8 +241,7 @@
   auto Decls = AST.context().getTranslationUnitDecl()->decls();
   auto Results =
   analyze(std::vector{Decls.begin(), Decls.end()},
-  PP.MacroReferences, PP.Includes, , AST.sourceManager(),
-  AST.preprocessor().getHeaderSearchInfo());
+  PP.MacroReferences, PP.Includes, , AST.preprocessor());
 
   const Include *B = PP.Includes.atLine(3);
   ASSERT_EQ(B->Spelled, "b.h");
@@ -257,8 +257,7 @@
   Inputs.FileName = "public.h";
   TestAST AST(Inputs);
   EXPECT_FALSE(PP.Includes.all().empty());
-  auto Results = analyze({}, {}, PP.Includes, , AST.sourceManager(),
- AST.preprocessor().getHeaderSearchInfo());
+  auto Results = analyze({}, {}, PP.Includes, , AST.preprocessor());
   EXPECT_THAT(Results.Unused, testing::IsEmpty());
 }
 
@@ -268,8 +267,7 @@
   Inputs.ErrorOK = true;
   TestAST AST(Inputs);
   EXPECT_FALSE(PP.Includes.all().empty());
-  auto Results = analyze({}, {}, PP.Includes, , AST.sourceManager(),
- AST.preprocessor().getHeaderSearchInfo());
+  auto Results = analyze({}, {}, PP.Includes, , AST.preprocessor());
   EXPECT_THAT(Results.Unused, testing::IsEmpty());
 }
 
@@ -409,7 +407,7 @@
 
 

[PATCH] D158269: [clang] Prevent possible use-after-free

2023-08-18 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added reviewers: sammccall, ilya-biryukov.
Herald added a project: All.
kadircet requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This prevents further parsing of tokens (that'll be freed) inside method
body by propagating EOF emitted by reaching code completion token up the parsing
stack.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D158269

Files:
  clang/lib/Parse/ParseObjc.cpp
  clang/test/Parser/objc-delayed-method-use-after-free.m


Index: clang/test/Parser/objc-delayed-method-use-after-free.m
===
--- /dev/null
+++ clang/test/Parser/objc-delayed-method-use-after-free.m
@@ -0,0 +1,13 @@
+// Make sure we don't trigger use-after-free when we encounter a code 
completion
+// token inside a objc method.
+@interface Foo
+@end
+
+@implementation Foo
+- (void)foo {
+
+// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class 
-code-completion-at=%s:%(line-1):1 %s | FileCheck %s
+// CHECK: COMPLETION: self : [#Foo *#]self
+  [self foo];
+}
+@end
Index: clang/lib/Parse/ParseObjc.cpp
===
--- clang/lib/Parse/ParseObjc.cpp
+++ clang/lib/Parse/ParseObjc.cpp
@@ -3764,6 +3764,8 @@
   while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
 ConsumeAnyToken();
   }
-  // Clean up the remaining EOF token.
-  ConsumeAnyToken();
+  // Clean up the remaining EOF token, only if it's inserted by us. Otherwise
+  // this might be code-completion token, so leave it.
+  if (Tok.is(tok::eof) && Tok.getEofData() == MCDecl)
+ConsumeAnyToken();
 }


Index: clang/test/Parser/objc-delayed-method-use-after-free.m
===
--- /dev/null
+++ clang/test/Parser/objc-delayed-method-use-after-free.m
@@ -0,0 +1,13 @@
+// Make sure we don't trigger use-after-free when we encounter a code completion
+// token inside a objc method.
+@interface Foo
+@end
+
+@implementation Foo
+- (void)foo {
+
+// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -code-completion-at=%s:%(line-1):1 %s | FileCheck %s
+// CHECK: COMPLETION: self : [#Foo *#]self
+  [self foo];
+}
+@end
Index: clang/lib/Parse/ParseObjc.cpp
===
--- clang/lib/Parse/ParseObjc.cpp
+++ clang/lib/Parse/ParseObjc.cpp
@@ -3764,6 +3764,8 @@
   while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
 ConsumeAnyToken();
   }
-  // Clean up the remaining EOF token.
-  ConsumeAnyToken();
+  // Clean up the remaining EOF token, only if it's inserted by us. Otherwise
+  // this might be code-completion token, so leave it.
+  if (Tok.is(tok::eof) && Tok.getEofData() == MCDecl)
+ConsumeAnyToken();
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157905: [include-cleaner] Filter references to identity macros

2023-08-16 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet updated this revision to Diff 550790.
kadircet added a comment.
Herald added subscribers: PiotrZSL, carlosgalvezp, arphaman.
Herald added a reviewer: njames93.

- Apply filtering only to macros that expand to themselves


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157905/new/

https://reviews.llvm.org/D157905

Files:
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
  clang-tools-extra/clangd/Hover.cpp
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/clangd/XRefs.cpp
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
  clang-tools-extra/include-cleaner/lib/Analysis.cpp
  clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp
  clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp

Index: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
@@ -66,8 +66,9 @@
   }
 
   std::multimap>
-  offsetToProviders(TestAST , SourceManager ,
+  offsetToProviders(TestAST ,
 llvm::ArrayRef MacroRefs = {}) {
+const auto  = AST.sourceManager();
 llvm::SmallVector TopLevelDecls;
 for (Decl *D : AST.context().getTranslationUnitDecl()->decls()) {
   if (!SM.isWrittenInMainFile(SM.getExpansionLoc(D->getLocation(
@@ -75,7 +76,7 @@
   TopLevelDecls.emplace_back(D);
 }
 std::multimap> OffsetToProviders;
-walkUsed(TopLevelDecls, MacroRefs, , SM,
+walkUsed(TopLevelDecls, MacroRefs, , AST.preprocessor(),
  [&](const SymbolReference , llvm::ArrayRef Providers) {
auto [FID, Offset] = SM.getDecomposedLoc(Ref.RefLocation);
if (FID != SM.getMainFileID())
@@ -118,7 +119,7 @@
   auto VectorSTL = Header(*tooling::stdlib::Header::named(""));
   auto UtilitySTL = Header(*tooling::stdlib::Header::named(""));
   EXPECT_THAT(
-  offsetToProviders(AST, SM),
+  offsetToProviders(AST),
   UnorderedElementsAre(
   Pair(Code.point("bar"), UnorderedElementsAre(MainFile)),
   Pair(Code.point("private"),
@@ -155,7 +156,7 @@
   auto HeaderFile2 = Header(AST.fileManager().getFile("header2.h").get());
   auto MainFile = Header(SM.getFileEntryForID(SM.getMainFileID()));
   EXPECT_THAT(
-  offsetToProviders(AST, SM),
+  offsetToProviders(AST),
   Contains(Pair(Code.point("foo"),
 UnorderedElementsAre(HeaderFile1, HeaderFile2, MainFile;
 }
@@ -171,19 +172,19 @@
   Inputs.ExtraFiles["hdr.h"] = Hdr.code();
   TestAST AST(Inputs);
   auto  = AST.sourceManager();
+  auto  = AST.preprocessor();
   const auto *HdrFile = SM.getFileManager().getFile("hdr.h").get();
   auto MainFile = Header(SM.getFileEntryForID(SM.getMainFileID()));
 
   auto HdrID = SM.translateFile(HdrFile);
 
-  IdentifierTable Idents;
-  Symbol Answer1 =
-  Macro{("ANSWER"), SM.getComposedLoc(HdrID, Hdr.point())};
-  Symbol Answer2 =
-  Macro{("ANSWER"), SM.getComposedLoc(HdrID, Hdr.point())};
+  Symbol Answer1 = Macro{PP.getIdentifierInfo("ANSWER"),
+ SM.getComposedLoc(HdrID, Hdr.point())};
+  Symbol Answer2 = Macro{PP.getIdentifierInfo("ANSWER"),
+ SM.getComposedLoc(HdrID, Hdr.point())};
   EXPECT_THAT(
   offsetToProviders(
-  AST, SM,
+  AST,
   {SymbolReference{
Answer1, SM.getComposedLoc(SM.getMainFileID(), Code.point("1")),
RefType::Explicit},
@@ -240,8 +241,7 @@
   auto Decls = AST.context().getTranslationUnitDecl()->decls();
   auto Results =
   analyze(std::vector{Decls.begin(), Decls.end()},
-  PP.MacroReferences, PP.Includes, , AST.sourceManager(),
-  AST.preprocessor().getHeaderSearchInfo());
+  PP.MacroReferences, PP.Includes, , AST.preprocessor());
 
   const Include *B = PP.Includes.atLine(3);
   ASSERT_EQ(B->Spelled, "b.h");
@@ -257,8 +257,7 @@
   Inputs.FileName = "public.h";
   TestAST AST(Inputs);
   EXPECT_FALSE(PP.Includes.all().empty());
-  auto Results = analyze({}, {}, PP.Includes, , AST.sourceManager(),
- AST.preprocessor().getHeaderSearchInfo());
+  auto Results = analyze({}, {}, PP.Includes, , AST.preprocessor());
   EXPECT_THAT(Results.Unused, testing::IsEmpty());
 }
 
@@ -268,8 +267,7 @@
   Inputs.ErrorOK = true;
   TestAST AST(Inputs);
   EXPECT_FALSE(PP.Includes.all().empty());
-  auto Results = analyze({}, {}, PP.Includes, , AST.sourceManager(),
- AST.preprocessor().getHeaderSearchInfo());
+  auto Results = analyze({}, {}, PP.Includes, , AST.preprocessor());
   EXPECT_THAT(Results.Unused, testing::IsEmpty());
 }
 
@@ -409,7 +407,7 @@
 
 SourceLocation RefLoc;
 walkUsed(TopLevelDecls, Recorded.MacroReferences,
-   

[PATCH] D157905: [include-cleaner] Filter references to identity macros

2023-08-16 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet marked 2 inline comments as done.
kadircet added inline comments.



Comment at: clang-tools-extra/include-cleaner/lib/Analysis.cpp:43
+  // This results in surprising behavior from users point of view (we
+  // generate a usage of stdio.h, in places unrelated to standard library).
+  // FIXME: Also eliminate the false positives by treating declarations

sammccall wrote:
> kadircet wrote:
> > sammccall wrote:
> > > Comment nit: I'm having trouble imagining cases that are 
> > > actually*unrelated* to the stdlib.
> > > 
> > > If `stderr` is an impl-defined macro, then the only way to use the name 
> > > to refer to something else is if it's not defined (inside ifndef stderr, 
> > > or if you can be sure your TU doesn't include stdio first). Seems 
> > > implausible...
> > > 
> > > That said I feel like we've had this conversation before and I've just 
> > > forgotten the details.
> > > If stderr is an impl-defined macro, then the only way to use the name to 
> > > refer to something else is if it's not defined
> > 
> > That's absolutely right. The issue here is macro expansion triggers 
> > independent of the context, e.g.
> > ```
> > #include 
> > namespace ns { void stderr(); }
> > void foo() { ns::stderr(); }
> > ```
> > 
> > here we have a (well two) reference to `stderr` macro from stdandard 
> > library, which is not user's intent, but rather a quirk of the language.
> Sure, but this code is not valid C++ (since `stderr` is not guaranteed to 
> expand to a single identifier). Is this actually a common/motivating case?
> Sure, but this code is not valid C++ (since stderr is not guaranteed to 
> expand to a single identifier).

That's true. Most of the standard library implementations I checked does that, 
but I also don't like that reliance, so making it a little bit more generic 
(which meant some more plumbing, sorry for the big diff :( ), by making sure 
that we apply this to all the macros that expand to themselves.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157905/new/

https://reviews.llvm.org/D157905

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


[PATCH] D158093: [Sema] Clean up ActionResult type a little. NFCI

2023-08-16 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

thanks a lot for doing this, i think this makes it a lot more obvious that this 
is a tristate struct rather than invalid just being a bit that can bit set for 
both null and non-null pointers.




Comment at: clang/include/clang/Sema/Ownership.h:155
+  PtrTy Val = {};
+  bool Invalid;
+

nit: also initialize Invalid to false?



Comment at: clang/include/clang/Sema/Ownership.h:204
+  PtrTy get() const {
+void *VP = reinterpret_cast(Value & ~0x01);
+return PtrTraits::getFromVoidPointer(VP);

nit: `Value == InvalidValue ? nullptr : Value` ?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158093/new/

https://reviews.llvm.org/D158093

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


[PATCH] D157905: [include-cleaner] Filter references to identity macros

2023-08-16 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet marked an inline comment as done.
kadircet added inline comments.



Comment at: clang-tools-extra/include-cleaner/lib/Analysis.cpp:43
+  // This results in surprising behavior from users point of view (we
+  // generate a usage of stdio.h, in places unrelated to standard library).
+  // FIXME: Also eliminate the false positives by treating declarations

sammccall wrote:
> Comment nit: I'm having trouble imagining cases that are actually*unrelated* 
> to the stdlib.
> 
> If `stderr` is an impl-defined macro, then the only way to use the name to 
> refer to something else is if it's not defined (inside ifndef stderr, or if 
> you can be sure your TU doesn't include stdio first). Seems implausible...
> 
> That said I feel like we've had this conversation before and I've just 
> forgotten the details.
> If stderr is an impl-defined macro, then the only way to use the name to 
> refer to something else is if it's not defined

That's absolutely right. The issue here is macro expansion triggers independent 
of the context, e.g.
```
#include 
namespace ns { void stderr(); }
void foo() { ns::stderr(); }
```

here we have a (well two) reference to `stderr` macro from stdandard library, 
which is not user's intent, but rather a quirk of the language.



Comment at: clang-tools-extra/include-cleaner/lib/Analysis.cpp:44
+  // generate a usage of stdio.h, in places unrelated to standard library).
+  // FIXME: Also eliminate the false positives by treating declarations
+  // resulting from these expansions as used.

sammccall wrote:
> Nit: "false positives" is a little unclear: positives for this function are 
> negatives for walkAST and could be either for diagnostics.
> 
> Also, I think you mean *references* rather than declarations?
> 
this should've been "false negatives" from the "usedness perspective", we 
basically drop the reference to `ns::stderr` in above example, because the name 
is not spelled in the main file (but rather spelled inside a macro body).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157905/new/

https://reviews.llvm.org/D157905

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


[PATCH] D157905: [include-cleaner] Filter references to identity macros

2023-08-16 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet updated this revision to Diff 550662.
kadircet marked an inline comment as done.
kadircet added a comment.

- Rename helper, update comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157905/new/

https://reviews.llvm.org/D157905

Files:
  clang-tools-extra/include-cleaner/lib/Analysis.cpp
  clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp


Index: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
@@ -483,5 +483,29 @@
 Pair(Code.point("partial"), UnorderedElementsAre(Partial);
 }
 
+TEST_F(WalkUsedTest, IgnoresIdentityMacros) {
+  llvm::Annotations Code(R"cpp(
+  #include "header.h"
+  void $bar^bar() {
+$stdin^stdin();
+  }
+  )cpp");
+  Inputs.Code = Code.code();
+  Inputs.ExtraFiles["header.h"] = guard(R"cpp(
+  #include "inner.h"
+  void stdin();
+  )cpp");
+  Inputs.ExtraFiles["inner.h"] = guard(R"cpp(
+  #define stdin stdin
+  )cpp");
+
+  TestAST AST(Inputs);
+  auto  = AST.sourceManager();
+  auto MainFile = Header(SM.getFileEntryForID(SM.getMainFileID()));
+  EXPECT_THAT(offsetToProviders(AST, SM),
+  UnorderedElementsAre(
+  // FIXME: we should have a reference from stdin to header.h
+  Pair(Code.point("bar"), UnorderedElementsAre(MainFile;
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/Analysis.cpp
===
--- clang-tools-extra/include-cleaner/lib/Analysis.cpp
+++ clang-tools-extra/include-cleaner/lib/Analysis.cpp
@@ -28,10 +28,29 @@
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
+#include 
 #include 
 
 namespace clang::include_cleaner {
 
+namespace {
+bool shouldIgnoreMacroReference(const Macro ) {
+  static const auto *MacroNamesToIgnore = new llvm::StringSet<>{
+  // C standard says these are implementation defined macros, hence most of
+  // the standard library providers implement it by defining these as 
macros
+  // that resolve to themselves.
+  // This results in surprising behavior from users point of view (we
+  // generate a usage of stdio.h, in places unrelated to standard library).
+  // FIXME: Also eliminate the false negatives by treating declarations
+  // resulting from these expansions as used.
+  "stdin",
+  "stdout",
+  "stderr",
+  };
+  return MacroNamesToIgnore->contains(M.Name->getName());
+}
+} // namespace
+
 void walkUsed(llvm::ArrayRef ASTRoots,
   llvm::ArrayRef MacroRefs,
   const PragmaIncludes *PI, const SourceManager ,
@@ -51,7 +70,8 @@
   }
   for (const SymbolReference  : MacroRefs) {
 assert(MacroRef.Target.kind() == Symbol::Macro);
-if (!SM.isWrittenInMainFile(SM.getSpellingLoc(MacroRef.RefLocation)))
+if (!SM.isWrittenInMainFile(SM.getSpellingLoc(MacroRef.RefLocation)) ||
+shouldIgnoreMacroReference(MacroRef.Target.macro()))
   continue;
 CB(MacroRef, headersForSymbol(MacroRef.Target, SM, PI));
   }


Index: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
@@ -483,5 +483,29 @@
 Pair(Code.point("partial"), UnorderedElementsAre(Partial);
 }
 
+TEST_F(WalkUsedTest, IgnoresIdentityMacros) {
+  llvm::Annotations Code(R"cpp(
+  #include "header.h"
+  void $bar^bar() {
+$stdin^stdin();
+  }
+  )cpp");
+  Inputs.Code = Code.code();
+  Inputs.ExtraFiles["header.h"] = guard(R"cpp(
+  #include "inner.h"
+  void stdin();
+  )cpp");
+  Inputs.ExtraFiles["inner.h"] = guard(R"cpp(
+  #define stdin stdin
+  )cpp");
+
+  TestAST AST(Inputs);
+  auto  = AST.sourceManager();
+  auto MainFile = Header(SM.getFileEntryForID(SM.getMainFileID()));
+  EXPECT_THAT(offsetToProviders(AST, SM),
+  UnorderedElementsAre(
+  // FIXME: we should have a reference from stdin to header.h
+  Pair(Code.point("bar"), UnorderedElementsAre(MainFile;
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/Analysis.cpp
===
--- clang-tools-extra/include-cleaner/lib/Analysis.cpp
+++ clang-tools-extra/include-cleaner/lib/Analysis.cpp
@@ -28,10 +28,29 @@
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
+#include 
 #include 
 
 namespace clang::include_cleaner {
 
+namespace {
+bool shouldIgnoreMacroReference(const Macro ) {
+  static const auto 

[PATCH] D157868: [clang] Use RecoveryExprs for broken defaultargs, instead of OpaqueValueExprs

2023-08-16 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
kadircet marked 3 inline comments as done.
Closed by commit rG373fcd5d73a3: [clang] Use RecoveryExprs for broken 
defaultargs, instead of OpaqueValueExprs (authored by kadircet).

Changed prior to commit:
  https://reviews.llvm.org/D157868?vs=549939=550659#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157868/new/

https://reviews.llvm.org/D157868

Files:
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/AST/ast-dump-default-arg-recovery.cpp
  clang/test/Index/complete-optional-params.cpp

Index: clang/test/Index/complete-optional-params.cpp
===
--- clang/test/Index/complete-optional-params.cpp
+++ clang/test/Index/complete-optional-params.cpp
@@ -79,7 +79,7 @@
 // CHECK-CC5-NEXT: Objective-C interface
 
 // RUN: c-index-test -code-completion-at=%s:17:11 %s | FileCheck -check-prefix=CHECK-CC6 %s
-// CHECK-CC6: FunctionDecl:{ResultType void}{TypedText foo_2}{LeftParen (}{Optional {Placeholder Bar1 b1 = Bar1()}{Optional {Comma , }{Placeholder Bar2 b2}}}{RightParen )} (50)
+// CHECK-CC6: FunctionDecl:{ResultType void}{TypedText foo_2}{LeftParen (}{Optional {Placeholder Bar1 b1 = Bar1()}{Optional {Comma , }{Placeholder Bar2 b2 = Bar2()}}}{RightParen )} (50)
 // CHECK-CC6: Completion contexts:
 // CHECK-CC6-NEXT: Any type
 // CHECK-CC6-NEXT: Any value
Index: clang/test/AST/ast-dump-default-arg-recovery.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-default-arg-recovery.cpp
@@ -0,0 +1,8 @@
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -ast-dump -frecovery-ast %s | FileCheck %s
+
+void foo();
+void fun(int arg = foo());
+//  CHECK: -ParmVarDecl {{.*}}  col:14 invalid arg 'int' cinit
+// CHECK-NEXT:   -RecoveryExpr {{.*}}  'int' contains-errors
+// Make sure we also preserve structure of the errorneous expression
+//  CHECK: -DeclRefExpr {{.*}}  'void ()' {{.*}} 'foo'
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -20,6 +20,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
+#include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/RecursiveASTVisitor.h"
@@ -37,11 +38,13 @@
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
+#include "clang/Sema/Ownership.h"
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Template.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
@@ -329,23 +332,16 @@
   ParmVarDecl *Param = cast(param);
   UnparsedDefaultArgLocs.erase(Param);
 
-  auto Fail = [&] {
-Param->setInvalidDecl();
-Param->setDefaultArg(new (Context) OpaqueValueExpr(
-EqualLoc, Param->getType().getNonReferenceType(), VK_PRValue));
-  };
-
   // Default arguments are only permitted in C++
   if (!getLangOpts().CPlusPlus) {
 Diag(EqualLoc, diag::err_param_default_argument)
   << DefaultArg->getSourceRange();
-return Fail();
+return ActOnParamDefaultArgumentError(param, EqualLoc, DefaultArg);
   }
 
   // Check for unexpanded parameter packs.
-  if (DiagnoseUnexpandedParameterPack(DefaultArg, UPPC_DefaultArgument)) {
-return Fail();
-  }
+  if (DiagnoseUnexpandedParameterPack(DefaultArg, UPPC_DefaultArgument))
+return ActOnParamDefaultArgumentError(param, EqualLoc, DefaultArg);
 
   // C++11 [dcl.fct.default]p3
   //   A default argument expression [...] shall not be specified for a
@@ -360,14 +356,14 @@
 
   ExprResult Result = ConvertParamDefaultArgument(Param, DefaultArg, EqualLoc);
   if (Result.isInvalid())
-return Fail();
+return ActOnParamDefaultArgumentError(param, EqualLoc, DefaultArg);
 
   DefaultArg = Result.getAs();
 
   // Check that the default argument is well-formed
   CheckDefaultArgumentVisitor DefaultArgChecker(*this, DefaultArg);
   if (DefaultArgChecker.Visit(DefaultArg))
-return Fail();
+return ActOnParamDefaultArgumentError(param, EqualLoc, DefaultArg);
 
   SetParamDefaultArgument(Param, DefaultArg, EqualLoc);
 }
@@ -389,16 +385,23 @@
 
 /// ActOnParamDefaultArgumentError - Parsing or semantic analysis of
 /// the default argument for the parameter param failed.
-void Sema::ActOnParamDefaultArgumentError(Decl 

[PATCH] D157207: [clangd] Fix typo in comment

2023-08-14 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG09a622baa2d8: [clangd] Fix typo in comment (authored by 
Eymay, committed by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157207/new/

https://reviews.llvm.org/D157207

Files:
  clang-tools-extra/clangd/Protocol.h


Index: clang-tools-extra/clangd/Protocol.h
===
--- clang-tools-extra/clangd/Protocol.h
+++ clang-tools-extra/clangd/Protocol.h
@@ -592,7 +592,7 @@
 /// Clangd extension: parameters configurable at `initialize` time.
 /// LSP defines this type as `any`.
 struct InitializationOptions {
-  // What we can change throught the didChangeConfiguration request, we can
+  // What we can change through the didChangeConfiguration request, we can
   // also set through the initialize request (initializationOptions field).
   ConfigurationSettings ConfigSettings;
 


Index: clang-tools-extra/clangd/Protocol.h
===
--- clang-tools-extra/clangd/Protocol.h
+++ clang-tools-extra/clangd/Protocol.h
@@ -592,7 +592,7 @@
 /// Clangd extension: parameters configurable at `initialize` time.
 /// LSP defines this type as `any`.
 struct InitializationOptions {
-  // What we can change throught the didChangeConfiguration request, we can
+  // What we can change through the didChangeConfiguration request, we can
   // also set through the initialize request (initializationOptions field).
   ConfigurationSettings ConfigSettings;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D157905: [include-cleaner] Filter references to identity macros

2023-08-14 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added a reviewer: sammccall.
Herald added a project: All.
kadircet requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Despite being true positives, these results just confuse users. So
filter them out.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157905

Files:
  clang-tools-extra/include-cleaner/lib/Analysis.cpp
  clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp


Index: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
@@ -483,5 +483,29 @@
 Pair(Code.point("partial"), UnorderedElementsAre(Partial);
 }
 
+TEST_F(WalkUsedTest, IgnoresIdentityMacros) {
+  llvm::Annotations Code(R"cpp(
+  #include "header.h"
+  void $bar^bar() {
+$stdin^stdin();
+  }
+  )cpp");
+  Inputs.Code = Code.code();
+  Inputs.ExtraFiles["header.h"] = guard(R"cpp(
+  #include "inner.h"
+  void stdin();
+  )cpp");
+  Inputs.ExtraFiles["inner.h"] = guard(R"cpp(
+  #define stdin stdin
+  )cpp");
+
+  TestAST AST(Inputs);
+  auto  = AST.sourceManager();
+  auto MainFile = Header(SM.getFileEntryForID(SM.getMainFileID()));
+  EXPECT_THAT(offsetToProviders(AST, SM),
+  UnorderedElementsAre(
+  // FIXME: we should have a reference from stdin to header.h
+  Pair(Code.point("bar"), UnorderedElementsAre(MainFile;
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/Analysis.cpp
===
--- clang-tools-extra/include-cleaner/lib/Analysis.cpp
+++ clang-tools-extra/include-cleaner/lib/Analysis.cpp
@@ -28,10 +28,29 @@
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
+#include 
 #include 
 
 namespace clang::include_cleaner {
 
+namespace {
+bool shouldSkipMacro(const Macro ) {
+  static const auto *MacroNamesToIgnore = new llvm::StringSet<>{
+  // C standard says these are implementation defined macros, hence most of
+  // the standard library providers implement it by defining these as 
macros
+  // that resolve to themselves.
+  // This results in surprising behavior from users point of view (we
+  // generate a usage of stdio.h, in places unrelated to standard library).
+  // FIXME: Also eliminate the false positives by treating declarations
+  // resulting from these expansions as used.
+  "stdin",
+  "stdout",
+  "stderr",
+  };
+  return MacroNamesToIgnore->contains(M.Name->getName());
+}
+} // namespace
+
 void walkUsed(llvm::ArrayRef ASTRoots,
   llvm::ArrayRef MacroRefs,
   const PragmaIncludes *PI, const SourceManager ,
@@ -51,7 +70,8 @@
   }
   for (const SymbolReference  : MacroRefs) {
 assert(MacroRef.Target.kind() == Symbol::Macro);
-if (!SM.isWrittenInMainFile(SM.getSpellingLoc(MacroRef.RefLocation)))
+if (!SM.isWrittenInMainFile(SM.getSpellingLoc(MacroRef.RefLocation)) ||
+shouldSkipMacro(MacroRef.Target.macro()))
   continue;
 CB(MacroRef, headersForSymbol(MacroRef.Target, SM, PI));
   }


Index: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
@@ -483,5 +483,29 @@
 Pair(Code.point("partial"), UnorderedElementsAre(Partial);
 }
 
+TEST_F(WalkUsedTest, IgnoresIdentityMacros) {
+  llvm::Annotations Code(R"cpp(
+  #include "header.h"
+  void $bar^bar() {
+$stdin^stdin();
+  }
+  )cpp");
+  Inputs.Code = Code.code();
+  Inputs.ExtraFiles["header.h"] = guard(R"cpp(
+  #include "inner.h"
+  void stdin();
+  )cpp");
+  Inputs.ExtraFiles["inner.h"] = guard(R"cpp(
+  #define stdin stdin
+  )cpp");
+
+  TestAST AST(Inputs);
+  auto  = AST.sourceManager();
+  auto MainFile = Header(SM.getFileEntryForID(SM.getMainFileID()));
+  EXPECT_THAT(offsetToProviders(AST, SM),
+  UnorderedElementsAre(
+  // FIXME: we should have a reference from stdin to header.h
+  Pair(Code.point("bar"), UnorderedElementsAre(MainFile;
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/Analysis.cpp
===
--- clang-tools-extra/include-cleaner/lib/Analysis.cpp
+++ clang-tools-extra/include-cleaner/lib/Analysis.cpp
@@ -28,10 +28,29 @@
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
+#include 
 #include 
 
 namespace clang::include_cleaner {
 
+namespace {

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

2023-08-14 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp:122
   llvm::DenseSet SeenSymbols;
+  std::string ResourceDir = HS->getHeaderSearchOpts().ResourceDir;
   // FIXME: Find a way to have less code duplication between include-cleaner

VitaNuo wrote:
> kadircet wrote:
> > let's use `HS->getModuleMap().getBuiltinDir()` then we can get away with 
> > just comparing that pointer to `H.physical()->getLastRef().getDir()` (same 
> > applies to all the other places as well)
> This only works in `clangd` code for me. I get `nullptr` for 
> `HS->getModuleMap().getBuiltinDir()` in other places (Clang Tidy check and 
> the library).
hmm that's probably because you're not setting up the include structure 
correctly. resource-dir isn't the `builtindir`, it's `resource-dir + 
"/include"` (the comments i had in the clangd unittests applies in a similar 
manner to other tests as well).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157610/new/

https://reviews.llvm.org/D157610

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


[PATCH] D157868: [clang] Use RecoveryExprs for broken defaultargs, instead of OpaqueValueExprs

2023-08-14 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang/include/clang/Sema/Sema.h:3026
+  void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc,
+  ExprResult DefaultArg);
   ExprResult ConvertParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,

sammccall wrote:
> nit: Nullable `ExprResult*` since there are only two states?
> Extra get() in some callers, but less mysterious
i guess you meant `Expr*` ?



Comment at: clang/lib/Parse/ParseCXXInlineMethods.cpp:398
 DefArgResult = ParseAssignmentExpression();
-  DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult);
+  DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult, Param);
   if (DefArgResult.isInvalid()) {

sammccall wrote:
> If this fixes the recursive copy-constructor case you mentioned, can you add 
> a test?
> 
> (Else does it do anything? Or just cleanup)
no it doesn't. unfortunately that requires change in a separate code path to 
mark any method decls with invalid parmvardecls as invalid, which i'll try to 
put together. as that's the behavior for regular functiondecls, i don't see why 
it should be different for methods (if so we should probably change the 
behavior for functions instead).



Comment at: clang/lib/Parse/ParseCXXInlineMethods.cpp:400
   if (DefArgResult.isInvalid()) {
-Actions.ActOnParamDefaultArgumentError(Param, EqualLoc);
+Actions.ActOnParamDefaultArgumentError(Param, EqualLoc, DefArgResult);
   } else {

sammccall wrote:
> DefArgResult is never anything here. I'd probably find 
> `/*DefaultArg=*/nullptr` more obvious
maybe i am missing something, but "invalid" doesn't mean "unusable".


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157868/new/

https://reviews.llvm.org/D157868

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


[PATCH] D157868: [clang] Use RecoveryExprs for broken defaultargs, instead of OpaqueValueExprs

2023-08-14 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet updated this revision to Diff 549939.
kadircet marked 2 inline comments as done.
kadircet added a comment.

- Use Expr* instead of ExprResult
- Add dump test to demonstrate new RecoveryExpr


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157868/new/

https://reviews.llvm.org/D157868

Files:
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/AST/ast-dump-default-arg-recovery.cpp
  clang/test/Index/complete-optional-params.cpp

Index: clang/test/Index/complete-optional-params.cpp
===
--- clang/test/Index/complete-optional-params.cpp
+++ clang/test/Index/complete-optional-params.cpp
@@ -79,7 +79,7 @@
 // CHECK-CC5-NEXT: Objective-C interface
 
 // RUN: c-index-test -code-completion-at=%s:17:11 %s | FileCheck -check-prefix=CHECK-CC6 %s
-// CHECK-CC6: FunctionDecl:{ResultType void}{TypedText foo_2}{LeftParen (}{Optional {Placeholder Bar1 b1 = Bar1()}{Optional {Comma , }{Placeholder Bar2 b2}}}{RightParen )} (50)
+// CHECK-CC6: FunctionDecl:{ResultType void}{TypedText foo_2}{LeftParen (}{Optional {Placeholder Bar1 b1 = Bar1()}{Optional {Comma , }{Placeholder Bar2 b2 = Bar2()}}}{RightParen )} (50)
 // CHECK-CC6: Completion contexts:
 // CHECK-CC6-NEXT: Any type
 // CHECK-CC6-NEXT: Any value
Index: clang/test/AST/ast-dump-default-arg-recovery.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-default-arg-recovery.cpp
@@ -0,0 +1,6 @@
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -ast-dump -frecovery-ast %s | FileCheck %s
+
+void foo();
+void fun(int arg = foo());
+//  CHECK: -ParmVarDecl {{.*}}  col:14 invalid arg 'int' cinit
+// CHECK-NEXT:   -RecoveryExpr {{.*}}  'int' contains-errors
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -20,6 +20,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
+#include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/RecursiveASTVisitor.h"
@@ -37,11 +38,13 @@
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
+#include "clang/Sema/Ownership.h"
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Template.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
@@ -329,23 +332,16 @@
   ParmVarDecl *Param = cast(param);
   UnparsedDefaultArgLocs.erase(Param);
 
-  auto Fail = [&] {
-Param->setInvalidDecl();
-Param->setDefaultArg(new (Context) OpaqueValueExpr(
-EqualLoc, Param->getType().getNonReferenceType(), VK_PRValue));
-  };
-
   // Default arguments are only permitted in C++
   if (!getLangOpts().CPlusPlus) {
 Diag(EqualLoc, diag::err_param_default_argument)
   << DefaultArg->getSourceRange();
-return Fail();
+return ActOnParamDefaultArgumentError(param, EqualLoc, DefaultArg);
   }
 
   // Check for unexpanded parameter packs.
-  if (DiagnoseUnexpandedParameterPack(DefaultArg, UPPC_DefaultArgument)) {
-return Fail();
-  }
+  if (DiagnoseUnexpandedParameterPack(DefaultArg, UPPC_DefaultArgument))
+return ActOnParamDefaultArgumentError(param, EqualLoc, DefaultArg);
 
   // C++11 [dcl.fct.default]p3
   //   A default argument expression [...] shall not be specified for a
@@ -360,14 +356,14 @@
 
   ExprResult Result = ConvertParamDefaultArgument(Param, DefaultArg, EqualLoc);
   if (Result.isInvalid())
-return Fail();
+return ActOnParamDefaultArgumentError(param, EqualLoc, DefaultArg);
 
   DefaultArg = Result.getAs();
 
   // Check that the default argument is well-formed
   CheckDefaultArgumentVisitor DefaultArgChecker(*this, DefaultArg);
   if (DefaultArgChecker.Visit(DefaultArg))
-return Fail();
+return ActOnParamDefaultArgumentError(param, EqualLoc, DefaultArg);
 
   SetParamDefaultArgument(Param, DefaultArg, EqualLoc);
 }
@@ -389,16 +385,23 @@
 
 /// ActOnParamDefaultArgumentError - Parsing or semantic analysis of
 /// the default argument for the parameter param failed.
-void Sema::ActOnParamDefaultArgumentError(Decl *param,
-  SourceLocation EqualLoc) {
+void Sema::ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc,
+  Expr *DefaultArg) {
   if (!param)
 return;
 
   ParmVarDecl *Param = cast(param);
   Param->setInvalidDecl();
   

[PATCH] D157868: [clang] Use RecoveryExprs for broken defaultargs, instead of OpaqueValueExprs

2023-08-14 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added reviewers: sammccall, aaron.ballman.
Herald added a subscriber: arphaman.
Herald added a project: All.
kadircet requested review of this revision.
Herald added projects: clang, clang-tools-extra.
Herald added a subscriber: cfe-commits.

This makes sure we can preserve invalid-ness for consumers of this
node, it prevents crashes. It also aligns better with rest of the places that
store invalid expressions.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157868

Files:
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/Index/complete-optional-params.cpp

Index: clang/test/Index/complete-optional-params.cpp
===
--- clang/test/Index/complete-optional-params.cpp
+++ clang/test/Index/complete-optional-params.cpp
@@ -79,7 +79,7 @@
 // CHECK-CC5-NEXT: Objective-C interface
 
 // RUN: c-index-test -code-completion-at=%s:17:11 %s | FileCheck -check-prefix=CHECK-CC6 %s
-// CHECK-CC6: FunctionDecl:{ResultType void}{TypedText foo_2}{LeftParen (}{Optional {Placeholder Bar1 b1 = Bar1()}{Optional {Comma , }{Placeholder Bar2 b2}}}{RightParen )} (50)
+// CHECK-CC6: FunctionDecl:{ResultType void}{TypedText foo_2}{LeftParen (}{Optional {Placeholder Bar1 b1 = Bar1()}{Optional {Comma , }{Placeholder Bar2 b2 = Bar2()}}}{RightParen )} (50)
 // CHECK-CC6: Completion contexts:
 // CHECK-CC6-NEXT: Any type
 // CHECK-CC6-NEXT: Any value
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -20,6 +20,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
+#include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/RecursiveASTVisitor.h"
@@ -37,11 +38,13 @@
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
+#include "clang/Sema/Ownership.h"
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Template.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
@@ -329,23 +332,16 @@
   ParmVarDecl *Param = cast(param);
   UnparsedDefaultArgLocs.erase(Param);
 
-  auto Fail = [&] {
-Param->setInvalidDecl();
-Param->setDefaultArg(new (Context) OpaqueValueExpr(
-EqualLoc, Param->getType().getNonReferenceType(), VK_PRValue));
-  };
-
   // Default arguments are only permitted in C++
   if (!getLangOpts().CPlusPlus) {
 Diag(EqualLoc, diag::err_param_default_argument)
   << DefaultArg->getSourceRange();
-return Fail();
+return ActOnParamDefaultArgumentError(param, EqualLoc, DefaultArg);
   }
 
   // Check for unexpanded parameter packs.
-  if (DiagnoseUnexpandedParameterPack(DefaultArg, UPPC_DefaultArgument)) {
-return Fail();
-  }
+  if (DiagnoseUnexpandedParameterPack(DefaultArg, UPPC_DefaultArgument))
+return ActOnParamDefaultArgumentError(param, EqualLoc, DefaultArg);
 
   // C++11 [dcl.fct.default]p3
   //   A default argument expression [...] shall not be specified for a
@@ -360,14 +356,14 @@
 
   ExprResult Result = ConvertParamDefaultArgument(Param, DefaultArg, EqualLoc);
   if (Result.isInvalid())
-return Fail();
+return ActOnParamDefaultArgumentError(param, EqualLoc, DefaultArg);
 
   DefaultArg = Result.getAs();
 
   // Check that the default argument is well-formed
   CheckDefaultArgumentVisitor DefaultArgChecker(*this, DefaultArg);
   if (DefaultArgChecker.Visit(DefaultArg))
-return Fail();
+return ActOnParamDefaultArgumentError(param, EqualLoc, DefaultArg);
 
   SetParamDefaultArgument(Param, DefaultArg, EqualLoc);
 }
@@ -389,16 +385,24 @@
 
 /// ActOnParamDefaultArgumentError - Parsing or semantic analysis of
 /// the default argument for the parameter param failed.
-void Sema::ActOnParamDefaultArgumentError(Decl *param,
-  SourceLocation EqualLoc) {
+void Sema::ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc,
+  ExprResult DefaultArg) {
   if (!param)
 return;
 
   ParmVarDecl *Param = cast(param);
   Param->setInvalidDecl();
   UnparsedDefaultArgLocs.erase(Param);
-  Param->setDefaultArg(new (Context) OpaqueValueExpr(
-  EqualLoc, Param->getType().getNonReferenceType(), VK_PRValue));
+  ExprResult RE;
+  if (DefaultArg.isUsable()) {
+RE = CreateRecoveryExpr(EqualLoc, DefaultArg.get()->getEndLoc(),
+{DefaultArg.get()},
+   

[PATCH] D154503: [Sema] Fix handling of functions that hide classes

2023-08-14 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

In D154503#4576481 , @aaron.ballman 
wrote:

> In D154503#4576475 , @kadircet 
> wrote:
>
>> In D154503#4576442 , 
>> @aaron.ballman wrote:
>>
>>> I'm not opposed to a revert if this is causing problems for your 
>>> downstream, but be sure to also remove the changes from the 17.x branch if 
>>> you go this route rather than fixing forward.
>>
>> Thanks! I didn't notice it made into the release branch. I'd wait for 
>> author's comment on this one, as I guess we can cherry-pick just the 
>> fix-forward if it turns out to be small and safe. Otherwise I am more than 
>> happy to request the cherry-pick for the revert.
>
> SGTM!

Requested cherry-pick in https://github.com/llvm/llvm-project/issues/64670


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154503/new/

https://reviews.llvm.org/D154503

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


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

2023-08-10 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp:122
   llvm::DenseSet SeenSymbols;
+  std::string ResourceDir = HS->getHeaderSearchOpts().ResourceDir;
   // FIXME: Find a way to have less code duplication between include-cleaner

let's use `HS->getModuleMap().getBuiltinDir()` then we can get away with just 
comparing that pointer to `H.physical()->getLastRef().getDir()` (same applies 
to all the other places as well)



Comment at: clang-tools-extra/clangd/IncludeCleaner.cpp:309
   continue;
+auto Dir = llvm::StringRef{MFI.Resolved}.rsplit('/').first;
+if (Dir == AST.getPreprocessor()

let's move this into `mayConsiderUnused`, we also convert this include into a 
FileEntry in there, so we can directly compare the directory agian.



Comment at: clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp:579-580
+  auto TU = TestTU::withCode(R"cpp(
+#include "resources/amintrin.h"
+#include "resources/imintrin.h"
+void baz() {

can you rather include these as ``



Comment at: clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp:587-588
+  TU.ExtraArgs.push_back(testPath("resources"));
+  TU.AdditionalFiles["resources/amintrin.h"] = "";
+   TU.AdditionalFiles["resources/imintrin.h"] = guard(R"cpp(
+#include "emintrin.h"

we should put these under `resources/include/.h`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157610/new/

https://reviews.llvm.org/D157610

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


[PATCH] D154503: [Sema] Fix handling of functions that hide classes

2023-08-10 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

In D154503#4576442 , @aaron.ballman 
wrote:

> I'm not opposed to a revert if this is causing problems for your downstream, 
> but be sure to also remove the changes from the 17.x branch if you go this 
> route rather than fixing forward.

Thanks! I didn't notice it made into the release branch. I'd wait for author's 
comment on this one, as I guess we can cherry-pick just the fix-forward if it 
turns out to be small and safe. Otherwise I am more than happy to request the 
cherry-pick for the revert.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154503/new/

https://reviews.llvm.org/D154503

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


[PATCH] D154503: [Sema] Fix handling of functions that hide classes

2023-08-10 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

Hi!

After this patch clang seems to be crashing on:

  class a {
static c a;
void b(){a};
  };

with stack trace and assertion error:

  $ ~/repos/llvm/build/bin/clang -xc++ repro.cc
  repro.cc:2:10: error: unknown type name 'c'
  2 |   static c a;
|  ^
  repro.cc:2:12: error: member 'a' has the same name as its class
  2 |   static c a;
|^
  clang-17: 
/usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaLookup.cpp:333: 
bool clang::LookupResult::checkDebugAssumptions() const: Assertion `ResultKind 
!= Found || Decls.size() == 1' failed.
  PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ 
and include the crash backtrace, preprocessed source, and associated run script.
  Stack dump:
  0.  Program arguments: 
/usr/local/google/home/kadircet/repos/llvm/build/bin/clang-17 -cc1 -triple 
x86_64-unknown-linux-gnu -emit-obj -mrelax-all -dumpdir a- -disable-free 
-clear-ast-before-backend -main-file-name repro.cc -mrelocation-model pic 
-pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on 
-fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 
-tune-cpu generic -debugger-tuning=gdb 
-fcoverage-compilation-dir=/usr/local/google/home/kadircet/repos/tmp/new_crasher
 -resource-dir /usr/local/google/home/kadircet/repos/llvm/build/lib/clang/18 
-internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12 
-internal-isystem 
/usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12 
-internal-isystem 
/usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/backward 
-internal-isystem 
/usr/local/google/home/kadircet/repos/llvm/build/lib/clang/18/include 
-internal-isystem /usr/local/include -internal-isystem 
/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include 
-internal-externc-isystem /usr/include/x86_64-linux-gnu 
-internal-externc-isystem /include -internal-externc-isystem /usr/include 
-fdeprecated-macro 
-fdebug-compilation-dir=/usr/local/google/home/kadircet/repos/tmp/new_crasher 
-ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions 
-fcolor-diagnostics -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o 
/tmp/repro-aa9901.o -x c++ repro.cc
  1.  repro.cc:3:12: current parser token 'a'
  2.  repro.cc:1:1: parsing struct/union/class body 'a'
  3.  repro.cc:3:11: parsing function body 'a::b'
  4.  repro.cc:3:11: in compound statement ('{}')
   #0 0x0746e327 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
/usr/local/google/home/kadircet/repos/llvm/llvm/lib/Support/Unix/Signals.inc:602:13
   #1 0x0746c0ae llvm::sys::RunSignalHandlers() 
/usr/local/google/home/kadircet/repos/llvm/llvm/lib/Support/Signals.cpp:105:18
   #2 0x0746e9ba SignalHandler(int) 
/usr/local/google/home/kadircet/repos/llvm/llvm/lib/Support/Unix/Signals.inc:413:1
   #3 0x7efd7465a540 (/lib/x86_64-linux-gnu/libc.so.6+0x3c540)
   #4 0x7efd746a812c __pthread_kill_implementation 
./nptl/pthread_kill.c:44:76
   #5 0x7efd7465a4a2 raise ./signal/../sysdeps/posix/raise.c:27:6
   #6 0x7efd746444b2 abort ./stdlib/abort.c:81:7
   #7 0x7efd746443d5 _nl_load_domain ./intl/loadmsgcat.c:1177:9
   #8 0x7efd746533a2 (/lib/x86_64-linux-gnu/libc.so.6+0x353a2)
   #9 0x0a014bf8 clang::LookupResult::checkDebugAssumptions() const 
/usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaLookup.cpp:334:3
  #10 0x09b95356 getResultKind 
/usr/local/google/home/kadircet/repos/llvm/clang/include/clang/Sema/Lookup.h:342:5
  #11 0x09b95356 clang::Sema::ClassifyName(clang::Scope*, 
clang::CXXScopeSpec&, clang::IdentifierInfo*&, clang::SourceLocation, 
clang::Token const&, clang::CorrectionCandidateCallback*) 
/usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaDecl.cpp:953:18
  #12 0x098a793e 
clang::Parser::TryAnnotateName(clang::CorrectionCandidateCallback*, 
clang::ImplicitTypenameContext) 
/usr/local/google/home/kadircet/repos/llvm/clang/lib/Parse/Parser.cpp:1770:53
  #13 0x099570dd 
clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, 
clang::ParsedAttributes&, clang::ParsedAttributes&) 
/usr/local/google/home/kadircet/repos/llvm/clang/lib/Parse/ParseStmt.cpp:214:33
  #14 0x09956c55 
clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) 
/usr/local/google/home/kadircet/repos/llvm/clang/lib/Parse/ParseStmt.cpp:117:20
  #15 0x09960ab1 clang::Parser::ParseCompoundStatementBody(bool) 
/usr/local/google/home/kadircet/repos/llvm/clang/lib/Parse/ParseStmt.cpp:1205:11
  #16 0x09961a9d 
clang::Parser::ParseFunctionStatementBody(clang::Decl*, 
clang::Parser::ParseScope&) 
/usr/local/google/home/kadircet/repos/llvm/clang/lib/Parse/ParseStmt.cpp:2468:21
  #17 

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

2023-08-09 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

> Order of exporters is from outermost to innermost.

FWIW, that's mostly a coincidence. all 3 exporters are private headers, hence 
they're penalized for it. Afterwards "export1.h" is actually boosted among 
other exporters as it is also an "origin" provider. "export2.h" and "export3.h" 
are pretty much equal hence they're ranked based on their name. (discovery 
order of includes doesn't determine the ranking).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157395/new/

https://reviews.llvm.org/D157395

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


[PATCH] D156704: [clang][HeaderSearch] Treat framework headers as System for suggestPath

2023-08-09 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156704/new/

https://reviews.llvm.org/D156704

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


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

2023-08-09 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

i think we should also have some unittests in FindHeadersTest, some sample 
scenarios:

foo.h

  #pragma once
  void foo();

export1.h

  #pragma once
  // IWYU pragma: private, include "public1.h"
  #include "foo.h" // IWYU pragma: export

export2.h

  #pragma once
  // IWYU pragma: private, include "public2.h"
  #include "export2.h" // IWYU pragma: export

export3.h

  #pragma once
  // IWYU pragma: private, include "public3.h"
  #include "export3.h" // IWYU pragma: export
  void foo(); // we also have a declaration here, hence this is another 
provider root.

user.cc

  #include "export3.h"
  void bar() { foo(); }

`headersForFoo()` should look like `foo.h, public3.h,  export1.h, export2.h, 
export3.h`




Comment at: clang-tools-extra/include-cleaner/lib/FindHeaders.cpp:195
+std::set Exporters;
 while (FE) {
   Results.emplace_back(FE,

what about writing this as:
```
std::queue Exporters;
while (FE) {
 Results.emplace_back(FE,
   isPublicHeader(FE, *PI) |
   (IsOrigin ? Hints::OriginHeader : Hints::None));
  for (const auto *Export : PI->getExporters(FE, SM.getFileManager()))
Exporters.push(Export);

  if (auto Verbatim = PI->getPublic(FE); !Verbatim.empty()) {
Results.emplace_back(Verbatim,
 Hints::PublicHeader | Hints::PreferredHeader);
break;
  }
  if (PI->isSelfContained(FE) || FID == SM.getMainFileID())
break;

  // Walkup the include stack for non self-contained headers.
  FID = SM.getDecomposedIncludedLoc(FID).first;
  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(FE, SM.getFileManager()))
 Exporters.push(Export);
}
```

That way we don't need to change the contracts around `getExporter` in 
`PragmaIncludes`



Comment at: clang-tools-extra/include-cleaner/lib/FindHeaders.cpp:204
 
   if (auto Verbatim = PI->getPublic(FE); !Verbatim.empty()) {
+Hints Hint = Hints::PublicHeader;

`FE` here is always a "provider" for the symbol in question, so we should 
actually respect the private pragmas in them. we should only ignore those 
pragmas if they're discovered inside a header, that we found because we 
followed an export edge.



Comment at: clang-tools-extra/include-cleaner/lib/FindHeaders.cpp:207
+auto FE =
+expectedToOptional(SM.getFileManager().getFileRef(Verbatim));
+if (!FE || std::find(Exporters.begin(), Exporters.end(), FE) ==

verbatim spellings are relative to an include search path (or even worse, 
relative to the file containing the include directive) so we can't rely on 
being able to resolve it directly through FileManager (it can only resolve 
either absolute paths nor paths relative to CWD).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157395/new/

https://reviews.llvm.org/D157395

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


[PATCH] D157400: [include-cleaner] Dont boost private headers beyond public ones

2023-08-09 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0a315be2a46f: [include-cleaner] Dont boost private headers 
beyond public ones (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157400/new/

https://reviews.llvm.org/D157400

Files:
  clang-tools-extra/include-cleaner/lib/TypesInternal.h
  clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
  clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp


Index: clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -465,6 +465,22 @@
physicalHeader("foo.h")));
 }
 
+TEST_F(HeadersForSymbolTest, PublicOverPrivateWithoutUmbrella) {
+  Inputs.Code = R"cpp(
+#include "bar.h"
+#include "foo.h"
+  )cpp";
+  Inputs.ExtraFiles["bar.h"] =
+  guard(R"cpp(#include "foo.h" // IWYU pragma: export)cpp");
+  Inputs.ExtraFiles["foo.h"] = guard(R"cpp(
+// IWYU pragma: private
+struct foo {};
+  )cpp");
+  buildAST();
+  EXPECT_THAT(headersForFoo(),
+  ElementsAre(physicalHeader("bar.h"), physicalHeader("foo.h")));
+}
+
 TEST_F(HeadersForSymbolTest, AmbiguousStdSymbols) {
   struct {
 llvm::StringRef Code;
Index: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
@@ -441,9 +441,9 @@
   };
   EXPECT_LT(Hinted(Hints::None), Hinted(Hints::CompleteSymbol));
   EXPECT_LT(Hinted(Hints::CompleteSymbol), Hinted(Hints::PublicHeader));
-  EXPECT_LT(Hinted(Hints::PublicHeader), Hinted(Hints::PreferredHeader));
-  EXPECT_LT(Hinted(Hints::CompleteSymbol | Hints::PublicHeader),
-Hinted(Hints::PreferredHeader));
+  EXPECT_LT(Hinted(Hints::PreferredHeader), Hinted(Hints::PublicHeader));
+  EXPECT_LT(Hinted(Hints::CompleteSymbol | Hints::PreferredHeader),
+Hinted(Hints::PublicHeader));
 }
 
 // Test ast traversal & redecl selection end-to-end for templates, as explicit
Index: clang-tools-extra/include-cleaner/lib/TypesInternal.h
===
--- clang-tools-extra/include-cleaner/lib/TypesInternal.h
+++ clang-tools-extra/include-cleaner/lib/TypesInternal.h
@@ -69,15 +69,15 @@
   /// Provides a generally-usable definition for the symbol. (a function decl,
   /// or class definition and not a forward declaration of a template).
   CompleteSymbol = 1 << 1,
-  /// Symbol is provided by a public file. Only absent in the cases where file
-  /// is explicitly marked as such, non self-contained or IWYU private
-  /// pragmas.
-  PublicHeader = 1 << 2,
   /// Header providing the symbol is explicitly marked as preferred, with an
   /// IWYU private pragma that points at this provider or header and symbol has
   /// ~the same name.
-  PreferredHeader = 1 << 3,
-  LLVM_MARK_AS_BITMASK_ENUM(PreferredHeader),
+  PreferredHeader = 1 << 2,
+  /// Symbol is provided by a public file. Only absent in the cases where file
+  /// is explicitly marked as such, non self-contained or IWYU private
+  /// pragmas.
+  PublicHeader = 1 << 3,
+  LLVM_MARK_AS_BITMASK_ENUM(PublicHeader),
 };
 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
 /// A wrapper to augment values with hints.


Index: clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -465,6 +465,22 @@
physicalHeader("foo.h")));
 }
 
+TEST_F(HeadersForSymbolTest, PublicOverPrivateWithoutUmbrella) {
+  Inputs.Code = R"cpp(
+#include "bar.h"
+#include "foo.h"
+  )cpp";
+  Inputs.ExtraFiles["bar.h"] =
+  guard(R"cpp(#include "foo.h" // IWYU pragma: export)cpp");
+  Inputs.ExtraFiles["foo.h"] = guard(R"cpp(
+// IWYU pragma: private
+struct foo {};
+  )cpp");
+  buildAST();
+  EXPECT_THAT(headersForFoo(),
+  ElementsAre(physicalHeader("bar.h"), physicalHeader("foo.h")));
+}
+
 TEST_F(HeadersForSymbolTest, AmbiguousStdSymbols) {
   struct {
 llvm::StringRef Code;
Index: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
@@ -441,9 +441,9 @@
   };
   EXPECT_LT(Hinted(Hints::None), Hinted(Hints::CompleteSymbol));
   EXPECT_LT(Hinted(Hints::CompleteSymbol), Hinted(Hints::PublicHeader));
- 

[PATCH] D157400: [include-cleaner] Dont boost private headers beyond public ones

2023-08-08 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added a reviewer: VitaNuo.
Herald added a project: All.
kadircet requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Private headers should be the last resort, even if they match the name
of a symbol. It's pretty common in umrella headers to have internal file names
that match the symbol (e.g. Eigen::Matrix, declared in private header Matrix.h,
and exposed in umbrella header Eigen/Core).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157400

Files:
  clang-tools-extra/include-cleaner/lib/TypesInternal.h
  clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
  clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp


Index: clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -465,6 +465,22 @@
physicalHeader("foo.h")));
 }
 
+TEST_F(HeadersForSymbolTest, PublicOverPrivateWithoutUmbrella) {
+  Inputs.Code = R"cpp(
+#include "bar.h"
+#include "foo.h"
+  )cpp";
+  Inputs.ExtraFiles["bar.h"] =
+  guard(R"cpp(#include "foo.h" // IWYU pragma: export)cpp");
+  Inputs.ExtraFiles["foo.h"] = guard(R"cpp(
+// IWYU pragma: private
+struct foo {};
+  )cpp");
+  buildAST();
+  EXPECT_THAT(headersForFoo(),
+  ElementsAre(physicalHeader("bar.h"), physicalHeader("foo.h")));
+}
+
 TEST_F(HeadersForSymbolTest, AmbiguousStdSymbols) {
   struct {
 llvm::StringRef Code;
Index: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
@@ -441,9 +441,9 @@
   };
   EXPECT_LT(Hinted(Hints::None), Hinted(Hints::CompleteSymbol));
   EXPECT_LT(Hinted(Hints::CompleteSymbol), Hinted(Hints::PublicHeader));
-  EXPECT_LT(Hinted(Hints::PublicHeader), Hinted(Hints::PreferredHeader));
-  EXPECT_LT(Hinted(Hints::CompleteSymbol | Hints::PublicHeader),
-Hinted(Hints::PreferredHeader));
+  EXPECT_LT(Hinted(Hints::PreferredHeader), Hinted(Hints::PublicHeader));
+  EXPECT_LT(Hinted(Hints::CompleteSymbol | Hints::PreferredHeader),
+Hinted(Hints::PublicHeader));
 }
 
 // Test ast traversal & redecl selection end-to-end for templates, as explicit
Index: clang-tools-extra/include-cleaner/lib/TypesInternal.h
===
--- clang-tools-extra/include-cleaner/lib/TypesInternal.h
+++ clang-tools-extra/include-cleaner/lib/TypesInternal.h
@@ -69,15 +69,15 @@
   /// Provides a generally-usable definition for the symbol. (a function decl,
   /// or class definition and not a forward declaration of a template).
   CompleteSymbol = 1 << 1,
-  /// Symbol is provided by a public file. Only absent in the cases where file
-  /// is explicitly marked as such, non self-contained or IWYU private
-  /// pragmas.
-  PublicHeader = 1 << 2,
   /// Header providing the symbol is explicitly marked as preferred, with an
   /// IWYU private pragma that points at this provider or header and symbol has
   /// ~the same name.
-  PreferredHeader = 1 << 3,
-  LLVM_MARK_AS_BITMASK_ENUM(PreferredHeader),
+  PreferredHeader = 1 << 2,
+  /// Symbol is provided by a public file. Only absent in the cases where file
+  /// is explicitly marked as such, non self-contained or IWYU private
+  /// pragmas.
+  PublicHeader = 1 << 3,
+  LLVM_MARK_AS_BITMASK_ENUM(PublicHeader),
 };
 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
 /// A wrapper to augment values with hints.


Index: clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -465,6 +465,22 @@
physicalHeader("foo.h")));
 }
 
+TEST_F(HeadersForSymbolTest, PublicOverPrivateWithoutUmbrella) {
+  Inputs.Code = R"cpp(
+#include "bar.h"
+#include "foo.h"
+  )cpp";
+  Inputs.ExtraFiles["bar.h"] =
+  guard(R"cpp(#include "foo.h" // IWYU pragma: export)cpp");
+  Inputs.ExtraFiles["foo.h"] = guard(R"cpp(
+// IWYU pragma: private
+struct foo {};
+  )cpp");
+  buildAST();
+  EXPECT_THAT(headersForFoo(),
+  ElementsAre(physicalHeader("bar.h"), physicalHeader("foo.h")));
+}
+
 TEST_F(HeadersForSymbolTest, AmbiguousStdSymbols) {
   struct {
 llvm::StringRef Code;
Index: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
===
--- 

[PATCH] D157390: [clang-tidy][include-cleaner] Add option to control deduplication of findings per symbol

2023-08-08 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet marked 2 inline comments as done.
kadircet added a comment.

hi @PiotrZSL, addressed those in 724b40a1379f7c116473a02a3cec4d341c475b46 



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157390/new/

https://reviews.llvm.org/D157390

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


[PATCH] D157390: [clang-tidy][include-cleaner] Add option to control deduplication of findings per symbol

2023-08-08 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG89d0a76be68b: [clang-tidy][include-cleaner] Add option to 
control deduplication of findings… (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157390/new/

https://reviews.llvm.org/D157390

Files:
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
  clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp

Index: clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp
===
--- clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp
+++ clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp
@@ -15,6 +15,8 @@
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Regex.h"
+#include "llvm/Testing/Annotations/Annotations.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
 
@@ -108,6 +110,50 @@
)"}}));
 }
 
+TEST(IncludeCleanerCheckTest, DedupsMissingIncludes) {
+  llvm::Annotations Code(R"(
+#include "baz.h" // IWYU pragma: keep
+
+int BarResult1 = $diag1^bar();
+int BarResult2 = $diag2^bar();)");
+
+  {
+std::vector Errors;
+runCheckOnCode(Code.code(), , "file.cpp",
+std::nullopt, ClangTidyOptions(),
+{{"baz.h", R"(#pragma once
+  #include "bar.h"
+   )"},
+ {"bar.h", R"(#pragma once
+  int bar();
+   )"}});
+ASSERT_THAT(Errors.size(), testing::Eq(1U));
+EXPECT_EQ(Errors.front().Message.Message,
+  "no header providing \"bar\" is directly included");
+EXPECT_EQ(Errors.front().Message.FileOffset, Code.point("diag1"));
+  }
+  {
+std::vector Errors;
+ClangTidyOptions Opts;
+Opts.CheckOptions.insert({"DeduplicateFindings", "false"});
+runCheckOnCode(Code.code(), , "file.cpp",
+std::nullopt, Opts,
+{{"baz.h", R"(#pragma once
+  #include "bar.h"
+   )"},
+ {"bar.h", R"(#pragma once
+  int bar();
+   )"}});
+ASSERT_THAT(Errors.size(), testing::Eq(2U));
+EXPECT_EQ(Errors.front().Message.Message,
+  "no header providing \"bar\" is directly included");
+EXPECT_EQ(Errors.front().Message.FileOffset, Code.point("diag1"));
+EXPECT_EQ(Errors.back().Message.Message,
+  "no header providing \"bar\" is directly included");
+EXPECT_EQ(Errors.back().Message.FileOffset, Code.point("diag2"));
+  }
+}
+
 TEST(IncludeCleanerCheckTest, SuppressMissingIncludes) {
   const char *PreCode = R"(
 #include "bar.h"
Index: clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
+++ clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
@@ -33,3 +33,8 @@
files that match this regex as a suffix.  E.g., `foo/.*` disables
insertion/removal for all headers under the directory `foo`. By default, no 
headers will be ignored.
+
+.. option:: DeduplicateFindings
+
+   A boolean that controls whether the check should deduplicate findings for the
+   same symbol. Defaults to true.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -192,6 +192,9 @@
   ` check to emit proper
   warnings when a type forward declaration precedes its definition.
 
+- Misc-include-cleaner check has option `DeduplicateFindings` to output one
+  finding per occurence of a symbol.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
===
--- clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
+++ clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
@@ -44,6 +44,8 @@
   include_cleaner::PragmaIncludes RecordedPI;
   HeaderSearch *HS;
   std::vector IgnoreHeaders;
+  // Whether emit only one finding per usage of a symbol.
+  const bool DeduplicateFindings;
   llvm::SmallVector IgnoreHeadersRegex;
   bool shouldIgnore(const include_cleaner::Header );
 };
Index: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp

[PATCH] D157390: [clang-tidy][include-cleaner] Add option to control deduplication of findings per symbol

2023-08-08 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet updated this revision to Diff 548199.
kadircet added a comment.

- Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157390/new/

https://reviews.llvm.org/D157390

Files:
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
  clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp

Index: clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp
===
--- clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp
+++ clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp
@@ -15,6 +15,8 @@
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Regex.h"
+#include "llvm/Testing/Annotations/Annotations.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
 
@@ -108,6 +110,50 @@
)"}}));
 }
 
+TEST(IncludeCleanerCheckTest, DedupsMissingIncludes) {
+  llvm::Annotations Code(R"(
+#include "baz.h" // IWYU pragma: keep
+
+int BarResult1 = $diag1^bar();
+int BarResult2 = $diag2^bar();)");
+
+  {
+std::vector Errors;
+runCheckOnCode(Code.code(), , "file.cpp",
+std::nullopt, ClangTidyOptions(),
+{{"baz.h", R"(#pragma once
+  #include "bar.h"
+   )"},
+ {"bar.h", R"(#pragma once
+  int bar();
+   )"}});
+ASSERT_THAT(Errors.size(), testing::Eq(1U));
+EXPECT_EQ(Errors.front().Message.Message,
+  "no header providing \"bar\" is directly included");
+EXPECT_EQ(Errors.front().Message.FileOffset, Code.point("diag1"));
+  }
+  {
+std::vector Errors;
+ClangTidyOptions Opts;
+Opts.CheckOptions.insert({"DeduplicateFindings", "false"});
+runCheckOnCode(Code.code(), , "file.cpp",
+std::nullopt, Opts,
+{{"baz.h", R"(#pragma once
+  #include "bar.h"
+   )"},
+ {"bar.h", R"(#pragma once
+  int bar();
+   )"}});
+ASSERT_THAT(Errors.size(), testing::Eq(2U));
+EXPECT_EQ(Errors.front().Message.Message,
+  "no header providing \"bar\" is directly included");
+EXPECT_EQ(Errors.front().Message.FileOffset, Code.point("diag1"));
+EXPECT_EQ(Errors.back().Message.Message,
+  "no header providing \"bar\" is directly included");
+EXPECT_EQ(Errors.back().Message.FileOffset, Code.point("diag2"));
+  }
+}
+
 TEST(IncludeCleanerCheckTest, SuppressMissingIncludes) {
   const char *PreCode = R"(
 #include "bar.h"
Index: clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
+++ clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
@@ -33,3 +33,8 @@
files that match this regex as a suffix.  E.g., `foo/.*` disables
insertion/removal for all headers under the directory `foo`. By default, no 
headers will be ignored.
+
+.. option:: DeduplicateFindings
+
+   A boolean that controls whether the check should deduplicate findings for the
+   same symbol. Defaults to true.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -192,6 +192,9 @@
   ` check to emit proper
   warnings when a type forward declaration precedes its definition.
 
+- Misc-include-cleaner check has option `DeduplicateFindings` to output one
+  finding per occurence of a symbol.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
===
--- clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
+++ clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
@@ -44,6 +44,8 @@
   include_cleaner::PragmaIncludes RecordedPI;
   HeaderSearch *HS;
   std::vector IgnoreHeaders;
+  // Whether emit only one finding per usage of a symbol.
+  const bool DeduplicateFindings;
   llvm::SmallVector IgnoreHeadersRegex;
   bool shouldIgnore(const include_cleaner::Header );
 };
Index: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
===
--- clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
+++ clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
@@ -55,7 +55,9 @@

[PATCH] D157390: [clang-tidy][include-cleaner] Add option to control deduplication of findings per symbol

2023-08-08 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet updated this revision to Diff 548190.
kadircet marked 2 inline comments as done.
kadircet added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157390/new/

https://reviews.llvm.org/D157390

Files:
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
  clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp

Index: clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp
===
--- clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp
+++ clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp
@@ -15,6 +15,8 @@
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Regex.h"
+#include "llvm/Testing/Annotations/Annotations.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
 
@@ -108,6 +110,50 @@
)"}}));
 }
 
+TEST(IncludeCleanerCheckTest, DedupsMissingIncludes) {
+  llvm::Annotations Code(R"(
+#include "baz.h" // IWYU pragma: keep
+
+int BarResult1 = $diag1^bar();
+int BarResult2 = $diag2^bar();)");
+
+  {
+std::vector Errors;
+runCheckOnCode(Code.code(), , "file.cpp",
+std::nullopt, ClangTidyOptions(),
+{{"baz.h", R"(#pragma once
+  #include "bar.h"
+   )"},
+ {"bar.h", R"(#pragma once
+  int bar();
+   )"}});
+ASSERT_THAT(Errors.size(), testing::Eq(1U));
+EXPECT_EQ(Errors.front().Message.Message,
+  "no header providing \"bar\" is directly included");
+EXPECT_EQ(Errors.front().Message.FileOffset, Code.point("diag1"));
+  }
+  {
+std::vector Errors;
+ClangTidyOptions Opts;
+Opts.CheckOptions.insert({"DeduplicateFindings", "false"});
+runCheckOnCode(Code.code(), , "file.cpp",
+std::nullopt, Opts,
+{{"baz.h", R"(#pragma once
+  #include "bar.h"
+   )"},
+ {"bar.h", R"(#pragma once
+  int bar();
+   )"}});
+ASSERT_THAT(Errors.size(), testing::Eq(2U));
+EXPECT_EQ(Errors.front().Message.Message,
+  "no header providing \"bar\" is directly included");
+EXPECT_EQ(Errors.front().Message.FileOffset, Code.point("diag1"));
+EXPECT_EQ(Errors.back().Message.Message,
+  "no header providing \"bar\" is directly included");
+EXPECT_EQ(Errors.back().Message.FileOffset, Code.point("diag2"));
+  }
+}
+
 TEST(IncludeCleanerCheckTest, SuppressMissingIncludes) {
   const char *PreCode = R"(
 #include "bar.h"
Index: clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
+++ clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
@@ -33,3 +33,8 @@
files that match this regex as a suffix.  E.g., `foo/.*` disables
insertion/removal for all headers under the directory `foo`. By default, no 
headers will be ignored.
+
+.. option:: DeduplicateFindings
+
+   A boolean that controls whether the check should deduplicate findings for the
+   same symbol. Defaults to true.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -163,6 +163,9 @@
   `, so that it does not warn
   on macros starting with underscore and lowercase letter.
 
+- Misc-include-cleaner check has option `DeduplicateFindings` to output one
+  finding per occurence of a symbol.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
===
--- clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
+++ clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
@@ -44,6 +44,8 @@
   include_cleaner::PragmaIncludes RecordedPI;
   HeaderSearch *HS;
   std::vector IgnoreHeaders;
+  // Whether emit only one finding per usage of a symbol.
+  const bool DeduplicateFindings;
   llvm::SmallVector IgnoreHeadersRegex;
   bool shouldIgnore(const include_cleaner::Header );
 };
Index: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
===
--- clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
+++ 

[PATCH] D157390: [clang-tidy][include-cleaner] Add option to control deduplication of findings per symbol

2023-08-08 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added a reviewer: VitaNuo.
Herald added subscribers: PiotrZSL, carlosgalvezp, xazax.hun.
Herald added a reviewer: njames93.
Herald added a project: All.
kadircet requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

We received some user feedback around this being disruptful rather than
useful in certain workflows so add an option to control the output behaviour.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157390

Files:
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
  clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp

Index: clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp
===
--- clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp
+++ clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp
@@ -15,6 +15,8 @@
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Regex.h"
+#include "llvm/Testing/Annotations/Annotations.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
 
@@ -108,6 +110,48 @@
)"}}));
 }
 
+TEST(IncludeCleanerCheckTest, DedupsMissingIncludes) {
+  llvm::Annotations Code(R"(
+#include "baz.h" // IWYU pragma: keep
+
+int BarResult1 = $diag^bar();
+int BarResult2 = bar();)");
+
+  {
+std::vector Errors;
+runCheckOnCode(Code.code(), , "file.cpp",
+std::nullopt, ClangTidyOptions(),
+{{"baz.h", R"(#pragma once
+  #include "bar.h"
+   )"},
+ {"bar.h", R"(#pragma once
+  int bar();
+   )"}});
+ASSERT_THAT(Errors.size(), testing::Eq(1U));
+EXPECT_EQ(Errors.front().Message.Message,
+  "no header providing \"bar\" is directly included");
+EXPECT_EQ(Errors.front().Message.FileOffset, Code.point("diag"));
+  }
+  {
+std::vector Errors;
+ClangTidyOptions Opts;
+Opts.CheckOptions.insert({"DeduplicateFindings", "false"});
+runCheckOnCode(Code.code(), , "file.cpp",
+std::nullopt, Opts,
+{{"baz.h", R"(#pragma once
+  #include "bar.h"
+   )"},
+ {"bar.h", R"(#pragma once
+  int bar();
+   )"}});
+ASSERT_THAT(Errors.size(), testing::Eq(2U));
+EXPECT_EQ(Errors.front().Message.Message,
+  "no header providing \"bar\" is directly included");
+EXPECT_EQ(Errors.back().Message.Message,
+  "no header providing \"bar\" is directly included");
+  }
+}
+
 TEST(IncludeCleanerCheckTest, SuppressMissingIncludes) {
   const char *PreCode = R"(
 #include "bar.h"
Index: clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
+++ clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst
@@ -33,3 +33,8 @@
files that match this regex as a suffix.  E.g., `foo/.*` disables
insertion/removal for all headers under the directory `foo`. By default, no 
headers will be ignored.
+
+.. option:: DeduplicateFindings
+
+   A boolean that controls whether the check should deduplicate findings for the
+   same symbol. Defaults to true.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -163,6 +163,9 @@
   `, so that it does not warn
   on macros starting with underscore and lowercase letter.
 
+- Misc-include-cleaner check has option `DeduplicateFindings` to output one
+  finding per occurence of a symbol.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
===
--- clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
+++ clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
@@ -44,6 +44,8 @@
   include_cleaner::PragmaIncludes RecordedPI;
   HeaderSearch *HS;
   std::vector IgnoreHeaders;
+  // Whether emit only one finding per usage of a symbol.
+  const bool EmitOnce;
   llvm::SmallVector IgnoreHeadersRegex;
   bool shouldIgnore(const include_cleaner::Header );
 };
Index: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
===

[PATCH] D157207: [clangd] Fix typo in comment

2023-08-07 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

Thanks! LMK if i should land this for you (and an email address to set as 
commit author)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157207/new/

https://reviews.llvm.org/D157207

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


[PATCH] D157078: [include-cleaner] Handle files with unnamed buffers

2023-08-04 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG31873d3fca38: [include-cleaner] Handle files with unnamed 
buffers (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157078/new/

https://reviews.llvm.org/D157078

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

Index: clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
@@ -7,18 +7,32 @@
 //===--===//
 
 #include "clang-include-cleaner/Record.h"
+#include "clang-include-cleaner/Types.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
+#include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Serialization/PCHContainerOperations.h"
 #include "clang/Testing/TestAST.h"
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Testing/Annotations/Annotations.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
+#include 
+#include 
+#include 
 
 namespace clang::include_cleaner {
 namespace {
@@ -509,5 +523,38 @@
   EXPECT_TRUE(PI.shouldKeep(FM.getFile("always_keep.h").get()));
   EXPECT_FALSE(PI.shouldKeep(FM.getFile("usual.h").get()));
 }
+
+TEST_F(PragmaIncludeTest, ExportInUnnamedBuffer) {
+  llvm::StringLiteral Filename = "test.cpp";
+  auto Code = R"cpp(#include "exporter.h")cpp";
+  Inputs.ExtraFiles["exporter.h"] = R"cpp(
+  #pragma once
+  #include "foo.h" // IWYU pragma: export
+  )cpp";
+  Inputs.ExtraFiles["foo.h"] = "";
+
+  auto Clang = std::make_unique(
+  std::make_shared());
+  Clang->createDiagnostics();
+
+  Clang->setInvocation(std::make_unique());
+  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(
+  Clang->getInvocation(), {Filename.data()}, Clang->getDiagnostics(),
+  "clang"));
+
+  // Create unnamed memory buffers for all the files.
+  auto VFS = llvm::makeIntrusiveRefCnt();
+  VFS->addFile(Filename, /*ModificationTime=*/0,
+   llvm::MemoryBuffer::getMemBufferCopy(Code, /*BufferName=*/""));
+  for (const auto  : Inputs.ExtraFiles)
+VFS->addFile(Extra.getKey(), /*ModificationTime=*/0,
+ llvm::MemoryBuffer::getMemBufferCopy(Extra.getValue(),
+  /*BufferName=*/""));
+  auto *FM = Clang->createFileManager(VFS);
+  ASSERT_TRUE(Clang->ExecuteAction(*Inputs.MakeAction()));
+  EXPECT_THAT(
+  PI.getExporters(llvm::cantFail(FM->getFileRef("foo.h")), *FM),
+  testing::ElementsAre(llvm::cantFail(FM->getFileRef("exporter.h";
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/Record.cpp
===
--- clang-tools-extra/include-cleaner/lib/Record.cpp
+++ clang-tools-extra/include-cleaner/lib/Record.cpp
@@ -279,20 +279,6 @@
 
 auto [CommentFID, CommentOffset] = SM.getDecomposedLoc(Range.getBegin());
 int CommentLine = SM.getLineNumber(CommentFID, CommentOffset);
-auto Filename = SM.getBufferName(Range.getBegin());
-// Record export pragma.
-if (Pragma->startswith("export")) {
-  ExportStack.push_back({CommentLine, CommentFID, save(Filename), false});
-} else if (Pragma->startswith("begin_exports")) {
-  ExportStack.push_back({CommentLine, CommentFID, save(Filename), true});
-} else if (Pragma->startswith("end_exports")) {
-  // FIXME: be robust on unmatching cases. We should only pop the stack if
-  // the begin_exports and end_exports is in the same file.
-  if (!ExportStack.empty()) {
-assert(ExportStack.back().Block);
-ExportStack.pop_back();
-  }
-}
 
 if (InMainFile) {
   if (Pragma->startswith("keep")) {
@@ -307,8 +293,10 @@
 
 auto FE = SM.getFileEntryRefForID(CommentFID);
 if (!FE) {
-  // FIXME: Support IWYU pragmas in virtual files. Our mappings rely on
-  // "persistent" UniqueIDs and that is not the case for virtual files.
+  // This can only happen when the buffer was registered virtually into
+  // SourceManager and FileManager has no idea about it. In such a scenario,
+  // that file cannot be discovered by HeaderSearch, therefore no "explicit"
+  // includes 

[PATCH] D157071: [clangd] Dont assert on specific uris for diagnostics docs

2023-08-04 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG734da23e21eb: [clangd] Dont assert on specific uris for 
diagnostics docs (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157071/new/

https://reviews.llvm.org/D157071

Files:
  clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
  clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp


Index: clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
===
--- clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
+++ clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
@@ -34,6 +34,7 @@
 #include "llvm/Support/JSON.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
@@ -1961,8 +1962,8 @@
   withTag(DiagnosticTag::Unnecessary), diagSource(Diag::Clangd),
   withFix(Fix(Test.range("fix"), "", "remove #include directive");
   auto  = AST.getDiagnostics().front();
-  EXPECT_EQ(getDiagnosticDocURI(Diag.Source, Diag.ID, Diag.Name),
-std::string("https://clangd.llvm.org/guides/include-cleaner;));
+  EXPECT_THAT(getDiagnosticDocURI(Diag.Source, Diag.ID, Diag.Name),
+  llvm::ValueIs(Not(IsEmpty(;
   Cfg.Diagnostics.SuppressAll = true;
   WithContextValue SuppressAllWithCfg(Config::Key, std::move(Cfg));
   EXPECT_THAT(TU.build().getDiagnostics(), IsEmpty());
Index: clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
===
--- clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
+++ clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
@@ -34,7 +34,7 @@
 # CHECK-NEXT:   {
 # CHECK-NEXT: "code": "missing-includes",
 # CHECK-NEXT: "codeDescription": {
-# CHECK-NEXT:   "href": 
"https://clangd.llvm.org/guides/include-cleaner;
+# CHECK-NEXT:   "href": "{{.*}}"
 # CHECK-NEXT: },
 # CHECK-NEXT: "message": "No header providing \"Foo\" is directly 
included (fixes available)",
 # CHECK-NEXT: "range": {
@@ -53,7 +53,7 @@
 # CHECK-NEXT:   {
 # CHECK-NEXT: "code": "missing-includes",
 # CHECK-NEXT: "codeDescription": {
-# CHECK-NEXT:   "href": 
"https://clangd.llvm.org/guides/include-cleaner;
+# CHECK-NEXT:   "href": "{{.*}}"
 # CHECK-NEXT: },
 # CHECK-NEXT: "message": "No header providing \"Bar\" is directly 
included (fixes available)",
 # CHECK-NEXT: "range": {
@@ -72,7 +72,7 @@
 # CHECK-NEXT:   {
 # CHECK-NEXT: "code": "unused-includes",
 # CHECK-NEXT: "codeDescription": {
-# CHECK-NEXT:   "href": 
"https://clangd.llvm.org/guides/include-cleaner;
+# CHECK-NEXT:   "href": "{{.*}}"
 # CHECK-NEXT: },
 # CHECK-NEXT: "message": "Included header all1.h is not used directly 
(fixes available)",
 # CHECK-NEXT: "range": {
@@ -94,7 +94,7 @@
 # CHECK-NEXT:   {
 # CHECK-NEXT: "code": "unused-includes",
 # CHECK-NEXT: "codeDescription": {
-# CHECK-NEXT:   "href": 
"https://clangd.llvm.org/guides/include-cleaner;
+# CHECK-NEXT:   "href": "{{.*}}"
 # CHECK-NEXT: },
 # CHECK-NEXT: "message": "Included header all2.h is not used directly 
(fixes available)",
 # CHECK-NEXT: "range": {


Index: clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
===
--- clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
+++ clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
@@ -34,6 +34,7 @@
 #include "llvm/Support/JSON.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
@@ -1961,8 +1962,8 @@
   withTag(DiagnosticTag::Unnecessary), diagSource(Diag::Clangd),
   withFix(Fix(Test.range("fix"), "", "remove #include directive");
   auto  = AST.getDiagnostics().front();
-  EXPECT_EQ(getDiagnosticDocURI(Diag.Source, Diag.ID, Diag.Name),
-std::string("https://clangd.llvm.org/guides/include-cleaner;));
+  EXPECT_THAT(getDiagnosticDocURI(Diag.Source, Diag.ID, Diag.Name),
+  llvm::ValueIs(Not(IsEmpty(;
   Cfg.Diagnostics.SuppressAll = true;
   WithContextValue SuppressAllWithCfg(Config::Key, std::move(Cfg));
   EXPECT_THAT(TU.build().getDiagnostics(), IsEmpty());
Index: clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
===
--- clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
+++ clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
@@ -34,7 +34,7 @@
 # CHECK-NEXT:   

[PATCH] D157078: [include-cleaner] Handle files with unnamed buffers

2023-08-04 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added a reviewer: hokein.
Herald added a subscriber: ChuanqiXu.
Herald added a project: All.
kadircet requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Some tools can register virtual buffers without identifiers into the
filemanager. Make sure we can handle pragmas in such cases.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157078

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

Index: clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
@@ -7,18 +7,32 @@
 //===--===//
 
 #include "clang-include-cleaner/Record.h"
+#include "clang-include-cleaner/Types.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
+#include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Serialization/PCHContainerOperations.h"
 #include "clang/Testing/TestAST.h"
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Testing/Annotations/Annotations.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
+#include 
+#include 
+#include 
 
 namespace clang::include_cleaner {
 namespace {
@@ -509,5 +523,38 @@
   EXPECT_TRUE(PI.shouldKeep(FM.getFile("always_keep.h").get()));
   EXPECT_FALSE(PI.shouldKeep(FM.getFile("usual.h").get()));
 }
+
+TEST_F(PragmaIncludeTest, ExportInUnnamedBuffer) {
+  llvm::StringLiteral Filename = "test.cpp";
+  auto Code = R"cpp(#include "exporter.h")cpp";
+  Inputs.ExtraFiles["exporter.h"] = R"cpp(
+  #pragma once
+  #include "foo.h" // IWYU pragma: export
+  )cpp";
+  Inputs.ExtraFiles["foo.h"] = "";
+
+  auto Clang = std::make_unique(
+  std::make_shared());
+  Clang->createDiagnostics();
+
+  Clang->setInvocation(std::make_unique());
+  ASSERT_TRUE(CompilerInvocation::CreateFromArgs(
+  Clang->getInvocation(), {Filename.data()}, Clang->getDiagnostics(),
+  "clang"));
+
+  // Create unnamed memory buffers for all the files.
+  auto VFS = llvm::makeIntrusiveRefCnt();
+  VFS->addFile(Filename, /*ModificationTime=*/0,
+   llvm::MemoryBuffer::getMemBufferCopy(Code, /*BufferName=*/""));
+  for (const auto  : Inputs.ExtraFiles)
+VFS->addFile(Extra.getKey(), /*ModificationTime=*/0,
+ llvm::MemoryBuffer::getMemBufferCopy(Extra.getValue(),
+  /*BufferName=*/""));
+  auto *FM = Clang->createFileManager(VFS);
+  ASSERT_TRUE(Clang->ExecuteAction(*Inputs.MakeAction()));
+  EXPECT_THAT(
+  PI.getExporters(llvm::cantFail(FM->getFileRef("foo.h")), *FM),
+  testing::ElementsAre(llvm::cantFail(FM->getFileRef("exporter.h";
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/Record.cpp
===
--- clang-tools-extra/include-cleaner/lib/Record.cpp
+++ clang-tools-extra/include-cleaner/lib/Record.cpp
@@ -279,20 +279,6 @@
 
 auto [CommentFID, CommentOffset] = SM.getDecomposedLoc(Range.getBegin());
 int CommentLine = SM.getLineNumber(CommentFID, CommentOffset);
-auto Filename = SM.getBufferName(Range.getBegin());
-// Record export pragma.
-if (Pragma->startswith("export")) {
-  ExportStack.push_back({CommentLine, CommentFID, save(Filename), false});
-} else if (Pragma->startswith("begin_exports")) {
-  ExportStack.push_back({CommentLine, CommentFID, save(Filename), true});
-} else if (Pragma->startswith("end_exports")) {
-  // FIXME: be robust on unmatching cases. We should only pop the stack if
-  // the begin_exports and end_exports is in the same file.
-  if (!ExportStack.empty()) {
-assert(ExportStack.back().Block);
-ExportStack.pop_back();
-  }
-}
 
 if (InMainFile) {
   if (Pragma->startswith("keep")) {
@@ -307,8 +293,10 @@
 
 auto FE = SM.getFileEntryRefForID(CommentFID);
 if (!FE) {
-  // FIXME: Support IWYU pragmas in virtual files. Our mappings rely on
-  // "persistent" UniqueIDs and that is not the case for virtual files.
+  // This can only happen when the buffer was registered virtually into
+  // SourceManager and FileManager 

[PATCH] D157071: [clangd] Dont assert on specific uris for diagnostics docs

2023-08-04 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added a reviewer: hokein.
Herald added a subscriber: arphaman.
Herald added a project: All.
kadircet requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

To enable customization of links in downstream projects without
breaking tests (and also ease of pointing at different links in the future).
Just check for existence instead.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157071

Files:
  clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
  clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp


Index: clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
===
--- clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
+++ clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
@@ -34,6 +34,7 @@
 #include "llvm/Support/JSON.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
@@ -1961,8 +1962,8 @@
   withTag(DiagnosticTag::Unnecessary), diagSource(Diag::Clangd),
   withFix(Fix(Test.range("fix"), "", "remove #include directive");
   auto  = AST.getDiagnostics().front();
-  EXPECT_EQ(getDiagnosticDocURI(Diag.Source, Diag.ID, Diag.Name),
-std::string("https://clangd.llvm.org/guides/include-cleaner;));
+  EXPECT_THAT(getDiagnosticDocURI(Diag.Source, Diag.ID, Diag.Name),
+  llvm::ValueIs(Not(IsEmpty(;
   Cfg.Diagnostics.SuppressAll = true;
   WithContextValue SuppressAllWithCfg(Config::Key, std::move(Cfg));
   EXPECT_THAT(TU.build().getDiagnostics(), IsEmpty());
Index: clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
===
--- clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
+++ clang-tools-extra/clangd/test/include-cleaner-batch-fix.test
@@ -34,7 +34,7 @@
 # CHECK-NEXT:   {
 # CHECK-NEXT: "code": "missing-includes",
 # CHECK-NEXT: "codeDescription": {
-# CHECK-NEXT:   "href": 
"https://clangd.llvm.org/guides/include-cleaner;
+# CHECK-NEXT:   "href": "{{.*}}"
 # CHECK-NEXT: },
 # CHECK-NEXT: "message": "No header providing \"Foo\" is directly 
included (fixes available)",
 # CHECK-NEXT: "range": {
@@ -53,7 +53,7 @@
 # CHECK-NEXT:   {
 # CHECK-NEXT: "code": "missing-includes",
 # CHECK-NEXT: "codeDescription": {
-# CHECK-NEXT:   "href": 
"https://clangd.llvm.org/guides/include-cleaner;
+# CHECK-NEXT:   "href": "{{.*}}"
 # CHECK-NEXT: },
 # CHECK-NEXT: "message": "No header providing \"Bar\" is directly 
included (fixes available)",
 # CHECK-NEXT: "range": {
@@ -72,7 +72,7 @@
 # CHECK-NEXT:   {
 # CHECK-NEXT: "code": "unused-includes",
 # CHECK-NEXT: "codeDescription": {
-# CHECK-NEXT:   "href": 
"https://clangd.llvm.org/guides/include-cleaner;
+# CHECK-NEXT:   "href": "{{.*}}"
 # CHECK-NEXT: },
 # CHECK-NEXT: "message": "Included header all1.h is not used directly 
(fixes available)",
 # CHECK-NEXT: "range": {
@@ -94,7 +94,7 @@
 # CHECK-NEXT:   {
 # CHECK-NEXT: "code": "unused-includes",
 # CHECK-NEXT: "codeDescription": {
-# CHECK-NEXT:   "href": 
"https://clangd.llvm.org/guides/include-cleaner;
+# CHECK-NEXT:   "href": "{{.*}}"
 # CHECK-NEXT: },
 # CHECK-NEXT: "message": "Included header all2.h is not used directly 
(fixes available)",
 # CHECK-NEXT: "range": {


Index: clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
===
--- clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
+++ clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
@@ -34,6 +34,7 @@
 #include "llvm/Support/JSON.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
@@ -1961,8 +1962,8 @@
   withTag(DiagnosticTag::Unnecessary), diagSource(Diag::Clangd),
   withFix(Fix(Test.range("fix"), "", "remove #include directive");
   auto  = AST.getDiagnostics().front();
-  EXPECT_EQ(getDiagnosticDocURI(Diag.Source, Diag.ID, Diag.Name),
-std::string("https://clangd.llvm.org/guides/include-cleaner;));
+  EXPECT_THAT(getDiagnosticDocURI(Diag.Source, Diag.ID, Diag.Name),
+  llvm::ValueIs(Not(IsEmpty(;
   Cfg.Diagnostics.SuppressAll = true;
   WithContextValue SuppressAllWithCfg(Config::Key, std::move(Cfg));
   EXPECT_THAT(TU.build().getDiagnostics(), IsEmpty());
Index: clang-tools-extra/clangd/test/include-cleaner-batch-fix.test

[PATCH] D156704: [clang][HeaderSearch] Treat framework headers as System for suggestPath

2023-08-03 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang/lib/Lex/HeaderSearch.cpp:1939
 
 std::string HeaderSearch::suggestPathToFileForDiagnostics(
 llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,

sorry I guess my suggestion get distorted a little bit on the way :D

I was actually suggesting to rename `IsSystem` to `IsAngled`, and change the 
logic in the rest of the code here to look for angled-ness of include search 
path, rather than system-ness.
As all of the current callers make use of this information to figure out if 
they should spell the includes with `angles` or `quotes` and set it if the 
include search dir is either part of angled or system includes.

That way we make sure we're not giving mixed signals out of this function. WDYT?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156704/new/

https://reviews.llvm.org/D156704

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


[PATCH] D156123: [include-cleaner] Unify always_keep with rest of the keep logic

2023-08-02 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG43974333dd09: [include-cleaner] Unify always_keep with rest 
of the keep logic (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156123/new/

https://reviews.llvm.org/D156123

Files:
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h
  clang-tools-extra/include-cleaner/lib/Analysis.cpp
  clang-tools-extra/include-cleaner/lib/Record.cpp
  clang-tools-extra/include-cleaner/unittests/RecordTest.cpp

Index: clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
@@ -13,10 +13,12 @@
 #include "clang/Testing/TestAST.h"
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Testing/Annotations/Annotations.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
+#include 
 
 namespace clang::include_cleaner {
 namespace {
@@ -309,68 +311,58 @@
 };
 
 TEST_F(PragmaIncludeTest, IWYUKeep) {
-  llvm::Annotations MainFile(R"cpp(
-$keep1^#include "keep1.h" // IWYU pragma: keep
-$keep2^#include "keep2.h" /* IWYU pragma: keep */
+  Inputs.Code = R"cpp(
+#include "keep1.h" // IWYU pragma: keep
+#include "keep2.h" /* IWYU pragma: keep */
 
-$export1^#include "export1.h" // IWYU pragma: export
-$begin_exports^// IWYU pragma: begin_exports
-$export2^#include "export2.h"
-$export3^#include "export3.h"
-$end_exports^// IWYU pragma: end_exports
+#include "export1.h" // IWYU pragma: export
+// IWYU pragma: begin_exports
+#include "export2.h"
+#include "export3.h"
+// IWYU pragma: end_exports
 
-$normal^#include "normal.h"
+#include "normal.h"
 
-$begin_keep^// IWYU pragma: begin_keep 
-$keep3^#include "keep3.h"
-$end_keep^// IWYU pragma: end_keep
+// IWYU pragma: begin_keep
+#include "keep3.h"
+// IWYU pragma: end_keep
 
-// IWYU pragma: begin_keep 
-$keep4^#include "keep4.h"
 // IWYU pragma: begin_keep
-$keep5^#include "keep5.h"
+#include "keep4.h"
+// IWYU pragma: begin_keep
+#include "keep5.h"
 // IWYU pragma: end_keep
-$keep6^#include "keep6.h"
+#include "keep6.h"
 // IWYU pragma: end_keep
-  )cpp");
-
-  auto OffsetToLineNum = [](size_t Offset) {
-int Count = MainFile.code().substr(0, Offset).count('\n');
-return Count + 1;
-  };
-
-  Inputs.Code = MainFile.code();
+#include 
+#include  // IWYU pragma: keep
+#include  // IWYU pragma: export
+  )cpp";
   createEmptyFiles({"keep1.h", "keep2.h", "keep3.h", "keep4.h", "keep5.h",
 "keep6.h", "export1.h", "export2.h", "export3.h",
-"normal.h"});
+"normal.h", "std/vector", "std/map", "std/set"});
 
+  Inputs.ExtraArgs.push_back("-isystemstd");
   TestAST Processed = build();
-  EXPECT_FALSE(PI.shouldKeep(1));
-
-  // Keep
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep1";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep2";
+  auto  = Processed.fileManager();
 
-  EXPECT_FALSE(PI.shouldKeep(
-  OffsetToLineNum(MainFile.point("begin_keep"; // no # directive
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep3";
-  EXPECT_FALSE(PI.shouldKeep(
-  OffsetToLineNum(MainFile.point("end_keep"; // no # directive
+  EXPECT_FALSE(PI.shouldKeep(FM.getFile("normal.h").get()));
+  EXPECT_FALSE(PI.shouldKeep(FM.getFile("std/vector").get()));
 
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep4";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep5";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep6";
+  // Keep
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep1.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep2.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep3.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep4.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep5.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep6.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("std/map").get()));
 
   // Exports
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("export1";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("export2";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("export3";
-  EXPECT_FALSE(PI.shouldKeep(
-  

[PATCH] D156122: [include-cleaner] Introduce support for always_keep pragma

2023-08-02 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG778a5e9bc633: [include-cleaner] Introduce support for 
always_keep pragma (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156122/new/

https://reviews.llvm.org/D156122

Files:
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h
  clang-tools-extra/include-cleaner/lib/Analysis.cpp
  clang-tools-extra/include-cleaner/lib/Record.cpp
  clang-tools-extra/include-cleaner/unittests/RecordTest.cpp

Index: clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
@@ -502,5 +502,20 @@
   EXPECT_FALSE(PI.isSelfContained(FM.getFile("unguarded.h").get()));
 }
 
+TEST_F(PragmaIncludeTest, AlwaysKeep) {
+  Inputs.Code = R"cpp(
+  #include "always_keep.h"
+  #include "usual.h"
+  )cpp";
+  Inputs.ExtraFiles["always_keep.h"] = R"cpp(
+  #pragma once
+  // IWYU pragma: always_keep
+  )cpp";
+  Inputs.ExtraFiles["usual.h"] = "#pragma once";
+  TestAST Processed = build();
+  auto  = Processed.fileManager();
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("always_keep.h").get()));
+  EXPECT_FALSE(PI.shouldKeep(FM.getFile("usual.h").get()));
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/Record.cpp
===
--- clang-tools-extra/include-cleaner/lib/Record.cpp
+++ clang-tools-extra/include-cleaner/lib/Record.cpp
@@ -11,6 +11,9 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclGroup.h"
+#include "clang/Basic/FileEntry.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -20,8 +23,17 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Tooling/Inclusions/HeaderAnalysis.h"
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/StringSaver.h"
+#include 
+#include 
 #include 
+#include 
 #include 
 #include 
 
@@ -262,32 +274,14 @@
 if (!Pragma)
   return false;
 
-if (Pragma->consume_front("private")) {
-  auto *FE = SM.getFileEntryForID(SM.getFileID(Range.getBegin()));
-  if (!FE)
-return false;
-  StringRef PublicHeader;
-  if (Pragma->consume_front(", include ")) {
-// We always insert using the spelling from the pragma.
-PublicHeader = save(Pragma->startswith("<") || Pragma->startswith("\"")
-? (*Pragma)
-: ("\"" + *Pragma + "\"").str());
-  }
-  Out->IWYUPublic.insert({FE->getLastRef().getUniqueID(), PublicHeader});
-  return false;
-}
-FileID CommentFID = SM.getFileID(Range.getBegin());
-int CommentLine = SM.getLineNumber(SM.getFileID(Range.getBegin()),
-   SM.getFileOffset(Range.getBegin()));
+auto [CommentFID, CommentOffset] = SM.getDecomposedLoc(Range.getBegin());
+int CommentLine = SM.getLineNumber(CommentFID, CommentOffset);
+auto Filename = SM.getBufferName(Range.getBegin());
 // Record export pragma.
 if (Pragma->startswith("export")) {
-  ExportStack.push_back({CommentLine, CommentFID,
- save(SM.getFileEntryForID(CommentFID)->getName()),
- false});
+  ExportStack.push_back({CommentLine, CommentFID, save(Filename), false});
 } else if (Pragma->startswith("begin_exports")) {
-  ExportStack.push_back({CommentLine, CommentFID,
- save(SM.getFileEntryForID(CommentFID)->getName()),
- true});
+  ExportStack.push_back({CommentLine, CommentFID, save(Filename), true});
 } else if (Pragma->startswith("end_exports")) {
   // FIXME: be robust on unmatching cases. We should only pop the stack if
   // the begin_exports and end_exports is in the same file.
@@ -307,6 +301,29 @@
 KeepStack.pop_back();
   }
 }
+
+auto FE = SM.getFileEntryRefForID(CommentFID);
+if (!FE) {
+  // FIXME: Support IWYU pragmas in virtual files. Our mappings rely on
+  // "persistent" UniqueIDs and that is not the case for virtual files.
+  return false;
+}
+auto CommentUID = FE->getUniqueID();
+if (Pragma->consume_front("private")) {
+  StringRef PublicHeader;
+  if 

[PATCH] D156123: [include-cleaner] Unify always_keep with rest of the keep logic

2023-08-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/include-cleaner/lib/Record.cpp:248
+  if (Top.SeenAtFile == SM.getMainFileID() && IncludedFile)
+Out->ShouldKeep.insert(IncludedFile->getUniqueID());
 }

VitaNuo wrote:
> If I understand correctly, you should be able to extract `IncludedFile` from 
> `IncludedHeader->physical()` and then you don't need the extra parameter.
> 
> Also, technically this and the below code used to work for standard and 
> verbatim headers before this change. Now it probably won't, since there will 
> be no corresponding `IncludedFile`. Is this actually something to worry about?
> If I understand correctly, you should be able to extract IncludedFile from 
> IncludedHeader->physical() and then you don't need the extra parameter.

Not really, if included file is recognized as a system include we won't have a 
physical file entry.

> Also, technically this and the below code used to work for standard and 
> verbatim headers before this change. Now it probably won't, since there will 
> be no corresponding IncludedFile. Is this actually something to worry about?

It still does (and I am adding tests for those). All of them were still 
recorded based on their line number into this structure, now instead we're 
recording them through their fileentry (even if their `include_cleaner::Header` 
representation is non-physical, we're talking about an include here, so it must 
have a logical file it resolves to, when it exists). So this still implies some 
behavior changes of course:
- We no longer respect IWYU pragmas assoaciated with non-existent/virtual 
files, but all of the users already suppress unused diagnostics for unresolved 
files and moreover the new `shouldKeep` API forces the caller to pass in a 
file-entry. Hence going forward we give explicit info to the callers that they 
should deal with unresolved headers on their own way.
- If there are multiple include directives resolving to the same physical file, 
we'll bind their fate. We already assume in other places that a file will be 
included at most once, so I don't think that's also a worth concern.

WDYT?



Comment at: clang-tools-extra/include-cleaner/lib/Record.cpp:262
+  Out->ShouldKeep.insert(IncludedFile->getUniqueID());
+}
 

VitaNuo wrote:
> nit: remove braces.
because the condition is spanning multiple lines, i'd rather keep it



Comment at: clang-tools-extra/include-cleaner/lib/Record.cpp:419
 bool PragmaIncludes::shouldKeep(const FileEntry *FE) const {
-  return AlwaysKeep.contains(FE->getUniqueID());
+  return ShouldKeep.contains(FE->getUniqueID());
 }

VitaNuo wrote:
> Consider inlining this function.
same concerns about inlining as in the previous patch


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156123/new/

https://reviews.llvm.org/D156123

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


[PATCH] D156123: [include-cleaner] Unify always_keep with rest of the keep logic

2023-08-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet updated this revision to Diff 546070.
kadircet added a comment.

- Add tests for pragmas on stdlib headers


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156123/new/

https://reviews.llvm.org/D156123

Files:
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h
  clang-tools-extra/include-cleaner/lib/Analysis.cpp
  clang-tools-extra/include-cleaner/lib/Record.cpp
  clang-tools-extra/include-cleaner/unittests/RecordTest.cpp

Index: clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
@@ -13,10 +13,12 @@
 #include "clang/Testing/TestAST.h"
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Testing/Annotations/Annotations.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
+#include 
 
 namespace clang::include_cleaner {
 namespace {
@@ -309,68 +311,58 @@
 };
 
 TEST_F(PragmaIncludeTest, IWYUKeep) {
-  llvm::Annotations MainFile(R"cpp(
-$keep1^#include "keep1.h" // IWYU pragma: keep
-$keep2^#include "keep2.h" /* IWYU pragma: keep */
+  Inputs.Code = R"cpp(
+#include "keep1.h" // IWYU pragma: keep
+#include "keep2.h" /* IWYU pragma: keep */
 
-$export1^#include "export1.h" // IWYU pragma: export
-$begin_exports^// IWYU pragma: begin_exports
-$export2^#include "export2.h"
-$export3^#include "export3.h"
-$end_exports^// IWYU pragma: end_exports
+#include "export1.h" // IWYU pragma: export
+// IWYU pragma: begin_exports
+#include "export2.h"
+#include "export3.h"
+// IWYU pragma: end_exports
 
-$normal^#include "normal.h"
+#include "normal.h"
 
-$begin_keep^// IWYU pragma: begin_keep 
-$keep3^#include "keep3.h"
-$end_keep^// IWYU pragma: end_keep
+// IWYU pragma: begin_keep
+#include "keep3.h"
+// IWYU pragma: end_keep
 
-// IWYU pragma: begin_keep 
-$keep4^#include "keep4.h"
 // IWYU pragma: begin_keep
-$keep5^#include "keep5.h"
+#include "keep4.h"
+// IWYU pragma: begin_keep
+#include "keep5.h"
 // IWYU pragma: end_keep
-$keep6^#include "keep6.h"
+#include "keep6.h"
 // IWYU pragma: end_keep
-  )cpp");
-
-  auto OffsetToLineNum = [](size_t Offset) {
-int Count = MainFile.code().substr(0, Offset).count('\n');
-return Count + 1;
-  };
-
-  Inputs.Code = MainFile.code();
+#include 
+#include  // IWYU pragma: keep
+#include  // IWYU pragma: export
+  )cpp";
   createEmptyFiles({"keep1.h", "keep2.h", "keep3.h", "keep4.h", "keep5.h",
 "keep6.h", "export1.h", "export2.h", "export3.h",
-"normal.h"});
+"normal.h", "std/vector", "std/map", "std/set"});
 
+  Inputs.ExtraArgs.push_back("-isystemstd");
   TestAST Processed = build();
-  EXPECT_FALSE(PI.shouldKeep(1));
-
-  // Keep
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep1";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep2";
+  auto  = Processed.fileManager();
 
-  EXPECT_FALSE(PI.shouldKeep(
-  OffsetToLineNum(MainFile.point("begin_keep"; // no # directive
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep3";
-  EXPECT_FALSE(PI.shouldKeep(
-  OffsetToLineNum(MainFile.point("end_keep"; // no # directive
+  EXPECT_FALSE(PI.shouldKeep(FM.getFile("normal.h").get()));
+  EXPECT_FALSE(PI.shouldKeep(FM.getFile("std/vector").get()));
 
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep4";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep5";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep6";
+  // Keep
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep1.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep2.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep3.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep4.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep5.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep6.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("std/map").get()));
 
   // Exports
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("export1";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("export2";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("export3";
-  EXPECT_FALSE(PI.shouldKeep(
-  OffsetToLineNum(MainFile.point("begin_exports"; // no # directive
-  EXPECT_FALSE(PI.shouldKeep(
-  OffsetToLineNum(MainFile.point("end_exports"; // no # directive
-
-  

[PATCH] D156122: [include-cleaner] Introduce support for always_keep pragma

2023-08-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet updated this revision to Diff 546001.
kadircet marked an inline comment as done.
kadircet added a comment.

- Rebase
- Properly check for null-ness of FileEntry.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156122/new/

https://reviews.llvm.org/D156122

Files:
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h
  clang-tools-extra/include-cleaner/lib/Analysis.cpp
  clang-tools-extra/include-cleaner/lib/Record.cpp
  clang-tools-extra/include-cleaner/unittests/RecordTest.cpp

Index: clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
@@ -502,5 +502,20 @@
   EXPECT_FALSE(PI.isSelfContained(FM.getFile("unguarded.h").get()));
 }
 
+TEST_F(PragmaIncludeTest, AlwaysKeep) {
+  Inputs.Code = R"cpp(
+  #include "always_keep.h"
+  #include "usual.h"
+  )cpp";
+  Inputs.ExtraFiles["always_keep.h"] = R"cpp(
+  #pragma once
+  // IWYU pragma: always_keep
+  )cpp";
+  Inputs.ExtraFiles["usual.h"] = "#pragma once";
+  TestAST Processed = build();
+  auto  = Processed.fileManager();
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("always_keep.h").get()));
+  EXPECT_FALSE(PI.shouldKeep(FM.getFile("usual.h").get()));
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/Record.cpp
===
--- clang-tools-extra/include-cleaner/lib/Record.cpp
+++ clang-tools-extra/include-cleaner/lib/Record.cpp
@@ -11,6 +11,9 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclGroup.h"
+#include "clang/Basic/FileEntry.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -20,8 +23,17 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Tooling/Inclusions/HeaderAnalysis.h"
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/StringSaver.h"
+#include 
+#include 
 #include 
+#include 
 #include 
 #include 
 
@@ -262,32 +274,14 @@
 if (!Pragma)
   return false;
 
-if (Pragma->consume_front("private")) {
-  auto *FE = SM.getFileEntryForID(SM.getFileID(Range.getBegin()));
-  if (!FE)
-return false;
-  StringRef PublicHeader;
-  if (Pragma->consume_front(", include ")) {
-// We always insert using the spelling from the pragma.
-PublicHeader = save(Pragma->startswith("<") || Pragma->startswith("\"")
-? (*Pragma)
-: ("\"" + *Pragma + "\"").str());
-  }
-  Out->IWYUPublic.insert({FE->getLastRef().getUniqueID(), PublicHeader});
-  return false;
-}
-FileID CommentFID = SM.getFileID(Range.getBegin());
-int CommentLine = SM.getLineNumber(SM.getFileID(Range.getBegin()),
-   SM.getFileOffset(Range.getBegin()));
+auto [CommentFID, CommentOffset] = SM.getDecomposedLoc(Range.getBegin());
+int CommentLine = SM.getLineNumber(CommentFID, CommentOffset);
+auto Filename = SM.getBufferName(Range.getBegin());
 // Record export pragma.
 if (Pragma->startswith("export")) {
-  ExportStack.push_back({CommentLine, CommentFID,
- save(SM.getFileEntryForID(CommentFID)->getName()),
- false});
+  ExportStack.push_back({CommentLine, CommentFID, save(Filename), false});
 } else if (Pragma->startswith("begin_exports")) {
-  ExportStack.push_back({CommentLine, CommentFID,
- save(SM.getFileEntryForID(CommentFID)->getName()),
- true});
+  ExportStack.push_back({CommentLine, CommentFID, save(Filename), true});
 } else if (Pragma->startswith("end_exports")) {
   // FIXME: be robust on unmatching cases. We should only pop the stack if
   // the begin_exports and end_exports is in the same file.
@@ -307,6 +301,29 @@
 KeepStack.pop_back();
   }
 }
+
+auto FE = SM.getFileEntryRefForID(CommentFID);
+if (!FE) {
+  // FIXME: Support IWYU pragmas in virtual files. Our mappings rely on
+  // "persistent" UniqueIDs and that is not the case for virtual files.
+  return false;
+}
+auto CommentUID = FE->getUniqueID();
+if (Pragma->consume_front("private")) {
+  StringRef PublicHeader;
+  if 

[PATCH] D156122: [include-cleaner] Introduce support for always_keep pragma

2023-08-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet marked an inline comment as done.
kadircet added inline comments.



Comment at: 
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h:63
+  bool shouldKeep(unsigned HashLineNumber) const;
+  bool shouldKeep(const FileEntry *FE) const;
 

VitaNuo wrote:
> Why wouldn't you actually inline the implementation for both these functions? 
> The implementations seem trivial enough. 
most of the binaries are build with LTO nowadays, so inlining code into headers 
doesn't really gain much from performance perspective. moreover, these are not 
really hot functions, they're invoked once per `#include` directive inside the 
main file, at the end of analysis.

OTOH, when they're inlined and there needs to be a change to these function 
definitions, it requires all the translation units depending on this header to 
be recompiled. Hence I think having them in the cpp file is a not benefit for 
development cycles.



Comment at: clang-tools-extra/include-cleaner/lib/Record.cpp:37
 #include 
+#include 
 

VitaNuo wrote:
> I don't think you've added a dependency on all these headers in this patch. 
> Nice if you've actually fixed the missing include violations all over the 
> file, but please double-check that there are no debugging etc. artefacts left.
yes these are all fixes generated by include-cleaner, I don't have any unused 
include findings.



Comment at: clang-tools-extra/include-cleaner/lib/Record.cpp:272
 
+FileID CommentFID = SM.getFileID(Range.getBegin());
+auto *FE = SM.getFileEntryForID(CommentFID);

VitaNuo wrote:
> You might want to inline this call, it seems to have a single usage right 
> below.
do you mean initializer for `CommentFID`? if so `CommentFID` is actually used 
in more places below



Comment at: clang-tools-extra/include-cleaner/lib/Record.cpp:288
+if (Pragma->consume_front("always_keep")) {
+  Out->AlwaysKeep.insert(FE->getUniqueID());
+  return false;

VitaNuo wrote:
> I believe you need to check `FE` for `nullptr`, similar to private pragma 
> handling above. 
> Also, the code above does `FE->getLastRef().getUniqueID()`, is there any 
> difference to `FE->getUniqueID()`? I wouldn't expect so, but then you could 
> maybe unify this one with the above, this way or the other.
thanks missed that. unified all the usages for `getUniqueID`, they all should 
be the same.

you're absolutely right about checking for `FE`, in practice it's almost never 
null as it's the file in which we've found the IWYU pragma. But SourceManager 
actually allows working with virtual files, in which case there might not be a 
phyiscal file entry.
code in rest of this logic was also relying on `FE` being non-null without 
checking for it. Moved code around a little bit and used filename inside the 
SourceManager instead to make sure export/keep logic can work with virtual 
files too.

for now not adding support to always_keep and private pragmas for virtual 
files, as it requires deeper changes in the way we store uniqueids (we can no 
longer depend on them) and they're not common in practice (usually those 
virtual files are provided as predefines from the compiler and they likely 
won't contain IWYU pragmas).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156122/new/

https://reviews.llvm.org/D156122

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


[PATCH] D156712: [include-cleaner] Handle StdInitializerListExprs

2023-08-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG3736eaa6a0b8: [include-cleaner] Handle 
StdInitializerListExprs (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156712/new/

https://reviews.llvm.org/D156712

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


Index: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -282,7 +282,6 @@
"using ns::^function;");
 }
 
-
 TEST(WalkAST, Alias) {
   testWalk(R"cpp(
 namespace ns { int x; }
@@ -510,5 +509,14 @@
   testWalk("enum class E : int {};", "enum class ^E : int ;");
 }
 
+TEST(WalkAST, InitializerList) {
+  testWalk(R"cpp(
+   namespace std {
+template  struct $implicit^initializer_list {};
+   })cpp",
+   R"cpp(
+   const char* s = "";
+   auto sx = ^{s};)cpp");
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/WalkAST.cpp
===
--- clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -304,6 +304,16 @@
 }
 return RecursiveASTVisitor::TraverseTemplateArgumentLoc(TL);
   }
+
+  bool VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
+// Reliance on initializer_lists requires std::initializer_list to be
+// visible per standard. So report a reference to it, otherwise include of
+// `` might not receive any use.
+report(E->getExprLoc(),
+   const_cast(E->getBestDynamicClassType()),
+   RefType::Implicit);
+return true;
+  }
 };
 
 } // namespace


Index: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -282,7 +282,6 @@
"using ns::^function;");
 }
 
-
 TEST(WalkAST, Alias) {
   testWalk(R"cpp(
 namespace ns { int x; }
@@ -510,5 +509,14 @@
   testWalk("enum class E : int {};", "enum class ^E : int ;");
 }
 
+TEST(WalkAST, InitializerList) {
+  testWalk(R"cpp(
+   namespace std {
+template  struct $implicit^initializer_list {};
+   })cpp",
+   R"cpp(
+   const char* s = "";
+   auto sx = ^{s};)cpp");
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/WalkAST.cpp
===
--- clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -304,6 +304,16 @@
 }
 return RecursiveASTVisitor::TraverseTemplateArgumentLoc(TL);
   }
+
+  bool VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
+// Reliance on initializer_lists requires std::initializer_list to be
+// visible per standard. So report a reference to it, otherwise include of
+// `` might not receive any use.
+report(E->getExprLoc(),
+   const_cast(E->getBestDynamicClassType()),
+   RefType::Implicit);
+return true;
+  }
 };
 
 } // namespace
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156712: [include-cleaner] Handle StdInitializerListExprs

2023-07-31 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added a reviewer: hokein.
Herald added a project: All.
kadircet requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Per C++ standard, programs omitting the definition for initializer_list
is ill-formed, https://eel.is/c++draft/dcl.init.list#2.

Fixes https://github.com/llvm/llvm-project/issues/64198


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156712

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


Index: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -282,7 +282,6 @@
"using ns::^function;");
 }
 
-
 TEST(WalkAST, Alias) {
   testWalk(R"cpp(
 namespace ns { int x; }
@@ -510,5 +509,14 @@
   testWalk("enum class E : int {};", "enum class ^E : int ;");
 }
 
+TEST(WalkAST, InitializerList) {
+  testWalk(R"cpp(
+   namespace std {
+template  struct $implicit^initializer_list {};
+   })cpp",
+   R"cpp(
+   const char* s = "";
+   auto sx = ^{s};)cpp");
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/WalkAST.cpp
===
--- clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -304,6 +304,16 @@
 }
 return RecursiveASTVisitor::TraverseTemplateArgumentLoc(TL);
   }
+
+  bool VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
+// Reliance on initializer_lists requires std::initializer_list to be
+// visible per standard. So report a reference to it, otherwise include of
+// `` might not receive any use.
+report(E->getExprLoc(),
+   const_cast(E->getBestDynamicClassType()),
+   RefType::Implicit);
+return true;
+  }
 };
 
 } // namespace


Index: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -282,7 +282,6 @@
"using ns::^function;");
 }
 
-
 TEST(WalkAST, Alias) {
   testWalk(R"cpp(
 namespace ns { int x; }
@@ -510,5 +509,14 @@
   testWalk("enum class E : int {};", "enum class ^E : int ;");
 }
 
+TEST(WalkAST, InitializerList) {
+  testWalk(R"cpp(
+   namespace std {
+template  struct $implicit^initializer_list {};
+   })cpp",
+   R"cpp(
+   const char* s = "";
+   auto sx = ^{s};)cpp");
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/WalkAST.cpp
===
--- clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -304,6 +304,16 @@
 }
 return RecursiveASTVisitor::TraverseTemplateArgumentLoc(TL);
   }
+
+  bool VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
+// Reliance on initializer_lists requires std::initializer_list to be
+// visible per standard. So report a reference to it, otherwise include of
+// `` might not receive any use.
+report(E->getExprLoc(),
+   const_cast(E->getBestDynamicClassType()),
+   RefType::Implicit);
+return true;
+  }
 };
 
 } // namespace
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156650: [clangd] Respect IWYU keep pragma for standard headers.

2023-07-31 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

also we should get this cherry-picked too. `keep` pragmas on includes are not 
common, but people do have export pragmas often enough to cause some annoyance 
here.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156650/new/

https://reviews.llvm.org/D156650

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


[PATCH] D156648: [Tooling/Inclusion] Add std::range symbols in the mapping.

2023-07-31 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

can you also create a cherry-pick request for this patch once it lands?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156648/new/

https://reviews.llvm.org/D156648

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


[PATCH] D156650: [clangd] Respect IWYU keep pragma for standard headers.

2023-07-31 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

thanks!




Comment at: clang-tools-extra/clangd/IncludeCleaner.cpp:85-86
   if (PI) {
 if (PI->shouldKeep(Inc.HashLine + 1))
   return false;
 // Check if main file is the public interface for a private header. If so 
we

can you unify this and the previous check and just have a single:
```
if (PI && PI->shouldKeep(Inc.HashLine + 1))
  return false;
```

at the top of the function?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156650/new/

https://reviews.llvm.org/D156650

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


[PATCH] D150124: [index][clangd] Consider labels when indexing function bodies

2023-07-28 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

sorry for missing this review. Nathan's explanation around `targetDecl` vs 
`findRefs` is absolutely right (btw, thanks a lot Nathan for taking good care 
of clangd, I don't think I say that enough). hopefully one day we can switch 
clangd's usage of libindex to our internal find target/explicitrefs 
implementation, but until then we actually need to address such things in both 
places to make sure functionality is actually consistent.




Comment at: clang/lib/Index/IndexBody.cpp:150
+ParentDC,
+unsigned(SymbolRole::NameReference));
+  }

nridge wrote:
> `NameReference` was introduced in 
> https://github.com/llvm/llvm-project/commit/e7eb27a9a0edd859de49bcc9af7ca27dbb435886
>  to handle the somewhat unique situation with constructors and destructors 
> where the constructor/destructor references the class by name but 
> semantically denotes a separate entity.
> 
> Why is that applicable here?
> 
> Note that `handleReference()` will automatically add `SymbolRole::Reference` 
> [here](https://searchfox.org/llvm/rev/cea72fe34194d58ac1ba9485ee9c9a63cf98a4e6/clang/lib/Index/IndexingContext.cpp#404).
+1 we shouldn't be setting namereference here.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150124/new/

https://reviews.llvm.org/D150124

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


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

2023-07-27 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:842
 
-  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;

can you also move this into an anonymous namespace?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156403/new/

https://reviews.llvm.org/D156403

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


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

2023-07-27 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added inline comments.
This revision is now accepted and ready to land.



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:901
 }
+if (auto StdSym = tooling::stdlib::Symbol::named(S->Scope, S->Name, Lang))
+  if (auto Header = StdSym->header())

we shouldn't be overriding the include header if it's already set above. also i 
think it would be easier to have this out of the way so that reverting to old 
behaviour is easier:
```
llvm::StringRef getStdHeader(const Symbol *S, const LanguageOptions ) {
  tooling::stdlib::Lang Lang = tooling::stdlib::Lang::CXX;
if (ASTCtx->getLangOpts().C11)
  Lang = tooling::stdlib::Lang::C;
else if(!ASTCtx->getLangOpts().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 "";
}
```


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156403/new/

https://reviews.llvm.org/D156403

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


[PATCH] D155819: [include-cleaner] Loose matching for verbatim headers

2023-07-27 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added inline comments.
This revision is now accepted and ready to land.



Comment at: clang-tools-extra/include-cleaner/lib/Types.cpp:171-173
+for (unsigned I : BySpellingAlternate.lookup(Spelling))
+  if (!llvm::is_contained(Result, [I]))
+Result.push_back([I]);

sammccall wrote:
> kadircet wrote:
> > i think we shouldn't look into alternate spellings if we've already found 
> > an exact spelling. we would be matching wrong headers for sure in those 
> > cases.
> I had it this way initially and changed my mind. Having the presence of some 
> includes affect whether others match at all breaks an "obvious" part of the 
> contract. (So obvious that I assumed it in the test ten minutes after 
> deliberately breaking it). I wouldn't add a special case here unless there's 
> some observed bad-results motivation for it.
> 
> > we would be matching wrong headers for sure in those cases.
> 
> You could be including the same header under two paths (and in fact that's 
> what this testcase is doing). I don't know why you would, but we also don't 
> have real examples of this happening with *different* headers.
> You could be including the same header under two paths (and in fact that's 
> what this testcase is doing). I don't know why you would

I do think it's better to diagnose one of those as unused in such a scenario. 
As tools like clang-format won't be able to de-duplicate those automatically.

but you're right about not having examples for alternate spellings resolving to 
different files, so I guess this is at least "safe" and we can change the 
behaviour if we encounter examples.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155819/new/

https://reviews.llvm.org/D155819

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


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

2023-07-27 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:841-847
   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();
   }

can you also get rid of this piece, and `SymbolProviders` map ?



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:873
   llvm::DenseMap FileToContainsImportsOrObjC;
   llvm::DenseMap HeaderSpelling;
   // Fill in IncludeHeaders.

we can drop this too



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:903-927
+// mapping inside the include-cleaner library again.
+llvm::StringRef IncludeHeader;
+if (auto StdSym = tooling::stdlib::Symbol::named(S->Scope, S->Name))
+  if (auto Header = StdSym->header())
+IncludeHeader = Header->name();
+if (S->Scope == "std::" && S->Name == "move") {
+  IncludeHeader = "";

rather than duplicating some of the checks, can we rewrite this block as:
```
llvm::StringRef IncludeHeader = getStdlibHeader(*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);
}
```



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:905
+llvm::StringRef IncludeHeader;
+if (auto StdSym = tooling::stdlib::Symbol::named(S->Scope, S->Name))
+  if (auto Header = StdSym->header())

let's pass in the language options from ASTCtx into here



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:908-912
+if (S->Scope == "std::" && S->Name == "move") {
+  IncludeHeader = "";
+  if (S->Signature.contains(','))
+IncludeHeader = "";
+}

i think the old order of, first dealing with `std::move` and then using 
`tooling::stdlib` is less error-prone and the order in which we apply the 
mapping in include-cleaner, so that would be a more compatible change going 
forward.



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:929-964
+// FIXME: use providers from include-cleaner library once it's polished
+// for Objective-C.
+continue;
+
+// FIXME: Re-enable for C++ code. The code below uses include-cleaner
+// library but is currently unreachable due to regression.
 assert(Directives == Symbol::Include);

let's drop this block to not create confusion


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156403/new/

https://reviews.llvm.org/D156403

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


[PATCH] D155878: [clangd] Loose include-cleaner matching for verbatim headers

2023-07-26 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

thanks!




Comment at: clang-tools-extra/clangd/Hover.cpp:1250
   const SourceManager  = AST.getSourceManager();
-  const auto  =
-  convertIncludes(SM, AST.getIncludeStructure().MainFileIncludes);
-  const auto  = convertIncludes(SM, llvm::ArrayRef{Inc});
+  const auto  = convertIncludes(AST);
   llvm::DenseSet UsedSymbols;

sammccall wrote:
> kadircet wrote:
> > oops, looks like we were getting away with some dangling references.
> > the reference here is wrong, `convertIncludes` returns a value type. can 
> > you fix that while here?
> this isn't dangling, it's lifetime extension.
> 
> Can change it for style if you like, though?
you're right. i think it would be better to have it as value though.



Comment at: clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp:486-491
+  include_cleaner::walkUsed(AST.getLocalTopLevelDecls(), {},
+AST.getPragmaIncludes(), AST.getSourceManager(),
+[&](const include_cleaner::SymbolReference ,
+llvm::ArrayRef P) {
+  Providers[llvm::to_string(Ref.Target)] = P.vec();
+});

sammccall wrote:
> kadircet wrote:
> > i don't think making this test rely on `walkUsed` is a good idea. what 
> > about just populating the providers directly, like:
> > 
> > ```
> > EXPECT_TRUE(isPreferredProvider(Decl, Includes, 
> > {include_cleaner::Header{"decl.h"}, include_cleaner::Header{"def.h"}}));
> > ```
> > 
> > and verifying we're recognizing preferred providers purely on that ordering 
> > ?
> That would be a strict unit test, but I think it's too easy to lose track of 
> how this idea of "preferred" relates to the code.
> 
> For example, when writing this test, I expected `Y` to match the includes for 
> both `Decl` and `Def`, because they're intuitively both "best matches" and we 
> do allow multiple includes to match.
> But of course we force the *providers* to be ranked, so really ~only multiple 
> includes of the *same* header will be accepted as all-preferred.
> 
> This wrinkle seems worth recording, and totally disappears if we make the 
> test abstract by describing a provider list directly.
> 
> (Can do it though if that's what you do prefer)
i completely agree with what you said, but I don't see why ranking should 
matter here. i do feel like all of those concerns you raised can still be 
inferred from the fact that we're providing a set of ordered providers, but 
maybe it's just me. i just feel like the downside is we should update this test 
if ranking for providers changes for whatever reason, and i don't think we 
should. but that is not a big deal, so feel free to keep it as-is.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155878/new/

https://reviews.llvm.org/D155878

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


[PATCH] D155878: [clangd] Loose include-cleaner matching for verbatim headers

2023-07-26 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/Headers.cpp:185
+  // The entries will be the same, but canonicalizing to find out is expensive!
+  if (SearchPathCanonical.empty()) {
+for (const auto  :

nit: early exit



Comment at: clang-tools-extra/clangd/Headers.h:179
+  // All paths are canonical (FileManager::getCanonicalPath()).
+  std::vector SearchPathCanonical;
+

s/SearchPathCanonical/SearchPathsCanonical/



Comment at: clang-tools-extra/clangd/Hover.cpp:1250
   const SourceManager  = AST.getSourceManager();
-  const auto  =
-  convertIncludes(SM, AST.getIncludeStructure().MainFileIncludes);
-  const auto  = convertIncludes(SM, llvm::ArrayRef{Inc});
+  const auto  = convertIncludes(AST);
   llvm::DenseSet UsedSymbols;

oops, looks like we were getting away with some dangling references.
the reference here is wrong, `convertIncludes` returns a value type. can you 
fix that while here?



Comment at: clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp:486-491
+  include_cleaner::walkUsed(AST.getLocalTopLevelDecls(), {},
+AST.getPragmaIncludes(), AST.getSourceManager(),
+[&](const include_cleaner::SymbolReference ,
+llvm::ArrayRef P) {
+  Providers[llvm::to_string(Ref.Target)] = P.vec();
+});

i don't think making this test rely on `walkUsed` is a good idea. what about 
just populating the providers directly, like:

```
EXPECT_TRUE(isPreferredProvider(Decl, Includes, 
{include_cleaner::Header{"decl.h"}, include_cleaner::Header{"def.h"}}));
```

and verifying we're recognizing preferred providers purely on that ordering ?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155878/new/

https://reviews.llvm.org/D155878

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


[PATCH] D155819: [include-cleaner] Loose matching for verbatim headers

2023-07-26 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: 
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h:198
   llvm::StringMap> BySpelling;
+  llvm::StringMap> BySpellingAlternate;
   llvm::DenseMap> ByFile;

maybe add a comment saying that these spellings are generated heuristically?



Comment at: clang-tools-extra/include-cleaner/lib/Types.cpp:110-112
+  while (!P.empty() && path::is_separator(P.back()))
+P.pop_back();
+  return P;

nit: `return P.rtrim('/');` // only separator we can encounter is forward slash 
at this point.



Comment at: clang-tools-extra/include-cleaner/lib/Types.cpp:129
   ByLine[I.Line] = Index;
+  if (I.Resolved) {
+ByFile[I.Resolved].push_back(Index);

nit: prefer early exit



Comment at: clang-tools-extra/include-cleaner/lib/Types.cpp:137
+// verbatim "e/f" should match (spelled=c/d/e/f, resolved=/a/b/c/d/e/f).
+// We assume entry's (normalized) name will match the search dirs.
+auto Path = normalizePath(I.Resolved->getName());

i think this assumption breaks when we have an absolute include search path, 
which is a subdirectory of the CWD of file manager. as we might now have a 
resolved include which is relative, but a search path that'll never match a 
prefix of those includes.

i guess this is fine, as we're trying to heuristically match. but it would be 
useful to mention it here and add a unittest for that. (unless I am missing 
something and headersearch already normalizes such paths)



Comment at: clang-tools-extra/include-cleaner/lib/Types.cpp:141
+ Parent = path::parent_path(Parent)) {
+  if (SearchPath.contains(Parent)) {
+llvm::StringRef Rel = llvm::StringRef(Path).drop_front(Parent.size());

nit: prefer early exit



Comment at: clang-tools-extra/include-cleaner/lib/Types.cpp:142-144
+llvm::StringRef Rel = llvm::StringRef(Path).drop_front(Parent.size());
+while (!Rel.empty() && path::is_separator(Rel.front()))
+  Rel = Rel.drop_front();

nit: `auto Rel = llvm::StringRef(Path).drop_front(Parent.size()).ltrim('/');` 
// we already normalized the path and only have forward slashes.



Comment at: clang-tools-extra/include-cleaner/lib/Types.cpp:171-173
+for (unsigned I : BySpellingAlternate.lookup(Spelling))
+  if (!llvm::is_contained(Result, [I]))
+Result.push_back([I]);

i think we shouldn't look into alternate spellings if we've already found an 
exact spelling. we would be matching wrong headers for sure in those cases.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155819/new/

https://reviews.llvm.org/D155819

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


[PATCH] D155619: [clangd] Always run preamble indexing on a separate thread

2023-07-25 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet closed this revision.
kadircet added a comment.

landed with 27ade4b554774187d2c0afcf64cd16fa6d5f619d 



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155619/new/

https://reviews.llvm.org/D155619

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


[PATCH] D156122: [include-cleaner] Introduce support for always_keep pragma

2023-07-24 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

FWIW, details of pragma are explained in 
https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md#iwyu-pragma-always_keep


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156122/new/

https://reviews.llvm.org/D156122

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


[PATCH] D156123: [include-cleaner] Unify always_keep with rest of the keep logic

2023-07-24 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added a reviewer: VitaNuo.
Herald added subscribers: PiotrZSL, carlosgalvezp, arphaman.
Herald added a reviewer: njames93.
Herald added a project: All.
kadircet requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Depends on D156122 


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156123

Files:
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h
  clang-tools-extra/include-cleaner/lib/Analysis.cpp
  clang-tools-extra/include-cleaner/lib/Record.cpp
  clang-tools-extra/include-cleaner/unittests/RecordTest.cpp

Index: clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
@@ -13,10 +13,12 @@
 #include "clang/Testing/TestAST.h"
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Testing/Annotations/Annotations.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
+#include 
 
 namespace clang::include_cleaner {
 namespace {
@@ -309,68 +311,51 @@
 };
 
 TEST_F(PragmaIncludeTest, IWYUKeep) {
-  llvm::Annotations MainFile(R"cpp(
-$keep1^#include "keep1.h" // IWYU pragma: keep
-$keep2^#include "keep2.h" /* IWYU pragma: keep */
+  Inputs.Code = R"cpp(
+#include "keep1.h" // IWYU pragma: keep
+#include "keep2.h" /* IWYU pragma: keep */
 
-$export1^#include "export1.h" // IWYU pragma: export
-$begin_exports^// IWYU pragma: begin_exports
-$export2^#include "export2.h"
-$export3^#include "export3.h"
-$end_exports^// IWYU pragma: end_exports
+#include "export1.h" // IWYU pragma: export
+// IWYU pragma: begin_exports
+#include "export2.h"
+#include "export3.h"
+// IWYU pragma: end_exports
 
-$normal^#include "normal.h"
+#include "normal.h"
 
-$begin_keep^// IWYU pragma: begin_keep 
-$keep3^#include "keep3.h"
-$end_keep^// IWYU pragma: end_keep
+// IWYU pragma: begin_keep
+#include "keep3.h"
+// IWYU pragma: end_keep
 
-// IWYU pragma: begin_keep 
-$keep4^#include "keep4.h"
 // IWYU pragma: begin_keep
-$keep5^#include "keep5.h"
+#include "keep4.h"
+// IWYU pragma: begin_keep
+#include "keep5.h"
 // IWYU pragma: end_keep
-$keep6^#include "keep6.h"
+#include "keep6.h"
 // IWYU pragma: end_keep
-  )cpp");
-
-  auto OffsetToLineNum = [](size_t Offset) {
-int Count = MainFile.code().substr(0, Offset).count('\n');
-return Count + 1;
-  };
-
-  Inputs.Code = MainFile.code();
+  )cpp";
   createEmptyFiles({"keep1.h", "keep2.h", "keep3.h", "keep4.h", "keep5.h",
 "keep6.h", "export1.h", "export2.h", "export3.h",
 "normal.h"});
 
   TestAST Processed = build();
-  EXPECT_FALSE(PI.shouldKeep(1));
-
-  // Keep
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep1";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep2";
+  auto  = Processed.fileManager();
 
-  EXPECT_FALSE(PI.shouldKeep(
-  OffsetToLineNum(MainFile.point("begin_keep"; // no # directive
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep3";
-  EXPECT_FALSE(PI.shouldKeep(
-  OffsetToLineNum(MainFile.point("end_keep"; // no # directive
+  EXPECT_FALSE(PI.shouldKeep(FM.getFile("normal.h").get()));
 
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep4";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep5";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep6";
+  // Keep
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep1.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep2.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep3.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep4.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep5.h").get()));
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep6.h").get()));
 
   // Exports
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("export1";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("export2";
-  EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("export3";
-  EXPECT_FALSE(PI.shouldKeep(
-  OffsetToLineNum(MainFile.point("begin_exports"; // no # directive
-  EXPECT_FALSE(PI.shouldKeep(
-  OffsetToLineNum(MainFile.point("end_exports"; // no # directive
-
-  EXPECT_FALSE(PI.shouldKeep(OffsetToLineNum(MainFile.point("normal";
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("export1.h").get()));
+  

[PATCH] D156122: [include-cleaner] Introduce support for always_keep pragma

2023-07-24 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added a reviewer: VitaNuo.
Herald added subscribers: PiotrZSL, carlosgalvezp, arphaman.
Herald added a reviewer: njames93.
Herald added a project: All.
kadircet requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156122

Files:
  clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h
  clang-tools-extra/include-cleaner/lib/Analysis.cpp
  clang-tools-extra/include-cleaner/lib/Record.cpp
  clang-tools-extra/include-cleaner/unittests/RecordTest.cpp

Index: clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
===
--- clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
@@ -502,5 +502,20 @@
   EXPECT_FALSE(PI.isSelfContained(FM.getFile("unguarded.h").get()));
 }
 
+TEST_F(PragmaIncludeTest, AlwaysKeep) {
+  Inputs.Code = R"cpp(
+  #include "always_keep.h"
+  #include "usual.h"
+  )cpp";
+  Inputs.ExtraFiles["always_keep.h"] = R"cpp(
+  #pragma once
+  // IWYU pragma: always_keep
+  )cpp";
+  Inputs.ExtraFiles["usual.h"] = "#pragma once";
+  TestAST Processed = build();
+  auto  = Processed.fileManager();
+  EXPECT_TRUE(PI.shouldKeep(FM.getFile("always_keep.h").get()));
+  EXPECT_FALSE(PI.shouldKeep(FM.getFile("usual.h").get()));
+}
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/Record.cpp
===
--- clang-tools-extra/include-cleaner/lib/Record.cpp
+++ clang-tools-extra/include-cleaner/lib/Record.cpp
@@ -11,6 +11,9 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclGroup.h"
+#include "clang/Basic/FileEntry.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -19,8 +22,19 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Tooling/Inclusions/HeaderAnalysis.h"
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/StringSaver.h"
+#include 
+#include 
 #include 
+#include 
 #include 
+#include 
 
 namespace clang::include_cleaner {
 namespace {
@@ -255,8 +269,9 @@
 if (!Pragma)
   return false;
 
+FileID CommentFID = SM.getFileID(Range.getBegin());
+auto *FE = SM.getFileEntryForID(CommentFID);
 if (Pragma->consume_front("private")) {
-  auto *FE = SM.getFileEntryForID(SM.getFileID(Range.getBegin()));
   if (!FE)
 return false;
   StringRef PublicHeader;
@@ -269,7 +284,10 @@
   Out->IWYUPublic.insert({FE->getLastRef().getUniqueID(), PublicHeader});
   return false;
 }
-FileID CommentFID = SM.getFileID(Range.getBegin());
+if (Pragma->consume_front("always_keep")) {
+  Out->AlwaysKeep.insert(FE->getUniqueID());
+  return false;
+}
 int CommentLine = SM.getLineNumber(SM.getFileID(Range.getBegin()),
SM.getFileOffset(Range.getBegin()));
 // Record export pragma.
@@ -394,6 +412,14 @@
   return IWYUPublic.contains(FE->getUniqueID());
 }
 
+bool PragmaIncludes::shouldKeep(unsigned HashLineNumber) const {
+  return ShouldKeep.contains(HashLineNumber);
+}
+
+bool PragmaIncludes::shouldKeep(const FileEntry *FE) const {
+  return AlwaysKeep.contains(FE->getUniqueID());
+}
+
 namespace {
 template  bool isImplicitTemplateSpecialization(const Decl *D) {
   if (const auto *TD = dyn_cast(D))
Index: clang-tools-extra/include-cleaner/lib/Analysis.cpp
===
--- clang-tools-extra/include-cleaner/lib/Analysis.cpp
+++ clang-tools-extra/include-cleaner/lib/Analysis.cpp
@@ -91,7 +91,7 @@
 HeaderFilter(I.Resolved->tryGetRealPathName()))
   continue;
 if (PI) {
-  if (PI->shouldKeep(I.Line))
+  if (PI->shouldKeep(I.Line) || PI->shouldKeep(I.Resolved))
 continue;
   // Check if main file is the public interface for a private header. If so
   // we shouldn't diagnose it as unused.
Index: clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h
===
--- clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h
+++ clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h
@@ -59,9 +59,8 @@
 
   /// Returns true if the given #include of the main-file should 

[PATCH] D155992: [clangd] Use xxh3_64bits for background index file digests

2023-07-24 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

thanks for doing this!

as Sam pointed out this will result in invalidation of all the index shards, 
but that's not something new. we already don't clean up non-relevant index 
shards when people delete sources over time and rely on people having new 
checkouts or clearing things up manually. this will be somewhat more severe, as 
we'll double the index size all of a sudden.

but i'd like to keep this patch from landing until llvm-17 is cut (which should 
be tomorrow). we didn't have any changes to our index shard serialization since 
llvm-16 release, so forcing everyone to face this invalidation purely for the 
sake of a clean up that might never happen in the codebase doesn't feel enough 
of a justification. whereas it's more likely that we'll have changes to 
serialization format throughout the next release cycle and can hit users only 
once with big cache invalidations.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155992/new/

https://reviews.llvm.org/D155992

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


[PATCH] D156044: [clangd] Exclude builtin headers from system include extraction

2023-07-24 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

thanks a lot!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156044/new/

https://reviews.llvm.org/D156044

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


[PATCH] D133843: [clangd] Prefer definitions for gototype and implementation

2023-07-21 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0a093f62d154: [clangd] Prefer definitions for gototype and 
implementation (authored by kadircet).

Changed prior to commit:
  https://reviews.llvm.org/D133843?vs=460003=542874#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133843/new/

https://reviews.llvm.org/D133843

Files:
  clang-tools-extra/clangd/ClangdLSPServer.cpp


Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -1451,7 +1451,7 @@
   return Reply(Types.takeError());
 std::vector Response;
 for (const LocatedSymbol  : *Types)
-  Response.push_back(Sym.PreferredDeclaration);
+  
Response.push_back(Sym.Definition.value_or(Sym.PreferredDeclaration));
 return Reply(std::move(Response));
   });
 }
@@ -1467,7 +1467,7 @@
   return Reply(Overrides.takeError());
 std::vector Impls;
 for (const LocatedSymbol  : *Overrides)
-  Impls.push_back(Sym.PreferredDeclaration);
+  Impls.push_back(Sym.Definition.value_or(Sym.PreferredDeclaration));
 return Reply(std::move(Impls));
   });
 }


Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -1451,7 +1451,7 @@
   return Reply(Types.takeError());
 std::vector Response;
 for (const LocatedSymbol  : *Types)
-  Response.push_back(Sym.PreferredDeclaration);
+  Response.push_back(Sym.Definition.value_or(Sym.PreferredDeclaration));
 return Reply(std::move(Response));
   });
 }
@@ -1467,7 +1467,7 @@
   return Reply(Overrides.takeError());
 std::vector Impls;
 for (const LocatedSymbol  : *Overrides)
-  Impls.push_back(Sym.PreferredDeclaration);
+  Impls.push_back(Sym.Definition.value_or(Sym.PreferredDeclaration));
 return Reply(std::move(Impls));
   });
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133843: [clangd] Prefer definitions for gototype and implementation

2023-07-21 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet abandoned this revision.
kadircet added a comment.

abandoning in favor of D155898 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133843/new/

https://reviews.llvm.org/D133843

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


[PATCH] D153769: [clangd] Implement the 'Organize Imports' source action. Fix include-cleaner findings in batch.

2023-07-20 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

so as we were discussing offline (just to summarize it here) there's also the 
possibility of propagating context kind in selection, and making this code 
action fire when code actions are requested for "source code action kind" or 
the selection intersects with includes. which feels like the most useful 
alternative without annoying old clients.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153769/new/

https://reviews.llvm.org/D153769

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


[PATCH] D153769: [clangd] Implement the 'Organize Imports' source action. Fix include-cleaner findings in batch.

2023-07-20 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

there are unittests for tweaks under 
`clang-tools-extra/clangd/unittests/tweaks/` can you create one for 
`OrganizeImports` there and test this in there?

i've got another concern around triggering of this interaction.
in theory code-action context has a `only` field, dictating which code actions 
should be surfaced, but when it's unset (as it's usually not set by clients and 
hard to understand semantics of code action kinds) clangd just provides all of 
the available code actions for a given selection.
since organize imports (and other source actions) are going to be available for 
all selections, it means we'll now have some code action response all the time 
and clients that don't know about semantics for "source" code action kind, will 
likely just show it in their UIs. so we need to be somewhat careful about 
triggering.

two alternatives that I can think of are:
1- show "source" kind code actions, only when they're explicitly requested.
2- make use of trigger kind and return these only when code actions are 
"explicitly" triggered.

1 has the downside of never showing up on editors that don't know about 
"source" code action kind, and also complicates behaviour on clangd side.
2 has the downside of being introduced very recently (trigger kind is made part 
of the spec at LSP 3.17), hence it'll likely be absent in old clients.

so my inclination is towards alternative 2), which at least limits the blast 
radius and gives clients a reasonably easy way to control the behavior. WDYT?




Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:24-25
+
+namespace clang {
+namespace clangd {
+namespace {

nit: `namespace clang::clangd {`



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:45-49
+std::string OrganizeImports::title() const {
+  return "Remove unused and add missing includes";
+}
+
+bool OrganizeImports::prepare(const Selection ) { return true; }

nit: i'd inline these into the class definition as well



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:51
+
+Expected
+OrganizeImports::apply(const Selection ) {

s/OrganizeImports::Effect/Tweak::Effect



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:62
+  const auto  = Inputs.AST->getSourceManager();
+  std::set Spellings;
+  for (const auto  : Findings.MissingIncludes)

prefer `llvm::StringSet<>`



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:64-67
+for (const auto  : Missing.Providers)
+  Spellings.insert(include_cleaner::spellHeader(
+  {P, Inputs.AST->getPreprocessor().getHeaderSearchInfo(),
+   SM.getFileEntryForID(SM.getMainFileID())}));

this will insert all providers for a symbol (e.g. if we have both `foo.h` and 
`bar.h`, we'll insert both).



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:75
+  auto FileStyle =
+  format::getStyle(format::DefaultFormatStyle, Inputs.AST->tuPath(),
+   format::DefaultFallbackStyle, Inputs.Code, Inputs.FS);





Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:77
+   format::DefaultFallbackStyle, Inputs.Code, Inputs.FS);
+  if (!FileStyle)
+FileStyle = format::getLLVMStyle();

unfortunately we actually have to consume the error here, as `getStyle` returns 
an `Expected` and destroying an unchecked `Expected` is undefined behavior :/

something like `elog("Couldn't get style for {0}: {1}", MainFilePath, 
FileStyle.takeError());` should do the trick.



Comment at: clang-tools-extra/clangd/refactor/tweaks/OrganizeImports.cpp:79-83
+  if (auto Final = format::cleanupAroundReplacements(Inputs.Code, Replacements,
+ *FileStyle))
+return Effect::mainFileEdit(SM, *Final);
+  else
+return Final.takeError();

nit:


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153769/new/

https://reviews.llvm.org/D153769

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


[PATCH] D142967: [clangd] Introduce source.organizeImports code action.

2023-07-19 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet resigned from this revision.
kadircet added a comment.
Herald added a subscriber: kadircet.

resigning in favor of https://reviews.llvm.org/D153769


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142967/new/

https://reviews.llvm.org/D142967

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


[PATCH] D155385: [clangd] enable unused-include warnings for standard library headers

2023-07-19 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added inline comments.
This revision is now accepted and ready to land.



Comment at: clang-tools-extra/clangd/IncludeCleaner.cpp:75-77
+if (tooling::stdlib::Header::named(Inc.Written))
   return true;
 return false;




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155385/new/

https://reviews.llvm.org/D155385

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


[PATCH] D155392: [clangd] add a config knob to disable modules

2023-07-19 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/unittests/ModulesTests.cpp:34
+protected:
+  ModulesTest() : WithCfg(Config::Key, makeModuleConfig(GetParam())) {}
+};

testing behaviour indirectly through config options cause some troubles in the 
long term (e.g. when we want to change the default behaviour a bunch of tests 
observe a different behaviour all of a sudden, or when we want to override 
behaviour at different layers it's hard to compose as we can't overlay configs 
but only override them)

so can we have this as a `ParseInput::ParseOption` instead? as discussed we can 
set it in `ASTWorker`, without doing the extra IO.

(you've got more context as we discussed this offline, there's also a solution 
that provides tests with the ability to have a different default "test" config 
and flips bits on it, but that's a little bit more involved so no need to block 
this patch on it)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155392/new/

https://reviews.llvm.org/D155392

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


[PATCH] D78038: [clangd] WIP: fix several bugs relating to include insertion

2023-07-19 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

thanks, i think this LG.




Comment at: 
clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp:1697-1698
+  )cpp");
+  TU.HeaderFilename = "Foo.h";
+  auto Symbols = TU.headerSymbols();
+  EXPECT_THAT(Symbols, Not(Contains(qName("HEADER_GUARD_";

`headerSymbols` still uses `Filename` not `HeaderFilename` of the TU.



Comment at: 
clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp:1699-1702
+  EXPECT_THAT(Symbols, Not(Contains(qName("HEADER_GUARD_";
+  EXPECT_THAT(Symbols, Contains(qName("MACRO")));
+  EXPECT_THAT(Symbols, Contains(qName("MACRO2")));
+  EXPECT_THAT(Symbols, Contains(qName("decl")));

i think we don't want to just check for names of the symbols, but also want to 
make sure they got proper include headers assigned?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78038/new/

https://reviews.llvm.org/D78038

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


[PATCH] D155619: [clangd] Always run preamble indexing on a separate thread

2023-07-19 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet updated this revision to Diff 541938.
kadircet added a comment.

Fix some tsan issues


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155619/new/

https://reviews.llvm.org/D155619

Files:
  clang-tools-extra/clangd/ClangdServer.cpp
  clang-tools-extra/clangd/ClangdServer.h
  clang-tools-extra/clangd/Preamble.cpp

Index: clang-tools-extra/clangd/Preamble.cpp
===
--- clang-tools-extra/clangd/Preamble.cpp
+++ clang-tools-extra/clangd/Preamble.cpp
@@ -11,6 +11,8 @@
 #include "Compiler.h"
 #include "Config.h"
 #include "Diagnostics.h"
+#include "FS.h"
+#include "FeatureModule.h"
 #include "Headers.h"
 #include "Protocol.h"
 #include "SourceCode.h"
@@ -21,8 +23,10 @@
 #include "support/ThreadsafeFS.h"
 #include "support/Trace.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Type.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticLex.h"
+#include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
@@ -51,12 +55,17 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/raw_ostream.h"
+#include 
+#include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -616,7 +625,8 @@
   });
   llvm::IntrusiveRefCntPtr PreambleDiagsEngine =
   CompilerInstance::createDiagnostics((),
-  , false);
+  ,
+  /*ShouldOwnClient=*/false);
   const Config  = Config::current();
   PreambleDiagnostics.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel,
const clang::Diagnostic ) {
@@ -663,8 +673,12 @@
   auto BuiltPreamble = PrecompiledPreamble::Build(
   CI, ContentsBuffer.get(), Bounds, *PreambleDiagsEngine,
   Stats ? TimedFS : StatCacheFS, std::make_shared(),
-  StoreInMemory, /*StoragePath=*/StringRef(), CapturedInfo);
+  StoreInMemory, /*StoragePath=*/"", CapturedInfo);
   PreambleTimer.stopTimer();
+  // Reset references to ref-counted-ptrs before executing the callbacks, to
+  // prevent resetting them concurrently.
+  PreambleDiagsEngine.reset();
+  CI.DiagnosticOpts.reset();
 
   // When building the AST for the main file, we do want the function
   // bodies.
Index: clang-tools-extra/clangd/ClangdServer.h
===
--- clang-tools-extra/clangd/ClangdServer.h
+++ clang-tools-extra/clangd/ClangdServer.h
@@ -185,10 +185,6 @@
 /// regions in the document.
 bool PublishInactiveRegions = false;
 
-/// Whether to run preamble indexing asynchronously in an independent
-/// thread.
-bool AsyncPreambleIndexing = false;
-
 explicit operator TUScheduler::Options() const;
   };
   // Sensible default options for use in tests.
Index: clang-tools-extra/clangd/ClangdServer.cpp
===
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -67,11 +67,10 @@
   UpdateIndexCallbacks(FileIndex *FIndex,
ClangdServer::Callbacks *ServerCallbacks,
const ThreadsafeFS , AsyncTaskRunner *Tasks,
-   bool CollectInactiveRegions,
-   const ClangdServer::Options )
-  : FIndex(FIndex), ServerCallbacks(ServerCallbacks),
-TFS(TFS), Stdlib{std::make_shared()}, Tasks(Tasks),
-CollectInactiveRegions(CollectInactiveRegions), Opts(Opts) {}
+   bool CollectInactiveRegions)
+  : FIndex(FIndex), ServerCallbacks(ServerCallbacks), TFS(TFS),
+Stdlib{std::make_shared()}, Tasks(Tasks),
+CollectInactiveRegions(CollectInactiveRegions) {}
 
   void onPreambleAST(
   PathRef Path, llvm::StringRef Version, CapturedASTCtx ASTCtx,
@@ -94,7 +93,7 @@
  ASTCtx.getPreprocessor(), *CanonIncludes);
 };
 
-if (Opts.AsyncPreambleIndexing && Tasks) {
+if (Tasks) {
   Tasks->runAsync("Preamble indexing for:" + Path + Version,
   std::move(Task));
 } else
@@ -164,7 +163,6 @@
   std::shared_ptr Stdlib;
   AsyncTaskRunner *Tasks;
   bool CollectInactiveRegions;
-  const ClangdServer::Options 
 };
 
 class DraftStoreFS : public ThreadsafeFS {
@@ -229,7 +227,7 @@
 std::make_unique(
 DynamicIdx.get(), Callbacks, TFS,
 IndexTasks ? &*IndexTasks : nullptr,
-

[PATCH] D155614: [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 Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/XRefs.cpp:1365
   // Add the #include line to the references list.
   ReferencesResult::Reference Result;
   Result.Loc.range =

i guess this patch is not needed anymore, but one comment about this behaviour 
in clangd as well (no action needed in this patch)

why are we providing the reference to the include line itself? in other 
interactions we do that for the sake of completeness (e.g. if you trigger xrefs 
on a reference, seeing the declaration/definition location is useful) but 
usually the result under the cursor is not so interesting, especially in this 
case. the include line itself is drastically different than the nature of other 
references, the user can only see the include, if they triggered the xrefs on 
the include line itself and not when they trigger it on the symbol. also that 
ref doesn't count if there's no symbols used?

FWIW I am not sure if that's a useful interaction. What was the rationale here 
exactly? It might be useful to always emit this reference, but also append 
provider to the refs list in the other direction as well (that way the results 
will be coherent again)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155614/new/

https://reviews.llvm.org/D155614

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


[PATCH] D155619: [clangd] Always run preamble indexing on a separate thread

2023-07-19 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG036a1b2202cb: [clangd] Always run preamble indexing on a 
separate thread (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155619/new/

https://reviews.llvm.org/D155619

Files:
  clang-tools-extra/clangd/ClangdServer.cpp
  clang-tools-extra/clangd/ClangdServer.h


Index: clang-tools-extra/clangd/ClangdServer.h
===
--- clang-tools-extra/clangd/ClangdServer.h
+++ clang-tools-extra/clangd/ClangdServer.h
@@ -185,10 +185,6 @@
 /// regions in the document.
 bool PublishInactiveRegions = false;
 
-/// Whether to run preamble indexing asynchronously in an independent
-/// thread.
-bool AsyncPreambleIndexing = false;
-
 explicit operator TUScheduler::Options() const;
   };
   // Sensible default options for use in tests.
Index: clang-tools-extra/clangd/ClangdServer.cpp
===
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -94,7 +94,7 @@
  ASTCtx.getPreprocessor(), *CanonIncludes);
 };
 
-if (Opts.AsyncPreambleIndexing && Tasks) {
+if (Tasks) {
   Tasks->runAsync("Preamble indexing for:" + Path + Version,
   std::move(Task));
 } else


Index: clang-tools-extra/clangd/ClangdServer.h
===
--- clang-tools-extra/clangd/ClangdServer.h
+++ clang-tools-extra/clangd/ClangdServer.h
@@ -185,10 +185,6 @@
 /// regions in the document.
 bool PublishInactiveRegions = false;
 
-/// Whether to run preamble indexing asynchronously in an independent
-/// thread.
-bool AsyncPreambleIndexing = false;
-
 explicit operator TUScheduler::Options() const;
   };
   // Sensible default options for use in tests.
Index: clang-tools-extra/clangd/ClangdServer.cpp
===
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -94,7 +94,7 @@
  ASTCtx.getPreprocessor(), *CanonIncludes);
 };
 
-if (Opts.AsyncPreambleIndexing && Tasks) {
+if (Tasks) {
   Tasks->runAsync("Preamble indexing for:" + Path + Version,
   std::move(Task));
 } else
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   4   5   6   7   8   9   10   >