diff options
author | Chris Lattner <sabre@nondot.org> | 2008-10-26 22:36:07 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-10-26 22:36:07 +0000 |
commit | eccc53a0a0ed1abc7bb4c04ed9566ce0c5c63140 (patch) | |
tree | f832445008342b83358543fb03d5e122137f467f /lib/Parse/ParseInit.cpp | |
parent | 838cb21b800e55d88201fa76b978a7d11478c655 (diff) |
This patch continues parser-level implementation of designators:
1. It introduces new parser level abstractions for designators
that are used to communicate between parser and sema.
2. This fixes a FIXME where "identifier ':'" was considered to be
a designator even if it wasn't the first in a designator list.
3. In the "identifier ':'" case, it actually builds the designator
representation.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58205 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseInit.cpp')
-rw-r--r-- | lib/Parse/ParseInit.cpp | 64 |
1 files changed, 41 insertions, 23 deletions
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp index f4073af33f..5f2dc6d8e5 100644 --- a/lib/Parse/ParseInit.cpp +++ b/lib/Parse/ParseInit.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/Parse/Designator.h" #include "clang/Parse/Parser.h" #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/SmallString.h" @@ -54,7 +55,32 @@ static bool MayBeDesignationStart(tok::TokenKind K) { /// initializer (because it is an expression). We need to consider this case /// when parsing array designators. /// -Parser::ExprResult Parser::ParseInitializerWithPotentialDesignator() { +Parser::ExprResult Parser:: +ParseInitializerWithPotentialDesignator(InitListDesignations &Designations, + unsigned InitNum) { + + // If this is the old-style GNU extension: + // designation ::= identifier ':' + // Handle it as a field designator. Otherwise, this must be the start of a + // normal expression. + if (Tok.is(tok::identifier)) { + if (NextToken().is(tok::colon)) { + Diag(Tok, diag::ext_gnu_old_style_field_designator); + + Designation &D = Designations.CreateDesignation(InitNum); + D.AddDesignator(Designator::getField(Tok.getIdentifierInfo())); + ConsumeToken(); // Eat the identifier. + + assert(Tok.is(tok::colon) && "NextToken() not working properly!"); + ConsumeToken(); + return ParseInitializer(); + } + + // Otherwise, parse the assignment-expression. + return ParseAssignmentExpression(); + } + + // Parse each designator in the designator list until we find an initializer. while (1) { switch (Tok.getKind()) { @@ -138,25 +164,6 @@ Parser::ExprResult Parser::ParseInitializerWithPotentialDesignator() { MatchRHSPunctuation(tok::r_square, StartLoc); break; } - case tok::identifier: { - // Due to the GNU "designation: identifier ':'" extension, we don't know - // whether something starting with an identifier is an - // assignment-expression or if it is an old-style structure field - // designator. - // TODO: Check that this is the first designator. - - // If this is the gross GNU extension, handle it now. - if (NextToken().is(tok::colon)) { - Diag(Tok, diag::ext_gnu_old_style_field_designator); - ConsumeToken(); // The identifier. - assert(Tok.is(tok::colon) && "NextToken() not working properly!"); - ConsumeToken(); - return ParseInitializer(); - } - - // Otherwise, parse the assignment-expression. - return ParseAssignmentExpression(); - } } } } @@ -174,6 +181,8 @@ Parser::ExprResult Parser::ParseInitializerWithPotentialDesignator() { /// initializer-list ',' designation[opt] initializer /// Parser::ExprResult Parser::ParseInitializer() { + // TODO: Split this up into ParseInitializer + ParseBraceInitializer, make + // ParseInitializer inline so that the non-brace case is short-cut. if (Tok.isNot(tok::l_brace)) return ParseAssignmentExpression(); @@ -186,7 +195,15 @@ Parser::ExprResult Parser::ParseInitializer() { // Match the '}'. return Actions.ActOnInitList(LBraceLoc, 0, 0, ConsumeBrace()); } + + /// InitExprs - This is the actual list of expressions contained in the + /// initializer. llvm::SmallVector<ExprTy*, 8> InitExprs; + + /// ExprDesignators - For each initializer, keep track of the designator that + /// was specified for it, if any. + InitListDesignations InitExprDesignations(Actions); + bool InitExprsOk = true; while (1) { @@ -198,7 +215,8 @@ Parser::ExprResult Parser::ParseInitializer() { if (!MayBeDesignationStart(Tok.getKind())) SubElt = ParseInitializer(); else - SubElt = ParseInitializerWithPotentialDesignator(); + SubElt = ParseInitializerWithPotentialDesignator(InitExprDesignations, + InitExprs.size()); // If we couldn't parse the subelement, bail out. if (!SubElt.isInvalid) { @@ -220,7 +238,7 @@ Parser::ExprResult Parser::ParseInitializer() { // If we don't have a comma continued list, we're done. if (Tok.isNot(tok::comma)) break; - // FIXME: save comma locations. + // TODO: save comma locations if some client cares. ConsumeToken(); // Handle trailing comma. @@ -230,7 +248,7 @@ Parser::ExprResult Parser::ParseInitializer() { return Actions.ActOnInitList(LBraceLoc, &InitExprs[0], InitExprs.size(), ConsumeBrace()); - // Delete any parsed subexpressions. + // On error, delete any parsed subexpressions. for (unsigned i = 0, e = InitExprs.size(); i != e; ++i) Actions.DeleteExpr(InitExprs[i]); |