[cfe-commits] r38873 - in /cfe/cfe/trunk: Parse/ParseExpr.cpp Parse/ParseStmt.cpp include/clang/Parse/Parser.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:25:23 PDT 2007
Author: sabre
Date: Wed Jul 11 11:25:22 2007
New Revision: 38873
URL: http://llvm.org/viewvc/llvm-project?rev=38873&view=rev
Log:
Return information about whether expression parsing was successful
Modified:
cfe/cfe/trunk/Parse/ParseExpr.cpp
cfe/cfe/trunk/Parse/ParseStmt.cpp
cfe/cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseExpr.cpp?rev=38873&r1=38872&r2=38873&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:25:22 2007
@@ -17,7 +17,7 @@
using namespace clang;
// C99 6.7.8
-void Parser::ParseInitializer() {
+Parser::ExprResult Parser::ParseInitializer() {
// FIXME: STUB.
if (Tok.getKind() == tok::l_brace) {
ConsumeBrace();
@@ -29,22 +29,21 @@
// Match the '}'.
MatchRHSPunctuation(tok::r_brace, Tok.getLocation(), "{",
diag::err_expected_rbrace);
- return;
+ return ExprResult(false);
}
- ParseAssignmentExpression();
+ return ParseAssignmentExpression();
}
-Parser::ExprTy Parser::ParseExpression() {
- ParseCastExpression(false);
- return 0;
+Parser::ExprResult Parser::ParseExpression() {
+ return ParseCastExpression(false);
}
// Expr that doesn't include commas.
-void Parser::ParseAssignmentExpression() {
- ParseExpression();
+Parser::ExprResult Parser::ParseAssignmentExpression() {
+ return ParseExpression();
}
/// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
@@ -116,7 +115,9 @@
/// [GNU] offsetof-member-designator '[' expression ']'
///
///
-void Parser::ParseCastExpression(bool isUnaryExpression) {
+Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
+ ExprResult Res;
+
// This handles all of cast-expression, unary-expression, postfix-expression,
// and primary-expression. We handle them together like this for efficiency
// and to simplify handling of an expression starting with a '(' token: which
@@ -133,8 +134,9 @@
// not start a cast expression.
ParenParseOption ParenExprType =
isUnaryExpression ? CompoundLiteral : CastExpr;
- ParseParenExpression(ParenExprType);
-
+ Res = ParseParenExpression(ParenExprType);
+ if (Res.isInvalid) return Res;
+
switch (ParenExprType) {
case SimpleExpr: break; // Nothing else to do.
case CompoundStmt: break; // Nothing else to do.
@@ -145,11 +147,10 @@
case CastExpr:
// We parsed '(' type-name ')' and the thing after it wasn't a '{'. Parse
// the cast-expression that follows it next.
- ParseCastExpression(false);
- return;
+ return ParseCastExpression(false);
}
break; // These can be followed by postfix-expr pieces.
-
+
// primary-expression
case tok::identifier: // primary-expression: identifier
// constant: enumeration-constant
@@ -162,7 +163,8 @@
ConsumeToken();
break;
case tok::string_literal: // primary-expression: string-literal
- ParseStringLiteralExpression();
+ Res = ParseStringLiteralExpression();
+ if (Res.isInvalid) return Res;
break;
case tok::kw___builtin_va_arg:
case tok::kw___builtin_offsetof:
@@ -172,8 +174,7 @@
case tok::plusplus: // unary-expression: '++' unary-expression
case tok::minusminus: // unary-expression: '--' unary-expression
ConsumeToken();
- ParseCastExpression(true);
- return;
+ return ParseCastExpression(true);
case tok::amp: // unary-expression: '&' cast-expression
case tok::star: // unary-expression: '*' cast-expression
case tok::plus: // unary-expression: '+' cast-expression
@@ -184,15 +185,13 @@
case tok::kw___imag: // unary-expression: '__real' cast-expression [GNU]
//case tok::kw__extension__: [TODO]
ConsumeToken();
- ParseCastExpression(false);
- return;
+ return ParseCastExpression(false);
case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
// unary-expression: 'sizeof' '(' type-name ')'
case tok::kw___alignof: // unary-expression: '__alignof' unary-expression
// unary-expression: '__alignof' '(' type-name ')'
- ParseSizeofAlignofExpression();
- return;
+ return ParseSizeofAlignofExpression();
case tok::ampamp: // unary-expression: '&&' identifier
Diag(Tok, diag::ext_gnu_address_of_label);
ConsumeToken();
@@ -200,18 +199,12 @@
ConsumeToken();
} else {
Diag(Tok, diag::err_expected_ident);
- ConsumeToken(); // FIXME: Should just return error!
- return;
+ return ExprResult(true);
}
- return;
+ return ExprResult(false);
default:
Diag(Tok, diag::err_expected_expression);
- // Guarantee forward progress.
- // FIXME: this dies on 'if ({1; });'. Expression parsing should return a
- // bool for failure. This will cause higher-level parsing stuff to do the
- // right thing.
- ConsumeToken();
- return;
+ return ExprResult(true);
}
// Now that the primary-expression piece of the postfix-expression has been
@@ -219,47 +212,47 @@
SourceLocation Loc;
while (1) {
switch (Tok.getKind()) {
- default:
- return;
- case tok::l_square: // postfix-expression: p-e '[' expression ']'
- Loc = Tok.getLocation();
- ConsumeBracket();
- ParseExpression();
- // Match the ']'.
- MatchRHSPunctuation(tok::r_square, Loc, "[", diag::err_expected_rsquare);
- break;
-
- case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')'
- Loc = Tok.getLocation();
- ConsumeParen();
-
- while (1) {
- // FIXME: This should be argument-expression!
- ParseAssignmentExpression();
-
- if (Tok.getKind() != tok::comma)
- break;
- ConsumeToken(); // Next argument.
- }
-
- // Match the ')'.
- MatchRHSPunctuation(tok::r_paren, Loc, "(", diag::err_expected_rparen);
- break;
+ default:
+ return ExprResult(false);
+ case tok::l_square: // postfix-expression: p-e '[' expression ']'
+ Loc = Tok.getLocation();
+ ConsumeBracket();
+ ParseExpression();
+ // Match the ']'.
+ MatchRHSPunctuation(tok::r_square, Loc, "[", diag::err_expected_rsquare);
+ break;
+
+ case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')'
+ Loc = Tok.getLocation();
+ ConsumeParen();
+
+ while (1) {
+ // FIXME: This should be argument-expression!
+ ParseAssignmentExpression();
- case tok::arrow: // postfix-expression: p-e '->' identifier
- case tok::period: // postfix-expression: p-e '.' identifier
- ConsumeToken();
- if (Tok.getKind() != tok::identifier) {
- Diag(Tok, diag::err_expected_ident);
- return;
- }
- ConsumeToken();
- break;
+ if (Tok.getKind() != tok::comma)
+ break;
+ ConsumeToken(); // Next argument.
+ }
- case tok::plusplus: // postfix-expression: postfix-expression '++'
- case tok::minusminus: // postfix-expression: postfix-expression '--'
- ConsumeToken();
- break;
+ // Match the ')'.
+ MatchRHSPunctuation(tok::r_paren, Loc, "(", diag::err_expected_rparen);
+ break;
+
+ case tok::arrow: // postfix-expression: p-e '->' identifier
+ case tok::period: // postfix-expression: p-e '.' identifier
+ ConsumeToken();
+ if (Tok.getKind() != tok::identifier) {
+ Diag(Tok, diag::err_expected_ident);
+ return ExprResult(true);
+ }
+ ConsumeToken();
+ break;
+
+ case tok::plusplus: // postfix-expression: postfix-expression '++'
+ case tok::minusminus: // postfix-expression: postfix-expression '--'
+ ConsumeToken();
+ break;
}
}
}
@@ -270,7 +263,7 @@
/// 'sizeof' '(' type-name ')'
/// [GNU] '__alignof' unary-expression
/// [GNU] '__alignof' '(' type-name ')'
-void Parser::ParseSizeofAlignofExpression() {
+Parser::ExprResult Parser::ParseSizeofAlignofExpression() {
assert((Tok.getKind() == tok::kw_sizeof ||
Tok.getKind() == tok::kw___alignof) &&
"Not a sizeof/alignof expression!");
@@ -278,15 +271,14 @@
// If the operand doesn't start with an '(', it must be an expression.
if (Tok.getKind() != tok::l_paren) {
- ParseCastExpression(true);
- return;
+ return ParseCastExpression(true);
}
// If it starts with a '(', we know that it is either a parenthesized
// type-name, or it is a unary-expression that starts with a compound literal,
// or starts with a primary-expression that is a parenthesized expression.
ParenParseOption ExprType = CastExpr;
- ParseParenExpression(ExprType);
+ return ParseParenExpression(ExprType);
}
/// ParseStringLiteralExpression - This handles the various token types that
@@ -295,7 +287,7 @@
///
/// primary-expression: [C99 6.5.1]
/// string-literal
-void Parser::ParseStringLiteralExpression() {
+Parser::ExprResult Parser::ParseStringLiteralExpression() {
assert(isTokenStringLiteral() && "Not a string literal!");
ConsumeStringToken();
@@ -303,6 +295,7 @@
// considered to be strings.
while (isTokenStringLiteral())
ConsumeStringToken();
+ return ExprResult(false);
}
@@ -319,10 +312,11 @@
/// cast-expression: [C99 6.5.4]
/// '(' type-name ')' cast-expression
///
-void Parser::ParseParenExpression(ParenParseOption &ExprType) {
+Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType) {
assert(Tok.getKind() == tok::l_paren && "Not a paren expr!");
SourceLocation OpenLoc = Tok.getLocation();
ConsumeParen();
+ ExprResult Result(false);
if (ExprType >= CompoundStmt && Tok.getKind() == tok::l_brace &&
!getLang().NoExtensions) {
@@ -337,21 +331,25 @@
MatchRHSPunctuation(tok::r_paren, OpenLoc, "(", diag::err_expected_rparen);
if (Tok.getKind() == tok::l_brace) {
- ParseInitializer();
+ Result = ParseInitializer();
ExprType = CompoundLiteral;
} else if (ExprType == CastExpr) {
// Note that this doesn't parse the subsequence cast-expression.
ExprType = CastExpr;
} else {
Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
- return;
+ return ExprResult(true);
}
- return;
+ return Result;
} else {
- ParseExpression();
+ Result = ParseExpression();
ExprType = SimpleExpr;
}
// Match the ')'.
- MatchRHSPunctuation(tok::r_paren, OpenLoc, "(", diag::err_expected_rparen);
+ if (Result.isInvalid)
+ SkipUntil(tok::r_paren);
+ else
+ MatchRHSPunctuation(tok::r_paren, OpenLoc, "(", diag::err_expected_rparen);
+ return Result;
}
Modified: cfe/cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseStmt.cpp?rev=38873&r1=38872&r2=38873&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseStmt.cpp Wed Jul 11 11:25:22 2007
@@ -91,7 +91,13 @@
Diag(Tok, diag::err_expected_statement);
} else {
// expression[opt] ';'
- ParseExpression();
+ ExprResult Res = ParseExpression();
+ if (Res.isInvalid) {
+ // If the expression is invalid, skip ahead to the next semicolon. Not
+ // doing this opens us up to the possibility of infinite loops if
+ // ParseExpression does not consume any tokens.
+ SkipUntil(tok::semi);
+ }
}
return;
@@ -407,6 +413,8 @@
SourceLocation LParenLoc = Tok.getLocation();
ConsumeParen();
+ ExprResult Value;
+
// Parse the first part of the for specifier.
if (Tok.getKind() == tok::semi) { // for (;
// no first part, eat the ';'.
@@ -417,12 +425,12 @@
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
ParseDeclaration(Declarator::ForContext);
} else {
- ParseExpression();
+ Value = ParseExpression();
if (Tok.getKind() == tok::semi) {
ConsumeToken();
} else {
- Diag(Tok, diag::err_expected_semi_for);
+ if (!Value.isInvalid) Diag(Tok, diag::err_expected_semi_for);
SkipUntil(tok::semi);
}
}
@@ -430,22 +438,24 @@
// Parse the second part of the for specifier.
if (Tok.getKind() == tok::semi) { // for (...;;
// no second part.
+ Value = ExprResult();
} else {
- ParseExpression();
+ Value = ParseExpression();
}
if (Tok.getKind() == tok::semi) {
ConsumeToken();
} else {
- Diag(Tok, diag::err_expected_semi_for);
+ if (!Value.isInvalid) Diag(Tok, diag::err_expected_semi_for);
SkipUntil(tok::semi);
}
// Parse the third part of the for specifier.
if (Tok.getKind() == tok::r_paren) { // for (...;...;)
// no third part.
+ Value = ExprResult();
} else {
- ParseExpression();
+ Value = ParseExpression();
}
// Match the ')'.
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=38873&r1=38872&r2=38873&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:22 2007
@@ -50,7 +50,15 @@
// Parsing methods.
void ParseTranslationUnit();
- ExprTy ParseExpression();
+
+ struct ExprResult {
+ ExprTy Val;
+ bool isInvalid;
+
+ ExprResult(bool Invalid = false) : isInvalid(Invalid) {}
+ };
+
+ ExprResult ParseExpression();
// Diagnostics.
@@ -169,11 +177,11 @@
//===--------------------------------------------------------------------===//
// C99 6.5: Expressions.
- //ExprTy ParseExpression(); // Above.
- void ParseAssignmentExpression(); // Expr that doesn't include commas.
+ //ExprResult ParseExpression(); // Above.
+ ExprResult ParseAssignmentExpression(); // Expr that doesn't include commas.
- void ParseCastExpression(bool isUnaryExpression);
- void ParseSizeofAlignofExpression();
+ ExprResult ParseCastExpression(bool isUnaryExpression);
+ ExprResult ParseSizeofAlignofExpression();
/// ParenParseOption - Control what ParseParenExpression will parse.
enum ParenParseOption {
@@ -182,10 +190,10 @@
CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}'
CastExpr // Also allow '(' type-name ')' <anything>
};
- void ParseParenExpression(ParenParseOption &ExprType);
- void ParseStringLiteralExpression();
+ ExprResult ParseParenExpression(ParenParseOption &ExprType);
+ ExprResult ParseStringLiteralExpression();
- void ParseInitializer(); // C99 6.7.8
+ ExprResult ParseInitializer(); // C99 6.7.8
//===--------------------------------------------------------------------===//
// C99 6.8: Statements and Blocks.
More information about the cfe-commits
mailing list