Patchwork [RFC,c*,ObjC*] make the translation unit decl avail. via a lang hook

login
register
mail settings
Submitter IainS
Date Oct. 29, 2010, 1:44 p.m.
Message ID <5AEA56D9-052C-4FE7-B8E0-D78BDFCD3C57@sandoe-acoustics.co.uk>
Download mbox | patch
Permalink /patch/69588/
State New
Headers show

Comments

IainS - Oct. 29, 2010, 1:44 p.m.
given that my current understanding is:
(a) we should make vars file-scope by setting DECL_CONTEXT =  
translation unit decl
(b) there should only be one translation unit decl per TU
(c) at present none of the FEs export the t_u_d where other parts of  
the machinery can see it.

would the following patch be appropriate?
(it can be extended to fortran and java, I believe, fairly easily).

---

(With this applied I can use
   DECL_CONTEXT (decl) = (*lang_hooks.decls.translation_unit_context)  
();

   in each place that it is currently set to NULL in objc-act.c
   and also replace the two instances of pushdecl_top_level () with  
the same.

  and I get no new test-suite fails for ObjC*
)

comments?
Iain
Richard Guenther - Oct. 29, 2010, 3:28 p.m.
On Fri, Oct 29, 2010 at 3:44 PM, IainS <developer@sandoe-acoustics.co.uk> wrote:
> given that my current understanding is:
> (a) we should make vars file-scope by setting DECL_CONTEXT = translation
> unit decl
> (b) there should only be one translation unit decl per TU
> (c) at present none of the FEs export the t_u_d where other parts of the
> machinery can see it.
>
> would the following patch be appropriate?
> (it can be extended to fortran and java, I believe, fairly easily).

Sounds like a hack.  Note that frontends might end up with multiple
TUs (for example for things in fortran modules).  It's a hack because
it's a frontend hook that is only used by the frontend (which means
a single global variable does do it as well, like other FEs do it).

Richard.

