OSDN Git Service

* tree.c (build_common_builtin_nodes): Always clear TREE_NOTHROW on
[pf3gnuchains/gcc-fork.git] / gcc / c-pragma.c
index f281644..1fc006c 100644 (file)
@@ -24,19 +24,23 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "rtl.h"
 #include "tree.h"
-#include "function.h"
+#include "function.h"          /* For cfun.  FIXME: Does the parser know
+                                  when it is inside a function, so that
+                                  we don't have to look at cfun?  */
 #include "cpplib.h"
 #include "c-pragma.h"
 #include "flags.h"
 #include "toplev.h"
-#include "ggc.h"
 #include "c-common.h"
 #include "output.h"
-#include "tm_p.h"
+#include "tm_p.h"              /* For REGISTER_TARGET_PRAGMAS (why is
+                                  this not a target hook?).  */
 #include "vec.h"
+#include "vecprim.h"
 #include "target.h"
 #include "diagnostic.h"
 #include "opts.h"
+#include "plugin.h"
 
 #define GCC_BAD(gmsgid) \
   do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
@@ -243,145 +247,16 @@ handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
 }
 #endif  /* HANDLE_PRAGMA_PACK */
 
-struct GTY(()) def_pragma_macro_value {
-  struct def_pragma_macro_value *prev;
-  cpp_macro *value;
-};
-
-struct GTY(()) def_pragma_macro {
-  hashval_t hash;
-  const char *name;
-  struct def_pragma_macro_value value;
-};
-
-static GTY((param_is (struct def_pragma_macro))) htab_t pushed_macro_table;
-
-#ifdef HANDLE_PRAGMA_PUSH_POP_MACRO
-/* Hash table control functions for pushed_macro_table.  */
-static hashval_t
-dpm_hash (const void *p)
+typedef struct GTY(()) pending_weak_d
 {
-  return ((const struct def_pragma_macro *)p)->hash;
-}
+  tree name;
+  tree value;
+} pending_weak;
 
-static int
-dpm_eq (const void *pa, const void *pb)
-{
-  const struct def_pragma_macro *const a = (const struct def_pragma_macro *) pa,
-    *const b = (const struct def_pragma_macro *) pb;
-  return a->hash == b->hash && strcmp (a->name, b->name) == 0;
-}
-
-/* #pragma push_macro("MACRO_NAME")
-   #pragma pop_macro("MACRO_NAME") */
-
-static void
-handle_pragma_push_macro (cpp_reader *reader)
-{
-  tree x, id = 0;
-  enum cpp_ttype token;
-  struct def_pragma_macro dummy, *c;
-  const char *macroname;
-  void **slot;
-
-  if (pragma_lex (&x) != CPP_OPEN_PAREN)
-    GCC_BAD ("missing %<(%> after %<#pragma push_macro%> - ignored");
+DEF_VEC_O(pending_weak);
+DEF_VEC_ALLOC_O(pending_weak,gc);
 
-  token = pragma_lex (&id);
-
-  /* Silently ignore */
-  if (token == CPP_CLOSE_PAREN)
-    return;
-  if (token != CPP_STRING)
-    GCC_BAD ("invalid constant in %<#pragma push_macro%> - ignored");
-
-  if (pragma_lex (&x) != CPP_CLOSE_PAREN)
-    GCC_BAD ("missing %<)%> after %<#pragma push_macro%> - ignored");
-
-  if (pragma_lex (&x) != CPP_EOF)
-    warning (OPT_Wpragmas, "junk at end of %<#pragma push_macro%>");
-
-  /* Check for empty string, and silently ignore.  */
-  if (TREE_STRING_LENGTH (id) < 1)
-    return;
-  macroname = TREE_STRING_POINTER (id);
-
-  if (pushed_macro_table == NULL)
-    pushed_macro_table = htab_create_ggc (15, dpm_hash, dpm_eq, 0);
-
-  dummy.hash = htab_hash_string (macroname);
-  dummy.name = macroname;
-  slot = htab_find_slot_with_hash (pushed_macro_table, &dummy,
-                                  dummy.hash, INSERT);
-  c = (struct def_pragma_macro *) *slot;
-  if (c == NULL)
-    {
-      *slot = c = GGC_NEW (struct def_pragma_macro);
-      c->hash = dummy.hash;
-      c->name = ggc_alloc_string (macroname, TREE_STRING_LENGTH (id) - 1);
-      c->value.prev = NULL;
-    }
-  else
-    {
-      struct def_pragma_macro_value *v;
-      v = GGC_NEW (struct def_pragma_macro_value);
-      *v = c->value;
-      c->value.prev = v;
-    }
-
-  c->value.value = cpp_push_definition (reader, macroname);
-}
-
-static void
-handle_pragma_pop_macro (cpp_reader *reader)
-{
-  tree x, id = 0;
-  enum cpp_ttype token;
-  struct def_pragma_macro dummy, *c;
-  const char *macroname;
-  void **slot = NULL;
-
-  if (pragma_lex (&x) != CPP_OPEN_PAREN)
-    GCC_BAD ("missing %<(%> after %<#pragma pop_macro%> - ignored");
-
-  token = pragma_lex (&id);
-
-  /* Silently ignore */
-  if (token == CPP_CLOSE_PAREN)
-    return;
-  if (token != CPP_STRING)
-    GCC_BAD ("invalid constant in %<#pragma pop_macro%> - ignored");
-
-  if (pragma_lex (&x) != CPP_CLOSE_PAREN)
-    GCC_BAD ("missing %<)%> after %<#pragma pop_macro%> - ignored");
-
-  if (pragma_lex (&x) != CPP_EOF)
-    warning (OPT_Wpragmas, "junk at end of %<#pragma pop_macro%>");
-
-  /* Check for empty string, and silently ignore.  */
-  if (TREE_STRING_LENGTH (id) < 1)
-    return;
-  macroname = TREE_STRING_POINTER (id);
-
-  dummy.hash = htab_hash_string (macroname);
-  dummy.name = macroname;
-  if (pushed_macro_table)
-    slot = htab_find_slot_with_hash (pushed_macro_table, &dummy,
-                                    dummy.hash, NO_INSERT);
-  if (slot == NULL)
-    return;
-  c = (struct def_pragma_macro *) *slot;
-
-  cpp_pop_definition (reader, c->name, c->value.value);
-
-  if (c->value.prev)
-    c->value = *c->value.prev;
-  else
-    htab_clear_slot (pushed_macro_table, slot);
-}
-#endif /* HANDLE_PRAGMA_PUSH_POP_MACRO */
-
-static GTY(()) tree pending_weaks;
+static GTY(()) VEC(pending_weak,gc) *pending_weaks;
 
 #ifdef HANDLE_PRAGMA_WEAK
 static void apply_pragma_weak (tree, tree);
