Skip to content

Commit 41a9df2

Browse files
authored
[Clang] Fix handling of explicit parameters in SemaLambda (#168558)
Previously, the presence of an explicit parameter list was detected by querying `getNumTypeObjects()` from the `Declarator` block of the lambda definition. This breaks for lambdas which do not have a parameter list but _do_ have a trailing return type; that is, both of ``` []() -> int { return 0; }; [] -> int { return 0; }; ``` would return `true` when inspecting `LambdaExpr::hasExplicitParameters()`. Fix this by instead querying the `LParenLoc()` from the `Declarator`'s `FunctionTypeInfo`. If `isValid() == true`, then an explicit parameter list must be present, and if it is `false`, then it is not. This commit also adds `hasExplicitParameters` as an attribute to a `LambdaExpr`'s JSON AST dump. A new test (`ast-dump-lambda-json.cpp`) is also added to validate the fix and presence of the new attribute in the output. `ast-dump-expr-json.cpp` is also updated to validate the new attribute. Fixes #168452.
1 parent 764c1d4 commit 41a9df2

File tree

6 files changed

+3419
-9
lines changed

6 files changed

+3419
-9
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,9 @@ AST Matchers
684684

685685
- ``hasConditionVariableStatement`` now supports ``for`` loop, ``while`` loop
686686
and ``switch`` statements.
687+
- Fixed detection of explicit parameter lists in ``LambdaExpr``. (#GH168452)
688+
- Added ``hasExplicitParameters`` for ``LambdaExpr`` as an output attribute to
689+
AST JSON dumps.
687690

688691
clang-format
689692
------------

clang/include/clang/AST/JSONNodeDumper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ class JSONNodeDumper
315315
void VisitRequiresExpr(const RequiresExpr *RE);
316316
void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node);
317317
void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node);
318+
void VisitLambdaExpr(const LambdaExpr *LE);
318319

319320
void VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE);
320321
void VisitObjCMessageExpr(const ObjCMessageExpr *OME);

clang/lib/AST/JSONNodeDumper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,10 @@ void JSONNodeDumper::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) {
16071607
attributeOnlyIfTrue("hasRewrittenInit", Node->hasRewrittenInit());
16081608
}
16091609

