[cfe-commits] r131014 - in /cfe/trunk: include/clang/Basic/TokenKinds.def include/clang/Parse/Parser.h include/clang/Sema/Sema.h lib/Parse/ParseStmt.cpp lib/Sema/SemaExprCXX.cpp test/Parser/MicrosoftExtensions.cpp

Francois Pichet pichet2000 at gmail.com
Fri May 6 13:48:22 PDT 2011


Author: fpichet
Date: Fri May  6 15:48:22 2011
New Revision: 131014

URL: http://llvm.org/viewvc/llvm-project?rev=131014&view=rev
Log:
Add support for Microsoft __if_exists and __if_not_exists construct inside function definition.
Allow to include or exclude code depending on if a symbol exists or not. Just like a #ifdef but for C/C++ symbols.

More doc: http://msdn.microsoft.com/en-us/library/x7wy9xh3(v=VS.100).aspx

Support at class and namespace scopes will be added later.

Modified:
    cfe/trunk/include/clang/Basic/TokenKinds.def
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseStmt.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/Parser/MicrosoftExtensions.cpp

Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=131014&r1=131013&r2=131014&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Fri May  6 15:48:22 2011
@@ -451,6 +451,8 @@
 KEYWORD(__finally                 , KEYMS | KEYBORLAND)
 KEYWORD(__leave                   , KEYMS | KEYBORLAND)
 KEYWORD(__int64                   , KEYMS)
+KEYWORD(__if_exists               , KEYMS)
+KEYWORD(__if_not_exists           , KEYMS)
 ALIAS("__int8"       , char       , KEYMS)
 ALIAS("__int16"      , short      , KEYMS)
 ALIAS("__int32"      , int        , KEYMS)

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=131014&r1=131013&r2=131014&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri May  6 15:48:22 2011
@@ -1308,7 +1308,8 @@
   StmtResult ParseReturnStatement(ParsedAttributes &Attr);
   StmtResult ParseAsmStatement(bool &msAsm);
   StmtResult FuzzyParseMicrosoftAsmStatement(SourceLocation AsmLoc);
-  bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
+  void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
+bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
                            llvm::SmallVectorImpl<ExprTy *> &Constraints,
                            llvm::SmallVectorImpl<ExprTy *> &Exprs);
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=131014&r1=131013&r2=131014&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri May  6 15:48:22 2011
@@ -2385,6 +2385,8 @@
 
   bool CheckCaseExpression(Expr *expr);
 
+  bool CheckMicrosoftIfExistsSymbol(CXXScopeSpec &SS, UnqualifiedId &Name);
+
   //===------------------------- "Block" Extension ------------------------===//
 
   /// ActOnBlockStart - This callback is invoked when a block literal is

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=131014&r1=131013&r2=131014&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Fri May  6 15:48:22 2011
@@ -741,6 +741,12 @@
       continue;
     }
 
+    if (getLang().Microsoft && (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);
@@ -2000,3 +2006,67 @@
 
   return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.take());
 }
+
+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);
+    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)) {
+    SkipUntil(tok::r_brace, false);
+    return;
+  }
+
+  // Condition is true, parse the statements.
+  while (Tok.isNot(tok::r_brace)) {
+    StmtResult R = ParseStatementOrDeclaration(Stmts, false);
+    if (R.isUsable())
+      Stmts.push_back(R.release());
+  }
+
+  if (Tok.isNot(tok::r_brace)) {
+    Diag(Tok, diag::err_expected_rbrace);
+    return;
+  }
+  ConsumeBrace();
+}

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=131014&r1=131013&r2=131014&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri May  6 15:48:22 2011
@@ -4295,3 +4295,18 @@
 
   return MaybeCreateStmtWithCleanups(FullStmt);
 }
+
+bool Sema::CheckMicrosoftIfExistsSymbol(CXXScopeSpec &SS,
+                                        UnqualifiedId &Name) {
+  DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name);
+  DeclarationName TargetName = TargetNameInfo.getName();
+  if (!TargetName)
+    return false;
+
+  // Do the redeclaration lookup in the current scope.
+  LookupResult R(*this, TargetNameInfo, Sema::LookupAnyName,
+                 Sema::NotForRedeclaration);
+  R.suppressDiagnostics();
+  LookupParsedName(R, getCurScope(), &SS);
+  return !R.empty(); 
+}

Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=131014&r1=131013&r2=131014&view=diff
==============================================================================
--- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Fri May  6 15:48:22 2011
@@ -164,3 +164,36 @@
 };
 
 __int64 x7 = __int64(0);
+
+
+
+
+class IF_EXISTS {
+private:
+    typedef int Type;
+};
+
+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++;
+  }
+
+}





More information about the cfe-commits mailing list