This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Solaris pragma macro expansion


This patch makes the implementation of the "align" and "pack" pragmas
on Solaris follow the specification followed by the Sun compiler more
closely.  In particular, #pragma align may appear after the first
declaration, and the Solaris specification is that the arguments to
certain pragmas are macro expanded.  (The introduction of
macro-expanded pragmas is part of the Solaris 10 patches which I'm not
particularly certain of the desirability of for FSF GCC, though if the
pragmas are for compatibility with vendor compilers it seems to make
sense to follow the vendor specification in this regard.)

Bootstrapped with no regressions on i386-pc-solaris2.10 (on top of the
previous five unreviewed patches).  OK to commit?

gcc:
2004-11-19  Daniel Jacobowitz  <dan@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>

	* config/sol2-c.c (solaris_pragma_align): Allow #pragma align
	after the first declaration.
	(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.

gcc/testsuite:
2004-11-19  Daniel Jacobowitz  <dan@codesourcery.com>

	* gcc.dg/pragma-align-2.c: Test for #pragma align after the
	definition of y16.  Test macro expansion.
	* gcc.dg/pragma-pack-2.c: New test.

libcpp:
2004-11-19  Daniel Jacobowitz  <dan@codesourcery.com>

	* 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.
	* include/cpplib.h (cpp_register_pragma): Update prototype.

diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/gcc/config/sol2-c.c gcc-sol210/gcc/config/sol2-c.c
--- gcc-merge-HEAD-csl-sol210-1/gcc/config/sol2-c.c	2004-09-17 14:54:50.000000000 -0700
+++ gcc-sol210/gcc/config/sol2-c.c	2004-09-27 09:24:48.000000000 -0700
@@ -115,8 +115,11 @@ solaris_pragma_align (cpp_reader *pfile 
     {
       tree decl = identifier_global_value (t);
       if (decl && DECL_P (decl))
-	warning ("%<#pragma align%> must appear before the declaration of "
-		 "%D, ignoring", decl);
+	{
+	  decl_attributes (&decl, build_tree_list (get_identifier ("aligned"),
+						   build_tree_list (NULL, x)),
+			   0);
+	}
       else
 	solaris_pending_aligns = tree_cons (t, build_tree_list (NULL, x),
 					    solaris_pending_aligns);
@@ -266,7 +269,7 @@ solaris_pragma_fini (cpp_reader *pfile A
 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);
 }
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/gcc/config/sol2.h gcc-sol210/gcc/config/sol2.h
--- gcc-merge-HEAD-csl-sol210-1/gcc/config/sol2.h	2004-07-25 11:10:02.000000000 -0700
+++ gcc-sol210/gcc/config/sol2.h	2004-09-27 08:44:58.000000000 -0700
@@ -234,3 +245,6 @@ __enable_execute_stack (void *addr)					
 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
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/gcc/c-pragma.c gcc-sol210/gcc/c-pragma.c
--- gcc-merge-HEAD-csl-sol210-1/gcc/c-pragma.c	2004-09-17 14:54:22.000000000 -0700
+++ gcc-sol210/gcc/c-pragma.c	2004-09-27 08:44:55.000000000 -0700
@@ -627,13 +658,20 @@ handle_pragma_visibility (cpp_reader *du
 
 #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 +679,12 @@ void
 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
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/gcc/c-pragma.h gcc-sol210/gcc/c-pragma.h
--- gcc-merge-HEAD-csl-sol210-1/gcc/c-pragma.h	2004-09-20 19:22:36.000000000 -0700
+++ gcc-sol210/gcc/c-pragma.h	2004-09-27 08:44:55.000000000 -0700
@@ -53,11 +53,13 @@ extern struct cpp_reader* parse_in;
 
 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);
 
--- GCC.orig/gcc/doc/extend.texi	2004-11-05 01:22:46.000000000 +0000
+++ GCC/gcc/doc/extend.texi	2004-11-19 16:36:59.000000000 +0000
@@ -8603,7 +8603,7 @@
 
 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.
 
 @item fini (@var{function} [, @var{function}]...)
 @cindex pragma, fini
--- GCC.orig/gcc/doc/tm.texi	2004-11-18 09:38:16.000000000 +0000
+++ GCC/gcc/doc/tm.texi	2004-11-19 16:56:11.000000000 +0000
@@ -9037,7 +9037,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
@@ -9053,8 +9054,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
 
@@ -9068,7 +9071,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}.
@@ -9132,6 +9138,12 @@
 value.
 @end defmac
 
+@defmac HANDLE_PRAGMA_PACK_WITH_EXPANSION
+Define this macro (to a value of 1), 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).
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/gcc/testsuite/gcc.dg/pragma-align-2.c gcc-sol210/gcc/testsuite/gcc.dg/pragma-align-2.c
--- gcc-merge-HEAD-csl-sol210-1/gcc/testsuite/gcc.dg/pragma-align-2.c	2004-07-25 11:08:52.000000000 -0700
+++ gcc-sol210/gcc/testsuite/gcc.dg/pragma-align-2.c	2004-09-27 08:45:13.000000000 -0700
@@ -11,6 +11,12 @@ void abort (void);
 #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,9 +25,9 @@ void abort (void);
 #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 x1, x2, x4, x8, y8, z8, x16, y16, x32, x64, x128, y128, z128;
 
