aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseInit.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-10-26 22:36:07 +0000
committerChris Lattner <sabre@nondot.org>2008-10-26 22:36:07 +0000
commiteccc53a0a0ed1abc7bb4c04ed9566ce0c5c63140 (patch)
treef832445008342b83358543fb03d5e122137f467f /lib/Parse/ParseInit.cpp
parent838cb21b800e55d88201fa76b978a7d11478c655 (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.cpp64
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]);