+
+
+#ifdef HANDLE_PRAGMA_VISIBILITY
+static void handle_pragma_visibility (cpp_reader *);
+
+/* Sets the default visibility for symbols to something other than that
+ 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;
+ tree x;
+ enum cpp_ttype token;
+ enum { bad, push, pop } action = bad;
+
+ token = c_lex (&x);
+ if (token == CPP_NAME)
+ {
+ const char *op = IDENTIFIER_POINTER (x);
+ if (!strcmp (op, "push"))
+ action = push;
+ else if (!strcmp (op, "pop"))
+ action = pop;
+ }
+ if (bad == action)
+ GCC_BAD ("#pragma GCC visibility must be followed by push or pop");
+ else
+ {
+ if (pop == action)
+ {
+ if (!visidx)
+ {
+ GCC_BAD ("No matching push for %<#pragma GCC visibility pop%>");
+ }
+ else
+ {
+ default_visibility = visstack[--visidx];
+ visibility_options.inpragma = (visidx>0);
+ }
+ }
+ else
+ {
+ if (c_lex (&x) != CPP_OPEN_PAREN)
+ GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
+ token = c_lex (&x);
+ if (token != CPP_NAME)
+ {
+ GCC_BAD ("malformed #pragma GCC visibility push");
+ }
+ else if (visidx >= 16)
+ {
+ GCC_BAD ("No more than sixteen #pragma GCC visibility pushes allowed at once");
+ }
+ else
+ {
+ const char *str = IDENTIFIER_POINTER (x);
+ visstack[visidx++] = default_visibility;
+ if (!strcmp (str, "default"))
+ default_visibility = VISIBILITY_DEFAULT;
+ else if (!strcmp (str, "internal"))
+ default_visibility = VISIBILITY_INTERNAL;
+ else if (!strcmp (str, "hidden"))
+ default_visibility = VISIBILITY_HIDDEN;
+ else if (!strcmp (str, "protected"))
+ default_visibility = VISIBILITY_PROTECTED;
+ else
+ {
+ GCC_BAD ("#pragma GCC visibility push() must specify default, internal, hidden or protected");
+ }
+ visibility_options.inpragma = 1;
+ }
+ if (c_lex (&x) != CPP_CLOSE_PAREN)
+ GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
+ }
+ }
+ if (c_lex (&x) != CPP_EOF)
+ warning ("junk at end of %<#pragma GCC visibility%>");
+}
+
+#endif
+
+/* 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, 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. */
+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
+#ifdef HANDLE_PRAGMA_VISIBILITY
+ c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
+#endif
+
+ c_register_pragma (0, "redefine_extname", handle_pragma_redefine_extname);
+ c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
+
+ c_register_pragma ("GCC", "pch_preprocess", c_common_pch_pragma);
+
+#ifdef REGISTER_TARGET_PRAGMAS
+ REGISTER_TARGET_PRAGMAS ();
+#endif
+}
+
+#include "gt-c-pragma.h"