aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Tooling/Syntax/BuildTree.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-09-12[clang] AST: remove DependentTemplateSpecializationType (#158109)Matheus Izvekov1-7/+0
A DependentTemplateSpecializationType (DTST) is basically just a TemplateSpecializationType (TST) with a hardcoded DependentTemplateName (DTN) as its TemplateName. This removes the DTST and replaces all uses of it with a TST, removing a lot of duplication in the implementation. Technically the hardcoded DTN is an optimization for a most common case, but the TST implementation is in better shape overall and with other optimizations, so this patch ends up being an overall performance positive: <img width="1465" height="38" alt="image" src="https://github.com/user-attachments/assets/084b0694-2839-427a-b664-eff400f780b5" /> A DTST also didn't allow a template name representing a DTN that was substituted, such as from an alias template, while the TST does allow it by the simple fact it can hold an arbitrary TemplateName, so this patch also increases the amount of sugar retained, while still being faster overall. Example (from included test case): ```C++ template<template<class> class TT> using T1 = TT<int>; template<class T> using T2 = T1<T::template X>; ``` Here we can now represent in the AST that `TT` was substituted for the dependent template name `T::template X`.
2025-09-02[Clang] [C2y] Implement N3355 ‘Named Loops’ (#152870)Sirraide1-4/+2
This implements support for [named loops](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3355.htm) for C2y. When parsing a `LabelStmt`, we create the `LabeDecl` early before we parse the substatement; this label is then passed down to `ParseWhileStatement()` and friends, which then store it in the loop’s (or switch statement’s) `Scope`; when we encounter a `break/continue` statement, we perform a lookup for the label (and error if it doesn’t exist), and then walk the scope stack and check if there is a scope whose preceding label is the target label, which identifies the jump target. The feature is only supported in C2y mode, though a cc1-only option exists for testing (`-fnamed-loops`), which is mostly intended to try and make sure that we don’t have to refactor this entire implementation when/if we start supporting it in C++. --------- Co-authored-by: Balazs Benics <benicsbalazs@gmail.com>
2025-08-09[clang] Improve nested name specifier AST representation (#147835)Matheus Izvekov1-86/+85
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-07-18[Clang][AST][NFC] Introduce `NamespaceBaseDecl` (#149123)Yanzuo Liu1-1/+0
Add `NamespaceBaseDecl` as common base class of `NamespaceDecl` and `NamespaceAliasDecl`. This simplifies `NestedNameSpecifier` a bit. Co-authored-by: Matheus Izvekov <mizvekov@gmail.com>
2025-05-31[Tooling] Remove unused includes (NFC) (#142257)Kazu Hirata1-6/+0
These are identified by misc-include-cleaner. I've filtered out those that break builds. Also, I'm staying away from llvm-config.h, config.h, and Compiler.h, which likely cause platform- or compiler-specific build failures.
2025-04-01[clang] improved preservation of template keyword (#133610)Matheus Izvekov1-2/+0
2024-05-14Reapply "[Clang] Unify interface for accessing template arguments as written ↵Krystian Stasiowski1-1/+2
for class/variable template specializations (#81642)" (#91393) Reapplies #81642, fixing the crash which occurs when running the lldb test suite.
2024-05-07Revert "[Clang] Unify interface for accessing template arguments as written ↵Adrian Prantl1-2/+1
for class/variable template specializations (#81642)" This reverts commit 7115ed0fff027b65fa76fdfae215ed1382ed1473. This commit broke several LLDB tests. https://green.lab.llvm.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/3480/
2024-05-07[Clang] Unify interface for accessing template arguments as written for ↵Krystian Stasiowski1-1/+2
class/variable template specializations (#81642) Our current method of storing the template arguments as written for `(Class/Var)Template(Partial)SpecializationDecl` suffers from a number of flaws: - We use `TypeSourceInfo` to store `TemplateArgumentLocs` for class template/variable template partial/explicit specializations. For variable template specializations, this is a rather unintuitive hack (as we store a non-type specialization as a type). Moreover, we don't ever *need* the type as written -- in almost all cases, we only want the template arguments (e.g. in tooling use-cases). - The template arguments as written are stored in a number of redundant data members. For example, `(Class/Var)TemplatePartialSpecialization` have their own `ArgsAsWritten` member that stores an `ASTTemplateArgumentListInfo` (the template arguments). `VarTemplateSpecializationDecl` has yet _another_ redundant member "`TemplateArgsInfo`" that also stores an `ASTTemplateArgumentListInfo`. This patch eliminates all `(Class/Var)Template(Partial)SpecializationDecl` members which store the template arguments as written, and turns the `ExplicitInfo` member into a `llvm::PointerUnion<const ASTTemplateArgumentListInfo*, ExplicitInstantiationInfo*>` (to avoid unnecessary allocations when the declaration isn't an explicit instantiation). The template arguments as written are now accessed via `getTemplateArgsWritten` in all cases. The "most breaking" change is to AST Matchers, insofar that `hasTypeLoc` will no longer match class template specializations (since they no longer store the type as written).
2023-01-09Move from llvm::makeArrayRef to ArrayRef deduction guides - clang/ partserge-sans-paille1-4/+4
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
2022-07-15[syntax] Introduce a TokenManager interface.Haojian Wu1-25/+32
TokenManager defines Token interfaces for the clang syntax-tree. This is the level of abstraction that the syntax-tree should use to operate on Tokens. It decouples the syntax-tree from a particular token implementation (TokenBuffer previously). This enables us to use a different underlying token implementation for the syntax Leaf node -- in clang pseudoparser, we want to produce a syntax-tree with its own pseudo::Token rather than syntax::Token. Differential Revision: https://reviews.llvm.org/D128411
2022-06-20Don't use Optional::hasValue (NFC)Kazu Hirata1-2/+2
2021-10-25[clang] Use llvm::{count,count_if,find_if,all_of,none_of} (NFC)Kazu Hirata1-3/+2
2021-02-18[Syntax] No crash on OpaqueValueExpr.Haojian Wu1-0/+5
OpaqueValueExpr doesn't correspond to the concrete syntax, it has invalid source location, ignore them. Reviewed By: kbobyrev Differential Revision: https://reviews.llvm.org/D96112
2021-02-11[Syntax] Remove a strict valid source location assertion for TypeLoc.Haojian Wu1-2/+3
The EndLoc of a type loc can be invalid for broken code. Also extend the existing test to support error code with `error-ok` annotation. Differential Revision: https://reviews.llvm.org/D96261
2021-02-04[Syntax] Support condition for IfStmt.Haojian Wu1-0/+28
Differential Revision: https://reviews.llvm.org/D95782
2020-11-09[clang] Simplify buildSyntaxTree APIKirill Bobyrev1-3/+3
Follow-up on https://reviews.llvm.org/D88553#inline-837013 Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D90672
2020-11-05[SyntaxTree] Add reverse links to syntax Nodes.Eduardo Caldas1-4/+3
Rationale: Children of a syntax tree had forward links only, because there was no need for reverse links. This need appeared when we started mutating the syntax tree. On a forward list, to remove a target node in O(1) we need a pointer to the node before the target. If we don't have this "before" pointer, we have to find it, and that requires O(n). So in order to remove a syntax node from a tree, we would similarly need to find the node before to then remove. This is both not ergonomic nor does it have a good complexity. Differential Revision: https://reviews.llvm.org/D90240
2020-10-20[clang] Use SourceLocation as key in hash maps, NFCIMikhail Maltsev1-4/+3
The patch adjusts the existing `llvm::DenseMap<unsigned, T>` and `llvm::DenseSet<unsigned>` objects that store source locations, so that they use `SourceLocation` directly instead of `unsigned`. This patch relies on the `DenseMapInfo` trait added in D89719. It also replaces the construction of `SourceLocation` objects from the constants -1 and -2 with calls to the trait's methods `getEmptyKey` and `getTombstoneKey` where appropriate. Reviewed By: dexonsmith Differential Revision: https://reviews.llvm.org/D69840
2020-10-01Migrate Declarators to use the List APIEduardo Caldas1-6/+63
After this change all nodes that have a delimited-list are using the `List` API. Implementation details: Let's look at a declaration with multiple declarators: `int a, b;` To generate a declarator list node we need to have the range of declarators: `a, b`: However, the `ClangAST` actually stores them as separate declarations: `int a ;` `int b;` We solve that by appropriately marking the declarators on each separate declaration in the `ClangAST` and then for the final declarator `int b`, shrinking its range to fit to the already marked declarators. Differential Revision: https://reviews.llvm.org/D88403
2020-09-21[SyntaxTree][NFC] follow naming convention + remove auto on empty vector ↵Eduardo Caldas1-6/+6
declaration Differential Revision: https://reviews.llvm.org/D88004
2020-09-12Fix clang Wrange-loop-analysis in BuildTree.cppDmitri Gribenko1-1/+1
Building on Mac OS with clang 12: ``` jhemphill@jhemphill-mbp build % clang --version Apple clang version 12.0.0 (clang-1200.0.26.2) Target: x86_64-apple-darwin19.6.0 Thread model: posix InstalledDir: /Library/Developer/CommandLineTools/usr/bin ``` yields one warning: ``` /Users/jhemphill/oss/llvm-project/clang/lib/Tooling/Syntax/BuildTree.cpp:1126:22: warning: loop variable 'Arg' is always a copy because the range of type 'llvm::iterator_range<clang::Stmt::CastIterator<clang::Expr, clang::Expr *, clang::Stmt *> >' does not return a reference [-Wrange-loop-analysis] for (const auto &Arg : Args) { ^ /Users/jhemphill/oss/llvm-project/clang/lib/Tooling/Syntax/BuildTree.cpp:1126:10: note: use non-reference type 'clang::Expr *' for (const auto &Arg : Args) { ``` It appears that `Arg` is an `Expr*`, passed by value rather than by const reference. Reviewed By: eduucaldas, gribozavr2 Differential Revision: https://reviews.llvm.org/D87482
2020-09-11[SyntaxTree] Add const qualifiers, from [llvm-qualified-auto]Eduardo Caldas1-1/+1
Differential Revision: https://reviews.llvm.org/D87522
2020-09-11[SyntaxTree] Rename functions to start with verbEduardo Caldas1-20/+23
According to LLVM coding standards: https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly Differential Revision: https://reviews.llvm.org/D87498
2020-09-08[SyntaxTree] Fix crash on functions with default arguments.Eduardo Caldas1-1/+14
* Do not visit `CXXDefaultArgExpr` * To build `CallArguments` nodes, just go through non-default arguments Differential Revision: https://reviews.llvm.org/D87249
2020-09-08[SyntaxTree] Ignore implicit `CXXFunctionalCastExpr` wrapping constructorEduardo Caldas1-1/+18
Differential Revision: https://reviews.llvm.org/D87229
2020-09-08[SyntaxTree] Ignore implicit leaf `CXXConstructExpr`Eduardo Caldas1-0/+8
Differential Revision: https://reviews.llvm.org/D86700
2020-09-08[SyntaxTree] Ignore implicit non-leaf `CXXConstructExpr`Eduardo Caldas1-3/+24
Differential Revision: https://reviews.llvm.org/D86699
2020-08-28[SyntaxTree] Add coverage for declarators and init-declaratorsEduardo Caldas1-1/+2
2020-08-28[SyntaxTree][NFC] Refactor function templates into functions taking base classEduardo Caldas1-48/+51
The refactored functions were * `isReponsibleForCreatingDeclaration` * `getQualifiedNameStart` Differential Revision: https://reviews.llvm.org/D86719
2020-08-27[SyntaxTree][NFC][Style] Functions start with lowercaseEduardo Caldas1-4/+4
Differential Revision: https://reviews.llvm.org/D86682
2020-08-27[SyntaxTree] Refactor `NodeRole`sEduardo Caldas1-78/+47
Previously a NodeRole would generally be prefixed with the `NodeKind`, we remove this prefix, as it we redundant and made tests more noisy. Differential Revision: https://reviews.llvm.org/D86636
2020-08-26[SyntaxTree] Migrate `ParamatersAndQualifiers` to use the new List APIEduardo Caldas1-3/+21
Fix: Add missing `List::getTerminationKind()`, `List::canBeEmpty()`, `List::getDelimiterTokenKind()` for `CallArguments`. Differential Revision: https://reviews.llvm.org/D86600
2020-08-26[SyntaxTree] Add support for `CallExpression`Eduardo Caldas1-2/+64
* Generate `CallExpression` syntax node for all semantic nodes inheriting from `CallExpr` with call-expression syntax - except `CUDAKernelCallExpr`. * Implement all the accessors * Arguments of `CallExpression` have their own syntax node which is based on the `List` base API Differential Revision: https://reviews.llvm.org/D86544
2020-08-25[SyntaxTree] Extend the syntax tree dump to also cover `NodeRole`Eduardo Caldas1-1/+1
We should see `NodeRole` information in the dump because that exposes how the accessors will behave. Functional changes in the dump: * Surround Leaf tokens with `'` * Append `Node` dumps with `NodeRole` information, except for unknown roles * Append marks to `Node` dumps, instead of prepending Non-functional changes: * `::dumpTokens(llvm::raw_ostream, ArrayRef<syntax::Token>, const SourceManager &SM)` always received as parameter a `syntax::Token *` pointing to `Leaf::token()`. Changed the function to `dumpLeaf(llvm::raw_ostream, syntax::Leaf *, const SourceManager&)` * `dumpTree` acted on a Node, rename to `dumpNode` Differential Revision: https://reviews.llvm.org/D85330
2020-08-21[SyntaxTree] Add support for `this`Eduardo Caldas1-0/+10
Differential Revision: https://reviews.llvm.org/D86298
2020-08-20[SyntaxTree] Unify logic for generating `id-expression`Eduardo Caldas1-48/+31
2020-08-20[SyntaxTree] Add support for `MemberExpression`Eduardo Caldas1-0/+43
Differential Revision: https://reviews.llvm.org/D86227
2020-08-12[SyntaxTree] Unbox operators into tokens for nodes generated from ↵Eduardo Caldas1-11/+14
`CXXOperatorCallExpr` For an user define `<`, `x < y` would yield the syntax tree: ``` BinaryOperatorExpression |-IdExpression | `-UnqualifiedId | `-x |-IdExpression | `-UnqualifiedId | `-< `-IdExpression `-UnqualifiedId `-y ``` But there is no syntatic difference at call site between call site or built-in `<`. As such they should generate the same syntax tree, namely: ``` BinaryOperatorExpression |-IdExpression | `-UnqualifiedId | `-x |-< `-IdExpression `-UnqualifiedId `-y ``` Differential Revision: https://reviews.llvm.org/D85750
2020-08-10[SyntaxTree] Expand support for `NestedNameSpecifier`Eduardo Caldas1-54/+120
Summary: We want NestedNameSpecifier syntax nodes to be generally supported, not only for `DeclRefExpr` and `DependentScopedDeclRefExpr`. To achieve this we: * Use the `RecursiveASTVisitor`'s API to traverse `NestedNameSpecifierLoc`s and automatically create its syntax nodes * Add links from the `NestedNameSpecifierLoc`s to their syntax nodes. In this way, from any semantic construct that has a `NestedNameSpecifier`, we implicitly generate its syntax node via RAV and we can easily access this syntax node via the links we added.
2020-08-10[SyntaxTree] Implement `NestedNameSpecifier` using the `List` base APIEduardo Caldas1-3/+2
2020-08-08Fix MSVC "not all control paths return a value" warning. NFC.Simon Pilgrim1-0/+1
2020-08-07[SyntaxTree] Use simplified grammar rule for `NestedNameSpecifier` grammar nodesEduardo Caldas1-29/+114
This is our grammar rule for nested-name-specifiers: globalbal-specifier: /*empty*/ simple-template-specifier: template_opt simple-template-id name-specifier: global-specifier decltype-specifier identifier simple-template-specifier nested-name-specifier: list(name-specifier, ::, non-empty, terminated) It is a relaxed version of C++ [expr.prim.id] and quite simpler to map to our API. TODO: refine name specifiers, `simple-template-name-specifier` and decltype-name-specifier` are token soup for now.
2020-08-07[SyntaxTree][NFC] remove redundant namespace-specifiersEduardo Caldas1-39/+34
Differential Revision: https://reviews.llvm.org/D85427
2020-08-04[SyntaxTree] Fix crash on pointer to member functionEduardo Caldas1-0/+12
Differential Revision: https://reviews.llvm.org/D85146
2020-07-11Fix `-Wreturn-type` warning. NFC.Michael Liao1-0/+1
2020-07-10Use FileRange::text instead of Lexer::getSpellingEduardo Caldas1-6/+4
* as we are using them only for integer and floating literals they have the same behavior * FileRange::text is simpler to call and is within the context of syntax trees
2020-07-10Add kinded UDL for raw literal operator and numeric literal operator templateEduardo Caldas1-15/+30
2020-07-10Fix crash on `user defined literals`Eduardo Caldas1-4/+41
Summary: Given an UserDefinedLiteral `1.2_w`: Problem: Lexer generates one Token for the literal, but ClangAST references two source locations Fix: Ignore the operator and interpret it as the underlying literal. e.g.: `1.2_w` token generates syntax node IntegerLiteral(1.2_w) Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D82157
2020-07-09Fix MSVC "not all control paths return a value" warning. NFC.Simon Pilgrim1-0/+1