This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Make C++ use TRANSLATION_UNIT_DECL for global entities
On Tue, 28 Sep 2010, Richard Guenther wrote:
> On Tue, 28 Sep 2010, Jason Merrill wrote:
>
> > On 09/28/2010 10:23 AM, Richard Guenther wrote:
> > > then we'd push global_namespace where we previously didn't.
> > > Or maybe I misunderstood you?
> >
> > Right, that is what I meant. I think that pushing global_namespace there
> > shouldn't hurt, but it would also be fine to test against global_namespace and
> > just not push in that case.
Here is an updated patch. Pushing global_namespace doesn't bootstrap
so I test against it.
Bootstrapped and tested on x86_64-unknown-linux-gnu, ok?
Thanks,
Richard.
2010-09-29 Richard Guenther <rguenther@suse.de>
* tree.h (SCOPE_FILE_SCOPE_P): New macro.
(DECL_FILE_SCOPE_P): Use it.
(TYPE_FILE_SCOPE_P): New macro.
* cp-tree.h (CP_DECL_CONTEXT): Check DECL_FILE_SCOPE_P.
(CP_TYPE_CONTEXT): Similar.
(FROB_CONTEXT): Frob global_namespace to the global
TRANSLATION_UNIT_DECL.
* decl.c (cxx_init_decl_processing): Build a TRANSLATION_UNIT_DECL,
set DECL_CONTEXT of global_namespace to it.
* decl.c (start_decl): Use CP_DECL_CONTEXT and test TYPE_P
instead of zeroing context.
(cp_finish_decl): Use DECL_FILE_SCOPE_P.
(grokfndecl): Likewise.
(start_preparsed_function): Likewise.
* name-lookup.c (maybe_push_decl): Use CP_DECL_CONTEXT.
(namespace_binding): Use SCOPE_FILE_SCOPE_P.
* pt.c (template_class_depth): Use CP_TYPE_CONTEXT.
(is_specialization_of_friend): Use CP_DECL_CONTEXT.
(push_template_decl_real): Likewise.
(tsubst_friend_class): Likewise. Adjust context comparisons.
(instantiate_class_template): Use CP_TYPE_CONTEXT.
(tsubst): Do not substitute into TRANSLATION_UNIT_DECL.
* cxx-pretty-print.c (pp_cxx_nested_name_specifier): Use
SCOPE_FILE_SCOPE_P.
Index: gcc/cp/cp-tree.h
===================================================================
*** gcc/cp/cp-tree.h.orig 2010-09-28 12:29:24.000000000 +0200
--- gcc/cp/cp-tree.h 2010-09-28 16:15:47.000000000 +0200
*************** struct GTY((variable_size)) lang_decl {
*** 2361,2372 ****
#define SET_DECL_FRIEND_CONTEXT(NODE, CONTEXT) \
(LANG_DECL_FN_CHECK (NODE)->context = (CONTEXT))
- /* NULL_TREE in DECL_CONTEXT represents the global namespace. */
#define CP_DECL_CONTEXT(NODE) \
! (DECL_CONTEXT (NODE) ? DECL_CONTEXT (NODE) : global_namespace)
#define CP_TYPE_CONTEXT(NODE) \
! (TYPE_CONTEXT (NODE) ? TYPE_CONTEXT (NODE) : global_namespace)
! #define FROB_CONTEXT(NODE) ((NODE) == global_namespace ? NULL_TREE : (NODE))
/* 1 iff NODE has namespace scope, including the global namespace. */
#define DECL_NAMESPACE_SCOPE_P(NODE) \
--- 2361,2372 ----
#define SET_DECL_FRIEND_CONTEXT(NODE, CONTEXT) \
(LANG_DECL_FN_CHECK (NODE)->context = (CONTEXT))
#define CP_DECL_CONTEXT(NODE) \
! (!DECL_FILE_SCOPE_P (NODE) ? DECL_CONTEXT (NODE) : global_namespace)
#define CP_TYPE_CONTEXT(NODE) \
! (!TYPE_FILE_SCOPE_P (NODE) ? TYPE_CONTEXT (NODE) : global_namespace)
! #define FROB_CONTEXT(NODE) \
! ((NODE) == global_namespace ? DECL_CONTEXT (NODE) : (NODE))
/* 1 iff NODE has namespace scope, including the global namespace. */
#define DECL_NAMESPACE_SCOPE_P(NODE) \
Index: gcc/cp/decl.c
===================================================================
*** gcc/cp/decl.c.orig 2010-09-28 12:29:24.000000000 +0200
--- gcc/cp/decl.c 2010-09-28 17:56:12.000000000 +0200
*************** cxx_init_decl_processing (void)
*** 3417,3422 ****
--- 3417,3423 ----
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);
TREE_PUBLIC (global_namespace) = 1;
begin_scope (sk_namespace, global_namespace);
*************** start_decl (const cp_declarator *declara
*** 4163,4178 ****
|| decl == error_mark_node)
return error_mark_node;
! context = DECL_CONTEXT (decl);
!
! if (context)
! {
! *pushed_scope_p = push_scope (context);
!
! /* We are only interested in class contexts, later. */
! if (TREE_CODE (context) == NAMESPACE_DECL)
! context = NULL_TREE;
! }
if (initialized)
/* Is it valid for this decl to have an initializer at all?
--- 4164,4172 ----
|| decl == error_mark_node)
return error_mark_node;
! context = CP_DECL_CONTEXT (decl);
! if (context != global_namespace)
! *pushed_scope_p = push_scope (context);
if (initialized)
/* Is it valid for this decl to have an initializer at all?
*************** start_decl (const cp_declarator *declara
*** 4241,4247 ****
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
warning (0, "inline function %q+D given attribute noinline", decl);
! if (context && COMPLETE_TYPE_P (complete_type (context)))
{
if (TREE_CODE (decl) == VAR_DECL)
{
--- 4235,4241 ----
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
warning (0, "inline function %q+D given attribute noinline", decl);
! if (TYPE_P (context) && COMPLETE_TYPE_P (complete_type (context)))
{
if (TREE_CODE (decl) == VAR_DECL)
{
*************** cp_finish_decl (tree decl, tree init, bo
*** 5802,5808 ****
&& !COMPLETE_TYPE_P (TREE_TYPE (decl)))
TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
! rest_of_decl_compilation (decl, DECL_CONTEXT (decl) == NULL_TREE,
at_eof);
goto finish_end;
}
--- 5796,5802 ----
&& !COMPLETE_TYPE_P (TREE_TYPE (decl)))
TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
! rest_of_decl_compilation (decl, DECL_FILE_SCOPE_P (decl),
at_eof);
goto finish_end;
}
*************** grokfndecl (tree ctype,
*** 6888,6895 ****
&& strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0))
&& current_lang_name == lang_name_cplusplus
&& ctype == NULL_TREE
! /* NULL_TREE means global namespace. */
! && DECL_CONTEXT (decl) == NULL_TREE)
SET_DECL_LANGUAGE (decl, lang_c);
/* Should probably propagate const out from type to decl I bet (mrs). */
--- 6882,6888 ----
&& strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0))
&& current_lang_name == lang_name_cplusplus
&& ctype == NULL_TREE
! && DECL_FILE_SCOPE_P (decl))
SET_DECL_LANGUAGE (decl, lang_c);
/* Should probably propagate const out from type to decl I bet (mrs). */
*************** start_preparsed_function (tree decl1, tr
*** 12068,12074 ****
with any previous declarations; if the original declaration
has a linkage specification, that specification applies to
the definition as well, and may affect the mangled name. */
! if (!DECL_CONTEXT (decl1))
maybe_apply_pragma_weak (decl1);
}
--- 12061,12067 ----
with any previous declarations; if the original declaration
has a linkage specification, that specification applies to
the definition as well, and may affect the mangled name. */
! if (DECL_FILE_SCOPE_P (decl1))
maybe_apply_pragma_weak (decl1);
}
Index: gcc/cp/name-lookup.c
===================================================================
*** gcc/cp/name-lookup.c.orig 2010-09-28 12:29:24.000000000 +0200
--- gcc/cp/name-lookup.c 2010-09-28 16:21:45.000000000 +0200
*************** maybe_push_decl (tree decl)
*** 1169,1175 ****
&& DECL_CONTEXT (decl) != NULL_TREE
/* Definitions of namespace members outside their namespace are
possible. */
! && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
|| (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
|| type == unknown_type_node
/* The declaration of a template specialization does not affect
--- 1169,1175 ----
&& DECL_CONTEXT (decl) != NULL_TREE
/* Definitions of namespace members outside their namespace are
possible. */
! && TREE_CODE (CP_DECL_CONTEXT (decl)) != NAMESPACE_DECL)
|| (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
|| type == unknown_type_node
/* The declaration of a template specialization does not affect
*************** namespace_binding (tree name, tree scope
*** 3068,3074 ****
{
cxx_binding *binding;
! if (scope == NULL)
scope = global_namespace;
else
/* Unnecessary for the global namespace because it can't be an alias. */
--- 3068,3074 ----
{
cxx_binding *binding;
! if (SCOPE_FILE_SCOPE_P (scope))
scope = global_namespace;
else
/* Unnecessary for the global namespace because it can't be an alias. */
Index: gcc/cp/pt.c
===================================================================
*** gcc/cp/pt.c.orig 2010-09-28 12:29:24.000000000 +0200
--- gcc/cp/pt.c 2010-09-28 16:15:47.000000000 +0200
*************** template_class_depth (tree type)
*** 344,350 ****
for (depth = 0;
type && TREE_CODE (type) != NAMESPACE_DECL;
type = (TREE_CODE (type) == FUNCTION_DECL)
! ? CP_DECL_CONTEXT (type) : TYPE_CONTEXT (type))
{
tree tinfo = get_template_info (type);
--- 344,350 ----
for (depth = 0;
type && TREE_CODE (type) != NAMESPACE_DECL;
type = (TREE_CODE (type) == FUNCTION_DECL)
! ? CP_DECL_CONTEXT (type) : CP_TYPE_CONTEXT (type))
{
tree tinfo = get_template_info (type);
*************** is_specialization_of_friend (tree decl,
*** 1130,1136 ****
nonzero. To determine if DECL is a friend of FRIEND, we first
check if the enclosing class is a specialization of another. */
! template_depth = template_class_depth (DECL_CONTEXT (friend_decl));
if (template_depth
&& DECL_CLASS_SCOPE_P (decl)
&& is_specialization_of (TYPE_NAME (DECL_CONTEXT (decl)),
--- 1130,1136 ----
nonzero. To determine if DECL is a friend of FRIEND, we first
check if the enclosing class is a specialization of another. */
! template_depth = template_class_depth (CP_DECL_CONTEXT (friend_decl));
if (template_depth
&& DECL_CLASS_SCOPE_P (decl)
&& is_specialization_of (TYPE_NAME (DECL_CONTEXT (decl)),
*************** push_template_decl_real (tree decl, bool
*** 4346,4352 ****
if (is_friend)
/* For a friend, we want the context of the friend function, not
the type of which it is a friend. */
! ctx = DECL_CONTEXT (decl);
else if (CP_DECL_CONTEXT (decl)
&& TREE_CODE (CP_DECL_CONTEXT (decl)) != NAMESPACE_DECL)
/* In the case of a virtual function, we want the class in which
--- 4346,4352 ----
if (is_friend)
/* For a friend, we want the context of the friend function, not
the type of which it is a friend. */
! ctx = CP_DECL_CONTEXT (decl);
else if (CP_DECL_CONTEXT (decl)
&& TREE_CODE (CP_DECL_CONTEXT (decl)) != NAMESPACE_DECL)
/* In the case of a virtual function, we want the class in which
*************** tsubst_friend_class (tree friend_tmpl, t
*** 7530,7538 ****
tree tmpl;
tree context;
! context = DECL_CONTEXT (friend_tmpl);
! if (context)
{
if (TREE_CODE (context) == NAMESPACE_DECL)
push_nested_namespace (context);
--- 7530,7538 ----
tree tmpl;
tree context;
! context = CP_DECL_CONTEXT (friend_tmpl);
! if (context != global_namespace)
{
if (TREE_CODE (context) == NAMESPACE_DECL)
push_nested_namespace (context);
*************** tsubst_friend_class (tree friend_tmpl, t
*** 7621,7627 ****
friend_type = TREE_TYPE (pushdecl_top_level_maybe_friend (tmpl, true));
}
! if (context)
{
if (TREE_CODE (context) == NAMESPACE_DECL)
pop_nested_namespace (context);
--- 7621,7627 ----
friend_type = TREE_TYPE (pushdecl_top_level_maybe_friend (tmpl, true));
}
! if (context != global_namespace)
{
if (TREE_CODE (context) == NAMESPACE_DECL)
pop_nested_namespace (context);
*************** instantiate_class_template (tree type)
*** 7883,7896 ****
if (BINFO_N_BASE_BINFOS (pbinfo))
{
tree pbase_binfo;
- tree context = TYPE_CONTEXT (type);
tree pushed_scope;
int i;
/* We must enter the scope containing the type, as that is where
the accessibility of types named in dependent bases are
looked up from. */
! pushed_scope = push_scope (context ? context : global_namespace);
/* Substitute into each of the bases to determine the actual
basetypes. */
--- 7883,7895 ----
if (BINFO_N_BASE_BINFOS (pbinfo))
{
tree pbase_binfo;
tree pushed_scope;
int i;
/* We must enter the scope containing the type, as that is where
the accessibility of types named in dependent bases are
looked up from. */
! pushed_scope = push_scope (CP_TYPE_CONTEXT (type));
/* Substitute into each of the bases to determine the actual
basetypes. */
*************** tsubst (tree t, tree args, tsubst_flags_
*** 10012,10018 ****
|| t == void_type_node
|| t == char_type_node
|| t == unknown_type_node
! || TREE_CODE (t) == NAMESPACE_DECL)
return t;
if (DECL_P (t))
--- 10011,10018 ----
|| t == void_type_node
|| t == char_type_node
|| t == unknown_type_node
! || TREE_CODE (t) == NAMESPACE_DECL
! || TREE_CODE (t) == TRANSLATION_UNIT_DECL)
return t;
if (DECL_P (t))
Index: gcc/tree.h
===================================================================
*** gcc/tree.h.orig 2010-09-28 12:29:24.000000000 +0200
--- gcc/tree.h 2010-09-28 16:15:47.000000000 +0200
*************** struct GTY(()) tree_decl_minimal {
*** 2687,2696 ****
#define DECL_LANG_FLAG_8(NODE) \
(DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_8)
/* Nonzero for a decl which is at file scope. */
! #define DECL_FILE_SCOPE_P(EXP) \
! (! DECL_CONTEXT (EXP) \
! || TREE_CODE (DECL_CONTEXT (EXP)) == TRANSLATION_UNIT_DECL)
/* Nonzero for a decl that is decorated using attribute used.
This indicates to compiler tools that this decl needs to be preserved. */
--- 2687,2699 ----
#define DECL_LANG_FLAG_8(NODE) \
(DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_8)
+ /* Nonzero for a scope which is equal to file scope. */
+ #define SCOPE_FILE_SCOPE_P(EXP) \
+ (! (EXP) || TREE_CODE (EXP) == TRANSLATION_UNIT_DECL)
/* Nonzero for a decl which is at file scope. */
! #define DECL_FILE_SCOPE_P(EXP) SCOPE_FILE_SCOPE_P (DECL_CONTEXT (EXP))
! /* Nonzero for a type which is at file scope. */
! #define TYPE_FILE_SCOPE_P(EXP) SCOPE_FILE_SCOPE_P (TYPE_CONTEXT (EXP))
/* Nonzero for a decl that is decorated using attribute used.
This indicates to compiler tools that this decl needs to be preserved. */
Index: gcc/cp/cxx-pretty-print.c
===================================================================
*** gcc/cp/cxx-pretty-print.c.orig 2010-09-28 12:29:24.000000000 +0200
--- gcc/cp/cxx-pretty-print.c 2010-09-28 16:15:47.000000000 +0200
*************** pp_cxx_template_keyword_if_needed (cxx_p
*** 260,266 ****
static void
pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
{
! if (t != NULL && t != pp->enclosing_scope)
{
tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
pp_cxx_nested_name_specifier (pp, scope);
--- 260,266 ----
static void
pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
{
! if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
{
tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
pp_cxx_nested_name_specifier (pp, scope);