[PATCH][RFC] Add #pragma message ... to gcc/g++

Simon Baldwin simonb@google.com
Fri Jul 18 15:31:00 GMT 2008


This patch adds '#pragma message ...' to gcc.  This pragma is currently
present in both ICC and MSVC, but not gcc, and the feature is occasionally
requested by gcc users.

This #pragma message implementation matches those of the other compilers as
closely as possible, for best compatibility.  In particular, the new message
pragma is not prefixed with "GCC".

Tested and confirmed with gcc and g++ build, bootstrap, and testsuite.

Okay for trunk?  Or, let the debate commence...


gcc/ChangeLog:
2008-07-18  Simon Baldwin  <simonb@google.com>

	* c-pragma.c (handle_pragma_message): New function.
	* (init_pragma): Register handle_pragma_message.

gcc/testsuite/ChangeLog:
2008-07-18  Simon Baldwin  <simonb@google.com>

	* gcc.dg/pragma-message.c: New.


diff -Nr -C 10 -p gcc-message_orig/gcc/c-pragma.c gcc-message/gcc/c-pragma.c
*** gcc-message_orig/gcc/c-pragma.c	Thu Jul 17 13:05:49 2008
--- gcc-message/gcc/c-pragma.c	Fri Jul 18 10:03:47 2008
*************** handle_pragma_diagnostic(cpp_reader *ARG
*** 859,878 ****
--- 859,909 ----
  	/* This makes sure the option is enabled, like -Wfoo would do.  */
  	if (cl_options[option_index].var_type == CLVC_BOOLEAN
  	    && cl_options[option_index].flag_var
  	    && kind != DK_IGNORED)
  	    *(int *) cl_options[option_index].flag_var = 1;
  	return;
        }
    GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
  }
  
+ static void
+ handle_pragma_message (cpp_reader *ARG_UNUSED(dummy))
+ {
+   enum cpp_ttype token;
+   tree x, message = 0;
+ 
+   token = pragma_lex (&x);
+   if (token == CPP_OPEN_PAREN)
+     {
+       token = pragma_lex (&x);
+       if (token == CPP_STRING)
+         message = x;
+       else
+         GCC_BAD ("expected a string after %<#pragma message%>");
+       if (pragma_lex (&x) != CPP_CLOSE_PAREN)
+         GCC_BAD ("malformed %<#pragma message%> - ignored");
+     }
+   else if (token == CPP_STRING)
+     message = x;
+   else
+     GCC_BAD ("expected a string after %<#pragma message%>");
+ 
+   gcc_assert (message);
+ 
+   if (pragma_lex (&x) != CPP_EOF)
+     warning (OPT_Wpragmas, "junk at end of %<#pragma message%>");
+ 
+   if (TREE_STRING_LENGTH (message) > 1)
+     fnotice (stdout, "%s\n", TREE_STRING_POINTER (message));
+ }
+ 
  /* A vector of registered pragma callbacks.  */
  
  DEF_VEC_O (pragma_handler);
  DEF_VEC_ALLOC_O (pragma_handler, heap);
  
  static VEC(pragma_handler, heap) *registered_pragmas;
  
  typedef struct
  {
    const char *space;
*************** init_pragma (void)
*** 1025,1040 ****
--- 1056,1073 ----
  #endif
  #ifdef HANDLE_PRAGMA_VISIBILITY
    c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
  #endif
  
    c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
  
    c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
    c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
  
+   c_register_pragma_with_expansion (0, "message", handle_pragma_message);
+ 
  #ifdef REGISTER_TARGET_PRAGMAS
    REGISTER_TARGET_PRAGMAS ();
  #endif
  }
  
  #include "gt-c-pragma.h"
diff -Nr -C 10 -p gcc-message_orig/gcc/doc/extend.texi gcc-message/gcc/doc/extend.texi
*** gcc-message_orig/gcc/doc/extend.texi	Thu Jul 17 13:05:33 2008
--- gcc-message/gcc/doc/extend.texi	Fri Jul 18 14:21:57 2008
*************** while it is syntactically valid to put t
*** 11397,11416 ****
--- 11397,11450 ----
  sources, the only supported location for them is before any data or
  functions are defined.  Doing otherwise may result in unpredictable
  results depending on how the optimizer manages your sources.  If the
  same option is listed multiple times, the last one specified is the
  one that is in effect.  This pragma is not intended to be a general
  purpose replacement for command line options, but for implementing
  strict control over project policies.
  
  @end table
  