@@ -411,7 +286,9 @@ apply_pragma_weak (tree decl, tree value)
 void
 maybe_apply_pragma_weak (tree decl)
 {
-  tree *p, t, id;
+  tree id;
+  int i;
+  pending_weak *pe;
 
   /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed.  */
 
@@ -430,11 +307,11 @@ maybe_apply_pragma_weak (tree decl)
 
   id = DECL_ASSEMBLER_NAME (decl);
 
-  for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t))
-    if (id == TREE_PURPOSE (t))
+  for (i = 0; VEC_iterate (pending_weak, pending_weaks, i, pe); i++)
+    if (id == pe->name)
       {
-       apply_pragma_weak (decl, TREE_VALUE (t));
-       *p = TREE_CHAIN (t);
+       apply_pragma_weak (decl, pe->value);
+       VEC_unordered_remove (pending_weak, pending_weaks, i);
        break;
       }
 }
@@ -444,15 +321,16 @@ maybe_apply_pragma_weak (tree decl)
 void
 maybe_apply_pending_pragma_weaks (void)
 {
-  tree *p, t, alias_id, id, decl, *next;
+  tree alias_id, id, decl;
+  int i;
+  pending_weak *pe;
 
-  for (p = &pending_weaks; (t = *p) ; p = next)
+  for (i = 0; VEC_iterate (pending_weak, pending_weaks, i, pe); i++)
     {
-      next = &TREE_CHAIN (t);
-      alias_id = TREE_PURPOSE (t);
-      id = TREE_VALUE (t);
+      alias_id = pe->name;
+      id = pe->value;
 
-      if (TREE_VALUE (t) == NULL)
+      if (id == NULL)
        continue;
 
       decl = build_decl (UNKNOWN_LOCATION,
@@ -496,7 +374,12 @@ handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy))
        assemble_alias (decl, value);
     }
   else
-    pending_weaks = tree_cons (name, value, pending_weaks);
+    {
+      pending_weak *pe;
+      pe = VEC_safe_push (pending_weak, gc, pending_weaks, NULL);
+      pe->name = name;
+      pe->value = value;
+    }
 }
 #else
 void
@@ -1421,10 +1304,6 @@ init_pragma (void)
   c_register_pragma (0, "pack", handle_pragma_pack);
 #endif
 #endif
-#ifdef HANDLE_PRAGMA_PUSH_POP_MACRO
-  c_register_pragma (0 ,"push_macro", handle_pragma_push_macro);
-  c_register_pragma (0 ,"pop_macro", handle_pragma_pop_macro);
-#endif
 #ifdef HANDLE_PRAGMA_WEAK
   c_register_pragma (0, "weak", handle_pragma_weak);
 #endif
@@ -1450,6 +1329,9 @@ init_pragma (void)
 #ifdef REGISTER_TARGET_PRAGMAS
   REGISTER_TARGET_PRAGMAS ();
 #endif
+
+  /* Allow plugins to register their own pragmas. */
+  invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL);
 }
 
 #include "gt-c-pragma.h"