25 Commits

Author SHA1 Message Date
Victor Vianna
16dfd317f3
[llvm] Fix C++23 error in ParentMapContext (#163553)
ParentMapContext::ParentMapContext(ASTContext &Ctx) instantiates
~unique_ptr<ParentMapContext::ParentMap>, so it must be defined after
that class is a complete type.

Co-authored-by: Victor Hugo Vianna Silva <victorvianna@google.com>
2025-10-15 17:25:46 +02: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
Rahul Joshi
6cf656eca7
[NFC][Clang][AST] Drop llvm:: in front of ArrayRef/MutableArrayRef (#145207) 2025-06-23 13:10:42 -07:00
higher-performance
8c7f0eaa6e
Reduce memory usage in AST parent map generation by lazily checking if nodes have been seen (#129934)
This mitigates a regression introduced in #87824.

The mitigation here is to store pointers the deduplicated AST nodes, rather than copies of the nodes themselves. This allows a pointer-optimized set to be used and saves a lot of memory because `clang::DynTypedNode` is ~5 times larger than a pointer.

Fixes #129808.
2025-03-13 16:02:39 -04:00
Kazu Hirata
c8ba57ec23
[AST] Migrate away from PointerUnion::dyn_cast (NFC) (#125157)
Note that PointerUnion::dyn_cast has been soft deprecated in
PointerUnion.h:

  // FIXME: Replace the uses of is(), get() and dyn_cast() with
  //        isa<T>, cast<T> and the llvm::dyn_cast<T>

Literal migration would result in dyn_cast_if_present (see the
definition of PointerUnion::dyn_cast), but this patch uses dyn_cast
because we expect NodeOrVector to be nonnull.
2025-01-31 07:50:04 -08:00
Kazu Hirata
c583df46d4
[AST] Migrate away from PointerUnion::dyn_cast (NFC) (#124882)
Note that PointerUnion::dyn_cast has been soft deprecated in
PointerUnion.h:

  // FIXME: Replace the uses of is(), get() and dyn_cast() with
  //        isa<T>, cast<T> and the llvm::dyn_cast<T>

Literal migration would result in dyn_cast_if_present (see the
definition of PointerUnion::dyn_cast), but this patch uses dyn_cast
because we expect It->second to be nonnull.
getSingleDynTypedNodeFromParentMap ends with a deference of U.
2025-01-29 07:48:06 -08:00
Kazu Hirata
0f3c2884f3
[AST] Migrate away from PointerUnion::dyn_cast (NFC) (#124433)
Note that PointerUnion::dyn_cast has been soft deprecated in
PointerUnion.h:

  // FIXME: Replace the uses of is(), get() and dyn_cast() with
  //        isa<T>, cast<T> and the llvm::dyn_cast<T>

Literal migration would result in dyn_cast_if_present (see the
definition of PointerUnion::dyn_cast), but this patch uses dyn_cast
because we expect U to be nonnull.
2025-01-25 15:25:04 -08:00
Congcong Cai
cbdd14ee9d
[clang][NFC]add static for internal linkage function (#117482)
Detected by misc-use-internal-linkage
2024-11-25 06:48:33 +08:00
Kazu Hirata
63d9ef5e37
[AST] Migrate away from PointerUnion::{is,get} (NFC) (#117469)
Note that PointerUnion::{is,get} have been soft deprecated in
PointerUnion.h:

  // FIXME: Replace the uses of is(), get() and dyn_cast() with
  //        isa<T>, cast<T> and the llvm::dyn_cast<T>

I'm not touching PointerUnion::dyn_cast for now because it's a bit
complicated; we could blindly migrate it to dyn_cast_if_present, but
we should probably use dyn_cast when the operand is known to be
non-null.
2024-11-24 07:28:20 -08:00
higher-performance
c54afe5c33
Fix quadratic slowdown in AST matcher parent map generation (#87824)
Avoids the need to linearly re-scan all seen parent nodes to check for
duplicates, which previously caused a slowdown for ancestry checks in
Clang AST matchers.

Fixes: #86881
2024-04-10 13:24:19 -04:00
serge-sans-paille
a3c248db87
Move from llvm::makeArrayRef to ArrayRef deduction guides - clang/ part
This is a follow-up to https://reviews.llvm.org/D140896, split into
several parts as it touches a lot of files.

Differential Revision: https://reviews.llvm.org/D141139
2023-01-09 12:15:24 +01:00
Benjamin Kramer
bbf19a6745 [AST] Use std::apply to pop front of tuples. NFCI. 2022-08-25 00:03:08 +02:00
David Goldman
805f7a4fa4 [clang] Add ObjCProtocolLoc to represent protocol references
Add `ObjCProtocolLoc` which behaves like `TypeLoc` but for
`ObjCProtocolDecl` references.

RecursiveASTVisitor now synthesizes `ObjCProtocolLoc` during traversal
and the `ObjCProtocolLoc` can be stored in a `DynTypedNode`.

In a follow up patch, I'll update clangd to make use of this
to properly support protocol references for hover + goto definition.

Differential Revision: https://reviews.llvm.org/D119363
2022-02-18 15:24:00 -05:00
Kazu Hirata
57b40b5f34 [AST, CodeGen, Driver] Use llvm::is_contained (NFC) 2021-10-12 09:19:49 -07:00
Sam McCall
c8f148274f Reapply "Support Attr in DynTypedNode and ASTMatchers."
This reverts commit 3241680f111ddf3eac37db88cacac199083543f0.
Fixed mangled post-test formatting :-(
2021-08-06 22:30:32 +02:00
Sam McCall
3241680f11 Revert "Support Attr in DynTypedNode and ASTMatchers."
This reverts commit a4bdcdadc6ffab250b218bbdae9a0ced05bebfc9.

Fails bots:
https://lab.llvm.org/buildbot/#/builders/109/builds/20231/steps/6/logs/stdio
2021-08-06 22:27:54 +02:00
Sam McCall
a4bdcdadc6 Support Attr in DynTypedNode and ASTMatchers.
Differential Revision: https://reviews.llvm.org/D89743
2021-08-06 22:06:04 +02:00
Stephen Kelly
e4d5f00093 [ASTMatchers] Fix hasParent while ignoring unwritten nodes
For example, before this patch we can use has() to get from a
cxxRewrittenBinaryOperator to its operand, but hasParent doesn't get
back to the cxxRewrittenBinaryOperator.  This patch fixes that.

Differential Revision: https://reviews.llvm.org/D96113
2021-02-18 15:04:03 +00:00
Stephen Kelly
5e1801813d Remove the IgnoreImplicitCastsAndParentheses traversal kind
Differential Revision: https://reviews.llvm.org/D91918
2020-11-23 14:27:48 +00:00
Stephen Kelly
52ff86d255 [AST] Fix traversal over CXXConstructExpr in Syntactic mode
Summary:
Skip over elidable nodes, and ensure that intermediate
CXXFunctionalCastExpr nodes are also skipped if they are semantic.

Reviewers: klimek, ymandel

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82278
2020-10-30 12:14:41 +00:00
Sam McCall
1ad94624f8 [AST] Use data-recursion when building ParentMap, avoid stack overflow.
The following crashes on my system before this patch, but not after:

  void foo(int i) {
    switch (i) {
      case 1:
      case 2:
      ... 100000 cases ...
        ;
    }
  }

  clang-query -c="match stmt(hasAncestor(stmt()))" deep.c

I'm not sure it's actually a sane testcase to run though, it's pretty slow :-)

Differential Revision: https://reviews.llvm.org/D88222
2020-09-24 22:49:44 +02:00
Reid Kleckner
cd62511496 Remove clang::ast_type_traits namespace in favor of clang
DynTypedNode and ASTNodeKind are implemented as part of the clang AST
library, which uses the main clang namespace. There doesn't seem to be a
need for this extra level of namespacing.

I left behind aliases in the ast_type_traits namespace for out of tree
clients of these APIs. To provide aliases for the enumerators, I used
this pattern:
  namespace ast_type_traits {
  constexpr TraversalKind TK_AsIs = ::clang::TK_AsIs;
  }
I think the typedefs will be useful for migration, but we might be able
to drop these enumerator aliases.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D74499
2020-02-13 10:46:47 -08:00
Stephen Kelly
0a57d14abf [ASTMatchers] Fix parent traversal with InitListExpr
Children of InitListExpr are traversed twice by RAV, so this code
populates a vector to represent the possibly-multiple parents (in
reality in this situation the parent is the same and is therefore
de-duplicated).
2020-01-27 11:19:59 +00:00
Stephen Kelly
f29204d388 NFC: Implement AST node skipping in ParentMapContext
Summary:
This allows ASTContext to store only one parent map, rather than storing
an entire parent map for each traversal mode used.

This is therefore a partial revert of commit 0a717d5b (Make it possible
control matcher traversal kind with ASTContext, 2019-12-06).

Reviewers: aaron.ballman, rsmith, rnk

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D73388
2020-01-26 18:35:44 +00:00
Reid Kleckner
8a81daaa8b [AST] Split parent map traversal logic into ParentMapContext.h
The only part of ASTContext.h that requires most AST types to be
complete is the parent map. Nothing in Clang proper uses the ParentMap,
so split it out into its own class. Make ASTContext own the
ParentMapContext so there is still a one-to-one relationship.

After this change, 562 fewer files depend on ASTTypeTraits.h, and 66
fewer depend on TypeLoc.h:
  $ diff -u deps-before.txt deps-after.txt | \
    grep '^[-+] ' | sort | uniq -c | sort -nr | less
      562 -    ../clang/include/clang/AST/ASTTypeTraits.h
      340 +    ../clang/include/clang/AST/ParentMapContext.h
       66 -    ../clang/include/clang/AST/TypeLocNodes.def
       66 -    ../clang/include/clang/AST/TypeLoc.h
       15 -    ../clang/include/clang/AST/TemplateBase.h
  ...
I computed deps-before.txt and deps-after.txt with `ninja -t deps`.

This removes a common and key dependency on TemplateBase.h and
TypeLoc.h.

This also has the effect of breaking the ParentMap RecursiveASTVisitor
instantiation into its own file, which roughly halves the compilation
time of ASTContext.cpp (29.75s -> 17.66s). The new file takes 13.8s to
compile.

I left behind forwarding methods for getParents(), but clients will need
to include a new header to make them work:
  #include "clang/AST/ParentMapContext.h"

I noticed that this parent map functionality is unfortunately duplicated
in ParentMap.h, which only works for Stmt nodes.

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D71313
2020-01-24 13:42:28 -08:00