aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1995-05-16 21:10:32 +0000
committerMike Stump <mrs@gcc.gnu.org>1995-05-16 21:10:32 +0000
commita9aedbc26d61fbe2fef53254408dbbb37c3992fa (patch)
tree028f47896fbbf644d31fd3de7372df8ca1a6bd39 /gcc
parent45ca9d09a13dac9ef4d013ede726cfa1e270649c (diff)
downloadgcc-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/ChangeLog70
-rw-r--r--gcc/cp/call.c9
-rw-r--r--gcc/cp/class.c6
-rw-r--r--gcc/cp/cp-tree.def3
-rw-r--r--gcc/cp/cp-tree.h8
-rw-r--r--gcc/cp/cvt.c6
-rw-r--r--gcc/cp/decl.c444
-rw-r--r--gcc/cp/decl2.c78
-rw-r--r--gcc/cp/error.c4
-rw-r--r--gcc/cp/init.c54
-rw-r--r--gcc/cp/lex.c19
-rw-r--r--gcc/cp/parse.y13
-rw-r--r--gcc/cp/pt.c8
-rw-r--r--gcc/cp/spew.c5
-rw-r--r--gcc/cp/typeck.c68
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);