[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2023-11-21 Thread Christian Kandeler via cfe-commits


@@ -499,17 +473,64 @@ class DefineOutline : public Tweak {
   HeaderUpdates = HeaderUpdates.merge(*DelInline);
 }
 
-auto HeaderFE = Effect::fileEdit(SM, SM.getMainFileID(), HeaderUpdates);
-if (!HeaderFE)
-  return HeaderFE.takeError();
-
-Effect->ApplyEdits.try_emplace(HeaderFE->first,
-   std::move(HeaderFE->second));
+if (SameFile) {
+  tooling::Replacements &R = Effect->ApplyEdits[*CCFile].Replacements;
+  R = R.merge(HeaderUpdates);
+} else {
+  auto HeaderFE = Effect::fileEdit(SM, SM.getMainFileID(), HeaderUpdates);
+  if (!HeaderFE)
+return HeaderFE.takeError();
+  Effect->ApplyEdits.try_emplace(HeaderFE->first,
+ std::move(HeaderFE->second));
+}
 return std::move(*Effect);
   }
 
+  // Returns the most natural insertion point for \p QualifiedName in \p
+  // Contents. This currently cares about only the namespace proximity, but in
+  // feature it should also try to follow ordering of declarations. For 
example,
+  // if decls come in order `foo, bar, baz` then this function should return
+  // some point between foo and baz for inserting bar.
+  llvm::Expected getInsertionPoint(llvm::StringRef Contents,
+   const Selection &Sel) {
+// If the definition goes to the same file and there is a namespace,
+// we should (and, in the case of anonymous namespaces, need to)
+// put the definition into the original namespace block.
+// Within this constraint, the same considerations apply as in
+// the FIXME below.
+if (SameFile) {
+  if (auto *Namespace = Source->getEnclosingNamespaceContext()) {

ckandeler wrote:

You mean this also covers the global namespace? I wasn't sure about that. But 
don't we need special handling for that case, then? As I'd assume it won't have 
a proper location?

https://github.com/llvm/llvm-project/pull/69704
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2023-11-21 Thread Christian Kandeler via cfe-commits


@@ -19,7 +19,7 @@ TWEAK_TEST(DefineOutline);
 
 TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
   FileName = "Test.cpp";
-  // Not available unless in a header file.
+  // Not available for free function unless in a header file.

ckandeler wrote:

Do you have suggestions? anon namespace in header is already covered.

https://github.com/llvm/llvm-project/pull/69704
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2023-11-21 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/69704

>From 27af98b5a9b71255b2873f25943ed23e42946b27 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Thu, 19 Oct 2023 17:51:11 +0200
Subject: [PATCH] [clangd] Allow "move function body out-of-line" in non-header
 files

Moving the body of member functions out-of-line makes sense for classes
defined in implementation files too.
---
 .../clangd/refactor/tweaks/DefineOutline.cpp  | 135 ++
 .../unittests/tweaks/DefineOutlineTests.cpp   |  43 +-
 2 files changed, 119 insertions(+), 59 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index b84ae04072f2c19..67d13f3eb4a6b07 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -179,14 +179,11 @@ deleteTokensWithKind(const syntax::TokenBuffer &TokBuf, 
tok::TokenKind Kind,
 // looked up in the context containing the function/method.
 // FIXME: Drop attributes in function signature.
 llvm::Expected
-getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace,
+getFunctionSourceCode(const FunctionDecl *FD, const DeclContext *TargetContext,
   const syntax::TokenBuffer &TokBuf,
   const HeuristicResolver *Resolver) {
   auto &AST = FD->getASTContext();
   auto &SM = AST.getSourceManager();
-  auto TargetContext = findContextForNS(TargetNamespace, FD->getDeclContext());
-  if (!TargetContext)
-return error("define outline: couldn't find a context for target");
 
   llvm::Error Errors = llvm::Error::success();
   tooling::Replacements DeclarationCleanups;
@@ -216,7 +213,7 @@ getFunctionSourceCode(const FunctionDecl *FD, 
llvm::StringRef TargetNamespace,
 }
 const NamedDecl *ND = Ref.Targets.front();
 const std::string Qualifier =
-getQualification(AST, *TargetContext,
+getQualification(AST, TargetContext,
  SM.getLocForStartOfFile(SM.getMainFileID()), ND);
 if (auto Err = DeclarationCleanups.add(
 tooling::Replacement(SM, Ref.NameLoc, 0, Qualifier)))
@@ -232,7 +229,7 @@ getFunctionSourceCode(const FunctionDecl *FD, 
llvm::StringRef TargetNamespace,
   if (const auto *Destructor = llvm::dyn_cast(FD)) {
 if (auto Err = DeclarationCleanups.add(tooling::Replacement(
 SM, Destructor->getLocation(), 0,
-getQualification(AST, *TargetContext,
+getQualification(AST, TargetContext,
  SM.getLocForStartOfFile(SM.getMainFileID()),
  Destructor
   Errors = llvm::joinErrors(std::move(Errors), std::move(Err));
@@ -319,29 +316,9 @@ getFunctionSourceCode(const FunctionDecl *FD, 
llvm::StringRef TargetNamespace,
 }
 
 struct InsertionPoint {
-  std::string EnclosingNamespace;
+  const DeclContext *EnclosingNamespace = nullptr;
   size_t Offset;
 };
-// Returns the most natural insertion point for \p QualifiedName in \p 
Contents.
-// This currently cares about only the namespace proximity, but in feature it
-// should also try to follow ordering of declarations. For example, if decls
-// come in order `foo, bar, baz` then this function should return some point
-// between foo and baz for inserting bar.
-llvm::Expected getInsertionPoint(llvm::StringRef Contents,
- llvm::StringRef QualifiedName,
- const LangOptions &LangOpts) {
-  auto Region = getEligiblePoints(Contents, QualifiedName, LangOpts);
-
-  assert(!Region.EligiblePoints.empty());
-  // FIXME: This selection can be made smarter by looking at the definition
-  // locations for adjacent decls to Source. Unfortunately pseudo parsing in
-  // getEligibleRegions only knows about namespace begin/end events so we
-  // can't match function start/end positions yet.
-  auto Offset = positionToOffset(Contents, Region.EligiblePoints.back());
-  if (!Offset)
-return Offset.takeError();
-  return InsertionPoint{Region.EnclosingNamespace, *Offset};
-}
 
 // Returns the range that should be deleted from declaration, which always
 // contains function body. In addition to that it might contain constructor
@@ -409,14 +386,9 @@ class DefineOutline : public Tweak {
   }
 
   bool prepare(const Selection &Sel) override {
-// Bail out if we are not in a header file.
-// FIXME: We might want to consider moving method definitions below class
-// definition even if we are inside a source file.
-if (!isHeaderFile(Sel.AST->getSourceManager().getFilename(Sel.Cursor),
-  Sel.AST->getLangOpts()))
-  return false;
-
+SameFile = !isHeaderFile(Sel.AST->tuPath(), Sel.AST->getLangOpts());
 Source = getSelectedFunction(Sel.ASTSelection.commonAncestor());
+
 // Bai

[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2023-11-21 Thread Christian Kandeler via cfe-commits


@@ -349,6 +358,36 @@ TEST_F(DefineOutlineTest, ApplyTest) {
   }
 }
 
+TEST_F(DefineOutlineTest, InCppFile) {
+  FileName = "Test.cpp";
+
+  struct {
+llvm::StringRef Test;
+llvm::StringRef ExpectedSource;
+  } Cases[] = {
+  {
+  R"cpp(
+namespace foo {
+namespace {
+struct Foo { void ba^r() {} };

ckandeler wrote:

> so what about changing this logic to get to enclosing decl instead (i.e. 
> TagDecl) and insert right after its end location?

That will break with nested classes, won't it?

https://github.com/llvm/llvm-project/pull/69704
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2023-11-21 Thread Christian Kandeler via cfe-commits


@@ -349,6 +358,36 @@ TEST_F(DefineOutlineTest, ApplyTest) {
   }
 }
 
+TEST_F(DefineOutlineTest, InCppFile) {
+  FileName = "Test.cpp";
+
+  struct {
+llvm::StringRef Test;
+llvm::StringRef ExpectedSource;
+  } Cases[] = {
+  {
+  R"cpp(
+namespace foo {
+namespace {
+struct Foo { void ba^r() {} };

ckandeler wrote:

Ah, maybe getOuterLexicalRecordContext().

https://github.com/llvm/llvm-project/pull/69704
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2023-11-21 Thread Christian Kandeler via cfe-commits


@@ -349,6 +358,36 @@ TEST_F(DefineOutlineTest, ApplyTest) {
   }
 }
 
+TEST_F(DefineOutlineTest, InCppFile) {
+  FileName = "Test.cpp";
+
+  struct {
+llvm::StringRef Test;
+llvm::StringRef ExpectedSource;
+  } Cases[] = {
+  {
+  R"cpp(
+namespace foo {
+namespace {
+struct Foo { void ba^r() {} };

ckandeler wrote:

Hm, the SourceLocations are weird: getEndLoc() points to the closing brace of 
the class. Do I really have to look for the semicolon manually?

https://github.com/llvm/llvm-project/pull/69704
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2023-11-21 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/69704

>From 40df0527b2a3af8012f32d771a1bb2c861d42ed3 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Thu, 19 Oct 2023 17:51:11 +0200
Subject: [PATCH] [clangd] Allow "move function body out-of-line" in non-header
 files

Moving the body of member functions out-of-line makes sense for classes
defined in implementation files too.
---
 .../clangd/refactor/tweaks/DefineOutline.cpp  | 150 +++---
 .../unittests/tweaks/DefineOutlineTests.cpp   |  73 -
 2 files changed, 164 insertions(+), 59 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index b84ae04072f2c19..98cb3a8770c696d 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -179,14 +179,11 @@ deleteTokensWithKind(const syntax::TokenBuffer &TokBuf, 
tok::TokenKind Kind,
 // looked up in the context containing the function/method.
 // FIXME: Drop attributes in function signature.
 llvm::Expected
-getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace,
+getFunctionSourceCode(const FunctionDecl *FD, const DeclContext *TargetContext,
   const syntax::TokenBuffer &TokBuf,
   const HeuristicResolver *Resolver) {
   auto &AST = FD->getASTContext();
   auto &SM = AST.getSourceManager();
-  auto TargetContext = findContextForNS(TargetNamespace, FD->getDeclContext());
-  if (!TargetContext)
-return error("define outline: couldn't find a context for target");
 
   llvm::Error Errors = llvm::Error::success();
   tooling::Replacements DeclarationCleanups;
@@ -216,7 +213,7 @@ getFunctionSourceCode(const FunctionDecl *FD, 
llvm::StringRef TargetNamespace,
 }
 const NamedDecl *ND = Ref.Targets.front();
 const std::string Qualifier =
-getQualification(AST, *TargetContext,
+getQualification(AST, TargetContext,
  SM.getLocForStartOfFile(SM.getMainFileID()), ND);
 if (auto Err = DeclarationCleanups.add(
 tooling::Replacement(SM, Ref.NameLoc, 0, Qualifier)))
@@ -232,7 +229,7 @@ getFunctionSourceCode(const FunctionDecl *FD, 
llvm::StringRef TargetNamespace,
   if (const auto *Destructor = llvm::dyn_cast(FD)) {
 if (auto Err = DeclarationCleanups.add(tooling::Replacement(
 SM, Destructor->getLocation(), 0,
-getQualification(AST, *TargetContext,
+getQualification(AST, TargetContext,
  SM.getLocForStartOfFile(SM.getMainFileID()),
  Destructor
   Errors = llvm::joinErrors(std::move(Errors), std::move(Err));
@@ -319,29 +316,9 @@ getFunctionSourceCode(const FunctionDecl *FD, 
llvm::StringRef TargetNamespace,
 }
 
 struct InsertionPoint {
-  std::string EnclosingNamespace;
+  const DeclContext *EnclosingNamespace = nullptr;
   size_t Offset;
 };
-// Returns the most natural insertion point for \p QualifiedName in \p 
Contents.
-// This currently cares about only the namespace proximity, but in feature it
-// should also try to follow ordering of declarations. For example, if decls
-// come in order `foo, bar, baz` then this function should return some point
-// between foo and baz for inserting bar.
-llvm::Expected getInsertionPoint(llvm::StringRef Contents,
- llvm::StringRef QualifiedName,
- const LangOptions &LangOpts) {
-  auto Region = getEligiblePoints(Contents, QualifiedName, LangOpts);
-
-  assert(!Region.EligiblePoints.empty());
-  // FIXME: This selection can be made smarter by looking at the definition
-  // locations for adjacent decls to Source. Unfortunately pseudo parsing in
-  // getEligibleRegions only knows about namespace begin/end events so we
-  // can't match function start/end positions yet.
-  auto Offset = positionToOffset(Contents, Region.EligiblePoints.back());
-  if (!Offset)
-return Offset.takeError();
-  return InsertionPoint{Region.EnclosingNamespace, *Offset};
-}
 
 // Returns the range that should be deleted from declaration, which always
 // contains function body. In addition to that it might contain constructor
@@ -409,14 +386,9 @@ class DefineOutline : public Tweak {
   }
 
   bool prepare(const Selection &Sel) override {
-// Bail out if we are not in a header file.
-// FIXME: We might want to consider moving method definitions below class
-// definition even if we are inside a source file.
-if (!isHeaderFile(Sel.AST->getSourceManager().getFilename(Sel.Cursor),
-  Sel.AST->getLangOpts()))
-  return false;
-
+SameFile = !isHeaderFile(Sel.AST->tuPath(), Sel.AST->getLangOpts());
 Source = getSelectedFunction(Sel.ASTSelection.commonAncestor());
+
 // 

[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-01-08 Thread Christian Kandeler via cfe-commits


@@ -490,6 +491,13 @@ bool eligibleForExtraction(const SelectionTree::Node *N) {
 BO->getRHS() == OuterImplicit.ASTNode.get())
   return false;
   }
+  if (const auto *Decl = Parent->ASTNode.get()) {
+if (!Decl->isInitCapture() &&

ckandeler wrote:

Presumably, with the BinOp check I intended to prevent a false negative for 
this case:
`int x = 1 + 2 + [[3 + 4 + 5]];`
Apparently, the parser considers the last "+" to be the top-level expression, 
so we would erroneously fail to offer extraction for the above expression.
However, the same problem already existed for the assignment case, so it's 
probably wrong anyway to add such a workaround for initialization only. On the 
other hand, I don't want to introduce a regression either. Do you have a good 
idea as to how a proper check could look like?


https://github.com/llvm/llvm-project/pull/69477
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-01-11 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/69477

>From 0ad973446c970e110f1b9c1213e97a7d3da8 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Wed, 18 Oct 2023 17:24:04 +0200
Subject: [PATCH] [clangd] Do not offer extraction to variable for decl init
 expression

That would turn:
  int x = f() + 1;
into:
  auto placeholder = f() + 1;
  int x = placeholder;
which makes little sense and is clearly not intended, as stated
explicitly by a comment in eligibleForExtraction(). It appears that the
declaration case was simply forgotten (the assignment case was already
implemented).
---
 .../refactor/tweaks/ExtractVariable.cpp   | 44 +--
 .../unittests/tweaks/ExtractVariableTests.cpp | 27 +++-
 2 files changed, 55 insertions(+), 16 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp
index 79bf962544242b..3b378153eafd52 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp
@@ -468,7 +468,8 @@ bool eligibleForExtraction(const SelectionTree::Node *N) {
   // Extracting Exprs like a = 1 gives placeholder = a = 1 which isn't useful.
   // FIXME: we could still hoist the assignment, and leave the variable there?
   ParsedBinaryOperator BinOp;
-  if (BinOp.parse(*N) && BinaryOperator::isAssignmentOp(BinOp.Kind))
+  bool IsBinOp = BinOp.parse(*N);
+  if (IsBinOp && BinaryOperator::isAssignmentOp(BinOp.Kind))
 return false;
 
   const SelectionTree::Node &OuterImplicit = N->outerImplicit();
@@ -483,13 +484,48 @@ bool eligibleForExtraction(const SelectionTree::Node *N) {
   OuterImplicit.ASTNode.get()))
 return false;
 
+  std::function IsFullySelected =
+  [&](const SelectionTree::Node *N) {
+if (N->ASTNode.getSourceRange().isValid() &&
+N->Selected != SelectionTree::Complete)
+  return false;
+for (const auto *Child : N->Children) {
+  if (!IsFullySelected(Child))
+return false;
+}
+return true;
+  };
+  auto ExprIsFullySelectedTargetNode = [&](const Expr *E) {
+if (E != OuterImplicit.ASTNode.get())
+  return false;
+
+// The above condition is the only relevant one except for binary 
operators.
+// Without the following code, we would fail to offer extraction for e.g.:
+//   int x = 1 + 2 + [[3 + 4 + 5]];
+// See the documentation of ParsedBinaryOperator for further details.
+if (!IsBinOp)
+  return true;
+return IsFullySelected(N);
+  };
+
   // Disable extraction of full RHS on assignment operations, e.g:
-  // auto x = [[RHS_EXPR]];
+  // x = [[RHS_EXPR]];
   // This would just result in duplicating the code.
   if (const auto *BO = Parent->ASTNode.get()) {
-if (BO->isAssignmentOp() &&
-BO->getRHS() == OuterImplicit.ASTNode.get())
+if (BO->isAssignmentOp() && ExprIsFullySelectedTargetNode(BO->getRHS()))
+  return false;
+  }
+
+  // The same logic as for assignments applies to initializations.
+  // However, we do allow extracting the RHS of an init capture, as it is
+  // a valid use case to move non-trivial expressions out of the capture 
clause.
+  // FIXME: In that case, the extracted variable should be captured directly,
+  //rather than an explicit copy.
+  if (const auto *Decl = Parent->ASTNode.get()) {
+if (!Decl->isInitCapture() &&
+ExprIsFullySelectedTargetNode(Decl->getInit())) {
   return false;
+}
   }
 
   return true;
diff --git a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp 
b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp
index eb5b06cfee4316..42dd612c46 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp
@@ -27,10 +27,10 @@ TEST_F(ExtractVariableTest, Test) {
   return t.b[[a]]r]]([[t.z]])]];
 }
 void f() {
-  int a = [[5 +]] [[4 * xyz]]();
+  int a = 5 + [[4 * xyz]]();
   // multivariable initialization
   if(1)
-int x = [[1]], y = [[a + 1]], a = [[1]], z = a + 1;
+int x = [[1]] + 1, y = a + [[1]], a = [[1]] + 2, z = a + 1;
   // if without else
   if([[1]])
 a = [[1]] + 1;
@@ -61,7 +61,7 @@ TEST_F(ExtractVariableTest, Test) {
   ExtraArgs = {"-xc"};
   const char *AvailableC = R"cpp(
 void foo() {
-  int x = [[1]];
+  int x = [[1]] + 1;
 })cpp";
   EXPECT_AVAILABLE(AvailableC);
 
@@ -79,7 +79,7 @@ TEST_F(ExtractVariableTest, Test) {
 @end
 @implementation Foo
 - (void)method {
-  int x = [[1 + 2]];
+  int x = [[1]] + 2;
 }
 @end)cpp";
   EXPECT_AVAILABLE(AvailableObjC);
@@ -103,6 +103,9 @@ TEST_F(ExtractVariableTest, Test) {
 }
 int z = [[1]];
   } t;
+  int x = [

[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-01-11 Thread Christian Kandeler via cfe-commits


@@ -27,10 +27,10 @@ TEST_F(ExtractVariableTest, Test) {
   return t.b[[a]]r]]([[t.z]])]];
 }
 void f() {
-  int a = [[5 +]] [[4 * xyz]]();
+  int a = 5 + [[4 * xyz]]();
   // multivariable initialization
   if(1)
-int x = [[1]], y = [[a + 1]], a = [[1]], z = a + 1;
+int x = [[1]] + 1, y = [[a + 1]], a = [[1]] + 2, z = a + 1;

ckandeler wrote:

Yes, I got side-tracked by fixing all the regressions, and in the end the patch 
didn't fulfill its original purpose anymore.
Fixed  now.

https://github.com/llvm/llvm-project/pull/69477
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-01-11 Thread Christian Kandeler via cfe-commits


@@ -422,8 +422,6 @@ TEST_F(ExtractVariableTest, Test) {
 int member = 42;
 };
 )cpp"},
-  {R"cpp(void f() { auto x = [[ [](){ return 42; }]]; })cpp",

ckandeler wrote:

Done.

https://github.com/llvm/llvm-project/pull/69477
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-01-11 Thread Christian Kandeler via cfe-commits


@@ -504,68 +502,6 @@ TEST_F(ExtractVariableTest, Test) {
 int main() {
   auto placeholder = []() { return 42; }(); return  placeholder ;
 })cpp"},
-  {R"cpp(

ckandeler wrote:

Done.

https://github.com/llvm/llvm-project/pull/69477
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-01-11 Thread Christian Kandeler via cfe-commits


@@ -504,68 +502,6 @@ TEST_F(ExtractVariableTest, Test) {
 int main() {
   auto placeholder = []() { return 42; }(); return  placeholder ;
 })cpp"},
-  {R"cpp(
-template 
-void foo(Ts ...args) {
-  auto x = [[ [&args...]() {} ]];
-}
-  )cpp",
-   R"cpp(
-template 
-void foo(Ts ...args) {
-  auto placeholder = [&args...]() {}; auto x =  placeholder ;
-}
-  )cpp"},
-  {R"cpp(

ckandeler wrote:

Done.

https://github.com/llvm/llvm-project/pull/69477
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-01-11 Thread Christian Kandeler via cfe-commits


@@ -490,6 +491,13 @@ bool eligibleForExtraction(const SelectionTree::Node *N) {
 BO->getRHS() == OuterImplicit.ASTNode.get())
   return false;
   }
+  if (const auto *Decl = Parent->ASTNode.get()) {
+if (!Decl->isInitCapture() &&

ckandeler wrote:

I think I found a not-too-horrible solution.

https://github.com/llvm/llvm-project/pull/69477
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-01-11 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

The latest patch set addresses all the comments.

https://github.com/llvm/llvm-project/pull/69477
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Fix JSON conversion for symbol tags (PR #84747)

2024-03-11 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler created 
https://github.com/llvm/llvm-project/pull/84747

The wrong constructor of json::Value got called, making every tag an array 
instead of a number.

>From f67994902314acd8ae0f0c561b07b8c014172e17 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Mon, 11 Mar 2024 13:04:21 +0100
Subject: [PATCH] [clangd] Fix JSON conversion for symbol tags

The wrong constructor of json::Value got called, making every tag an
array instead of a number.
---
 clang-tools-extra/clangd/Protocol.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clangd/Protocol.cpp 
b/clang-tools-extra/clangd/Protocol.cpp
index 8aa18bb0058abe..c6553e00dcae28 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -1412,7 +1412,7 @@ bool fromJSON(const llvm::json::Value &Params, 
ReferenceParams &R,
 }
 
 llvm::json::Value toJSON(SymbolTag Tag) {
-  return llvm::json::Value{static_cast(Tag)};
+  return llvm::json::Value(static_cast(Tag));
 }
 
 llvm::json::Value toJSON(const CallHierarchyItem &I) {

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


[clang-tools-extra] [clangd] Remove potential prefix from enum value names (PR #83412)

2024-02-29 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler created 
https://github.com/llvm/llvm-project/pull/83412

... when converting unscoped to scoped enums.
With traditional enums, a popular technique to guard against potential name 
clashes is to use the enum name as a pseudo-namespace, like this:
  enum MyEnum { MyEnumValue1, MyEnumValue2 };
With scoped enums, this makes no sense, making it extremely unlikely that the 
user wants to keep such a prefix when modernizing. Therefore, our tweak now 
removes it.

>From c687b73939821eba285b35e50c241738ba7915e4 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Thu, 29 Feb 2024 12:26:52 +0100
Subject: [PATCH] [clangd] Remove potential prefix from enum value names

... when converting unscoped to scoped enums.
With traditional enums, a popular technique to guard against potential
name clashes is to use the enum name as a pseudo-namespace, like this:
  enum MyEnum { MyEnumValue1, MyEnumValue2 };
With scoped enums, this makes no sense, making it extremely unlikely
that the user wants to keep such a prefix when modernizing. Therefore, our
tweak now removes it.
---
 .../clangd/refactor/tweaks/ScopifyEnum.cpp| 49 +--
 .../unittests/tweaks/ScopifyEnumTests.cpp |  8 +--
 2 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
index e36b3249bc7b92..5c042ee7b782b9 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
@@ -40,15 +40,12 @@ namespace {
 ///   void f() { E e1 = EV1; }
 ///
 /// After:
-///   enum class E { EV1, EV2 };
-///   void f() { E e1 = E::EV1; }
+///   enum class E { V1, V2 };
+///   void f() { E e1 = E::V1; }
 ///
 /// Note that the respective project code might not compile anymore
 /// if it made use of the now-gone implicit conversion to int.
 /// This is out of scope for this tweak.
-///
-/// TODO: In the above example, we could detect that the values
-///   start with the enum name, and remove that prefix.
 
 class ScopifyEnum : public Tweak {
   const char *id() const final;
@@ -63,7 +60,8 @@ class ScopifyEnum : public Tweak {
   std::function;
   llvm::Error addClassKeywordToDeclarations();
   llvm::Error scopifyEnumValues();
-  llvm::Error scopifyEnumValue(const EnumConstantDecl &CD, StringRef Prefix);
+  llvm::Error scopifyEnumValue(const EnumConstantDecl &CD, StringRef EnumName,
+   bool StripPrefix);
   llvm::Expected getContentForFile(StringRef FilePath);
   unsigned getOffsetFromPosition(const Position &Pos, StringRef Content) const;
   llvm::Error addReplacementForReference(const ReferencesResult::Reference 
&Ref,
@@ -125,25 +123,42 @@ llvm::Error ScopifyEnum::addClassKeywordToDeclarations() {
 }
 
 llvm::Error ScopifyEnum::scopifyEnumValues() {
-  std::string PrefixToInsert(D->getName());
-  PrefixToInsert += "::";
+  StringRef EnumName(D->getName());
+  bool StripPrefix = true;
+  for (auto E : D->enumerators()) {
+if (!E->getName().starts_with(EnumName)) {
+  StripPrefix = false;
+  break;
+}
+  }
   for (auto E : D->enumerators()) {
-if (auto Err = scopifyEnumValue(*E, PrefixToInsert))
+if (auto Err = scopifyEnumValue(*E, EnumName, StripPrefix))
   return Err;
   }
   return llvm::Error::success();
 }
 
 llvm::Error ScopifyEnum::scopifyEnumValue(const EnumConstantDecl &CD,
-  StringRef Prefix) {
+  StringRef EnumName,
+  bool StripPrefix) {
   for (const auto &Ref :
findReferences(*S->AST, getPosition(CD), 0, S->Index, false)
.References) {
-if (Ref.Attributes & ReferencesResult::Declaration)
+if (Ref.Attributes & ReferencesResult::Declaration) {
+  if (StripPrefix) {
+const auto MakeReplacement = [&EnumName](StringRef FilePath,
+ StringRef /* Content */,
+ unsigned Offset) {
+  return tooling::Replacement(FilePath, Offset, EnumName.size(), {});
+};
+if (auto Err = addReplacementForReference(Ref, MakeReplacement))
+  return Err;
+  }
   continue;
+}
 
-const auto MakeReplacement = [&Prefix](StringRef FilePath,
-   StringRef Content, unsigned Offset) 
{
+const auto MakeReplacement = [&](StringRef FilePath, StringRef Content,
+ unsigned Offset) {
   const auto IsAlreadyScoped = [Content, Offset] {
 if (Offset < 2)
   return false;
@@ -164,9 +179,15 @@ llvm::Error ScopifyEnum::scopifyEnumValue(const 
EnumConstantDecl &CD,
 }
 return false;
   };
+  if (StripPrefix) {
+if (IsAlreadyScoped())
+  return tooling::Replacement(FilePath, O

[clang-tools-extra] [clangd] Remove potential prefix from enum value names (PR #83412)

2024-03-01 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/83412

>From 01f74ddece947755938ccecbcc5f9d18a41eb793 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Thu, 29 Feb 2024 12:26:52 +0100
Subject: [PATCH] [clangd] Remove potential prefix from enum value names

... when converting unscoped to scoped enums.
With traditional enums, a popular technique to guard against potential
name clashes is to use the enum name as a pseudo-namespace, like this:
  enum MyEnum { MyEnumValue1, MyEnumValue2 };
With scoped enums, this makes no sense, making it extremely unlikely
that the user wants to keep such a prefix when modernizing. Therefore, our
tweak now removes it.
---
 .../clangd/refactor/tweaks/ScopifyEnum.cpp| 53 +--
 .../unittests/tweaks/ScopifyEnumTests.cpp | 38 +++--
 2 files changed, 70 insertions(+), 21 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
index e36b3249bc7b92..8e13ae52d121a6 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
@@ -40,15 +40,12 @@ namespace {
 ///   void f() { E e1 = EV1; }
 ///
 /// After:
-///   enum class E { EV1, EV2 };
-///   void f() { E e1 = E::EV1; }
+///   enum class E { V1, V2 };
+///   void f() { E e1 = E::V1; }
 ///
 /// Note that the respective project code might not compile anymore
 /// if it made use of the now-gone implicit conversion to int.
 /// This is out of scope for this tweak.
-///
-/// TODO: In the above example, we could detect that the values
-///   start with the enum name, and remove that prefix.
 
 class ScopifyEnum : public Tweak {
   const char *id() const final;
@@ -63,7 +60,8 @@ class ScopifyEnum : public Tweak {
   std::function;
   llvm::Error addClassKeywordToDeclarations();
   llvm::Error scopifyEnumValues();
-  llvm::Error scopifyEnumValue(const EnumConstantDecl &CD, StringRef Prefix);
+  llvm::Error scopifyEnumValue(const EnumConstantDecl &CD, StringRef EnumName,
+   bool StripPrefix);
   llvm::Expected getContentForFile(StringRef FilePath);
   unsigned getOffsetFromPosition(const Position &Pos, StringRef Content) const;
   llvm::Error addReplacementForReference(const ReferencesResult::Reference 
&Ref,
@@ -125,25 +123,42 @@ llvm::Error ScopifyEnum::addClassKeywordToDeclarations() {
 }
 
 llvm::Error ScopifyEnum::scopifyEnumValues() {
-  std::string PrefixToInsert(D->getName());
-  PrefixToInsert += "::";
+  StringRef EnumName(D->getName());
+  bool StripPrefix = true;
+  for (auto E : D->enumerators()) {
+if (!E->getName().starts_with(EnumName)) {
+  StripPrefix = false;
+  break;
+}
+  }
   for (auto E : D->enumerators()) {
-if (auto Err = scopifyEnumValue(*E, PrefixToInsert))
+if (auto Err = scopifyEnumValue(*E, EnumName, StripPrefix))
   return Err;
   }
   return llvm::Error::success();
 }
 
 llvm::Error ScopifyEnum::scopifyEnumValue(const EnumConstantDecl &CD,
-  StringRef Prefix) {
+  StringRef EnumName,
+  bool StripPrefix) {
   for (const auto &Ref :
findReferences(*S->AST, getPosition(CD), 0, S->Index, false)
.References) {
-if (Ref.Attributes & ReferencesResult::Declaration)
+if (Ref.Attributes & ReferencesResult::Declaration) {
+  if (StripPrefix) {
+const auto MakeReplacement = [&EnumName](StringRef FilePath,
+ StringRef /* Content */,
+ unsigned Offset) {
+  return tooling::Replacement(FilePath, Offset, EnumName.size(), {});
+};
+if (auto Err = addReplacementForReference(Ref, MakeReplacement))
+  return Err;
+  }
   continue;
+}
 
-const auto MakeReplacement = [&Prefix](StringRef FilePath,
-   StringRef Content, unsigned Offset) 
{
+const auto MakeReplacement = [&](StringRef FilePath, StringRef Content,
+ unsigned Offset) {
   const auto IsAlreadyScoped = [Content, Offset] {
 if (Offset < 2)
   return false;
@@ -164,9 +179,15 @@ llvm::Error ScopifyEnum::scopifyEnumValue(const 
EnumConstantDecl &CD,
 }
 return false;
   };
-  return IsAlreadyScoped()
- ? tooling::Replacement()
- : tooling::Replacement(FilePath, Offset, 0, Prefix);
+  if (StripPrefix) {
+if (IsAlreadyScoped())
+  return tooling::Replacement(FilePath, Offset, EnumName.size(), {});
+return tooling::Replacement(FilePath, Offset + EnumName.size(), 0,
+"::");
+  }
+  return IsAlreadyScoped() ? tooling::Replacement()
+   :

[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2024-03-04 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

ping

https://github.com/llvm/llvm-project/pull/69704
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-02-01 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

ping

https://github.com/llvm/llvm-project/pull/67802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-02-01 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

ping

https://github.com/llvm/llvm-project/pull/69477
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2024-02-01 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

ping

https://github.com/llvm/llvm-project/pull/69704
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-02-01 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

> Do you have another patch where you use the new `DocComment` field?  Is it 
> for showing in a hover?

Yes, it is for showing documentation in a hover. clangd already supports that; 
it's just that it currently works only if the comments are attached to the 
declaration. With this patch it works also for comments at the implementation 
site,   (which I think was the intended behavior all along). No additional 
patch is necessary.



https://github.com/llvm/llvm-project/pull/67802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-02-01 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

> Ok, I see. (I was confused because nothing in the patch looks at the contents 
> of `Symbol::DocComment` other than 
> an `empty()` check; maybe a `bool HasDocComment` flag is sufficient?)

Right, we just need to save the information whether there was a doc comment 
before clangd put default values into the Documentation field. 

> I'll have a more detailed look when I get a chance, but one suggestion I 
> wanted to make in the meantime: for 
> changes that add new information to the index, it helps to have a sense of 
> how large of an increase to the index's 
> disk and memory footprint they entail. In the past, I've measured this with 
> the LLVM codebase's index as a "test 
> case".

Will check.


https://github.com/llvm/llvm-project/pull/67802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-02-02 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/67802

>From fb3711aa040aa2a986ed7d0c503042adecc6662a Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Fri, 29 Sep 2023 15:01:58 +0200
Subject: [PATCH] [clangd] Collect comments from function definitions into the
 index

This is useful with projects that put their (doxygen) comments at the
implementation site, rather than the header.
---
 clang-tools-extra/clangd/index/Symbol.h   |  4 ++-
 .../clangd/index/SymbolCollector.cpp  | 29 +--
 clang/lib/AST/ASTContext.cpp  | 11 ++-
 3 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/clang-tools-extra/clangd/index/Symbol.h 
b/clang-tools-extra/clangd/index/Symbol.h
index 1aa5265299231..62c47ddfc5758 100644
--- a/clang-tools-extra/clangd/index/Symbol.h
+++ b/clang-tools-extra/clangd/index/Symbol.h
@@ -145,9 +145,11 @@ struct Symbol {
 ImplementationDetail = 1 << 2,
 /// Symbol is visible to other files (not e.g. a static helper function).
 VisibleOutsideFile = 1 << 3,
+/// Symbol has an attached documentation comment.
+HasDocComment = 1 << 4
   };
-
   SymbolFlag Flags = SymbolFlag::None;
+
   /// FIXME: also add deprecation message and fixit?
 };
 
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp 
b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index bf838e53f2a21..d071228455836 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -1020,15 +1020,17 @@ const Symbol *SymbolCollector::addDeclaration(const 
NamedDecl &ND, SymbolID ID,
   *ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
   *CompletionTUInfo,
   /*IncludeBriefComments*/ false);
-  std::string Documentation =
-  formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion,
-  /*CommentsFromHeaders=*/true));
+  std::string DocComment = getDocComment(Ctx, SymbolCompletion,
+ /*CommentsFromHeaders=*/true);
+  std::string Documentation = formatDocumentation(*CCS, DocComment);
   if (!(S.Flags & Symbol::IndexedForCodeCompletion)) {
 if (Opts.StoreAllDocumentation)
   S.Documentation = Documentation;
 Symbols.insert(S);
 return Symbols.find(S.ID);
   }
+  if (!DocComment.empty())
+S.Flags |= Symbol::HasDocComment;
   S.Documentation = Documentation;
   std::string Signature;
   std::string SnippetSuffix;
@@ -1069,6 +1071,27 @@ void SymbolCollector::addDefinition(const NamedDecl &ND,
   Symbol S = DeclSym;
   // FIXME: use the result to filter out symbols.
   S.Definition = *DefLoc;
+
+  std::string DocComment;
+  std::string Documentation;
+  if (!(S.Flags & Symbol::HasDocComment) &&
+  (llvm::isa(ND) || llvm::isa(ND))) {
+CodeCompletionResult SymbolCompletion(&getTemplateOrThis(ND), 0);
+const auto *CCS = SymbolCompletion.CreateCodeCompletionString(
+*ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
+*CompletionTUInfo,
+/*IncludeBriefComments*/ false);
+DocComment = getDocComment(ND.getASTContext(), SymbolCompletion,
+   /*CommentsFromHeaders=*/true);
+if (!S.Documentation.empty())
+  Documentation = S.Documentation.str() + '\n' + DocComment;
+else
+  Documentation = formatDocumentation(*CCS, DocComment);
+if (!DocComment.empty())
+  S.Flags |= Symbol::HasDocComment;
+S.Documentation = Documentation;
+  }
+
   Symbols.insert(S);
 }
 
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index f7c9e4521b5f1..aa06a1ada4ba7 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -448,8 +448,17 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
 if (LastCheckedRedecl) {
   if (LastCheckedRedecl == Redecl) {
 LastCheckedRedecl = nullptr;
+continue;
+  }
+  if (auto F = llvm::dyn_cast(Redecl)) {
+if (!F->isThisDeclarationADefinition())
+  continue;
+  } else if (auto M = llvm::dyn_cast(Redecl)) {
+if (!M->isThisDeclarationADefinition())
+  continue;
+  } else {
+continue;
   }
-  continue;
 }
 const RawComment *RedeclComment = getRawCommentForDeclNoCache(Redecl);
 if (RedeclComment) {

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


[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-02-02 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

I have removed the extra Symbol member and extended the Flags enum instead.
I benchmarked with Qt as the test project (qtbase, to be exact), which is 
heavily documented and has all its function documentation in the cpp files, so 
it should provide an upper bound on the effects of this patch.
Index size before this patch : 68MB on-disk, 552MB in-memory
With original patch (extra Symbol member): 70MB/576MB
With latest patch set: 70MB/564 MB
I only did one measurement each, so I don't know if there might be unrelated 
fluctuations there.

https://github.com/llvm/llvm-project/pull/67802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 8b36687 - [clangd] Add highlighting modifier "constructorOrDestructor"

2022-10-21 Thread Christian Kandeler via cfe-commits

Author: Christian Kandeler
Date: 2022-10-21T15:14:38+02:00
New Revision: 8b3668754c889a9412a76035235b6fc581ca9863

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

LOG: [clangd] Add highlighting modifier "constructorOrDestructor"

This is useful for clients that want to highlight constructors and
destructors different from classes, e.g. like functions.

Reviewed By: sammccall

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

Added: 


Modified: 
clang-tools-extra/clangd/SemanticHighlighting.cpp
clang-tools-extra/clangd/SemanticHighlighting.h
clang-tools-extra/clangd/test/initialize-params.test
clang-tools-extra/clangd/test/semantic-tokens.test
clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index 1a6fa528acced..08cca2203667b 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -649,6 +649,29 @@ class CollectExtraHighlightings
 return true;
   }
 
+  bool VisitCXXDestructorDecl(CXXDestructorDecl *D) {
+if (auto *TI = D->getNameInfo().getNamedTypeInfo()) {
+  SourceLocation Loc = TI->getTypeLoc().getBeginLoc();
+  H.addExtraModifier(Loc, HighlightingModifier::ConstructorOrDestructor);
+  H.addExtraModifier(Loc, HighlightingModifier::Declaration);
+  if (D->isThisDeclarationADefinition())
+H.addExtraModifier(Loc, HighlightingModifier::Definition);
+}
+return true;
+  }
+
+  bool VisitCXXMemberCallExpr(CXXMemberCallExpr *CE) {
+if (isa(CE->getMethodDecl())) {
+  if (auto *ME = dyn_cast(CE->getCallee())) {
+if (auto *TI = ME->getMemberNameInfo().getNamedTypeInfo()) {
+  H.addExtraModifier(TI->getTypeLoc().getBeginLoc(),
+ HighlightingModifier::ConstructorOrDestructor);
+}
+  }
+}
+return true;
+  }
+
   bool VisitDeclaratorDecl(DeclaratorDecl *D) {
 auto *AT = D->getType()->getContainedAutoType();
 if (!AT)
@@ -879,6 +902,8 @@ std::vector 
getSemanticHighlightings(ParsedAST &AST) {
 Tok.addModifier(HighlightingModifier::DefaultLibrary);
   if (Decl->isDeprecated())
 Tok.addModifier(HighlightingModifier::Deprecated);
+  if (isa(Decl))
+Tok.addModifier(HighlightingModifier::ConstructorOrDestructor);
   if (R.IsDecl) {
 // Do not treat an UnresolvedUsingValueDecl as a declaration.
 // It's more common to think of it as a reference to the
@@ -960,6 +985,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
HighlightingModifier K) {
 return OS << "decl"; // abbreviation for common case
   case HighlightingModifier::Definition:
 return OS << "def"; // abbrevation for common case
+  case HighlightingModifier::ConstructorOrDestructor:
+return OS << "constrDestr";
   default:
 return OS << toSemanticTokenModifier(K);
   }
@@ -,6 +1138,8 @@ llvm::StringRef 
toSemanticTokenModifier(HighlightingModifier Modifier) {
 return "defaultLibrary";
   case HighlightingModifier::UsedAsMutableReference:
 return "usedAsMutableReference"; // nonstandard
+  case HighlightingModifier::ConstructorOrDestructor:
+return "constructorOrDestructor"; // nonstandard
   case HighlightingModifier::FunctionScope:
 return "functionScope"; // nonstandard
   case HighlightingModifier::ClassScope:

diff  --git a/clang-tools-extra/clangd/SemanticHighlighting.h 
b/clang-tools-extra/clangd/SemanticHighlighting.h
index 4fe2fc7aee54d..79ecb344275d1 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.h
+++ b/clang-tools-extra/clangd/SemanticHighlighting.h
@@ -71,6 +71,7 @@ enum class HighlightingModifier {
   DependentName,
   DefaultLibrary,
   UsedAsMutableReference,
+  ConstructorOrDestructor,
 
   FunctionScope,
   ClassScope,

diff  --git a/clang-tools-extra/clangd/test/initialize-params.test 
b/clang-tools-extra/clangd/test/initialize-params.test
index 031be9e147f74..eb958cac20279 100644
--- a/clang-tools-extra/clangd/test/initialize-params.test
+++ b/clang-tools-extra/clangd/test/initialize-params.test
@@ -68,6 +68,7 @@
 # CHECK-NEXT:"dependentName",
 # CHECK-NEXT:"defaultLibrary",
 # CHECK-NEXT:"usedAsMutableReference",
+# CHECK-NEXT:"constructorOrDestructor",
 # CHECK-NEXT:"functionScope",
 # CHECK-NEXT:"classScope",
 # CHECK-NEXT:"fileScope",

diff  --git a/clang-tools-extra/clangd/test/semantic-tokens.test 
b/clang-tools-extra/clangd/test/semantic-tokens.test
index b85d720ff5137..5abe78e9a51e1 100644
--- a/clang-tools-extra/clangd/test/semantic-tokens

[clang-tools-extra] 6ed4a54 - [clangd] Make file limit for textDocument/rename configurable

2022-10-22 Thread Christian Kandeler via cfe-commits

Author: Christian Kandeler
Date: 2022-10-22T10:17:41+02:00
New Revision: 6ed4a543b8b3ab38ddb30cf4c15b70ed11266388

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

LOG: [clangd] Make file limit for textDocument/rename configurable

Without this, clients are unable to rename often-used symbols in larger
projects.

Reviewed By: kadircet

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

Added: 


Modified: 
clang-tools-extra/clangd/tool/ClangdMain.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp 
b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index 68c0a51a2d74d..53b6653c51f20 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -327,6 +327,14 @@ opt ReferencesLimit{
 init(1000),
 };
 
+opt RenameFileLimit{
+"rename-file-limit",
+cat(Features),
+desc("Limit the number of files to be affected by symbol renaming. "
+ "0 means no limit (default=50)"),
+init(50),
+};
+
 list TweakList{
 "tweaks",
 cat(Features),
@@ -891,6 +899,7 @@ clangd accepts flags on the commandline, and in the 
CLANGD_FLAGS environment var
   Opts.BackgroundIndex = EnableBackgroundIndex;
   Opts.BackgroundIndexPriority = BackgroundIndexPriority;
   Opts.ReferencesLimit = ReferencesLimit;
+  Opts.Rename.LimitFiles = RenameFileLimit;
   auto PAI = createProjectAwareIndex(loadExternalIndex, Sync);
   if (StaticIdx) {
 IdxStack.emplace_back(std::move(StaticIdx));



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


[clang-tools-extra] 2bf960a - [clangd] Add "usedAsMutablePointer" highlighting modifier

2022-11-07 Thread Christian Kandeler via cfe-commits

Author: Christian Kandeler
Date: 2022-11-07T11:58:33+01:00
New Revision: 2bf960aef08e93d687f21e6d636186561b56cbf3

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

LOG: [clangd] Add "usedAsMutablePointer" highlighting modifier

Counterpart to "usedAsMutableReference". Just as for references, there
are const and non-const pointer parameters, and it's valuable to be able
to have different highlighting for the two cases at the call site.
We could have re-used the existing modifier, but having a dedicated one
maximizes client flexibility.

Reviewed By: nridge

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

Added: 


Modified: 
clang-tools-extra/clangd/SemanticHighlighting.cpp
clang-tools-extra/clangd/SemanticHighlighting.h
clang-tools-extra/clangd/test/initialize-params.test
clang-tools-extra/clangd/test/semantic-tokens.test
clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index af3a3e6f8e941..dd9392b029df8 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -597,19 +597,27 @@ class CollectExtraHighlightings
 if (!Arg)
   return;
 
-// Is this parameter passed by non-const reference?
+// Is this parameter passed by non-const pointer or reference?
 // FIXME The condition T->idDependentType() could be relaxed a bit,
 // e.g. std::vector& is dependent but we would want to highlight it
-if (!T->isLValueReferenceType() ||
-T.getNonReferenceType().isConstQualified() || T->isDependentType()) {
+bool IsRef = T->isLValueReferenceType();
+bool IsPtr = T->isPointerType();
+if ((!IsRef && !IsPtr) || T->getPointeeType().isConstQualified() ||
+T->isDependentType()) {
   return;
 }
 
 llvm::Optional Location;
 
-// FIXME Add "unwrapping" for ArraySubscriptExpr and UnaryOperator,
+// FIXME Add "unwrapping" for ArraySubscriptExpr,
 //  e.g. highlight `a` in `a[i]`
 // FIXME Handle dependent expression types
+if (auto *IC = dyn_cast(Arg))
+  Arg = IC->getSubExprAsWritten();
+if (auto *UO = dyn_cast(Arg)) {
+  if (UO->getOpcode() == UO_AddrOf)
+Arg = UO->getSubExpr();
+}
 if (auto *DR = dyn_cast(Arg))
   Location = DR->getLocation();
 else if (auto *M = dyn_cast(Arg))
@@ -617,7 +625,8 @@ class CollectExtraHighlightings
 
 if (Location)
   H.addExtraModifier(*Location,
- HighlightingModifier::UsedAsMutableReference);
+ IsRef ? HighlightingModifier::UsedAsMutableReference
+   : HighlightingModifier::UsedAsMutablePointer);
   }
 
   void
@@ -1140,6 +1149,8 @@ llvm::StringRef 
toSemanticTokenModifier(HighlightingModifier Modifier) {
 return "defaultLibrary";
   case HighlightingModifier::UsedAsMutableReference:
 return "usedAsMutableReference"; // nonstandard
+  case HighlightingModifier::UsedAsMutablePointer:
+return "usedAsMutablePointer"; // nonstandard
   case HighlightingModifier::ConstructorOrDestructor:
 return "constructorOrDestructor"; // nonstandard
   case HighlightingModifier::FunctionScope:

diff  --git a/clang-tools-extra/clangd/SemanticHighlighting.h 
b/clang-tools-extra/clangd/SemanticHighlighting.h
index 79ecb344275d1..64ad431909faa 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.h
+++ b/clang-tools-extra/clangd/SemanticHighlighting.h
@@ -71,6 +71,7 @@ enum class HighlightingModifier {
   DependentName,
   DefaultLibrary,
   UsedAsMutableReference,
+  UsedAsMutablePointer,
   ConstructorOrDestructor,
 
   FunctionScope,

diff  --git a/clang-tools-extra/clangd/test/initialize-params.test 
b/clang-tools-extra/clangd/test/initialize-params.test
index eb958cac20279..a2df61ca75235 100644
--- a/clang-tools-extra/clangd/test/initialize-params.test
+++ b/clang-tools-extra/clangd/test/initialize-params.test
@@ -68,6 +68,7 @@
 # CHECK-NEXT:"dependentName",
 # CHECK-NEXT:"defaultLibrary",
 # CHECK-NEXT:"usedAsMutableReference",
+# CHECK-NEXT:"usedAsMutablePointer",
 # CHECK-NEXT:"constructorOrDestructor",
 # CHECK-NEXT:"functionScope",
 # CHECK-NEXT:"classScope",

diff  --git a/clang-tools-extra/clangd/test/semantic-tokens.test 
b/clang-tools-extra/clangd/test/semantic-tokens.test
index 5abe78e9a51e1..b3a92b7cc737b 100644
--- a/clang-tools-extra/clangd/test/semantic-tokens.test
+++ b/clang-tools-extra/clangd/test/semantic-tokens.test
@@ -23,7 +23,7 @@
 # CHECK-NEXT:  4,
 # CHECK-NEXT:  1,
 # CHECK-NEXT:  0,
-# CHECK-NEXT:  32771
+

[clang-tools-extra] bbddbe5 - [clangd] Add semantic token for angle brackets

2023-01-31 Thread Christian Kandeler via cfe-commits

Author: Christian Kandeler
Date: 2023-01-31T17:15:31+01:00
New Revision: bbddbe580bca5fa1c0478a3ec6edd0e0c40b9d96

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

LOG: [clangd] Add semantic token for angle brackets

This is needed for clients that would like to visualize matching
opening and closing angle brackets, which can be valuable in non-trivial
template declarations or instantiations.
It is not possible to do this with simple lexing, as the tokens
could also refer to operators.

Reviewed By: kadircet

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

Added: 


Modified: 
clang-tools-extra/clangd/SemanticHighlighting.cpp
clang-tools-extra/clangd/SemanticHighlighting.h
clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index a516c688efc1..e3022ad131ff 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -369,6 +369,47 @@ class HighlightingsBuilder {
 return addToken(*Range, Kind);
   }
 
+  // Most of this function works around
+  // https://github.com/clangd/clangd/issues/871.
+  void addAngleBracketTokens(SourceLocation LLoc, SourceLocation RLoc) {
+if (!LLoc.isValid() || !RLoc.isValid())
+  return;
+
+auto LRange = getRangeForSourceLocation(LLoc);
+if (!LRange)
+  return;
+
+// RLoc might be pointing at a virtual buffer when it's part of a `>>`
+// token.
+RLoc = SourceMgr.getFileLoc(RLoc);
+// Make sure token is part of the main file.
+RLoc = getHighlightableSpellingToken(RLoc, SourceMgr);
+if (!RLoc.isValid())
+  return;
+
+const auto *RTok = TB.spelledTokenAt(RLoc);
+// Handle `>>`. RLoc is always pointing at the right location, just change
+// the end to be offset by 1.
+// We'll either point at the beginning of `>>`, hence get a proper spelled
+// or point in the middle of `>>` hence get no spelled tok.
+if (!RTok || RTok->kind() == tok::greatergreater) {
+  Position Begin = sourceLocToPosition(SourceMgr, RLoc);
+  Position End = sourceLocToPosition(SourceMgr, RLoc.getLocWithOffset(1));
+  addToken(*LRange, HighlightingKind::Bracket);
+  addToken({Begin, End}, HighlightingKind::Bracket);
+  return;
+}
+
+// Easy case, we have the `>` token directly available.
+if (RTok->kind() == tok::greater) {
+  if (auto RRange = getRangeForSourceLocation(RLoc)) {
+addToken(*LRange, HighlightingKind::Bracket);
+addToken(*RRange, HighlightingKind::Bracket);
+  }
+  return;
+}
+  }
+
   HighlightingToken &addToken(Range R, HighlightingKind Kind) {
 HighlightingToken HT;
 HT.R = std::move(R);
@@ -559,6 +600,12 @@ class CollectExtraHighlightings
 return Base::TraverseConstructorInitializer(Init);
   }
 
+  bool TraverseTypeConstraint(const TypeConstraint *C) {
+if (auto *Args = C->getTemplateArgsAsWritten())
+  H.addAngleBracketTokens(Args->getLAngleLoc(), Args->getRAngleLoc());
+return Base::TraverseTypeConstraint(C);
+  }
+
   bool VisitPredefinedExpr(PredefinedExpr *E) {
 H.addToken(E->getLocation(), HighlightingKind::LocalVariable)
 .addModifier(HighlightingModifier::Static)
@@ -567,6 +614,77 @@ class CollectExtraHighlightings
 return true;
   }
 
+  bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
+if (auto *Args = E->getTemplateArgsAsWritten())
+  H.addAngleBracketTokens(Args->getLAngleLoc(), Args->getRAngleLoc());
+return true;
+  }
+
+  bool VisitTemplateDecl(TemplateDecl *D) {
+if (auto *TPL = D->getTemplateParameters())
+  H.addAngleBracketTokens(TPL->getLAngleLoc(), TPL->getRAngleLoc());
+return true;
+  }
+
+  bool VisitTagDecl(TagDecl *D) {
+for (unsigned i = 0; i < D->getNumTemplateParameterLists(); ++i) {
+  if (auto *TPL = D->getTemplateParameterList(i))
+H.addAngleBracketTokens(TPL->getLAngleLoc(), TPL->getRAngleLoc());
+}
+return true;
+  }
+
+  bool VisitClassTemplatePartialSpecializationDecl(
+  ClassTemplatePartialSpecializationDecl *D) {
+if (auto *TPL = D->getTemplateParameters())
+  H.addAngleBracketTokens(TPL->getLAngleLoc(), TPL->getRAngleLoc());
+if (auto *Args = D->getTemplateArgsAsWritten())
+  H.addAngleBracketTokens(Args->getLAngleLoc(), Args->getRAngleLoc());
+return true;
+  }
+
+  bool VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D) {
+if (auto *Args = D->getTemplateArgsInfo())
+  H.addAngleBracketTokens(Args->getLAngleLoc(), Args->getRAngleLoc());
+return true;
+  }
+
+  bool VisitVarTemplatePartialSpecializationDecl(
+

[clang] 535f34d - [index][clangd] Consider labels when indexing function bodies

2023-08-01 Thread Christian Kandeler via cfe-commits

Author: Christian Kandeler
Date: 2023-08-01T09:07:05+02:00
New Revision: 535f34dd80c2200c35971632021a5ed375774d9b

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

LOG: [index][clangd] Consider labels when indexing function bodies

It's valuable to have document highlights for labels and be able to find
references to them.

Reviewed By: nridge

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

Added: 


Modified: 
clang-tools-extra/clangd/unittests/XRefsTests.cpp
clang/lib/Index/IndexBody.cpp
clang/unittests/Index/IndexTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp 
b/clang-tools-extra/clangd/unittests/XRefsTests.cpp
index 05cf891e71db40..6d7fd62016991a 100644
--- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -125,6 +125,13 @@ TEST(HighlightsTest, All) {
   [Foo [[x]]:2 [[^y]]:4];
 }
   )cpp",
+  R"cpp( // Label
+int main() {
+  goto [[^theLabel]];
+  [[theLabel]]:
+return 1;
+}
+  )cpp",
   };
   for (const char *Test : Tests) {
 Annotations T(Test);

diff  --git a/clang/lib/Index/IndexBody.cpp b/clang/lib/Index/IndexBody.cpp
index e5f1764550ffa7..e88f321f18a712 100644
--- a/clang/lib/Index/IndexBody.cpp
+++ b/clang/lib/Index/IndexBody.cpp
@@ -144,6 +144,17 @@ class BodyIndexer : public 
RecursiveASTVisitor {
 Parent, ParentDC, Roles, Relations, E);
   }
 
+  bool VisitGotoStmt(GotoStmt *S) {
+return IndexCtx.handleReference(S->getLabel(), S->getLabelLoc(), Parent,
+ParentDC);
+  }
+
+  bool VisitLabelStmt(LabelStmt *S) {
+if (IndexCtx.shouldIndexFunctionLocalSymbols())
+  return IndexCtx.handleDecl(S->getDecl());
+return true;
+  }
+
   bool VisitMemberExpr(MemberExpr *E) {
 SourceLocation Loc = E->getMemberLoc();
 if (Loc.isInvalid())

diff  --git a/clang/unittests/Index/IndexTests.cpp 
b/clang/unittests/Index/IndexTests.cpp
index 690673a1072b00..4d19f47283c285 100644
--- a/clang/unittests/Index/IndexTests.cpp
+++ b/clang/unittests/Index/IndexTests.cpp
@@ -218,6 +218,28 @@ TEST(IndexTest, IndexParametersInDecls) {
   EXPECT_THAT(Index->Symbols, Not(Contains(QName("bar";
 }
 
+TEST(IndexTest, IndexLabels) {
+  std::string Code = R"cpp(
+int main() {
+  goto theLabel;
+  theLabel:
+return 1;
+}
+  )cpp";
+  auto Index = std::make_shared();
+  IndexingOptions Opts;
+  Opts.IndexFunctionLocals = true;
+  tooling::runToolOnCode(std::make_unique(Index, Opts), Code);
+  EXPECT_THAT(Index->Symbols,
+  Contains(AllOf(QName("theLabel"), WrittenAt(Position(3, 16)),
+ DeclAt(Position(4, 11);
+
+  Opts.IndexFunctionLocals = false;
+  Index->Symbols.clear();
+  tooling::runToolOnCode(std::make_unique(Index, Opts), Code);
+  EXPECT_THAT(Index->Symbols, Not(Contains(QName("theLabel";
+}
+
 TEST(IndexTest, IndexExplicitTemplateInstantiation) {
   std::string Code = R"cpp(
 template 



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


[clang-tools-extra] 699a59a - [clangd] Mark "override" and "final" as modifiers

2022-11-21 Thread Christian Kandeler via cfe-commits

Author: Christian Kandeler
Date: 2022-11-21T22:01:12+01:00
New Revision: 699a59aa5865d8b10f42284f68c424a9123cb8b2

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

LOG: [clangd] Mark "override" and "final" as modifiers

... in semantic highlighting.
These specifiers cannot be identified by simple lexing (since e.g.
variables with these names can legally be declared), which means they
should be semantic tokens.

Reviewed By: sammccall

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

Added: 


Modified: 
clang-tools-extra/clangd/SemanticHighlighting.cpp
clang-tools-extra/clangd/SemanticHighlighting.h
clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index dd9392b029df8..dd25a2f31230c 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -809,6 +809,18 @@ class CollectExtraHighlightings
 return true;
   }
 
+  bool VisitAttr(Attr *A) {
+switch (A->getKind()) {
+case attr::Override:
+case attr::Final:
+  H.addToken(A->getLocation(), HighlightingKind::Modifier);
+  break;
+default:
+  break;
+}
+return true;
+  }
+
   bool VisitDependentNameTypeLoc(DependentNameTypeLoc L) {
 H.addToken(L.getNameLoc(), HighlightingKind::Type)
 .addModifier(HighlightingModifier::DependentName)
@@ -985,6 +997,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
HighlightingKind K) {
 return OS << "Primitive";
   case HighlightingKind::Macro:
 return OS << "Macro";
+  case HighlightingKind::Modifier:
+return OS << "Modifier";
   case HighlightingKind::InactiveCode:
 return OS << "InactiveCode";
   }
@@ -1119,6 +1133,8 @@ llvm::StringRef toSemanticTokenType(HighlightingKind 
Kind) {
 return "type";
   case HighlightingKind::Macro:
 return "macro";
+  case HighlightingKind::Modifier:
+return "modifier";
   case HighlightingKind::InactiveCode:
 return "comment";
   }

diff  --git a/clang-tools-extra/clangd/SemanticHighlighting.h 
b/clang-tools-extra/clangd/SemanticHighlighting.h
index 64ad431909faa..e8f60c13000e1 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.h
+++ b/clang-tools-extra/clangd/SemanticHighlighting.h
@@ -49,6 +49,7 @@ enum class HighlightingKind {
   Concept,
   Primitive,
   Macro,
+  Modifier,
 
   // This one is 
diff erent from the other kinds as it's a line style
   // rather than a token style.

diff  --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp 
b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
index 3ea4a58a83a70..70d8f91f129e4 100644
--- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
@@ -864,6 +864,12 @@ sizeof...($TemplateParameter[[Elements]]);
 const char *$LocalVariable_def_readonly[[s]] = 
$LocalVariable_readonly_static[[__func__]];
 }
   )cpp",
+  // override and final
+  R"cpp(
+class $Class_def_abstract[[Base]] { virtual void 
$Method_decl_abstract_virtual[[m]]() = 0; };
+class $Class_def[[override]] : public $Class_abstract[[Base]] { void 
$Method_decl_virtual[[m]]() $Modifier[[override]]; };
+class $Class_def[[final]] : public $Class[[override]] { void 
$Method_decl_virtual[[m]]() $Modifier[[override]] $Modifier[[final]]; };
+  )cpp",
   // Issue 1222: readonly modifier for generic parameter
   R"cpp(
 template 



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


[clang-tools-extra] 008cb29 - [clangd] Renaming: Treat member functions like other functions

2023-05-22 Thread Christian Kandeler via cfe-commits

Author: Christian Kandeler
Date: 2023-05-22T12:50:38+02:00
New Revision: 008cb29f87f3af391eb6c3747bdad16f2e386161

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

LOG: [clangd] Renaming: Treat member functions like other functions

... by skipping the conflict check. The same considerations apply.

Reviewed By: hokein

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

Added: 


Modified: 
clang-tools-extra/clangd/refactor/Rename.cpp
clang-tools-extra/clangd/unittests/RenameTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/refactor/Rename.cpp 
b/clang-tools-extra/clangd/refactor/Rename.cpp
index 6362768f9b475..b3270534b13b1 100644
--- a/clang-tools-extra/clangd/refactor/Rename.cpp
+++ b/clang-tools-extra/clangd/refactor/Rename.cpp
@@ -515,7 +515,8 @@ std::optional checkName(const NamedDecl 
&RenameDecl,
   else {
 // Name conflict detection.
 // Function conflicts are subtle (overloading), so ignore them.
-if (RenameDecl.getKind() != Decl::Function) {
+if (RenameDecl.getKind() != Decl::Function &&
+RenameDecl.getKind() != Decl::CXXMethod) {
   if (auto *Conflict = lookupSiblingWithName(ASTCtx, RenameDecl, NewName))
 Result = InvalidName{
 InvalidName::Conflict,

diff  --git a/clang-tools-extra/clangd/unittests/RenameTests.cpp 
b/clang-tools-extra/clangd/unittests/RenameTests.cpp
index 5b99f8c4fc44c..9be4a970a7cfb 100644
--- a/clang-tools-extra/clangd/unittests/RenameTests.cpp
+++ b/clang-tools-extra/clangd/unittests/RenameTests.cpp
@@ -1062,6 +1062,19 @@ TEST(RenameTest, Renameable) {
   )cpp",
"conflict", !HeaderFile, "Conflict"},
 
+  {R"cpp(
+void func(int);
+void [[o^therFunc]](double);
+  )cpp",
+   nullptr, !HeaderFile, "func"},
+  {R"cpp(
+struct S {
+  void func(int);
+  void [[o^therFunc]](double);
+};
+  )cpp",
+   nullptr, !HeaderFile, "func"},
+
   {R"cpp(
 int V^ar;
   )cpp",
@@ -1121,9 +1134,7 @@ TEST(RenameTest, Renameable) {
 } else {
   EXPECT_TRUE(bool(Results)) << "rename returned an error: "
  << llvm::toString(Results.takeError());
-  ASSERT_EQ(1u, Results->GlobalChanges.size());
-  EXPECT_EQ(applyEdits(std::move(Results->GlobalChanges)).front().second,
-expectedResult(T, NewName));
+  EXPECT_EQ(Results->LocalChanges, T.ranges());
 }
   }
 }



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


[clang-tools-extra] e72baa7 - [clangd] Add semantic token for labels

2023-06-07 Thread Christian Kandeler via cfe-commits

Author: Christian Kandeler
Date: 2023-06-07T12:28:06+02:00
New Revision: e72baa76b91fbcb2b16747cb7d2088723478a754

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

LOG: [clangd] Add semantic token for labels

Reviewed By: kadircet

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

Added: 


Modified: 
clang-tools-extra/clangd/SemanticHighlighting.cpp
clang-tools-extra/clangd/SemanticHighlighting.h
clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index ec37476cf94ea..6a835f31f064b 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -166,6 +166,8 @@ std::optional kindForDecl(const NamedDecl 
*D,
 return HighlightingKind::TemplateParameter;
   if (isa(D))
 return HighlightingKind::Concept;
+  if (isa(D))
+return HighlightingKind::Label;
   if (const auto *UUVD = dyn_cast(D)) {
 auto Targets = Resolver->resolveUsingValueDecl(UUVD);
 if (!Targets.empty() && Targets[0] != UUVD) {
@@ -1271,6 +1273,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
HighlightingKind K) {
 return OS << "Operator";
   case HighlightingKind::Bracket:
 return OS << "Bracket";
+  case HighlightingKind::Label:
+return OS << "Label";
   case HighlightingKind::InactiveCode:
 return OS << "InactiveCode";
   }
@@ -1470,6 +1474,8 @@ llvm::StringRef toSemanticTokenType(HighlightingKind 
Kind) {
 return "operator";
   case HighlightingKind::Bracket:
 return "bracket";
+  case HighlightingKind::Label:
+return "label";
   case HighlightingKind::InactiveCode:
 return "comment";
   }

diff  --git a/clang-tools-extra/clangd/SemanticHighlighting.h 
b/clang-tools-extra/clangd/SemanticHighlighting.h
index c9db598ff08c9..59d742b83ee52 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.h
+++ b/clang-tools-extra/clangd/SemanticHighlighting.h
@@ -52,6 +52,7 @@ enum class HighlightingKind {
   Modifier,
   Operator,
   Bracket,
+  Label,
 
   // This one is 
diff erent from the other kinds as it's a line style
   // rather than a token style.

diff  --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp 
b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
index 9c6e5246f5c37..ff052e6be9549 100644
--- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
@@ -1028,6 +1028,16 @@ sizeof...($TemplateParameter[[Elements]]);
 template $Bracket[[<]]$Concept[[C2]]$Bracket[[<]]int$Bracket[[>]] 
$TemplateParameter_def[[A]]$Bracket[[>]]
 class $Class_def[[B]] {};
   )cpp",
+  // Labels
+  R"cpp(
+bool $Function_def[[funcWithGoto]](bool $Parameter_def[[b]]) {
+  if ($Parameter[[b]])
+goto $Label[[return_true]];
+  return false;
+  $Label_decl[[return_true]]:
+return true;
+}
+  )cpp",
   // no crash
   R"cpp(
 struct $Class_def[[Foo]] {



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


[clang-tools-extra] 647d314 - [clangd] Add support for semantic token type "operator"

2022-12-12 Thread Christian Kandeler via cfe-commits

Author: Christian Kandeler
Date: 2022-12-12T16:17:43+01:00
New Revision: 647d314eb059b6d2e7c00d7eefe6a7afc37dff25

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

LOG: [clangd] Add support for semantic token type "operator"

Also add new modifier for differentiating between built-in and user-
provided operators.

Reviewed By: sammccall

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

Added: 


Modified: 
clang-tools-extra/clangd/SemanticHighlighting.cpp
clang-tools-extra/clangd/SemanticHighlighting.h
clang-tools-extra/clangd/test/initialize-params.test
clang-tools-extra/clangd/test/semantic-tokens.test
clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index ccdaab89620b2..6745e2594ead3 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -566,6 +566,71 @@ class CollectExtraHighlightings
 return true;
   }
 
+  bool VisitFunctionDecl(FunctionDecl *D) {
+if (D->isOverloadedOperator()) {
+  const auto addOpDeclToken = [&](SourceLocation Loc) {
+auto &Token = H.addToken(Loc, HighlightingKind::Operator)
+  .addModifier(HighlightingModifier::Declaration);
+if (D->isThisDeclarationADefinition())
+  Token.addModifier(HighlightingModifier::Definition);
+  };
+  const auto Range = D->getNameInfo().getCXXOperatorNameRange();
+  addOpDeclToken(Range.getBegin());
+  const auto Kind = D->getOverloadedOperator();
+  if (Kind == OO_Call || Kind == OO_Subscript)
+addOpDeclToken(Range.getEnd());
+}
+return true;
+  }
+
+  bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+const auto addOpToken = [&](SourceLocation Loc) {
+  H.addToken(Loc, HighlightingKind::Operator)
+  .addModifier(HighlightingModifier::UserDefined);
+};
+addOpToken(E->getOperatorLoc());
+const auto Kind = E->getOperator();
+if (Kind == OO_Call || Kind == OO_Subscript) {
+  if (auto *Callee = E->getCallee())
+addOpToken(Callee->getBeginLoc());
+}
+return true;
+  }
+
+  bool VisitUnaryOperator(UnaryOperator *Op) {
+auto &Token = H.addToken(Op->getOperatorLoc(), HighlightingKind::Operator);
+if (Op->getSubExpr()->isTypeDependent())
+  Token.addModifier(HighlightingModifier::UserDefined);
+return true;
+  }
+
+  bool VisitBinaryOperator(BinaryOperator *Op) {
+auto &Token = H.addToken(Op->getOperatorLoc(), HighlightingKind::Operator);
+if (Op->getLHS()->isTypeDependent() || Op->getRHS()->isTypeDependent())
+  Token.addModifier(HighlightingModifier::UserDefined);
+return true;
+  }
+
+  bool VisitConditionalOperator(ConditionalOperator *Op) {
+H.addToken(Op->getQuestionLoc(), HighlightingKind::Operator);
+H.addToken(Op->getColonLoc(), HighlightingKind::Operator);
+return true;
+  }
+
+  bool VisitCXXNewExpr(CXXNewExpr *E) {
+auto &Token = H.addToken(E->getBeginLoc(), HighlightingKind::Operator);
+if (isa(E->getOperatorNew()))
+  Token.addModifier(HighlightingModifier::UserDefined);
+return true;
+  }
+
+  bool VisitCXXDeleteExpr(CXXDeleteExpr *E) {
+auto &Token = H.addToken(E->getBeginLoc(), HighlightingKind::Operator);
+if (isa(E->getOperatorDelete()))
+  Token.addModifier(HighlightingModifier::UserDefined);
+return true;
+  }
+
   bool VisitCallExpr(CallExpr *E) {
 // Highlighting parameters passed by non-const reference does not really
 // make sense for literals...
@@ -671,12 +736,20 @@ class CollectExtraHighlightings
   bool VisitCXXMemberCallExpr(CXXMemberCallExpr *CE) {
 // getMethodDecl can return nullptr with member pointers, e.g.
 // `(foo.*pointer_to_member_fun)(arg);`
-if (isa_and_present(CE->getMethodDecl())) {
-  if (auto *ME = dyn_cast(CE->getCallee())) {
-if (auto *TI = ME->getMemberNameInfo().getNamedTypeInfo()) {
-  H.addExtraModifier(TI->getTypeLoc().getBeginLoc(),
- HighlightingModifier::ConstructorOrDestructor);
+if (auto *D = CE->getMethodDecl()) {
+  if (isa(D)) {
+if (auto *ME = dyn_cast(CE->getCallee())) {
+  if (auto *TI = ME->getMemberNameInfo().getNamedTypeInfo()) {
+H.addExtraModifier(TI->getTypeLoc().getBeginLoc(),
+   HighlightingModifier::ConstructorOrDestructor);
+  }
 }
+  } else if (D->isOverloadedOperator()) {
+if (auto *ME = dyn_cast(CE->getCallee()))
+  H.addToken(
+   ME->getMemberNameInfo().getCXXOperatorNameRange().getBegin(),
+   Highlight

[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-02-19 Thread Christian Kandeler via cfe-commits


@@ -490,6 +491,13 @@ bool eligibleForExtraction(const SelectionTree::Node *N) {
 BO->getRHS() == OuterImplicit.ASTNode.get())
   return false;
   }
+  if (const auto *Decl = Parent->ASTNode.get()) {
+if (!Decl->isInitCapture() &&

ckandeler wrote:

> For this case in particular, even if you said the refactoring is available 
> for selection of `x = 1 + [[2 + 3]]` through 
> these heuristics, clangd will still end up extracting the full RHS, because 
> that's the AST node we associated with that 
> selection.

I'm not sure I follow. In the example given above, invoking the tweak on the 
selection results in:
```
auto placeholder = 2 + 3;
int x = 1 + placeholder;
```
Which is exactly what I (the user) wanted. Am I misunderstanding something?

https://github.com/llvm/llvm-project/pull/69477
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-02-19 Thread Christian Kandeler via cfe-commits


@@ -490,6 +491,13 @@ bool eligibleForExtraction(const SelectionTree::Node *N) {
 BO->getRHS() == OuterImplicit.ASTNode.get())
   return false;
   }
+  if (const auto *Decl = Parent->ASTNode.get()) {
+if (!Decl->isInitCapture() &&

ckandeler wrote:

> * "end":{"character":18,"

But that's [[2 + ]]3, no? I get an end character position of 19 with both Qt 
Creator and VSCode for the [[2 + 3]] selection.

https://github.com/llvm/llvm-project/pull/69477
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-02-19 Thread Christian Kandeler via cfe-commits


@@ -490,6 +491,13 @@ bool eligibleForExtraction(const SelectionTree::Node *N) {
 BO->getRHS() == OuterImplicit.ASTNode.get())
   return false;
   }
+  if (const auto *Decl = Parent->ASTNode.get()) {
+if (!Decl->isInitCapture() &&

ckandeler wrote:

Note also that there are already (pre-existing) tests for such selections, e.g.:
```
  {R"cpp(void f() {
   int x = 1 + 2 + [[3 + 4 + 5]];
 })cpp",
   R"cpp(void f() {
   auto placeholder = 3 + 4 + 5; int x = 1 + 2 + placeholder;
 })cpp"},
```

https://github.com/llvm/llvm-project/pull/69477
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)

2024-02-19 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler closed 
https://github.com/llvm/llvm-project/pull/69477
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-09 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/67802

>From 80e15f748b30d4e977b58a42d8fd4403234bb954 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Fri, 29 Sep 2023 15:01:58 +0200
Subject: [PATCH] [clangd] Collect comments from function definitions into the
 index

This is useful with projects that put their (doxygen) comments at the
implementation site, rather than the header.
---
 clang-tools-extra/clangd/index/Symbol.h   |  4 +-
 .../clangd/index/SymbolCollector.cpp  | 42 +++
 .../clangd/index/SymbolCollector.h|  3 +-
 .../clangd/unittests/SymbolCollectorTests.cpp | 20 +
 clang/lib/AST/ASTContext.cpp  | 11 -
 5 files changed, 69 insertions(+), 11 deletions(-)

diff --git a/clang-tools-extra/clangd/index/Symbol.h 
b/clang-tools-extra/clangd/index/Symbol.h
index 1aa5265299231b..62c47ddfc5758d 100644
--- a/clang-tools-extra/clangd/index/Symbol.h
+++ b/clang-tools-extra/clangd/index/Symbol.h
@@ -145,9 +145,11 @@ struct Symbol {
 ImplementationDetail = 1 << 2,
 /// Symbol is visible to other files (not e.g. a static helper function).
 VisibleOutsideFile = 1 << 3,
+/// Symbol has an attached documentation comment.
+HasDocComment = 1 << 4
   };
-
   SymbolFlag Flags = SymbolFlag::None;
+
   /// FIXME: also add deprecation message and fixit?
 };
 
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp 
b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index 5c4e2150cf3123..d3df6a26fd9365 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -635,17 +635,20 @@ bool SymbolCollector::handleDeclOccurrence(
 return true;
 
   const Symbol *BasicSymbol = Symbols.find(ID);
-  if (isPreferredDeclaration(*OriginalDecl, Roles))
+  bool SkipDocCheckInDef = false;
+  if (isPreferredDeclaration(*OriginalDecl, Roles)) {
 // If OriginalDecl is preferred, replace/create the existing canonical
 // declaration (e.g. a class forward declaration). There should be at most
 // one duplicate as we expect to see only one preferred declaration per
 // TU, because in practice they are definitions.
 BasicSymbol = addDeclaration(*OriginalDecl, std::move(ID), IsMainFileOnly);
-  else if (!BasicSymbol || DeclIsCanonical)
+SkipDocCheckInDef = true;
+  } else if (!BasicSymbol || DeclIsCanonical) {
 BasicSymbol = addDeclaration(*ND, std::move(ID), IsMainFileOnly);
+  }
 
   if (Roles & static_cast(index::SymbolRole::Definition))
-addDefinition(*OriginalDecl, *BasicSymbol);
+addDefinition(*OriginalDecl, *BasicSymbol, SkipDocCheckInDef);
 
   return true;
 }
@@ -1025,15 +1028,17 @@ const Symbol *SymbolCollector::addDeclaration(const 
NamedDecl &ND, SymbolID ID,
   *ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
   *CompletionTUInfo,
   /*IncludeBriefComments*/ false);
-  std::string Documentation =
-  formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion,
-  /*CommentsFromHeaders=*/true));
+  std::string DocComment = getDocComment(Ctx, SymbolCompletion,
+ /*CommentsFromHeaders=*/true);
+  std::string Documentation = formatDocumentation(*CCS, DocComment);
   if (!(S.Flags & Symbol::IndexedForCodeCompletion)) {
 if (Opts.StoreAllDocumentation)
   S.Documentation = Documentation;
 Symbols.insert(S);
 return Symbols.find(S.ID);
   }
+  if (!DocComment.empty())
+S.Flags |= Symbol::HasDocComment;
   S.Documentation = Documentation;
   std::string Signature;
   std::string SnippetSuffix;
@@ -1058,8 +1063,8 @@ const Symbol *SymbolCollector::addDeclaration(const 
NamedDecl &ND, SymbolID ID,
   return Symbols.find(S.ID);
 }
 
-void SymbolCollector::addDefinition(const NamedDecl &ND,
-const Symbol &DeclSym) {
+void SymbolCollector::addDefinition(const NamedDecl &ND, const Symbol &DeclSym,
+bool SkipDocCheck) {
   if (DeclSym.Definition)
 return;
   const auto &SM = ND.getASTContext().getSourceManager();
@@ -1074,6 +1079,27 @@ void SymbolCollector::addDefinition(const NamedDecl &ND,
   Symbol S = DeclSym;
   // FIXME: use the result to filter out symbols.
   S.Definition = *DefLoc;
+
+  std::string DocComment;
+  std::string Documentation;
+  if (!SkipDocCheck && !(S.Flags & Symbol::HasDocComment) &&
+  (llvm::isa(ND) || llvm::isa(ND))) {
+CodeCompletionResult SymbolCompletion(&getTemplateOrThis(ND), 0);
+const auto *CCS = SymbolCompletion.CreateCodeCompletionString(
+*ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
+*CompletionTUInfo,
+/*IncludeBriefComments*/ false);
+DocComment = getDocComment(ND.getASTContext(), SymbolCompletion,
+   /*CommentsFromHeaders=*/true);
+if (!S.Documentation.emp

[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-09 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

> At this point, my main feedback is that it would be good to include some unit 
> tests. `SymbolCollectorTests.cpp` is a good 
> place for them.

I've added a new test and verified that it fails without this patch.

> What is the purpose of the change to `ASTContext.cpp`? 

There was some assumption about the order of redeclarations that did not match 
reality, like that the definition always comes first or something along those 
lines. I do not know whether the assumption there was wrong or whether some 
other code messed up by breaking it. 

> This codepath has consumers other than clangd, so if we're changing the 
> behaviour, we need to evaluate whether it's 
> appropriate for other consumers (and maybe add libAST unit tests as well).

Hence my original comment. Though it should be noted that no existing tests 
appear to have been broken.

https://github.com/llvm/llvm-project/pull/67802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-09 Thread Christian Kandeler via cfe-commits


@@ -1069,6 +1071,27 @@ void SymbolCollector::addDefinition(const NamedDecl &ND,
   Symbol S = DeclSym;
   // FIXME: use the result to filter out symbols.
   S.Definition = *DefLoc;
+
+  std::string DocComment;
+  std::string Documentation;
+  if (!(S.Flags & Symbol::HasDocComment) &&

ckandeler wrote:

Done.

https://github.com/llvm/llvm-project/pull/67802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-11 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

> I wrote a libAST unit test to demonstrate the bug, and filed #108145 about 
> it. Hopefully folks more familiar with that code can suggest an appropriate 
> fix there.

Awesome, thanks.

https://github.com/llvm/llvm-project/pull/67802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-11 Thread Christian Kandeler via cfe-commits


@@ -1477,6 +1477,26 @@ TEST_F(SymbolCollectorTest, Documentation) {
 forCodeCompletion(false;
 }
 
+TEST_F(SymbolCollectorTest, DocumentationInMain) {

ckandeler wrote:

Hm, do we really want to specify a behavior there? My thinking was that the 
comment should be at either the declaration or the definition and otherwise one 
of them gets chosen at random, depending on the parse order. I suppose one 
could also cook up some elaborated merging scheme, but that seems like overkill.

https://github.com/llvm/llvm-project/pull/67802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-04-08 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

ping

https://github.com/llvm/llvm-project/pull/67802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2024-04-08 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

ping

https://github.com/llvm/llvm-project/pull/69704
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Let DefineOutline tweak handle member functions (PR #95235)

2024-06-12 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler created 
https://github.com/llvm/llvm-project/pull/95235

... of class templates.

>From fc3a907ab2550a999801d37400268fdc31df054d Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Tue, 14 Nov 2023 16:35:46 +0100
Subject: [PATCH] [clangd] Let DefineOutline tweak handle member functions

... of class templates.
---
 clang-tools-extra/clangd/AST.cpp  |  7 ++-
 .../clangd/refactor/tweaks/DefineOutline.cpp  | 47 ++--
 .../unittests/tweaks/DefineOutlineTests.cpp   | 55 ++-
 3 files changed, 89 insertions(+), 20 deletions(-)

diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index fda1e5fdf8d82..2f2f8437d6ed9 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -144,8 +144,13 @@ getQualification(ASTContext &Context, const DeclContext 
*DestContext,
   // since we stored inner-most parent first.
   std::string Result;
   llvm::raw_string_ostream OS(Result);
-  for (const auto *Parent : llvm::reverse(Parents))
+  for (const auto *Parent : llvm::reverse(Parents)) {
+if (Parent != *Parents.rbegin() && Parent->isDependent() &&
+Parent->getAsRecordDecl() &&
+Parent->getAsRecordDecl()->getDescribedClassTemplate())
+  OS << "template ";
 Parent->print(OS, Context.getPrintingPolicy());
+  }
   return OS.str();
 }
 
diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index f43f2417df8fc..15cb586e6c21e 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -128,7 +128,27 @@ getFunctionSourceAfterReplacements(const FunctionDecl *FD,
   SM.getBufferData(SM.getMainFileID()), Replacements);
   if (!QualifiedFunc)
 return QualifiedFunc.takeError();
-  return QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1);
+
+  std::string TemplatePrefix;
+  if (auto *MD = llvm::dyn_cast(FD)) {
+for (const CXXRecordDecl *Parent = MD->getParent(); Parent;
+ Parent =
+ llvm::dyn_cast_or_null(Parent->getParent())) 
{
+  if (auto Params = Parent->getDescribedTemplateParams()) {
+std::string S;
+llvm::raw_string_ostream Stream(S);
+Params->print(Stream, FD->getASTContext());
+if (!S.empty())
+  *S.rbegin() = '\n'; // Replace space with newline
+TemplatePrefix.insert(0, S);
+  }
+}
+  }
+
+  auto Source = QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1);
+  if (!TemplatePrefix.empty())
+Source.insert(0, TemplatePrefix);
+  return Source;
 }
 
 // Returns replacements to delete tokens with kind `Kind` in the range
@@ -212,9 +232,13 @@ getFunctionSourceCode(const FunctionDecl *FD, const 
DeclContext *TargetContext,
   }
 }
 const NamedDecl *ND = Ref.Targets.front();
-const std::string Qualifier =
+std::string Qualifier =
 getQualification(AST, TargetContext,
  SM.getLocForStartOfFile(SM.getMainFileID()), ND);
+if (ND->getDeclContext()->isDependentContext()) {
+  if (llvm::isa(ND))
+Qualifier.insert(0, "typename ");
+}
 if (auto Err = DeclarationCleanups.add(
 tooling::Replacement(SM, Ref.NameLoc, 0, Qualifier)))
   Errors = llvm::joinErrors(std::move(Errors), std::move(Err));
@@ -407,10 +431,21 @@ class DefineOutline : public Tweak {
   return !SameFile;
 }
 
-// Bail out in templated classes, as it is hard to spell the class name,
-// i.e if the template parameter is unnamed.
-if (MD->getParent()->isTemplated())
-  return false;
+for (const CXXRecordDecl *Parent = MD->getParent(); Parent;
+ Parent =
+ llvm::dyn_cast_or_null(Parent->getParent())) 
{
+  if (auto Params = Parent->getDescribedTemplateParams()) {
+
+// Class template member functions must be defined in the
+// same file.
+SameFile = true;
+
+for (NamedDecl *P : *Params) {
+  if (!P->getIdentifier())
+return false;
+}
+  }
+}
 
 // The refactoring is meaningless for unnamed classes and namespaces,
 // unless we're outlining in the same file
diff --git a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp 
b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
index 906ff33db8734..6a9e90c3bfa70 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
@@ -105,8 +105,8 @@ TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
   F^oo(const Foo&) = delete;
 };)cpp");
 
-  // Not available within templated classes, as it is hard to spell class name
-  // out-of-line in such cases.
+  // Not available within templated classes with unnamed parameters, as it is
+  

[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2024-06-03 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

I'm going to merge this without explicit format approval based on the following:
  - There was a general LGTM.
  - I addressed the remaining issues.
  - There was no further feedback for more than half a year.

https://github.com/llvm/llvm-project/pull/69704
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2024-06-03 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler closed 
https://github.com/llvm/llvm-project/pull/69704
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Remove potential prefix from enum value names (PR #83412)

2024-04-15 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/83412

>From 78393d26e62f2f9a30f366501f8e61b1a32d6af4 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Thu, 29 Feb 2024 12:26:52 +0100
Subject: [PATCH] [clangd] Remove potential prefix from enum value names

... when converting unscoped to scoped enums.
With traditional enums, a popular technique to guard against potential
name clashes is to use the enum name as a pseudo-namespace, like this:
  enum MyEnum { MyEnumValue1, MyEnumValue2 };
With scoped enums, this makes no sense, making it extremely unlikely
that the user wants to keep such a prefix when modernizing. Therefore, our
tweak now removes it.
---
 .../clangd/refactor/tweaks/ScopifyEnum.cpp| 55 +--
 .../unittests/tweaks/ScopifyEnumTests.cpp | 38 +++--
 clang-tools-extra/docs/ReleaseNotes.rst   |  3 +
 3 files changed, 74 insertions(+), 22 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
index e36b3249bc7b92..d44f2bb862ed07 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
@@ -40,15 +40,12 @@ namespace {
 ///   void f() { E e1 = EV1; }
 ///
 /// After:
-///   enum class E { EV1, EV2 };
-///   void f() { E e1 = E::EV1; }
+///   enum class E { V1, V2 };
+///   void f() { E e1 = E::V1; }
 ///
 /// Note that the respective project code might not compile anymore
 /// if it made use of the now-gone implicit conversion to int.
 /// This is out of scope for this tweak.
-///
-/// TODO: In the above example, we could detect that the values
-///   start with the enum name, and remove that prefix.
 
 class ScopifyEnum : public Tweak {
   const char *id() const final;
@@ -63,7 +60,8 @@ class ScopifyEnum : public Tweak {
   std::function;
   llvm::Error addClassKeywordToDeclarations();
   llvm::Error scopifyEnumValues();
-  llvm::Error scopifyEnumValue(const EnumConstantDecl &CD, StringRef Prefix);
+  llvm::Error scopifyEnumValue(const EnumConstantDecl &CD, StringRef EnumName,
+   bool StripPrefix);
   llvm::Expected getContentForFile(StringRef FilePath);
   unsigned getOffsetFromPosition(const Position &Pos, StringRef Content) const;
   llvm::Error addReplacementForReference(const ReferencesResult::Reference 
&Ref,
@@ -125,25 +123,42 @@ llvm::Error ScopifyEnum::addClassKeywordToDeclarations() {
 }
 
 llvm::Error ScopifyEnum::scopifyEnumValues() {
-  std::string PrefixToInsert(D->getName());
-  PrefixToInsert += "::";
-  for (auto E : D->enumerators()) {
-if (auto Err = scopifyEnumValue(*E, PrefixToInsert))
+  StringRef EnumName(D->getName());
+  bool StripPrefix = true;
+  for (const EnumConstantDecl *E : D->enumerators()) {
+if (!E->getName().starts_with(EnumName)) {
+  StripPrefix = false;
+  break;
+}
+  }
+  for (const EnumConstantDecl *E : D->enumerators()) {
+if (auto Err = scopifyEnumValue(*E, EnumName, StripPrefix))
   return Err;
   }
   return llvm::Error::success();
 }
 
 llvm::Error ScopifyEnum::scopifyEnumValue(const EnumConstantDecl &CD,
-  StringRef Prefix) {
+  StringRef EnumName,
+  bool StripPrefix) {
   for (const auto &Ref :
findReferences(*S->AST, getPosition(CD), 0, S->Index, false)
.References) {
-if (Ref.Attributes & ReferencesResult::Declaration)
+if (Ref.Attributes & ReferencesResult::Declaration) {
+  if (StripPrefix) {
+const auto MakeReplacement = [&EnumName](StringRef FilePath,
+ StringRef /* Content */,
+ unsigned Offset) {
+  return tooling::Replacement(FilePath, Offset, EnumName.size(), {});
+};
+if (auto Err = addReplacementForReference(Ref, MakeReplacement))
+  return Err;
+  }
   continue;
+}
 
-const auto MakeReplacement = [&Prefix](StringRef FilePath,
-   StringRef Content, unsigned Offset) 
{
+const auto MakeReplacement = [&](StringRef FilePath, StringRef Content,
+ unsigned Offset) {
   const auto IsAlreadyScoped = [Content, Offset] {
 if (Offset < 2)
   return false;
@@ -164,9 +179,15 @@ llvm::Error ScopifyEnum::scopifyEnumValue(const 
EnumConstantDecl &CD,
 }
 return false;
   };
-  return IsAlreadyScoped()
- ? tooling::Replacement()
- : tooling::Replacement(FilePath, Offset, 0, Prefix);
+  if (StripPrefix) {
+if (IsAlreadyScoped())
+  return tooling::Replacement(FilePath, Offset, EnumName.size(), {});
+return tooling::Replacement(FilePath, Offset + EnumName.size(), 0,
+ 

[clang-tools-extra] [clangd] Remove potential prefix from enum value names (PR #83412)

2024-04-15 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

Incorporated review comments.

https://github.com/llvm/llvm-project/pull/83412
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] use existing function for code locations in the scopify enum tweak (PR #88737)

2024-04-15 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler approved this pull request.


https://github.com/llvm/llvm-project/pull/88737
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Let DefineOutline tweak create a definition from scratch (PR #71950)

2024-04-18 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

We should probably rekindle the discussion on the associated bug report; I 
think users (rightly) expect this feature.

https://github.com/llvm/llvm-project/pull/71950
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Remove potential prefix from enum value names (PR #83412)

2024-05-02 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/83412

>From 349edc160e9c13068c42b35321814296bb713a09 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Thu, 29 Feb 2024 12:26:52 +0100
Subject: [PATCH] [clangd] Remove potential prefix from enum value names

... when converting unscoped to scoped enums.
With traditional enums, a popular technique to guard against potential
name clashes is to use the enum name as a pseudo-namespace, like this:
  enum MyEnum { MyEnumValue1, MyEnumValue2 };
With scoped enums, this makes no sense, making it extremely unlikely
that the user wants to keep such a prefix when modernizing. Therefore, our
tweak now removes it.
---
 .../clangd/refactor/tweaks/ScopifyEnum.cpp| 61 -
 .../unittests/tweaks/ScopifyEnumTests.cpp | 66 +--
 clang-tools-extra/docs/ReleaseNotes.rst   |  3 +
 3 files changed, 108 insertions(+), 22 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
index e36b3249bc7b92..2be2bbc422af75 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
@@ -40,15 +40,12 @@ namespace {
 ///   void f() { E e1 = EV1; }
 ///
 /// After:
-///   enum class E { EV1, EV2 };
-///   void f() { E e1 = E::EV1; }
+///   enum class E { V1, V2 };
+///   void f() { E e1 = E::V1; }
 ///
 /// Note that the respective project code might not compile anymore
 /// if it made use of the now-gone implicit conversion to int.
 /// This is out of scope for this tweak.
-///
-/// TODO: In the above example, we could detect that the values
-///   start with the enum name, and remove that prefix.
 
 class ScopifyEnum : public Tweak {
   const char *id() const final;
@@ -63,7 +60,8 @@ class ScopifyEnum : public Tweak {
   std::function;
   llvm::Error addClassKeywordToDeclarations();
   llvm::Error scopifyEnumValues();
-  llvm::Error scopifyEnumValue(const EnumConstantDecl &CD, StringRef Prefix);
+  llvm::Error scopifyEnumValue(const EnumConstantDecl &CD, StringRef EnumName,
+   bool StripPrefix);
   llvm::Expected getContentForFile(StringRef FilePath);
   unsigned getOffsetFromPosition(const Position &Pos, StringRef Content) const;
   llvm::Error addReplacementForReference(const ReferencesResult::Reference 
&Ref,
@@ -125,25 +123,45 @@ llvm::Error ScopifyEnum::addClassKeywordToDeclarations() {
 }
 
 llvm::Error ScopifyEnum::scopifyEnumValues() {
-  std::string PrefixToInsert(D->getName());
-  PrefixToInsert += "::";
-  for (auto E : D->enumerators()) {
-if (auto Err = scopifyEnumValue(*E, PrefixToInsert))
+  StringRef EnumName(D->getName());
+  bool StripPrefix = true;
+  for (const EnumConstantDecl *E : D->enumerators()) {
+if (!E->getName().starts_with(EnumName)) {
+  StripPrefix = false;
+  break;
+}
+  }
+  for (const EnumConstantDecl *E : D->enumerators()) {
+if (auto Err = scopifyEnumValue(*E, EnumName, StripPrefix))
   return Err;
   }
   return llvm::Error::success();
 }
 
 llvm::Error ScopifyEnum::scopifyEnumValue(const EnumConstantDecl &CD,
-  StringRef Prefix) {
+  StringRef EnumName,
+  bool StripPrefix) {
   for (const auto &Ref :
findReferences(*S->AST, getPosition(CD), 0, S->Index, false)
.References) {
-if (Ref.Attributes & ReferencesResult::Declaration)
+if (Ref.Attributes & ReferencesResult::Declaration) {
+  if (StripPrefix) {
+const auto MakeReplacement = [&EnumName](StringRef FilePath,
+ StringRef Content,
+ unsigned Offset) {
+  unsigned Length = EnumName.size();
+  if (Content[Offset + Length] == '_')
+++Length;
+  return tooling::Replacement(FilePath, Offset, Length, {});
+};
+if (auto Err = addReplacementForReference(Ref, MakeReplacement))
+  return Err;
+  }
   continue;
+}
 
-const auto MakeReplacement = [&Prefix](StringRef FilePath,
-   StringRef Content, unsigned Offset) 
{
+const auto MakeReplacement = [&](StringRef FilePath, StringRef Content,
+ unsigned Offset) {
   const auto IsAlreadyScoped = [Content, Offset] {
 if (Offset < 2)
   return false;
@@ -164,9 +182,18 @@ llvm::Error ScopifyEnum::scopifyEnumValue(const 
EnumConstantDecl &CD,
 }
 return false;
   };
-  return IsAlreadyScoped()
- ? tooling::Replacement()
- : tooling::Replacement(FilePath, Offset, 0, Prefix);
+  if (StripPrefix) {
+const int ExtraLength =
+Content[Offset + EnumName.size()] == '_' ? 1 : 0

[clang-tools-extra] [clangd] Remove potential prefix from enum value names (PR #83412)

2024-05-02 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

Underscore separators get removed now.

https://github.com/llvm/llvm-project/pull/83412
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Remove potential prefix from enum value names (PR #83412)

2024-05-02 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler closed 
https://github.com/llvm/llvm-project/pull/83412
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Remove potential prefix from enum value names (PR #83412)

2024-05-02 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler reopened 
https://github.com/llvm/llvm-project/pull/83412
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Remove potential prefix from enum value names (PR #83412)

2024-05-02 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler closed 
https://github.com/llvm/llvm-project/pull/83412
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Allow "move function body out-of-line" in non-header files (PR #69704)

2024-05-02 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

ping

https://github.com/llvm/llvm-project/pull/69704
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-05-02 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

ping

https://github.com/llvm/llvm-project/pull/67802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Support callHierarchy/outgoingCalls (PR #91191)

2024-05-06 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler created 
https://github.com/llvm/llvm-project/pull/91191

None

>From d7cfeb6599fd507eed8935e452efd782fc3f0481 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Tue, 30 Apr 2024 18:20:05 +0200
Subject: [PATCH] [clangd] Support callHierarchy/outgoingCalls

---
 clang-tools-extra/clangd/ClangdLSPServer.cpp  |   7 +
 clang-tools-extra/clangd/ClangdLSPServer.h|   3 +
 clang-tools-extra/clangd/ClangdServer.cpp |  13 +
 clang-tools-extra/clangd/ClangdServer.h   |   4 +
 clang-tools-extra/clangd/XRefs.cpp|  71 ++
 clang-tools-extra/clangd/XRefs.h  |   3 +
 .../clangd/unittests/CallHierarchyTests.cpp   | 226 +++---
 7 files changed, 293 insertions(+), 34 deletions(-)

diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp 
b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 7fd599d4e1a0b0..5820a644088e3e 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -1368,6 +1368,12 @@ void ClangdLSPServer::onCallHierarchyIncomingCalls(
   Server->incomingCalls(Params.item, std::move(Reply));
 }
 
+void ClangdLSPServer::onCallHierarchyOutgoingCalls(
+const CallHierarchyOutgoingCallsParams &Params,
+Callback> Reply) {
+  Server->outgoingCalls(Params.item, std::move(Reply));
+}
+
 void ClangdLSPServer::onClangdInlayHints(const InlayHintsParams &Params,
  Callback Reply) {
   // Our extension has a different representation on the wire than the 
standard.
@@ -1688,6 +1694,7 @@ void ClangdLSPServer::bindMethods(LSPBinder &Bind,
   Bind.method("typeHierarchy/subtypes", this, &ClangdLSPServer::onSubTypes);
   Bind.method("textDocument/prepareCallHierarchy", this, 
&ClangdLSPServer::onPrepareCallHierarchy);
   Bind.method("callHierarchy/incomingCalls", this, 
&ClangdLSPServer::onCallHierarchyIncomingCalls);
+  Bind.method("callHierarchy/outgoingCalls", this, 
&ClangdLSPServer::onCallHierarchyOutgoingCalls);
   Bind.method("textDocument/selectionRange", this, 
&ClangdLSPServer::onSelectionRange);
   Bind.method("textDocument/documentLink", this, 
&ClangdLSPServer::onDocumentLink);
   Bind.method("textDocument/semanticTokens/full", this, 
&ClangdLSPServer::onSemanticTokens);
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h 
b/clang-tools-extra/clangd/ClangdLSPServer.h
index 8bcb29522509b7..4981027372cb57 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.h
+++ b/clang-tools-extra/clangd/ClangdLSPServer.h
@@ -153,6 +153,9 @@ class ClangdLSPServer : private ClangdServer::Callbacks,
   void onCallHierarchyIncomingCalls(
   const CallHierarchyIncomingCallsParams &,
   Callback>);
+  void onCallHierarchyOutgoingCalls(
+  const CallHierarchyOutgoingCallsParams &,
+  Callback>);
   void onClangdInlayHints(const InlayHintsParams &,
   Callback);
   void onInlayHint(const InlayHintsParams &, Callback>);
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index 1c4c2a79b5c051..19d01dfbd873e2 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -898,6 +898,19 @@ void ClangdServer::incomingCalls(
  });
 }
 
+void ClangdServer::outgoingCalls(
+const CallHierarchyItem &Item,
+Callback> CB) {
+  auto Action = [Item,
+ CB = std::move(CB)](Expected InpAST) mutable {
+if (!InpAST)
+  return CB(InpAST.takeError());
+CB(clangd::outgoingCalls(InpAST->AST, Item));
+  };
+  WorkScheduler->runWithAST("Outgoing Calls", Item.uri.file(),
+std::move(Action));
+}
+
 void ClangdServer::inlayHints(PathRef File, std::optional RestrictRange,
   Callback> CB) {
   auto Action = [RestrictRange(std::move(RestrictRange)),
diff --git a/clang-tools-extra/clangd/ClangdServer.h 
b/clang-tools-extra/clangd/ClangdServer.h
index 1661028be88b4e..4caef917c1ec16 100644
--- a/clang-tools-extra/clangd/ClangdServer.h
+++ b/clang-tools-extra/clangd/ClangdServer.h
@@ -288,6 +288,10 @@ class ClangdServer {
   void incomingCalls(const CallHierarchyItem &Item,
  Callback>);
 
+  /// Resolve outgoing calls for a given call hierarchy item.
+  void outgoingCalls(const CallHierarchyItem &Item,
+ Callback>);
+
   /// Resolve inlay hints for a given document.
   void inlayHints(PathRef File, std::optional RestrictRange,
   Callback>);
diff --git a/clang-tools-extra/clangd/XRefs.cpp 
b/clang-tools-extra/clangd/XRefs.cpp
index cd909266489a85..b9bf944a7bba98 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -42,6 +42,7 @@
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/Type.h"
+#include "clang/Analysis/CallGraph.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/

[clang-tools-extra] [clangd] Support callHierarchy/outgoingCalls (PR #91191)

2024-05-06 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler closed 
https://github.com/llvm/llvm-project/pull/91191
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Support callHierarchy/outgoingCalls (PR #91191)

2024-05-06 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

> I remembered @HighCommander4 had filed a similar PR at #77556. Is this one 
> separate, or are they actually the same (i.e. both are salvaged from 
> https://reviews.llvm.org/D93829)?

I didn't know about that one. Seems nothing gets reviewed anymore these days.

https://github.com/llvm/llvm-project/pull/91191
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Support callHierarchy/outgoingCalls (PR #91191)

2024-05-06 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

> If I'm understanding correctly, the implementation approach in this PR only 
> finds callees in the current translation 
> unit.
> The approach in #77556 uses the project's index to find callees across 
> translation unit boundaries.

Right, that's obviously nicer.

> Regarding reviews: yes, it seems quite unfortunate that the original 
> developers seem to have largely moved on to 
> other things. I will do my best to make some progress of the project's review 
> backlog (including in particular 
> #86629 and #67802) as time permits.

Your work is highly appreciated, but I don't think it's reasonable to expect a 
single unpaid contributor to maintain the entire project, as appears to be the 
case right now.



https://github.com/llvm/llvm-project/pull/91191
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Let DefineOutline tweak handle member functions (PR #95235)

2024-08-26 Thread Christian Kandeler via cfe-commits


@@ -144,8 +144,13 @@ getQualification(ASTContext &Context, const DeclContext 
*DestContext,
   // since we stored inner-most parent first.
   std::string Result;
   llvm::raw_string_ostream OS(Result);
-  for (const auto *Parent : llvm::reverse(Parents))
+  for (const auto *Parent : llvm::reverse(Parents)) {
+if (Parent != *Parents.rbegin() && Parent->isDependent() &&
+Parent->getAsRecordDecl() &&
+Parent->getAsRecordDecl()->getDescribedClassTemplate())

ckandeler wrote:

The function doesn't look expensive, and this would complicate the code, so I'd 
rather not.

https://github.com/llvm/llvm-project/pull/95235
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Let DefineOutline tweak handle member functions (PR #95235)

2024-08-26 Thread Christian Kandeler via cfe-commits


@@ -407,10 +431,21 @@ class DefineOutline : public Tweak {
   return !SameFile;
 }
 
-// Bail out in templated classes, as it is hard to spell the class name,
-// i.e if the template parameter is unnamed.
-if (MD->getParent()->isTemplated())
-  return false;
+for (const CXXRecordDecl *Parent = MD->getParent(); Parent;
+ Parent =
+ llvm::dyn_cast_or_null(Parent->getParent())) 
{
+  if (auto Params = Parent->getDescribedTemplateParams()) {

ckandeler wrote:

Done, but note that auto is not generally used in this project the way you 
prefer (with the type obvious from the rhs).

https://github.com/llvm/llvm-project/pull/95235
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Let DefineOutline tweak handle member functions (PR #95235)

2024-08-26 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/95235

>From de740c00c4cc3a9f2e8aff14cf8ebd880a240e58 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Tue, 14 Nov 2023 16:35:46 +0100
Subject: [PATCH] [clangd] Let DefineOutline tweak handle member functions

... of class templates.
---
 clang-tools-extra/clangd/AST.cpp  |  7 ++-
 .../clangd/refactor/tweaks/DefineOutline.cpp  | 50 +++--
 .../unittests/tweaks/DefineOutlineTests.cpp   | 55 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |  2 +
 4 files changed, 94 insertions(+), 20 deletions(-)

diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index fda1e5fdf8d82c..2f2f8437d6ed9a 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -144,8 +144,13 @@ getQualification(ASTContext &Context, const DeclContext 
*DestContext,
   // since we stored inner-most parent first.
   std::string Result;
   llvm::raw_string_ostream OS(Result);
-  for (const auto *Parent : llvm::reverse(Parents))
+  for (const auto *Parent : llvm::reverse(Parents)) {
+if (Parent != *Parents.rbegin() && Parent->isDependent() &&
+Parent->getAsRecordDecl() &&
+Parent->getAsRecordDecl()->getDescribedClassTemplate())
+  OS << "template ";
 Parent->print(OS, Context.getPrintingPolicy());
+  }
   return OS.str();
 }
 
diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index f43f2417df8fce..591a8b245260ea 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -128,7 +128,28 @@ getFunctionSourceAfterReplacements(const FunctionDecl *FD,
   SM.getBufferData(SM.getMainFileID()), Replacements);
   if (!QualifiedFunc)
 return QualifiedFunc.takeError();
-  return QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1);
+
+  std::string TemplatePrefix;
+  if (auto *MD = llvm::dyn_cast(FD)) {
+for (const CXXRecordDecl *Parent = MD->getParent(); Parent;
+ Parent =
+ llvm::dyn_cast_or_null(Parent->getParent())) 
{
+  if (const TemplateParameterList *Params =
+  Parent->getDescribedTemplateParams()) {
+std::string S;
+llvm::raw_string_ostream Stream(S);
+Params->print(Stream, FD->getASTContext());
+if (!S.empty())
+  *S.rbegin() = '\n'; // Replace space with newline
+TemplatePrefix.insert(0, S);
+  }
+}
+  }
+
+  auto Source = QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1);
+  if (!TemplatePrefix.empty())
+Source.insert(0, TemplatePrefix);
+  return Source;
 }
 
 // Returns replacements to delete tokens with kind `Kind` in the range
@@ -212,9 +233,13 @@ getFunctionSourceCode(const FunctionDecl *FD, const 
DeclContext *TargetContext,
   }
 }
 const NamedDecl *ND = Ref.Targets.front();
-const std::string Qualifier =
+std::string Qualifier =
 getQualification(AST, TargetContext,
  SM.getLocForStartOfFile(SM.getMainFileID()), ND);
+if (ND->getDeclContext()->isDependentContext() &&
+llvm::isa(ND)) {
+  Qualifier.insert(0, "typename ");
+}
 if (auto Err = DeclarationCleanups.add(
 tooling::Replacement(SM, Ref.NameLoc, 0, Qualifier)))
   Errors = llvm::joinErrors(std::move(Errors), std::move(Err));
@@ -407,10 +432,23 @@ class DefineOutline : public Tweak {
   return !SameFile;
 }
 
-// Bail out in templated classes, as it is hard to spell the class name,
-// i.e if the template parameter is unnamed.
-if (MD->getParent()->isTemplated())
-  return false;
+for (const CXXRecordDecl *Parent = MD->getParent(); Parent;
+ Parent =
+ llvm::dyn_cast_or_null(Parent->getParent())) 
{
+  if (const TemplateParameterList *Params =
+  Parent->getDescribedTemplateParams()) {
+
+// Class template member functions must be defined in the
+// same file.
+SameFile = true;
+
+// Bail out if the template parameter is unnamed.
+for (NamedDecl *P : *Params) {
+  if (!P->getIdentifier())
+return false;
+}
+  }
+}
 
 // The refactoring is meaningless for unnamed classes and namespaces,
 // unless we're outlining in the same file
diff --git a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp 
b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
index 906ff33db87344..6a9e90c3bfa70f 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
@@ -105,8 +105,8 @@ TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
   F^oo(const Foo&) = delete;
 };)cpp");
 
-  // Not available with

[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-12 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/67802

>From dec33143e617967dee46ce4123a2e298220d73fc Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Fri, 29 Sep 2023 15:01:58 +0200
Subject: [PATCH] [clangd] Collect comments from function definitions into the
 index

This is useful with projects that put their (doxygen) comments at the
implementation site, rather than the header.
---
 clang-tools-extra/clangd/index/Symbol.h   |  4 +-
 .../clangd/index/SymbolCollector.cpp  | 56 +++
 .../clangd/index/SymbolCollector.h|  3 +-
 .../clangd/unittests/SymbolCollectorTests.cpp | 52 +
 clang/lib/AST/ASTContext.cpp  | 11 +++-
 5 files changed, 113 insertions(+), 13 deletions(-)

diff --git a/clang-tools-extra/clangd/index/Symbol.h 
b/clang-tools-extra/clangd/index/Symbol.h
index 1aa5265299231b..62c47ddfc5758d 100644
--- a/clang-tools-extra/clangd/index/Symbol.h
+++ b/clang-tools-extra/clangd/index/Symbol.h
@@ -145,9 +145,11 @@ struct Symbol {
 ImplementationDetail = 1 << 2,
 /// Symbol is visible to other files (not e.g. a static helper function).
 VisibleOutsideFile = 1 << 3,
+/// Symbol has an attached documentation comment.
+HasDocComment = 1 << 4
   };
-
   SymbolFlag Flags = SymbolFlag::None;
+
   /// FIXME: also add deprecation message and fixit?
 };
 
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp 
b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index 5c4e2150cf3123..066c7428ace555 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -635,17 +635,20 @@ bool SymbolCollector::handleDeclOccurrence(
 return true;
 
   const Symbol *BasicSymbol = Symbols.find(ID);
-  if (isPreferredDeclaration(*OriginalDecl, Roles))
+  bool SkipDocCheckInDef = false;
+  if (isPreferredDeclaration(*OriginalDecl, Roles)) {
 // If OriginalDecl is preferred, replace/create the existing canonical
 // declaration (e.g. a class forward declaration). There should be at most
 // one duplicate as we expect to see only one preferred declaration per
 // TU, because in practice they are definitions.
 BasicSymbol = addDeclaration(*OriginalDecl, std::move(ID), IsMainFileOnly);
-  else if (!BasicSymbol || DeclIsCanonical)
+SkipDocCheckInDef = true;
+  } else if (!BasicSymbol || DeclIsCanonical) {
 BasicSymbol = addDeclaration(*ND, std::move(ID), IsMainFileOnly);
+  }
 
   if (Roles & static_cast(index::SymbolRole::Definition))
-addDefinition(*OriginalDecl, *BasicSymbol);
+addDefinition(*OriginalDecl, *BasicSymbol, SkipDocCheckInDef);
 
   return true;
 }
@@ -1025,16 +1028,28 @@ const Symbol *SymbolCollector::addDeclaration(const 
NamedDecl &ND, SymbolID ID,
   *ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
   *CompletionTUInfo,
   /*IncludeBriefComments*/ false);
-  std::string Documentation =
-  formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion,
-  /*CommentsFromHeaders=*/true));
+  std::string DocComment;
+  std::string Documentation;
+  bool AlreadyHasDoc = S.Flags & Symbol::HasDocComment;
+  if (!AlreadyHasDoc) {
+DocComment = getDocComment(Ctx, SymbolCompletion,
+   /*CommentsFromHeaders=*/true);
+Documentation = formatDocumentation(*CCS, DocComment);
+  }
+  const auto UpdateDoc = [&] {
+if (!AlreadyHasDoc) {
+  if (!DocComment.empty())
+S.Flags |= Symbol::HasDocComment;
+  S.Documentation = Documentation;
+}
+  };
   if (!(S.Flags & Symbol::IndexedForCodeCompletion)) {
 if (Opts.StoreAllDocumentation)
-  S.Documentation = Documentation;
+  UpdateDoc();
 Symbols.insert(S);
 return Symbols.find(S.ID);
   }
-  S.Documentation = Documentation;
+  UpdateDoc();
   std::string Signature;
   std::string SnippetSuffix;
   getSignature(*CCS, &Signature, &SnippetSuffix, SymbolCompletion.Kind,
@@ -1058,8 +1073,8 @@ const Symbol *SymbolCollector::addDeclaration(const 
NamedDecl &ND, SymbolID ID,
   return Symbols.find(S.ID);
 }
 
-void SymbolCollector::addDefinition(const NamedDecl &ND,
-const Symbol &DeclSym) {
+void SymbolCollector::addDefinition(const NamedDecl &ND, const Symbol &DeclSym,
+bool SkipDocCheck) {
   if (DeclSym.Definition)
 return;
   const auto &SM = ND.getASTContext().getSourceManager();
@@ -1074,6 +1089,27 @@ void SymbolCollector::addDefinition(const NamedDecl &ND,
   Symbol S = DeclSym;
   // FIXME: use the result to filter out symbols.
   S.Definition = *DefLoc;
+
+  std::string DocComment;
+  std::string Documentation;
+  if (!SkipDocCheck && !(S.Flags & Symbol::HasDocComment) &&
+  (llvm::isa(ND) || llvm::isa(ND))) {
+CodeCompletionResult SymbolCompletion(&getTemplateOrThis(ND), 0);
+const auto *CCS = Symbol

[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-13 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/67802

>From f441c0bd52add3d5b63bc0f19a3d38cb12477359 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Fri, 29 Sep 2023 15:01:58 +0200
Subject: [PATCH] [clangd] Collect comments from function definitions into the
 index

This is useful with projects that put their (doxygen) comments at the
implementation site, rather than the header.
---
 clang-tools-extra/clangd/index/Symbol.h   |  4 +-
 .../clangd/index/SymbolCollector.cpp  | 57 +++
 .../clangd/index/SymbolCollector.h|  3 +-
 .../clangd/unittests/SymbolCollectorTests.cpp | 52 +
 clang/lib/AST/ASTContext.cpp  | 11 +++-
 5 files changed, 114 insertions(+), 13 deletions(-)

diff --git a/clang-tools-extra/clangd/index/Symbol.h 
b/clang-tools-extra/clangd/index/Symbol.h
index 1aa5265299231b..62c47ddfc5758d 100644
--- a/clang-tools-extra/clangd/index/Symbol.h
+++ b/clang-tools-extra/clangd/index/Symbol.h
@@ -145,9 +145,11 @@ struct Symbol {
 ImplementationDetail = 1 << 2,
 /// Symbol is visible to other files (not e.g. a static helper function).
 VisibleOutsideFile = 1 << 3,
+/// Symbol has an attached documentation comment.
+HasDocComment = 1 << 4
   };
-
   SymbolFlag Flags = SymbolFlag::None;
+
   /// FIXME: also add deprecation message and fixit?
 };
 
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp 
b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index 5c4e2150cf3123..a76894cf0855f3 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -635,17 +635,21 @@ bool SymbolCollector::handleDeclOccurrence(
 return true;
 
   const Symbol *BasicSymbol = Symbols.find(ID);
-  if (isPreferredDeclaration(*OriginalDecl, Roles))
+  bool SkipDocCheckInDef = false;
+  if (isPreferredDeclaration(*OriginalDecl, Roles)) {
 // If OriginalDecl is preferred, replace/create the existing canonical
 // declaration (e.g. a class forward declaration). There should be at most
 // one duplicate as we expect to see only one preferred declaration per
 // TU, because in practice they are definitions.
 BasicSymbol = addDeclaration(*OriginalDecl, std::move(ID), IsMainFileOnly);
-  else if (!BasicSymbol || DeclIsCanonical)
+SkipDocCheckInDef = true;
+  } else if (!BasicSymbol || DeclIsCanonical) {
 BasicSymbol = addDeclaration(*ND, std::move(ID), IsMainFileOnly);
+SkipDocCheckInDef = true;
+  }
 
   if (Roles & static_cast(index::SymbolRole::Definition))
-addDefinition(*OriginalDecl, *BasicSymbol);
+addDefinition(*OriginalDecl, *BasicSymbol, SkipDocCheckInDef);
 
   return true;
 }
@@ -1025,16 +1029,28 @@ const Symbol *SymbolCollector::addDeclaration(const 
NamedDecl &ND, SymbolID ID,
   *ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
   *CompletionTUInfo,
   /*IncludeBriefComments*/ false);
-  std::string Documentation =
-  formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion,
-  /*CommentsFromHeaders=*/true));
+  std::string DocComment;
+  std::string Documentation;
+  bool AlreadyHasDoc = S.Flags & Symbol::HasDocComment;
+  if (!AlreadyHasDoc) {
+DocComment = getDocComment(Ctx, SymbolCompletion,
+   /*CommentsFromHeaders=*/true);
+Documentation = formatDocumentation(*CCS, DocComment);
+  }
+  const auto UpdateDoc = [&] {
+if (!AlreadyHasDoc) {
+  if (!DocComment.empty())
+S.Flags |= Symbol::HasDocComment;
+  S.Documentation = Documentation;
+}
+  };
   if (!(S.Flags & Symbol::IndexedForCodeCompletion)) {
 if (Opts.StoreAllDocumentation)
-  S.Documentation = Documentation;
+  UpdateDoc();
 Symbols.insert(S);
 return Symbols.find(S.ID);
   }
-  S.Documentation = Documentation;
+  UpdateDoc();
   std::string Signature;
   std::string SnippetSuffix;
   getSignature(*CCS, &Signature, &SnippetSuffix, SymbolCompletion.Kind,
@@ -1058,8 +1074,8 @@ const Symbol *SymbolCollector::addDeclaration(const 
NamedDecl &ND, SymbolID ID,
   return Symbols.find(S.ID);
 }
 
-void SymbolCollector::addDefinition(const NamedDecl &ND,
-const Symbol &DeclSym) {
+void SymbolCollector::addDefinition(const NamedDecl &ND, const Symbol &DeclSym,
+bool SkipDocCheck) {
   if (DeclSym.Definition)
 return;
   const auto &SM = ND.getASTContext().getSourceManager();
@@ -1074,6 +1090,27 @@ void SymbolCollector::addDefinition(const NamedDecl &ND,
   Symbol S = DeclSym;
   // FIXME: use the result to filter out symbols.
   S.Definition = *DefLoc;
+
+  std::string DocComment;
+  std::string Documentation;
+  if (!SkipDocCheck && !(S.Flags & Symbol::HasDocComment) &&
+  (llvm::isa(ND) || llvm::isa(ND))) {
+CodeCompletionResult SymbolCompletion(&getTemplateOrThis(ND), 0)

[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-13 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

> Meanwhile, I thought of a fix for #108145 and submitted it as #108475.
> If that's accepted, you should be able to drop the `ASTContext.cpp` changes 
> from this patch.

Nice, will do.



https://github.com/llvm/llvm-project/pull/67802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Let DefineOutline tweak handle member functions (PR #95235)

2024-10-14 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler closed 
https://github.com/llvm/llvm-project/pull/95235
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Let DefineOutline tweak handle member functions (PR #95235)

2024-10-14 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

Thanks!

https://github.com/llvm/llvm-project/pull/95235
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Let DefineOutline tweak handle member function templates (PR #112345)

2024-10-15 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler created 
https://github.com/llvm/llvm-project/pull/112345

None

>From f2b6d67d882fca9a1dae3b50166541df7f22cb44 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Mon, 14 Oct 2024 15:37:01 +0200
Subject: [PATCH] [clangd] Let DefineOutline tweak handle member function
 templates

---
 .../clangd/refactor/tweaks/DefineOutline.cpp  | 69 ++-
 .../unittests/tweaks/DefineOutlineTests.cpp   | 51 --
 2 files changed, 94 insertions(+), 26 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index 591a8b245260ea..14d9858b702a1d 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -109,7 +109,8 @@ findContextForNS(llvm::StringRef TargetNS, const 
DeclContext *CurContext) {
 // afterwards it can be shared with define-inline code action.
 llvm::Expected
 getFunctionSourceAfterReplacements(const FunctionDecl *FD,
-   const tooling::Replacements &Replacements) {
+   const tooling::Replacements &Replacements,
+   bool TargetFileIsHeader) {
   const auto &SM = FD->getASTContext().getSourceManager();
   auto OrigFuncRange = toHalfOpenFileRange(
   SM, FD->getASTContext().getLangOpts(), FD->getSourceRange());
@@ -130,23 +131,41 @@ getFunctionSourceAfterReplacements(const FunctionDecl *FD,
 return QualifiedFunc.takeError();
 
   std::string TemplatePrefix;
+  auto AddToTemplatePrefixIfApplicable = [&](const Decl *D, bool append) {
+const TemplateParameterList *Params = D->getDescribedTemplateParams();
+if (!Params)
+  return;
+for (Decl *P : *Params) {
+  if (auto *TTP = dyn_cast(P)) {
+TTP->removeDefaultArgument();
+  } else if (auto *NTTP = dyn_cast(P)) {
+NTTP->removeDefaultArgument();
+  } else if (auto * TTPD = dyn_cast(P)) {
+TTPD->removeDefaultArgument();
+  }
+}
+std::string S;
+llvm::raw_string_ostream Stream(S);
+Params->print(Stream, FD->getASTContext());
+if (!S.empty())
+  *S.rbegin() = '\n'; // Replace space with newline
+if (append)
+  TemplatePrefix.append(S);
+else
+  TemplatePrefix.insert(0, S);
+  };
   if (auto *MD = llvm::dyn_cast(FD)) {
 for (const CXXRecordDecl *Parent = MD->getParent(); Parent;
  Parent =
  llvm::dyn_cast_or_null(Parent->getParent())) 
{
-  if (const TemplateParameterList *Params =
-  Parent->getDescribedTemplateParams()) {
-std::string S;
-llvm::raw_string_ostream Stream(S);
-Params->print(Stream, FD->getASTContext());
-if (!S.empty())
-  *S.rbegin() = '\n'; // Replace space with newline
-TemplatePrefix.insert(0, S);
-  }
+  AddToTemplatePrefixIfApplicable(Parent, false);
 }
   }
-
+  
+  AddToTemplatePrefixIfApplicable(FD, true);
   auto Source = QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1);
+  if (TargetFileIsHeader)
+Source.insert(0, "inline ");
   if (!TemplatePrefix.empty())
 Source.insert(0, TemplatePrefix);
   return Source;
@@ -202,7 +221,8 @@ deleteTokensWithKind(const syntax::TokenBuffer &TokBuf, 
tok::TokenKind Kind,
 llvm::Expected
 getFunctionSourceCode(const FunctionDecl *FD, const DeclContext *TargetContext,
   const syntax::TokenBuffer &TokBuf,
-  const HeuristicResolver *Resolver) {
+  const HeuristicResolver *Resolver,
+  bool targetFileIsHeader) {
   auto &AST = FD->getASTContext();
   auto &SM = AST.getSourceManager();
 
@@ -337,7 +357,7 @@ getFunctionSourceCode(const FunctionDecl *FD, const 
DeclContext *TargetContext,
 
   if (Errors)
 return std::move(Errors);
-  return getFunctionSourceAfterReplacements(FD, DeclarationCleanups);
+  return getFunctionSourceAfterReplacements(FD, DeclarationCleanups, 
targetFileIsHeader);
 }
 
 struct InsertionPoint {
@@ -419,15 +439,15 @@ class DefineOutline : public Tweak {
 Source->isOutOfLine())
   return false;
 
-// Bail out if this is a function template or specialization, as their
+// Bail out if this is a function template specialization, as their
 // definitions need to be visible in all including translation units.
-if (Source->getDescribedFunctionTemplate())
-  return false;
 if (Source->getTemplateSpecializationInfo())
   return false;
 
 auto *MD = llvm::dyn_cast(Source);
 if (!MD) {
+  if (Source->getDescribedFunctionTemplate())
+return false;
   // Can't outline free-standing functions in the same file.
   return !SameFile;
 }
@@ -443,13 +463,24 @@ class DefineOutline : public Tweak {
 SameFile = true;
 
 // Bail out if the template parameter is unnamed.
+// FIXME: Is this really ne

[clang-tools-extra] [clangd] Let DefineOutline tweak handle member function templates (PR #112345)

2024-10-15 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/112345

>From 0d847ccd3b26f2e0ef1203c091d6152d6abea58a Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Mon, 14 Oct 2024 15:37:01 +0200
Subject: [PATCH] [clangd] Let DefineOutline tweak handle member function
 templates

---
 .../clangd/refactor/tweaks/DefineOutline.cpp  | 67 ++-
 .../unittests/tweaks/DefineOutlineTests.cpp   | 49 --
 2 files changed, 94 insertions(+), 22 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index 591a8b245260ea..a552114da1054d 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -109,7 +109,8 @@ findContextForNS(llvm::StringRef TargetNS, const 
DeclContext *CurContext) {
 // afterwards it can be shared with define-inline code action.
 llvm::Expected
 getFunctionSourceAfterReplacements(const FunctionDecl *FD,
-   const tooling::Replacements &Replacements) {
+   const tooling::Replacements &Replacements,
+   bool TargetFileIsHeader) {
   const auto &SM = FD->getASTContext().getSourceManager();
   auto OrigFuncRange = toHalfOpenFileRange(
   SM, FD->getASTContext().getLangOpts(), FD->getSourceRange());
@@ -130,23 +131,41 @@ getFunctionSourceAfterReplacements(const FunctionDecl *FD,
 return QualifiedFunc.takeError();
 
   std::string TemplatePrefix;
+  auto AddToTemplatePrefixIfApplicable = [&](const Decl *D, bool append) {
+const TemplateParameterList *Params = D->getDescribedTemplateParams();
+if (!Params)
+  return;
+for (Decl *P : *Params) {
+  if (auto *TTP = dyn_cast(P)) {
+TTP->removeDefaultArgument();
+  } else if (auto *NTTP = dyn_cast(P)) {
+NTTP->removeDefaultArgument();
+  } else if (auto *TTPD = dyn_cast(P)) {
+TTPD->removeDefaultArgument();
+  }
+}
+std::string S;
+llvm::raw_string_ostream Stream(S);
+Params->print(Stream, FD->getASTContext());
+if (!S.empty())
+  *S.rbegin() = '\n'; // Replace space with newline
+if (append)
+  TemplatePrefix.append(S);
+else
+  TemplatePrefix.insert(0, S);
+  };
   if (auto *MD = llvm::dyn_cast(FD)) {
 for (const CXXRecordDecl *Parent = MD->getParent(); Parent;
  Parent =
  llvm::dyn_cast_or_null(Parent->getParent())) 
{
-  if (const TemplateParameterList *Params =
-  Parent->getDescribedTemplateParams()) {
-std::string S;
-llvm::raw_string_ostream Stream(S);
-Params->print(Stream, FD->getASTContext());
-if (!S.empty())
-  *S.rbegin() = '\n'; // Replace space with newline
-TemplatePrefix.insert(0, S);
-  }
+  AddToTemplatePrefixIfApplicable(Parent, false);
 }
   }
 
+  AddToTemplatePrefixIfApplicable(FD, true);
   auto Source = QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1);
+  if (TargetFileIsHeader)
+Source.insert(0, "inline ");
   if (!TemplatePrefix.empty())
 Source.insert(0, TemplatePrefix);
   return Source;
@@ -202,7 +221,8 @@ deleteTokensWithKind(const syntax::TokenBuffer &TokBuf, 
tok::TokenKind Kind,
 llvm::Expected
 getFunctionSourceCode(const FunctionDecl *FD, const DeclContext *TargetContext,
   const syntax::TokenBuffer &TokBuf,
-  const HeuristicResolver *Resolver) {
+  const HeuristicResolver *Resolver,
+  bool targetFileIsHeader) {
   auto &AST = FD->getASTContext();
   auto &SM = AST.getSourceManager();
 
@@ -337,7 +357,8 @@ getFunctionSourceCode(const FunctionDecl *FD, const 
DeclContext *TargetContext,
 
   if (Errors)
 return std::move(Errors);
-  return getFunctionSourceAfterReplacements(FD, DeclarationCleanups);
+  return getFunctionSourceAfterReplacements(FD, DeclarationCleanups,
+targetFileIsHeader);
 }
 
 struct InsertionPoint {
@@ -419,15 +440,15 @@ class DefineOutline : public Tweak {
 Source->isOutOfLine())
   return false;
 
-// Bail out if this is a function template or specialization, as their
+// Bail out if this is a function template specialization, as their
 // definitions need to be visible in all including translation units.
-if (Source->getDescribedFunctionTemplate())
-  return false;
 if (Source->getTemplateSpecializationInfo())
   return false;
 
 auto *MD = llvm::dyn_cast(Source);
 if (!MD) {
+  if (Source->getDescribedFunctionTemplate())
+return false;
   // Can't outline free-standing functions in the same file.
   return !SameFile;
 }
@@ -443,6 +464,8 @@ class DefineOutline : public Tweak {
 SameFile = true;
 
 // Bail out if the template parameter is unnamed.
+

[clang-tools-extra] [clangd] Let DefineOutline tweak handle member function templates (PR #112345)

2024-10-15 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/112345

>From 5b729d0bc7b2d5ed2f0d1645a29e3fb9b0a35033 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Mon, 14 Oct 2024 15:37:01 +0200
Subject: [PATCH] [clangd] Let DefineOutline tweak handle member function
 templates

---
 .../clangd/refactor/tweaks/DefineOutline.cpp  | 66 ++-
 .../unittests/tweaks/DefineOutlineTests.cpp   | 49 --
 2 files changed, 93 insertions(+), 22 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index 591a8b245260ea..c2a517e644c8aa 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -109,7 +109,8 @@ findContextForNS(llvm::StringRef TargetNS, const 
DeclContext *CurContext) {
 // afterwards it can be shared with define-inline code action.
 llvm::Expected
 getFunctionSourceAfterReplacements(const FunctionDecl *FD,
-   const tooling::Replacements &Replacements) {
+   const tooling::Replacements &Replacements,
+   bool TargetFileIsHeader) {
   const auto &SM = FD->getASTContext().getSourceManager();
   auto OrigFuncRange = toHalfOpenFileRange(
   SM, FD->getASTContext().getLangOpts(), FD->getSourceRange());
@@ -130,23 +131,40 @@ getFunctionSourceAfterReplacements(const FunctionDecl *FD,
 return QualifiedFunc.takeError();
 
   std::string TemplatePrefix;
+  auto AddToTemplatePrefixIfApplicable = [&](const Decl *D, bool append) {
+const TemplateParameterList *Params = D->getDescribedTemplateParams();
+if (!Params)
+  return;
+for (Decl *P : *Params) {
+  if (auto *TTP = dyn_cast(P))
+TTP->removeDefaultArgument();
+  else if (auto *NTTP = dyn_cast(P))
+NTTP->removeDefaultArgument();
+  else if (auto *TTPD = dyn_cast(P))
+TTPD->removeDefaultArgument();
+}
+std::string S;
+llvm::raw_string_ostream Stream(S);
+Params->print(Stream, FD->getASTContext());
+if (!S.empty())
+  *S.rbegin() = '\n'; // Replace space with newline
+if (append)
+  TemplatePrefix.append(S);
+else
+  TemplatePrefix.insert(0, S);
+  };
   if (auto *MD = llvm::dyn_cast(FD)) {
 for (const CXXRecordDecl *Parent = MD->getParent(); Parent;
  Parent =
  llvm::dyn_cast_or_null(Parent->getParent())) 
{
-  if (const TemplateParameterList *Params =
-  Parent->getDescribedTemplateParams()) {
-std::string S;
-llvm::raw_string_ostream Stream(S);
-Params->print(Stream, FD->getASTContext());
-if (!S.empty())
-  *S.rbegin() = '\n'; // Replace space with newline
-TemplatePrefix.insert(0, S);
-  }
+  AddToTemplatePrefixIfApplicable(Parent, false);
 }
   }
 
+  AddToTemplatePrefixIfApplicable(FD, true);
   auto Source = QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1);
+  if (TargetFileIsHeader)
+Source.insert(0, "inline ");
   if (!TemplatePrefix.empty())
 Source.insert(0, TemplatePrefix);
   return Source;
@@ -202,7 +220,8 @@ deleteTokensWithKind(const syntax::TokenBuffer &TokBuf, 
tok::TokenKind Kind,
 llvm::Expected
 getFunctionSourceCode(const FunctionDecl *FD, const DeclContext *TargetContext,
   const syntax::TokenBuffer &TokBuf,
-  const HeuristicResolver *Resolver) {
+  const HeuristicResolver *Resolver,
+  bool targetFileIsHeader) {
   auto &AST = FD->getASTContext();
   auto &SM = AST.getSourceManager();
 
@@ -337,7 +356,8 @@ getFunctionSourceCode(const FunctionDecl *FD, const 
DeclContext *TargetContext,
 
   if (Errors)
 return std::move(Errors);
-  return getFunctionSourceAfterReplacements(FD, DeclarationCleanups);
+  return getFunctionSourceAfterReplacements(FD, DeclarationCleanups,
+targetFileIsHeader);
 }
 
 struct InsertionPoint {
@@ -419,15 +439,15 @@ class DefineOutline : public Tweak {
 Source->isOutOfLine())
   return false;
 
-// Bail out if this is a function template or specialization, as their
+// Bail out if this is a function template specialization, as their
 // definitions need to be visible in all including translation units.
-if (Source->getDescribedFunctionTemplate())
-  return false;
 if (Source->getTemplateSpecializationInfo())
   return false;
 
 auto *MD = llvm::dyn_cast(Source);
 if (!MD) {
+  if (Source->getDescribedFunctionTemplate())
+return false;
   // Can't outline free-standing functions in the same file.
   return !SameFile;
 }
@@ -443,6 +463,8 @@ class DefineOutline : public Tweak {
 SameFile = true;
 
 // Bail out if the template parameter is unnamed.
+// FIXME: Is th

[clang-tools-extra] [clangd] Let DefineOutline tweak handle member function templates (PR #112345)

2024-10-15 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/112345

>From 42ea89f38b599796b15d50d078cba1cb0e0f2b02 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Mon, 14 Oct 2024 15:37:01 +0200
Subject: [PATCH] [clangd] Let DefineOutline tweak handle member function
 templates

---
 .../clangd/refactor/tweaks/DefineOutline.cpp  | 68 ++-
 .../unittests/tweaks/DefineOutlineTests.cpp   | 49 +++--
 2 files changed, 93 insertions(+), 24 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index 591a8b245260ea..56f3ccdf493419 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -109,14 +109,13 @@ findContextForNS(llvm::StringRef TargetNS, const 
DeclContext *CurContext) {
 // afterwards it can be shared with define-inline code action.
 llvm::Expected
 getFunctionSourceAfterReplacements(const FunctionDecl *FD,
-   const tooling::Replacements &Replacements) {
+   const tooling::Replacements &Replacements,
+   bool TargetFileIsHeader) {
   const auto &SM = FD->getASTContext().getSourceManager();
   auto OrigFuncRange = toHalfOpenFileRange(
   SM, FD->getASTContext().getLangOpts(), FD->getSourceRange());
   if (!OrigFuncRange)
 return error("Couldn't get range for function.");
-  assert(!FD->getDescribedFunctionTemplate() &&
- "Define out-of-line doesn't apply to function templates.");
 
   // Get new begin and end positions for the qualified function definition.
   unsigned FuncBegin = SM.getFileOffset(OrigFuncRange->getBegin());
@@ -130,23 +129,40 @@ getFunctionSourceAfterReplacements(const FunctionDecl *FD,
 return QualifiedFunc.takeError();
 
   std::string TemplatePrefix;
+  auto AddToTemplatePrefixIfApplicable = [&](const Decl *D, bool append) {
+const TemplateParameterList *Params = D->getDescribedTemplateParams();
+if (!Params)
+  return;
+for (Decl *P : *Params) {
+  if (auto *TTP = dyn_cast(P))
+TTP->removeDefaultArgument();
+  else if (auto *NTTP = dyn_cast(P))
+NTTP->removeDefaultArgument();
+  else if (auto *TTPD = dyn_cast(P))
+TTPD->removeDefaultArgument();
+}
+std::string S;
+llvm::raw_string_ostream Stream(S);
+Params->print(Stream, FD->getASTContext());
+if (!S.empty())
+  *S.rbegin() = '\n'; // Replace space with newline
+if (append)
+  TemplatePrefix.append(S);
+else
+  TemplatePrefix.insert(0, S);
+  };
   if (auto *MD = llvm::dyn_cast(FD)) {
 for (const CXXRecordDecl *Parent = MD->getParent(); Parent;
  Parent =
  llvm::dyn_cast_or_null(Parent->getParent())) 
{
-  if (const TemplateParameterList *Params =
-  Parent->getDescribedTemplateParams()) {
-std::string S;
-llvm::raw_string_ostream Stream(S);
-Params->print(Stream, FD->getASTContext());
-if (!S.empty())
-  *S.rbegin() = '\n'; // Replace space with newline
-TemplatePrefix.insert(0, S);
-  }
+  AddToTemplatePrefixIfApplicable(Parent, false);
 }
   }
 
+  AddToTemplatePrefixIfApplicable(FD, true);
   auto Source = QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1);
+  if (TargetFileIsHeader)
+Source.insert(0, "inline ");
   if (!TemplatePrefix.empty())
 Source.insert(0, TemplatePrefix);
   return Source;
@@ -202,7 +218,8 @@ deleteTokensWithKind(const syntax::TokenBuffer &TokBuf, 
tok::TokenKind Kind,
 llvm::Expected
 getFunctionSourceCode(const FunctionDecl *FD, const DeclContext *TargetContext,
   const syntax::TokenBuffer &TokBuf,
-  const HeuristicResolver *Resolver) {
+  const HeuristicResolver *Resolver,
+  bool targetFileIsHeader) {
   auto &AST = FD->getASTContext();
   auto &SM = AST.getSourceManager();
 
@@ -337,7 +354,8 @@ getFunctionSourceCode(const FunctionDecl *FD, const 
DeclContext *TargetContext,
 
   if (Errors)
 return std::move(Errors);
-  return getFunctionSourceAfterReplacements(FD, DeclarationCleanups);
+  return getFunctionSourceAfterReplacements(FD, DeclarationCleanups,
+targetFileIsHeader);
 }
 
 struct InsertionPoint {
@@ -419,15 +437,15 @@ class DefineOutline : public Tweak {
 Source->isOutOfLine())
   return false;
 
-// Bail out if this is a function template or specialization, as their
+// Bail out if this is a function template specialization, as their
 // definitions need to be visible in all including translation units.
-if (Source->getDescribedFunctionTemplate())
-  return false;
 if (Source->getTemplateSpecializationInfo())
   return false;
 
 auto *MD = llvm::dyn_cast(Source);
 if (!

[clang-tools-extra] [clangd] Let DefineOutline tweak handle member functions (PR #95235)

2024-10-09 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

ping

https://github.com/llvm/llvm-project/pull/95235
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] fix extract-to-function for overloaded operators (PR #81640)

2024-10-17 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

Needs rebase and another typo fix. Looks good to me otherwise.

https://github.com/llvm/llvm-project/pull/81640
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] fix extract-to-function for overloaded operators (PR #81640)

2024-10-17 Thread Christian Kandeler via cfe-commits


@@ -105,7 +105,7 @@ bool isRootStmt(const Node *N) {
   if (N->Selected == SelectionTree::Partial)
 return false;
   // A DeclStmt can be an unselected RootStmt since VarDecls claim the entire
-  // selection range in selectionTree. Additionally, an CXXOperatorCallExpr of 
a
+  // selection range in selectionTree. Additionally, a CXXOperatorCallExpr of a
   // binary operation can be unselected because it's children claim the entire

ckandeler wrote:

"it's" should also be changed to "its"

https://github.com/llvm/llvm-project/pull/81640
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Let DefineOutline tweak handle member function templates (PR #112345)

2024-10-18 Thread Christian Kandeler via cfe-commits

ckandeler wrote:


> ```c++
> template 
> inline void Foo::bar(const T& t, const U& u) {}
> ```
> 
> this won't compile as `T` isn't defined. you also need to print `template 
> ` on top (and keep doing for rest of the outer decls).

The patch does that already.
In the test, the outer template declaration is on the line above.

https://github.com/llvm/llvm-project/pull/112345
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-20 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/67802

>From 9dd725113a156a01f1866cfefe181c1b22f7e8d0 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Fri, 29 Sep 2023 15:01:58 +0200
Subject: [PATCH] [clangd] Collect comments from function definitions into the
 index

This is useful with projects that put their (doxygen) comments at the
implementation site, rather than the header.
---
 clang-tools-extra/clangd/index/Symbol.h   |  4 +-
 .../clangd/index/SymbolCollector.cpp  | 57 +++
 .../clangd/index/SymbolCollector.h|  3 +-
 .../clangd/unittests/SymbolCollectorTests.cpp | 52 +
 4 files changed, 104 insertions(+), 12 deletions(-)

diff --git a/clang-tools-extra/clangd/index/Symbol.h 
b/clang-tools-extra/clangd/index/Symbol.h
index 1aa5265299231b..62c47ddfc5758d 100644
--- a/clang-tools-extra/clangd/index/Symbol.h
+++ b/clang-tools-extra/clangd/index/Symbol.h
@@ -145,9 +145,11 @@ struct Symbol {
 ImplementationDetail = 1 << 2,
 /// Symbol is visible to other files (not e.g. a static helper function).
 VisibleOutsideFile = 1 << 3,
+/// Symbol has an attached documentation comment.
+HasDocComment = 1 << 4
   };
-
   SymbolFlag Flags = SymbolFlag::None;
+
   /// FIXME: also add deprecation message and fixit?
 };
 
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp 
b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index 5c4e2150cf3123..a76894cf0855f3 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -635,17 +635,21 @@ bool SymbolCollector::handleDeclOccurrence(
 return true;
 
   const Symbol *BasicSymbol = Symbols.find(ID);
-  if (isPreferredDeclaration(*OriginalDecl, Roles))
+  bool SkipDocCheckInDef = false;
+  if (isPreferredDeclaration(*OriginalDecl, Roles)) {
 // If OriginalDecl is preferred, replace/create the existing canonical
 // declaration (e.g. a class forward declaration). There should be at most
 // one duplicate as we expect to see only one preferred declaration per
 // TU, because in practice they are definitions.
 BasicSymbol = addDeclaration(*OriginalDecl, std::move(ID), IsMainFileOnly);
-  else if (!BasicSymbol || DeclIsCanonical)
+SkipDocCheckInDef = true;
+  } else if (!BasicSymbol || DeclIsCanonical) {
 BasicSymbol = addDeclaration(*ND, std::move(ID), IsMainFileOnly);
+SkipDocCheckInDef = true;
+  }
 
   if (Roles & static_cast(index::SymbolRole::Definition))
-addDefinition(*OriginalDecl, *BasicSymbol);
+addDefinition(*OriginalDecl, *BasicSymbol, SkipDocCheckInDef);
 
   return true;
 }
@@ -1025,16 +1029,28 @@ const Symbol *SymbolCollector::addDeclaration(const 
NamedDecl &ND, SymbolID ID,
   *ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
   *CompletionTUInfo,
   /*IncludeBriefComments*/ false);
-  std::string Documentation =
-  formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion,
-  /*CommentsFromHeaders=*/true));
+  std::string DocComment;
+  std::string Documentation;
+  bool AlreadyHasDoc = S.Flags & Symbol::HasDocComment;
+  if (!AlreadyHasDoc) {
+DocComment = getDocComment(Ctx, SymbolCompletion,
+   /*CommentsFromHeaders=*/true);
+Documentation = formatDocumentation(*CCS, DocComment);
+  }
+  const auto UpdateDoc = [&] {
+if (!AlreadyHasDoc) {
+  if (!DocComment.empty())
+S.Flags |= Symbol::HasDocComment;
+  S.Documentation = Documentation;
+}
+  };
   if (!(S.Flags & Symbol::IndexedForCodeCompletion)) {
 if (Opts.StoreAllDocumentation)
-  S.Documentation = Documentation;
+  UpdateDoc();
 Symbols.insert(S);
 return Symbols.find(S.ID);
   }
-  S.Documentation = Documentation;
+  UpdateDoc();
   std::string Signature;
   std::string SnippetSuffix;
   getSignature(*CCS, &Signature, &SnippetSuffix, SymbolCompletion.Kind,
@@ -1058,8 +1074,8 @@ const Symbol *SymbolCollector::addDeclaration(const 
NamedDecl &ND, SymbolID ID,
   return Symbols.find(S.ID);
 }
 
-void SymbolCollector::addDefinition(const NamedDecl &ND,
-const Symbol &DeclSym) {
+void SymbolCollector::addDefinition(const NamedDecl &ND, const Symbol &DeclSym,
+bool SkipDocCheck) {
   if (DeclSym.Definition)
 return;
   const auto &SM = ND.getASTContext().getSourceManager();
@@ -1074,6 +1090,27 @@ void SymbolCollector::addDefinition(const NamedDecl &ND,
   Symbol S = DeclSym;
   // FIXME: use the result to filter out symbols.
   S.Definition = *DefLoc;
+
+  std::string DocComment;
+  std::string Documentation;
+  if (!SkipDocCheck && !(S.Flags & Symbol::HasDocComment) &&
+  (llvm::isa(ND) || llvm::isa(ND))) {
+CodeCompletionResult SymbolCompletion(&getTemplateOrThis(ND), 0);
+const auto *CCS = SymbolCompletion.CreateCodeCompl

[clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-20 Thread Christian Kandeler via cfe-commits


@@ -451,8 +451,17 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
 if (LastCheckedRedecl) {
   if (LastCheckedRedecl == Redecl) {
 LastCheckedRedecl = nullptr;
+continue;

ckandeler wrote:

Done.

https://github.com/llvm/llvm-project/pull/67802
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Support outgoing calls in call hierarchy (PR #77556)

2024-11-25 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler approved this pull request.

Appears to work fine.
Regarding the slight memory increase: If anyone feels strongly about it, they 
had plenty of time to chime in.

https://github.com/llvm/llvm-project/pull/77556
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Store full decl/def range with symbol locations (PR #118102)

2024-11-29 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler created 
https://github.com/llvm/llvm-project/pull/118102

Apart from fixing the linked issue, this is also necessary for supporting LSP's 
LocationLink feature and for finding proper insertion locations in the 
DefineOutline tweak. Memory consumption of the background index grows by about 
~2.5%.

Closes https://github.com/clangd/clangd/issues/59

>From 99e7189c6f3c19e3aabeee56793f5683251ecb26 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Wed, 27 Nov 2024 13:47:32 +0100
Subject: [PATCH] [clangd] Store full decl/def range with symbol locations

Apart from fixing the linked issue, this is also necessary
for supporting LSP's LocationLink feature and for finding
proper insertion locations in the DefineOutline tweak.
Memory consumption of the background index grows by about ~2.5%.

Closes https://github.com/clangd/clangd/issues/59
---
 clang-tools-extra/clangd/CodeComplete.cpp |   4 +-
 clang-tools-extra/clangd/FindSymbols.cpp  |  34 --
 clang-tools-extra/clangd/FindSymbols.h|   8 +-
 .../clangd/HeaderSourceSwitch.cpp |   4 +-
 clang-tools-extra/clangd/IncludeFixer.cpp |   6 +-
 clang-tools-extra/clangd/Quality.cpp  |   2 +-
 clang-tools-extra/clangd/XRefs.cpp|  65 ++-
 clang-tools-extra/clangd/index/FileIndex.cpp  |   6 +-
 clang-tools-extra/clangd/index/Merge.cpp  |  13 ++-
 clang-tools-extra/clangd/index/Ref.h  |  11 +-
 .../clangd/index/Serialization.cpp|  36 --
 clang-tools-extra/clangd/index/StdLib.cpp |  12 +-
 clang-tools-extra/clangd/index/Symbol.h   |   8 +-
 .../clangd/index/SymbolCollector.cpp  |  89 +++
 .../clangd/index/SymbolCollector.h|   3 +-
 .../clangd/index/SymbolLocation.cpp   |  11 +-
 .../clangd/index/SymbolLocation.h | 103 +++---
 .../clangd/index/YAMLSerialization.cpp|  37 +--
 clang-tools-extra/clangd/index/dex/Dex.cpp|   4 +-
 clang-tools-extra/clangd/refactor/Rename.cpp  |   4 +-
 .../clangd/test/Inputs/symbols.test.yaml  |  17 ++-
 .../index-serialization/Inputs/sample.idx | Bin 470 -> 496 bytes
 .../clangd/test/type-hierarchy-ext.test   |   8 +-
 .../clangd/test/type-hierarchy.test   |   8 +-
 .../clangd/unittests/BackgroundIndexTests.cpp |   4 +-
 .../clangd/unittests/CodeCompleteTests.cpp|  18 +--
 .../clangd/unittests/DexTests.cpp |   5 +-
 .../clangd/unittests/DiagnosticsTests.cpp |  13 ++-
 .../clangd/unittests/FileIndexTests.cpp   |  14 +--
 .../clangd/unittests/IndexTests.cpp   |  45 
 .../clangd/unittests/SerializationTests.cpp   |  23 +++-
 .../clangd/unittests/SymbolCollectorTests.cpp |  12 +-
 32 files changed, 388 insertions(+), 239 deletions(-)

diff --git a/clang-tools-extra/clangd/CodeComplete.cpp 
b/clang-tools-extra/clangd/CodeComplete.cpp
index 2c2d5f0b5ac924..04e4aa2d2d1ca9 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -418,7 +418,7 @@ struct CodeCompletionBuilder {
 auto Inserted = [&](llvm::StringRef Header)
 -> llvm::Expected> {
   auto ResolvedDeclaring =
-  URI::resolve(C.IndexResult->CanonicalDeclaration.FileURI, FileName);
+  URI::resolve(C.IndexResult->CanonicalDeclaration.fileURI(), 
FileName);
   if (!ResolvedDeclaring)
 return ResolvedDeclaring.takeError();
   auto ResolvedInserted = toHeaderFile(Header, FileName);
@@ -451,7 +451,7 @@ struct CodeCompletionBuilder {
   } else
 log("Failed to generate include insertion edits for adding header "
 "(FileURI='{0}', IncludeHeader='{1}') into {2}: {3}",
-C.IndexResult->CanonicalDeclaration.FileURI, Inc.Header, FileName,
+C.IndexResult->CanonicalDeclaration.fileURI(), Inc.Header, 
FileName,
 ToInclude.takeError());
 }
 // Prefer includes that do not need edits (i.e. already exist).
diff --git a/clang-tools-extra/clangd/FindSymbols.cpp 
b/clang-tools-extra/clangd/FindSymbols.cpp
index 84bcbc1f2ddd3f..646cb261309c80 100644
--- a/clang-tools-extra/clangd/FindSymbols.cpp
+++ b/clang-tools-extra/clangd/FindSymbols.cpp
@@ -54,9 +54,19 @@ bool approximateScopeMatch(llvm::StringRef Scope, 
llvm::StringRef Query) {
   return Query.empty();
 }
 
+Range indexToLSPRange(const SymbolPosition &SrcStart,
+  const SymbolPosition &SrcEnd) {
+  Position Start, End;
+  Start.line = SrcStart.line();
+  Start.character = SrcStart.column();
+  End.line = SrcEnd.line();
+  End.character = SrcEnd.column();
+  return {Start, End};
+}
+
 } // namespace
 
-llvm::Expected indexToLSPLocation(const SymbolLocation &Loc,
+llvm::Expected indexToLSPLocation(const SymbolNameLocation &Loc,
 llvm::StringRef TUPath) {
   auto Path = URI::resolve(Loc.FileURI, TUPath);
   if (!Path)
@@ -64,17 +74,21 @@ llvm::Expected indexToLSPLocation(c

[clang-tools-extra] [clangd] Consolidate two functions converting index to LSP locations (PR #117885)

2024-11-27 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler created 
https://github.com/llvm/llvm-project/pull/117885

None

>From 7aa28a386a84c4fa8e7e8aa13822fd3e058b076c Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Wed, 27 Nov 2024 14:55:18 +0100
Subject: [PATCH] [clangd] Consolidate two functions converting index to LSP
 locations

---
 clang-tools-extra/clangd/XRefs.cpp | 22 --
 1 file changed, 4 insertions(+), 18 deletions(-)

diff --git a/clang-tools-extra/clangd/XRefs.cpp 
b/clang-tools-extra/clangd/XRefs.cpp
index 61fa66180376cd..f1e701f1ad0210 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -121,31 +121,17 @@ void logIfOverflow(const SymbolLocation &Loc) {
 
 // Convert a SymbolLocation to LSP's Location.
 // TUPath is used to resolve the path of URI.
-// FIXME: figure out a good home for it, and share the implementation with
-// FindSymbols.
 std::optional toLSPLocation(const SymbolLocation &Loc,
   llvm::StringRef TUPath) {
   if (!Loc)
 return std::nullopt;
-  auto Uri = URI::parse(Loc.FileURI);
-  if (!Uri) {
-elog("Could not parse URI {0}: {1}", Loc.FileURI, Uri.takeError());
+  auto LSPLoc = indexToLSPLocation(Loc, TUPath);
+  if (!LSPLoc) {
+elog("{0}", LSPLoc.takeError());
 return std::nullopt;
   }
-  auto U = URIForFile::fromURI(*Uri, TUPath);
-  if (!U) {
-elog("Could not resolve URI {0}: {1}", Loc.FileURI, U.takeError());
-return std::nullopt;
-  }
-
-  Location LSPLoc;
-  LSPLoc.uri = std::move(*U);
-  LSPLoc.range.start.line = Loc.Start.line();
-  LSPLoc.range.start.character = Loc.Start.column();
-  LSPLoc.range.end.line = Loc.End.line();
-  LSPLoc.range.end.character = Loc.End.column();
   logIfOverflow(Loc);
-  return LSPLoc;
+  return *LSPLoc;
 }
 
 SymbolLocation toIndexLocation(const Location &Loc, std::string &URIStorage) {

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


[clang-tools-extra] [clangd] Fix erroneous qualification of template type parameters (PR #116821)

2024-11-19 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler created 
https://github.com/llvm/llvm-project/pull/116821

...in DefineOutline tweak.
E.g. moving the following definition:
  template struct S { T f^oo() const { return T(); } };
would result in:
  // ...
  template S::T S::foo() const { return T(); }
instead of:
  template T S::foo() const { return T(); }

>From 00f85ed13e689331adbbc3513dde09023dfc68d4 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Tue, 19 Nov 2024 16:00:29 +0100
Subject: [PATCH] [clangd] Fix erroneous qualification of template type
 parameters

...in DefineOutline tweak.
E.g. moving the following definition:
  template struct S { T f^oo() const { return T(); } };
would result in:
  // ...
  template S::T S::foo() const { return T(); }
instead of:
  template T S::foo() const { return T(); }
---
 .../clangd/refactor/tweaks/DefineOutline.cpp |  2 ++
 .../clangd/unittests/tweaks/DefineOutlineTests.cpp   | 12 ++--
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index 2a96b305bd7a25..789c10bdd4822a 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -239,6 +239,8 @@ getFunctionSourceCode(const FunctionDecl *FD, const 
DeclContext *TargetContext,
   return;
 
 for (const NamedDecl *ND : Ref.Targets) {
+  if (ND->getKind() == Decl::TemplateTypeParm)
+return;
   if (ND->getDeclContext() != Ref.Targets.front()->getDeclContext()) {
 elog("Targets from multiple contexts: {0}, {1}",
  printQualifiedName(*Ref.Targets.front()),
diff --git a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp 
b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
index 1af1bc31bf6486..d2d2ae9e7bb610 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
@@ -411,14 +411,14 @@ inline typename O1::template O2::E O1::template O2
   R"cpp(
 struct Foo {
   template 
-  void ^bar() {}
+  T ^bar() { return {}; }
 };)cpp",
   R"cpp(
 struct Foo {
   template 
-  void bar() ;
+  T bar() ;
 };template 
-inline void Foo::bar() {}
+inline T Foo::bar() { return {}; }
 )cpp",
   ""},
 
@@ -426,14 +426,14 @@ inline void Foo::bar() {}
   {
   R"cpp(
 template  struct Foo {
-  template  void ^bar(const T& t, const U& u) {}
+  template  T ^bar(const T& t, const U& u) { return 
{}; }
 };)cpp",
   R"cpp(
 template  struct Foo {
-  template  void bar(const T& t, const U& u) ;
+  template  T bar(const T& t, const U& u) ;
 };template 
 template 
-inline void Foo::bar(const T& t, const U& u) {}
+inline T Foo::bar(const T& t, const U& u) { return {}; }
 )cpp",
   ""},
   };

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


[clang-tools-extra] [clangd] Let DefineOutline tweak handle member function templates (PR #112345)

2024-11-18 Thread Christian Kandeler via cfe-commits


@@ -443,13 +461,26 @@ class DefineOutline : public Tweak {
 SameFile = true;
 
 // Bail out if the template parameter is unnamed.
+// FIXME: Is this really needed? It inhibits application on

ckandeler wrote:

I've moved the comment down to the function template part.

https://github.com/llvm/llvm-project/pull/112345
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Fix erroneous qualification of template type parameters (PR #116821)

2024-11-20 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler closed 
https://github.com/llvm/llvm-project/pull/116821
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Support outgoing calls in call hierarchy (PR #77556)

2024-11-20 Thread Christian Kandeler via cfe-commits


@@ -88,56 +89,6 @@
 # CHECK-NEXT: }
 # CHECK-NEXT:  ]
 ---
-{"jsonrpc":"2.0","id":2,"method":"typeHierarchy/subtypes","params":{"item":{"uri":"test:///main.cpp","data":{"parents":[{"parents":[{"parents":[],"symbolID":"FE546E7B648D69A7"}],"symbolID":"ECDC0C46D75120F4"}],"symbolID":"8A991335E4E67D08"},"name":"Child2","kind":23,"range":{"end":{"character":13,"line":3},"start":{"character":7,"line":3}},"selectionRange":{"end":{"character":13,"line":3},"start":{"character":7,"line":3}

ckandeler wrote:

What was the reasoning for removing this entirely?

https://github.com/llvm/llvm-project/pull/77556
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Support outgoing calls in call hierarchy (PR #77556)

2024-11-20 Thread Christian Kandeler via cfe-commits


@@ -2346,11 +2346,11 @@ outgoingCalls(const CallHierarchyItem &Item, const 
SymbolIndex *Index) {
 // Filter references to only keep function calls
 using SK = index::SymbolKind;
 auto Kind = Callee.SymInfo.Kind;
-if (Kind != SK::Function && Kind != SK::InstanceMethod &&
-Kind != SK::ClassMethod && Kind != SK::StaticMethod &&
-Kind != SK::Constructor && Kind != SK::Destructor &&
-Kind != SK::ConversionFunction)
-  return;
+bool NotCall = (Kind != SK::Function && Kind != SK::InstanceMethod &&
+Kind != SK::ClassMethod && Kind != SK::StaticMethod &&
+Kind != SK::Constructor && Kind != SK::Destructor &&
+Kind != SK::ConversionFunction);
+assert(!NotCall);

ckandeler wrote:

Can we get rid of the double negation? It just seems to obfuscate the logic for 
no particular reason.

https://github.com/llvm/llvm-project/pull/77556
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Support outgoing calls in call hierarchy (PR #77556)

2024-11-20 Thread Christian Kandeler via cfe-commits


@@ -2346,11 +2346,11 @@ outgoingCalls(const CallHierarchyItem &Item, const 
SymbolIndex *Index) {
 // Filter references to only keep function calls

ckandeler wrote:

This comment doesn't really apply anymore.

https://github.com/llvm/llvm-project/pull/77556
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Fix erroneous qualification of template type parameters (PR #116821)

2024-11-19 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler edited 
https://github.com/llvm/llvm-project/pull/116821
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Let DefineOutline tweak handle member function templates (PR #112345)

2024-11-19 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler closed 
https://github.com/llvm/llvm-project/pull/112345
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Let DefineOutline tweak handle member function templates (PR #112345)

2024-11-18 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/112345

>From 5b563ceec2c3462a00101526fa416a835a59e7c0 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Mon, 14 Oct 2024 15:37:01 +0200
Subject: [PATCH] [clangd] Let DefineOutline tweak handle member function
 templates

---
 .../clangd/refactor/tweaks/DefineOutline.cpp  | 67 +--
 .../unittests/tweaks/DefineOutlineTests.cpp   | 49 --
 2 files changed, 91 insertions(+), 25 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index 591a8b245260ea..2a96b305bd7a25 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -109,14 +109,13 @@ findContextForNS(llvm::StringRef TargetNS, const 
DeclContext *CurContext) {
 // afterwards it can be shared with define-inline code action.
 llvm::Expected
 getFunctionSourceAfterReplacements(const FunctionDecl *FD,
-   const tooling::Replacements &Replacements) {
+   const tooling::Replacements &Replacements,
+   bool TargetFileIsHeader) {
   const auto &SM = FD->getASTContext().getSourceManager();
   auto OrigFuncRange = toHalfOpenFileRange(
   SM, FD->getASTContext().getLangOpts(), FD->getSourceRange());
   if (!OrigFuncRange)
 return error("Couldn't get range for function.");
-  assert(!FD->getDescribedFunctionTemplate() &&
- "Define out-of-line doesn't apply to function templates.");
 
   // Get new begin and end positions for the qualified function definition.
   unsigned FuncBegin = SM.getFileOffset(OrigFuncRange->getBegin());
@@ -129,24 +128,38 @@ getFunctionSourceAfterReplacements(const FunctionDecl *FD,
   if (!QualifiedFunc)
 return QualifiedFunc.takeError();
 
+  auto Source = QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1);
   std::string TemplatePrefix;
+  auto AddToTemplatePrefixIfApplicable = [&](const Decl *D) {
+const TemplateParameterList *Params = D->getDescribedTemplateParams();
+if (!Params)
+  return;
+for (Decl *P : *Params) {
+  if (auto *TTP = dyn_cast(P))
+TTP->removeDefaultArgument();
+  else if (auto *NTTP = dyn_cast(P))
+NTTP->removeDefaultArgument();
+  else if (auto *TTPD = dyn_cast(P))
+TTPD->removeDefaultArgument();
+}
+std::string S;
+llvm::raw_string_ostream Stream(S);
+Params->print(Stream, FD->getASTContext());
+if (!S.empty())
+  *S.rbegin() = '\n'; // Replace space with newline
+TemplatePrefix.insert(0, S);
+  };
+  AddToTemplatePrefixIfApplicable(FD);
   if (auto *MD = llvm::dyn_cast(FD)) {
 for (const CXXRecordDecl *Parent = MD->getParent(); Parent;
  Parent =
  llvm::dyn_cast_or_null(Parent->getParent())) 
{
-  if (const TemplateParameterList *Params =
-  Parent->getDescribedTemplateParams()) {
-std::string S;
-llvm::raw_string_ostream Stream(S);
-Params->print(Stream, FD->getASTContext());
-if (!S.empty())
-  *S.rbegin() = '\n'; // Replace space with newline
-TemplatePrefix.insert(0, S);
-  }
+  AddToTemplatePrefixIfApplicable(Parent);
 }
   }
 
-  auto Source = QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1);
+  if (TargetFileIsHeader)
+Source.insert(0, "inline ");
   if (!TemplatePrefix.empty())
 Source.insert(0, TemplatePrefix);
   return Source;
@@ -202,7 +215,8 @@ deleteTokensWithKind(const syntax::TokenBuffer &TokBuf, 
tok::TokenKind Kind,
 llvm::Expected
 getFunctionSourceCode(const FunctionDecl *FD, const DeclContext *TargetContext,
   const syntax::TokenBuffer &TokBuf,
-  const HeuristicResolver *Resolver) {
+  const HeuristicResolver *Resolver,
+  bool TargetFileIsHeader) {
   auto &AST = FD->getASTContext();
   auto &SM = AST.getSourceManager();
 
@@ -337,7 +351,8 @@ getFunctionSourceCode(const FunctionDecl *FD, const 
DeclContext *TargetContext,
 
   if (Errors)
 return std::move(Errors);
-  return getFunctionSourceAfterReplacements(FD, DeclarationCleanups);
+  return getFunctionSourceAfterReplacements(FD, DeclarationCleanups,
+TargetFileIsHeader);
 }
 
 struct InsertionPoint {
@@ -419,15 +434,15 @@ class DefineOutline : public Tweak {
 Source->isOutOfLine())
   return false;
 
-// Bail out if this is a function template or specialization, as their
+// Bail out if this is a function template specialization, as their
 // definitions need to be visible in all including translation units.
-if (Source->getDescribedFunctionTemplate())
-  return false;
 if (Source->getTemplateSpecializationInfo())
   return false;
 
 auto *MD = llvm::dyn_cast(Source)

[clang-tools-extra] [clangd] Drop requirement for named template parameters (PR #117565)

2024-11-25 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler created 
https://github.com/llvm/llvm-project/pull/117565

... in DefineOutline tweak for function templates. As opposed to class 
templates, the name is not required for writing an out-of-line definition.

>From 064d23753ed1ac673bda33ab815dbb12c6bcc6f6 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Mon, 25 Nov 2024 15:42:54 +0100
Subject: [PATCH] [clangd] Drop requirement for named template parameters

... in DefineOutline tweak for function templates.
As opposed to class templates, the name is not required for writing an
out-of-line definition.
---
 .../clangd/refactor/tweaks/DefineOutline.cpp   | 13 ++---
 .../unittests/tweaks/DefineOutlineTests.cpp| 18 ++
 2 files changed, 8 insertions(+), 23 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index 789c10bdd4822a..e4eef228b6b99f 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -467,18 +467,9 @@ class DefineOutline : public Tweak {
   }
 }
 
-// For function templates, the same limitations as for class templates
-// apply.
-if (const TemplateParameterList *Params =
-MD->getDescribedTemplateParams()) {
-  // FIXME: Is this really needed? It inhibits application on
-  //e.g. std::enable_if.
-  for (NamedDecl *P : *Params) {
-if (!P->getIdentifier())
-  return false;
-  }
+// Function templates must be defined in the same file.
+if (MD->getDescribedTemplate())
   SameFile = true;
-}
 
 // The refactoring is meaningless for unnamed classes and namespaces,
 // unless we're outlining in the same file
diff --git a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp 
b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
index d2d2ae9e7bb610..b5f09f9b14604f 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
@@ -118,12 +118,6 @@ TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
 template <> void fo^o() {}
   )cpp");
 
-  // Not available on member function templates with unnamed template
-  // parameters.
-  EXPECT_UNAVAILABLE(R"cpp(
-struct Foo { template  void ba^r() {} };
-  )cpp");
-
   // Not available on methods of unnamed classes.
   EXPECT_UNAVAILABLE(R"cpp(
 struct Foo {
@@ -410,14 +404,14 @@ inline typename O1::template O2::E O1::template O2
   {
   R"cpp(
 struct Foo {
-  template 
+  template 
   T ^bar() { return {}; }
 };)cpp",
   R"cpp(
 struct Foo {
-  template 
+  template 
   T bar() ;
-};template 
+};template 
 inline T Foo::bar() { return {}; }
 )cpp",
   ""},
@@ -426,13 +420,13 @@ inline T Foo::bar() { return {}; }
   {
   R"cpp(
 template  struct Foo {
-  template  T ^bar(const T& t, const U& u) { return 
{}; }
+  template  T ^bar(const T& t, const U& u) { 
return {}; }
 };)cpp",
   R"cpp(
 template  struct Foo {
-  template  T bar(const T& t, const U& u) ;
+  template  T bar(const T& t, const U& u) ;
 };template 
-template 
+template 
 inline T Foo::bar(const T& t, const U& u) { return {}; }
 )cpp",
   ""},

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


[clang-tools-extra] [clangd] Drop requirement for named template parameters (PR #117565)

2024-11-26 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler closed 
https://github.com/llvm/llvm-project/pull/117565
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Consolidate two functions converting index to LSP locations (PR #117885)

2024-12-05 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler closed 
https://github.com/llvm/llvm-project/pull/117885
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Store full decl/def range with symbol locations (PR #118102)

2024-12-05 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/118102

>From c44237813fb3357dee3f7d17048a7178e67a2422 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Wed, 27 Nov 2024 13:47:32 +0100
Subject: [PATCH] [clangd] Store full decl/def range with symbol locations

Apart from fixing the linked issue, this is also necessary
for supporting LSP's LocationLink feature and for finding
proper insertion locations in the DefineOutline tweak.
Memory consumption of the background index grows by about ~2.5%.

Closes https://github.com/clangd/clangd/issues/59
---
 clang-tools-extra/clangd/CodeComplete.cpp |   4 +-
 clang-tools-extra/clangd/FindSymbols.cpp  |  34 --
 clang-tools-extra/clangd/FindSymbols.h|   8 +-
 .../clangd/HeaderSourceSwitch.cpp |   4 +-
 clang-tools-extra/clangd/IncludeFixer.cpp |   6 +-
 clang-tools-extra/clangd/Quality.cpp  |   2 +-
 clang-tools-extra/clangd/XRefs.cpp|  65 ++-
 clang-tools-extra/clangd/index/FileIndex.cpp  |   6 +-
 clang-tools-extra/clangd/index/Index.h|   2 +-
 clang-tools-extra/clangd/index/Merge.cpp  |  13 ++-
 clang-tools-extra/clangd/index/Ref.h  |  11 +-
 .../clangd/index/Serialization.cpp|  34 --
 clang-tools-extra/clangd/index/StdLib.cpp |  12 +-
 clang-tools-extra/clangd/index/Symbol.h   |   8 +-
 .../clangd/index/SymbolCollector.cpp  |  89 +++
 .../clangd/index/SymbolCollector.h|   3 +-
 .../clangd/index/SymbolLocation.cpp   |  11 +-
 .../clangd/index/SymbolLocation.h | 103 +++---
 .../clangd/index/YAMLSerialization.cpp|  37 +--
 clang-tools-extra/clangd/index/dex/Dex.cpp|   4 +-
 clang-tools-extra/clangd/refactor/Rename.cpp  |   4 +-
 .../clangd/test/Inputs/symbols.test.yaml  |  17 ++-
 .../index-serialization/Inputs/sample.idx | Bin 470 -> 496 bytes
 .../clangd/test/type-hierarchy-ext.test   |   8 +-
 .../clangd/test/type-hierarchy.test   |   8 +-
 .../clangd/unittests/BackgroundIndexTests.cpp |   4 +-
 .../clangd/unittests/CodeCompleteTests.cpp|  18 +--
 .../clangd/unittests/DexTests.cpp |   5 +-
 .../clangd/unittests/DiagnosticsTests.cpp |  13 ++-
 .../clangd/unittests/FileIndexTests.cpp   |  14 +--
 .../clangd/unittests/IndexTests.cpp   |  45 
 .../clangd/unittests/SerializationTests.cpp   |  23 +++-
 .../clangd/unittests/SymbolCollectorTests.cpp |  12 +-
 33 files changed, 388 insertions(+), 239 deletions(-)

diff --git a/clang-tools-extra/clangd/CodeComplete.cpp 
b/clang-tools-extra/clangd/CodeComplete.cpp
index 2c2d5f0b5ac924..04e4aa2d2d1ca9 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -418,7 +418,7 @@ struct CodeCompletionBuilder {
 auto Inserted = [&](llvm::StringRef Header)
 -> llvm::Expected> {
   auto ResolvedDeclaring =
-  URI::resolve(C.IndexResult->CanonicalDeclaration.FileURI, FileName);
+  URI::resolve(C.IndexResult->CanonicalDeclaration.fileURI(), 
FileName);
   if (!ResolvedDeclaring)
 return ResolvedDeclaring.takeError();
   auto ResolvedInserted = toHeaderFile(Header, FileName);
@@ -451,7 +451,7 @@ struct CodeCompletionBuilder {
   } else
 log("Failed to generate include insertion edits for adding header "
 "(FileURI='{0}', IncludeHeader='{1}') into {2}: {3}",
-C.IndexResult->CanonicalDeclaration.FileURI, Inc.Header, FileName,
+C.IndexResult->CanonicalDeclaration.fileURI(), Inc.Header, 
FileName,
 ToInclude.takeError());
 }
 // Prefer includes that do not need edits (i.e. already exist).
diff --git a/clang-tools-extra/clangd/FindSymbols.cpp 
b/clang-tools-extra/clangd/FindSymbols.cpp
index 84bcbc1f2ddd3f..646cb261309c80 100644
--- a/clang-tools-extra/clangd/FindSymbols.cpp
+++ b/clang-tools-extra/clangd/FindSymbols.cpp
@@ -54,9 +54,19 @@ bool approximateScopeMatch(llvm::StringRef Scope, 
llvm::StringRef Query) {
   return Query.empty();
 }
 
+Range indexToLSPRange(const SymbolPosition &SrcStart,
+  const SymbolPosition &SrcEnd) {
+  Position Start, End;
+  Start.line = SrcStart.line();
+  Start.character = SrcStart.column();
+  End.line = SrcEnd.line();
+  End.character = SrcEnd.column();
+  return {Start, End};
+}
+
 } // namespace
 
-llvm::Expected indexToLSPLocation(const SymbolLocation &Loc,
+llvm::Expected indexToLSPLocation(const SymbolNameLocation &Loc,
 llvm::StringRef TUPath) {
   auto Path = URI::resolve(Loc.FileURI, TUPath);
   if (!Path)
@@ -64,17 +74,21 @@ llvm::Expected indexToLSPLocation(const 
SymbolLocation &Loc,
  Path.takeError());
   Location L;
   L.uri = URIForFile::canonicalize(*Path, TUPath);
-  Position Start, End;
-  Start.line = Loc.Start.line();
-  Start.character = Loc.Start.column();
-  End

[clang-tools-extra] [clangd] Consider expression statements in ExtractVariable tweak (PR #112525)

2024-12-09 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

> In the expression-statement case, the expression isn't moving to a new 
> location, and the variable name is only mentioned in 
> one place. In essence, the refactoring amounts to prepending `auto 
> placeholder = ` to the expression. Given that you're 
> going to be (very likely) renaming `placeholder` anyways, does this really 
> add anything meaningful over just typing `auto 
> VariableNameYouWant = ` "manually"?

My thinking was that because the expression is assignable and it's not clearly 
pointless to do so, the tweak should be available (plus it still saves some 
keystrokes). My concrete motivation was due to user requests on the client 
side, e.g.:
https://bugreports.qt.io/browse/QTCREATORBUG-9363
https://bugreports.qt.io/browse/QTCREATORBUG-9578
Maybe some developers have the habit of writing just the rhs of an init 
statement and then let tooling insert the lhs? It's possible, I suppose. E.g. 
if the return type is complex and you want to have it spelt out in the 
declaration (as per the project's coding conventions), then you could apply 
this tweak and then the ExpandDeducedType one.
In general, I'm not a big fan of going out of my way to prevent users from 
doing something. And once you start deliberating about degrees of usefulness, 
you quickly run into problems deciding where to draw the line.



https://github.com/llvm/llvm-project/pull/112525
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Store full decl/def range with symbol locations (PR #118102)

2025-02-10 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

ping

https://github.com/llvm/llvm-project/pull/118102
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   >