diff options
| author | John McCall <rjmccall@apple.com> | 2010-08-28 22:34:47 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2010-08-28 22:34:47 +0000 |
| commit | 89e925d78e27a9c4b5faee55e49271ba11f624b3 (patch) | |
| tree | 6c8a1ace1ebe23f63eca5e32635bb3e502651922 /clang/lib | |
| parent | 0856906b1e7efe7d27b0e094567c22833fd01bc5 (diff) | |
| download | bcm5719-llvm-89e925d78e27a9c4b5faee55e49271ba11f624b3.tar.gz bcm5719-llvm-89e925d78e27a9c4b5faee55e49271ba11f624b3.zip | |
Add support for Microsoft's __pragma in the preprocessor.
Patch by Francois Pichet!
llvm-svn: 112391
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 12 | ||||
| -rw-r--r-- | clang/lib/Lex/Pragma.cpp | 54 |
2 files changed, 61 insertions, 5 deletions
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 894dc368e4c..9654104d4d2 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -72,6 +72,12 @@ void Preprocessor::RegisterBuiltinMacros() { 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 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { 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; diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index f0f3bce008d..af676670d1f 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -169,6 +169,57 @@ void Preprocessor::Handle_Pragma(Token &Tok) { --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 @@ void Preprocessor::Handle_Pragma(Token &Tok) { // With everything set up, lex this as a #pragma directive. HandlePragmaDirective(); - - // Finally, return whatever came after the pragma directive. - return Lex(Tok); } |

