Solaris pragma macro expansion

Joseph S. Myers joseph@codesourcery.com
Tue Nov 23 23:39:00 GMT 2004


Committed in the following form.  Bugs 18637 (for merging the pragma 
handler interfaces again when it's appropriate to cause churn to all back 
ends registering pragmas) and 18638 (for expanding macros in pragmas in 
C++) have been filed.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

Index: gcc/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ChangeLog,v
retrieving revision 2.6497
diff -u -r2.6497 ChangeLog
--- gcc/ChangeLog	23 Nov 2004 23:10:04 -0000	2.6497
+++ gcc/ChangeLog	23 Nov 2004 23:22:30 -0000
@@ -1,3 +1,19 @@
+2004-11-23  Daniel Jacobowitz  <dan@codesourcery.com>
+            Joseph Myers  <joseph@codesourcery.com>
+
+	* config/sol2-c.c (solaris_register_pragmas): Use
+	c_register_pragma_with_expansion.
+	* config/sol2.h (HANDLE_PRAGMA_PACK_WITH_EXPANSION): Define.
+	* c-pragma.c (c_register_pragma): Update call to
+	cpp_register_pragma.
+	(c_register_pragma_with_expansion): New function.
+	(init_pragma): Honor HANDLE_PRAGMA_PACK_WITH_EXPANSION.
+	* c-pragma.h (c_register_pragma_with_expansion): New prototype.
+	* doc/extend.texi (Solaris Pragmas): Mention macro expansion for
+	#pragma align.
+	* doc/tm.texi (c_register_pragma_with_expansion,
+	HANDLE_PRAGMA_PACK_WITH_EXPANSION): Document.
+
 2004-11-23  Richard Henderson  <rth@redhat.com>
 
 	* emit-rtl.c, rtl.h (subreg_hard_regno): Remove.
Index: gcc/c-pragma.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.c,v
retrieving revision 1.80
diff -u -r1.80 c-pragma.c
--- gcc/c-pragma.c	9 Nov 2004 10:12:15 -0000	1.80
+++ gcc/c-pragma.c	23 Nov 2004 23:22:30 -0000
@@ -627,13 +627,20 @@
 
 #endif
 
-/* Front-end wrapper for pragma registration to avoid dragging
+/* Front-end wrappers for pragma registration to avoid dragging
    cpplib.h in almost everywhere.  */
 void
 c_register_pragma (const char *space, const char *name,
 		   void (*handler) (struct cpp_reader *))
 {
-  cpp_register_pragma (parse_in, space, name, handler);
+  cpp_register_pragma (parse_in, space, name, handler, 0);
+}
+
+void
+c_register_pragma_with_expansion (const char *space, const char *name,
+				  void (*handler) (struct cpp_reader *))
+{
+  cpp_register_pragma (parse_in, space, name, handler, 1);
 }
 
 /* Set up front-end pragmas.  */