> ---
>
> (With this applied I can use
>  DECL_CONTEXT (decl) = (*lang_hooks.decls.translation_unit_context) ();
>
>  in each place that it is currently set to NULL in objc-act.c
>  and also replace the two instances of pushdecl_top_level () with the same.
>
>  and I get no new test-suite fails for ObjC*
> )
>
> comments?
> Iain
>
>
> Index: gcc/c-family/c-common.h
> ===================================================================
> --- gcc/c-family/c-common.h     (revision 166059)
> +++ gcc/c-family/c-common.h     (working copy)
> @@ -514,6 +514,7 @@ extern tree add_stmt (tree);
>  extern void push_cleanup (tree, tree, bool);
>  extern tree pushdecl_top_level (tree);
>  extern tree pushdecl (tree);
> +extern tree c_translation_unit_decl (void);
>  extern tree build_modify_expr (location_t, tree, tree, enum tree_code,
>                               location_t, tree, tree);
>  extern tree build_indirect_ref (location_t, tree, ref_operator);
> Index: gcc/cp/decl.c
> ===================================================================
> --- gcc/cp/decl.c       (revision 166059)
> +++ gcc/cp/decl.c       (working copy)
> @@ -3427,6 +3427,19 @@ initialize_predefined_identifiers (void)
>     }
>  }
>
> +/* The current translation unit.  */
> +static GTY(()) tree current_translation_unit = NULL_TREE;
> +
> +/* The function used to return the current t_u_d for the
> +   translation_unit_context langhook.  */
> +
> +tree
> +cp_translation_unit_decl (void)
> +{
> +  gcc_assert (current_translation_unit);
> +  return current_translation_unit;
> +}
> +
>  /* Create the predefined scalar types of C,
>    and some nodes representing standard constants (0, 1, (void *)0).
>    Initialize the global binding level.
> @@ -3452,7 +3465,8 @@ cxx_init_decl_processing (void)
>   gcc_assert (global_namespace == NULL_TREE);
>   global_namespace = build_lang_decl (NAMESPACE_DECL, global_scope_name,
>                                      void_type_node);
> -  DECL_CONTEXT (global_namespace) = build_translation_unit_decl
> (NULL_TREE);
> +  current_translation_unit = build_translation_unit_decl (NULL_TREE);
> +  DECL_CONTEXT (global_namespace) = current_translation_unit;
>   TREE_PUBLIC (global_namespace) = 1;
>   begin_scope (sk_namespace, global_namespace);
>
> Index: gcc/cp/cp-objcp-common.h
> ===================================================================
> --- gcc/cp/cp-objcp-common.h    (revision 166059)
> +++ gcc/cp/cp-objcp-common.h    (working copy)
> @@ -132,6 +132,8 @@ extern bool cp_function_decl_explicit_p (tree decl
>  #define LANG_HOOKS_GIMPLIFY_EXPR cp_gimplify_expr
>  #undef LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P
>  #define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P cp_function_decl_explicit_p
> +#undef  LANG_HOOKS_TUD
> +#define LANG_HOOKS_TUD cp_translation_unit_decl
>  #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
>  #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing
>  #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR
> Index: gcc/cp/cp-tree.h
> ===================================================================
> --- gcc/cp/cp-tree.h    (revision 166059)
> +++ gcc/cp/cp-tree.h    (working copy)
> @@ -4764,6 +4764,7 @@ extern tree current_decl_namespace
>  (void);
>
>  /* decl.c */
>  extern tree poplevel                           (int, int, int);
> +extern tree cp_translation_unit_decl           (void);
>  extern void cxx_init_decl_processing           (void);
>  enum cp_tree_node_structure_enum cp_tree_node_structure
>                                                (union lang_tree_node *);
> Index: gcc/c-objc-common.h
> ===================================================================
> --- gcc/c-objc-common.h (revision 166059)
> +++ gcc/c-objc-common.h (working copy)
> @@ -85,6 +85,8 @@ along with GCC; see the file COPYING3.  If not see
>  #define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset
>  #undef LANG_HOOKS_EXPR_TO_DECL
>  #define LANG_HOOKS_EXPR_TO_DECL c_expr_to_decl
> +#undef  LANG_HOOKS_TUD
> +#define LANG_HOOKS_TUD c_translation_unit_decl
>
>  /* The C front end's scoping structure is very different from
>    that expected by the language-independent code; it is best
> Index: gcc/c-decl.c
> ===================================================================
> --- gcc/c-decl.c        (revision 166059)
> +++ gcc/c-decl.c        (working copy)
> @@ -454,6 +454,8 @@ static GTY((deletable)) struct c_binding *binding_
>   t_->to##_last = f_->from##_last;                             \
>  } while (0)
>
> +static GTY(()) tree current_translation_unit = NULL_TREE;
> +
>  /* A c_inline_static structure stores details of a static identifier
>    referenced in a definition of a function that may be an inline
>    definition if no subsequent declaration of that function uses
> @@ -528,6 +530,14 @@ static tree grokdeclarator (const struct c_declara
>  static tree grokparms (struct c_arg_info *, bool);
>  static void layout_array_type (tree);
>
> +/* Return the translation unit decl for the current TU.  */
> +tree
> +c_translation_unit_decl (void)
> +{
> +  gcc_assert (current_translation_unit);
> +  return current_translation_unit;
> +}
> +
>  /* T is a statement.  Add it to the statement-tree.  This is the
>    C/ObjC version--C++ has a slightly different version of this
>    function.  */
> @@ -1066,8 +1076,7 @@ pop_scope (void)
>     context = current_function_decl;
>   else if (scope == file_scope)
>     {
> -      tree file_decl = build_translation_unit_decl (NULL_TREE);
> -      context = file_decl;
> +      context = (*lang_hooks.decls.translation_unit_context) ();
>     }
>   else
>     context = block;
> @@ -3461,6 +3470,9 @@ c_init_decl_processing (void)
>
>   c_common_nodes_and_builtins ();
>
> +  /* The current translation unit.  */
> +  current_translation_unit = build_translation_unit_decl (NULL_TREE);
> +
>   /* In C, comparisons and TRUTH_* expressions have type int.  */
>   truthvalue_type_node = integer_type_node;
>   truthvalue_true_node = integer_one_node;
> Index: gcc/langhooks.h
> ===================================================================
> --- gcc/langhooks.h     (revision 166059)
> +++ gcc/langhooks.h     (working copy)
> @@ -152,6 +152,9 @@ struct lang_hooks_for_decls
>      symbol is already declared, may return a different decl for that
>      name.  */
>   tree (*pushdecl) (tree);
> +
> +  /* To add a decl to 'file scope' set its DECL_CONTEXT to this.  */
> +  tree (*translation_unit_context) (void);
>
>   /* Returns the chain of decls so far in the current scope level.  */
>   tree (*getdecls) (void);
> Index: gcc/langhooks-def.h
> ===================================================================
> --- gcc/langhooks-def.h (revision 166059)
> +++ gcc/langhooks-def.h (working copy)
> @@ -200,6 +200,7 @@ extern tree lhd_make_node (enum tree_code);
>  /* Declaration hooks.  */
>  #define LANG_HOOKS_GLOBAL_BINDINGS_P global_bindings_p
>  #define LANG_HOOKS_PUSHDECL    pushdecl
> +#define LANG_HOOKS_TUD lhd_return_null_tree_v
>  #define LANG_HOOKS_GETDECLS    getdecls
>  #define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P hook_bool_tree_false
>  #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
> @@ -220,6 +221,7 @@ extern tree lhd_make_node (enum tree_code);
>  #define LANG_HOOKS_DECLS { \
>   LANG_HOOKS_GLOBAL_BINDINGS_P, \
>   LANG_HOOKS_PUSHDECL, \
> +  LANG_HOOKS_TUD, \
>   LANG_HOOKS_GETDECLS, \
>   LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P, \
>   LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P, \
>
>
Paolo Bonzini - Oct. 29, 2010, 3:54 p.m.
On 10/29/2010 05:28 PM, Richard Guenther wrote:
> Sounds like a hack.  Note that frontends might end up with multiple
> TUs (for example for things in fortran modules).  It's a hack because
> it's a frontend hook that is only used by the frontend (which means
> a single global variable does do it as well, like other FEs do it).

