aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseExpr.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2009-05-22 10:22:50 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2009-05-22 10:22:50 +0000
commit5ab0640efb436a721d408c853b771932d1a6ffce (patch)
tree8ca6bf0589cbb398662c852dfa628022de4acbe9 /lib/Parse/ParseExpr.cpp
parent6409625011e4a11ff07956ff46a44d6ca4473992 (diff)
Refactor the common code of 'ParseTypeofSpecifier' and 'ParseSizeofAlignofExpression' into a new
'ParseExprAfterTypeofSizeofAlignof' method. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72256 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseExpr.cpp')
-rw-r--r--lib/Parse/ParseExpr.cpp91
1 files changed, 72 insertions, 19 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 869b315d99..ac2d4a88df 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -913,42 +913,60 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
}
}
-
-/// ParseSizeofAlignofExpression - Parse a sizeof or alignof expression.
+/// ParseExprAfterTypeofSizeofAlignof - We parsed a typeof/sizeof/alignof and
+/// we are at the start of an expression or a parenthesized type-id.
+/// OpTok is the operand token (typeof/sizeof/alignof). Returns the expression
+/// (isCastExpr == false) or the type (isCastExpr == true).
+///
/// unary-expression: [C99 6.5.3]
/// 'sizeof' unary-expression
/// 'sizeof' '(' type-name ')'
/// [GNU] '__alignof' unary-expression
/// [GNU] '__alignof' '(' type-name ')'
/// [C++0x] 'alignof' '(' type-id ')'
-Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() {
- assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof)
- || Tok.is(tok::kw_alignof)) &&
- "Not a sizeof/alignof expression!");
- Token OpTok = Tok;
- ConsumeToken();
+///
+/// [GNU] typeof-specifier:
+/// typeof ( expressions )
+/// typeof ( type-name )
+/// [GNU/C++] typeof unary-expression
+///
+Parser::OwningExprResult
+Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
+ bool &isCastExpr,
+ TypeTy *&CastTy,
+ SourceRange &CastRange) {
- // If the operand doesn't start with an '(', it must be an expression.
+ assert((OpTok.is(tok::kw_typeof) || OpTok.is(tok::kw_sizeof) ||
+ OpTok.is(tok::kw___alignof) || OpTok.is(tok::kw_alignof)) &&
+ "Not a typeof/sizeof/alignof expression!");
+
OwningExprResult Operand(Actions);
+
+ // If the operand doesn't start with an '(', it must be an expression.
if (Tok.isNot(tok::l_paren)) {
- Operand = ParseCastExpression(true);
+ isCastExpr = false;
+ if (OpTok.is(tok::kw_typeof) && !getLang().CPlusPlus) {
+ Diag(Tok,diag::err_expected_lparen_after_id) << OpTok.getIdentifierInfo();
+ return ExprError();
+ }
+ Operand = ParseCastExpression(true/*isUnaryExpression*/);
+
} else {
// 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;
- TypeTy *CastTy;
SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
Operand = ParseParenExpression(ExprType, CastTy, RParenLoc);
+ CastRange = SourceRange(LParenLoc, RParenLoc);
- // If ParseParenExpression parsed a '(typename)' sequence only, the this is
- // sizeof/alignof a type. Otherwise, it is sizeof/alignof an expression.
- if (ExprType == CastExpr)
- return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
- OpTok.is(tok::kw_sizeof),
- /*isType=*/true, CastTy,
- SourceRange(LParenLoc, RParenLoc));
+ // If ParseParenExpression parsed a '(typename)' sequence only, then this is
+ // a type.
+ if (ExprType == CastExpr) {
+ isCastExpr = true;
+ return ExprEmpty();
+ }
// If this is a parenthesized expression, it is the start of a
// unary-expression, but doesn't include any postfix pieces. Parse these
@@ -956,12 +974,46 @@ Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() {
Operand = ParsePostfixExpressionSuffix(move(Operand));
}
+ // If we get here, the operand to the typeof/sizeof/alignof was an expresion.
+ isCastExpr = false;
+ return move(Operand);
+}
+
+
+/// ParseSizeofAlignofExpression - Parse a sizeof or alignof expression.
+/// unary-expression: [C99 6.5.3]
+/// 'sizeof' unary-expression
+/// 'sizeof' '(' type-name ')'
+/// [GNU] '__alignof' unary-expression
+/// [GNU] '__alignof' '(' type-name ')'
+/// [C++0x] 'alignof' '(' type-id ')'
+Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() {
+ assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof)
+ || Tok.is(tok::kw_alignof)) &&
+ "Not a sizeof/alignof expression!");
+ Token OpTok = Tok;
+ ConsumeToken();
+
+ bool isCastExpr;
+ TypeTy *CastTy;
+ SourceRange CastRange;
+ OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
+ isCastExpr,
+ CastTy,
+ CastRange);
+
+ if (isCastExpr)
+ return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
+ OpTok.is(tok::kw_sizeof),
+ /*isType=*/true, CastTy,
+ CastRange);
+
// If we get here, the operand to the sizeof/alignof was an expresion.
if (!Operand.isInvalid())
Operand = Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
OpTok.is(tok::kw_sizeof),
/*isType=*/false,
- Operand.release(), SourceRange());
+ Operand.release(), CastRange);
return move(Operand);
}
@@ -1177,6 +1229,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType,
Result = Actions.ActOnStmtExpr(OpenLoc, move(Stmt), Tok.getLocation());
} else if (ExprType >= CompoundLiteral && isTypeIdInParens()) {
+
// Otherwise, this is a compound literal expression or cast expression.
TypeResult Ty = ParseTypeName();