[cfe-commits] r112391 - in /cfe/trunk: include/clang/Lex/Preprocessor.h lib/Lex/PPMacroExpansion.cpp lib/Lex/Pragma.cpp test/Preprocessor/pragma_microsoft.c

John McCall rjmccall at apple.com
Sat Aug 28 15:34:47 PDT 2010


Author: rjmccall
Date: Sat Aug 28 17:34:47 2010
New Revision: 112391

URL: http://llvm.org/viewvc/llvm-project?rev=112391&view=rev
Log:
Add support for Microsoft's __pragma in the preprocessor.
Patch by Francois Pichet!


Modified:
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/lib/Lex/Pragma.cpp
    cfe/trunk/test/Preprocessor/pragma_microsoft.c

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=112391&r1=112390&r2=112391&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Sat Aug 28 17:34:47 2010
@@ -78,7 +78,8 @@
   IdentifierInfo *Ident__BASE_FILE__;              // __BASE_FILE__
   IdentifierInfo *Ident__TIMESTAMP__;              // __TIMESTAMP__
   IdentifierInfo *Ident__COUNTER__;                // __COUNTER__
-  IdentifierInfo *Ident_Pragma, *Ident__VA_ARGS__; // _Pragma, __VA_ARGS__
+  IdentifierInfo *Ident_Pragma, *Ident__pragma;    // _Pragma, __pragma
+  IdentifierInfo *Ident__VA_ARGS__;                // __VA_ARGS__
   IdentifierInfo *Ident__has_feature;              // __has_feature
   IdentifierInfo *Ident__has_builtin;              // __has_builtin
   IdentifierInfo *Ident__has_include;              // __has_include
@@ -904,6 +905,13 @@
   /// been read into 'Tok'.
   void Handle_Pragma(Token &Tok);
 
+  /// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text
+  /// is not enclosed within a string literal.
+  void HandleMicrosoft__pragma(Token &Tok);
+
+  void Handle_Pragma(const std::string &StrVal, SourceLocation PragmaLoc,
+                     SourceLocation RParenLoc);
+
   /// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and
   /// start lexing tokens from it instead of the current buffer.
   void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=112391&r1=112390&r2=112391&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Sat Aug 28 17:34:47 2010
@@ -72,6 +72,12 @@
   Ident__has_builtin      = RegisterBuiltinMacro(*this, "__has_builtin");
   Ident__has_include      = RegisterBuiltinMacro(*this, "__has_include");
   Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next");
+
+  // Microsoft Extensions.
+  if (Features.Microsoft) 
+    Ident__pragma = RegisterBuiltinMacro(*this, "__pragma");
+  else
+    Ident__pragma = 0;
 }
 
 /// isTrivialSingleTokenExpansion - Return true if MI, which has a single token
@@ -641,10 +647,12 @@
   IdentifierInfo *II = Tok.getIdentifierInfo();
   assert(II && "Can't be a macro without id info!");
 
-  // If this is an _Pragma directive, expand it, invoke the pragma handler, then
-  // lex the token after it.
+  // If this is an _Pragma or Microsoft __pragma directive, expand it,
+  // invoke the pragma handler, then lex the token after it.
   if (II == Ident_Pragma)
     return Handle_Pragma(Tok);
+  else if (II == Ident__pragma) // in non-MS mode this is null
+    return HandleMicrosoft__pragma(Tok);
 
   ++NumBuiltinMacroExpanded;
 

Modified: cfe/trunk/lib/Lex/Pragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Pragma.cpp?rev=112391&r1=112390&r2=112391&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Pragma.cpp (original)
+++ cfe/trunk/lib/Lex/Pragma.cpp Sat Aug 28 17:34:47 2010
@@ -169,6 +169,57 @@
       --e;
     }
   }
+  
+  Handle_Pragma(StrVal, PragmaLoc, RParenLoc);
+
+  // Finally, return whatever came after the pragma directive.
+  return Lex(Tok);
+}
+
+/// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text
+/// is not enclosed within a string literal.
+void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
+  // Remember the pragma token location.
+  SourceLocation PragmaLoc = Tok.getLocation();
+
+  // Read the '('.
+  Lex(Tok);
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(PragmaLoc, diag::err__Pragma_malformed);
+    return;
+  }
+
+  // Get the tokens enclosed within the __pragma().
+  llvm::SmallVector<Token, 32> PragmaToks;
+  int NumParens = 0;
+  Lex(Tok);
+  while (Tok.isNot(tok::eof)) {
+    if (Tok.is(tok::l_paren))
+      NumParens++;
+    else if (Tok.is(tok::r_paren) && NumParens-- == 0)
+      break;
+    PragmaToks.push_back(Tok);
+    Lex(Tok);
+  }
+
+  // Build the pragma string.
+  std::string StrVal = " ";
+  for (llvm::SmallVector<Token, 32>::iterator I =
+       PragmaToks.begin(), E = PragmaToks.end(); I != E; ++I) {
+    StrVal += getSpelling(*I);
+  }
+  
+  SourceLocation RParenLoc = Tok.getLocation();
+
+  Handle_Pragma(StrVal, PragmaLoc, RParenLoc);
+
+  // Finally, return whatever came after the pragma directive.
+  return Lex(Tok);
+}
+
+void Preprocessor::Handle_Pragma(const std::string &StrVal,
+                                 SourceLocation PragmaLoc,
+                                 SourceLocation RParenLoc) {
 
   // Plop the string (including the newline and trailing null) into a buffer
   // where we can lex it.
@@ -186,9 +237,6 @@
 
   // With everything set up, lex this as a #pragma directive.
   HandlePragmaDirective();
-
-  // Finally, return whatever came after the pragma directive.
-  return Lex(Tok);
 }
 
 

Modified: cfe/trunk/test/Preprocessor/pragma_microsoft.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/pragma_microsoft.c?rev=112391&r1=112390&r2=112391&view=diff
==============================================================================
--- cfe/trunk/test/Preprocessor/pragma_microsoft.c (original)
+++ cfe/trunk/test/Preprocessor/pragma_microsoft.c Sat Aug 28 17:34:47 2010
@@ -18,3 +18,23 @@
 
 #pragma comment(user, "foo\abar\nbaz\tsome	thing")
 
+
+// __pragma
+
+__pragma(comment(linker," bar=" BAR))                                            
+
+#define MACRO_WITH__PRAGMA { \
+  __pragma(warning(push)); \
+  __pragma(warning(disable: 10000)); \
+  2+2; \
+  __pragma(warning(pop)); \
+}
+
+void f()
+{
+  __pragma()
+
+  // If we ever actually *support* __pragma(warning(disable: x)),
+  // this warning should go away.
+  MACRO_WITH__PRAGMA // expected-warning {{expression result unused}}
+}





More information about the cfe-commits mailing list