[clang-tools-extra] 8cf2858 - [pseudo] Allow mixed designated/undesignated init lists.

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 28 06:46:09 PDT 2022


Author: Sam McCall
Date: 2022-06-28T15:45:41+02:00
New Revision: 8cf28585a40311163a08840beee035097638d41d

URL: https://github.com/llvm/llvm-project/commit/8cf28585a40311163a08840beee035097638d41d
DIFF: https://github.com/llvm/llvm-project/commit/8cf28585a40311163a08840beee035097638d41d.diff

LOG: [pseudo] Allow mixed designated/undesignated init lists.

This isn't allowed by the standard grammar but is allowed in C, and clang/GCC
permit it as an extension.
It avoids the need to determine which type of list we have in error-recovery.

While here, also support array index designators `{ [4]=1 }` which are
also legal in C, and common extensions in C++.

Differential Revision: https://reviews.llvm.org/D128687

Added: 
    clang-tools-extra/pseudo/test/cxx/mixed-designator.cpp

Modified: 
    clang-tools-extra/pseudo/lib/cxx.bnf

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/pseudo/lib/cxx.bnf b/clang-tools-extra/pseudo/lib/cxx.bnf
index ec05af94c0269..aa243db6c5b40 100644
--- a/clang-tools-extra/pseudo/lib/cxx.bnf
+++ b/clang-tools-extra/pseudo/lib/cxx.bnf
@@ -158,7 +158,10 @@ postfix-expression := REINTERPRET_CAST < type-id > ( expression )
 postfix-expression := CONST_CAST < type-id > ( expression )
 postfix-expression := TYPEID ( expression )
 postfix-expression := TYPEID ( type-id )
-expression-list := initializer-list
+#! Standard defines expression-list in terms of initializer-list, but our
+#  initializer-list allows designators.
+expression-list := initializer-clause ..._opt
+expression-list := expression-list , initializer-clause ..._opt
 # expr.unary
 unary-expression := postfix-expression
 unary-expression := unary-operator cast-expression
@@ -453,15 +456,17 @@ brace-or-equal-initializer := = initializer-clause
 brace-or-equal-initializer := braced-init-list
 initializer-clause := assignment-expression
 initializer-clause := braced-init-list
+#! Allow mixed designated/non-designated init-list.
+# This is standard C, and accepted by clang and others as an extension.
 braced-init-list := { initializer-list ,_opt }
-braced-init-list := { designated-initializer-list ,_opt }
 braced-init-list := { }
-initializer-list := initializer-clause ..._opt
-initializer-list := initializer-list , initializer-clause ..._opt
-designated-initializer-list := designated-initializer-clause
-designated-initializer-list := designated-initializer-list , designated-initializer-clause
-designated-initializer-clause := designator brace-or-equal-initializer
+initializer-list := initializer-list-item ..._opt
+initializer-list := initializer-list , initializer-list-item ..._opt
+initializer-list-item := initializer-clause
+initializer-list-item := designator brace-or-equal-initializer
 designator := . IDENTIFIER
+#! Array designators are legal in C, and a common extension in C++.
+designator := [ expression ]
 expr-or-braced-init-list := expression
 expr-or-braced-init-list := braced-init-list
 # dcl.fct

diff  --git a/clang-tools-extra/pseudo/test/cxx/mixed-designator.cpp b/clang-tools-extra/pseudo/test/cxx/mixed-designator.cpp
new file mode 100644
index 0000000000000..ec568390ffff5
--- /dev/null
+++ b/clang-tools-extra/pseudo/test/cxx/mixed-designator.cpp
@@ -0,0 +1,27 @@
+// RUN: clang-pseudo -grammar=%cxx-bnf-file -source=%s --print-forest | FileCheck %s
+// FIXME: tighten CHECK to CHECK-NEXT once numeric literals are unambiguous.
+auto x = { 1, .f = 2, [c]{3} };
+// CHECK:      initializer-clause~braced-init-list
+// CHECK-NEXT: ├─{ := tok[3]
+// CHECK-NEXT: ├─initializer-list
+// CHECK-NEXT: │ ├─initializer-list
+// CHECK-NEXT: │ │ ├─initializer-list~literal
+// CHECK:      │ │ ├─, := tok[5]
+// CHECK-NEXT: │ │ └─initializer-list-item
+// CHECK-NEXT: │ │   ├─designator
+// CHECK-NEXT: │ │   │ ├─. := tok[6]
+// CHECK-NEXT: │ │   │ └─IDENTIFIER := tok[7]
+// CHECK-NEXT: │ │   └─brace-or-equal-initializer
+// CHECK-NEXT: │ │     ├─= := tok[8]
+// CHECK-NEXT: │ │     └─initializer-clause~literal
+// CHECK:      │ ├─, := tok[10]
+// CHECK-NEXT: │ └─initializer-list-item
+// CHECK-NEXT: │   ├─designator
+// CHECK-NEXT: │   │ ├─[ := tok[11]
+// CHECK-NEXT: │   │ ├─expression~IDENTIFIER := tok[12]
+// CHECK-NEXT: │   │ └─] := tok[13]
+// CHECK-NEXT: │   └─brace-or-equal-initializer~braced-init-list
+// CHECK-NEXT: │     ├─{ := tok[14]
+// CHECK-NEXT: │     ├─initializer-list~literal
+// CHECK:      │     └─} := tok[16]
+// CHECK-NEXT: └─} := tok[17]


        


More information about the cfe-commits mailing list