OSDN Git Service

* configure.ac (glibc_header_dir): Set using with_build_sysroot if
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index f669a47..fd5b065 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -62,12 +62,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "langhooks-def.h"
 #include "pointer-set.h"
 
-/* Set this to 1 if you want the standard ISO C99 semantics of 'inline'
-   when you specify -std=c99 or -std=gnu99, and to 0 if you want
-   behaviour compatible with the nonstandard semantics implemented by
-   GCC 2.95 through 4.2.  */
-#define WANT_C99_INLINE_SEMANTICS 1
-
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
 { NORMAL,                      /* Ordinary declaration */
@@ -411,11 +405,6 @@ static bool keep_next_level_flag;
 
 static bool next_is_function_body;
 
-/* Functions called automatically at the beginning and end of execution.  */
-
-static GTY(()) tree static_ctors;
-static GTY(()) tree static_dtors;
-
 /* Forward declarations.  */
 static tree lookup_name_in_scope (tree, struct c_scope *);
 static tree c_make_fname_decl (tree, int);
@@ -761,13 +750,9 @@ pop_scope (void)
              error ("label %q+D used but not defined", p);
              DECL_INITIAL (p) = error_mark_node;
            }
-         else if (!TREE_USED (p) && warn_unused_label)
-           {
-             if (DECL_INITIAL (p))
-               warning (0, "label %q+D defined but not used", p);
-             else
-               warning (0, "label %q+D declared but not defined", p);
-           }
+         else 
+           warn_for_unused_label (p);
+
          /* Labels go in BLOCK_VARS.  */
          TREE_CHAIN (p) = BLOCK_VARS (block);
          BLOCK_VARS (block) = p;
@@ -812,7 +797,7 @@ pop_scope (void)
          else if (DECL_DECLARED_INLINE_P (p)
                   && TREE_PUBLIC (p)
                   && !DECL_INITIAL (p)
-                  && flag_isoc99)
+                  && !flag_gnu89_inline)
            pedwarn ("inline function %q+D declared but never defined", p);
 
          goto common_symbol;
@@ -1339,15 +1324,13 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
                 unit.  */
              if ((!DECL_EXTERN_INLINE (olddecl)
                   || DECL_EXTERN_INLINE (newdecl)
-#if WANT_C99_INLINE_SEMANTICS
-                  || (flag_isoc99
+                  || (!flag_gnu89_inline
                       && (!DECL_DECLARED_INLINE_P (olddecl)
                           || !lookup_attribute ("gnu_inline",
                                                 DECL_ATTRIBUTES (olddecl)))
                       && (!DECL_DECLARED_INLINE_P (newdecl)
                           || !lookup_attribute ("gnu_inline",
                                                 DECL_ATTRIBUTES (newdecl))))
-#endif /* WANT_C99_INLINE_SEMANTICS */
                  )
                  && same_translation_unit_p (newdecl, olddecl))
                {
@@ -1562,7 +1545,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
         we still shouldn't warn.)  */
       if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl)
          && same_translation_unit_p (olddecl, newdecl)
-         && ! flag_isoc99)
+         && flag_gnu89_inline)
        {
          if (TREE_USED (olddecl))
            {
@@ -1707,11 +1690,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
     TREE_READONLY (olddecl) = 1;
 
   if (TREE_THIS_VOLATILE (newdecl))
-    {
-      TREE_THIS_VOLATILE (olddecl) = 1;
-      if (TREE_CODE (newdecl) == VAR_DECL)
-       make_var_volatile (newdecl);
-    }
+    TREE_THIS_VOLATILE (olddecl) = 1;
 
   /* Merge deprecatedness.  */
   if (TREE_DEPRECATED (newdecl))
@@ -1792,12 +1771,11 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
        }
     }
 
-#if WANT_C99_INLINE_SEMANTICS
   /* In c99, 'extern' declaration before (or after) 'inline' means this
      function is not DECL_EXTERNAL, unless 'gnu_inline' attribute
      is present.  */
   if (TREE_CODE (newdecl) == FUNCTION_DECL
-      && flag_isoc99
+      && !flag_gnu89_inline
       && (DECL_DECLARED_INLINE_P (newdecl)
          || DECL_DECLARED_INLINE_P (olddecl))
       && (!DECL_DECLARED_INLINE_P (newdecl)
@@ -1806,7 +1784,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
       && DECL_EXTERNAL (newdecl)
       && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (newdecl)))
     DECL_EXTERNAL (newdecl) = 0;
