[cfe-commits] r72255 - in /cfe/trunk: lib/AST/Type.cpp lib/Parse/ParseDecl.cpp test/Parser/cxx-template-decl.cpp test/Parser/typeof.c test/Sema/exprs.c

Argiris Kirtzidis akyrtzi at gmail.com
Fri May 22 03:22:23 PDT 2009


Author: akirtzidis
Date: Fri May 22 05:22:18 2009
New Revision: 72255

URL: http://llvm.org/viewvc/llvm-project?rev=72255&view=rev
Log:
Parse typeof-specifier the same way as sizeof/alignof are parsed.

-Makes typeof consistent with sizeof/alignof
-Fixes a bug when '>' is in a typeof expression, inside a template type param:
  A<typeof(x>1)> a;

Modified:
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/test/Parser/cxx-template-decl.cpp
    cfe/trunk/test/Parser/typeof.c
    cfe/trunk/test/Sema/exprs.c

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=72255&r1=72254&r2=72255&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Fri May 22 05:22:18 2009
@@ -1324,7 +1324,7 @@
   std::string Str;
   llvm::raw_string_ostream s(Str);
   getUnderlyingExpr()->printPretty(s);
-  InnerString = "typeof(" + s.str() + ")" + InnerString;
+  InnerString = "typeof " + s.str() + InnerString;
 }
 
 void TypeOfType::getAsStringInternal(std::string &InnerString) const {

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=72255&r1=72254&r2=72255&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri May 22 05:22:18 2009
@@ -2651,68 +2651,59 @@
   const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
   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;
     }
-
-    OwningExprResult Result(ParseCastExpression(true/*isUnaryExpression*/));
-    if (Result.isInvalid()) {
-      DS.SetTypeSpecError();
-      return;
-    }
-
-    const char *PrevSpec = 0;
-    // Check for duplicate type specifiers.
-    if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, 
-                           Result.release()))
-      Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
-
+    Operand = ParseCastExpression(true/*isUnaryExpression*/);
     // FIXME: Not accurate, the range gets one token more than it should.
     DS.SetRangeEnd(Tok.getLocation());
-    return;
-  }
-
-  SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
-  
-  if (isTypeIdInParens()) {
-    Action::TypeResult Ty = ParseTypeName();
-
-    assert((Ty.isInvalid() || Ty.get()) && 
-           "Parser::ParseTypeofSpecifier(): missing type");
 
-    if (Tok.isNot(tok::r_paren)) {
-      MatchRHSPunctuation(tok::r_paren, LParenLoc);
-      return;
-    }
-    RParenLoc = ConsumeParen();
+  } 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;
+      }
 
-    if (Ty.isInvalid())
-      DS.SetTypeSpecError();
-    else {
       const char *PrevSpec = 0;
       // Check for duplicate type specifiers (e.g. "int typeof(int)").
-      if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, 
-                             Ty.get()))
+      if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
+                             CastTy))
         Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
-    }
-  } else { // we have an expression.
-    OwningExprResult Result(ParseExpression());
-
-    if (Result.isInvalid() || Tok.isNot(tok::r_paren)) {
-      MatchRHSPunctuation(tok::r_paren, LParenLoc);
-      DS.SetTypeSpecError();
       return;
     }
-    RParenLoc = ConsumeParen();
-    const char *PrevSpec = 0;
-    // Check for duplicate type specifiers (e.g. "int typeof(int)").
-    if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, 
-                           Result.release()))
-      Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+
+    // 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));
   }
-  DS.SetRangeEnd(RParenLoc);
-}
 
+  // If we get here, the operand to the typeof was an expresion.
+  if (Operand.isInvalid()) {
+    DS.SetTypeSpecError();
+    return;
+  }
 
+  const char *PrevSpec = 0;
+  // Check for duplicate type specifiers (e.g. "int typeof(int)").
+  if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
+                         Operand.release()))
+    Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+}

Modified: cfe/trunk/test/Parser/cxx-template-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-decl.cpp?rev=72255&r1=72254&r2=72255&view=diff

==============================================================================
--- cfe/trunk/test/Parser/cxx-template-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx-template-decl.cpp Fri May 22 05:22:18 2009
@@ -75,3 +75,8 @@
 
 template<typename T>
 const T& min(const T&, const T&);
+
+void f2() {
+  int x;
+  A< typeof(x>1) > a;
+}

Modified: cfe/trunk/test/Parser/typeof.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/typeof.c?rev=72255&r1=72254&r2=72255&view=diff

==============================================================================
--- cfe/trunk/test/Parser/typeof.c (original)
+++ cfe/trunk/test/Parser/typeof.c Fri May 22 05:22:18 2009
@@ -11,7 +11,7 @@
   typeof(TInt) anInt; 
   short TInt eee; // expected-error{{expected ';' at end of declaration}}
   void ary[7] fff; // expected-error{{array has incomplete element type 'void'}} expected-error{{expected ';' at end of declaration}}
-  typeof(void ary[7]) anIntError; // expected-error{{expected ')'}} expected-note {{to match this '('}}  expected-warning {{type specifier missing, defaults to 'int'}}
+  typeof(void ary[7]) anIntError; // expected-error{{expected ')'}} expected-note {{to match this '('}}  expected-error {{variable has incomplete type 'typeof(void)' (aka 'void')}}
   typeof(const int) aci; 
   const typeof (*pi) aConstInt; 
   int xx;

Modified: cfe/trunk/test/Sema/exprs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/exprs.c?rev=72255&r1=72254&r2=72255&view=diff

==============================================================================
--- cfe/trunk/test/Sema/exprs.c (original)
+++ cfe/trunk/test/Sema/exprs.c Fri May 22 05:22:18 2009
@@ -79,7 +79,7 @@
 
 struct mystruct {int A; };
 void test11(struct mystruct P, float F) {
-  MYMAX(P, F);  // expected-error {{invalid operands to binary expression ('typeof(P)' (aka 'struct mystruct') and 'typeof(F)' (aka 'float'))}}
+  MYMAX(P, F);  // expected-error {{invalid operands to binary expression ('typeof (P)' (aka 'struct mystruct') and 'typeof (F)' (aka 'float'))}}
 }
 
 // PR3753





More information about the cfe-commits mailing list