diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2009-05-22 10:22:50 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2009-05-22 10:22:50 +0000 |
commit | 5ab0640efb436a721d408c853b771932d1a6ffce (patch) | |
tree | 8ca6bf0589cbb398662c852dfa628022de4acbe9 /lib/Parse/ParseExpr.cpp | |
parent | 6409625011e4a11ff07956ff46a44d6ca4473992 (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.cpp | 91 |
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(); |