[c++20] Add support for designated direct-list-initialization syntax.

This completes the implementation of P0329R4.

llvm-svn: 370558
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
index eaf31e8..5ab0551 100644
--- a/clang/lib/Parse/ParseInit.cpp
+++ b/clang/lib/Parse/ParseInit.cpp
@@ -116,6 +116,8 @@
 /// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production
 /// checking to see if the token stream starts with a designator.
 ///
+/// C99:
+///
 ///       designation:
 ///         designator-list '='
 /// [GNU]   array-designator
@@ -133,6 +135,21 @@
 ///         '[' constant-expression ']'
 /// [GNU]   '[' constant-expression '...' constant-expression ']'
 ///
+/// C++20:
+///
+///       designated-initializer-list:
+///         designated-initializer-clause
+///         designated-initializer-list ',' designated-initializer-clause
+///
+///       designated-initializer-clause:
+///         designator brace-or-equal-initializer
+///
+///       designator:
+///         '.' identifier
+///
+/// We allow the C99 syntax extensions in C++20, but do not allow the C++20
+/// extension (a braced-init-list after the designator with no '=') in C99.
+///
 /// NOTE: [OBC] allows '[ objc-receiver objc-message-args ]' as an
 /// initializer (because it is an expression).  We need to consider this case
 /// when parsing array designators.
@@ -365,6 +382,14 @@
                                               ParseInitializer());
   }
 
+  // Handle a C++20 braced designated initialization, which results in
+  // direct-list-initialization of the aggregate element. We allow this as an
+  // extension from C++11 onwards (when direct-list-initialization was added).
+  if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus11) {
+    return Actions.ActOnDesignatedInitializer(Desig, SourceLocation(), false,
+                                              ParseBraceInitializer());
+  }
+
   // We read some number of designators and found something that isn't an = or
   // an initializer.  If we have exactly one array designator, this
   // is the GNU 'designation: array-designator' extension.  Otherwise, it is a