Not necessarily, it can be used by target hooks as well if they want to 
create new globals.

Paolo
IainS - Oct. 29, 2010, 3:57 p.m.
Hi Richard,

On 29 Oct 2010, at 16:28, Richard Guenther wrote:

> On Fri, Oct 29, 2010 at 3:44 PM, IainS <developer@sandoe-acoustics.co.uk 
> > wrote:
>> given that my current understanding is:
>> (a) we should make vars file-scope by setting DECL_CONTEXT =  
>> translation
>> unit decl
>> (b) there should only be one translation unit decl per TU
>> (c) at present none of the FEs export the t_u_d where other parts  
>> of the
>> machinery can see it.
>>
>> would the following patch be appropriate?
>> (it can be extended to fortran and java, I believe, fairly easily).
>
> Sounds like a hack.  Note that frontends might end up with multiple
> TUs (for example for things in fortran modules).

One would assume that a built-in that wishes to push an item to the  
'file scope' would still use 'current_translation_unit_decl'.
(to attach the decl to the 'file scope' of the current module).

[and I guess the name mangling must take care of different module  
ordering in different fortran source files?]

> It's a hack because
> it's a frontend hook that is only used by the frontend (which means
> a single global variable does do it as well,

OK, I had a global originally  (called current_translation_unit_decl)
- but that means defining it also in lto which seemed unnecessary.

> like other FEs do it

none of the FEs make the t_u_d available outside the file in which  
it's created.
and, AFAICT,  ObjC* must use the t_u_d created in c* - since they are  
sharing spaces.

If this seems reasonable
I can re-do the patch as I had it originally - with a global.

