aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseInit.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-01-22 00:58:24 +0000
committerDouglas Gregor <dgregor@apple.com>2009-01-22 00:58:24 +0000
commit05c13a3411782108d65aab3c77b1a231a4963bc0 (patch)
tree06c579135c022b061f4665e7607296b0920c9261 /lib/Parse/ParseInit.cpp
parentdb2868616b966c96a5014e58892c27cea377477c (diff)
Initial implementation of semantic analysis and ASTs for C99
designated initializers. This implementation should cover all of the constraints in C99 6.7.8, including long, complex designations and computing the size of incomplete array types initialized with a designated initializer. Please see the new test-case and holler if you find cases where this doesn't work. There are still some wrinkles with GNU's anonymous structs and anonymous unions (it isn't clear how these should work; we'll just follow GCC's lead) and with designated initializers for the members of a union. I'll tackle those very soon. CodeGen is still nonexistent, and there's some leftover code in the parser's representation of designators that I'll also need to clean up. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62737 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseInit.cpp')
-rw-r--r--lib/Parse/ParseInit.cpp36
1 files changed, 22 insertions, 14 deletions
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp
index ff73b0b9e1..b5d0ec05db 100644
--- a/lib/Parse/ParseInit.cpp
+++ b/lib/Parse/ParseInit.cpp
@@ -68,13 +68,16 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations,
if (Tok.is(tok::identifier)) {
Diag(Tok, diag::ext_gnu_old_style_field_designator);
- Designation &D = Designations.CreateDesignation(InitNum);
- D.AddDesignator(Designator::getField(Tok.getIdentifierInfo()));
- ConsumeToken(); // Eat the identifier.
+ const IdentifierInfo *FieldName = Tok.getIdentifierInfo();
+ SourceLocation NameLoc = ConsumeToken(); // Eat the identifier.
assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!");
- ConsumeToken();
- return ParseInitializer();
+ SourceLocation ColonLoc = ConsumeToken();
+
+ Designation &D = Designations.CreateDesignation(InitNum);
+ D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc));
+ return Actions.ActOnDesignatedInitializer(D, ColonLoc, true,
+ ParseInitializer());
}
// Desig - This is initialized when we see our first designator. We may have
@@ -86,7 +89,7 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations,
while (Tok.is(tok::period) || Tok.is(tok::l_square)) {
if (Tok.is(tok::period)) {
// designator: '.' identifier
- ConsumeToken();
+ SourceLocation DotLoc = ConsumeToken();
// Create designation if we haven't already.
if (Desig == 0)
@@ -97,7 +100,8 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations,
return ExprError();
}
- Desig->AddDesignator(Designator::getField(Tok.getIdentifierInfo()));
+ Desig->AddDesignator(Designator::getField(Tok.getIdentifierInfo(), DotLoc,
+ Tok.getLocation()));
ConsumeToken(); // Eat the identifier.
continue;
}
@@ -179,11 +183,12 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations,
// If this is a normal array designator, remember it.
if (Tok.isNot(tok::ellipsis)) {
- Desig->AddDesignator(Designator::getArray(Idx.release()));
+ Desig->AddDesignator(Designator::getArray(Idx.release(),
+ StartLoc));
} else {
// Handle the gnu array range extension.
Diag(Tok, diag::ext_gnu_array_range);
- ConsumeToken();
+ SourceLocation EllipsisLoc = ConsumeToken();
OwningExprResult RHS(ParseConstantExpression());
if (RHS.isInvalid()) {
@@ -191,10 +196,12 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations,
return move(RHS);
}
Desig->AddDesignator(Designator::getArrayRange(Idx.release(),
- RHS.release()));
+ RHS.release(),
+ StartLoc, EllipsisLoc));
}
- MatchRHSPunctuation(tok::r_square, StartLoc);
+ SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
+ Desig->getDesignator(Desig->getNumDesignators() - 1).setRBracketLoc(EndLoc);
}
// Okay, we're done with the designator sequence. We know that there must be
@@ -205,8 +212,9 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations,
// Handle a normal designator sequence end, which is an equal.
if (Tok.is(tok::equal)) {
- ConsumeToken();
- return ParseInitializer();
+ SourceLocation EqualLoc = ConsumeToken();
+ return Actions.ActOnDesignatedInitializer(*Desig, EqualLoc, false,
+ ParseInitializer());
}
// We read some number of designators and found something that isn't an = or
@@ -274,7 +282,7 @@ Parser::OwningExprResult Parser::ParseBraceInitializer() {
// If we had an erroneous initializer, and we had a potentially valid
// designator, make sure to remove the designator from
// InitExprDesignations, otherwise we'll end up with a designator with no
- // making initializer.
+ // matching initializer.
if (SubElt.isInvalid())
InitExprDesignations.EraseDesignation(InitExprs.size());
}