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

Francois Pichet pichet2000 at gmail.com
Sat May 7 10:30:27 PDT 2011


Author: fpichet
Date: Sat May  7 12:30:27 2011
New Revision: 131050

URL: http://llvm.org/viewvc/llvm-project?rev=131050&view=rev
Log:
Add support for _if_exists and __if_not_exists at namespace/global scope.

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseStmt.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=131050&r1=131049&r2=131050&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sat May  7 12:30:27 2011
@@ -1308,7 +1308,9 @@
   StmtResult ParseReturnStatement(ParsedAttributes &Attr);
   StmtResult ParseAsmStatement(bool &msAsm);
   StmtResult FuzzyParseMicrosoftAsmStatement(SourceLocation AsmLoc);
+  bool ParseMicrosoftIfExistsCondition(bool& Result);
   void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
+  void ParseMicrosoftIfExistsDeclaration();
 bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
                            llvm::SmallVectorImpl<ExprTy *> &Constraints,
                            llvm::SmallVectorImpl<ExprTy *> &Exprs);

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=131050&r1=131049&r2=131050&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Sat May  7 12:30:27 2011
@@ -2008,51 +2008,18 @@
 }
 
 void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
-  assert((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists)) &&
-         "Expected '__if_exists' or '__if_not_exists'");
-  Token Condition = Tok;
-  SourceLocation IfExistsLoc = ConsumeToken();
-
-  SourceLocation LParenLoc = Tok.getLocation();
-  if (Tok.isNot(tok::l_paren)) {
-    Diag(Tok, diag::err_expected_lparen_after) << IfExistsLoc;
-    SkipUntil(tok::semi);
+  bool Result;
+  if (ParseMicrosoftIfExistsCondition(Result))
     return;
-  }
-  ConsumeParen(); // eat the '('.
   
-  // Parse nested-name-specifier.
-  CXXScopeSpec SS;
-  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
-
-  // Check nested-name specifier.
-  if (SS.isInvalid()) {
-    SkipUntil(tok::semi);
-    return;
-  }
-
-  // Parse the unqualified-id. 
-  UnqualifiedId Name;
-  if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), Name)) {
-    SkipUntil(tok::semi);
-    return;
-  }
-
-  if (MatchRHSPunctuation(tok::r_paren, LParenLoc).isInvalid())
-    return;
-
   if (Tok.isNot(tok::l_brace)) {
     Diag(Tok, diag::err_expected_lbrace);
     return;
   }
   ConsumeBrace();
 
-  // Check if the symbol exists.
-  bool Exist = Actions.CheckMicrosoftIfExistsSymbol(SS, Name);
-
-  // If the condition is false skip the tokens until the '}'
-  if ((Condition.is(tok::kw___if_exists) && !Exist) ||
-      (Condition.is(tok::kw___if_not_exists) && Exist)) {
+  // Condition is false skip all inside the {}.
+  if (!Result) {
     SkipUntil(tok::r_brace, false);
     return;
   }

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=131050&r1=131049&r2=131050&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Sat May  7 12:30:27 2011
@@ -20,6 +20,7 @@
 #include "RAIIObjectsForParser.h"
 #include "ParsePragma.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ASTConsumer.h"
 using namespace clang;
 
 Parser::Parser(Preprocessor &pp, Sema &actions)
@@ -653,6 +654,11 @@
     // FIXME: Detect C++ linkage specifications here?
     goto dont_know;
 
+  case tok::kw___if_exists:
+  case tok::kw___if_not_exists:
+    ParseMicrosoftIfExistsDeclaration();
+    return DeclGroupPtrTy();
+
   default:
   dont_know:
     // We can't tell whether this is a function-definition or declaration yet.
@@ -1374,3 +1380,80 @@
 void Parser::CodeCompleteNaturalLanguage() {
   Actions.CodeCompleteNaturalLanguage();
 }
+
+bool Parser::ParseMicrosoftIfExistsCondition(bool& Result) {
+  assert((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists)) &&
+         "Expected '__if_exists' or '__if_not_exists'");
+  Token Condition = Tok;
+  SourceLocation IfExistsLoc = ConsumeToken();
+
+  SourceLocation LParenLoc = Tok.getLocation();
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen_after) << IfExistsLoc;
+    SkipUntil(tok::semi);
+    return true;
+  }
+  ConsumeParen(); // eat the '('.
+  
+  // Parse nested-name-specifier.
+  CXXScopeSpec SS;
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
+
+  // Check nested-name specifier.
+  if (SS.isInvalid()) {
+    SkipUntil(tok::semi);
+    return true;
+  }
+
+  // Parse the unqualified-id. 
+  UnqualifiedId Name;
+  if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), Name)) {
+    SkipUntil(tok::semi);
+    return true;
+  }
+
+  if (MatchRHSPunctuation(tok::r_paren, LParenLoc).isInvalid())
+    return true;
+
+  // Check if the symbol exists.
+  bool Exist = Actions.CheckMicrosoftIfExistsSymbol(SS, Name);
+
+  Result = ((Condition.is(tok::kw___if_exists) && Exist) ||
+            (Condition.is(tok::kw___if_not_exists) && !Exist));
+
+  return false;
+}
+
+void Parser::ParseMicrosoftIfExistsDeclaration() {
+  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)) {
+    ParsedAttributesWithRange attrs(AttrFactory);
+    MaybeParseCXX0XAttributes(attrs);
+    MaybeParseMicrosoftAttributes(attrs);
+    DeclGroupPtrTy Result = ParseExternalDeclaration(attrs);
+    if (Result && !getCurScope()->getParent())
+      Actions.getASTConsumer().HandleTopLevelDecl(Result.get());
+  }
+
+  if (Tok.isNot(tok::r_brace)) {
+    Diag(Tok, diag::err_expected_rbrace);
+    return;
+  }
+  ConsumeBrace();
+}

Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=131050&r1=131049&r2=131050&view=diff
==============================================================================
--- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Sat May  7 12:30:27 2011
@@ -174,26 +174,36 @@
 };
 
 int __if_exists_test() {
-
   int b=0;
-
-
   __if_exists(IF_EXISTS::Type) {
      b++;
      b++;
   }
-
   __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) {
      b++;
      b++;
   }
+}
+
+
+__if_exists(IF_EXISTS::Type) {
+  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;
 }





More information about the cfe-commits mailing list