Fix parsing nested __if_exists blocks
authorReid Kleckner <reid@kleckner.net>
Wed, 25 Jun 2014 00:28:35 +0000 (00:28 +0000)
committerReid Kleckner <reid@kleckner.net>
Wed, 25 Jun 2014 00:28:35 +0000 (00:28 +0000)
Rather than having kw___if_exists be a special case of
ParseCompoundStatementBody, we can look for kw___if_exists in the big
switch over for valid statement tokens in ParseStatementOrDeclaration.

Nested __if_exists blocks are used in the DECLARE_REGISTRY_RESOURCEID
macro from atlcom.h.

llvm-svn: 211654

clang/lib/Parse/ParseStmt.cpp
clang/test/Parser/ms-if-exists.cpp

index 536e92c..f27634c 100644 (file)
@@ -273,6 +273,14 @@ Retry:
     break;
   }
 
+  case tok::kw___if_exists:
+  case tok::kw___if_not_exists:
+    ProhibitAttributes(Attrs);
+    ParseMicrosoftIfExistsStatement(Stmts);
+    // An __if_exists block is like a compound statement, but it doesn't create
+    // a new scope.
+    return StmtEmpty();
+
   case tok::kw_try:                 // C++ 15: try-block
     return ParseCXXTryBlock();
 
@@ -914,12 +922,6 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
       continue;
     }
 
-    if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
-        Tok.is(tok::kw___if_not_exists))) {
-      ParseMicrosoftIfExistsStatement(Stmts);
-      continue;
-    }
-
     StmtResult R;
     if (Tok.isNot(tok::kw___extension__)) {
       R = ParseStatementOrDeclaration(Stmts, false);
index 2d4a957..79cc571 100644 (file)
@@ -1,7 +1,5 @@
 // RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -Wmicrosoft -verify -fms-extensions
 
-// expected-no-diagnostics
-
 class MayExist {
 private:
   typedef int Type;
@@ -101,3 +99,19 @@ class IfExistsClassScope {
     int var244;
   }
 };
+
+void test_nested_if_exists() {
+  __if_exists(MayExist::Type) {
+    int x = 42;
+    __if_not_exists(MayExist::Type_not) {
+      x++;
+    }
+  }
+}
+
+void test_attribute_on_if_exists() {
+  [[clang::fallthrough]] // expected-error {{an attribute list cannot appear here}}
+  __if_exists(MayExist::Type) {
+    int x;
+  }
+}