[cfe-commits] r72256 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseExpr.cpp
Argiris Kirtzidis
akyrtzi at gmail.com
Fri May 22 03:22:51 PDT 2009
Author: akirtzidis
Date: Fri May 22 05:22:50 2009
New Revision: 72256
URL: http://llvm.org/viewvc/llvm-project?rev=72256&view=rev
Log:
Refactor the common code of 'ParseTypeofSpecifier' and 'ParseSizeofAlignofExpression' into a new
'ParseExprAfterTypeofSizeofAlignof' method.
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=72256&r1=72255&r2=72256&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri May 22 05:22:50 2009
@@ -158,6 +158,8 @@
OwningExprResult ExprError(const DiagnosticBuilder &) { return ExprError(); }
OwningStmtResult StmtError(const DiagnosticBuilder &) { return StmtError(); }
+ OwningExprResult ExprEmpty() { return OwningExprResult(Actions, false); }
+
// Parsing methods.
/// ParseTranslationUnit - All in one method that initializes parses, and
@@ -663,6 +665,11 @@
OwningExprResult ParsePostfixExpressionSuffix(OwningExprResult LHS);
OwningExprResult ParseSizeofAlignofExpression();
OwningExprResult ParseBuiltinPrimaryExpression();
+
+ OwningExprResult ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
+ bool &isCastExpr,
+ TypeTy *&CastTy,
+ SourceRange &CastRange);
static const unsigned ExprListSize = 12;
typedef llvm::SmallVector<ExprTy*, ExprListSize> ExprListTy;
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=72256&r1=72255&r2=72256&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri May 22 05:22:50 2009
@@ -2648,51 +2648,35 @@
///
void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
- const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
+ Token OpTok = Tok;
SourceLocation StartLoc = ConsumeToken();
- // If the operand doesn't start with an '(', it must be an expression.
- OwningExprResult Operand(Actions);
- if (Tok.isNot(tok::l_paren)) {
- if (!getLang().CPlusPlus) {
- Diag(Tok, diag::err_expected_lparen_after_id) << BuiltinII;
- return;
- }
- Operand = ParseCastExpression(true/*isUnaryExpression*/);
+ bool isCastExpr;
+ TypeTy *CastTy;
+ SourceRange CastRange;
+ OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
+ isCastExpr,
+ CastTy,
+ CastRange);
+
+ if (CastRange.getEnd().isInvalid())
// FIXME: Not accurate, the range gets one token more than it should.
DS.SetRangeEnd(Tok.getLocation());
-
- } 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);
- DS.SetRangeEnd(RParenLoc);
-
- // If ParseParenExpression parsed a '(typename)' sequence only, then this is
- // typeof a type. Otherwise, it is typeof an expression.
- if (ExprType == CastExpr) {
- if (!CastTy) {
- DS.SetTypeSpecError();
- return;
- }
-
- const char *PrevSpec = 0;
- // Check for duplicate type specifiers (e.g. "int typeof(int)").
- if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
- CastTy))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+ else
+ DS.SetRangeEnd(CastRange.getEnd());
+
+ if (isCastExpr) {
+ if (!CastTy) {
+ DS.SetTypeSpecError();
return;
}
- // If this is a parenthesized expression, it is the start of a
- // unary-expression, but doesn't include any postfix pieces. Parse these
- // now if present.
- Operand = ParsePostfixExpressionSuffix(move(Operand));
+ const char *PrevSpec = 0;
+ // Check for duplicate type specifiers (e.g. "int typeof(int)").
+ if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
+ CastTy))
+ Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+ return;
}
// If we get here, the operand to the typeof was an expresion.
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=72256&r1=72255&r2=72256&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Fri May 22 05:22:50 2009
@@ -913,42 +913,60 @@
}
}
-
-/// 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 @@
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 @@
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();
More information about the cfe-commits
mailing list