@@ -641,8 +648,12 @@
 init_pragma (void)
 {
 #ifdef HANDLE_PRAGMA_PACK
+#ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
+  c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
+#else
   c_register_pragma (0, "pack", handle_pragma_pack);
 #endif
+#endif
 #ifdef HANDLE_PRAGMA_WEAK
   c_register_pragma (0, "weak", handle_pragma_weak);
 #endif
Index: gcc/c-pragma.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.h,v
retrieving revision 1.43
diff -u -r1.43 c-pragma.h
--- gcc/c-pragma.h	21 Sep 2004 02:22:36 -0000	1.43
+++ gcc/c-pragma.h	23 Nov 2004 23:22:30 -0000
@@ -53,10 +53,12 @@
 
 extern void init_pragma (void);
 
-/* Front-end wrapper for pragma registration to avoid dragging
+/* Front-end wrappers for pragma registration to avoid dragging
    cpplib.h in almost everywhere.  */
 extern void c_register_pragma (const char *, const char *,
 			       void (*) (struct cpp_reader *));
+extern void c_register_pragma_with_expansion (const char *, const char *,
+					      void (*) (struct cpp_reader *));
 extern void maybe_apply_pragma_weak (tree);
 extern tree maybe_apply_renaming_pragma (tree, tree);
 extern void add_to_renaming_pragma_list (tree, tree);
Index: gcc/config/sol2-c.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sol2-c.c,v
retrieving revision 1.4
diff -u -r1.4 sol2-c.c
--- gcc/config/sol2-c.c	15 Nov 2004 16:08:04 -0000	1.4
+++ gcc/config/sol2-c.c	23 Nov 2004 23:22:30 -0000
@@ -266,7 +266,7 @@
 void
 solaris_register_pragmas (void)
 {
-  c_register_pragma (0, "align", solaris_pragma_align);
+  c_register_pragma_with_expansion (0, "align", solaris_pragma_align);
   c_register_pragma (0, "init", solaris_pragma_init);
   c_register_pragma (0, "fini", solaris_pragma_fini);
 }
Index: gcc/config/sol2.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sol2.h,v
retrieving revision 1.16
diff -u -r1.16 sol2.h
--- gcc/config/sol2.h	16 Nov 2004 22:42:21 -0000	1.16
+++ gcc/config/sol2.h	23 Nov 2004 23:22:30 -0000
@@ -245,3 +245,6 @@
 extern GTY(()) tree solaris_pending_aligns;
 extern GTY(()) tree solaris_pending_inits;
 extern GTY(()) tree solaris_pending_finis;
+
+/* Allow macro expansion in #pragma pack.  */
+#define HANDLE_PRAGMA_PACK_WITH_EXPANSION
Index: gcc/doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.231
diff -u -r1.231 extend.texi
--- gcc/doc/extend.texi	5 Nov 2004 01:36:56 -0000	1.231
+++ gcc/doc/extend.texi	23 Nov 2004 23:22:33 -0000
@@ -8603,7 +8603,10 @@
 
 Increase the minimum alignment of each @var{variable} to @var{alignment}.
 This is the same as GCC's @code{aligned} attribute @pxref{Variable
-Attributes}).
+Attributes}).  Macro expansion occurs on the arguments to this pragma
+when compiling C and Objective-C.  It does not currently occur when
+compiling C++, but this is a bug which may be fixed in a future
+release.
 
 @item fini (@var{function} [, @var{function}]...)
 @cindex pragma, fini
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.394
diff -u -r1.394 tm.texi
--- gcc/doc/tm.texi	23 Nov 2004 19:55:24 -0000	1.394
+++ gcc/doc/tm.texi	23 Nov 2004 23:22:37 -0000
@@ -9029,7 +9029,8 @@
 @defmac REGISTER_TARGET_PRAGMAS ()
 Define this macro if you want to implement any target-specific pragmas.
 If defined, it is a C expression which makes a series of calls to
-@code{c_register_pragma} for each pragma.  The macro may also do any
+@code{c_register_pragma} or @code{c_register_pragma_with_expansion}
+for each pragma.  The macro may also do any
 setup required for the pragmas.
 
 The primary reason to define this macro is to provide compatibility with
@@ -9045,8 +9046,10 @@
 @end defmac
 
 @deftypefun void c_register_pragma (const char *@var{space}, const char *@var{name}, void (*@var{callback}) (struct cpp_reader *))
+@deftypefunx void c_register_pragma_with_expansion (const char *@var{space}, const char *@var{name}, void (*@var{callback}) (struct cpp_reader *))
 
-Each call to @code{c_register_pragma} establishes one pragma.  The
+Each call to @code{c_register_pragma} or
+@code{c_register_pragma_with_expansion} establishes one pragma.  The
 @var{callback} routine will be called when the preprocessor encounters a
 pragma of the form
 
@@ -9060,7 +9063,10 @@
 on to cpplib's functions if necessary.  You can lex tokens after the
 @var{name} by calling @code{c_lex}.  Tokens that are not read by the
 callback will be silently ignored.  The end of the line is indicated by
-a token of type @code{CPP_EOF}
+a token of type @code{CPP_EOF}.  Macro expansion occurs on the
+arguments of pragmas registered with
+@code{c_register_pragma_with_expansion} but not on the arguments of
+pragmas registered with @code{c_register_pragma}.
 
 For an example use of this routine, see @file{c4x.h} and the callback
 routines defined in @file{c4x-c.c}.
@@ -9124,6 +9130,12 @@
 value.
 @end defmac
 
