[cfe-commits] r132052 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDeclCXX.cpp lib/Parse/Parser.cpp test/Parser/MicrosoftExtensions.cpp

Francois Pichet pichet2000 at gmail.com
Wed May 25 03:19:49 PDT 2011


Author: fpichet
Date: Wed May 25 05:19:49 2011
New Revision: 132052

URL: http://llvm.org/viewvc/llvm-project?rev=132052&view=rev
Log:
Add support for Microsoft __if_exists, __if_not_exists extension at class scope.

Example:

typedef int TYPE;
class C {
  __if_exists(TYPE) {
     TYPE a;
  }
  __if_not_exists(TYPE) {
     this will never be parsed.
  }
};

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/test/Parser/MicrosoftExtensions.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=132052&r1=132051&r2=132052&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed May 25 05:19:49 2011
@@ -1310,7 +1310,9 @@
   StmtResult FuzzyParseMicrosoftAsmStatement(SourceLocation AsmLoc);
   bool ParseMicrosoftIfExistsCondition(bool& Result);
   void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
-  void ParseMicrosoftIfExistsDeclaration();
+  void ParseMicrosoftIfExistsExternalDeclaration();
+  void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
+                                              AccessSpecifier& CurAS);
 bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
                            llvm::SmallVectorImpl<ExprTy *> &Constraints,
                            llvm::SmallVectorImpl<ExprTy *> &Exprs);

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=132052&r1=132051&r2=132052&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed May 25 05:19:49 2011
@@ -1929,6 +1929,12 @@
     while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
       // Each iteration of this loop reads one member-declaration.
 
+      if (getLang().Microsoft && (Tok.is(tok::kw___if_exists) ||
+          Tok.is(tok::kw___if_not_exists))) {
+        ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
+        continue;
+      }
+
       // Check for extraneous top-level semicolon.
       if (Tok.is(tok::semi)) {
         Diag(Tok, diag::ext_extra_struct_semi)
@@ -2528,3 +2534,64 @@
     ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
   }
 }
+
+void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
+                                                    AccessSpecifier& CurAS) {
+  bool Result;
+  if (ParseMicrosoftIfExistsCondition(Result))
+    return;
+  
+  if (Tok.isNot(tok::l_brace)) {
+    Diag(Tok, diag::err_expected_lbrace);
+    return;
+  }
+  ConsumeBrace();
+
+  // Condition is false skip all inside the {}.
+  if (!Result) {
+    SkipUntil(tok::r_brace, false);
+    return;
+  }
+
+  // Condition is true, parse the declaration.
+  while (Tok.isNot(tok::r_brace)) {
+
+    // __if_exists, __if_not_exists can nest.
+    if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) {
+      ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
+      continue;
+    }
+
+    // Check for extraneous top-level semicolon.
+    if (Tok.is(tok::semi)) {
+      Diag(Tok, diag::ext_extra_struct_semi)
+        << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
+        << FixItHint::CreateRemoval(Tok.getLocation());
+      ConsumeToken();
+      continue;
+    }
+
+    AccessSpecifier AS = getAccessSpecifierIfPresent();
+    if (AS != AS_none) {
+      // Current token is a C++ access specifier.
+      CurAS = AS;
+      SourceLocation ASLoc = Tok.getLocation();
+      ConsumeToken();
+      if (Tok.is(tok::colon))
+        Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
+      else
+        Diag(Tok, diag::err_expected_colon);
+      ConsumeToken();
+      continue;
+    }
+
+    // Parse all the comma separated declarators.
+    ParseCXXClassMemberDeclaration(CurAS);
+  }
+
+  if (Tok.isNot(tok::r_brace)) {
+    Diag(Tok, diag::err_expected_rbrace);
+    return;
+  }
+  ConsumeBrace();
+}

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=132052&r1=132051&r2=132052&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Wed May 25 05:19:49 2011
@@ -656,7 +656,7 @@
 
   case tok::kw___if_exists:
   case tok::kw___if_not_exists:
-    ParseMicrosoftIfExistsDeclaration();
+    ParseMicrosoftIfExistsExternalDeclaration();
     return DeclGroupPtrTy();
 
   default:
@@ -1474,7 +1474,7 @@
   return false;
 }
 
-void Parser::ParseMicrosoftIfExistsDeclaration() {
+void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
   bool Result;
   if (ParseMicrosoftIfExistsCondition(Result))
     return;

Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=132052&r1=132051&r2=132052&view=diff
==============================================================================
--- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Wed May 25 05:19:49 2011
@@ -168,7 +168,7 @@
 __int64 x7 = __int64(0);
 
 
-
+namespace If_exists_test {
 
 class IF_EXISTS {
 private:
@@ -210,6 +210,31 @@
   int var244;
 }
 
+class IF_EXISTS_CLASS_TEST {
+  __if_exists(IF_EXISTS::Type) {
+    // __if_exists, __if_not_exists can nest
+    __if_not_exists(IF_EXISTS::Type_not) {
+      int var123;
+    }
+    int var23;
+  }
+
+  __if_exists(IF_EXISTS::Type_not) {
+   this wont compile.
+  }
+
+  __if_not_exists(IF_EXISTS::Type) {
+   this wont compile.
+  }
+
+  __if_not_exists(IF_EXISTS::Type_not) {
+    int var244;
+  }
+};
+
+}
+
+
 int __identifier(generic) = 3;
 
 class inline_definition_pure_spec {





More information about the cfe-commits mailing list