352 Commits

Author SHA1 Message Date
Kazu Hirata
ccd5ddab9b
[clang-tools-extra] Replace SmallSet with SmallPtrSet (NFC) (#154365)
This patch replaces SmallSet<T *, N> with SmallPtrSet<T *, N>.  Note
that SmallSet.h "redirects" SmallSet to SmallPtrSet for pointer
element types:

  template <typename PointeeType, unsigned N>
class SmallSet<PointeeType*, N> : public SmallPtrSet<PointeeType*, N>
{};

We only have 10 instances that rely on this "redirection", with more
than half of them under clang-tools-extra/.  Since the redirection
doesn't improve readability, this patch replaces SmallSet with
SmallPtrSet for pointer element types.

I'm planning to remove the redirection eventually.
2025-08-19 09:09:03 -07:00
Matheus Izvekov
91cdd35008
[clang] Improve nested name specifier AST representation (#147835)
This is a major change on how we represent nested name qualifications in
the AST.

* The nested name specifier itself and how it's stored is changed. The
prefixes for types are handled within the type hierarchy, which makes
canonicalization for them super cheap, no memory allocation required.
Also translating a type into nested name specifier form becomes a no-op.
An identifier is stored as a DependentNameType. The nested name
specifier gains a lightweight handle class, to be used instead of
passing around pointers, which is similar to what is implemented for
TemplateName. There is still one free bit available, and this handle can
be used within a PointerUnion and PointerIntPair, which should keep
bit-packing aficionados happy.
* The ElaboratedType node is removed, all type nodes in which it could
previously apply to can now store the elaborated keyword and name
qualifier, tail allocating when present.
* TagTypes can now point to the exact declaration found when producing
these, as opposed to the previous situation of there only existing one
TagType per entity. This increases the amount of type sugar retained,
and can have several applications, for example in tracking module
ownership, and other tools which care about source file origins, such as
IWYU. These TagTypes are lazily allocated, in order to limit the
increase in AST size.

This patch offers a great performance benefit.

It greatly improves compilation time for
[stdexec](https://github.com/NVIDIA/stdexec). For one datapoint, for
`test_on2.cpp` in that project, which is the slowest compiling test,
this patch improves `-c` compilation time by about 7.2%, with the
`-fsyntax-only` improvement being at ~12%.

This has great results on compile-time-tracker as well:

![image](https://github.com/user-attachments/assets/700dce98-2cab-4aa8-97d1-b038c0bee831)

This patch also further enables other optimziations in the future, and
will reduce the performance impact of template specialization resugaring
when that lands.

It has some other miscelaneous drive-by fixes.

About the review: Yes the patch is huge, sorry about that. Part of the
reason is that I started by the nested name specifier part, before the
ElaboratedType part, but that had a huge performance downside, as
ElaboratedType is a big performance hog. I didn't have the steam to go
back and change the patch after the fact.

There is also a lot of internal API changes, and it made sense to remove
ElaboratedType in one go, versus removing it from one type at a time, as
that would present much more churn to the users. Also, the nested name
specifier having a different API avoids missing changes related to how
prefixes work now, which could make existing code compile but not work.

How to review: The important changes are all in
`clang/include/clang/AST` and `clang/lib/AST`, with also important
changes in `clang/lib/Sema/TreeTransform.h`.

The rest and bulk of the changes are mostly consequences of the changes
in API.

PS: TagType::getDecl is renamed to `getOriginalDecl` in this patch, just
for easier to rebasing. I plan to rename it back after this lands.

Fixes #136624
Fixes https://github.com/llvm/llvm-project/issues/43179
Fixes https://github.com/llvm/llvm-project/issues/68670
Fixes https://github.com/llvm/llvm-project/issues/92757
2025-08-09 05:06:53 -03:00
Marco Maia
4072a6b85b
Reland "[clangd] Add tweak to override pure virtuals" (#150788)
This relands commit
7355ea3f6b.

The original commit was reverted in
bfd73a5161
because it was breaking the buildbot.

The issue has now been resolved by
38f82534bb.

Original PR: https://github.com/llvm/llvm-project/pull/139348
Original commit message:
<blockquote>

closes https://github.com/clangd/clangd/issues/1037 
closes https://github.com/clangd/clangd/issues/2240

Example:

```c++
class Base {
public:
  virtual void publicMethod() = 0;

protected:
  virtual auto privateMethod() const -> int = 0;
};

// Before:
//                        // cursor here
class Derived : public Base{}^ ;

// After:
class Derived : public Base {
public:
  void publicMethod() override {
    // TODO: Implement this pure virtual method.
    static_assert(false, "Method `publicMethod` is not implemented.");
  }

protected:
  auto privateMethod() const -> int override {
    // TODO: Implement this pure virtual method.
    static_assert(false, "Method `privateMethod` is not implemented.");
  }
};
```


https://github.com/user-attachments/assets/79de40d9-1004-4c2e-8f5c-be1fb074c6de

</blockquote>
2025-07-28 09:31:12 +02:00
Qinkun Bao
bfd73a5161
Revert "[clangd] Add tweak to override pure virtuals (#139348)" (#150404)
This reverts commit 7355ea3f6b214d1569da43d02f9a166ff15012e6.

Buildbot failures:

UBsan
https://lab.llvm.org/buildbot/#/builders/25/builds/10010
Fast
https://lab.llvm.org/buildbot/#/builders/169/builds/13150
2025-07-24 07:29:58 -04:00
Marco Maia
7355ea3f6b
[clangd] Add tweak to override pure virtuals (#139348)
closes https://github.com/clangd/clangd/issues/1037 
closes https://github.com/clangd/clangd/issues/2240

Example:

```c++
class Base {
public:
  virtual void publicMethod() = 0;

protected:
  virtual auto privateMethod() const -> int = 0;
};

// Before:
//                        // cursor here
class Derived : public Base{}^ ;

// After:
class Derived : public Base {
public:
  void publicMethod() override {
    // TODO: Implement this pure virtual method.
    static_assert(false, "Method `publicMethod` is not implemented.");
  }

protected:
  auto privateMethod() const -> int override {
    // TODO: Implement this pure virtual method.
    static_assert(false, "Method `privateMethod` is not implemented.");
  }
};
```


https://github.com/user-attachments/assets/79de40d9-1004-4c2e-8f5c-be1fb074c6de

---------

Co-authored-by: Marco Maia <marco.maia@iarasystems.com.br>
2025-07-21 09:36:08 +02:00
Yanzuo Liu
4a9eaad9e1
[Clang][AST][NFC] Introduce NamespaceBaseDecl (#149123)
Add `NamespaceBaseDecl` as common base class of `NamespaceDecl` and
`NamespaceAliasDecl`. This simplifies `NestedNameSpecifier` a bit.

Co-authored-by: Matheus Izvekov <mizvekov@gmail.com>
2025-07-18 09:01:47 +08:00
Kazu Hirata
0f1accd806
[clangd] Drop const from a return type (NFC) (#146707)
We don't need const on the return type.
2025-07-02 09:32:23 -07:00
Kazu Hirata
838b91d7f6
[clangd] Drop const from a return type (NFC) (#146623)
We don't need const on a return type.
2025-07-01 22:49:56 -07:00
Longsheng Mou
52360d195b
[NFC] Use llvm::includes instead of std::includes (#143542)
This PR follows up #143297.
2025-06-12 09:27:27 +08:00
Kazu Hirata
1a40edf2c0
[clang-tools-extra] Use llvm::find_if (NFC) (#140411) 2025-05-17 17:01:37 -07:00
Kazu Hirata
9bcb18db89
[clangd] Use llvm::unique (NFC) (#136470) 2025-04-19 20:34:03 -07:00
Matheus Izvekov
49fd0bf35d
[clang] support pack expansions for trailing requires clauses (#133190) 2025-04-03 12:36:15 -03:00
Alex Hoppen
3bcbb47258
[clangd] Use SymbolName to represent Objective-C selectors (#82061)
This is a cleaner design than using identifier and an optional `Selector`. It also allows rename of Objective-C method names if no declaration is at hand and thus no `Selector` instance can be formed. For example, when finding the ranges to rename based on an index that’s not clangd’s built-in index.
2025-03-25 14:34:00 -04:00
erichkeane
52552ce53b Reapply "[NFC] Change the return type of getTraversalScope to ArrayRef"
vitalybuka identified a fix here that fixes the issue, and lets us make
fewer copies!  This applies his patch plus reapplys the original.

This reverts commit c4c29b95a6e6809017e71e85f33faecfe85d88b2.
2025-03-06 09:43:37 -08:00
Ujan RoyBandyopadhyay
440ea3ecdc
[clangd] Reduce superfluous rename conflicts (#121515)
This commit adds a namespace check to the code for detecting name
collisions, allowing `bar` to be renamed to `foo` in the following
snippet:

```c
typedef struct foo {} Foo;
Foo bar;
```

Previously, such a rename would fail because a declaration for `foo`
already exists in the same scope.
2025-02-27 13:06:03 -06:00
Christian Kandeler
8d714db7f9
[clangd] Consider expression statements in ExtractVariable tweak (#112525)
For instance:
  int func();
  int main()
  {
    func(); // => auto placeholder = func();
  }
2024-12-11 10:58:22 +01:00
Christian Kandeler
9acd8e3810
[clangd] Drop requirement for named template parameters (#117565)
... in DefineOutline tweak for function templates. As opposed to class
templates, the name is not required for writing an out-of-line
definition.
2024-11-26 10:11:07 +01:00
Christian Kandeler
5310855316
[clangd] Fix erroneous qualification of template type parameters (#116821)
...in DefineOutline tweak.
E.g. moving the following definition:
  `template<typename T> struct S { T f^oo() const { return T(); } };`
would result in:
 `template<typename T> S<T>::T S::foo() const { return T(); }`
instead of:
  `template<typename T> T S::foo() const { return T(); }`
2024-11-20 10:15:29 +01:00
Christian Kandeler
8a6a76b1e1
[clangd] Let DefineOutline tweak handle member function templates (#112345) 2024-11-19 12:47:15 +01:00
Julian Schmidt
9ae21b073a
[clangd] fix extract-to-function for overloaded operators (#81640)
When selecting code that contains the use of overloaded operators,
the SelectionTree will attribute the operator to the operator
declaration, not to the `CXXOperatorCallExpr`. To allow
extract-to-function to work with these operators, make unselected
`CXXOperatorCallExpr`s valid root statements, just like `DeclStmt`s.

Partially fixes clangd/clangd#1254

---------

Co-authored-by: Nathan Ridge <zeratul976@hotmail.com>
2024-11-15 01:05:20 -05:00
Thomas Fransham
b735c66da9
Reland 'Update llvm::Registry to work for LLVM shared library builds on windows' (#109024) (#112640)
Fix missing extern templates for llvm::Registry use in other projects of
llvm

Windows doesn't implicitly import and merge exported symbols across
shared libraries
like Linux does so we need to explicitly export/import each
instantiation of llvm::Registry.
Updated LLVM_INSTANTIATE_REGISTRY to just be a full explicit template
instantiation.

This is part of the work to enable LLVM_BUILD_LLVM_DYLIB and LLVM
plugins on window.
2024-10-22 10:29:27 +03:00
Christian Kandeler
0cfa6e2092
[clangd] Let DefineOutline tweak handle member functions (#95235)
... of class templates.
2024-10-14 11:00:02 +02:00
Simon Pilgrim
992e75403f Fix MSVC "not all control paths return a value" warning. NFC. 2024-10-04 09:54:13 +01:00
Tor Shepherd
81fcdc6359
[clangd] Add CodeAction to swap operands to binary operators (#78999)
This MR resolves https://github.com/llvm/llvm-project/issues/78998
2024-10-03 18:34:02 +02:00
Utkarsh Saxena
5f1adf0433
[clangd] Fix crash with null check for Token at Loc (#94528)
Fixes https://github.com/llvm/llvm-project/issues/94599
2024-06-07 11:08:25 +02:00
Christian Kandeler
955c223762
[clangd] Allow "move function body out-of-line" in non-header files (#69704)
Moving the body of member functions out-of-line makes sense for classes
defined in implementation files too.
2024-06-03 14:48:53 +02:00
Fangrui Song
4cfe347c10 [clangd] Fix -Wunused-but-set-variable after #82396 2024-05-14 12:58:49 -07:00
Julian Schmidt
8d946c7171
[clangd] use existing functions for code locations in the scopify enum tweak (#88737)
Clangd already implements some utility functions for converting between
`SourceLocation`s, `Position`s and `Offset`s into a buffer.
2024-05-03 18:23:13 +02:00
Christian Kandeler
f2daa32fca
[clangd] Remove potential prefix from enum value names (#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.
2024-05-02 13:18:59 +02:00
David Goldman
ec7062d9d8
[clangd] Add metric for rename decl kind (#83867)
This will give us insight into what users are renaming in practice - for
instance, try to gauge the impact of the ObjC rename support.
2024-03-05 11:10:57 -05:00
David Goldman
59e5519c81
[clangd] Fix renaming single argument ObjC methods (#82396)
Use the legacy non-ObjC rename logic when dealing with selectors that
have zero or one arguments. In addition, make sure we don't add an extra
`:` during the rename.

Add a few more tests to verify this works (thanks to @ahoppen for the
tests and finding this bug).
2024-02-23 14:11:39 -05:00
Christian Kandeler
c9974ae4a0
[clangd] Do not offer extraction to variable for decl init expression (#69477)
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).
2024-02-19 20:00:24 +01:00
David Goldman
edfc859af8
Add support for renaming objc methods, even those with multiple selector pieces (#76466)
This adds support for  renaming Objective-C methods, which are unique since their method names can be split across multiple tokens.
2024-02-15 15:53:37 -05:00
Kazu Hirata
d5953e3e30 [clangd] Use StringRef::{starts,ends}_with (NFC)
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.

I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
2023-12-13 23:26:09 -08:00
Björn Pettersson
5bd0f0d9d6
[clangd] Check for valid location in ExtractionContext::exprIsValidOutside (#71162)
If the code has a call to an implicitly declared function, an expression
could end up referencing declarations without valid source locations. So
when doing the exprIsValidOutside check we could end up calling
SourceManager::isPointWithin using invalid source locations, and then a
debug build would crash with an assertion failure in
SourceManager::isBeforeInTranslationUnit.

This patch make sure that we deal with the invalid locations (by
considering a ReferencedDecl with invalid location as not being inside
the Scope).
2023-11-11 01:53:18 -05:00
Kadir Cetinkaya
ec095b7424
[clangd] Fix builds after 0255b217c3766ce0aa23bd4fb050b447be2a1d26 2023-11-10 13:55:43 +01:00
ckandeler
0255b217c3
[clangd] Add tweak for turning an unscoped into a scoped enum (#69481) 2023-11-10 10:02:05 +01:00
Vlad Serebrennikov
cd6022916b [clang][NFC] Refactor ConstantExpr::ResultStorageKind
This patch converts `ConstantExpr::ResultStorageKind` to a scoped enum in namespace scoped `ConstantResultStorageKind`. This patch makes it possible to forward-declare this enum where it's necessery, e.g. for `preferred_type` annotation for bit-fields.
2023-11-04 13:28:29 +03:00
Vlad Serebrennikov
edd690b02e
[clang][NFC] Refactor TagTypeKind (#71160)
This patch converts TagTypeKind into scoped enum. Among other benefits,
this allows us to forward-declare it where necessary.
2023-11-03 21:45:39 +04:00
robozati
2f3d4f6c98
[clangd] Do not offer RawStringLiteral code action in C and C++98 (#69775)
Raw string literals are a C++ feature first added in C++11.

Fixes https://github.com/clangd/clangd/issues/1795.
2023-10-24 17:29:43 -04:00
Julian Schmidt
94b14355e2 [clangd] allow extracting to variable for lambda expressions
Support for extracting lambda expressions, e.g. extracting a lambda from a callexpr (e.g. algorithms/ranges) to a named variable.

Reviewed By: nridge

Differential Revision: https://reviews.llvm.org/D141757
2023-09-11 04:03:38 -04:00
Jon Roelofs
2fb1c1082c
cmake: add missing dependencies on ClangDriverOptions tablegen
The modules build trips over this frequently because there is no textual
include of the tablegen output, but the module includes it.

Differential revision: https://reviews.llvm.org/D157119
2023-08-04 10:27:19 -07:00
Haojian Wu
5649b24c48 [clangd] Fix an assertion failure in NamedDecl::getName during the prepareRename
getName method required to be called on a simple-identifier NamedDecl,
otherwise it will trigger an assertion.

Reviewed By: kadircet

Differential Revision: https://reviews.llvm.org/D153617
2023-07-14 09:17:46 +02:00
Mariya Podchishchaeva
8b4a27f410 [clangd][NFC] Remove dead code
refactor/tweaks/ExtractVariable.cpp:
Condition (!C++ && !ExprType) is never true because if ExprType was null
we would early-exit earlier.

tool/ClangdMain.cpp:
StaticIdx variable is not initialized before check, so checking it
doesn't make sense.

Found by static analyzer tool.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D155164
2023-07-13 06:47:49 -04:00
David Goldman
1b66840f71 [clangd][ObjC] Support ObjC class rename from implementation decls
Reviewed By: kadircet

Differential Revision: https://reviews.llvm.org/D152720
2023-06-26 14:43:37 -04:00
Haojian Wu
be8da1f6e6 [clangd] Use FileManager for getCanonicalPath, NFC
get rid of the SourceManager dependency -- getCanonicalPath doesn't use
other SourceManager fields.
2023-06-02 12:55:21 +02:00
Brian Gluzman
fe7afcf70c
[clangd] Remove inline Specifier for DefineOutline Tweak
`inline` specifiers should be removed from from the function declaration and
the newly-created implementation.

For example, take the following (working) code:
```cpp
// foo.hpp
struct A {
  inline void foo() { std::cout << "hello world\n" << std::flush; }
};

// foo.cpp
#include "foo.hpp"

// main.cpp
#include "foo.hpp"

int main() {
  A a;
  a.foo();
  return 0;
}

// compile: clang++ -std=c++20 main.cpp foo.cpp -o main
```

After applying the tweak:
```
// foo.hpp
struct A {
  inline void foo();
};

// foo.cpp
#include "foo.hpp"

inline void A::foo() { std::cout << "hello world\n" << std::flush; }

// main.cpp
#include "foo.hpp"

int main() {
  A a;
  a.foo();
  return 0;
}

// compile: clang++ -std=c++20 main.cpp foo.cpp -o main
```

We get a link error, as expected:
```
/usr/bin/ld: /tmp/main-4c5d99.o: in function `main':
main.cpp:(.text+0x14): undefined reference to `A::foo()'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```

This revision removes these specifiers from both the header and the source file. This was identified in Github issue llvm/llvm-project#61295.

Reviewed By: kadircet

Differential Revision: https://reviews.llvm.org/D151294
2023-05-26 10:43:08 +02:00
Kadir Cetinkaya
51df1a9ac9
[clangd] Fix add-using tweak on declrefs with template arguments
Differential Revision: https://reviews.llvm.org/D151303
2023-05-24 09:56:53 +02:00
Christian Kandeler
008cb29f87 [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
2023-05-22 12:50:38 +02:00
Kazu Hirata
38d8b1f2b4 [clangd] Replace None with std::nullopt in comments (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-05-06 00:02:53 -07:00