61 Commits

Author SHA1 Message Date
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
Nathan Ridge
392bd577e3
[clangd] Guard against trivial FunctionProtoTypeLoc when creating inlay hints (#143087)
Fixes https://github.com/llvm/llvm-project/issues/142608
2025-06-09 00:33:20 -04:00
Mythreya
665914fea1
[clangd] Improve BlockEnd inlayhint presentation (#136106)
* Only show for blocks 10 lines or taller (including braces)
 * Add parens for function call: "// if foo" -> "// if foo()" or "// if foo(...)"
 * Print literal nullptr
 * Escaping for abbreviated strings

Fixes https://github.com/clangd/clangd/issues/1807.

Based on the original PR at https://github.com/llvm/llvm-project/pull/72345.

Co-authored-by: daiyousei-qz <qyzheng2@outlook.com>
2025-04-23 02:36:48 -04:00
Owen Anderson
6d765e1c91
Reapply 19c708c "FunctionDecl::getFunctionTypeLoc: ignore function type attributes (#118420)" (#136484)
Avoid using PreservesMost in the testcase as it is not supported on all
targets.

Original PR #118290.

Co-authored-by: Robert Dazi <14996868+v01dXYZ@users.noreply.github.com>
Co-authored-by: v01dxyz <v01dxyz@v01d.xyz>
2025-04-22 10:23:27 +12:00
Owen Anderson
a15ef95de4 Revert "FunctionDecl::getFunctionTypeLoc: ignore function type attributes (#118420)"
This reverts commit 19c708c18963ac24822564824cb5401e71a49943 because it caused test failures on non-x86 targets.
2025-04-20 00:01:53 +12:00
Robert Dazi
19c708c189
FunctionDecl::getFunctionTypeLoc: ignore function type attributes (#118420)
Related to #118290.

---------

Co-authored-by: v01dxyz <v01dxyz@v01d.xyz>
Co-authored-by: Owen Anderson <resistor@mac.com>
2025-04-19 23:39:18 +12:00
Nathan Ridge
5518bb215b
[clangd] Check getFunctionTypeLoc() for validity in InlayHintVisitor (#117296)
Fixes https://github.com/clangd/clangd/issues/2223
2024-11-22 03:11:07 -05:00
Tor Shepherd
2eb1699184
[clangd] Add inlay hints for default function arguments (#95712)
The new inlay hints have the `DefaultArguments` kind and can be enabled in config similar to other inlay kint kinds.
2024-10-19 18:19:01 -04:00
Mital Ashok
482c41e992
[Clang] [Sema] Diagnose unknown std::initializer_list layout in SemaInit (#95580)
This checks if the layout of `std::initializer_list` is something Clang
can handle much earlier and deduplicates the checks in
CodeGen/CGExprAgg.cpp and AST/ExprConstant.cpp

Also now diagnose `union initializer_list` (Fixes #95495), bit-field for
the size (Fixes a crash that would happen during codegen if it were
unnamed), base classes (that wouldn't be initialized) and polymorphic
classes (whose vtable pointer wouldn't be initialized).
2024-06-20 19:44:06 +02:00
Younan Zhang
c6a65e4b0c
[clangd] Support go-to-definition on type hints. The protocol part (#85497)
This is in preparation for implementing go-to-definition support on type
inlay hints, switching the `label` field within the InlayHint protocol from a
string to an array of `InlayHintLabelPart`.
2024-03-26 12:57:09 +08:00
Nathan Ridge
dbd1fb8e6f
[clangd] Avoid crash when summarizing pointer-to-member expr for block-end hint (#76492)
For calls through a pointer to member, CXXMemberCallExpr::getCallee() is
a BinaryOperator with operator ->* (after unwrapping parens).

getMethodDecl() only returns non-null if the callee is a MemberExpr.

Fixes https://github.com/clangd/clangd/issues/1873
2023-12-29 02:18:48 -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
Younan Zhang
0fc69b1402
[clangd] Carefully handle PseudoObjectExprs for inlay hints (#71366)
Not all subexpressions for a PseudoObjectExpr are interesting, and they
probably mess up inlay hints.

Fixes https://github.com/clangd/clangd/issues/1813.
2023-12-03 02:27:45 -05:00
Younan Zhang
4a540ceed4
[clangd] Adapt Inlay Hint support for Deducing This (#68177)
This is a follow-up for D140828, making Clangd omit the explicit object
parameter in a call to member function with Deducing This.

Given that the parent patch is still in its infancy and might undergo
several reverting-relanding processes, one can feel free to revert this
if encountering any CI failure. And please let me know if I should alter
anything.
2023-10-24 09:51:43 +08:00
Younan Zhang
cbd6ac6165 [clangd] Show parameter hints for operator()
Closes https://github.com/clangd/clangd/issues/1742

Reviewed By: nridge

Differential Revision: https://reviews.llvm.org/D158926
2023-09-10 15:56:00 +08:00
Yuanjing Hong
dc10bd43a1 [clangd] don't add inlay hint for dependent type in structured binding
Currently clangd will display useless inlay hint for dependent type in
structured binding, e.g.

```
template <class T>
void foobar(T arg) {
  auto [a/*: <dependent type>*/, b/*: <dependent type>*/] = arg;
}
```

Differential Revision: https://reviews.llvm.org/D157956
2023-08-21 11:10:40 +08:00
Nathan Ridge
8ee710a40c [clangd] Parameter hints for calls through function pointers
Fixes https://github.com/clangd/clangd/issues/1734

Differential Revision: https://reviews.llvm.org/D158249
2023-08-18 23:40:59 -04:00
Younan Zhang
b1193c13a5 [clangd] Avoid unexpected desugaring in isSugaredTemplateParameter
This is a follow-up to D151785, addressing https://github.com/clangd/clangd/issues/1703.

The previous approach of peeling pointer types during a traversal
using getPointeeType might have produced unexpected results; since
the method would implicitly desugar the type if the type being passed
in could not be cast to a Pointer-like Type.

Reviewed By: nridge

Differential Revision: https://reviews.llvm.org/D156300
2023-08-01 20:12:35 +08:00
Sam McCall
ee032bccc9 [clangd] Add BlockEnd comments for control flow statements
These mark the end of CompoundStmts bodies of if/while/for/switch.
To identify which statement is being ended, we include abbreviated
text of the condition/loop variable.

Differential Revision: https://reviews.llvm.org/D155421
2023-07-21 22:57:46 +02:00
daiyousei-qz
9e6a342fda [clangd] Implement end-definition-comment inlay hints
This patch implements a new inlay hint feature proposed in https://github.com/clangd/clangd/issues/1634. It introduces a new inlay hint kind BlockEnd which shows a comment-like hint after a definition brace pair, including function/type/namespace. For example,
```
void foo() {
} ^
```
In the code shown above, a hint should be displayed at ^ labelling `// foo`. Such hint only shows when there's no trailing character after the position except whitespaces and optionally ';'.

Also, new configurations are introduced in the inlay hints block
```
InlayHints:
    BlockEnd: Yes # toggling the feature
```

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D150635
2023-07-16 01:19:02 +02:00
Younan Zhang
5cdb906f1e [clangd] Unify printing policy for type hints
(This patch addresses the comment from https://reviews.llvm.org/D151785#4402460.)

Previously, we used a special printing policy that enabled `PrintCanonicalTypes`
to print type hints for structure bindings. This was intended to
eliminate type aliases like `tuple_element::type`. However, this also
caused TypePrinter to print default template arguments, which could
result in losing the ability to see types like `std::basic_string<char>`
if the fully expanded template-id exceeded the default inlay hint threshold.

Simply getting the canonical type at the call site could help us get rid of
the side effect.

This also merges overloaded `addTypeHint` into one function without
`PrintingPolicy`.

Reviewed By: nridge

Differential Revision: https://reviews.llvm.org/D152520
2023-06-13 21:31:10 +08:00
Younan Zhang
7d68f2ef41 [clangd] Desugar template parameter aliases in type hints
This patch alleviates https://github.com/clangd/clangd/issues/1298.

Containers in C++ such as `std::vector` or `llvm::SmallVector`,
introduce a series of type aliases to adapt to generic algorithms.

Currently, If we write an declarator involving expressions with
these containers and `auto` placeholder, we probably obtain opaque
type alias like following:

```
std::vector<int> v = {1, 2, 3};
auto value = v[1]; // hint for `value`: value_type
auto *ptr = &v[0]; // hint for `ptr`: value_type *
```

These hints are useless for most of the time. It would be nice if we
desugar the type of `value_type` and print `int`, `int *` respectively
in this situation. But note we can't always prefer desugared type
since user might introduce type-aliases for brevity, where printing
sugared types makes more sense.

This patch introduces a heuristic method that displays the desugared
type that is an alias of template parameter. It merges
analogous method `shouldPrintCanonicalType` into `maybeDesugar` as well.

Previous commit for shouldPrintCanonicalType: dde8a0fe91cc

Reviewed By: nridge

Differential Revision: https://reviews.llvm.org/D151785
2023-06-13 19:15:24 +08:00
zhangyi1357
2ae1aa9da7 [Clangd] Make the type hint length limit configurable
This commit is about clangd's type name hint length limit. The past behavior was 32 characters fixed limit. It is now configurable.

Projects can now add the following config fragment to their .clangd:

```
InlayHints:
  TypeNameLimit: 34
```

Ref: [[ https://github.com/clangd/clangd/issues/1357  | Make the type hint length limit configurable ]]

Reviewed By: hokein

Differential Revision: https://reviews.llvm.org/D147395
2023-04-20 15:21:48 +02:00
Younan Zhang
cb2d04d41e [clangd] Hide inlay hints when using a macro as a calling argument that with a param comment
We don't want to produce inlay hints for arguments for which
user has left param name comments. But we're not decomposing
location of the parameter correctly at the moment because the
location we've passed into `SM.getDecomposedLoc` is not always
FileID.

Fixes clangd/clangd#1495

Reviewed By: nridge

Differential Revision: https://reviews.llvm.org/D144074
2023-02-26 19:06:44 +08:00
Nathan Ridge
89590cd1fe [clangd] Fix test failure in TypeHints.Decltype 2023-01-30 02:08:02 -05:00
Nathan Ridge
68d7f69001 [clangd] Don't show 'auto' type hint when type deduction fails
Fixes https://github.com/clangd/clangd/issues/1475

Differential Revision: https://reviews.llvm.org/D142440
2023-01-30 01:21:09 -05:00
Haojian Wu
f7e9d5b43e [clangd] Fix an inlay-hint crash on a null deduced type. 2023-01-08 15:48:04 +01:00
v1nh1shungry
dde8a0fe91 [clangd] show underlying type in type hint for decltype(expr)
Reviewed By: nridge

Differential Revision: https://reviews.llvm.org/D140814
2023-01-03 13:58:39 -05:00
v1nh1shungry
4b2cf982cc [clangd] Support type hints for decltype(expr)
Reviewed By: nridge

Differential Revision: https://reviews.llvm.org/D138300
2022-12-19 16:10:26 -05:00
Kazu Hirata
649ef3386b [clang-tools-extra] Use std::nullopt instead of llvm::None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

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
2022-12-05 21:49:31 -08:00
Sam McCall
924974a3a1 [clangd] Improve inlay hints of things expanded from macros
When we aim a hint at some expanded tokens, we're only willing to attach it
to spelled tokens that exactly corresponde.

e.g.
int zoom(int x, int y, int z);
int dummy = zoom(NUMBERS);

Here we want to place a hint "x:" on the expanded "1", but we shouldn't
be willing to place it on NUMBERS, because it doesn't *exactly*
correspond (it has more tokens).

Fortunately we don't even have to implement this algorithm from scratch,
TokenBuffer has it.

Fixes https://github.com/clangd/clangd/issues/1289
Fixes https://github.com/clangd/clangd/issues/1118
Fixes https://github.com/clangd/clangd/issues/1018

Differential Revision: https://reviews.llvm.org/D133982
2022-09-19 16:44:21 +02:00
Haojian Wu
06b97b4985 [clangd] Fix an inlay-hint crash on a broken designator.
Differential Revision: https://reviews.llvm.org/D131696
2022-08-12 14:37:46 +02:00
Kadir Cetinkaya
4839929bed
[clangd] Make forwarding parameter detection logic resilient
This could crash when our heuristic picks the wrong function. Make sure
there is enough parameters in the candidate to prevent those crashes.

Also special case copy/move constructors to make the heuristic work in
presence of those.

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

Differential Revision: https://reviews.llvm.org/D130260
2022-07-22 14:37:13 +02:00
Tobias Ribizel
a638648fef
[clangd] add inlay hints for std::forward-ed parameter packs
This adds special-case treatment for parameter packs in
make_unique-like functions to forward parameter names to inlay hints.
The parameter packs are being resolved recursively by traversing the
function body of forwarding functions looking for expressions matching
the (std::forwarded) parameters expanded from a pack.
The implementation checks whether parameters are being passed by
(rvalue) reference or value and adds reference inlay hints accordingly.
The traversal has a limited recursion stack depth, and recursive calls
like std::make_tuple are cut off to avoid hinting duplicate parameter
names.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D124690
2022-07-06 22:23:18 +02:00
Tobias Ribizel
e984e1cd61
[clangd] Don't add inlay hints on std::move/forward
This removes parameter inlay hints from a few builtin functions like std::move/std::forward

Reviewed By: nridge

Differential Revision: https://reviews.llvm.org/D127859
2022-06-16 12:24:16 +02:00
Kadir Cetinkaya
3137ca80b9
[clangd] Support for standard inlayHint protocol
- Make clangd's internal representation more aligned with the standard.
  We keep range and extra inlayhint kinds around, but don't serialize
  them on standard version.
- Have custom serialization for extension (ugly, but going to go away).
- Support both versions until clangd-17.
- Don't advertise extension if client has support for standard
  implementation.
- Log a warning at startup about extension being deprecated, if client
  doesn't have support.

Differential Revision: https://reviews.llvm.org/D125228
2022-05-10 18:59:15 +02:00
Sam McCall
6385c039b8 [clangd] Fix inlayhints crash, don't assume functions have FunctionTypeLocs
Fixes https://github.com/clangd/clangd/issues/1140
2022-05-05 18:51:36 +02:00
Tobias Ribizel
043e965024 [clangd] Add inlay hints for mutable reference parameters
Add a & prefix to all parameter inlay hints that refer to a non-const l-value reference. That makes it easier to identify them even if semantic highlighting is not used (where this is already available)

Reviewed By: nridge

Differential Revision: https://reviews.llvm.org/D124359
2022-05-02 15:57:23 -04:00
Sam McCall
2da5c5781e [clangd] Add inlay hints for auto-typed parameters with one instantiation.
This takes a similar approach as b9b6938183e, and shares some code.
The code sharing is limited as inlay hints wants to deduce the type of the
variable rather than the type of the `auto` per-se.

It drops support (in both places) for multiple instantiations yielding the same
type, as this is pretty rare and hard to build a nice API around.

Differential Revision: https://reviews.llvm.org/D120258
2022-03-23 17:26:25 +01:00
Sam McCall
42cb812da7 [clangd] Test fixes missing from 257559ed9 2022-02-26 21:38:25 +01:00
Sam McCall
257559ed9a [clangd] Function return type hints: support lambdas, don't duplicate "->"
While here, fix an ugliness:
  auto foo()->auto { return 42; }
This (silly) code gains a "-> int" hint. While correct and useful, it renders as
  auto foo()->int->auto { return 42; }
which is confusing enough to do more harm than good I think.

Differential Revision: https://reviews.llvm.org/D120416
2022-02-26 21:28:09 +01:00
Sam McCall
ce94432702 [clangd] Add designator inlay hints for initializer lists.
These make the init lists appear as if designated initialization was used.

Example:
  ExpectedHint{"param: ", "arg"}
becomes
  ExpectedHint{.Label="param: ", .RangeName="arg"}

Differential Revision: https://reviews.llvm.org/D116786
2022-01-26 00:35:29 +01:00
Sam McCall
16fd5c2784 [clangd] Support configuration of inlay hints.
The idea is that the feature will always be advertised at the LSP level, but
depending on config we'll return partial or no responses.

We try to avoid doing the analysis for hints we're not going to return.

Examples of syntax:
```
InlayHints:
  Enabled: No
---
InlayHints:
  ParameterNames: No
---
InlayHints:
  ParameterNames: Yes
  DeducedTypes: Yes
```

Differential Revision: https://reviews.llvm.org/D116713
2022-01-10 10:49:35 +01:00
Sam McCall
7c19fdd599 [clangd] Polish clangd/inlayHints and expose them by default.
This means it's a "real feature" in clangd 14, albeit one that requires special
client support.

- remove "preview" from the flag description
- expose the `clangdInlayHints` capability by default
- provide `position` as well as `range`
- support `InlayHintsParams.range` to restrict the range retrieved
- inlay hint list is in document order (sorted by position)

Still to come: control feature via config rather than flag.

Fixes https://github.com/clangd/clangd/issues/313
Protocol doc is in https://github.com/llvm/clangd-www/pull/56/files

Differential Revision: https://reviews.llvm.org/D116699
2022-01-07 15:12:43 +01:00
Matheus Izvekov
c9e46219f3
[clang] retain type sugar in auto / template argument deduction
This implements the following changes:
* AutoType retains sugared deduced-as-type.
* Template argument deduction machinery analyses the sugared type all the way
down. It would previously lose the sugar on first recursion.
* Undeduced AutoType will be properly canonicalized, including the constraint
template arguments.
* Remove the decltype node created from the decltype(auto) deduction.

As a result, we start seeing sugared types in a lot more test cases,
including some which showed very unfriendly `type-parameter-*-*` types.

Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>

Reviewed By: rsmith, #libc, ldionne

Differential Revision: https://reviews.llvm.org/D110216
2021-11-15 23:07:45 +01:00
Matheus Izvekov
6438a52df1
Revert "[clang] retain type sugar in auto / template argument deduction"
This reverts commit 4d8fff477e024698facd89741cc6cf996708d598.
2021-11-15 00:29:05 +01:00
Matheus Izvekov
4d8fff477e
[clang] retain type sugar in auto / template argument deduction
This implements the following changes:
* AutoType retains sugared deduced-as-type.
* Template argument deduction machinery analyses the sugared type all the way
down. It would previously lose the sugar on first recursion.
* Undeduced AutoType will be properly canonicalized, including the constraint
template arguments.
* Remove the decltype node created from the decltype(auto) deduction.

As a result, we start seeing sugared types in a lot more test cases,
including some which showed very unfriendly `type-parameter-*-*` types.

Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D110216
2021-11-13 03:35:22 +01:00
Adrian Kuegel
1d7fdbbc18 Revert "[clang] retain type sugar in auto / template argument deduction"
This reverts commit 9b6036deedf28e10d797fc4ca734d57680d18053.
Breaks two libc++ tests.
2021-11-12 13:21:59 +01:00
Matheus Izvekov
9b6036deed
[clang] retain type sugar in auto / template argument deduction
This implements the following changes:
* AutoType retains sugared deduced-as-type.
* Template argument deduction machinery analyses the sugared type all the way
down. It would previously lose the sugar on first recursion.
* Undeduced AutoType will be properly canonicalized, including the constraint
template arguments.
* Remove the decltype node created from the decltype(auto) deduction.

As a result, we start seeing sugared types in a lot more test cases,
including some which showed very unfriendly `type-parameter-*-*` types.

Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D110216
2021-11-12 01:16:31 +01:00
Nathan Ridge
d87d1aa076 [clangd] Deduplicate inlay hints
Duplicates can sometimes appear due to e.g. explicit template
instantiations

Differential Revision: https://reviews.llvm.org/D110051
2021-09-21 03:23:04 -04:00