]> granicus.if.org Git - clang/commitdiff
Lexer: Implement GCC's version of pragma message.
authorMichael J. Spencer <bigcheesegs@gmail.com>
Mon, 27 Sep 2010 06:19:02 +0000 (06:19 +0000)
committerMichael J. Spencer <bigcheesegs@gmail.com>
Mon, 27 Sep 2010 06:19:02 +0000 (06:19 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114814 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/Pragma.cpp
test/Lexer/pragma-message.c [new file with mode: 0644]

index 3d6bc2aa839d6bf46050f1e38c2c619f3c7ef91a..4bca492adb061f91ed161440a44201a8e33d2e44 100644 (file)
@@ -483,23 +483,32 @@ 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.
+/// HandlePragmaMessage - Handle the microsoft and gcc #pragma message
+/// extension.  The syntax is:
+///   #pragma message(string)
+/// OR, in GCC mode:
+///   #pragma message string
+/// string 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)) {
+  bool ExpectClosingParen = false;
+  switch(Tok.getKind()) {
+  case tok::l_paren:
+    // We have a MSVC style pragma message.
+    ExpectClosingParen = true;
+    // Read the string.
+    Lex(Tok);
+    break;
+  case tok::string_literal:
+    // We have a GCC style pragma message, and we just read the string.
+    break;
+  default:
     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);
@@ -527,11 +536,13 @@ void Preprocessor::HandlePragmaMessage(Token &Tok) {
 
   llvm::StringRef MessageString(Literal.GetString(), Literal.GetStringLength());
 
-  if (Tok.isNot(tok::r_paren)) {
-    Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
-    return;
+  if (ExpectClosingParen) {
+    if (Tok.isNot(tok::r_paren)) {
+      Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
+      return;
+    }
+    Lex(Tok);  // eat the r_paren.
   }
-  Lex(Tok);  // eat the r_paren.
 
   if (Tok.isNot(tok::eom)) {
     Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
@@ -1001,6 +1012,7 @@ void Preprocessor::RegisterBuiltinPragmas() {
   AddPragmaHandler(new PragmaMarkHandler());
   AddPragmaHandler(new PragmaPushMacroHandler());
   AddPragmaHandler(new PragmaPopMacroHandler());
+  AddPragmaHandler(new PragmaMessageHandler());
 
   // #pragma GCC ...
   AddPragmaHandler("GCC", new PragmaPoisonHandler());
@@ -1022,6 +1034,5 @@ void Preprocessor::RegisterBuiltinPragmas() {
   // MS extensions.
   if (Features.Microsoft) {
     AddPragmaHandler(new PragmaCommentHandler());
-    AddPragmaHandler(new PragmaMessageHandler());
   }
 }
diff --git a/test/Lexer/pragma-message.c b/test/Lexer/pragma-message.c
new file mode 100644 (file)
index 0000000..423e6d0
--- /dev/null
@@ -0,0 +1,14 @@
+/* Test pragma message directive from\r
+   http://msdn.microsoft.com/en-us/library/x7dkzch2.aspx */\r
+\r
+// message: Sends a string literal to the standard output without terminating\r
+// the compilation.\r
+// #pragma message(messagestring)\r
+// OR\r
+// #pragma message messagestring\r
+//\r
+// RUN: %clang_cc1 -fsyntax-only -verify %s\r
+#define STRING2(x) #x\r
+#define STRING(x) STRING2(x)\r
+#pragma message(":O I'm a message! " STRING(__LINE__)) // expected-warning {{:O I'm a message! 13}}\r
+#pragma message ":O gcc accepts this! " STRING(__LINE__) // expected-warning {{:O gcc accepts this! 14}}\r