From: Michael J. Spencer Date: Mon, 27 Sep 2010 06:19:02 +0000 (+0000) Subject: Lexer: Implement GCC's version of pragma message. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=301669b381dfead44bda5ea3211d69ffec5a530b;p=clang Lexer: Implement GCC's version of pragma message. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114814 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 3d6bc2aa83..4bca492adb 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -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 index 0000000000..423e6d065a --- /dev/null +++ b/test/Lexer/pragma-message.c @@ -0,0 +1,14 @@ +/* Test pragma message directive from + http://msdn.microsoft.com/en-us/library/x7dkzch2.aspx */ + +// message: Sends a string literal to the standard output without terminating +// the compilation. +// #pragma message(messagestring) +// OR +// #pragma message messagestring +// +// RUN: %clang_cc1 -fsyntax-only -verify %s +#define STRING2(x) #x +#define STRING(x) STRING2(x) +#pragma message(":O I'm a message! " STRING(__LINE__)) // expected-warning {{:O I'm a message! 13}} +#pragma message ":O gcc accepts this! " STRING(__LINE__) // expected-warning {{:O gcc accepts this! 14}}