(or if I'm missing something fundamental, a pointer would be  
appreciated).

Iain

> Richard.
Richard Guenther - Oct. 29, 2010, 11:07 p.m.
On Fri, Oct 29, 2010 at 5:57 PM, IainS <developer@sandoe-acoustics.co.uk> wrote:
> Hi Richard,
>
> On 29 Oct 2010, at 16:28, Richard Guenther wrote:
>
>> On Fri, Oct 29, 2010 at 3:44 PM, IainS <developer@sandoe-acoustics.co.uk>
>> wrote:
>>>
>>> given that my current understanding is:
>>> (a) we should make vars file-scope by setting DECL_CONTEXT = translation
>>> unit decl
>>> (b) there should only be one translation unit decl per TU
>>> (c) at present none of the FEs export the t_u_d where other parts of the
>>> machinery can see it.
>>>
>>> would the following patch be appropriate?
>>> (it can be extended to fortran and java, I believe, fairly easily).
>>
>> Sounds like a hack.  Note that frontends might end up with multiple
>> TUs (for example for things in fortran modules).
>
> One would assume that a built-in that wishes to push an item to the 'file
> scope' would still use 'current_translation_unit_decl'.
> (to attach the decl to the 'file scope' of the current module).

Well, I would argue that builtins don't really have a TU unless they
are re-declared from a header.

> [and I guess the name mangling must take care of different module ordering
> in different fortran source files?]
>
>> It's a hack because
>> it's a frontend hook that is only used by the frontend (which means
>> a single global variable does do it as well,
>
> OK, I had a global originally  (called current_translation_unit_decl)
> - but that means defining it also in lto which seemed unnecessary.

Why in LTO?  What does LTO have to do with ObjC?

>> like other FEs do it
>
> none of the FEs make the t_u_d available outside the file in which it's
> created.
> and, AFAICT,  ObjC* must use the t_u_d created in c* - since they are
> sharing spaces.

Well, ok.