+@defmac HANDLE_PRAGMA_PACK_WITH_EXPANSION
+Define this macro, as well as
+@code{HANDLE_SYSV_PRAGMA}, if macros should be expanded in the
+arguments of @samp{#pragma pack}.
+@end defmac
+
 @defmac TARGET_DEFAULT_PACK_STRUCT
 If your target requires a structure packing default other than 0 (meaning
 the machine default), define this macro the the necessary value (in bytes).
Index: gcc/testsuite/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/ChangeLog,v
retrieving revision 1.4634
diff -u -r1.4634 ChangeLog
--- gcc/testsuite/ChangeLog	23 Nov 2004 22:03:23 -0000	1.4634
+++ gcc/testsuite/ChangeLog	23 Nov 2004 23:22:43 -0000
@@ -1,3 +1,8 @@
+2004-11-23  Daniel Jacobowitz  <dan@codesourcery.com>
+
+	* gcc.dg/pragma-align-2.c: Test macro expansion.
+	* gcc.dg/pragma-pack-2.c: New test.
+
 2004-11-23  Richard Henderson  <rth@redhat.com>
 
 	* gcc.dg/vect/pr18425.c: Use effective target vect_long.
Index: gcc/testsuite/gcc.dg/pragma-align-2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/pragma-align-2.c,v
retrieving revision 1.2
diff -u -r1.2 pragma-align-2.c
--- gcc/testsuite/gcc.dg/pragma-align-2.c	25 Jul 2004 18:08:52 -0000	1.2
+++ gcc/testsuite/gcc.dg/pragma-align-2.c	23 Nov 2004 23:22:43 -0000
@@ -11,6 +11,12 @@
 #pragma align 64(x64)
 #pragma align 128(x128)
 
+#define MACRO 128
+#define MACRO2(A) A
+
+#pragma align MACRO(y128)
+#pragma align MACRO2(MACRO) (z128)
+
 #pragma align 8(not_defined)
 
 #pragma align 9(odd_align)	/* { dg-error "invalid alignment" } */
@@ -19,7 +25,7 @@
 #pragma align bad_align		/* { dg-error "malformed" } */
 #pragma align 1(bad_align	/* { dg-error "malformed" } */
 
-int x, x1, x2, x4, x8, y8, z8, x16, x32, x64, x128;
+int x, x1, x2, x4, x8, y8, z8, x16, x32, x64, x128, y128, z128;
 
 #pragma align 16(x)		/* { dg-error "must appear before" } */
 
@@ -50,5 +56,11 @@
   if (__alignof__ (x128) < 128)
     abort ();
 
+  if (__alignof__ (y128) < 128)
+    abort ();
+
+  if (__alignof__ (z128) < 128)
+    abort (); 
+
   return 0;
 }
Index: gcc/testsuite/gcc.dg/pragma-pack-2.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/pragma-pack-2.c
diff -N gcc/testsuite/gcc.dg/pragma-pack-2.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/pragma-pack-2.c	23 Nov 2004 23:22:43 -0000
@@ -0,0 +1,48 @@
+/* On Solaris, #pragma pack should accept macro expansion.  */
+
+/* { dg-do run { target *-*-solaris2.* } } */
+
+extern void abort (void);
+
+struct {
+        char one;
+        long two;
+} defaultalign;
+
+#define ALIGNHIGH 16
+
+#pragma pack(ALIGNHIGH)
+struct {
+        char one;
+        long two;
+} sixteen;
+
+#define ALIGN1(X) 1
+#pragma pack(ALIGN1(4))
+struct {
+        char one;
+        long two;
+} two;
+
+#define ALIGN2(X) X
+#pragma pack(ALIGN2(2))
+struct {
+        char one;
+        long two;
+} three;
+
+#define EMPTY
+#pragma pack(EMPTY)
+struct {
+        char one;
+        long two;
+} resetalign;
+
+main()
+{
+        if(sizeof(sixteen) < sizeof(defaultalign)) abort();
+        if(sizeof(two) >= sizeof(defaultalign)) abort();
+        if(sizeof(three) <= sizeof(two)) abort();
+        if(sizeof(resetalign) != sizeof(defaultalign)) abort();
+	return 0;
+}
Index: libcpp/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/libcpp/ChangeLog,v
retrieving revision 1.39
diff -u -r1.39 ChangeLog
--- libcpp/ChangeLog	18 Nov 2004 01:06:51 -0000	1.39
+++ libcpp/ChangeLog	23 Nov 2004 23:22:43 -0000
@@ -1,3 +1,16 @@
+2004-11-23  Daniel Jacobowitz  <dan@codesourcery.com>
+            Joseph Myers  <joseph@codesourcery.com>
+
+	* internal.h (struct lexer_state): Add in_deferred_pragma.
+	* directives.c (struct pragma_entry): Add allow_expansion.
+	(insert_pragma_entry): Take allow_expansion flag.
+	(register_pragma): Likewise.
+	(cpp_register_pragma): Likewise.
+	(_cpp_init_internal_pragmas): Update calls to cpp_register_pragma.
+	(do_pragma): Honor allow_expansion.
+	(cpp_handle_deferred_pragma): Set in_deferred_pragma.
+	* include/cpplib.h (cpp_register_pragma): Update prototype.
+
 2004-11-18  Daniel Jacobowitz  <dan@codesourcery.com>
             Mark Mitchell  <mark@codesourcery.com>
 
