OSDN Git Service

2008-05-16 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / langhooks.c
index 8260b31..3943f02 100644 (file)
@@ -1,5 +1,5 @@
 /* Default language-specific hooks.
-   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Contributed by Alexandre Oliva  <aoliva@redhat.com>
 
@@ -76,14 +76,6 @@ lhd_do_nothing_f (struct function * ARG_UNUSED (f))
 {
 }
 
-/* Do nothing (return the tree node passed).  */
-
-tree
-lhd_return_tree (tree t)
-{
-  return t;
-}
-
 /* Do nothing (return NULL_TREE).  */
 
 tree
@@ -276,46 +268,6 @@ lhd_types_compatible_p (tree x, tree y)
   return TYPE_MAIN_VARIANT (x) == TYPE_MAIN_VARIANT (y);
 }
 
-/* lang_hooks.tree_inlining.cannot_inline_tree_fn is called to
-   determine whether there are language-specific reasons for not
-   inlining a given function.  */
-
-int
-lhd_tree_inlining_cannot_inline_tree_fn (tree *fnp)
-{
-  if (flag_really_no_inline
-      && lookup_attribute ("always_inline", DECL_ATTRIBUTES (*fnp)) == NULL)
-    return 1;
-
-  return 0;
-}
-
-/* lang_hooks.tree_inlining.disregard_inline_limits is called to
-   determine whether a function should be considered for inlining even
-   if it would exceed inlining limits.  */
-
-int
-lhd_tree_inlining_disregard_inline_limits (const_tree fn)
-{
-  if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
-    return 1;
-
-  return 0;
-}
-
-/* lang_hooks.tree_inlining.auto_var_in_fn_p is called to determine
-   whether VT is an automatic variable defined in function FT.  */
-
-int
-lhd_tree_inlining_auto_var_in_fn_p (const_tree var, const_tree fn)
-{
-  return (DECL_P (var) && DECL_CONTEXT (var) == fn
-         && (((TREE_CODE (var) == VAR_DECL || TREE_CODE (var) == PARM_DECL)
-              && ! TREE_STATIC (var))
-             || TREE_CODE (var) == LABEL_DECL
-             || TREE_CODE (var) == RESULT_DECL));
-}
-
 /* lang_hooks.tree_dump.dump_tree:  Dump language-specific parts of tree
    nodes.  Returns nonzero if it does not want the usual dumping of the
    second argument.  */
@@ -370,7 +322,7 @@ lhd_tree_size (enum tree_code c ATTRIBUTE_UNUSED)
    sibcall.  */
 
 bool
-lhd_decl_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED)
+lhd_decl_ok_for_sibcall (const_tree decl ATTRIBUTE_UNUSED)
 {
   return true;
 }
@@ -421,12 +373,15 @@ lhd_initialize_diagnostics (struct diagnostic_context *ctx ATTRIBUTE_UNUSED)
 /* The default function to print out name of current function that caused
    an error.  */
 void
