Community
Participate
Working Groups
We need to add semantic support for constexpr lambda expressions in order to have expression evaluation.
Gerrit change https://git.eclipse.org/r/159362 was merged to [master]. Commit: http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=16d73e00818bd186c2e62e2cbacca3b88d124e29
At the moment, with the previous commit, basic semantic support has been added to CDT. However the support isn't complete yet, since we need to model lambda captures as closure fields in order to have a complete "static" evaluation of the expression. Example of test cases to be addressed: constexpr int f() { return ([]() constexpr -> int {return 58;})(); } constexpr int x = f(); constexpr int f() { int a = 58; return ([=]() constexpr -> int {return a;})(); } constexpr int x = f(); constexpr int f() { int b = 57; return ([a = b + 1]() constexpr -> int {return a;})(); } constexpr int x = f();
(In reply to Marco Stornelli from comment #2) > constexpr int f() { > return ([]() constexpr -> int {return 58;})(); > } > constexpr int x = f(); Note, this test case doesn't involve a capture, so if it's failing there is something else going on.
Oops, my fault, yes, you are right, I copied pasted the test cases here just for reference and I didn't notice it.
@Nathan I was looking at that test and it's failing. The problem is inside the method "ICPPExecution computeFunctionBodyExecution(IASTNode def)" of CPPFunction. When this method is called, it calls getFunctionDefinition(). In this particular case it finds f() again and here we have a loop until the code hit the max steps threshold. Basically it seems to me that getFunctionDefinition() should take into accounts lambda expressions too or we need to perform a basic check before like that: public static ICPPExecution computeFunctionBodyExecution(IASTNode def) { if (def.getParent() instanceof ICPPASTLambdaExpression) { <-----additional check ......... } ICPPASTFunctionDefinition fnDef = getFunctionDefinition(def); if (fnDef == null) { ..... } ....... } Let me know what you think about that.
We can just inline the body of getFunctionDefintion() into computeFunctionBodyExection(), and modify the loop to check for a lambda expression as well.
I did the change but the test with the index strategy if the function is declared in the header file doesn't work. I tried to follow the code and I guess there's something wrong "around" PDOMCPPFunction but I didn't understand where to look into the index code.
Yes, I am not surprised that index support requires extra work. Please feel free to land the test case with all the code being in the main file (no header). I can try to look into the index stuff as time permits (it may take a few weeks).
New Gerrit change created: https://git.eclipse.org/r/159642
Gerrit change https://git.eclipse.org/r/159642 was merged to [master]. Commit: http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=c3346dd6cc9b6d90ed01e46db5c138fb10202c1b
Just a summary. We need two additional steps in this moment: model captures as fields (test2 and test3) and fix the index when the constexpr is defined in header file (test1). test1: header file constexpr int f() { return ([]() constexpr -> int {return 58;})(); } cpp file constexpr int x = f(); test2: constexpr int f() { int a = 58; return ([=]() constexpr -> int {return a;})(); } constexpr int x = f(); test3: constexpr int f() { int b = 57; return ([a = b + 1]() constexpr -> int {return a;})(); } constexpr int x = f();
The index problem occurs because we fail to store the CPPClosureType in the index. It's a local binding (its owner is a function), and in PDOMCPPLinkage.adaptOrAddParent() we have some logic that limits which local bindings are stored in the index. We can relax this to include closure types (in fact, all types).
New Gerrit change created: https://git.eclipse.org/r/159867
For modelling captures, the place to start looking is CPPASTLambdaExpression.getEvaluation(). Where we currently pass IntegralValue.UNKNOWN, we will want to pass a CompositeValue representing an object of the closure's type.
(In reply to Eclipse Genie from comment #13) > New Gerrit change created: https://git.eclipse.org/r/159867 This patch fixes the index issue.
Gerrit change https://git.eclipse.org/r/159867 was merged to [master]. Commit: http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=ce974266881b99ce2eec9e7daed6b33beef2b66c
Are these patches in CDT 9.11 (Eclipse 2020-09)? The following code (from https://docs.microsoft.com/de-de/cpp/cpp/lambda-expressions-constexpr?view=msvc-160) is indicated as an error in the editor: int y = 32; auto answer = [y]() constexpr { int x = 10; return y + x; }; If I rewrite the code to have constexpr up-front everything is fine. int y = 32; constexpr auto answer = [y]() { int x = 10; return y + x; };
(In reply to Axel Mueller from comment #17) > Are these patches in CDT 9.11 (Eclipse 2020-09)? The patch required to parse 'constexpr' in a lambda-declarator (which was in bug 560483) is in CDT 10.0. It is not in CDT 9.11. However, Eclipse 2020-09 should include CDT 10.0.
(In reply to Nathan Ridge from comment #18) > The patch required to parse 'constexpr' in a lambda-declarator (which was in > bug 560483) is in CDT 10.0. It is not in CDT 9.11. > > However, Eclipse 2020-09 should include CDT 10.0. Sorry, I have indeed CDT 10.0 installed (only some features report version 9.11). But unfortunately, the expression in bug 560483 shows an error in the editor
Which features report version 9.11? A mixture of versions can indicate an incomplete installation or upgrade. I did just download an unmodified 2020-09 Eclipse C++ package, and the code is parsed successfully.
(In reply to Nathan Ridge from comment #20) > Which features report version 9.11? A mixture of versions can indicate an > incomplete installation or upgrade. > > I did just download an unmodified 2020-09 Eclipse C++ package, and the code > is parsed successfully. I did run an update and now all features indicate version 10.0.1. The problem with the constexpr is gone. Thanks.