]> granicus.if.org Git - clang/commitdiff
Support "typeof unary-expression" (GNU C++ extension).
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 5 Sep 2008 11:26:19 +0000 (11:26 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 5 Sep 2008 11:26:19 +0000 (11:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55833 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseDecl.cpp
test/Parser/cxx-typeof.cpp [new file with mode: 0644]

index cd2dda2941e99bf9d6ff15ba4f43a0e9363c10cc..2a8ab3f8db75c5a7bf6be524d70828c1c38b2635 100644 (file)
@@ -1556,9 +1556,10 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
                                           NumElements.Val, StartLoc));
 }
 
-/// [GNU] typeof-specifier:
-///         typeof ( expressions )
-///         typeof ( type-name )
+/// [GNU]   typeof-specifier:
+///           typeof ( expressions )
+///           typeof ( type-name )
+/// [GNU/C++] typeof unary-expression
 ///
 void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
   assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
@@ -1566,9 +1567,26 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
   SourceLocation StartLoc = ConsumeToken();
 
   if (Tok.isNot(tok::l_paren)) {
-    Diag(Tok, diag::err_expected_lparen_after, BuiltinII->getName());
+    if (!getLang().CPlusPlus) {
+      Diag(Tok, diag::err_expected_lparen_after, BuiltinII->getName());
+      return;
+    }
+
+    ExprResult Result = ParseCastExpression(true/*isUnaryExpression*/);
+    if (Result.isInvalid)
+      return;
+
+    const char *PrevSpec = 0;
+    // Check for duplicate type specifiers.
+    if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, 
+                           Result.Val))
+      Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
+
+    // FIXME: Not accurate, the range gets one token more than it should.
+    DS.SetRangeEnd(Tok.getLocation());
     return;
   }
+
   SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
   
   if (isTypeSpecifierQualifier()) {
diff --git a/test/Parser/cxx-typeof.cpp b/test/Parser/cxx-typeof.cpp
new file mode 100644 (file)
index 0000000..7e09905
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: clang -fsyntax-only -verify %s
+
+static void test() {
+  int *pi;
+  int x;
+  typeof pi[x] y; 
+}