[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