> If this seems reasonable
> I can re-do the patch as I had it originally - with a global.
>
> (or if I'm missing something fundamental, a pointer would be appreciated).

Maybe I am missing something fundamental.  Why's this suddenly about
builtins?

Richard.

> Iain
>
>> Richard.
>
>
>
IainS - Oct. 30, 2010, 7:20 a.m.
On 30 Oct 2010, at 00:07, Richard Guenther wrote:

> On Fri, Oct 29, 2010 at 5:57 PM, IainS <developer@sandoe-acoustics.co.uk 
> > wrote:
>> Hi Richard,
>>
>> On 29 Oct 2010, at 16:28, Richard Guenther wrote:
>>
>>> On Fri, Oct 29, 2010 at 3:44 PM, IainS <developer@sandoe-acoustics.co.uk 
>>> >
>>> wrote:
>>>>
>>>> given that my current understanding is:
>>>> (a) we should make vars file-scope by setting DECL_CONTEXT =  
>>>> translation
>>>> unit decl
>>>> (b) there should only be one translation unit decl per TU
>>>> (c) at present none of the FEs export the t_u_d where other parts  
>>>> of the
>>>> machinery can see it.
>>>>
>>>> would the following patch be appropriate?
>>>> (it can be extended to fortran and java, I believe, fairly easily).
>>>
>>> Sounds like a hack.  Note that frontends might end up with multiple
>>> TUs (for example for things in fortran modules).
>>
>> One would assume that a built-in that wishes to push an item to the  
>> 'file
>> scope' would still use 'current_translation_unit_decl'.
>> (to attach the decl to the 'file scope' of the current module).
>
> Well, I would argue that builtins don't really have a TU unless they
> are re-declared from a header.
>
>> [and I guess the name mangling must take care of different module  
>> ordering
>> in different fortran source files?]
>>
>>> It's a hack because
>>> it's a frontend hook that is only used by the frontend (which means
>>> a single global variable does do it as well,
>>
>> OK, I had a global originally  (called current_translation_unit_decl)
>> - but that means defining it also in lto which seemed unnecessary.
>
> Why in LTO?  What does LTO have to do with ObjC?
>
>>> like other FEs do it
>>
>> none of the FEs make the t_u_d available outside the file in which  
>> it's
>> created.
>> and, AFAICT,  ObjC* must use the t_u_d created in c* - since they are
>> sharing spaces.
>
> Well, ok.
>
>> If this seems reasonable
>> I can re-do the patch as I had it originally - with a global.
>>
>> (or if I'm missing something fundamental, a pointer would be  
>> appreciated).
>
> Maybe I am missing something fundamental.  Why's this suddenly about
> builtins?

It is about two cases.

1/ the CFString built-in (see http://gcc.gnu.org/ml/gcc-patches/2010-10/msg01917.html)
.. which I was persuaded to make non-language-specific (and it seems  
to be working fine, so no issue there).

2/ the ObjC* FEs that need to use the t_u_d from c* because they  
inherit scopes from c*

(the two things could be done differently, I guess, but it seemed  
reasonable to try for one way).

LTO only arose in the case that a single named global was used as the  
mechanism to satisfy (1).

I have no immediate perception about whether there are more uses  
possible across the FEs (but it seems possible).

Iain

> Richard.
>
>> Iain
>>
>>> Richard.
>>
>>
>>
Richard Guenther - Oct. 30, 2010, 6:09 p.m.
On Sat, Oct 30, 2010 at 9:20 AM, IainS <developer@sandoe-acoustics.co.uk> wrote:
>
> On 30 Oct 2010, at 00:07, Richard Guenther wrote:
>
>> On Fri, Oct 29, 2010 at 5:57 PM, IainS <developer@sandoe-acoustics.co.uk>
>> wrote:
>>>
>>> Hi Richard,
>>>
>>> On 29 Oct 2010, at 16:28, Richard Guenther wrote:
>>>
>>>> On Fri, Oct 29, 2010 at 3:44 PM, IainS
>>>> <developer@sandoe-acoustics.co.uk>
>>>> wrote:
>>>>>
>>>>> given that my current understanding is:
>>>>> (a) we should make vars file-scope by setting DECL_CONTEXT =
>>>>> translation
>>>>> unit decl
>>>>> (b) there should only be one translation unit decl per TU
>>>>> (c) at present none of the FEs export the t_u_d where other parts of
>>>>> the
>>>>> machinery can see it.
>>>>>
>>>>> would the following patch be appropriate?
>>>>> (it can be extended to fortran and java, I believe, fairly easily).
>>>>
>>>> Sounds like a hack.  Note that frontends might end up with multiple
>>>> TUs (for example for things in fortran modules).
>>>
>>> One would assume that a built-in that wishes to push an item to the 'file
>>> scope' would still use 'current_translation_unit_decl'.
>>> (to attach the decl to the 'file scope' of the current module).
>>
>> Well, I would argue that builtins don't really have a TU unless they
>> are re-declared from a header.
>>
>>> [and I guess the name mangling must take care of different module
>>> ordering
>>> in different fortran source files?]
>>>
>>>> It's a hack because
>>>> it's a frontend hook that is only used by the frontend (which means
>>>> a single global variable does do it as well,
>>>
>>> OK, I had a global originally  (called current_translation_unit_decl)
>>> - but that means defining it also in lto which seemed unnecessary.
>>
>> Why in LTO?  What does LTO have to do with ObjC?
>>
>>>> like other FEs do it
>>>
>>> none of the FEs make the t_u_d available outside the file in which it's
>>> created.
>>> and, AFAICT,  ObjC* must use the t_u_d created in c* - since they are
>>> sharing spaces.
>>
>> Well, ok.
>>
>>> If this seems reasonable
>>> I can re-do the patch as I had it originally - with a global.
>>>
>>> (or if I'm missing something fundamental, a pointer would be
>>> appreciated).
>>
>> Maybe I am missing something fundamental.  Why's this suddenly about
>> builtins?
>
> It is about two cases.
>
> 1/ the CFString built-in (see
> http://gcc.gnu.org/ml/gcc-patches/2010-10/msg01917.html)
> .. which I was persuaded to make non-language-specific (and it seems to be
> working fine, so no issue there).
>
> 2/ the ObjC* FEs that need to use the t_u_d from c* because they inherit
> scopes from c*
>
> (the two things could be done differently, I guess, but it seemed reasonable
> to try for one way).
>
> LTO only arose in the case that a single named global was used as the
> mechanism to satisfy (1).
>
> I have no immediate perception about whether there are more uses possible
> across the FEs (but it seems possible).

Hm, I suppose this doesn't "fix" anything (it'll just be NULL_TREE DECL_CONTEXT
which then doesn't get attributed to a specific language context - but builtins
aren't).  So I think we should defer this to the point when someone
does the work
to unify builtin handling across frontends.

Richard.

> Iain
>
>> Richard.
>>
>>> Iain
>>>
>>>> Richard.
>>>
>>>
>>>
>
>

Patch

Index: gcc/c-family/c-common.h
===================================================================
--- gcc/c-family/c-common.h	(revision 166059)
+++ gcc/c-family/c-common.h	(working copy)
@@ -514,6 +514,7 @@  extern tree add_stmt (tree);
  extern void push_cleanup (tree, tree, bool);
  extern tree pushdecl_top_level (tree);
  extern tree pushdecl (tree);
+extern tree c_translation_unit_decl (void);
  extern tree build_modify_expr (location_t, tree, tree, enum tree_code,
  			       location_t, tree, tree);
  extern tree build_indirect_ref (location_t, tree, ref_operator);
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 166059)
+++ gcc/cp/decl.c	(working copy)
@@ -3427,6 +3427,19 @@  initialize_predefined_identifiers (void)
      }
  }

