diff options
author | Mike Stump <mrs@gcc.gnu.org> | 1995-05-16 21:10:32 +0000 |
---|---|---|
committer | Mike Stump <mrs@gcc.gnu.org> | 1995-05-16 21:10:32 +0000 |
commit | a9aedbc26d61fbe2fef53254408dbbb37c3992fa (patch) | |
tree | 028f47896fbbf644d31fd3de7372df8ca1a6bd39 /gcc | |
parent | 45ca9d09a13dac9ef4d013ede726cfa1e270649c (diff) | |
download | gcc-a9aedbc26d61fbe2fef53254408dbbb37c3992fa.zip gcc-a9aedbc26d61fbe2fef53254408dbbb37c3992fa.tar.gz gcc-a9aedbc26d61fbe2fef53254408dbbb37c3992fa.tar.bz2 |
71st Cygnus<->FSF merge
From-SVN: r9719
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 70 | ||||
-rw-r--r-- | gcc/cp/call.c | 9 | ||||
-rw-r--r-- | gcc/cp/class.c | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 3 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 8 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 444 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 78 | ||||
-rw-r--r-- | gcc/cp/error.c | 4 | ||||
-rw-r--r-- | gcc/cp/init.c | 54 | ||||
-rw-r--r-- | gcc/cp/lex.c | 19 | ||||
-rw-r--r-- | gcc/cp/parse.y | 13 | ||||
-rw-r--r-- | gcc/cp/pt.c | 8 | ||||
-rw-r--r-- | gcc/cp/spew.c | 5 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 68 |
15 files changed, 622 insertions, 173 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1a2624b..9e97ca6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,73 @@ +Tue May 16 12:40:16 1995 Jason Merrill <jason@lisa.cygnus.com> + + * lex.c (handle_sysv_pragma): Don't use token_buffer. + +Tue May 16 12:05:26 1995 Mike Stump <mrs@cygnus.com> + + * call.c (resolve_scope_to_name): Add initial semantic support for + namespaces. + * class.c (finish_struct): Ditto. + * cp-tree.h (NAMESPACE_LEVEL): Ditto. + * cvt.c (build_up_reference, convert_to_reference): Ditto. + * decl.c (binding_level::namespace_p, suspend_binding_level): Ditto. + (resume_binding_level, toplevel_bindings_p): Ditto + (namespace_bindings_p, declare_namespace_level): Ditto. + (resume_level, push_namespace, pop_namespace): Ditto. + (pop_everything, pushtag, duplicate_decls, pushdecl): Ditto. + (implicitly_declare, lookup_namespace_name, lookup_name_real): Ditto. + (start_decl, make_temporary_for_reference), Ditto. + (obscure_complex_init, finish_decl, expand_static_init): Ditto. + (grokvardecl, grokdeclarator, parmlist_is_exprlist): Ditto. + (store_parm_decls, hack_incomplete_structures): Ditto. + * decl2.c (get_temp_name, finish_anon_union, current_namespace): Ditto. + (push_namespace, pop_namespace, do_namespace_alias): Ditto. + (do_toplevel_using_decl, do_class_using_decl): Ditto. + * error.c (dump_decl): Ditto. + * init.c (build_member_call, build_offset_ref): Ditto. + * lex.c (identifier_type): Ditto. + * parse.y (lang_extdef, using_decl, extdef, component_decl_1): Ditto. + (nested_name_specifier_1): Ditto. + * spew.c (yylex): Ditto. + * tree.def (NAMESPACE_DECL): Ditto. + +Tue May 16 11:55:35 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * decl.c (push_overloaded_decl): Return the new decl even if it + can't be pushed. + +Tue May 16 11:00:37 1995 Jason Merrill <jason@lisa.cygnus.com> + + * typeck.c (decay_conversion): Split out from default_conversion. + (default_conversion): Call it. + (build_binary_op): Ditto. + (build_binary_op_nodefault): Use decay_conversion for truth ops. + +Mon May 15 12:47:56 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * decl.c (warn_extern_redeclared_static): This is a pedwarn. + (duplicate_decls): Always use the old decl's linkage info. Don't + play with linkage of consts. + (pushdecl): Don't play with linkage of consts. + (redeclaration_error_message): Don't complain about an old public + decl and a new non-public decl here. + (grokvardecl): Handle linkage of consts here. + (grokdeclarator): An 'extern inline' is public. Pass constp to + grokvardecl. + (start_function): Wait until after the pushdecl to do some linkage + stuff. + + * decl2.c (import_export_vtable): Make duplicates weak rather than + static if supported. + (import_export_inline): Ditto. + * pt.c (do_pending_expansions): Ditto. + + * class.c (build_vbase_path): flag_assume_nonnull_objects only + affects reference conversion. + + * init.c (emit_base_init): Build up an RTL_EXPR and add it to + rtl_expr_chain. + * decl.c, decl2.c: s/base_init_insns/base_init_expr/. + Tue May 16 07:06:28 1995 Paul Eggert <eggert@twinsun.com> * method.c (numeric_output_need_bar): Renamed from misspelling. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 9695968..ae14d8f 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1380,6 +1380,7 @@ resolve_scope_to_name (outer_type, inner_stuff) if (outer_type == NULL_TREE) { + tree x; /* If we have something that's already a type by itself, use that. */ if (IDENTIFIER_HAS_TYPE_VALUE (inner_name)) @@ -1389,6 +1390,14 @@ resolve_scope_to_name (outer_type, inner_stuff) inner_type); return inner_name; } + + x = lookup_name (inner_name, 0); + + if (x && TREE_CODE (x) == NAMESPACE_DECL) + { + x = lookup_namespace_name (x, inner_type); + return x; + } return NULL_TREE; } diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 08c2b53..7463058 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -237,7 +237,9 @@ build_vbase_path (code, type, expr, path, alias_this) } ind = build_indirect_ref (nonnull_expr, NULL_PTR); nonnull_expr = build_vbase_pointer (ind, last_virtual); - if (nonnull == 0 && !flag_assume_nonnull_objects + if (nonnull == 0 + && (TREE_CODE (type) == POINTER_TYPE + || !flag_assume_nonnull_objects) && null_expr == NULL_TREE) { null_expr = build1 (NOP_EXPR, TYPE_POINTER_TO (last_virtual), integer_zero_node); @@ -4106,7 +4108,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) } /* Finish debugging output for this type. */ - rest_of_type_compilation (t, global_bindings_p ()); + rest_of_type_compilation (t, toplevel_bindings_p ()); return t; } diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index 4f33c9f..f8a2fc7 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -101,3 +101,6 @@ DEFTREECODE (UNINSTANTIATED_P_TYPE, "uninstantiated_p_type", "t", 0) Other kinds of thunks may be defined later. */ DEFTREECODE (THUNK_DECL, "thunk_decl", "d", 0) + +/* A namespace declaration. */ +DEFTREECODE (NAMESPACE_DECL, "namespace_decl", "d", 0) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f2e3c48..e2e72d4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -928,6 +928,9 @@ struct lang_type /* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that this type can raise. */ #define TYPE_RAISES_EXCEPTIONS(NODE) TYPE_NONCOPIED_PARTS (NODE) + +/* The binding level associated with the namespace. */ +#define NAMESPACE_LEVEL(NODE) ((NODE)->decl.arguments) struct lang_decl_flags { @@ -1956,6 +1959,7 @@ extern tree type_promotes_to PROTO((tree)); /* decl.c */ extern int global_bindings_p PROTO((void)); +extern int toplevel_bindings_p PROTO((void)); extern void keep_next_level PROTO((void)); extern int kept_level_p PROTO((void)); extern void declare_parm_level PROTO((void)); @@ -2002,6 +2006,7 @@ extern tree gettags PROTO((void)); extern void set_current_level_tags_transparency PROTO((int)); extern tree typedecl_for_tag PROTO((tree)); extern tree lookup_name PROTO((tree, int)); +extern tree lookup_namespace_name PROTO((tree, tree)); extern tree lookup_name_current_level PROTO((tree)); extern void init_decl_processing PROTO((void)); /* skipped define_function */ @@ -2072,7 +2077,8 @@ extern tree reparse_decl_as_expr PROTO((tree, tree)); extern tree finish_decl_parsing PROTO((tree)); extern tree lookup_name_nonclass PROTO((tree)); extern tree check_cp_case_value PROTO((tree)); -extern tree do_using_decl PROTO((tree)); +extern tree do_toplevel_using_decl PROTO((tree)); +extern tree do_class_using_decl PROTO((tree)); extern tree current_namespace_id PROTO((tree)); extern tree get_namespace_id PROTO((void)); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 3bde08d..adc8b64 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -593,7 +593,7 @@ build_up_reference (type, arg, flags, checkconst) else { temp = get_temp_name (argtype, 0); - if (global_bindings_p ()) + if (toplevel_bindings_p ()) { /* Give this new temp some rtl and initialize it. */ DECL_INITIAL (temp) = targ; @@ -770,10 +770,10 @@ convert_to_reference (reftype, expr, convtype, flags, decl) { tree init; - if (global_bindings_p ()) + if (toplevel_bindings_p ()) { extern tree static_aggregates; - tree t = get_temp_name (type, global_bindings_p ()); + tree t = get_temp_name (type, toplevel_bindings_p ()); init = build_method_call (t, constructor_name_full (type), build_tree_list (NULL_TREE, expr), TYPE_BINFO (type), diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e695ce2..8ca4e23 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -286,7 +286,7 @@ extern rtx cleanup_label, return_label; rtx original_result_rtx; /* Sequence of insns which represents base initialization. */ -rtx base_init_insns; +tree base_init_expr; /* C++: Keep these around to reduce calls to `get_identifier'. Identifiers for `this' in member functions and the auto-delete @@ -578,7 +578,10 @@ struct binding_level unfortunately.) */ unsigned pseudo_global : 1; - /* Two bits left for this word. */ + /* This is set for a namespace binding level. */ + unsigned namespace_p : 1; + + /* One bit left for this word. */ #if defined(DEBUG_CP_BINDING_LEVELS) /* Binding depth at which this level began. */ @@ -713,6 +716,90 @@ pop_binding_level () current_binding_level = current_binding_level->level_chain; } } + +static void +suspend_binding_level () +{ + if (class_binding_level) + current_binding_level = class_binding_level; + + if (global_binding_level) + { + /* cannot suspend a level, if there are none left to suspend. */ + if (current_binding_level == global_binding_level) + my_friendly_abort (123); + } + /* Suspend the current level. */ +#if defined(DEBUG_CP_BINDING_LEVELS) + binding_depth--; + indent (); + fprintf (stderr, "suspend %s level 0x%08x line %d\n", + (is_class_level) ? "class" : "block", + current_binding_level, lineno); + if (is_class_level != (current_binding_level == class_binding_level)) +#if 0 /* XXX Don't abort when we're watching how things are being managed. */ + abort (); +#else + { + indent (); + fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); + } +#endif + is_class_level = 0; +#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ + { + register struct binding_level *level = current_binding_level; + current_binding_level = current_binding_level->level_chain; +#if 0 /* defined(DEBUG_CP_BINDING_LEVELS) */ + if (level->binding_depth != binding_depth) + abort (); +#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ + + class_binding_level = current_binding_level; + if (class_binding_level->parm_flag != 2) + class_binding_level = 0; + while (current_binding_level->parm_flag == 2) + current_binding_level = current_binding_level->level_chain; + } +} + +void +resume_binding_level (b) + struct binding_level *b; +{ + if (class_binding_level) + { +#if 1 + /* These are here because we cannot deal with shadows yet. */ + sorry ("cannot resume a namespace inside class"); + return; +#else + b->level_chain = class_binding_level; + class_binding_level = (struct binding_level *)0; +#endif + } + else + { +#if 1 + /* These are here because we cannot deal with shadows yet. */ + if (b->level_chain != current_binding_level) + { + sorry ("cannot resume a namespace inside a different namespace"); + return; + } +#endif + b->level_chain = current_binding_level; + } + current_binding_level = b; +#if defined(DEBUG_CP_BINDING_LEVELS) + b->binding_depth = binding_depth; + indent (); + fprintf (stderr, "resume %s level 0x%08x line %d\n", + (is_class_level) ? "class" : "block", b, lineno); + is_class_level = 0; + binding_depth++; +#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ +} /* Nonzero if we are currently in the global binding level. */ @@ -722,6 +809,33 @@ global_bindings_p () return current_binding_level == global_binding_level; } +/* Nonzero if we are currently in a toplevel binding level. This + means either the global binding level or a namespace in a toplevel + binding level. */ + +int +toplevel_bindings_p () +{ + struct binding_level *b = current_binding_level; + + while (1) + { + if (b == global_binding_level) + return 1; + if (! b->namespace_p) + return 0; + b=b->level_chain; + } +} + +/* Nonzero if this is a namespace scope. */ + +int +namespace_bindings_p () +{ + return current_binding_level->namespace_p; +} + void keep_next_level () { @@ -766,6 +880,12 @@ declare_pseudo_global_level () current_binding_level->pseudo_global = 1; } +void +declare_namespace_level () +{ + current_binding_level->namespace_p = 1; +} + int pseudo_global_level_p () { @@ -1110,6 +1230,31 @@ poplevel (keep, reverse, functionbody) return block; } +/* Resume a binding level for a namespace. */ +void +resume_level (b) + struct binding_level *b; +{ + tree decls, link; + + resume_binding_level (b); + + /* Resume the variable caches. */ + decls = current_binding_level->names; + + /* Restore the meanings of the local variables of this level. */ + + for (link = decls; link; link = TREE_CHAIN (link)) + { + if (DECL_NAME (link) != NULL_TREE) + IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = link; + + /* If this is a TYPE_DECL, push it into the type value slot. */ + if (TREE_CODE (link) == TYPE_DECL) + SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (link), TREE_TYPE (link)); + } +} + /* Delete the node BLOCK from the current binding level. This is used for the block inside a stmt expr ({...}) so that the block can be reinserted where appropriate. */ @@ -1428,6 +1573,95 @@ print_binding_stack () fprintf (stderr, "global:\n"); print_binding_level (global_binding_level); } + +/* Push into the scope of the NAME namespace. */ +void +push_namespace (name) + tree name; +{ + extern tree current_namespace; + tree old_id = get_namespace_id (); + char *buf; + tree d = make_node (NAMESPACE_DECL); + + DECL_NAME (d) = name; + DECL_ASSEMBLER_NAME (d) = name; + /* pushdecl wants to check the size of it to see if it is incomplete... */ + TREE_TYPE (d) = void_type_node; + /* Mark them as external, so redeclaration_error_message doesn't think + they are duplicates. */ + DECL_EXTERNAL (d) = 1; + d = pushdecl (d); + + if (NAMESPACE_LEVEL (d) == 0) + { + /* This is new for this compilation unit. */ + pushlevel (0); + declare_namespace_level (); + NAMESPACE_LEVEL (d) = (tree)current_binding_level; + } + else + { + resume_level ((struct binding_level*)NAMESPACE_LEVEL (d)); + } + + /* This code is just is bit old now... */ + current_namespace = tree_cons (NULL_TREE, name, current_namespace); + buf = (char *) alloca (4 + (old_id ? IDENTIFIER_LENGTH (old_id) : 0) + + IDENTIFIER_LENGTH (name)); + sprintf (buf, "%s%s", old_id ? IDENTIFIER_POINTER (old_id) : "", + IDENTIFIER_POINTER (name)); + TREE_PURPOSE (current_namespace) = get_identifier (buf); +} + +/* Pop from the scope of the current namespace. */ +void +pop_namespace () +{ + extern tree current_namespace; + tree decls, link; + current_namespace = TREE_CHAIN (current_namespace); + + /* Just in case we get out of sync. */ + if (! namespace_bindings_p ()) + poplevel (0, 0, 0); + + decls = current_binding_level->names; + + /* Clear out the meanings of the local variables of this level. */ + + for (link = decls; link; link = TREE_CHAIN (link)) + { + if (DECL_NAME (link) != NULL_TREE) + { + /* If the ident. was used or addressed via a local extern decl, + don't forget that fact. */ + if (DECL_EXTERNAL (link)) + { + if (TREE_USED (link)) + TREE_USED (DECL_ASSEMBLER_NAME (link)) = 1; + if (TREE_ADDRESSABLE (link)) + TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1; + } + IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE; + } + } + + /* Restore all name-meanings of the outer levels + that were shadowed by this level. */ + + for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link)) + IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); + for (link = current_binding_level->class_shadowed; + link; link = TREE_CHAIN (link)) + IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); + for (link = current_binding_level->type_shadowed; + link; link = TREE_CHAIN (link)) + IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); + + /* suspend a level. */ + suspend_binding_level (); +} /* Subroutines for reverting temporarily to top-level for instantiation of templates and such. We actually need to clear out the class- and @@ -1677,15 +1911,16 @@ set_nested_typename (decl, classname, name, type) } } -/* Pop off extraneous binding levels left over due to syntax errors. */ +/* Pop off extraneous binding levels left over due to syntax errors. + + We don't pop past namespaces, as they might be valid. */ void pop_everything () { #ifdef DEBUG_CP_BINDING_LEVELS fprintf (stderr, "XXX entering pop_everything ()\n"); #endif - while (current_binding_level != global_binding_level - && ! current_binding_level->pseudo_global) + while (! toplevel_bindings_p () && ! pseudo_global_level_p ()) { if (class_binding_level) pop_nested_class (1); @@ -1747,7 +1982,7 @@ pushtag (name, type, globalize) || (globalize && b->parm_flag == 2)) b = b->level_chain; - if (b == global_binding_level) + if (toplevel_bindings_p ()) b->tags = perm_tree_cons (name, type, b->tags); else b->tags = saveable_tree_cons (name, type, b->tags); @@ -2092,11 +2327,11 @@ warn_extern_redeclared_static (newdecl, olddecl) && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl)))) { - cp_warning (IDENTIFIER_IMPLICIT_DECL (name) + cp_pedwarn (IDENTIFIER_IMPLICIT_DECL (name) ? implicit_extern_static_warning : explicit_extern_static_warning, newdecl); if (olddecl != NULL_TREE) - cp_warning_at ("previous declaration of `%D'", olddecl); + cp_pedwarn_at ("previous declaration of `%D'", olddecl); } } } @@ -2507,35 +2742,17 @@ duplicate_decls (newdecl, olddecl) } /* Merge the storage class information. */ - if (DECL_EXTERNAL (newdecl) && ! DECL_INTERFACE_KNOWN (newdecl) - && ! (DECL_LANG_SPECIFIC (newdecl) && DECL_NOT_REALLY_EXTERN (newdecl))) - { - TREE_STATIC (newdecl) = TREE_STATIC (olddecl); - DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl); - TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); + DECL_WEAK (newdecl) |= DECL_WEAK (olddecl); + TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); + TREE_STATIC (olddecl) = TREE_STATIC (newdecl) |= TREE_STATIC (olddecl); + if (! DECL_EXTERNAL (olddecl)) + DECL_EXTERNAL (newdecl) = 0; - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - DECL_C_STATIC (newdecl) = DECL_C_STATIC (olddecl); - DECL_INTERFACE_KNOWN (newdecl) = DECL_INTERFACE_KNOWN (olddecl); - DECL_NOT_REALLY_EXTERN (newdecl) = DECL_NOT_REALLY_EXTERN (olddecl); - } - } - else + if (TREE_CODE (newdecl) == FUNCTION_DECL) { - TREE_STATIC (olddecl) = TREE_STATIC (newdecl); - /* A `const' which was not declared `extern' gets internal linkage. */ - if (TREE_CODE (newdecl) == VAR_DECL - && TREE_READONLY (newdecl) && ! DECL_THIS_EXTERN (newdecl)) - TREE_PUBLIC (newdecl) = 0; - else - { - TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); - - /* If this clears PUBLIC, clear it in the identifier too. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL && ! TREE_PUBLIC (olddecl)) - TREE_PUBLIC (DECL_ASSEMBLER_NAME (olddecl)) = 0; - } + DECL_C_STATIC (newdecl) = DECL_C_STATIC (olddecl); + DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl); + DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl); } if (TREE_CODE (newdecl) == FUNCTION_DECL) @@ -2588,6 +2805,11 @@ duplicate_decls (newdecl, olddecl) DECL_MAIN_VARIANT (newdecl) = DECL_MAIN_VARIANT (olddecl); } + if (TREE_CODE (newdecl) == NAMESPACE_DECL) + { + NAMESPACE_LEVEL (newdecl) = NAMESPACE_LEVEL (olddecl); + } + if (TREE_CODE (newdecl) == TEMPLATE_DECL) { if (DECL_TEMPLATE_INFO (olddecl)->length) @@ -2722,7 +2944,8 @@ pushdecl (x) #else /* Type are looked up using the DECL_NAME, as that is what the rest of the compiler wants to use. */ - if (TREE_CODE (x) == TYPE_DECL || TREE_CODE (x) == VAR_DECL) + if (TREE_CODE (x) == TYPE_DECL || TREE_CODE (x) == VAR_DECL + || TREE_CODE (x) == NAMESPACE_DECL) name = DECL_NAME (x); #endif @@ -2907,12 +3130,6 @@ pushdecl (x) { /* Install a global value. */ - /* Rule for VAR_DECLs, but not for other kinds of _DECLs: - A `const' which was not declared `extern' is invisible. */ - if (TREE_CODE (x) == VAR_DECL - && TREE_READONLY (x) && ! DECL_THIS_EXTERN (x)) - TREE_PUBLIC (x) = 0; - /* If the first global decl has external linkage, warn if we later see static one. */ if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && DECL_PUBLIC (x)) @@ -2968,6 +3185,12 @@ pushdecl (x) if (TREE_CODE (x) == TYPE_DECL) set_identifier_type_value_with_scope (name, TREE_TYPE (x), b); + /* Clear out any TYPE_DECL shadowed by a namespace so that + we won't think this is a type. The C struct hack doesn't + go through namespaces. */ + if (TREE_CODE (x) == NAMESPACE_DECL) + set_identifier_type_value_with_scope (name, NULL_TREE, b); + /* If this is an extern function declaration, see if we have a global definition or declaration for the function. */ if (oldlocal == NULL_TREE @@ -3352,7 +3575,7 @@ push_overloaded_decl (decl, forgettable) { cp_error_at ("previous non-function declaration `%#D'", old); cp_error ("conflicts with function declaration `%#D'", decl); - return error_mark_node; + return decl; } } @@ -3392,8 +3615,7 @@ implicitly_declare (functionid) /* Save the decl permanently so we can warn if definition follows. In ANSI C, warn_implicit is usually false, so the saves little space. But in C++, it's usually true, hence the extra code. */ - if (temp && (flag_traditional || !warn_implicit - || current_binding_level == global_binding_level)) + if (temp && (flag_traditional || !warn_implicit || toplevel_bindings_p ())) end_temporary_allocation (); /* We used to reuse an old implicit decl here, @@ -3475,9 +3697,6 @@ redeclaration_error_message (newdecl, olddecl) else if (current_binding_level == global_binding_level) { /* Objects declared at top level: */ - /* Insist that the linkage match. */ - if (! TREE_PUBLIC (newdecl) && TREE_PUBLIC (olddecl)) - return "conflicting declarations of `%#D'"; /* If at least one is a reference, it's ok. */ if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl)) return 0; @@ -3998,6 +4217,25 @@ lookup_nested_type (type, context) return NULL_TREE; } +/* Look up NAME in the NAMESPACE. */ +tree +lookup_namespace_name (namespace, name) + tree namespace, name; +{ + struct binding_level *b = (struct binding_level *)NAMESPACE_LEVEL (namespace); + tree x; + + for (x = NULL_TREE; b && !x; b = b->level_chain) + { + for (x = b->names; x; x = TREE_CHAIN (x)) + if (DECL_NAME (x) == name || DECL_ASSEMBLER_NAME (x) == name) + break; + /* Must find directly in the namespace. */ + break; + } + return x; +} + /* Look up NAME in the current binding level and its superiors in the namespace of variables, functions and typedefs. Return a ..._DECL node of some kind representing its definition if there is only one @@ -4045,6 +4283,10 @@ lookup_name_real (name, prefer_type, nonclass) else val = NULL_TREE; } + else if (TREE_CODE (type) == NAMESPACE_DECL) + { + val = lookup_namespace_name (type, name); + } else if (! IS_AGGR_TYPE (type)) /* Someone else will give an error about this if needed. */ val = NULL_TREE; @@ -5579,12 +5821,12 @@ start_decl (declarator, declspecs, initialized, raises) if (initialized) { - if (current_binding_level != global_binding_level + if (! toplevel_bindings_p () && DECL_EXTERNAL (decl)) cp_warning ("declaration of `%#D' has `extern' and is initialized", decl); DECL_EXTERNAL (decl) = 0; - if (current_binding_level == global_binding_level) + if ( toplevel_bindings_p ()) TREE_STATIC (decl) = 1; /* Tell `pushdecl' this is an initialized decl @@ -5636,7 +5878,7 @@ start_decl (declarator, declspecs, initialized, raises) #if 0 /* We don't do this yet for GNU C++. */ /* For a local variable, define the RTL now. */ - if (current_binding_level != global_binding_level + if (! toplevel_bindings_p () /* But not if this is a duplicate decl and we preserved the rtl from the previous one (which may or may not happen). */ @@ -5713,7 +5955,7 @@ start_decl (declarator, declspecs, initialized, raises) { /* When parsing and digesting the initializer, use temporary storage. Do this even if we will ignore the value. */ - if (current_binding_level == global_binding_level && debug_temp_inits) + if (toplevel_bindings_p () && debug_temp_inits) { if (TYPE_NEEDS_CONSTRUCTING (type) || TREE_CODE (type) == REFERENCE_TYPE) @@ -5751,8 +5993,7 @@ make_temporary_for_reference (decl, ctor_call, init, cleanupp) } else { - tmp = get_temp_name (target_type, - current_binding_level == global_binding_level); + tmp = get_temp_name (target_type, toplevel_bindings_p ()); tmp_addr = build_unary_op (ADDR_EXPR, tmp, 0); } @@ -5761,7 +6002,7 @@ make_temporary_for_reference (decl, ctor_call, init, cleanupp) TREE_TYPE (DECL_INITIAL (decl)) = type; if (TYPE_NEEDS_CONSTRUCTING (target_type)) { - if (current_binding_level == global_binding_level) + if (toplevel_bindings_p ()) { /* lay this variable out now. Otherwise `output_addressed_constants' gets confused by its initializer. */ @@ -5784,7 +6025,7 @@ make_temporary_for_reference (decl, ctor_call, init, cleanupp) else { DECL_INITIAL (tmp) = init; - TREE_STATIC (tmp) = current_binding_level == global_binding_level; + TREE_STATIC (tmp) = toplevel_bindings_p (); finish_decl (tmp, init, NULL_TREE, 0, LOOKUP_ONLYCONVERTING); } if (TREE_STATIC (tmp)) @@ -5920,8 +6161,7 @@ obscure_complex_init (decl, init) return NULL_TREE; } - if (current_binding_level == global_binding_level - && ! DECL_COMMON (decl)) + if (toplevel_bindings_p () && ! DECL_COMMON (decl)) DECL_INITIAL (decl) = build (CONSTRUCTOR, TREE_TYPE (decl), NULL_TREE, NULL_TREE); else @@ -5988,7 +6228,7 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags) if (type == error_mark_node) { - if (current_binding_level == global_binding_level && temporary) + if (toplevel_bindings_p () && temporary) end_temporary_allocation (); return; @@ -6081,7 +6321,7 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags) { if (TREE_STATIC (decl)) make_decl_rtl (decl, NULL_PTR, - current_binding_level == global_binding_level + toplevel_bindings_p () || pseudo_global_level_p ()); grok_reference_init (decl, type, init, &cleanup); init = NULL_TREE; @@ -6220,7 +6460,7 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags) must go in the permanent obstack; but don't discard the temporary data yet. */ - if (current_binding_level == global_binding_level && temporary) + if (toplevel_bindings_p () && temporary) end_temporary_allocation (); /* Deduce size of array from initialization, if not already known. */ @@ -6339,8 +6579,7 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags) || TREE_CODE (decl) == RESULT_DECL) { /* ??? FIXME: What about nested classes? */ - int toplev = (current_binding_level == global_binding_level - || pseudo_global_level_p ()); + int toplev = toplevel_bindings_p () || pseudo_global_level_p (); int was_temp = ((flag_traditional || (TREE_STATIC (decl) && TYPE_NEEDS_DESTRUCTOR (type))) @@ -6350,7 +6589,7 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags) end_temporary_allocation (); if (TREE_CODE (decl) == VAR_DECL - && current_binding_level != global_binding_level + && ! toplevel_bindings_p () && ! TREE_STATIC (decl) && type_needs_gc_entry (type)) DECL_GC_OFFSET (decl) = size_int (++current_function_obstack_index); @@ -6606,8 +6845,7 @@ expand_static_init (decl, init) if (TREE_PURPOSE (oldstatic) && init != NULL_TREE) cp_error ("multiple initializations given for `%D'", decl); } - else if (current_binding_level != global_binding_level - && current_binding_level->pseudo_global == 0) + else if (! toplevel_bindings_p () && ! pseudo_global_level_p ()) { /* Emit code to perform this initialization but once. */ tree temp; @@ -7005,11 +7243,12 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals, } static tree -grokvardecl (type, declarator, specbits, initialized) +grokvardecl (type, declarator, specbits, initialized, constp) tree type; tree declarator; RID_BIT_TYPE specbits; int initialized; + int constp; { tree decl; @@ -7046,9 +7285,10 @@ grokvardecl (type, declarator, specbits, initialized) } /* At top level, either `static' or no s.c. makes a definition (perhaps tentative), and absence of `static' makes it public. */ - else if (current_binding_level == global_binding_level) + else if (toplevel_bindings_p ()) { - TREE_PUBLIC (decl) = RIDBIT_NOTSETP (RID_STATIC, specbits); + TREE_PUBLIC (decl) = (RIDBIT_NOTSETP (RID_STATIC, specbits) + && (DECL_EXTERNAL (decl) || ! constp)); TREE_STATIC (decl) = ! DECL_EXTERNAL (decl); } /* Not at top level, only `static' makes a static definition. */ @@ -7471,11 +7711,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) Since we now wait to push a class scope until we are sure that we are in a legitimate method context, we must set oldcname - explicitly (since current_class_name is not yet alive). */ + explicitly (since current_class_name is not yet alive). + + We also want to avoid calling this a PARM if it is in a namespace. */ - if (decl_context == NORMAL - && current_binding_level->level_chain == global_binding_level) - decl_context = PARM; + if (decl_context == NORMAL && ! namespace_bindings_p ()) + { + struct binding_level *b = current_binding_level; + current_binding_level = b->level_chain; + if (current_binding_level != 0 && toplevel_bindings_p ()) + decl_context = PARM; + current_binding_level = b; + } /* Look through the decl specs and record which ones appear. Some typespecs are defined as built-in typenames. @@ -8048,7 +8295,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) } else if (RIDBIT_SETP (RID_EXTERN, specbits) && initialized && !funcdef_flag) { - if (current_binding_level == global_binding_level) + if (toplevel_bindings_p ()) { /* It's common practice (and completely valid) to have a const be initialized and declared extern. */ @@ -8059,9 +8306,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) error ("`%s' has both `extern' and initializer", name); } else if (RIDBIT_SETP (RID_EXTERN, specbits) && funcdef_flag - && current_binding_level != global_binding_level) + && ! toplevel_bindings_p ()) error ("nested function `%s' declared `extern'", name); - else if (current_binding_level == global_binding_level) + else if (toplevel_bindings_p ()) { if (RIDBIT_SETP (RID_AUTO, specbits)) error ("top-level declaration of `%s' specifies `auto'", name); @@ -9240,7 +9487,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) /* Function declaration not at top level. Storage classes other than `extern' are not allowed and `extern' makes no difference. */ - if (current_binding_level != global_binding_level + if (! toplevel_bindings_p () && ! processing_template_decl && (RIDBIT_SETP (RID_STATIC, specbits) || RIDBIT_SETP (RID_INLINE, specbits)) @@ -9277,6 +9524,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) /* Record presence of `static'. In C++, `inline' implies `static'. */ publicp = (ctype != NULL_TREE + || RIDBIT_SETP (RID_EXTERN, specbits) || (!RIDBIT_SETP (RID_STATIC, specbits) && !RIDBIT_SETP (RID_INLINE, specbits))); @@ -9346,7 +9594,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) } /* An uninitialized decl with `extern' is a reference. */ - decl = grokvardecl (type, declarator, specbits, initialized); + decl = grokvardecl (type, declarator, specbits, initialized, constp); bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); @@ -9416,7 +9664,7 @@ parmlist_is_exprlist (exprs) if (exprs == NULL_TREE || TREE_PARMLIST (exprs)) return 0; - if (current_binding_level == global_binding_level) + if (toplevel_bindings_p ()) { /* At the global level, if these are all identifiers, then it is a parmlist. */ @@ -10724,7 +10972,7 @@ start_function (declspecs, declarator, raises, pre_parsed_p) original_result_rtx = NULL_RTX; current_function_obstack_index = 0; current_function_obstack_usage = 0; - base_init_insns = NULL_RTX; + base_init_expr = NULL_TREE; protect_list = NULL_TREE; current_base_init_list = NULL_TREE; current_member_init_list = NULL_TREE; @@ -10905,14 +11153,8 @@ start_function (declspecs, declarator, raises, pre_parsed_p) So clear DECL_EXTERNAL. */ DECL_EXTERNAL (decl1) = 0; - if (DECL_THIS_INLINE (decl1) && ! DECL_C_STATIC (decl1)) - DECL_DEFER_OUTPUT (decl1) = 1; - else - { - DECL_INTERFACE_KNOWN (decl1) = 1; - if (DECL_C_STATIC (decl1)) - TREE_PUBLIC (decl1) = 0; - } + if (DECL_C_STATIC (decl1)) + TREE_PUBLIC (decl1) = 0; } /* Record the decl so that the function name is defined. @@ -10928,6 +11170,11 @@ start_function (declspecs, declarator, raises, pre_parsed_p) else current_function_decl = decl1; + if (DECL_THIS_INLINE (decl1) && ! DECL_INTERFACE_KNOWN (decl1)) + DECL_DEFER_OUTPUT (decl1) = 1; + else + DECL_INTERFACE_KNOWN (decl1) = 1; + if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)) { if (TREE_CODE (fntype) == METHOD_TYPE) @@ -11065,7 +11312,7 @@ store_parm_decls () then CONST_DECLs for foo and bar are put here. */ tree nonparms = NULL_TREE; - if (current_binding_level == global_binding_level) + if (toplevel_bindings_p ()) fatal ("parse errors have confused me too much"); /* Initialize RTL machinery. */ @@ -11512,7 +11759,7 @@ finish_function (lineno, call_poplevel, nested) current_function_assigns_this = 0; current_function_just_assigned_this = 0; - base_init_insns = NULL_RTX; + base_init_expr = NULL_TREE; } else if (DECL_CONSTRUCTOR_P (fndecl)) { @@ -11556,8 +11803,11 @@ finish_function (lineno, call_poplevel, nested) /* Emit insns from `emit_base_init' which sets up virtual function table pointer(s). */ - emit_insns (base_init_insns); - base_init_insns = NULL_RTX; + if (base_init_expr) + { + expand_expr_stmt (base_init_expr); + base_init_expr = NULL_TREE; + } /* This is where the body of the constructor begins. If there were no insns in this function body, then the @@ -12006,7 +12256,7 @@ hack_incomplete_structures (type) layout_type (TREE_TYPE (decl)); else { - int toplevel = global_binding_level == current_binding_level; + int toplevel = toplevel_bindings_p (); if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE && TREE_TYPE (TREE_TYPE (decl)) == type) layout_type (TREE_TYPE (decl)); @@ -12154,7 +12404,7 @@ finish_stmt () zones before calling base constructors. */ if (cond_stack || loop_stack || case_stack) return; - emit_insns (base_init_insns); + expand_expr_stmt (base_init_expr); check_base_init (current_class_type); } current_function_assigns_this = 1; @@ -12215,8 +12465,8 @@ struct cp_function tree protect_list; tree base_init_list; tree member_init_list; + tree base_init_expr; rtx result_rtx; - rtx base_init_insns; struct cp_function *next; struct binding_level *binding_level; }; @@ -12252,7 +12502,7 @@ push_cp_function_context (context) p->just_assigned_this = current_function_just_assigned_this; p->parms_stored = current_function_parms_stored; p->result_rtx = original_result_rtx; - p->base_init_insns = base_init_insns; + p->base_init_expr = base_init_expr; p->protect_list = protect_list; p->temp_name_counter = temp_name_counter; p->base_init_list = current_base_init_list; @@ -12302,7 +12552,7 @@ pop_cp_function_context (context) current_function_just_assigned_this = p->just_assigned_this; current_function_parms_stored = p->parms_stored; original_result_rtx = p->result_rtx; - base_init_insns = p->base_init_insns; + base_init_expr = p->base_init_expr; temp_name_counter = p->temp_name_counter; current_base_init_list = p->base_init_list; current_member_init_list = p->member_init_list; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 3d878a6..5bbc9c8 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -35,6 +35,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "decl.h" #include "lex.h" #include "output.h" +#include "defaults.h" extern tree grokdeclarator (); extern tree get_file_function_name (); @@ -2031,9 +2032,9 @@ constructor_name (thing) void setup_vtbl_ptr () { - extern rtx base_init_insns; + extern rtx base_init_expr; - if (base_init_insns == 0 + if (base_init_expr == 0 && DECL_CONSTRUCTOR_P (current_function_decl)) emit_base_init (current_class_type, 0); @@ -2145,7 +2146,7 @@ get_temp_name (type, staticp) { char buf[sizeof (AUTO_TEMP_FORMAT) + 20]; tree decl; - int toplev = global_bindings_p (); + int toplev = toplevel_bindings_p (); push_obstacks_nochange (); if (toplev || staticp) @@ -2278,7 +2279,7 @@ finish_anon_union (anon_union_decl) { if (main_decl) { - make_decl_rtl (main_decl, 0, global_bindings_p ()); + make_decl_rtl (main_decl, 0, toplevel_bindings_p ()); DECL_RTL (anon_union_decl) = DECL_RTL (main_decl); } else @@ -2568,7 +2569,10 @@ import_export_vtable (decl, type, final) if (TREE_PUBLIC (decl)) cp_error ("all virtual functions redeclared inline"); #endif - TREE_PUBLIC (decl) = 0; + if (SUPPORTS_WEAK) + DECL_WEAK (decl) = 1; + else + TREE_PUBLIC (decl) = 0; DECL_EXTERNAL (decl) = 0; } else @@ -2788,7 +2792,12 @@ import_export_inline (decl) if (DECL_TEMPLATE_INSTANTIATION (decl)) { if (DECL_IMPLICIT_INSTANTIATION (decl) && flag_implicit_templates) - TREE_PUBLIC (decl) = 0; + { + if (SUPPORTS_WEAK) + DECL_WEAK (decl) = 1; + else + TREE_PUBLIC (decl) = 0; + } else DECL_NOT_REALLY_EXTERN (decl) = 0; } @@ -2801,9 +2810,15 @@ import_export_inline (decl) = ! (CLASSTYPE_INTERFACE_ONLY (ctype) || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines)); } + else if (SUPPORTS_WEAK) + DECL_WEAK (decl) = 1; else TREE_PUBLIC (decl) = 0; } + else if (DECL_C_STATIC (decl)) + TREE_PUBLIC (decl) = 0; + else if (SUPPORTS_WEAK) + DECL_WEAK (decl) = 1; else TREE_PUBLIC (decl) = 0; @@ -3116,7 +3131,8 @@ finish_file () tree decl = TREE_VALUE (fnname); import_export_inline (decl); if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl) - && TREE_PUBLIC (decl) && DECL_NOT_REALLY_EXTERN (decl)) + && TREE_PUBLIC (decl) && ! DECL_WEAK (decl) + && DECL_NOT_REALLY_EXTERN (decl)) synthesize_method (decl); } @@ -3169,7 +3185,7 @@ finish_file () continue; } - if (TREE_PUBLIC (decl) + if ((TREE_PUBLIC (decl) && ! DECL_WEAK (decl)) || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) || flag_keep_inline_functions) { @@ -3426,7 +3442,7 @@ check_cp_case_value (value) return value; } -static tree current_namespace; +tree current_namespace; /* Get the inner part of a namespace id. It doesn't have any prefix, nor postfix. Returns 0 if in global namespace. */ @@ -3458,37 +3474,37 @@ current_namespace_id (name) return get_identifier (buf); } -/* Push into the scopre of the NAME namespace. */ void -push_namespace (name) - tree name; +do_namespace_alias (alias, namespace) + tree alias, namespace; { - tree old_id = get_namespace_id (); - char *buf; - - current_namespace = tree_cons (NULL_TREE, name, current_namespace); - buf = (char *) alloca (4 + (old_id ? IDENTIFIER_LENGTH (old_id) : 0) - + IDENTIFIER_LENGTH (name)); - sprintf (buf, "%s%s", old_id ? IDENTIFIER_POINTER (old_id) : "", - IDENTIFIER_POINTER (name)); - TREE_PURPOSE (current_namespace) = get_identifier (buf); } -/* Pop from the scope of the current namespace. */ -void -pop_namespace () +tree +do_toplevel_using_decl (decl) + tree decl; { - current_namespace = TREE_CHAIN (current_namespace); -} + if (decl == NULL_TREE || decl == error_mark_node) + return; -void -do_namespace_alias (alias, namespace) - tree alias, namespace; -{ + if (TREE_CODE (decl) == SCOPE_REF) + decl = resolve_scope_to_name (NULL_TREE, decl); + + /* Is this the right way to do an id list? */ + if (TREE_CODE (decl) != TREE_LIST) + { + pushdecl (decl); + } + else + while (decl) + { + pushdecl (TREE_VALUE (decl)); + decl = TREE_CHAIN (decl); + } } tree -do_using_decl (decl) +do_class_using_decl (decl) tree decl; { return error_mark_node; diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 26905e2..9185724 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -616,6 +616,10 @@ dump_decl (t, v) dump_type_suffix (TREE_TYPE (t), v); break; + case NAMESPACE_DECL: + OB_PUTID (DECL_NAME (t)); + break; + case ARRAY_REF: dump_decl (TREE_OPERAND (t, 0), v); OB_PUTC ('['); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 6b193a3..a70e95f 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -492,12 +492,14 @@ build_partial_cleanup_for (binfo) Argument IMMEDIATELY, if zero, forces a new sequence to be generated to contain these new insns, so it can be emitted later. - This sequence is saved in the global variable BASE_INIT_INSNS. + This sequence is saved in the global variable BASE_INIT_EXPR. Otherwise, the insns are emitted into the current sequence. Note that emit_base_init does *not* initialize virtual base classes. That is done specially, elsewhere. */ - + +extern tree base_init_expr, rtl_expr_chain; + void emit_base_init (t, immediately) tree t; @@ -511,13 +513,20 @@ emit_base_init (t, immediately) tree t_binfo = TYPE_BINFO (t); tree binfos = BINFO_BASETYPES (t_binfo); int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; + tree expr = NULL_TREE; my_friendly_assert (protect_list == NULL_TREE, 999); if (! immediately) { + int momentary; do_pending_stack_adjust (); - start_sequence (); + /* Make the RTL_EXPR node temporary, not momentary, + so that rtl_expr_chain doesn't become garbage. */ + momentary = suspend_momentary (); + expr = make_node (RTL_EXPR); + resume_momentary (momentary); + start_sequence_for_rtl_expr (expr); } if (write_symbols == NO_DEBUG) @@ -670,12 +679,15 @@ emit_base_init (t, immediately) if (! immediately) { - extern rtx base_init_insns; - do_pending_stack_adjust (); - my_friendly_assert (base_init_insns == 0, 207); - base_init_insns = get_insns (); + my_friendly_assert (base_init_expr == 0, 207); + base_init_expr = expr; + TREE_TYPE (expr) = void_type_node; + RTL_EXPR_RTL (expr) = const0_rtx; + RTL_EXPR_SEQUENCE (expr) = get_insns (); + rtl_expr_chain = tree_cons (NULL_TREE, expr, rtl_expr_chain); end_sequence (); + TREE_SIDE_EFFECTS (expr) = 1; } /* All the implicit try blocks we built up will be zapped @@ -1728,6 +1740,18 @@ build_member_call (cname, name, parmlist) if (TREE_CODE (cname) == SCOPE_REF) cname = resolve_scope_to_name (NULL_TREE, cname); + /* This shouldn't be here, and build_member_call shouldn't appear in + parse.y! (mrs) */ + if (cname && get_aggr_from_typedef (cname, 0) == 0 + && TREE_CODE (cname) == IDENTIFIER_NODE) + { + tree ns = lookup_name (cname, 0); + if (ns && TREE_CODE (ns) == NAMESPACE_DECL) + { + return build_x_function_call (build_offset_ref (cname, name), parmlist, current_class_decl); + } + } + if (cname == NULL_TREE || ! (type = get_aggr_from_typedef (cname, 1))) return error_mark_node; @@ -1839,6 +1863,22 @@ build_offset_ref (cname, name) if (TREE_CODE (cname) == SCOPE_REF) cname = resolve_scope_to_name (NULL_TREE, cname); + /* Handle namespace names fully here. */ + if (TREE_CODE (cname) == IDENTIFIER_NODE + && get_aggr_from_typedef (cname, 0) == 0) + { + tree ns = lookup_name (cname, 0); + tree val; + if (ns && TREE_CODE (ns) == NAMESPACE_DECL) + { + val = lookup_namespace_name (ns, name); + if (val) + return val; + cp_error ("namespace `%D' has no member named `%D'", ns, name); + return error_mark_node; + } + } + if (cname == NULL_TREE || ! is_aggr_typedef (cname, 1)) return error_mark_node; diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index a80b900..2d5b8b6 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -2806,6 +2806,8 @@ identifier_type (decl) if (TREE_CODE (decl) == TEMPLATE_DECL && DECL_TEMPLATE_IS_CLASS (decl)) return PTYPENAME; + if (TREE_CODE (decl) == NAMESPACE_DECL) + return NSNAME; if (TREE_CODE (decl) != TYPE_DECL) return IDENTIFIER; return TYPENAME; @@ -4606,13 +4608,26 @@ handle_sysv_pragma () case TYPENAME: case STRING: case CONSTANT: - handle_pragma_token (token_buffer, yylval.ttype); + handle_pragma_token ("ignored", yylval.ttype); + break; + case '(': + handle_pragma_token ("(", NULL_TREE); + break; + case ')': + handle_pragma_token (")", NULL_TREE); + break; + case '=': + handle_pragma_token ("=", NULL_TREE); + break; + case LEFT_RIGHT: + handle_pragma_token ("(", NULL_TREE); + handle_pragma_token (")", NULL_TREE); break; case END_OF_LINE: handle_pragma_token (NULL_PTR, NULL_TREE); return; default: - handle_pragma_token (token_buffer, NULL_TREE); + abort (); } } } diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 7b5fae4..84849c1 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -330,7 +330,7 @@ asm_keyword: lang_extdef: { if (pending_lang_change) do_pending_lang_change(); } extdef - { if (! global_bindings_p () && ! pseudo_global_level_p()) + { if (! toplevel_bindings_p () && ! pseudo_global_level_p()) pop_everything (); prefix_attributes = NULL_TREE; } ; @@ -365,18 +365,18 @@ extdef: | NAMESPACE identifier '=' any_id ';' { do_namespace_alias ($2, $4); } | using_decl ';' - { } + { do_toplevel_using_decl ($1); } | USING NAMESPACE any_id ';' { do_using_directive ($3); } ; using_decl: USING qualified_id - { $$ = do_using_decl ($2); } + { $$ = $2; } | USING global_scope qualified_id - { $$ = do_using_decl ($3); } + { $$ = $3; } | USING global_scope unqualified_id - { $$ = do_using_decl ($3); } + { $$ = $3; } ; any_id: @@ -2645,6 +2645,7 @@ component_decl_1: $$ = grokfield ($$, TREE_CHAIN ($1), $4, $7, $5); cplus_decl_attributes ($$, $6, prefix_attributes); } | using_decl + { $$ = do_class_using_decl ($1); } ; /* The case of exactly one component is handled directly by component_decl. */ @@ -2956,7 +2957,7 @@ nested_name_specifier_1: TYPENAME SCOPE { got_scope = TREE_TYPE ($$); } | NSNAME SCOPE - { got_scope = TREE_TYPE ($$); } + { got_scope = $$; } | template_type SCOPE { got_scope = TREE_TYPE ($$); } /* These break 'const i;' diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index fe47d1c..2bf8edd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -39,6 +39,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "parse.h" #include "lex.h" #include "output.h" +#include "defaults.h" extern struct obstack permanent_obstack; extern tree grokdeclarator (); @@ -2395,7 +2396,12 @@ do_pending_expansions () if (i->interface == 1) /* OK, it was an implicit instantiation. */ - TREE_PUBLIC (t) = 0; + { + if (SUPPORTS_WEAK) + DECL_WEAK (t) = 1; + else + TREE_PUBLIC (t) = 0; + } /* If it's a method, let the class type decide it. @@ What if the method template is in a separate file? diff --git a/gcc/cp/spew.c b/gcc/cp/spew.c index 296c8f6..68915a4 100644 --- a/gcc/cp/spew.c +++ b/gcc/cp/spew.c @@ -327,6 +327,11 @@ yylex() case PTYPENAME: lastiddecl = NULL_TREE; break; + case NSNAME: + lastiddecl = trrr; + if (got_scope || got_object) + tmp_token.yylval.ttype = trrr; + break; default: my_friendly_abort (101); } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index badefe8..c2eb1e0 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1337,7 +1337,7 @@ c_alignof (type) C++: this will automatically bash references to their target type. */ tree -default_conversion (exp) +decay_conversion (exp) tree exp; { register tree type = TREE_TYPE (exp); @@ -1346,7 +1346,7 @@ default_conversion (exp) if (code == OFFSET_TYPE /* || TREE_CODE (exp) == OFFSET_REF */ ) { if (TREE_CODE (exp) == OFFSET_REF) - return default_conversion (resolve_offset_ref (exp)); + return decay_conversion (resolve_offset_ref (exp)); type = TREE_TYPE (type); code = TREE_CODE (type); @@ -1372,15 +1372,6 @@ default_conversion (exp) /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. Leave such NOP_EXPRs, since RHS is being used in non-lvalue context. */ - if (INTEGRAL_CODE_P (code)) - { - tree t = type_promotes_to (type); - if (t != type) - return convert (t, exp); - } - if (flag_traditional - && TYPE_MAIN_VARIANT (type) == float_type_node) - return convert (double_type_node, exp); if (code == VOID_TYPE) { error ("void value not ignored as it ought to be"); @@ -1424,7 +1415,7 @@ default_conversion (exp) if (TREE_CODE (exp) == COMPOUND_EXPR) { - tree op1 = default_conversion (TREE_OPERAND (exp, 1)); + tree op1 = decay_conversion (TREE_OPERAND (exp, 1)); return build (COMPOUND_EXPR, TREE_TYPE (op1), TREE_OPERAND (exp, 0), op1); } @@ -1470,6 +1461,32 @@ default_conversion (exp) adr = build_unary_op (ADDR_EXPR, exp, 1); return convert (ptrtype, adr); } + + return exp; +} + +tree +default_conversion (exp) + tree exp; +{ + tree type; + enum tree_code code; + + exp = decay_conversion (exp); + + type = TREE_TYPE (exp); + code = TREE_CODE (type); + + if (INTEGRAL_CODE_P (code)) + { + tree t = type_promotes_to (type); + if (t != type) + return convert (t, exp); + } + if (flag_traditional + && TYPE_MAIN_VARIANT (type) == float_type_node) + return convert (double_type_node, exp); + return exp; } @@ -2809,8 +2826,8 @@ build_binary_op (code, arg1, arg2, convert_p) { tree args_save [2]; tree type0, type1; - args[0] = args_save [0] = default_conversion (args[0]); - args[1] = args_save [1] = default_conversion (args[1]); + args[0] = decay_conversion (args[0]); + args[1] = decay_conversion (args[1]); if (args[0] == error_mark_node || args[1] == error_mark_node) return error_mark_node; @@ -2821,13 +2838,13 @@ build_binary_op (code, arg1, arg2, convert_p) if (type_unknown_p (args[0])) { args[0] = instantiate_type (type1, args[0], 1); - args[0] = default_conversion (args[0]); + args[0] = decay_conversion (args[0]); } else if (type_unknown_p (args[1])) { args[1] = require_instantiated_type (type0, args[1], error_mark_node); - args[1] = default_conversion (args[1]); + args[1] = decay_conversion (args[1]); } if (IS_AGGR_TYPE (type0) || IS_AGGR_TYPE (type1)) @@ -2840,11 +2857,6 @@ build_binary_op (code, arg1, arg2, convert_p) return error_mark_node; } } - - if (args[0] == args_save[0]) - args[0] = arg1; - if (args[1] == args_save[1]) - args[1] = arg2; } return build_binary_op_nodefault (code, args[0], args[1], code); } @@ -2923,8 +2935,18 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) int common = 0; /* Apply default conversions. */ - op0 = default_conversion (orig_op0); - op1 = default_conversion (orig_op1); + if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR + || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR + || code == TRUTH_XOR_EXPR) + { + op0 = decay_conversion (orig_op0); + op1 = decay_conversion (orig_op1); + } + else + { + op0 = default_conversion (orig_op0); + op1 = default_conversion (orig_op1); + } type0 = TREE_TYPE (op0); type1 = TREE_TYPE (op1); |