summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex/Pragma.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-06-26 17:11:39 +0000
committerChris Lattner <sabre@nondot.org>2010-06-26 17:11:39 +0000
commit30c924b3e874ce14d877013727591699d1a5b209 (patch)
tree24a0e81d1752864b4298f41f86462aa178fa8df3 /clang/lib/Lex/Pragma.cpp
parent04775f84131467718edbb7b3698b0067164c395f (diff)
downloadbcm5719-llvm-30c924b3e874ce14d877013727591699d1a5b209.tar.gz
bcm5719-llvm-30c924b3e874ce14d877013727591699d1a5b209.zip
Implement support for #pragma message, patch by Michael Spencer!
llvm-svn: 106950
Diffstat (limited to 'clang/lib/Lex/Pragma.cpp')
-rw-r--r--clang/lib/Lex/Pragma.cpp73
1 files changed, 72 insertions, 1 deletions
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp
index 58a632618fd..18b46ad6116 100644
--- a/clang/lib/Lex/Pragma.cpp
+++ b/clang/lib/Lex/Pragma.cpp
@@ -419,7 +419,68 @@ void Preprocessor::HandlePragmaComment(Token &Tok) {
Callbacks->PragmaComment(CommentLoc, II, ArgumentString);
}
+/// HandlePragmaMessage - Handle the microsoft #pragma message extension. The
+/// syntax is:
+/// #pragma message(messagestring)
+/// messagestring is a string, which is fully macro expanded, and permits string
+/// concatenation, embedded escape characters etc. See MSDN for more details.
+void Preprocessor::HandlePragmaMessage(Token &Tok) {
+ SourceLocation MessageLoc = Tok.getLocation();
+ Lex(Tok);
+ if (Tok.isNot(tok::l_paren)) {
+ Diag(MessageLoc, diag::err_pragma_message_malformed);
+ return;
+ }
+
+ // Read the string.
+ Lex(Tok);
+
+
+ // We need at least one string.
+ if (Tok.isNot(tok::string_literal)) {
+ Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
+ return;
+ }
+
+ // String concatenation allows multiple strings, which can even come from
+ // macro expansion.
+ // "foo " "bar" "Baz"
+ llvm::SmallVector<Token, 4> StrToks;
+ while (Tok.is(tok::string_literal)) {
+ StrToks.push_back(Tok);
+ Lex(Tok);
+ }
+
+ // Concatenate and parse the strings.
+ StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this);
+ assert(!Literal.AnyWide && "Didn't allow wide strings in");
+ if (Literal.hadError)
+ return;
+ if (Literal.Pascal) {
+ Diag(StrToks[0].getLocation(), diag::err_pragma_message_malformed);
+ return;
+ }
+
+ llvm::StringRef MessageString(Literal.GetString(), Literal.GetStringLength());
+ if (Tok.isNot(tok::r_paren)) {
+ Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
+ return;
+ }
+ Lex(Tok); // eat the r_paren.
+
+ if (Tok.isNot(tok::eom)) {
+ Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
+ return;
+ }
+
+ // Output the message.
+ Diag(MessageLoc, diag::warn_pragma_message) << MessageString;
+
+ // If the pragma is lexically sound, notify any interested PPCallbacks.
+ if (Callbacks)
+ Callbacks->PragmaMessage(MessageLoc, MessageString);
+}
/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
@@ -632,6 +693,14 @@ struct PragmaCommentHandler : public PragmaHandler {
}
};
+/// PragmaMessageHandler - "#pragma message("...")".
+struct PragmaMessageHandler : public PragmaHandler {
+ PragmaMessageHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+ virtual void HandlePragma(Preprocessor &PP, Token &CommentTok) {
+ PP.HandlePragmaMessage(CommentTok);
+ }
+};
+
// Pragma STDC implementations.
enum STDCSetting {
@@ -743,6 +812,8 @@ void Preprocessor::RegisterBuiltinPragmas() {
AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());
// MS extensions.
- if (Features.Microsoft)
+ if (Features.Microsoft) {
AddPragmaHandler(0, new PragmaCommentHandler(getIdentifierInfo("comment")));
+ AddPragmaHandler(0, new PragmaMessageHandler(getIdentifierInfo("message")));
+ }
}
OpenPOWER on IntegriCloud