[cfe-commits] r38890 - in /cfe/cfe/trunk: Parse/ParseDecl.cpp Parse/ParseExpr.cpp Parse/Parser.cpp include/clang/Parse/Parser.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:25:31 PDT 2007
Author: sabre
Date: Wed Jul 11 11:25:31 2007
New Revision: 38890
URL: http://llvm.org/viewvc/llvm-project?rev=38890&view=rev
Log:
Implement parsing of array declarators like:
int Array[*(int*)P+A];
Modified:
cfe/cfe/trunk/Parse/ParseDecl.cpp
cfe/cfe/trunk/Parse/ParseExpr.cpp
cfe/cfe/trunk/Parse/Parser.cpp
cfe/cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=38890&r1=38889&r2=38890&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:25:31 2007
@@ -717,7 +717,7 @@
// Handle "direct-declarator [ type-qual-list[opt] * ]".
bool isStar = false;
- void *NumElts = 0;
+ ExprResult NumElements(false);
if (Tok.getKind() == tok::star) {
// Remember the '*' token, in case we have to un-get it.
LexerToken StarTok = Tok;
@@ -733,22 +733,19 @@
} else {
// Otherwise, the * must have been some expression (such as '*ptr') that
// started an assignment-expr. We already consumed the token, but now we
- // need to reparse it.
- // FIXME: We must push 'StarTok' and Tok back into the preprocessor as a
- // macro expansion context, so they will be read again. It is basically
- // impossible to refudge the * in otherwise, due to cases like X[*p + 4].
- assert(0 && "FIXME: int X[*p] unimplemented");
+ // need to reparse it. This handles cases like 'X[*p + 4]'
+ NumElements = ParseAssignmentExpressionWithLeadingStar(StarTok);
}
} else if (Tok.getKind() != tok::r_square) {
// Parse the assignment-expression now.
- ExprResult Res = ParseAssignmentExpression();
- if (Res.isInvalid) {
- // If the expression was invalid, skip it.
- SkipUntil(tok::r_square);
- return;
- }
-
- NumElts = /*TODO: parse array size expr*/0;
+ NumElements = ParseAssignmentExpression();
+ }
+
+ // If there was an error parsing the assignment-expression, recover.
+ if (NumElements.isInvalid) {
+ // If the expression was invalid, skip it.
+ SkipUntil(tok::r_square);
+ return;
}
MatchRHSPunctuation(tok::r_square, StartLoc, "[", diag::err_expected_rsquare);
@@ -757,13 +754,13 @@
// it was not a constant expression.
if (!getLang().C99) {
// TODO: check C90 array constant exprness.
- if (isStar || StaticLoc.isValid() || 0/*NumElts is constantexpr*/)
+ if (isStar || StaticLoc.isValid() || 0/*FIXME: NumElts is constantexpr*/)
Diag(StartLoc, diag::ext_c99_array_usage);
}
// Remember that we parsed a pointer type, and remember the type-quals.
D.AddTypeInfo(DeclaratorTypeInfo::getArray(DS.TypeQualifiers,
StaticLoc.isValid(), isStar,
- NumElts, StartLoc));
+ NumElements.Val, StartLoc));
}
Modified: cfe/cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseExpr.cpp?rev=38890&r1=38889&r2=38890&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:25:31 2007
@@ -233,6 +233,39 @@
return ParseRHSOfBinaryExpression(Res, prec::Comma);
}
+/// ParseAssignmentExpressionWithLeadingStar - This special purpose method is
+/// used in contexts where we have already consumed a '*' (which we saved in
+/// 'Tok'), then discovered that the '*' was really the leading token of an
+/// expression. For example, in "*(int*)P+B", we consumed "*" (which is
+/// now in 'Tok') and the current token is "(".
+Parser::ExprResult Parser::
+ParseAssignmentExpressionWithLeadingStar(const LexerToken &Tok) {
+ // We know that 'Tok' must correspond to this production:
+ // unary-expression: unary-operator cast-expression
+ // where 'unary-operator' is '*'.
+
+ // Parse the cast-expression that follows the '*'. This will parse the
+ // "*(int*)P" part of "*(int*)P+B".
+ ExprResult Res = ParseCastExpression(false);
+ if (Res.isInvalid) return Res;
+
+ // TODO: Combine Tok + Res to get the new AST.
+
+ // We have to parse an entire cast-expression before starting the
+ // ParseRHSOfBinaryExpression method (which parses any trailing binops). Since
+ // we know that the only production above us is the cast-expression
+ // production, and because the only alternative productions start with a '('
+ // token (we know we had a '*'), there is no work to do to get a whole
+ // cast-expression.
+
+ // At this point, the "*(int*)P" part of "*(int*)P+B" has been consumed. Once
+ // this is done, we can invoke ParseRHSOfBinaryExpression to consume any
+ // trailing operators (e.g. "+" in this example) and connected chunks of the
+ // assignment-expression.
+ return ParseRHSOfBinaryExpression(Res, prec::Assignment);
+}
+
+
/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
/// LHS and has a precedence of at least MinPrec.
Parser::ExprResult
@@ -309,7 +342,6 @@
}
}
-
/// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
/// true, parse a unary-expression.
///
Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=38890&r1=38889&r2=38890&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:25:31 2007
@@ -224,7 +224,7 @@
// C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
// declaration-specifiers init-declarator-list[opt] ';'
if (Tok.getKind() == tok::semi)
- assert(0 && "Unimp!");
+ assert(0 && "Unimp!"); // FIXME: implement 'struct foo;'.
// Parse the first declarator.
Modified: cfe/cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Parser.h?rev=38890&r1=38889&r2=38890&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:31 2007
@@ -179,6 +179,7 @@
// C99 6.5: Expressions.
//ExprResult ParseExpression(); // Above.
ExprResult ParseExpressionWithLeadingIdentifier(const LexerToken &Tok);
+ ExprResult ParseAssignmentExpressionWithLeadingStar(const LexerToken &Tok);
ExprResult ParseAssignmentExpression(); // Expr that doesn't include commas.
ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);
More information about the cfe-commits
mailing list