r370558 - [c++20] Add support for designated direct-list-initialization syntax.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 30 18:00:38 PDT 2019
Author: rsmith
Date: Fri Aug 30 18:00:37 2019
New Revision: 370558
URL: http://llvm.org/viewvc/llvm-project?rev=370558&view=rev
Log:
[c++20] Add support for designated direct-list-initialization syntax.
This completes the implementation of P0329R4.
Added:
cfe/trunk/test/Parser/cxx2a-designated-init.cpp
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseInit.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/www/cxx_status.html
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=370558&r1=370557&r2=370558&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri Aug 30 18:00:37 2019
@@ -4831,6 +4831,10 @@ public:
SourceLocation getEqualOrColonLoc() const { return EqualOrColonLoc; }
void setEqualOrColonLoc(SourceLocation L) { EqualOrColonLoc = L; }
+ /// Whether this designated initializer should result in direct-initialization
+ /// of the designated subobject (eg, '{.foo{1, 2, 3}}').
+ bool isDirectInit() const { return EqualOrColonLoc.isInvalid(); }
+
/// Determines whether this designated initializer used the
/// deprecated GNU syntax for designated initializers.
bool usesGNUSyntax() const { return GNUSyntax; }
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=370558&r1=370557&r2=370558&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Aug 30 18:00:37 2019
@@ -4644,7 +4644,7 @@ public:
SourceLocation RBraceLoc);
ExprResult ActOnDesignatedInitializer(Designation &Desig,
- SourceLocation Loc,
+ SourceLocation EqualOrColonLoc,
bool GNUSyntax,
ExprResult Init);
Modified: cfe/trunk/lib/Parse/ParseInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseInit.cpp?rev=370558&r1=370557&r2=370558&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseInit.cpp (original)
+++ cfe/trunk/lib/Parse/ParseInit.cpp Fri Aug 30 18:00:37 2019
@@ -116,6 +116,8 @@ static void CheckArrayDesignatorSyntax(P
/// 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 @@ static void CheckArrayDesignatorSyntax(P
/// '[' 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 @@ ExprResult Parser::ParseInitializerWithP
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
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=370558&r1=370557&r2=370558&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Aug 30 18:00:37 2019
@@ -2367,6 +2367,29 @@ InitListChecker::CheckDesignatedInitiali
bool FinishSubobjectInit,
bool TopLevelObject) {
if (DesigIdx == DIE->size()) {
+ // C++20 designated initialization can result in direct-list-initialization
+ // of the designated subobject. This is the only way that we can end up
+ // performing direct initialization as part of aggregate initialization, so
+ // it needs special handling.
+ if (DIE->isDirectInit()) {
+ Expr *Init = DIE->getInit();
+ assert(isa<InitListExpr>(Init) &&
+ "designator result in direct non-list initialization?");
+ InitializationKind Kind = InitializationKind::CreateDirectList(
+ DIE->getBeginLoc(), Init->getBeginLoc(), Init->getEndLoc());
+ InitializationSequence Seq(SemaRef, Entity, Kind, Init,
+ /*TopLevelOfInitList*/ true);
+ if (StructuredList) {
+ ExprResult Result = VerifyOnly
+ ? getDummyInit()
+ : Seq.Perform(SemaRef, Entity, Kind, Init);
+ UpdateStructuredListElement(StructuredList, StructuredIndex,
+ Result.get());
+ }
+ ++Index;
+ return !Seq;
+ }
+
// Check the actual initialization for the designated object type.
bool prevHadError = hadError;
@@ -3101,7 +3124,7 @@ CheckArrayDesignatorExpr(Sema &S, Expr *
}
ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
- SourceLocation Loc,
+ SourceLocation EqualOrColonLoc,
bool GNUSyntax,
ExprResult Init) {
typedef DesignatedInitExpr::Designator ASTDesignator;
@@ -3189,8 +3212,9 @@ ExprResult Sema::ActOnDesignatedInitiali
// Clear out the expressions within the designation.
Desig.ClearExprs(*this);
- return DesignatedInitExpr::Create(Context, Designators, InitExpressions, Loc,
- GNUSyntax, Init.getAs<Expr>());
+ return DesignatedInitExpr::Create(Context, Designators, InitExpressions,
+ EqualOrColonLoc, GNUSyntax,
+ Init.getAs<Expr>());
}
//===----------------------------------------------------------------------===//
Added: cfe/trunk/test/Parser/cxx2a-designated-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx2a-designated-init.cpp?rev=370558&view=auto
==============================================================================
--- cfe/trunk/test/Parser/cxx2a-designated-init.cpp (added)
+++ cfe/trunk/test/Parser/cxx2a-designated-init.cpp Fri Aug 30 18:00:37 2019
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++98 -verify=cxx98 %s
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+struct A {
+ explicit A(int, int); // expected-note {{here}}
+};
+
+struct B {
+ A a;
+};
+
+B b1 = {.a = {1, 2}}; // cxx98-error {{non-aggregate type 'A' cannot be initialized with an initializer list}}
+// expected-error at -1 {{chosen constructor is explicit in copy-initialization}}
+B b2 = {.a{1, 2}}; // cxx98-error {{expected '='}}
+
+struct C {
+ char x, y;
+};
+struct D {
+ C c;
+};
+
+D d1 = {.c = {1, 2000}}; // cxx98-warning {{changes value}} expected-error {{narrow}} expected-warning {{changes value}} expected-note {{}}
+D d2 = {.c{1, 2000}}; // cxx98-error {{expected '='}} expected-error {{narrow}} expected-warning {{changes value}} expected-note {{}}
Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=370558&r1=370557&r2=370558&view=diff
==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Fri Aug 30 18:00:37 2019
@@ -871,7 +871,7 @@ as the draft C++2a standard evolves.
<tr>
<td>Designated initializers</td>
<td><a href="http://wg21.link/p0329r4">P0329R4</a></td>
- <td class="partial" align="center">Partial (extension)</td>
+ <td class="svn" align="center">SVN (Clang 10)</td>
</tr>
<tr>
<td><i>template-parameter-list</i> for generic lambdas</td>
More information about the cfe-commits
mailing list