From 6d8d22ae404cc857782c422e1f53c7d4a3d9311f Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Wed, 25 Jun 2014 00:28:35 +0000 Subject: [PATCH] Fix parsing nested __if_exists blocks 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 | 14 ++++++++------ clang/test/Parser/ms-if-exists.cpp | 18 ++++++++++++++++-- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 536e92c..f27634c 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -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); diff --git a/clang/test/Parser/ms-if-exists.cpp b/clang/test/Parser/ms-if-exists.cpp index 2d4a957..79cc571 100644 --- a/clang/test/Parser/ms-if-exists.cpp +++ b/clang/test/Parser/ms-if-exists.cpp @@ -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; + } +} -- 2.7.4