summaryrefslogtreecommitdiff
path: root/gcc/c-pragma.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2002-03-22 22:51:48 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2002-03-22 22:51:48 +0000
commitea42c4de227309f4db936eae29f35e7b20a7353e (patch)
treeef58fdf21cd2d5af8fcc1fdca3da41897a87502f /gcc/c-pragma.c
parent92ec37e132679f46e77d77ea490053326041ccc9 (diff)
downloadgcc-ea42c4de227309f4db936eae29f35e7b20a7353e.tar.gz
* c-pragma.c (maybe_apply_renaming_pragma): New.
(handle_pragma_redefine_extname, pending_redefine_extname): New. (handle_pragma_extern_prefix, pragma_extern_prefix): New. (init_pragma): Register them. * c-pragma.h (maybe_apply_renaming_pragma): Declare. * c-decl.c (finish_decl): Call it. * cp/decl.c (cp_finish_decl): Likewise. * doc/extend.texi: Document the new pragmas. * config/alpha/osf.h (CPP_SUBTARGET_SPEC): Add __EXTERN_PREFIX. (HANDLE_PRAGMA_EXTERN_PREFIX): New. * config/i386/sol2.h (CPP_PREDEFINES): Add __PRAGMA_REDEFINE_EXTNAME. (HANDLE_PRAGMA_REDEFINE_EXTNAME): New. * config/sparc/sol2.h: Likewise. * g++.dg/other/pragma-re-1.C: New. * g++.dg/other/pragma-ep-1.C: New. * gcc.dg/pragma-re-1.c, gcc.dg/pragma-re-2.c: New. * gcc.dg/pragma-ep-1.c, gcc.dg/pragma-ep-2.c: New. * gcc.dg/pragma-ep-3.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@51200 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-pragma.c')
-rw-r--r--gcc/c-pragma.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c
index 1a17e67f1c5..4bf7ce205ac 100644
--- a/gcc/c-pragma.c
+++ b/gcc/c-pragma.c
@@ -351,6 +351,135 @@ maybe_apply_pragma_weak (decl)
}
#endif /* HANDLE_PRAGMA_WEAK */
+#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
+static void handle_pragma_redefine_extname PARAMS ((cpp_reader *));
+
+static tree pending_redefine_extname;
+
+/* #pragma redefined_extname oldname newname */
+static void
+handle_pragma_redefine_extname (dummy)
+ cpp_reader *dummy ATTRIBUTE_UNUSED;
+{
+ tree oldname, newname, decl, x;
+ enum cpp_ttype t;
+
+ if (c_lex (&oldname) != CPP_NAME)
+ {
+ warning ("malformed #pragma redefine_extname, ignored");
+ return;
+ }
+ if (c_lex (&newname) != CPP_NAME)
+ {
+ warning ("malformed #pragma redefine_extname, ignored");
+ return;
+ }
+ t = c_lex (&x);
+ if (t != CPP_EOF)
+ warning ("junk at end of #pragma redefine_extname");
+
+ decl = identifier_global_value (oldname);
+ if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+ {
+ if (DECL_ASSEMBLER_NAME_SET_P (decl)
+ && DECL_ASSEMBLER_NAME (decl) != newname)
+ warning ("#pragma redefine_extname conflicts with declaration");
+ SET_DECL_ASSEMBLER_NAME (decl, newname);
+ }
+ else
+ pending_redefine_extname
+ = tree_cons (oldname, newname, pending_redefine_extname);
+}
+#endif
+
+#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
+static void handle_pragma_extern_prefix PARAMS ((cpp_reader *));
+
+static tree pragma_extern_prefix;
+
+/* #pragma extern_prefix "prefix" */
+static void
+handle_pragma_extern_prefix (dummy)
+ cpp_reader *dummy ATTRIBUTE_UNUSED;
+{
+ tree prefix, x;
+ enum cpp_ttype t;
+
+ if (c_lex (&prefix) != CPP_STRING)
+ {
+ warning ("malformed #pragma extern_prefix, ignored");
+ return;
+ }
+ t = c_lex (&x);
+ if (t != CPP_EOF)
+ warning ("junk at end of #pragma extern_prefix");
+
+ /* Note that the length includes the null terminator. */
+ pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL);
+}
+#endif
+
+/* Hook from the front ends to apply the results of one of the preceeding
+ pragmas that rename variables. */
+
+tree
+maybe_apply_renaming_pragma (decl, asmname)
+ tree decl, asmname;
+{
+ tree oldname;
+
+ /* Copied from the check in set_decl_assembler_name. */
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ || (TREE_CODE (decl) == VAR_DECL
+ && (TREE_STATIC (decl)
+ || DECL_EXTERNAL (decl)
+ || TREE_PUBLIC (decl))))
+ oldname = DECL_ASSEMBLER_NAME (decl);
+ else
+ return asmname;
+
+ /* If the name begins with a *, that's a sign of an asmname attached to
+ a previous declaration. */
+ if (IDENTIFIER_POINTER (oldname)[0] == '*')
+ {
+ const char *oldasmname = IDENTIFIER_POINTER (oldname) + 1;
+ if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldasmname) != 0)
+ warning ("asm declaration conficts with previous rename");
+ asmname = build_string (strlen (oldasmname), oldasmname);
+ }
+
+#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
+ {
+ tree *p, t;
+
+ for (p = &pending_redefine_extname; (t = *p) ; p = &TREE_CHAIN (t))
+ if (oldname == TREE_PURPOSE (t))
+ {
+ const char *newname = IDENTIFIER_POINTER (TREE_VALUE (t));
+
+ if (asmname && strcmp (TREE_STRING_POINTER (asmname), newname) != 0)
+ warning ("#pragma redefine_extname conflicts with declaration");
+ *p = TREE_CHAIN (t);
+
+ return build_string (strlen (newname), newname);
+ }
+ }
+#endif
+
+#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
+ if (pragma_extern_prefix && !asmname)
+ {
+ char *x = concat (TREE_STRING_POINTER (pragma_extern_prefix),
+ IDENTIFIER_POINTER (oldname), NULL);
+ asmname = build_string (strlen (x), x);
+ free (x);
+ return asmname;
+ }
+#endif
+
+ return asmname;
+}
+
void
init_pragma ()
{
@@ -361,6 +490,17 @@ init_pragma ()
cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
ggc_add_tree_root (&pending_weaks, 1);
#endif
+#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
+ cpp_register_pragma (parse_in, 0, "redefine_extname",
+ handle_pragma_redefine_extname);
+ ggc_add_tree_root (&pending_redefine_extname, 1);
+#endif
+#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
+ cpp_register_pragma (parse_in, 0, "extern_prefix",
+ handle_pragma_extern_prefix);
+ ggc_add_tree_root (&pragma_extern_prefix, 1);
+#endif
+
#ifdef REGISTER_TARGET_PRAGMAS
REGISTER_TARGET_PRAGMAS (parse_in);
#endif