summaryrefslogtreecommitdiff
path: root/gcc/c-pragma.c
diff options
context:
space:
mode:
authorgiovannibajo <giovannibajo@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-25 22:52:22 +0000
committergiovannibajo <giovannibajo@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-25 22:52:22 +0000
commitb212f3783a23a6c9fb18ffb450223e7117ab9c55 (patch)
treef9985edc87f0241509ea6f38be708082bb83209a /gcc/c-pragma.c
parent4fd61bc65be58c3ae6a337331a66569609fa24fc (diff)
downloadgcc-b212f3783a23a6c9fb18ffb450223e7117ab9c55.tar.gz
PR c++/9283
PR c++/15000 * c-common.c (c_common_attribute_table): Allow handle_visibility_attribute to be called for types. (handle_visibility_attribute) When given a type, set the visibility bits on the TYPE_NAME. When given a decl, don't set no_add_attrs so that we can check later whether the attribute was present. Added warning if attribute applied to non class type. * c-decl.c (diagnose_mismatched_decls): Updated rules for merging decls and checking that they are consistent. * common.opt: Added -fvisibility. * c.opt, c-opts.c: Added -fvisibility-inlines-hidden. * c-pragma.h, c-pragma.c: Added handle_pragma_visibility(). * flags.h, tree.h: Added assorted support defines for overall patch * opts.c: Added parsing support for -fvisibility. * tree.c (build_decl): Set visibility for all decls to be whatever is in force at that time. * varasm.c (default_binds_local_p_1): Reworked logic determining when to make a symbol locally bound. * doc/invoke.texi: Added documentation for -fvisibility and -fvisibility-inlines-hidden. PR c++/15000 PR c++/9283 * class.c (check_field_decls): Apply hidden visibility if -fvisibility-inlines-hidden and inlined unless otherwise specified (build_vtable): Set vtable visibility to class visibility. (check_field_decls): Default static member visibility to class visibility. (check_methods): Default method visibility to class visibility. * cp-tree.h: Added CLASSTYPE_VISIBILITY and CLASSTYPE_VISIBILITY_SPECIFIED macro. * decl.c (duplicate_decls): New logic for merging definition decls with declaration decls. Added ignore & warning when non default applied to global operator new or delete. * method.c, optimize.c, rtti.c: Added setting of VISIBILITY_SPECIFIED wherever VISIBILITY was changed * rtti.c (get_tinfo_decl): Set typeinfo visibility to class visibility. (tinfo_base_init): Set typeinfo name visibility to class visibility. PR c++/9283 PR c++/15000 * gcc.dg/visibility-9.c, gcc.dg/visibility-a.c: New tests. * g++.dg/ext/visibility/: New directory. * g++.dg/ext/visibility-1.C, g++.dg/ext/visibility-2.C g++.dg/ext/visibility-3.C, g++.dg/ext/visibility-4.C, g++.dg/ext/visibility-5.C, g++.dg/ext/visibility-6.C, g++.dg/ext/visibility-7.C: Move to g++.dg/ext/visibility/. * g++.dg/ext/visibility/fvisibility.C, g++.dg/ext/visibility/fvisibility-inlines-hidden.C, g++.dg/ext/visibility/fvisibility-override1.C g++.dg/ext/visibility/fvisibility-override2.C g++.dg/ext/visibility/memfuncts.C g++.dg/ext/visibility/noPLT.C g++.dg/ext/visibility/pragma.C g++.dg/ext/visibility/pragma-override1.C g++.dg/ext/visibility/pragma-override2.C g++.dg/ext/visibility/staticmemfuncts.C g++.dg/ext/visibility/virtual.C: New tests. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85167 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-pragma.c')
-rw-r--r--gcc/c-pragma.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c
index 563e2d7abdc..0bf2f1231bc 100644
--- a/gcc/c-pragma.c
+++ b/gcc/c-pragma.c
@@ -566,6 +566,86 @@ maybe_apply_renaming_pragma (tree decl, tree asmname)
return 0;
}
+
+#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 wrapper for pragma registration to avoid dragging
cpplib.h in almost everywhere. */
void
@@ -585,6 +665,9 @@ init_pragma (void)
#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);