-#endif /* WANT_C99_INLINE_SEMANTICS */
 
   if (DECL_EXTERNAL (newdecl))
     {
@@ -2380,18 +2357,16 @@ pushdecl_top_level (tree x)
 static void
 implicit_decl_warning (tree id, tree olddecl)
 {
-  void (*diag) (const char *, ...) ATTRIBUTE_GCC_CDIAG(1,2);
-  switch (mesg_implicit_function_declaration)
+  if (warn_implicit_function_declaration)
     {
-    case 0: return;
-    case 1: diag = warning0; break;
-    case 2: diag = error;   break;
-    default: gcc_unreachable ();
+      if (flag_isoc99)
+       pedwarn (G_("implicit declaration of function %qE"), id);
+      else 
+       warning (OPT_Wimplicit_function_declaration, 
+                G_("implicit declaration of function %qE"), id);
+      if (olddecl)
+       locate_old_decl (olddecl, inform);
     }
-
-  diag (G_("implicit declaration of function %qE"), id);
-  if (olddecl)
-    locate_old_decl (olddecl, diag);
 }
 
 /* Generate an implicit declaration for identifier FUNCTIONID as a
@@ -3320,10 +3295,9 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
   /* Set attributes here so if duplicate decl, will have proper attributes.  */
   decl_attributes (&decl, attributes, 0);
 
-#if WANT_C99_INLINE_SEMANTICS
   /* Handle gnu_inline attribute.  */
   if (declspecs->inline_p
-      && flag_isoc99
+      && !flag_gnu89_inline
       && TREE_CODE (decl) == FUNCTION_DECL
       && lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl)))
     {
@@ -3332,7 +3306,6 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
       else if (declspecs->storage_class != csc_static)
        DECL_EXTERNAL (decl) = !DECL_EXTERNAL (decl);
     }
-#endif /* WANT_C99_INLINE_SEMANTICS */
 
   if (TREE_CODE (decl) == FUNCTION_DECL
       && targetm.calls.promote_prototypes (TREE_TYPE (decl)))
@@ -4771,6 +4744,8 @@ grokdeclarator (const struct c_declarator *declarator,
        type = c_build_qualified_type (type, type_quals);
        decl = build_decl (FIELD_DECL, declarator->u.id, type);
        DECL_NONADDRESSABLE_P (decl) = bitfield;
+       if (bitfield && !declarator->u.id)
+         TREE_NO_WARNING (decl) = 1;
 
        if (size_varies)
          C_DECL_VARIABLE_SIZE (decl) = 1;
@@ -4830,11 +4805,8 @@ grokdeclarator (const struct c_declarator *declarator,
           in this file, C99 6.7.4p6.  In GNU C89, a function declared
           'extern inline' is an external reference.  */
        else if (declspecs->inline_p && storage_class != csc_static)
-#if WANT_C99_INLINE_SEMANTICS
-         DECL_EXTERNAL (decl) = (storage_class == csc_extern) == !flag_isoc99;
-#else
-         DECL_EXTERNAL (decl) = (storage_class == csc_extern);
-#endif
+         DECL_EXTERNAL (decl) = ((storage_class == csc_extern)
+                                 == flag_gnu89_inline);
        else
          DECL_EXTERNAL (decl) = !initialized;
 
@@ -4931,14 +4903,7 @@ grokdeclarator (const struct c_declarator *declarator,
          }
 
        if (threadp)
-         {
-           if (targetm.have_tls)
-             DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
-           else
-             /* A mere warning is sure to result in improper semantics
-                at runtime.  Don't bother to allow this to compile.  */
-             error ("thread-local storage not supported for this target");
-         }
+         DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
       }
 
     if (storage_class == csc_extern
@@ -6103,17 +6068,15 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
     warning (OPT_Wattributes, "inline function %q+D given attribute noinline",
             decl1);
 
-#if WANT_C99_INLINE_SEMANTICS
   /* Handle gnu_inline attribute.  */
   if (declspecs->inline_p
-      && flag_isoc99
+      && !flag_gnu89_inline
       && TREE_CODE (decl1) == FUNCTION_DECL
       && lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl1)))
     {
       if (declspecs->storage_class != csc_static)
        DECL_EXTERNAL (decl1) = !DECL_EXTERNAL (decl1);
     }
