aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaLambda.cpp
AgeCommit message (Collapse)AuthorFilesLines
2023-09-06[Clang] Add captures to the instantiation scope of lambda call operatorsCorentin Jabot1-0/+32
Like concepts checking, a trailing return type of a lambda in a dependent context may refer to captures in which case they may need to be rebuilt, so the map of local decl should include captures. This patch reveal a pre-existing issue. `this` is always recomputed by TreeTransform. `*this` (like all captures) only become `const` after the parameter list. However, if try to recompute the value of `this` (in a parameter) during template instantiation while determining the type of the call operator, we will determine it to be const (unless the lambda is mutable). There is no good way to know at that point that we are in a parameter or not, the easiest/best solution is to transform the type of this. Note that doing so break a handful of HLSL tests. So this is a prototype at this point. Fixes #65067 Fixes #63675 Reviewed By: erichkeane Differential Revision: https://reviews.llvm.org/D159126
2023-09-02[Clang] Realize generic lambda call operators are dependent soonerCorentin Jabot1-5/+27
When parsing a trailing return type / noexcept / constraint of a generic lambda, we need to know that we are in a dependent context. We currently don't because we only create a TemplateDecl for the call operator one its fully parsed. This patch attach a template decl to the call operator as soon as the parameter declaration clause is parsed - the point at which we have collected all template parameters Fixes #64689 Reviewed By: erichkeane Differential Revision: https://reviews.llvm.org/D159358
2023-08-04[Clang] Implement P2169 A nice placeholder with no nameCorentin Jabot1-2/+12
This is a C++ feature that allows the use of `_` to declare multiple variable of that name in the same scope; these variables can then not be referred to. In addition, while P2169 does not extend to parameter declarations, we stop warning on unused parameters of that name, for consistency. The feature is backported to all C++ language modes. Reviewed By: #clang-language-wg, aaron.ballman Differential Revision: https://reviews.llvm.org/D153536
2023-07-21[Clang] Fix constraint checking of non-generic lambdas.Corentin Jabot1-0/+5
A lambda call operator can be a templated entity - and therefore have constraints while not being a function template template<class T> void f() { []() requires false { }(); } In that case, we would check the constraints of the call operator which is non-viable. However, we would find a viable candidate: the conversion operator to function pointer, and use it to perform a surrogate call. These constraints were not checked because: * We never check the constraints of surrogate functions * The lambda conversion operator has non constraints. From the wording, it is not clear what the intent is but it seems reasonable to expect the constraints of the lambda conversion operator to be checked and it is consistent with GCC and MSVC. This patch also improve the diagnostics for constraint failure on surrogate calls. Fixes #63181 Reviewed By: #clang-language-wg, aaron.ballman Differential Revision: https://reviews.llvm.org/D154368
2023-06-07[clang] Implement P2564 "consteval must propagate up"Corentin Jabot1-0/+4
Reviewed By: aaron.ballman, #clang-language-wg Differential Revision: https://reviews.llvm.org/D151094
2023-06-07Fix parameter name in Sema::addInitCapture to ByRef.Jens Massberg1-5/+4
Rename parameter in Sema::addInitCapture as proposed in review of Sema::addInitCapture. Sorry, that I have missed the comment there! Reviewed By: ilya-biryukov Differential Revision: https://reviews.llvm.org/D139541
2023-04-28[clang] Diagnose shadowing of lambda's template parameter by a captureMariya Podchishchaeva1-0/+20
expr.prim.lambda.capture p5 says: If an identifier in a capture appears as the declarator-id of a parameter of the lambda-declarator's parameter-declaration-clause or as the name of a template parameter of the lambda-expression's template-parameter-list, the program is ill-formed. and also has the following example: ``` auto h = [y = 0]<typename y>(y) { return 0; }; ``` which now results in ``` error: declaration of 'y' shadows template parameter auto l1 = [y = 0]<typename y>(y) { return 0; }; ^ note: template parameter is declared here auto l1 = [y = 0]<typename y>(y) { return 0; }; ^ ``` Fixes https://github.com/llvm/llvm-project/issues/61105 Reviewed By: shafik, cor3ntin Differential Revision: https://reviews.llvm.org/D148712
2023-04-06[Sema] Populate declarations inside TypeLocs for some invalid typesIlya Biryukov1-2/+1
This also reverts 282cae0b9a602267ad7ef622f770066491332a11 as the particular crash is now handled by the new code. Before this change Clang would always leave declarations inside the type-locs as `null` if the declarator had an invalid type. This patch populates declarations even for invalid types if the structure of the type and the type-locs match. There are certain cases that may still cause crashes. These happen when Clang recovers the type in a way that is not reflected in the declarator's structure, e.g. adding a pointer when it was not present in the code for ObjC interfaces or ignoring pointers written in the code in C++ with auto return type (`auto* foo() -> int`). Those cases look fixable with a better recovery strategy and I plan to follow up with more patches to address those. The first attempt caused 31 tests from `check-clang` to crash due to different structure of the types and type-locs after certain errors. The good news is that the failure is localized and mismatch in structures is discovered by assertions inside `DeclaratorLocFiller`. Some notable cases caught by existing tests: - Invalid chunks when type is fully ignored and replace with int or now. Crashed in `C/C2x/n2838.c`. - Invalid return types in lambdas. Crashed in `CXX/drs/dr6xx.cpp`. - Invalid member pointers. Crashed in `CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp` - ObjC recovery that adds pointers. Crashed in `SemaObjC/blocks.m` This change also updates the output of `Index/complete-blocks.m`. Not entirely sure what causes the change, but the new function signature is closer to the source code, so this seems like an improvement. Reviewed By: aaron.ballman, erichkeane Differential Revision: https://reviews.llvm.org/D146971
2023-04-04PR58819: Correct linkage and mangling of lambdas in inline static member ↵David Blaikie1-22/+13
initializers https://llvm.org/pr58819 - clang is giving an externally visible lambda in a static data member internal linkage and the wrong linkage name. Looks like we should be classifying this case the same as a non-static data member, so far as I can tell from the ABI docs and template examples (seems like the non-template inline-defined case should be the same). This is a change in ABI, but not sure it qualifies as an ABI break as far as Apple and Sony are concerned - do you folks want this change? (it should fix the example in the bug where a static member in such a lambda ends up bifurcated, and I don't /think/ it'll break existing code since the symbol was previously internal anyway) Looks like GCC has got this mangling slightly wrong (so we'd still end up with GCC+Clang bifurcation of the local static in the lambda, function address inequality, etc) in that they miss the variable name in the mangling in the non-template case. GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107741 Differential Revision: https://reviews.llvm.org/D138247
2023-03-30PR60985: Fix merging of lambda closure types across modules.Richard Smith1-22/+17
Previously, distinct lambdas would get merged, and multiple definitions of the same lambda would not get merged, because we attempted to identify lambdas by their ordinal position within their lexical DeclContext. This failed for lambdas within namespace-scope variables and within variable templates, where the lexical position in the context containing the variable didn't uniquely identify the lambda. In this patch, we instead identify lambda closure types by index within their context declaration, which does uniquely identify them in a way that's consistent across modules. This change causes a deserialization cycle between the type of a variable with deduced type and a lambda appearing as the initializer of the variable -- reading the variable's type requires reading and merging the lambda, and reading the lambda requires reading and merging the variable. This is addressed by deferring loading the deduced type of a variable until after we finish recursive deserialization. This also exposes a pre-existing subtle issue where loading a variable declaration would trigger immediate loading of its initializer, which could recursively refer back to properties of the variable. This particularly causes problems if the initializer contains a lambda-expression, but can be problematic in general. That is addressed by switching to lazily loading the initializers of variables rather than always loading them with the variable declaration. As well as fixing a deserialization cycle, that should improve laziness of deserialization in general. LambdaDefinitionData had 63 spare bits in it, presumably caused by an off-by-one-error in some previous change. This change claims 32 of those bits as a counter for the lambda within its context. We could probably move the numbering to separate storage, like we do for the device-side mangling number, to optimize the likely-common case where all three numbers (host-side mangling number, device-side mangling number, and index within the context declaration) are zero, but that's not done in this change. Fixes #60985. Reviewed By: #clang-language-wg, aaron.ballman Differential Revision: https://reviews.llvm.org/D145737
2023-03-29Improve requirement clause limitation on non templated functionErich Keane1-0/+31
The current implementation 6da3d66f03f9162ef341cc67218be40e22fe9808 got a few things wrong, particularly that a template, or definition or member in a templated entity is required to be allowed to have a trailing requires clause. This patch corrects this, as reproted by #61748 Fixes: #61748 Differential Revision: https://reviews.llvm.org/D147070
2023-03-23[Clang] Fix evaluation of parameters of lambda call operator attributesCorentin Jabot1-4/+3
Fix a regresion introduced by D124351. Attributes of lambda call operator were evaluated in the context of the closure object type rather than its operator, causing an assertion failure. This was because we temporarily switch to the class lambda to produce the mangling of the lambda, but we stayed in that context too long. Reviewed By: eandrews, aaron.ballman Differential Revision: https://reviews.llvm.org/D146535
2023-03-21[Sema] Fix crash on __fp16 parameters in template instantiationsIlya Biryukov1-1/+4
Fixes #61441. Currently, Clang stores `nullptr` in the parameter lists inside `FunctionProtoTypeLoc` if `__fp16` is used without pointer qualifiers. Any code path that calls `Declarator::setInvalidType()` before `GetFullTypeForDeclarator` will lead to the same problem downstream. The relevant code is: ```cpp if (D.isInvalidType()) return Context.getTrivialTypeSourceInfo(T); return GetTypeSourceInfoForDeclarator(state, T, TInfo); ``` `GetTypeSourceInfoForDeclarator` sets the parameter `Decl`, but we can't call it when `isInvalidType() == true` as this causes other assertion failures that seem harder to fix. Reviewed By: kadircet Differential Revision: https://reviews.llvm.org/D146426
2023-03-02[Clang] Implement Change scope of lambda trailing-return-typeCorentin Jabot1-277/+379
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-23[Clang] Fix a crash when taking the address of a consteval lambdaCorentin Jabot1-1/+1
The `_invoke` function of lambdas was not respecting the constexpr/consteval specifier of the call operator, so it was possible to take its address in a non-immmediately invoked context, even if the call operator was itself consteval. In addition, we improve the diagnostic emmited in the lambda case not to show that `invoke` method. Fixes #57682 Reviewed By: aaron.ballman, #clang-language-wg Differential Revision: https://reviews.llvm.org/D144627
2023-02-03Revert "[Clang] Implement Change scope of lambda trailing-return-type"Jordan Rupprecht1-383/+277
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-277/+383
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
2023-01-14[clang] Use std::optional instead of llvm::Optional (NFC)Kazu Hirata1-16/+17
This patch replaces (llvm::|)Optional< with std::optional<. I'll post a separate patch to remove #include "llvm/ADT/Optional.h". This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-14[clang] Add #include <optional> (NFC)Kazu Hirata1-0/+1
This patch adds #include <optional> to those files containing llvm::Optional<...> or Optional<...>. I'll post a separate patch to actually replace llvm::Optional with 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
2023-01-09[Clang] Correctly capture bindings in dependent lambdas.Corentin Jabot1-7/+3
Structured bindings were not properly marked odr-used and therefore captured in generic lambddas. Fixes #57826 It is unclear to me if further simplification can be gained through the allowance described in https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0588r1.html. Either way, I think this makes support for P0588 completes, but we probably want to add test for that in a separate PR. (and I lack confidence I understand P0588 sufficiently to assert the completeness of our cnformance). Reviewed By: aaron.ballman, #clang-language-wg Differential Revision: https://reviews.llvm.org/D137244
2022-12-16[clang][dataflow] Remove unused argument in getNullabilityDani Ferreira Franco Moura1-2/+2
This change will allow users to call getNullability() without providing an ASTContext. Reviewed By: gribozavr2 Differential Revision: https://reviews.llvm.org/D140104
2022-12-07[clang] Correctly handle by-reference capture with an initializer that is a ↵Jens Massberg1-5/+6
pack expansion in lambdas. Ensure that the correct information whether an init-capture of a lambda is passed by reference or by copy. This information is already computed and has to be passed to the place where `NewInitCaptureType` is created. Before this fix it has been checked whether the VarDecl is a reference type. This doesn't work for packed expansions, as the information whether it is passed by reference or by copy is stored at the pattern of a `PackExpansionType` and not at the type itself. However, as the information has been already computed, we just have to pass it. Add tests that lambda captures with var decls which are reference types are created in the AST and a disgnotics test for pack expansions. Fixes #49266 Differential Revision: https://reviews.llvm.org/D139125
2022-12-03[Sema] Use std::nullopt instead of None (NFC)Kazu Hirata1-4/+5
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-10-24"Reapply "GH58368: Correct concept checking in a lambda defined in concept""Erich Keane1-1/+9
This reverts commit cecc9a92cfca71c1b6c2a35c5e302ab649496d11. The problem ended up being how we were handling the lambda-context in code generation: we were assuming any decl context here would be a named-decl, but that isn't the case. Instead, we just replace it with the concept's owning context. Differential Revision: https://reviews.llvm.org/D136451
2022-10-24Revert "Reapply "GH58368: Correct concept checking in a lambda defined in ↵Erich Keane1-9/+1
concept""" This reverts commit b876f6e2f28779211a829d7d4e841fe68885ae20. Still getting build failures on PPC AIX that aren't obvious what is causing them, so reverting while I try to figure this out.
2022-10-24Reapply "GH58368: Correct concept checking in a lambda defined in concept""Erich Keane1-1/+9
This reverts commit 52930162870fee52d0d9c07c5d66e5dce32b08e8. Now with updating the ASTBitcodes to show that this AST is incompatible from the last.
2022-10-24Revert "GH58368: Correct concept checking in a lambda defined in concept"Erich Keane1-9/+1
This reverts commit b7c922607c5ba93db8b893d4ba461052af8317b5. This seems to cause some problems with some modules related things, which makes me think I should have updated the version-major in ast-bit-codes? Going to revert to confirm this was a problem, then change that and re-try a commit.
2022-10-24GH58368: Correct concept checking in a lambda defined in conceptErich Keane1-1/+9
As that bug reports, the problem here is that the lambda's 'context-decl' was not set to the concept, and the lambda picked up template arguments from the concept. SO, we failed to get the correct template arguments in SemaTemplateInstantiate. However, a Concept Specialization is NOT a decl, its an expression, so we weren't able to put the concept in the decl tree like we needed. This patch introduces a ConceptSpecializationDecl, which is the smallest type possible to use for this purpose, containing only the template arguments. The net memory impliciation of this is turning a trailing-objects into a pointer to a type with trailing-objects, so it should be minor. As future work, we may consider giving this type more responsibility, or figuring out how to better merge duplicates, but as this is just a template-argument collection at the moment, there isn't much value to it. Differential Revision: https://reviews.llvm.org/D136451
2022-10-20[HLSL] Add groupshare address space.Xiang Li1-0/+12
Added keyword, LangAS and TypeAttrbute for groupshared. Tanslate it to LangAS with asHLSLLangAS. Make sure it translated into address space 3 for DirectX target. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D135060
2022-10-15[clang] Fix a warningKazu Hirata1-5/+5
This patch fixes: clang/lib/Sema/SemaLambda.cpp:922:39: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
2022-09-29[Clang] P1169R4: static operator()Roy Jacobson1-48/+61
Implements 'P1169R4: static operator()' from C++2b. Reviewed By: #clang-language-wg, aaron.ballman Differential Revision: https://reviews.llvm.org/D133659
2022-09-03[clang] Qualify auto in range-based for loops (NFC)Kazu Hirata1-1/+1
2022-08-08[clang] LLVM_FALLTHROUGH => [[fallthrough]]. NFCFangrui Song1-1/+1
With C++17 there is no Clang pedantic warning or MSVC C5051. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D131346
2022-08-04[Clang][C++20] Support capturing structured bindings in lambdasCorentin Jabot1-11/+20
This completes the implementation of P1091R3 and P1381R1. This patch allow the capture of structured bindings both for C++20+ and C++17, with extension/compat warning. In addition, capturing an anonymous union member, a bitfield, or a structured binding thereof now has a better diagnostic. We only support structured bindings - as opposed to other kinds of structured statements/blocks. We still emit an error for those. In addition, support for structured bindings capture is entirely disabled in OpenMP mode as this needs more investigation - a specific diagnostic indicate the feature is not yet supported there. Note that the rest of P1091R3 (static/thread_local structured bindings) was already implemented. at the request of @shafik, i can confirm the correct behavior of lldb wit this change. Fixes https://github.com/llvm/llvm-project/issues/54300 Fixes https://github.com/llvm/llvm-project/issues/54300 Fixes https://github.com/llvm/llvm-project/issues/52720 Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D122768
2022-08-03Revert "[Clang][C++20] Support capturing structured bindings in lambdas"Corentin Jabot1-20/+11
This reverts commit 44f2baa3804a62ca793f0ff3e43aa71cea91a795. Breaks self builds and seems to have conformance issues.
2022-08-03[Clang][C++20] Support capturing structured bindings in lambdasCorentin Jabot1-11/+20
This completes the implementation of P1091R3 and P1381R1. This patch allow the capture of structured bindings both for C++20+ and C++17, with extension/compat warning. In addition, capturing an anonymous union member, a bitfield, or a structured binding thereof now has a better diagnostic. We only support structured bindings - as opposed to other kinds of structured statements/blocks. We still emit an error for those. In addition, support for structured bindings capture is entirely disabled in OpenMP mode as this needs more investigation - a specific diagnostic indicate the feature is not yet supported there. Note that the rest of P1091R3 (static/thread_local structured bindings) was already implemented. at the request of @shafik, i can confirm the correct behavior of lldb wit this change. Fixes https://github.com/llvm/llvm-project/issues/54300 Fixes https://github.com/llvm/llvm-project/issues/54300 Fixes https://github.com/llvm/llvm-project/issues/52720 Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D122768
2022-06-20[clang] Don't use Optional::getValue (NFC)Kazu Hirata1-2/+2
2022-04-20Revert D119136 "[clang] Implement Change scope of lambda ↵Fangrui Song1-427/+311
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-20[Clang] Fix references to captured variables in dependant context.Corentin Jabot1-133/+69
D119136 changed how captures are handled in a lambda call operator declaration, but did not properly handled dependant context, which led to crash when refering to init-captures in a trailing return type. We fix that bug by making transformations more symetric with parsing, ie. we first create the call operator, then transform the capture, then compute the type of the lambda call operaror. This ensures captures exist and have the right type when we parse a trailing requires-clause / return type. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D124012
2022-04-15[clang] Implement Change scope of lambda trailing-return-typeCorentin Jabot1-272/+452
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-449/+272
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-272/+449
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-449/+272
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-272/+449
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-03-25[Clang] Fix Unevaluated LambdasCorentin Jabot1-16/+15
Unlike other types, when lambdas are instanciated, they are recreated from scratch. When an unevaluated lambdas appear in the type of a function, parameter it is instanciated in the wrong declaration context, as parameters are transformed before the function. To support lambda in function parameters, we try to compute whether they are dependant without looking at the declaration context. This is a short term stopgap solution to avoid clang iceing. A better fix might be to inject some kind of transparent declaration with correctly computed dependency for function parameters, variable templates, etc. Fixes https://github.com/llvm/llvm-project/issues/50376 Fixes https://github.com/llvm/llvm-project/issues/51414 Fixes https://github.com/llvm/llvm-project/issues/51416 Fixes https://github.com/llvm/llvm-project/issues/51641 Fixes https://github.com/llvm/llvm-project/issues/54296 Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D121532
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