+/* The current translation unit.  */
+static GTY(()) tree current_translation_unit = NULL_TREE;
+
+/* The function used to return the current t_u_d for the
+   translation_unit_context langhook.  */
+
+tree
+cp_translation_unit_decl (void)
+{
+  gcc_assert (current_translation_unit);
+  return current_translation_unit;
+}
+
  /* Create the predefined scalar types of C,
     and some nodes representing standard constants (0, 1, (void *)0).
     Initialize the global binding level.
@@ -3452,7 +3465,8 @@  cxx_init_decl_processing (void)
    gcc_assert (global_namespace == NULL_TREE);
    global_namespace = build_lang_decl (NAMESPACE_DECL,  
global_scope_name,
  				      void_type_node);
-  DECL_CONTEXT (global_namespace) = build_translation_unit_decl  
(NULL_TREE);
+  current_translation_unit = build_translation_unit_decl (NULL_TREE);
+  DECL_CONTEXT (global_namespace) = current_translation_unit;
    TREE_PUBLIC (global_namespace) = 1;
    begin_scope (sk_namespace, global_namespace);

Index: gcc/cp/cp-objcp-common.h
===================================================================
--- gcc/cp/cp-objcp-common.h	(revision 166059)
+++ gcc/cp/cp-objcp-common.h	(working copy)
@@ -132,6 +132,8 @@  extern bool cp_function_decl_explicit_p (tree decl
  #define LANG_HOOKS_GIMPLIFY_EXPR cp_gimplify_expr
  #undef LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P
  #define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P  
cp_function_decl_explicit_p
+#undef  LANG_HOOKS_TUD
+#define LANG_HOOKS_TUD cp_translation_unit_decl
  #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
  #define LANG_HOOKS_OMP_PREDETERMINED_SHARING  
cxx_omp_predetermined_sharing
  #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 166059)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -4764,6 +4764,7 @@  extern tree current_decl_namespace		(void);

  /* decl.c */
  extern tree poplevel				(int, int, int);
+extern tree cp_translation_unit_decl		(void);
  extern void cxx_init_decl_processing		(void);
  enum cp_tree_node_structure_enum cp_tree_node_structure
  						(union lang_tree_node *);
