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
/// 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);
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
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;
--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.
// With everything set up, lex this as a #pragma directive.
HandlePragmaDirective();
-
- // Finally, return whatever came after the pragma directive.
- return Lex(Tok);
}
#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}}
+}