Index: libcpp/directives.c
===================================================================
RCS file: /cvs/gcc/gcc/libcpp/directives.c,v
retrieving revision 1.8
diff -u -r1.8 directives.c
--- libcpp/directives.c	27 Oct 2004 17:29:29 -0000	1.8
+++ libcpp/directives.c	23 Nov 2004 23:22:43 -0000
@@ -45,6 +45,7 @@
   struct pragma_entry *next;
   const cpp_hashnode *pragma;	/* Name and length.  */
   bool is_nspace;
+  bool allow_expansion;
   bool is_internal;
   union {
     pragma_cb handler;
@@ -108,9 +109,9 @@
                                                  struct pragma_entry **,
                                                  const cpp_hashnode *,
                                                  pragma_cb,
-						 bool);
+						 bool, bool);
 static void register_pragma (cpp_reader *, const char *, const char *,
-			     pragma_cb, bool);
+			     pragma_cb, bool, bool);
 static int count_registered_pragmas (struct pragma_entry *);
 static char ** save_registered_pragmas (struct pragma_entry *, char **);
 static char ** restore_registered_pragmas (cpp_reader *, struct pragma_entry *,
@@ -964,7 +965,7 @@
 static struct pragma_entry *
 insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain,
 		     const cpp_hashnode *pragma, pragma_cb handler,
-		     bool internal)
+		     bool allow_expansion, bool internal)
 {
   struct pragma_entry *new;
 
@@ -982,6 +983,7 @@
       new->u.space = NULL;
     }
 
+  new->allow_expansion = allow_expansion;
   new->is_internal = internal;
   new->next = *chain;
   *chain = new;
@@ -990,12 +992,13 @@
 
 /* Register a pragma NAME in namespace SPACE.  If SPACE is null, it
    goes in the global namespace.  HANDLER is the handler it will call,
-   which must be non-NULL.  INTERNAL is true if this is a pragma
-   registered by cpplib itself, false if it is registered via
+   which must be non-NULL.  If ALLOW_EXPANSION is set, allow macro
+   expansion while parsing pragma NAME.  INTERNAL is true if this is a
+   pragma registered by cpplib itself, false if it is registered via
    cpp_register_pragma */
 static void
 register_pragma (cpp_reader *pfile, const char *space, const char *name,
-		 pragma_cb handler, bool internal)
+		 pragma_cb handler, bool allow_expansion, bool internal)
 {
   struct pragma_entry **chain = &pfile->pragmas;
   struct pragma_entry *entry;
@@ -1009,7 +1012,8 @@
       node = cpp_lookup (pfile, U space, strlen (space));
       entry = lookup_pragma_entry (*chain, node);
       if (!entry)
-	entry = insert_pragma_entry (pfile, chain, node, NULL, internal);
+	entry = insert_pragma_entry (pfile, chain, node, NULL, 
+				     allow_expansion, internal);
       else if (!entry->is_nspace)
 	goto clash;
       chain = &entry->u.space;
@@ -1032,17 +1036,20 @@
 	cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name);
     }
   else
-    insert_pragma_entry (pfile, chain, node, handler, internal);
+    insert_pragma_entry (pfile, chain, node, handler, allow_expansion, 
+			 internal);
 }
 
 /* Register a pragma NAME in namespace SPACE.  If SPACE is null, it
    goes in the global namespace.  HANDLER is the handler it will call,
-   which must be non-NULL.  This function is exported from libcpp. */
+   which must be non-NULL.  If ALLOW_EXPANSION is set, allow macro
+   expansion while parsing pragma NAME.  This function is exported
+   from libcpp. */
 void
 cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name,
