aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaCXXScopeSpec.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-07-18[Clang][AST][NFC] Introduce `NamespaceBaseDecl` (#149123)Yanzuo Liu1-5/+1
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-02[clang][NFC] Convert `Sema::CorrectTypoKind` to scoped enumVlad Serebrennikov1-1/+1
2025-04-12Reland: [clang] Improved canonicalization for template specialization types ↵Matheus Izvekov1-10/+8
(#135414) This relands https://github.com/llvm/llvm-project/pull/135119, after fixing crashes seen in LLDB CI reported here: https://github.com/llvm/llvm-project/pull/135119#issuecomment-2794910840 Fixes https://github.com/llvm/llvm-project/pull/135119 This changes the TemplateArgument representation to hold a flag indicating whether a tempalte argument of expression type is supposed to be canonical or not. This gets one step closer to solving https://github.com/llvm/llvm-project/issues/92292 This still doesn't try to unique as-written TSTs. While this would increase the amount of memory savings and make code dealing with the AST more well-behaved, profiling template argument lists is still too expensive for this to be worthwhile, at least for now. This also fixes the context creation of TSTs, so that they don't in some cases get incorrectly flagged as sugar over their own canonical form. This is captured in the test expectation change of some AST dumps. This fixes some places which were unnecessarily canonicalizing these TSTs.
2025-04-11Revert "[clang] Improved canonicalization for template specialization types" ↵Dmitry Vasilyev1-8/+10
(#135354) Reverts llvm/llvm-project#135119 because of the assert in ASTContext.cpp, line 5619. See #135352 for details.
2025-04-10[clang] Improved canonicalization for template specialization types (#135119)Matheus Izvekov1-10/+8
This changes the TemplateArgument representation to hold a flag indicating whether a template argument of expression type is supposed to be canonical or not. This gets one step closer to solving https://github.com/llvm/llvm-project/issues/92292 This still doesn't try to unique as-written TSTs. While this would increase the amount of memory savings and make code dealing with the AST more well-behaved, profiling template argument lists is still too expensive for this to be worthwhile, at least for now. Without this uniquing, this patch stands neutral in terms of performance impact. This also fixes the context creation of TSTs, so that they don't in some cases get incorrectly flagged as sugar over their own canonical form. This is captured in the test expectation change of some AST dumps. This fixes some places which were unnecessarily canonicalizing these TSTs.
2025-04-09[clang] fix NestedNameSpecifier dependency calculation (#135067)Matheus Izvekov1-2/+1
A NestedNameSpecifier of TypeSpec kind can be non-dependent even if its prefix is dependent, when for example the prefix is an injected class type but the type itself is a simple alias to a non-dependent type. This issue was a bit hard to observe because if it is an alias to a class type, then we (for some unknown reason) ignored that the NNS was dependent in the first place, which wouldn't happen with an enum type. This could have been a workaround for previous dependency bugs, and is not relevant anymore for any of the test cases in the tree, so this patch also removes that. The other kinds of dependencies are still relevant. If the prefix contains an unexpanded pack, then this NNS is still unexpanded, and likewise for errors. This fixes a regression reported here: https://github.com/llvm/llvm-project/pull/133610#issuecomment-2787909829 which was introduced by https://github.com/llvm/llvm-project/pull/133610 There are no release notes since the regression was never released.
2025-04-01[clang] fix missing initialization msan failureMatheus Izvekov1-0/+1
fixes msan failure reported here: https://lab.llvm.org/buildbot/#/builders/94/builds/5821/steps/17/logs/stdio This was a regression introduced here: https://github.com/llvm/llvm-project/pull/133610
2025-04-01[clang] improved preservation of template keyword (#133610)Matheus Izvekov1-19/+12
2024-11-16[Sema] Remove unused includes (NFC) (#116461)Kazu Hirata1-1/+0
Identified with misc-include-cleaner.
2024-07-15Revert "Reapply "[Clang] Implement resolution for CWG1835 (#92957)" (#98547)"Haojian Wu1-91/+104
This reverts commit ce4aada6e2135e29839f672a6599db628b53295d and a follow-up patch 8ef26f1289bf069ccc0d6383f2f4c0116a1206c1. This new warning can not be fully suppressed by the `-Wno-missing-dependent-template-keyword` flag, this gives developer no time to do the cleanup in a large codebase, see https://github.com/llvm/llvm-project/pull/98547#issuecomment-2228250884
2024-07-11Reapply "[Clang] Implement resolution for CWG1835 (#92957)" (#98547)Krystian Stasiowski1-104/+91
Reapplies #92957, fixing an instance where the `template` keyword was missing prior to a dependent name in `llvm/ADT/ArrayRef.h`. An _alias-declaration_ is used to work around a bug affecting GCC releases before 11.1 (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94799) which rejects the use of the `template` keyword prior to the _nested-name-specifier_ in the class member access.
2024-07-10Revert "[Clang] Implement resolution for CWG1835 (#92957)"NAKAMURA Takumi1-91/+104
ppc64le-lld-multistage-test has been failing. This reverts commit 7bfb98c34687d9784f36937c3ff3e735698b498a.
2024-07-09[Clang] Implement resolution for CWG1835 (#92957)Krystian Stasiowski1-104/+91
CWG1835 was one of the many core issues resolved by P1787R6: "Declarations and where to find them" (http://wg21.link/p1787r6). Its resolution changes how member-qualified names (as defined by [basic.lookup.qual.general] p2) are looked up. This patch implementation that resolution. Previously, an _identifier_ following `.` or `->` would be first looked up in the type of the object expression (i.e. qualified lookup), and then in the context of the _postfix-expression_ (i.e. unqualified lookup) if nothing was found; the result of the second lookup was required to name a class template. Notably, this second lookup would occur even when the object expression was dependent, and its result would be used to determine whether a `<` token is the start of a _template-argument_list_. The new wording in [basic.lookup.qual.general] p2 states: > A member-qualified name is the (unique) component name, if any, of > - an _unqualified-id_ or > - a _nested-name-specifier_ of the form _`type-name ::`_ or _`namespace-name ::`​_ > > in the id-expression of a class member access expression. A ***qualified name*** is > - a member-qualified name or > - the terminal name of > - a _qualified-id_, > - a _using-declarator_, > - a _typename-specifier_, > - a _qualified-namespace-specifier_, or > - a _nested-name-specifier_, _elaborated-type-specifier_, or _class-or-decltype_ that has a _nested-name-specifier_. > > The _lookup context_ of a member-qualified name is the type of its associated object expression (considered dependent if the object expression is type-dependent). The lookup context of any other qualified name is the type, template, or namespace nominated by the preceding _nested-name-specifier_. And [basic.lookup.qual.general] p3 now states: > _Qualified name lookup_ in a class, namespace, or enumeration performs a search of the scope associated with it except as specified below. Unless otherwise specified, a qualified name undergoes qualified name lookup in its lookup context from the point where it appears unless the lookup context either is dependent and is not the current instantiation or is not a class or class template. If nothing is found by qualified lookup for a member-qualified name that is the terminal name of a _nested-name-specifier_ and is not dependent, it undergoes unqualified lookup. In non-standardese terms, these two paragraphs essentially state the following: - A name that immediately follows `.` or `->` in a class member access expression is a member-qualified name - A member-qualified name will be first looked up in the type of the object expression `T` unless `T` is a dependent type that is _not_ the current instantiation, e.g. ``` template<typename T> struct A { void f(T* t) { this->x; // type of the object expression is 'A<T>'. although 'A<T>' is dependent, it is the // current instantiation so we look up 'x' in the template definition context. t->y; // type of the object expression is 'T' ('->' is transformed to '.' per [expr.ref]). // 'T' is dependent and is *not* the current instantiation, so we lookup 'y' in the // template instantiation context. } }; ``` - If the first lookup finds nothing and: - the member-qualified name is the first component of a _nested-name-specifier_ (which could be an _identifier_ or a _simple-template-id_), and either: - the type of the object expression is the current instantiation and it has no dependent base classes, or - the type of the object expression is not dependent then we lookup the name again, this time via unqualified lookup. Although the second (unqualified) lookup is stated not to occur when the member-qualified name is dependent, a dependent name will _not_ be dependent once the template is instantiated, so the second lookup must "occur" during instantiation if qualified lookup does not find anything. This means that we must perform the second (unqualified) lookup during parsing even when the type of the object expression is dependent, but those results are _not_ used to determine whether a `<` token is the start of a _template-argument_list_; they are stored so we can replicate the second lookup during instantiation. In even simpler terms (paraphrasing the meeting minutes from the review of P1787; see https://wiki.edg.com/bin/view/Wg21summer2020/P1787%28Lookup%29Review2020-06-15Through2020-06-18): - Unqualified lookup always happens for the first name in a _nested-name-specifier_ that follows `.` or `->` - The result of that lookup is only used to determine whether `<` is the start of a _template-argument-list_ if the first (qualified) lookup found nothing and the lookup context: - is not dependent, or - is the current instantiation and has no dependent base classes. An example: ``` struct A { void f(); }; template<typename T> using B = A; template<typename T> struct C : A { template<typename U> void g(); void h(T* t) { this->g<int>(); // ok, '<' is the start of a template-argument-list ('g' was found via qualified lookup in the current instantiation) this->B<void>::f(); // ok, '<' is the start of a template-argument-list (current instantiation has no dependent bases, 'B' was found via unqualified lookup) t->g<int>(); // error: '<' means less than (unqualified lookup does not occur for a member-qualified name that isn't the first component of a nested-name-specifier) t->B<void>::f(); // error: '<' means less than (unqualified lookup does not occur if the name is dependent) t->template B<void>::f(); // ok: '<' is the start of a template-argument-list ('template' keyword used) } }; ``` Some additional notes: - Per [basic.lookup.qual.general] p1, lookup for a member-qualified name only considers namespaces, types, and templates whose specializations are types if it's an _identifier_ followed by `::`; lookup for the component name of a _simple-template-id_ followed by `::` is _not_ subject to this rule. - The wording which specifies when the second unqualified lookup occurs appears to be paradoxical. We are supposed to do it only for the first component name of a _nested-name-specifier_ that follows `.` or `->` when qualified lookup finds nothing. However, when that name is followed by `<` (potentially starting a _simple-template-id_) we don't _know_ whether it will be the start of a _nested-name-specifier_ until we do the lookup -- but we aren't supposed to do the lookup until we know it's part of a _nested-name-specifier_! ***However***, since we only do the second lookup when the first lookup finds nothing (and the name isn't dependent), ***and*** since neither lookup is type-only, the only valid option is for the name to be the _template-name_ in a _simple-template-id_ that is followed by `::` (it can't be an _unqualified-id_ naming a member because we already determined that the lookup context doesn't have a member with that name). Thus, we can lock into the _nested-name-specifier_ interpretation and do the second lookup without having to know whether the _simple-template-id_ will be followed by `::` yet.
2024-07-01[clang][NFC] Move documentation of `Sema` functions into `Sema.h`Vlad Serebrennikov1-82/+0
This patch moves documentation of `Sema` functions from `.cpp` files to `Sema.h` when there was no documentation in the latter, or it can be trivially subsumed. More complicated cases when there's less trivial divergence between documentation attached to declaration and the one attached to implementation are left for a later PR that would require review. It appears that doxygen can find the documentation for a function defined out-of-line even if it's attached to an implementation, and not declaration. But other tools, e.g. clangd, are not as powerful. So this patch significantly improves autocompletion experience for (at least) clangd-based IDEs.
2024-06-11[clang] Replace X && isa<Y>(X) with isa_and_nonnull<Y>(X). NFC (#94987)Pavel Samolysov1-1/+1
This addresses a clang-tidy suggestion.
2024-05-20[Clang][Sema] Don't build CXXDependentScopeMemberExprs for potentially ↵Krystian Stasiowski1-0/+8
implicit class member access expressions (#92318) According to [expr.prim.id.general] p2: > If an _id-expression_ `E` denotes a non-static non-type member of some class `C` at a point where the current class is `X` and > - `E` is potentially evaluated or `C` is `X` or a base class of `X`, and > - `E` is not the _id-expression_ of a class member access expression, and > - if `E` is a _qualified-id_, `E` is not the un-parenthesized operand of the unary `&` operator, > > the _id-expression_ is transformed into a class member access expression using `(*this)` as the object expression. Consider the following: ``` struct A { void f0(); template<typename T> void f1(); }; template<typename T> struct B : T { auto g0() -> decltype(T::f0()); // ok auto g1() -> decltype(T::template f1<int>()); // error: call to non-static member function without an object argument }; template struct B<A>; ``` Clang incorrectly rejects the call to `f1` in the _trailing-return-type_ of `g1`. Furthermore, the following snippet results in a crash during codegen: ``` struct A { void f(); }; template<typename T> struct B : T { template<typename U> static void g(); template<> void g<int>() { return T::f(); // crash here } }; template struct B<A>; ``` This happens because we unconditionally build a `CXXDependentScopeMemberExpr` (with an implicit object expression) for `T::f` when parsing the template definition, even though we don't know whether `g` is an implicit object member function yet. This patch fixes these issues by instead building `DependentScopeDeclRefExpr`s for such expressions, and only transforming them into implicit class member access expressions during instantiation. Since we implemented the MS "unqualified lookup into dependent bases" extension by building an implicit class member access (and relying on the first component name of the _nested-name-specifier_ to be looked up in the context of the object expression during instantiation), we instead pre-append a fake _nested-name-specifier_ that refers to the injected-class-name of the enclosing class. This patch also refactors `Sema::BuildQualifiedDeclarationNameExpr` and `Sema::BuildQualifiedTemplateIdExpr`, streamlining their implementation and removing any redundant checks.
2024-01-27[Clang][C++26] Implement Pack Indexing (P2662R3). (#72644)cor3ntin1-0/+23
Implements https://isocpp.org/files/papers/P2662R3.pdf The feature is exposed as an extension in older language modes. Mangling is not yet supported and that is something we will have to do before release.
2023-12-14Revert "[clang] Substitute alias templates from correct context (#75069)"Fangrui Song1-20/+4
This reverts commit dbf67ea1d334d2114fe49701a8f4b8afd536e39f. It caused spurious "out-of-line definition of 'operator=' does not match any declaration in" error. https://github.com/llvm/llvm-project/pull/75069#issuecomment-1856581259
2023-12-13[clang] Substitute alias templates from correct context (#75069)Mariya Podchishchaeva1-4/+20
Current context set to where alias was met, not where it is declared caused incorrect access check in case alias referenced private members of the parent class. This is a recommit of 6b1aa31 with a slight modification in order to fix reported regression. Fixes https://github.com/llvm/llvm-project/issues/41693
2023-12-06Revert "[clang] Substitute alias templates from correct context (#74335)"Podchishchaeva, Mariya1-19/+3
It was reported in the PR that commit caused clang giving errors for code previously considered valid. This reverts commit 6b1aa319754e76366edd88e10034e0539710d946.
2023-12-06[clang] Substitute alias templates from correct context (#74335)Mariya Podchishchaeva1-3/+19
Current context set to where alias was met, not where it is declared caused incorrect access check in case alias referenced private members of the parent class. Fixes https://github.com/llvm/llvm-project/issues/41693
2023-10-31[clang][NFC] Refactor ElaboratedTypeKeywordVlad Serebrennikov1-1/+1
This patch moves ElaboratedTypeKeyword before `Type` definition so that the enum is complete where bit-field for it is declared. It also converts it to scoped enum and removes `ETK_` prefix.
2023-06-13[Sema] Remove unused isNonTypeNestedNameSpecifierKazu Hirata1-45/+0
The last use was removed by: commit 04f131da0b19abff611773c03be9bafb53c753ce Author: Richard Smith <richard@metafoo.co.uk> Date: Fri Jan 24 15:14:25 2020 -0800 Differential Revision: https://reviews.llvm.org/D152634
2023-04-27[clang] Do not crash on undefined template partial specializationMariya Podchishchaeva1-1/+2
Before checking that template partial specialization is "reachable", ensure it exists. Fixes https://github.com/llvm/llvm-project/issues/61356 Reviewed By: shafik, erichkeane Differential Revision: https://reviews.llvm.org/D148330
2023-03-10[Clang][Sema] Start fixing handling of out-of-line definitions of ↵Alexander Shaposhnikov1-19/+37
constrained templates This diff starts fixing our handling of out-of-line definitions of constrained templates. Initially it was motivated by https://github.com/llvm/llvm-project/issues/49620 and https://github.com/llvm/llvm-project/issues/60231. In particular, this diff adjusts Sema::computeDeclContext to work properly in the case of constrained template parameters. Test plan: 1/ ninja check-all 2/ Bootstrapped Clang passes all the tests 3/ Internal testing Differential revision: https://reviews.llvm.org/D145034
2023-03-02[Clang] Implement Change scope of lambda trailing-return-typeCorentin Jabot1-3/+5
This implements P2036R3 and P2579R0. That is, explicit, int, and implicit capture become visible at the start of the parameter head. Reviewed By: aaron.ballman, rupprecht, shafik Differential Revision: https://reviews.llvm.org/D124351
2023-02-03Revert "[Clang] Implement Change scope of lambda trailing-return-type"Jordan Rupprecht1-5/+3
This reverts commit d708a186b6a9b050d09558163dd353d9f738c82d (and typo fix e4bc9898ddbeb70bc49d713bbf863f050f21e03f). It causes a compilation error for this: ``` struct StringLiteral { template <int N> StringLiteral(const char (&array)[N]) __attribute__((enable_if(N > 0 && N == __builtin_strlen(array) + 1, "invalid string literal"))); }; struct Message { Message(StringLiteral); }; void Func1() { auto x = Message("x"); // Note: this is fine // Note: "xx\0" to force a different type, StringLiteral<3>, otherwise this // successfully builds. auto y = [&](decltype(Message("xx"))) {}; // ^ fails with: repro.cc:18:13: error: reference to local variable 'array' // declared in enclosing function 'StringLiteral::StringLiteral<3>' (void)x; (void)y; } ``` More details posted to D124351.
2023-01-31[Clang] Implement Change scope of lambda trailing-return-typeCorentin Jabot1-3/+5
This implements P2036R3 and P2579R0. That is, explicit, int, and implicit capture become visible at the start of the parameter head. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D124351
2022-10-25NFC: [clang] Template argument cleanups.Matheus Izvekov1-4/+3
Removes a bunch of obsolete methods in favor of a single one returning an ArrayRef of TemplateArgument. Signed-off-by: Matheus Izvekov <mizvekov@gmail.com> Differential Revision: https://reviews.llvm.org/D136602
2022-06-29[C++20] [Module] Support reachable definition initially/partiallyChuanqi Xu1-3/+3
This patch introduces a new kind of ModuleOwnershipKind as ReachableWhenImported. This intended the status for reachable described at: https://eel.is/c++draft/module.reach#3. Note that this patch is not intended to support all semantics about reachable semantics. For example, this patch didn't implement discarded declarations in GMF. (https://eel.is/c++draft/module.global.frag#3). This fixes: https://bugs.llvm.org/show_bug.cgi?id=52281 and https://godbolt.org/z/81f3ocjfW. Reviewed By: rsmith, iains Differential Revision: https://reviews.llvm.org/D113545
2022-06-29Revert "[C++20] [Modules] Implement Reachable initiallly"Chuanqi Xu1-3/+3
This reverts commit a223ba0a697c1598b434cf2495c9cd9ec5640fc7. The previous commit don't contain additional information, which is bad.
2022-06-29[C++20] [Modules] Implement Reachable initialllyChuanqi Xu1-3/+3
2022-06-15[clang][sema] Provide better diagnostic for missing template argumentsTimm Bäder1-2/+6
Instead of just complaining that "x is not a class, namespace or enumeration", mention that using x requires template arguments. Differential Revision: https://reviews.llvm.org/D127638 Fixes https://github.com/llvm/llvm-project/issues/55962
2022-06-15[clang][NFC] Remove unused parameter from ActOnCXXNestedNameSpecifierTimm Bäder1-1/+0
2022-04-20Revert D119136 "[clang] Implement Change scope of lambda ↵Fangrui Song1-5/+3
trailing-return-type" and its follow-up This reverts commit 69dd89fdcbd846375a45e2fe3a88710887236d7a. This reverts commit 04000c2f928a7adc32138a664d167f01b642bef3. The current states breaks libstdc++ usage (https://reviews.llvm.org/D119136#3455423). The fixup has been reverted as it caused other valid code to be disallowed. I think we should start from the clean state by reverting all relevant commits.
2022-04-15[clang] Implement Change scope of lambda trailing-return-typeCorentin Jabot1-3/+5
Implement P2036R3. Captured variables by copy (explicitely or not), are deduced correctly at the point we know whether the lambda is mutable, and ill-formed before that. Up until now, the entire lambda declaration up to the start of the body would be parsed in the parent scope, such that capture would not be available to look up. The scoping is changed to have an outer lambda scope, followed by the lambda prototype and body. The lambda scope is necessary because there may be a template scope between the start of the lambda (to which we want to attach the captured variable) and the prototype scope. We also need to introduce a declaration context to attach the captured variable to (and several parts of clang assume captures are handled from the call operator context), before we know the type of the call operator. The order of operations is as follow: * Parse the init capture in the lambda's parent scope * Introduce a lambda scope * Create the lambda class and call operator * Add the init captures to the call operator context and the lambda scope. But the variables are not capured yet (because we don't know their type). Instead, explicit captures are stored in a temporary map that conserves the order of capture (for the purpose of having a stable order in the ast dumps). * A flag is set on LambdaScopeInfo to indicate that we have not yet injected the captures. * The parameters are parsed (in the parent context, as lambda mangling recurses in the parent context, we couldn't mangle a lambda that is attached to the context of a lambda whose type is not yet known). * The lambda qualifiers are parsed, at this point We can switch (for the second time) inside the lambda context, unset the flag indicating that we have not parsed the lambda qualifiers, record the lambda is mutable and capture the explicit variables. * We can parse the rest of the lambda type, transform the lambda and call operator's types and also transform the call operator to a template function decl where necessary. At this point, both captures and parameters can be injected in the body's scope. When trying to capture an implicit variable, if we are before the qualifiers of a lambda, we need to remember that the variables are still in the parent's context (rather than in the call operator's). Reviewed By: aaron.ballman, #clang-language-wg, ChuanqiXu Differential Revision: https://reviews.llvm.org/D119136
2022-04-13Revert "[clang] Implement Change scope of lambda trailing-return-type"Richard Smith1-5/+3
This reverts commit c729d5be781a8e80137c11ab28aa14d9ace148db. This change breaks thread safety annotations on lambdas.
2022-04-13[clang] Implement Change scope of lambda trailing-return-typeCorentin Jabot1-3/+5
Implement P2036R3. Captured variables by copy (explicitely or not), are deduced correctly at the point we know whether the lambda is mutable, and ill-formed before that. Up until now, the entire lambda declaration up to the start of the body would be parsed in the parent scope, such that captures would not be available to look up. The scoping is changed to have an outer lambda scope, followed by the lambda prototype and body. The lambda scope is necessary because there may be a template scope between the start of the lambda (to which we want to attach the captured variable) and the prototype scope. We also need to introduce a declaration context to attach the captured variable to (and several parts of clang assume captures are handled from the call operator context), before we know the type of the call operator. The order of operations is as follow: * Parse the init capture in the lambda's parent scope * Introduce a lambda scope * Create the lambda class and call operator * Add the init captures to the call operator context and the lambda scope. But the variables are not capured yet (because we don't know their type). Instead, explicit captures are stored in a temporary map that conserves the order of capture (for the purpose of having a stable order in the ast dumps). * A flag is set on LambdaScopeInfo to indicate that we have not yet injected the captures. * The parameters are parsed (in the parent context, as lambda mangling recurses in the parent context, we couldn't mangle a lambda that is attached to the context of a lambda whose type is not yet known). * The lambda qualifiers are parsed, at this point, we can switch (for the second time) inside the lambda context, unset the flag indicating that we have not parsed the lambda qualifiers, record the lambda is mutable and capture the explicit variables. * We can parse the rest of the lambda type, transform the lambda and call operator's types and also transform the call operator to a template function decl where necessary. At this point, both captures and parameters can be injected in the body's scope. When trying to capture an implicit variable, if we are before the qualifiers of a lambda, we need to remember that the variables are still in the parent's context (rather than in the call operator's). This is a recommit of adff142dc2 after a fix in d8d793f29b4 Reviewed By: aaron.ballman, #clang-language-wg, ChuanqiXu Differential Revision: https://reviews.llvm.org/D119136
2022-04-13Revert "[clang] Implement Change scope of lambda trailing-return-type"Mehdi Amini1-5/+3
This reverts commit adff142dc253d65b6560e420bba6b858d88d4a98. This broke clang bootstrap: it made existing C++ code in LLVM invalid: llvm/include/llvm/CodeGen/LiveInterval.h:630:53: error: captured variable 'Idx' cannot appear here [=](std::remove_reference_t<decltype(*Idx)> V, ^
2022-04-13[clang] Implement Change scope of lambda trailing-return-typeCorentin Jabot1-3/+5
Implement P2036R3. Captured variables by copy (explicitely or not), are deduced correctly at the point we know whether the lambda is mutable, and ill-formed before that. Up until now, the entire lambda declaration up to the start of the body would be parsed in the parent scope, such that capture would not be available to look up. The scoping is changed to have an outer lambda scope, followed by the lambda prototype and body. The lambda scope is necessary because there may be a template scope between the start of the lambda (to which we want to attach the captured variable) and the prototype scope. We also need to introduce a declaration context to attach the captured variable to (and several parts of clang assume captures are handled from the call operator context), before we know the type of the call operator. The order of operations is as follow: * Parse the init capture in the lambda's parent scope * Introduce a lambda scope * Create the lambda class and call operator * Add the init captures to the call operator context and the lambda scope. But the variables are not capured yet (because we don't know their type). Instead, explicit captures are stored in a temporary map that conserves the order of capture (for the purpose of having a stable order in the ast dumps). * A flag is set on LambdaScopeInfo to indicate that we have not yet injected the captures. * The parameters are parsed (in the parent context, as lambda mangling recurses in the parent context, we couldn't mangle a lambda that is attached to the context of a lambda whose type is not yet known). * The lambda qualifiers are parsed, at this point We can switch (for the second time) inside the lambda context, unset the flag indicating that we have not parsed the lambda qualifiers, record the lambda is mutable and capture the explicit variables. * We can parse the rest of the lambda type, transform the lambda and call operator's types and also transform the call operator to a template function decl where necessary. At this point, both captures and parameters can be injected in the body's scope. When trying to capture an implicit variable, if we are before the qualifiers of a lambda, we need to remember that the variables are still in the parent's context (rather than in the call operator's). Reviewed By: aaron.ballman, #clang-language-wg, ChuanqiXu Differential Revision: https://reviews.llvm.org/D119136
2022-01-10[AST] Add more source information for DecltypeTypeLoc.Haojian Wu1-1/+2
Adds the paren source location, and removes the hack in clangd. Differential Revision: https://reviews.llvm.org/D116793
2021-12-20Reland "[AST] Add UsingType: a sugar type for types found via UsingDecl"Sam McCall1-4/+8
This reverts commit cc56c66f27e131b914082d3bd21180646e842e9a. Fixed a bad assertion, the target of a UsingShadowDecl must not have *local* qualifiers, but it can be a typedef whose underlying type is qualified.
2021-12-20Revert "[AST] Add UsingType: a sugar type for types found via UsingDecl"Sam McCall1-8/+4
This reverts commit e1600db19d6303f84b995acb9340459694e06ea9. Breaks sanitizer tests, at least on windows: https://lab.llvm.org/buildbot/#/builders/127/builds/21592/steps/4/logs/stdio
2021-12-20[AST] Add UsingType: a sugar type for types found via UsingDeclSam McCall1-4/+8
Currently there's no way to find the UsingDecl that a typeloc found its underlying type through. Compare to DeclRefExpr::getFoundDecl(). Design decisions: - a sugar type, as there are many contexts this type of use may appear in - UsingType is a leaf like TypedefType, the underlying type has no TypeLoc - not unified with UnresolvedUsingType: a single name is appealing, but being sometimes-sugar is often fiddly. - not unified with TypedefType: the UsingShadowDecl is not a TypedefNameDecl or even a TypeDecl, and users think of these differently. - does not cover other rarer aliases like objc @compatibility_alias, in order to be have a concrete API that's easy to understand. - implicitly desugared by the hasDeclaration ASTMatcher, to avoid breaking existing patterns and following the precedent of ElaboratedType. Scope: - This does not cover types associated with template names introduced by using declarations. A future patch should introduce a sugar TemplateName variant for this. (CTAD deduced types fall under this) - There are enough AST matchers to fix the in-tree clang-tidy tests and probably any other matchers, though more may be useful later. Caveats: - This changes a fairly common pattern in the AST people may depend on matching. Previously, typeLoc(loc(recordType())) matched whether a struct was referred to by its original scope or introduced via using-decl. Now, the using-decl case is not matched, and needs a separate matcher. This is similar to the case of typedefs but nevertheless both adds complexity and breaks existing code. Differential Revision: https://reviews.llvm.org/D114251
2021-11-15[clang] retain type sugar in auto / template argument deductionMatheus Izvekov1-1/+1
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-15Revert "[clang] retain type sugar in auto / template argument deduction"Matheus Izvekov1-1/+1
This reverts commit 4d8fff477e024698facd89741cc6cf996708d598.
2021-11-13[clang] retain type sugar in auto / template argument deductionMatheus Izvekov1-1/+1
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-12Revert "[clang] retain type sugar in auto / template argument deduction"Adrian Kuegel1-1/+1
This reverts commit 9b6036deedf28e10d797fc4ca734d57680d18053. Breaks two libc++ tests.
2021-11-12[clang] retain type sugar in auto / template argument deductionMatheus Izvekov1-1/+1
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-09-20[clang] Fix a few comment more typos to cycle botsNico Weber1-1/+1