diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-01-22 00:58:24 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-01-22 00:58:24 +0000 |
commit | e4a0bb7a2039ed34ce1c253816aa3020007d3447 (patch) | |
tree | 69969f33a8c827a454ef563c395f4bf232cf00e1 /clang/lib/Parse/ParseInit.cpp | |
parent | eee54df5b611055c537ea92c7bbf89ca1fa4a14f (diff) | |
download | bcm5719-llvm-e4a0bb7a2039ed34ce1c253816aa3020007d3447.tar.gz bcm5719-llvm-e4a0bb7a2039ed34ce1c253816aa3020007d3447.zip |
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.
llvm-svn: 62737
Diffstat (limited to 'clang/lib/Parse/ParseInit.cpp')
-rw-r--r-- | clang/lib/Parse/ParseInit.cpp | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index ff73b0b9e15..b5d0ec05dbc 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/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()); } |