-#pragma align 16(x)		/* { dg-error "must appear before" } */
+#pragma align 16(y16)
 
 int
 main ()
@@ -41,6 +47,9 @@ main ()
   if (__alignof__ (x16) < 16)
     abort ();
 
+  if (__alignof__ (y16) < 16)
+    abort ();
+
   if (__alignof__ (x32) < 32)
     abort ();
 
@@ -50,5 +59,11 @@ main ()
   if (__alignof__ (x128) < 128)
     abort ();
 
+  if (__alignof__ (y128) < 128)
+    abort ();
+
+  if (__alignof__ (z128) < 128)
+    abort (); 
+
   return 0;
 }
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/gcc/testsuite/gcc.dg/pragma-pack-2.c gcc-sol210/gcc/testsuite/gcc.dg/pragma-pack-2.c
--- gcc-merge-HEAD-csl-sol210-1/gcc/testsuite/gcc.dg/pragma-pack-2.c	1969-12-31 16:00:00.000000000 -0800
+++ gcc-sol210/gcc/testsuite/gcc.dg/pragma-pack-2.c	2004-09-27 08:45:13.000000000 -0700
@@ -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;
+}
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/libcpp/directives.c gcc-sol210/libcpp/directives.c
--- gcc-merge-HEAD-csl-sol210-1/libcpp/directives.c	2004-09-17 17:53:50.000000000 -0700
+++ gcc-sol210/libcpp/directives.c	2004-09-27 08:45:16.000000000 -0700
@@ -45,6 +45,7 @@ struct pragma_entry
   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 @@ static struct pragma_entry *insert_pragm
                                                  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 @@ lookup_pragma_entry (struct pragma_entry
 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 @@ insert_pragma_entry (cpp_reader *pfile, 
       new->u.space = NULL;
     }
 
+  new->allow_expansion = allow_expansion;
   new->is_internal = internal;
   new->next = *chain;
   *chain = new;
@@ -990,12 +992,13 @@ insert_pragma_entry (cpp_reader *pfile, 
 
 /* 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 @@ register_pragma (cpp_reader *pfile, cons
       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 @@ register_pragma (cpp_reader *pfile, cons
 	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 @@ void
 _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,11 @@ do_pragma (cpp_reader *pfile)
 	     numbers in place.  */
 	  if (pfile->cb.line_change)
 	    (*pfile->cb.line_change) (pfile, pragma_token, false);
+	  if (p->allow_expansion)
+	    pfile->state.prevent_expansion--;
 	  (*p->u.handler) (pfile);
+	  if (p->allow_expansion)
+	    pfile->state.prevent_expansion++;
 	}
       else
 	{
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/libcpp/include/cpplib.h gcc-sol210/libcpp/include/cpplib.h
--- gcc-merge-HEAD-csl-sol210-1/libcpp/include/cpplib.h	2004-09-09 12:16:56.000000000 -0700
+++ gcc-sol210/libcpp/include/cpplib.h	2004-09-27 08:45:17.000000000 -0700
@@ -638,7 +638,7 @@ extern unsigned char *cpp_token_as_text 
 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 *);

-- 
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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]