Index: gcc/c-objc-common.h
===================================================================
--- gcc/c-objc-common.h	(revision 166059)
+++ gcc/c-objc-common.h	(working copy)
@@ -85,6 +85,8 @@  along with GCC; see the file COPYING3.  If not see
  #define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset
  #undef LANG_HOOKS_EXPR_TO_DECL
  #define LANG_HOOKS_EXPR_TO_DECL c_expr_to_decl
+#undef  LANG_HOOKS_TUD
+#define LANG_HOOKS_TUD c_translation_unit_decl

  /* The C front end's scoping structure is very different from
     that expected by the language-independent code; it is best
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 166059)
+++ gcc/c-decl.c	(working copy)
@@ -454,6 +454,8 @@  static GTY((deletable)) struct c_binding *binding_
    t_->to##_last = f_->from##_last;				\
  } while (0)

+static GTY(()) tree current_translation_unit = NULL_TREE;
+
  /* A c_inline_static structure stores details of a static identifier
     referenced in a definition of a function that may be an inline
     definition if no subsequent declaration of that function uses
@@ -528,6 +530,14 @@  static tree grokdeclarator (const struct c_declara
  static tree grokparms (struct c_arg_info *, bool);
  static void layout_array_type (tree);
  
+/* Return the translation unit decl for the current TU.  */
+tree
+c_translation_unit_decl (void)
+{
+  gcc_assert (current_translation_unit);
+  return current_translation_unit;
+}
+
  /* T is a statement.  Add it to the statement-tree.  This is the
     C/ObjC version--C++ has a slightly different version of this
     function.  */
@@ -1066,8 +1076,7 @@  pop_scope (void)
      context = current_function_decl;
    else if (scope == file_scope)
      {
-      tree file_decl = build_translation_unit_decl (NULL_TREE);
-      context = file_decl;
+      context = (*lang_hooks.decls.translation_unit_context) ();
      }
    else
      context = block;
@@ -3461,6 +3470,9 @@  c_init_decl_processing (void)

    c_common_nodes_and_builtins ();

+  /* The current translation unit.  */
+  current_translation_unit = build_translation_unit_decl (NULL_TREE);
+
    /* In C, comparisons and TRUTH_* expressions have type int.  */
    truthvalue_type_node = integer_type_node;
    truthvalue_true_node = integer_one_node;
Index: gcc/langhooks.h
===================================================================
--- gcc/langhooks.h	(revision 166059)
+++ gcc/langhooks.h	(working copy)
@@ -152,6 +152,9 @@  struct lang_hooks_for_decls
       symbol is already declared, may return a different decl for that
       name.  */
    tree (*pushdecl) (tree);
+
+  /* To add a decl to 'file scope' set its DECL_CONTEXT to this.  */
+  tree (*translation_unit_context) (void);

    /* Returns the chain of decls so far in the current scope level.  */
    tree (*getdecls) (void);
Index: gcc/langhooks-def.h
===================================================================
--- gcc/langhooks-def.h	(revision 166059)
+++ gcc/langhooks-def.h	(working copy)
@@ -200,6 +200,7 @@  extern tree lhd_make_node (enum tree_code);
  /* Declaration hooks.  */
  #define LANG_HOOKS_GLOBAL_BINDINGS_P global_bindings_p
  #define LANG_HOOKS_PUSHDECL	pushdecl
+#define LANG_HOOKS_TUD	lhd_return_null_tree_v
  #define LANG_HOOKS_GETDECLS	getdecls
  #define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P hook_bool_tree_false
  #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
@@ -220,6 +221,7 @@  extern tree lhd_make_node (enum tree_code);
  #define LANG_HOOKS_DECLS { \
    LANG_HOOKS_GLOBAL_BINDINGS_P, \
    LANG_HOOKS_PUSHDECL, \
+  LANG_HOOKS_TUD, \
    LANG_HOOKS_GETDECLS, \
    LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P, \
    LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P, \