+ GCC also provides a simple mechanism for printing messages during
+ compilation.
+ 
+ @table @code
+ @item #pragma message @var{string}
+ @cindex pragma, diagnostic
+ 
+ Prints @var{string} to the compiler's standard output stream on
+ compilation.  The output is informational only, and is neither a
+ compilation warning nor an error.
+ 
+ @smallexample
+ #pragma message "Compiling " __FILE__ "..."
+ @end smallexample
+ 
+ @var{string} may be parenthesized, and is printed exactly as given,
+ without any leading location information.  The pragma can be used in
+ combination with macros to generate messages in a format similar to
+ those printed by gcc.  For example:
+ 
+ @smallexample
+ #define STRING2(x) #x
+ #define STRING(x) STRING2(x)
+ #define DO_PRAGMA(x) _Pragma (#x)
+ #define TODO(x) \
+   DO_PRAGMA(message (__FILE__ ":" STRING(__LINE__) ": TODO - " #x))
+ 
+ TODO(Remember to do something about this)
+ @end smallexample
+ 
+ prints @samp{/tmp/file.c:7: TODO - Remember to do something about this}.
+ 
+ @end table
+ 
  @node Visibility Pragmas
  @subsection Visibility Pragmas
  
  @table @code
  @item #pragma GCC visibility push(@var{visibility})
  @itemx #pragma GCC visibility pop
  @cindex pragma, visibility
  
  This pragma allows the user to set the visibility for multiple
  declarations without having to give each a visibility attribute
diff -Nr -C 10 -p gcc-message_orig/gcc/testsuite/gcc.dg/pragma-message.c gcc-message/gcc/testsuite/gcc.dg/pragma-message.c
*** gcc-message_orig/gcc/testsuite/gcc.dg/pragma-message.c	Thu Jan  1 01:00:00 1970
--- gcc-message/gcc/testsuite/gcc.dg/pragma-message.c	Fri Jul 18 14:23:09 2008
***************
*** 0 ****
--- 1,58 ----
+ /* Test that #pragma message "..." writes to the compiler's stdout stream. */
+ 
+ #pragma message               /* { dg-warning "expected a string" } */
+ #pragma message 0             /* { dg-warning "expected a string" } */
+ #pragma message id            /* { dg-warning "expected a string" } */
+ #pragma message (             /* { dg-warning "expected a string" } */
+ #pragma message (0            /* { dg-warning "expected a string" } */
+ #pragma message (id           /* { dg-warning "expected a string" } */
+ #pragma message ()            /* { dg-warning "expected a string" } */
+ #pragma message (0)           /* { dg-warning "expected a string" } */
+ #pragma message (id)          /* { dg-warning "expected a string" } */
+ 
+ #pragma message "
+ /* { dg-error "missing terminating" "" { target *-*-* } 13 } */
+ /* { dg-warning "expected a string" "" { target *-*-* } 13 } */
+ #pragma message "Bad 1
+ /* { dg-error "missing terminating" "" { target *-*-* } 16 } */
+ /* { dg-warning "expected a string" "" { target *-*-* } 16 } */
+ #pragma message ("Bad 2
+ /* { dg-error "missing terminating" "" { target *-*-* } 19 } */
+ /* { dg-warning "expected a string" "" { target *-*-* } 19 } */
+ #pragma message ("Bad 3"
+ /* { dg-warning "malformed '#pragma message" "" { target *-*-* } 22 } */
+ 
+ #pragma message "" junk
+ /* { dg-warning "junk at end of '#pragma message'" "" { target *-*-* } 25 } */
+ 
+ #pragma message ("") junk
+ /* { dg-warning "junk at end of '#pragma message'" "" { target *-*-* } 28 } */
+ 
+ #pragma message ""            /* No output expected for empty messages.  */
+ #pragma message ("")
+ 
+ /* Messages printed with #pragma message are formatted with a leading
+    _:<line_number>" so that dg-message can verify them.  */
+ #pragma message "_:36: Okay 1"         /* { dg-message "Okay 1" } */
+ #pragma message ("_:37: Okay 2")       /* { dg-message "Okay 2" } */
+ #define THREE "3"
+ #pragma message ("_:39: Okay " THREE)  /* { dg-message "Okay 3" } */
+ 
+ /* Use __FILE__ and __LINE__ to generate messages that look like a standard
+    gcc warning/error report.  */
+ #define STRING2(x) #x
+ #define STRING(x) STRING2(x)
+ #define NOTE(x) (__FILE__ ":" STRING(__LINE__) ": Note - " #x)
+ #pragma message NOTE(Okay 4)           /* { dg-message "Note - Okay 4" } */
+ 
+ /* Create a TODO() that prints a message on compilation.  */
+ #define DO_PRAGMA(x) _Pragma (#x)
+ #define TODO(x) \
+   DO_PRAGMA(message (__FILE__ ":" STRING(__LINE__) ": TODO - " #x))
+ TODO(Okay 5)                           /* { dg-message "TODO - Okay 5" } */
+ 
+ #if 0
+ #pragma message ("Not printed")
+ #endif
+ 
+ int unused;  /* Silence `ISO C forbids an empty translation unit' warning.  */



More information about the Gcc-patches mailing list