-#endif /* WANT_C99_INLINE_SEMANTICS */
 
   announce_function (decl1);
 
@@ -6789,14 +6752,9 @@ finish_function (void)
      info for the epilogue.  */
   cfun->function_end_locus = input_location;
 
-  /* If we don't have ctors/dtors sections, and this is a static
-     constructor or destructor, it must be recorded now.  */
-  if (DECL_STATIC_CONSTRUCTOR (fndecl)
-      && !targetm.have_ctors_dtors)
-    static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
-  if (DECL_STATIC_DESTRUCTOR (fndecl)
-      && !targetm.have_ctors_dtors)
-    static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
+  /* Keep track of functions declared with the "constructor" and
+     "destructor" attribute.  */
+  c_record_cdtor_fn (fndecl);
 
   /* Finalize the ELF visibility for the function.  */
   c_determine_visibility (fndecl);
@@ -6841,28 +6799,6 @@ finish_function (void)
   cfun = NULL;
   current_function_decl = NULL;
 }
-
-/* Generate the RTL for the body of FNDECL.  */
-
-void
-c_expand_body (tree fndecl)
-{
-
-  if (!DECL_INITIAL (fndecl)
-      || DECL_INITIAL (fndecl) == error_mark_node)
-    return;
-
-  tree_rest_of_compilation (fndecl);
-
-  if (DECL_STATIC_CONSTRUCTOR (fndecl)
-      && targetm.have_ctors_dtors)
-    targetm.asm_out.constructor (XEXP (DECL_RTL (fndecl), 0),
-                                DEFAULT_INIT_PRIORITY);
-  if (DECL_STATIC_DESTRUCTOR (fndecl)
-      && targetm.have_ctors_dtors)
-    targetm.asm_out.destructor (XEXP (DECL_RTL (fndecl), 0),
-                               DEFAULT_INIT_PRIORITY);
-}
 \f
 /* Check the declarations given in a for-loop for satisfying the C99
    constraints.  If exactly one such decl is found, return it.  */
@@ -7847,24 +7783,6 @@ finish_declspecs (struct c_declspecs *specs)
   return specs;
 }
 
-/* Synthesize a function which calls all the global ctors or global
-   dtors in this file.  This is only used for targets which do not
-   support .ctors/.dtors sections.  FIXME: Migrate into cgraph.  */
-static void
-build_cdtor (int method_type, tree cdtors)
-{
-  tree body = 0;
-
-  if (!cdtors)
-    return;
-
-  for (; cdtors; cdtors = TREE_CHAIN (cdtors))
-    append_to_statement_list (build_function_call (TREE_VALUE (cdtors), 0),
-                             &body);
-
-  cgraph_build_static_cdtor (method_type, body, DEFAULT_INIT_PRIORITY);
-}
-
 /* A subroutine of c_write_global_declarations.  Perform final processing
    on one file scope's declarations (or the external scope's declarations),
    GLOBALS.  */
@@ -7958,11 +7876,9 @@ c_write_global_declarations (void)
     c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t)));
   c_write_global_declarations_1 (BLOCK_VARS (ext_block));
 
-  /* Generate functions to call static constructors and destructors
-     for targets that do not support .ctors/.dtors sections.  These
-     functions have magic names which are detected by collect2.  */
-  build_cdtor ('I', static_ctors); static_ctors = 0;
-  build_cdtor ('D', static_dtors); static_dtors = 0;
+  /* Call functions declared with the "constructor" or "destructor"
+     attribute.  */
+  c_build_cdtor_fns ();
 
   /* We're done parsing; proceed to optimize and emit assembly.
      FIXME: shouldn't be the front end's responsibility to call this.  */