[cfe-commits] r106950 - in /cfe/trunk: include/clang/Basic/DiagnosticLexKinds.td include/clang/Lex/PPCallbacks.h include/clang/Lex/Preprocessor.h lib/Frontend/PrintPreprocessedOutput.cpp lib/Lex/Pragma.cpp
Chris Lattner
sabre at nondot.org
Sat Jun 26 10:11:39 PDT 2010
Author: lattner
Date: Sat Jun 26 12:11:39 2010
New Revision: 106950
URL: http://llvm.org/viewvc/llvm-project?rev=106950&view=rev
Log:
Implement support for #pragma message, patch by Michael Spencer!
Modified:
cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
cfe/trunk/include/clang/Lex/PPCallbacks.h
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
cfe/trunk/lib/Lex/Pragma.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=106950&r1=106949&r2=106950&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Sat Jun 26 12:11:39 2010
@@ -225,6 +225,9 @@
"_Pragma takes a parenthesized string literal">;
def err_pragma_comment_malformed : Error<
"pragma comment requires parenthesized identifier and optional string">;
+def err_pragma_message_malformed : Error<
+ "pragma message requires parenthesized string">;
+def warn_pragma_message : Warning<"%0">;
def warn_pragma_ignored : Warning<"unknown pragma ignored">,
InGroup<UnknownPragmas>, DefaultIgnore;
def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
Modified: cfe/trunk/include/clang/Lex/PPCallbacks.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PPCallbacks.h?rev=106950&r1=106949&r2=106950&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/PPCallbacks.h (original)
+++ cfe/trunk/include/clang/Lex/PPCallbacks.h Sat Jun 26 12:11:39 2010
@@ -16,6 +16,7 @@
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/StringRef.h"
#include <string>
namespace clang {
@@ -70,6 +71,12 @@
const std::string &Str) {
}
+ /// PragmaMessage - This callback is invoked when a #pragma message directive
+ /// is read.
+ ///
+ virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
+ }
+
/// MacroExpands - This is called by
/// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
/// found.
@@ -127,6 +134,11 @@
Second->PragmaComment(Loc, Kind, Str);
}
+ virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
+ First->PragmaMessage(Loc, Str);
+ Second->PragmaMessage(Loc, Str);
+ }
+
virtual void MacroExpands(const Token &Id, const MacroInfo* MI) {
First->MacroExpands(Id, MI);
Second->MacroExpands(Id, MI);
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=106950&r1=106949&r2=106950&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Sat Jun 26 12:11:39 2010
@@ -918,6 +918,7 @@
void HandlePragmaSystemHeader(Token &SysHeaderTok);
void HandlePragmaDependency(Token &DependencyTok);
void HandlePragmaComment(Token &CommentTok);
+ void HandlePragmaMessage(Token &MessageTok);
// Return true and store the first token only if any CommentHandler
// has inserted some tokens and getCommentRetentionState() is false.
bool HandleComment(Token &Token, SourceRange Comment);
Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=106950&r1=106949&r2=106950&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp (original)
+++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Sat Jun 26 12:11:39 2010
@@ -23,6 +23,7 @@
#include "clang/Lex/TokenConcatenation.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
@@ -117,7 +118,7 @@
virtual void Ident(SourceLocation Loc, const std::string &str);
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
const std::string &Str);
-
+ virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str);
bool HandleFirstTokOnLine(Token &Tok);
bool MoveToLine(SourceLocation Loc) {
@@ -306,6 +307,29 @@
EmittedTokensOnThisLine = true;
}
+void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
+ llvm::StringRef Str) {
+ MoveToLine(Loc);
+ OS << "#pragma message(";
+
+ OS << '"';
+
+ for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+ unsigned char Char = Str[i];
+ if (isprint(Char) && Char != '\\' && Char != '"')
+ OS << (char)Char;
+ else // Output anything hard as an octal escape.
+ OS << '\\'
+ << (char)('0'+ ((Char >> 6) & 7))
+ << (char)('0'+ ((Char >> 3) & 7))
+ << (char)('0'+ ((Char >> 0) & 7));
+ }
+ OS << '"';
+
+ OS << ')';
+ EmittedTokensOnThisLine = true;
+}
+
/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
/// is called for the first token on each new line. If this really is the start
Modified: cfe/trunk/lib/Lex/Pragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Pragma.cpp?rev=106950&r1=106949&r2=106950&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Pragma.cpp (original)
+++ cfe/trunk/lib/Lex/Pragma.cpp Sat Jun 26 12:11:39 2010
@@ -419,7 +419,68 @@
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 @@
}
};
+/// 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 @@
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")));
+ }
}
More information about the cfe-commits
mailing list