diff gcc/c-pragma.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents 3bfb6c00c1e0
children b7f97abdc517
line wrap: on
line diff
--- a/gcc/c-pragma.c	Sun Feb 07 18:28:00 2010 +0900
+++ b/gcc/c-pragma.c	Fri Feb 12 23:39:51 2010 +0900
@@ -37,14 +37,14 @@
 #include "target.h"
 #include "diagnostic.h"
 #include "opts.h"
+#include "plugin.h"
 
 #define GCC_BAD(gmsgid) \
   do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
 #define GCC_BAD2(gmsgid, arg) \
   do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0)
 
-typedef struct align_stack GTY(())
-{
+typedef struct GTY(()) align_stack {
   int		       alignment;
   tree		       id;
   struct align_stack * prev;
@@ -113,8 +113,8 @@
 	  }
       if (entry == NULL)
 	warning (OPT_Wpragmas, "\
-#pragma pack(pop, %s) encountered without matching #pragma pack(push, %s)"
-		 , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
+#pragma pack(pop, %E) encountered without matching #pragma pack(push, %E)"
+		 , id, id);
     }
 
   entry = alignment_stack->prev;
@@ -180,7 +180,7 @@
       else if (!strcmp (op, "pop"))
 	action = pop;
       else
-	GCC_BAD2 ("unknown action %qs for %<#pragma pack%> - ignored", op);
+	GCC_BAD2 ("unknown action %qE for %<#pragma pack%> - ignored", x);
 
       while ((token = pragma_lex (&x)) == CPP_COMMA)
 	{
@@ -318,7 +318,8 @@
       if (TREE_VALUE (t) == NULL)
 	continue;
 
-      decl = build_decl (FUNCTION_DECL, alias_id, default_function_type);
+      decl = build_decl (UNKNOWN_LOCATION,
+			 FUNCTION_DECL, alias_id, default_function_type);
 
       DECL_ARTIFICIAL (decl) = 1;
       TREE_PUBLIC (decl) = 1;
@@ -423,14 +424,6 @@
   if (t != CPP_EOF)
     warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>");
 
-  if (!flag_mudflap && !targetm.handle_pragma_redefine_extname)
-    {
-      if (warn_unknown_pragmas > in_system_header)
-	warning (OPT_Wunknown_pragmas,
-		 "#pragma redefine_extname not supported on this target");
-      return;
-    }
-
   decl = identifier_global_value (oldname);
   if (decl
       && (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
@@ -593,19 +586,20 @@
 #ifdef HANDLE_PRAGMA_VISIBILITY
 static void handle_pragma_visibility (cpp_reader *);
 
-typedef enum symbol_visibility visibility;
-DEF_VEC_I (visibility);
-DEF_VEC_ALLOC_I (visibility, heap);
-static VEC (visibility, heap) *visstack;
+static VEC (int, heap) *visstack;
 
 /* Push the visibility indicated by STR onto the top of the #pragma
-   visibility stack.  */
+   visibility stack.  KIND is 0 for #pragma GCC visibility, 1 for
+   C++ namespace with visibility attribute and 2 for C++ builtin
+   ABI namespace.  push_visibility/pop_visibility calls must have
+   matching KIND, it is not allowed to push visibility using one
+   KIND and pop using a different one.  */
 
 void
-push_visibility (const char *str)
+push_visibility (const char *str, int kind)
 {
-  VEC_safe_push (visibility, heap, visstack,
-		 default_visibility);
+  VEC_safe_push (int, heap, visstack,
+		 ((int) default_visibility) | (kind << 8));
   if (!strcmp (str, "default"))
     default_visibility = VISIBILITY_DEFAULT;
   else if (!strcmp (str, "internal"))
@@ -619,14 +613,21 @@
   visibility_options.inpragma = 1;
 }
 
-/* Pop a level of the #pragma visibility stack.  */
+/* Pop a level of the #pragma visibility stack.  Return true if
+   successful.  */
 
-void
-pop_visibility (void)
+bool
+pop_visibility (int kind)
 {
-  default_visibility = VEC_pop (visibility, visstack);
+  if (!VEC_length (int, visstack))
+    return false;
+  if ((VEC_last (int, visstack) >> 8) != kind)
+    return false;
+  default_visibility
+    = (enum symbol_visibility) (VEC_pop (int, visstack) & 0xff);
   visibility_options.inpragma
-    = VEC_length (visibility, visstack) != 0;
+    = VEC_length (int, visstack) != 0;
+  return true;
 }
 
 /* Sets the default visibility for symbols to something other than that
@@ -655,10 +656,8 @@
     {
       if (pop == action)
 	{
-	  if (!VEC_length (visibility, visstack))
+	  if (! pop_visibility (0))
 	    GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>");
-	  else
-	    pop_visibility ();
 	}
       else
 	{
@@ -668,7 +667,7 @@
 	  if (token != CPP_NAME)
 	    GCC_BAD ("malformed #pragma GCC visibility push");
 	  else
-	    push_visibility (IDENTIFIER_POINTER (x));
+	    push_visibility (IDENTIFIER_POINTER (x), 0);
 	  if (pragma_lex (&x) != CPP_CLOSE_PAREN)
 	    GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
 	}
@@ -869,8 +868,7 @@
 /* Stack of the #pragma GCC options created with #pragma GCC push_option.  Save
    both the binary representation of the options and the TREE_LIST of
    strings that will be added to the function's attribute list.  */
-typedef struct opt_stack GTY(())
-{
+typedef struct GTY(()) opt_stack {
   struct opt_stack *prev;
   tree target_binary;
   tree target_strings;
@@ -1026,6 +1024,116 @@
     inform (input_location, "#pragma message: %s", TREE_STRING_POINTER (message));
 }
 
+/* Mark whether the current location is valid for a STDC pragma.  */
+
+static bool valid_location_for_stdc_pragma;
+
+void
+mark_valid_location_for_stdc_pragma (bool flag)
+{
+  valid_location_for_stdc_pragma = flag;
+}
+
+/* Return true if the current location is valid for a STDC pragma.  */
+
+bool
+valid_location_for_stdc_pragma_p (void)
+{
+  return valid_location_for_stdc_pragma;
+}
+
+enum pragma_switch_t { PRAGMA_ON, PRAGMA_OFF, PRAGMA_DEFAULT, PRAGMA_BAD };
+
+/* A STDC pragma must appear outside of external declarations or
+   preceding all explicit declarations and statements inside a compound
+   statement; its behavior is undefined if used in any other context.
+   It takes a switch of ON, OFF, or DEFAULT.  */
+
+static enum pragma_switch_t
+handle_stdc_pragma (const char *pname)
+{
+  const char *arg;
+  tree t;
+  enum pragma_switch_t ret;
+
+  if (!valid_location_for_stdc_pragma_p ())
+    {
+      warning (OPT_Wpragmas, "invalid location for %<pragma %s%>, ignored",
+	       pname);
+      return PRAGMA_BAD;
+    }
+
+  if (pragma_lex (&t) != CPP_NAME)
+    {
+      warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
+      return PRAGMA_BAD;
+    }
+
+  arg = IDENTIFIER_POINTER (t);
+
+  if (!strcmp (arg, "ON"))
+    ret = PRAGMA_ON;
+  else if (!strcmp (arg, "OFF"))
+    ret = PRAGMA_OFF;
+  else if (!strcmp (arg, "DEFAULT"))
+    ret = PRAGMA_DEFAULT;
+  else
+    {
+      warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
+      return PRAGMA_BAD;
+    }
+
+  if (pragma_lex (&t) != CPP_EOF)
+    {
+      warning (OPT_Wpragmas, "junk at end of %<#pragma %s%>", pname);
+      return PRAGMA_BAD;
+    }
+
+  return ret;
+}
+
+/* #pragma STDC FLOAT_CONST_DECIMAL64 ON
+   #pragma STDC FLOAT_CONST_DECIMAL64 OFF
+   #pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT */
+
+static void
+handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy))
+{
+  if (c_dialect_cxx ())
+    {
+      if (warn_unknown_pragmas > in_system_header)
+	warning (OPT_Wunknown_pragmas,
+		 "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
+		 " for C++");
+      return;
+    }
+
+  if (!targetm.decimal_float_supported_p ())
+    {
+      if (warn_unknown_pragmas > in_system_header)
+	warning (OPT_Wunknown_pragmas,
+		 "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
+		 " on this target");
+      return;
+    }
+
+  pedwarn (input_location, OPT_pedantic,
+	   "ISO C does not support %<#pragma STDC FLOAT_CONST_DECIMAL64%>");
+
+  switch (handle_stdc_pragma ("STDC FLOAT_CONST_DECIMAL64"))
+    {
+    case PRAGMA_ON:
+      set_float_const_decimal64 ();
+      break;
+    case PRAGMA_OFF:
+    case PRAGMA_DEFAULT:
+      clear_float_const_decimal64 ();
+      break;
+    case PRAGMA_BAD:
+      break;
+    }
+}
+
 /* A vector of registered pragma callbacks.  */
 
 DEF_VEC_O (pragma_handler);
@@ -1190,6 +1298,9 @@
   c_register_pragma ("GCC", "pop_options", handle_pragma_pop_options);
   c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options);
 
+  c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
+		     handle_pragma_float_const_decimal64);
+
   c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
   c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
 
@@ -1198,6 +1309,9 @@
 #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"