-		     pragma_cb handler)
+		     pragma_cb handler, bool allow_expansion)
 {
-  register_pragma (pfile, space, name, handler, false);
+  register_pragma (pfile, space, name, handler, allow_expansion, false);
 }
 
 /* Register the pragmas the preprocessor itself handles.  */
@@ -1050,12 +1057,14 @@
 _cpp_init_internal_pragmas (cpp_reader *pfile)
 {
   /* Pragmas in the global namespace.  */
-  register_pragma (pfile, 0, "once", do_pragma_once, true);
+  register_pragma (pfile, 0, "once", do_pragma_once, false, true);
 
   /* New GCC-specific pragmas should be put in the GCC namespace.  */
-  register_pragma (pfile, "GCC", "poison", do_pragma_poison, true);
-  register_pragma (pfile, "GCC", "system_header", do_pragma_system_header, true);
-  register_pragma (pfile, "GCC", "dependency", do_pragma_dependency, true);
+  register_pragma (pfile, "GCC", "poison", do_pragma_poison, false, true);
+  register_pragma (pfile, "GCC", "system_header", do_pragma_system_header, 
+		   false, true);
+  register_pragma (pfile, "GCC", "dependency", do_pragma_dependency, 
+		   false, true);
 }
 
 /* Return the number of registered pragmas in PE.  */
@@ -1176,7 +1185,14 @@
 	     numbers in place.  */
 	  if (pfile->cb.line_change)
 	    (*pfile->cb.line_change) (pfile, pragma_token, false);
+	  /* Never expand macros if handling a deferred pragma, since
+	     the macro definitions now applicable may be different
+	     from those at the point the pragma appeared.  */
+	  if (p->allow_expansion && !pfile->state.in_deferred_pragma)
+	    pfile->state.prevent_expansion--;
 	  (*p->u.handler) (pfile);
+	  if (p->allow_expansion && !pfile->state.in_deferred_pragma)
+	    pfile->state.prevent_expansion++;
 	}
       else
 	{
@@ -1430,6 +1446,7 @@
   pfile->context->macro = 0;
   pfile->context->prev = 0;
   pfile->cb.line_change = NULL;
+  pfile->state.in_deferred_pragma = true;
   CPP_OPTION (pfile, defer_pragmas) = false;
 
   run_directive (pfile, T_PRAGMA, (const char *)s->text, s->len);
@@ -1439,6 +1456,7 @@
   pfile->cur_token = saved_cur_token;
   pfile->cur_run = saved_cur_run;
   pfile->cb.line_change = saved_line_change;
+  pfile->state.in_deferred_pragma = false;
   CPP_OPTION (pfile, defer_pragmas) = saved_defer_pragmas;
 }
 
Index: libcpp/internal.h
===================================================================
RCS file: /cvs/gcc/gcc/libcpp/internal.h,v
retrieving revision 1.8
diff -u -r1.8 internal.h
--- libcpp/internal.h	4 Nov 2004 20:35:08 -0000	1.8
+++ libcpp/internal.h	23 Nov 2004 23:22:43 -0000
@@ -205,6 +205,9 @@
   /* Nonzero to prevent macro expansion.  */
   unsigned char prevent_expansion;
 
+  /* Nonzero when handling a deferred pragma.  */
+  unsigned char in_deferred_pragma;
+
   /* Nonzero when parsing arguments to a function-like macro.  */
   unsigned char parsing_args;
 
Index: libcpp/include/cpplib.h
===================================================================
RCS file: /cvs/gcc/gcc/libcpp/include/cpplib.h,v
retrieving revision 1.5
diff -u -r1.5 cpplib.h
--- libcpp/include/cpplib.h	9 Sep 2004 19:16:56 -0000	1.5
+++ libcpp/include/cpplib.h	23 Nov 2004 23:22:44 -0000
@@ -638,7 +638,7 @@
 extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *,
 				       unsigned char *);
 extern void cpp_register_pragma (cpp_reader *, const char *, const char *,
-				 void (*) (cpp_reader *));
+				 void (*) (cpp_reader *), bool);
 extern void cpp_handle_deferred_pragma (cpp_reader *, const cpp_string *);
 extern int cpp_avoid_paste (cpp_reader *, const cpp_token *,
 			    const cpp_token *);



More information about the Gcc-patches mailing list