PATCH: Support nested visibility push

H. J. Lu hjl@lucon.org
Thu Mar 3 17:46:00 GMT 2005


When

#pragma GCC visibility push(default)
#pragma GCC visibility pop

are used for header file wrappers, we may have more 16

#pragma GCC visibility push(default)

Currently gcc will fail. This patch tries to support nested visibility
push of the same visibility.


H.J.
---
2005-03-03  H.J. Lu  <hongjiu.lu@intel.com>

	* c-pragma.c (handle_pragma_visibility): Support nested push
	of the same visibility.

--- gcc/c-pragma.c.stack	2005-03-02 09:34:04.000000000 -0800
+++ gcc/c-pragma.c	2005-03-03 09:38:53.601409596 -0800
@@ -489,8 +489,18 @@ static void handle_pragma_visibility (cp
    specified on the command line.  */
 static void
 handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
-{ /* Form is #pragma GCC visibility push(hidden)|pop */
-  static int visstack [16], visidx;
+{
+  /* Form is #pragma GCC visibility push(hidden)|pop */
+  static int visidx;
+  static struct
+    {
+      enum symbol_visibility value;
+      unsigned int count;
+    } visstack [16];
+#define VISSTACK_EMPTY(vs, idx) (!idx && !vs [idx].count)
+#define VISSTACK_FULL(vs, idx, v) \
+  ((size_t) idx >= sizeof (vs)/sizeof (vs[0]) \
+   && (vs [idx].value != v || vs [idx].count == (unsigned int) -1))
   tree x;
   enum cpp_ttype token;
   enum { bad, push, pop } action = bad;
@@ -510,14 +520,17 @@ handle_pragma_visibility (cpp_reader *du
     {
       if (pop == action)
         {
-          if (!visidx)
+          if (VISSTACK_EMPTY (visstack, visidx))
             {
               GCC_BAD ("No matching push for '#pragma GCC visibility pop'");
             }
           else
             {
-              default_visibility = visstack[--visidx];
-              visibility_options.inpragma = (visidx>0);
+              default_visibility = visstack[visidx].value;
+	      if (--visstack [visidx].count == 0 && visidx != 0)
+		visidx--;
+              visibility_options.inpragma
+		= !VISSTACK_EMPTY (visstack, visidx);
             }
         }
       else
@@ -529,14 +542,18 @@ handle_pragma_visibility (cpp_reader *du
             {
               GCC_BAD ("malformed #pragma GCC visibility push");
             }
-          else if (visidx >= 16)
+          else if (VISSTACK_FULL (visstack, visidx, default_visibility))
             {
-              GCC_BAD ("No more than sixteen #pragma GCC visibility pushes allowed at once");
+              GCC_BAD ("Too many #pragma GCC visibility pushed at once");
             }
           else
             {
               const char *str = IDENTIFIER_POINTER (x);
-              visstack[visidx++] = default_visibility;
+	      if (VISSTACK_EMPTY (visstack, visidx))
+		visstack[visidx].value = default_visibility;
+	      else if (visstack[visidx].value != default_visibility)
+		visstack[++visidx].value = default_visibility;
+	      visstack[visidx].count++;
               if (!strcmp (str, "default"))
                 default_visibility = VISIBILITY_DEFAULT;
               else if (!strcmp (str, "internal"))



More information about the Gcc-patches mailing list