Skip to content
Snippets Groups Projects
Commit 4add4e6c authored by Chris Lattner's avatar Chris Lattner
Browse files

Simplify paren parsing, finish parsing of sizeof expressions and other cases.

llvm-svn: 38866
parent f5fbd796
No related branches found
No related tags found
No related merge requests found
...@@ -53,13 +53,24 @@ void Parser::ParseCastExpression() { ...@@ -53,13 +53,24 @@ void Parser::ParseCastExpression() {
if (Tok.getKind() != tok::l_paren) if (Tok.getKind() != tok::l_paren)
return ParseUnaryExpression(); return ParseUnaryExpression();
#if 0 ParenParseOption ParenExprType = CompoundLiteral;
// Otherwise this is either a cast, a compound literal, or a parenthesized ParseParenExpression(ParenExprType);
// expression.
SourceLocation LParenLoc = Tok.getLocation(); switch (ParenExprType) {
ConsumeParen(); case SimpleExpr: break; // Nothing to do.
#endif case CompoundStmt: break; // Nothing to do.
case CompoundLiteral:
// We parsed '(' type-name ')' '{' ... '}'. If any suffixes of
// postfix-expression exist, parse them now.
assert(0 && "FIXME");
break;
case CastExpr:
// We parsed '(' type-name ')' and the thing after it wasn't a '{'. Parse
// the cast-expression that follows it next.
ParseCastExpression();
break;
}
// If ParenExprType could have a postfix expr after it, handle it now.
assert(0); assert(0);
} }
...@@ -142,25 +153,8 @@ void Parser::ParseSizeofAlignofExpression() { ...@@ -142,25 +153,8 @@ void Parser::ParseSizeofAlignofExpression() {
// If it starts with a '(', we know that it is either a parenthesized // 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, // 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. // or starts with a primary-expression that is a parenthesized expression.
SourceLocation LParenLoc = Tok.getLocation(); ParenParseOption ExprType = CastExpr;
ConsumeParen(); ParseParenExpression(ExprType);
if (isTypeSpecifierQualifier()) {
// This is now known to be either a parenthesized type-name, or a compound
// literal.
// FIXME: ParseTypeName.
assert(0 && "implement!");
} else {
// Otherwise, this is known to be a parenthesized-expression. Parse the
// rest of the parethesized-expression here.
ParseExpression();
}
// Match the ')'.
MatchRHSPunctuation(tok::r_paren, LParenLoc, "(", diag::err_expected_rparen);
} }
/// ParsePostfixExpression /// ParsePostfixExpression
...@@ -227,10 +221,14 @@ void Parser::ParsePostfixExpression() { ...@@ -227,10 +221,14 @@ void Parser::ParsePostfixExpression() {
case tok::string_literal: // primary-expression: string-literal case tok::string_literal: // primary-expression: string-literal
ParseStringLiteralExpression(); ParseStringLiteralExpression();
break; break;
case tok::l_paren: // primary-expression: '(' expression ')' case tok::l_paren: { // primary-expr: '(' expression ')'
// primary-expression: '(' compound-statement ')' // primary-expr: '(' compound-statement ')'
ParseParenExpression(false/*allow statement exprs, initializers */); // postfix-expr: '(' type-name ')' '{' init-list '}'
// postfix-expr: '(' type-name ')' '{' init-list ',' '}'
ParenParseOption ParenExprType = CompoundLiteral;
ParseParenExpression(ParenExprType);
break; break;
}
case tok::kw___builtin_va_arg: case tok::kw___builtin_va_arg:
case tok::kw___builtin_offsetof: case tok::kw___builtin_offsetof:
case tok::kw___builtin_choose_expr: case tok::kw___builtin_choose_expr:
...@@ -313,42 +311,52 @@ void Parser::ParseStringLiteralExpression() { ...@@ -313,42 +311,52 @@ void Parser::ParseStringLiteralExpression() {
} }
/// ParseParenExpression - C99 6.5.1p5 /// ParseParenExpression - This parses the unit that starts with a '(' token,
/// primary-expression: /// based on what is allowed by ExprType. The actual thing parsed is returned
/// in ExprType.
///
/// primary-expression: [C99 6.5.1]
/// '(' expression ')' /// '(' expression ')'
/// [GNU] '(' compound-statement ')' (if !ParenExprOnly) /// [GNU] '(' compound-statement ')' (if !ParenExprOnly)
/// postfix-expression: [C99 6.5.2] /// postfix-expression: [C99 6.5.2]
/// '(' type-name ')' '{' initializer-list '}' /// '(' type-name ')' '{' initializer-list '}'
/// '(' type-name ')' '{' initializer-list ',' '}' /// '(' type-name ')' '{' initializer-list ',' '}'
/// cast-expression: [C99 6.5.4]
/// '(' type-name ')' cast-expression
/// ///
void Parser::ParseParenExpression(bool ParenExprOnly) { void Parser::ParseParenExpression(ParenParseOption &ExprType) {
assert(Tok.getKind() == tok::l_paren && "Not a paren expr!"); assert(Tok.getKind() == tok::l_paren && "Not a paren expr!");
SourceLocation OpenLoc = Tok.getLocation(); SourceLocation OpenLoc = Tok.getLocation();
ConsumeParen(); ConsumeParen();
if (!ParenExprOnly && Tok.getKind() == tok::l_brace && if (ExprType >= CompoundStmt && Tok.getKind() == tok::l_brace &&
!getLang().NoExtensions) { !getLang().NoExtensions) {
Diag(Tok, diag::ext_gnu_statement_expr); Diag(Tok, diag::ext_gnu_statement_expr);
ParseCompoundStatement(); ParseCompoundStatement();
} else if (ParenExprOnly || !isTypeSpecifierQualifier()) { ExprType = CompoundStmt;
ParseExpression(); } else if (ExprType >= CompoundLiteral && isTypeSpecifierQualifier()) {
} else {
// Otherwise, this is a compound expression. // Otherwise, this is a compound expression.
ParseTypeName(); ParseTypeName();
// Match the ')'. // Match the ')'.
MatchRHSPunctuation(tok::r_paren, OpenLoc, "(", diag::err_expected_rparen); MatchRHSPunctuation(tok::r_paren, OpenLoc, "(", diag::err_expected_rparen);
if (Tok.getKind() != tok::l_brace) { if (Tok.getKind() == tok::l_brace) {
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); Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
return; return;
} }
ParseInitializer();
return; return;
} else {
ParseExpression();
ExprType = SimpleExpr;
} }
// Match the ')'. // Match the ')'.
MatchRHSPunctuation(tok::r_paren, OpenLoc, "(", diag::err_expected_rparen); MatchRHSPunctuation(tok::r_paren, OpenLoc, "(", diag::err_expected_rparen);
} }
...@@ -303,7 +303,8 @@ void Parser::ParseIfStatement() { ...@@ -303,7 +303,8 @@ void Parser::ParseIfStatement() {
} }
// Parse the condition. // Parse the condition.
ParseParenExpression(); ParenParseOption ParenExprType = SimpleExpr;
ParseParenExpression(ParenExprType);
// Read the if condition. // Read the if condition.
ParseStatement(); ParseStatement();
...@@ -329,7 +330,8 @@ void Parser::ParseSwitchStatement() { ...@@ -329,7 +330,8 @@ void Parser::ParseSwitchStatement() {
} }
// Parse the condition. // Parse the condition.
ParseParenExpression(); ParenParseOption ParenExprType = SimpleExpr;
ParseParenExpression(ParenExprType);
// Read the body statement. // Read the body statement.
ParseStatement(); ParseStatement();
...@@ -349,7 +351,8 @@ void Parser::ParseWhileStatement() { ...@@ -349,7 +351,8 @@ void Parser::ParseWhileStatement() {
} }
// Parse the condition. // Parse the condition.
ParseParenExpression(); ParenParseOption ParenExprType = SimpleExpr;
ParseParenExpression(ParenExprType);
// Read the body statement. // Read the body statement.
ParseStatement(); ParseStatement();
...@@ -382,7 +385,8 @@ void Parser::ParseDoStatement() { ...@@ -382,7 +385,8 @@ void Parser::ParseDoStatement() {
} }
// Parse the condition. // Parse the condition.
ParseParenExpression(); ParenParseOption ParenExprType = SimpleExpr;
ParseParenExpression(ParenExprType);
} }
/// ParseForStatement /// ParseForStatement
......
...@@ -176,7 +176,15 @@ private: ...@@ -176,7 +176,15 @@ private:
void ParseUnaryExpression(); void ParseUnaryExpression();
void ParseSizeofAlignofExpression(); void ParseSizeofAlignofExpression();
void ParsePostfixExpression(); void ParsePostfixExpression();
void ParseParenExpression(bool ParenExprOnly = true);
/// ParenParseOption - Control what ParseParenExpression will parse.
enum ParenParseOption {
SimpleExpr, // Only parse '(' expression ')'
CompoundStmt, // Also allow '(' compound-statement ')'
CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}'
CastExpr // Also allow '(' type-name ')' <anything>
};
void ParseParenExpression(ParenParseOption &ExprType);
void ParseStringLiteralExpression(); void ParseStringLiteralExpression();
void ParseInitializer(); // C99 6.7.8 void ParseInitializer(); // C99 6.7.8
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment