[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