1610+
void JSONNodeDumper::VisitLambdaExpr(const LambdaExpr *LE) {
1611+
JOS.attribute("hasExplicitParameters", LE->hasExplicitParameters());
1612+
}
1613+
16101614
void JSONNodeDumper::VisitCXXDependentScopeMemberExpr(
16111615
const CXXDependentScopeMemberExpr *DSME) {
16121616
JOS.attribute("isArrow", DSME->isArrow());

clang/lib/Sema/SemaLambda.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,16 +1439,16 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
14391439
TypeSourceInfo *MethodTyInfo = getLambdaType(
14401440
*this, Intro, ParamInfo, getCurScope(), TypeLoc, ExplicitResultType);
14411441

1442-
LSI->ExplicitParams = ParamInfo.getNumTypeObjects() != 0;
1443-
1444-
if (ParamInfo.isFunctionDeclarator() != 0 &&
1445-
!FTIHasSingleVoidParameter(ParamInfo.getFunctionTypeInfo())) {
1442+
if (ParamInfo.isFunctionDeclarator() != 0) {
14461443
const auto &FTI = ParamInfo.getFunctionTypeInfo();
1447-
Params.reserve(Params.size());
1448-
for (unsigned I = 0; I < FTI.NumParams; ++I) {
1449-
auto *Param = cast<ParmVarDecl>(FTI.Params[I].Param);
1450-
Param->setScopeInfo(0, Params.size());
1451-
Params.push_back(Param);
1444+
LSI->ExplicitParams = FTI.getLParenLoc().isValid();
1445+
if (!FTIHasSingleVoidParameter(FTI)) {
1446+
Params.reserve(Params.size());
1447+
for (unsigned I = 0; I < FTI.NumParams; ++I) {
1448+
auto *Param = cast<ParmVarDecl>(FTI.Params[I].Param);
1449+
Param->setScopeInfo(0, Params.size());
1450+
Params.push_back(Param);
1451+
}
14521452
}
14531453
}
14541454

clang/test/AST/ast-dump-expr-json.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3889,6 +3889,7 @@ void TestNonADLCall3() {
38893889
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:98:7)"
38903890
// CHECK-NEXT: },
38913891
// CHECK-NEXT: "valueCategory": "prvalue",
3892+
// CHECK-NEXT: "hasExplicitParameters": false,
38923893
// CHECK-NEXT: "inner": [
38933894
// CHECK-NEXT: {
38943895
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -4098,6 +4099,7 @@ void TestNonADLCall3() {
40984099
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:99:7)"
40994100
// CHECK-NEXT: },
41004101
// CHECK-NEXT: "valueCategory": "prvalue",
4102+
// CHECK-NEXT: "hasExplicitParameters": false,
41014103
// CHECK-NEXT: "inner": [
41024104
// CHECK-NEXT: {
41034105
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -4413,6 +4415,7 @@ void TestNonADLCall3() {
44134415
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:105:3)"
44144416
// CHECK-NEXT: },
44154417
// CHECK-NEXT: "valueCategory": "prvalue",
4418+
// CHECK-NEXT: "hasExplicitParameters": true,
44164419
// CHECK-NEXT: "inner": [
44174420
// CHECK-NEXT: {
44184421
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -4615,6 +4618,7 @@ void TestNonADLCall3() {
46154618
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:106:3)"
46164619
// CHECK-NEXT: },
46174620
// CHECK-NEXT: "valueCategory": "prvalue",
4621+
// CHECK-NEXT: "hasExplicitParameters": true,
46184622
// CHECK-NEXT: "inner": [
46194623
// CHECK-NEXT: {
46204624
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -4871,6 +4875,7 @@ void TestNonADLCall3() {
48714875
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:107:3)"
48724876
// CHECK-NEXT: },
48734877
// CHECK-NEXT: "valueCategory": "prvalue",
4878+
// CHECK-NEXT: "hasExplicitParameters": false,
48744879
// CHECK-NEXT: "inner": [
48754880
// CHECK-NEXT: {
48764881
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -5088,6 +5093,7 @@ void TestNonADLCall3() {
50885093
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:108:3)"
50895094
// CHECK-NEXT: },
50905095
// CHECK-NEXT: "valueCategory": "prvalue",
5096+
// CHECK-NEXT: "hasExplicitParameters": false,
50915097
// CHECK-NEXT: "inner": [
50925098
// CHECK-NEXT: {
50935099
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -5234,6 +5240,7 @@ void TestNonADLCall3() {
52345240
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:109:3)"
52355241
// CHECK-NEXT: },
52365242
// CHECK-NEXT: "valueCategory": "prvalue",
5243+
// CHECK-NEXT: "hasExplicitParameters": false,
52375244
// CHECK-NEXT: "inner": [
52385245
// CHECK-NEXT: {
52395246
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -5476,6 +5483,7 @@ void TestNonADLCall3() {
54765483
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:110:3)"
54775484
// CHECK-NEXT: },
54785485
// CHECK-NEXT: "valueCategory": "prvalue",
5486+
// CHECK-NEXT: "hasExplicitParameters": false,
54795487
// CHECK-NEXT: "inner": [
54805488
// CHECK-NEXT: {
54815489
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -5622,6 +5630,7 @@ void TestNonADLCall3() {
56225630
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:111:3)"
56235631
// CHECK-NEXT: },
56245632
// CHECK-NEXT: "valueCategory": "prvalue",
5633+
// CHECK-NEXT: "hasExplicitParameters": false,
56255634
// CHECK-NEXT: "inner": [
56265635
// CHECK-NEXT: {
56275636
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -5864,6 +5873,7 @@ void TestNonADLCall3() {
58645873
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:112:3)"
58655874
// CHECK-NEXT: },
58665875
// CHECK-NEXT: "valueCategory": "prvalue",
5876+
// CHECK-NEXT: "hasExplicitParameters": false,
58675877
// CHECK-NEXT: "inner": [
58685878
// CHECK-NEXT: {
58695879
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -6425,6 +6435,7 @@ void TestNonADLCall3() {
64256435
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:113:3)"
64266436
// CHECK-NEXT: },
64276437
// CHECK-NEXT: "valueCategory": "prvalue",
6438+
// CHECK-NEXT: "hasExplicitParameters": false,
64286439
// CHECK-NEXT: "inner": [
64296440
// CHECK-NEXT: {
64306441
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -6688,6 +6699,7 @@ void TestNonADLCall3() {
66886699
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:114:3)"
66896700
// CHECK-NEXT: },
66906701
// CHECK-NEXT: "valueCategory": "prvalue",
6702+
// CHECK-NEXT: "hasExplicitParameters": true,
66916703
// CHECK-NEXT: "inner": [
66926704
// CHECK-NEXT: {
66936705
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -6892,6 +6904,7 @@ void TestNonADLCall3() {
68926904
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:115:3)"
68936905
// CHECK-NEXT: },
68946906
// CHECK-NEXT: "valueCategory": "prvalue",
6907+
// CHECK-NEXT: "hasExplicitParameters": true,
68956908
// CHECK-NEXT: "inner": [
68966909
// CHECK-NEXT: {
68976910
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -7094,6 +7107,7 @@ void TestNonADLCall3() {
70947107
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:116:3)"
70957108
// CHECK-NEXT: },
70967109
// CHECK-NEXT: "valueCategory": "prvalue",
7110+
// CHECK-NEXT: "hasExplicitParameters": true,
70977111
// CHECK-NEXT: "inner": [
70987112
// CHECK-NEXT: {
70997113
// CHECK-NEXT: "id": "0x{{.*}}",
@@ -7296,6 +7310,7 @@ void TestNonADLCall3() {
72967310
// CHECK-NEXT: "qualType": "(lambda at {{.*}}:117:3)"
72977311
// CHECK-NEXT: },
72987312
// CHECK-NEXT: "valueCategory": "prvalue",
7313+
// CHECK-NEXT: "hasExplicitParameters": true,
72997314
// CHECK-NEXT: "inner": [
73007315
// CHECK-NEXT: {
73017316
// CHECK-NEXT: "id": "0x{{.*}}",

0 commit comments

Comments
 (0)