-lhd_print_error_function (diagnostic_context *context, const char *file)
+lhd_print_error_function (diagnostic_context *context, const char *file,
+                         diagnostic_info *diagnostic)
 {
-  if (diagnostic_last_function_changed (context))
+  if (diagnostic_last_function_changed (context, diagnostic))
     {
       const char *old_prefix = context->printer->prefix;
-      char *new_prefix = file ? file_name_as_prefix (file) : NULL;
+      tree abstract_origin = diagnostic->abstract_origin;
+      char *new_prefix = (file && abstract_origin == NULL)
+                        ? file_name_as_prefix (file) : NULL;
 
       pp_set_prefix (context->printer, new_prefix);
 
@@ -434,17 +389,93 @@ lhd_print_error_function (diagnostic_context *context, const char *file)
        pp_printf (context->printer, _("At top level:"));
       else
        {
-         if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
+         tree fndecl, ao;
+
+         if (abstract_origin)
+           {
+             ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin);
+             while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
+               ao = BLOCK_ABSTRACT_ORIGIN (ao);
+             gcc_assert (TREE_CODE (ao) == FUNCTION_DECL);
+             fndecl = ao;
+           }
+         else
+           fndecl = current_function_decl;
+
+         if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
            pp_printf
-             (context->printer, _("In member function %qs:"),
-              lang_hooks.decl_printable_name (current_function_decl, 2));
+             (context->printer, _("In member function %qs"),
+              lang_hooks.decl_printable_name (fndecl, 2));
          else
            pp_printf
-             (context->printer, _("In function %qs:"),
-              lang_hooks.decl_printable_name (current_function_decl, 2));
+             (context->printer, _("In function %qs"),
+              lang_hooks.decl_printable_name (fndecl, 2));
+
+         while (abstract_origin)
+           {
+             location_t *locus;
+             tree block = abstract_origin;
+
+             locus = &BLOCK_SOURCE_LOCATION (block);
+             fndecl = NULL;
+             block = BLOCK_SUPERCONTEXT (block);
+             while (block && TREE_CODE (block) == BLOCK
+                    && BLOCK_ABSTRACT_ORIGIN (block))
+               {
+                 ao = BLOCK_ABSTRACT_ORIGIN (block);
+
+                 while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
+                   ao = BLOCK_ABSTRACT_ORIGIN (ao);
+
+                 if (TREE_CODE (ao) == FUNCTION_DECL)
+                   {
+                     fndecl = ao;
+                     break;
+                   }
+                 else if (TREE_CODE (ao) != BLOCK)
+                   break;
+
+                 block = BLOCK_SUPERCONTEXT (block);
+               }
+             if (fndecl)
+               abstract_origin = block;
+             else
+               {
+                 while (block && TREE_CODE (block) == BLOCK)
+                   block = BLOCK_SUPERCONTEXT (block);
+
+                 if (TREE_CODE (block) == FUNCTION_DECL)
+                   fndecl = block;
+                 abstract_origin = NULL;
+               }
+             if (fndecl)
+               {
+                 expanded_location s = expand_location (*locus);
+                 pp_character (context->printer, ',');
+                 pp_newline (context->printer);
+                 if (s.file != NULL)
+                   {
+                     if (flag_show_column && s.column != 0)
+                       pp_printf (context->printer,
+                                  _("    inlined from %qs at %s:%d:%d"),
+                                  lang_hooks.decl_printable_name (fndecl, 2),
+                                  s.file, s.line, s.column);
+                     else
+                       pp_printf (context->printer,
+                                  _("    inlined from %qs at %s:%d"),
+                                  lang_hooks.decl_printable_name (fndecl, 2),
+                                  s.file, s.line);
+
+                   }
+                 else
+                   pp_printf (context->printer, _("    inlined from %qs"),
+                              lang_hooks.decl_printable_name (fndecl, 2));
+               }
+           }
+         pp_character (context->printer, ':');
        }
 
-      diagnostic_set_last_function (context);
+      diagnostic_set_last_function (context, diagnostic);
       pp_flush (context->printer);
       context->printer->prefix = old_prefix;
       free ((char*) new_prefix);
@@ -453,8 +484,7 @@ lhd_print_error_function (diagnostic_context *context, const char *file)
 
 tree
 lhd_callgraph_analyze_expr (tree *tp ATTRIBUTE_UNUSED,
-                           int *walk_subtrees ATTRIBUTE_UNUSED,
-                           tree decl ATTRIBUTE_UNUSED)
+                           int *walk_subtrees ATTRIBUTE_UNUSED)
 {
   return NULL;
 }
@@ -472,8 +502,7 @@ lhd_to_target_charset (HOST_WIDE_INT c)
 }
 
 tree
-lhd_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED,
-                 bool *ti ATTRIBUTE_UNUSED, bool *se ATTRIBUTE_UNUSED)
+lhd_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED, bool *se ATTRIBUTE_UNUSED)
 {
   return expr;
 }
@@ -520,6 +549,9 @@ add_builtin_function (const char *name,
   TREE_PUBLIC (decl)         = 1;
   DECL_EXTERNAL (decl)       = 1;
   DECL_BUILT_IN_CLASS (decl) = cl;
+
+  DECL_FUNCTION_CODE (decl)  = -1;
+  gcc_assert (DECL_FUNCTION_CODE (decl) >= function_code);
   DECL_FUNCTION_CODE (decl)  = function_code;
 
   if (library_name)