summaryrefslogtreecommitdiff
path: root/gcc/cp/decl2.c
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-01-21 21:16:22 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-01-21 21:16:22 +0000
commit91bbfe2a9b41685a1a43c4c61de4c5c7dd50d295 (patch)
treee6f14953b9b72129c669c461010c89a23823f94b /gcc/cp/decl2.c
parent928a6bdc7cc5d5207afb28e91100986f0131dde8 (diff)
downloadgcc-91bbfe2a9b41685a1a43c4c61de4c5c7dd50d295.tar.gz
* cp-tree.h (PUSH_GLOBAL): New macro.
(PUSH_LOCAL): Likewise. (PUSH_USING): Likewise. (namespace_bindings_p): Declare. (push_overloaded_decl): Likewise. * decl.c (push_overloaded_decl): Don't make it static. Check for illegal declarations after using declarations here. (namespace_bindings_p): Likewise. (duplicate_decls): Don't consider declarations from different namespaces to be the same. (pushdecl): Use symbolic PUSH_ constants in calls to push_overloaded_decl. (push_overloaded_decl_1): Likewise. * decl2.c (validate_nonmember_using_decl): Tweak `std' handling. (do_nonmember_using_decl): Check for illegal using declarations after ordinary declarations here. (do_local_using_decl): Call pushdecl to insert declarations. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@24812 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r--gcc/cp/decl2.c63
1 files changed, 53 insertions, 10 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 303364453a7..ed9c11b3824 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -4703,6 +4703,16 @@ validate_nonmember_using_decl (decl, scope, name)
if (TREE_CODE (decl) == SCOPE_REF
&& TREE_OPERAND (decl, 0) == std_node)
{
+ if (namespace_bindings_p ()
+ && current_namespace == global_namespace)
+ /* There's no need for a using declaration at all, here,
+ since `std' is the same as `::'. We can't just pass this
+ on because we'll complain later about declaring something
+ in the same scope as a using declaration with the same
+ name. We return NULL_TREE which indicates to the caller
+ that there's no need to do any further processing. */
+ return NULL_TREE;
+
*scope = global_namespace;
*name = TREE_OPERAND (decl, 1);
}
@@ -4773,17 +4783,37 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
*newval = oldval;
for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp))
{
- /* Compare each new function with each old one.
- If the old function was also used, there is no conflict. */
+ tree new_fn = OVL_CURRENT (tmp);
+
+ /* [namespace.udecl]
+
+ If a function declaration in namespace scope or block
+ scope has the same name and the same parameter types as a
+ function introduced by a using declaration the program is
+ ill-formed. */
for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
- if (OVL_CURRENT (tmp) == OVL_CURRENT (tmp1))
- break;
- else if (OVL_USED (tmp1))
- continue;
- else if (duplicate_decls (OVL_CURRENT (tmp), OVL_CURRENT (tmp1)))
- return;
+ {
+ tree old_fn = OVL_CURRENT (tmp1);
- /* Duplicate use, ignore */
+ if (!OVL_USED (tmp1)
+ && compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
+ TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+ {
+ /* There was already a non-using declaration in
+ this scope with the same parameter types. */
+ cp_error ("`%D' is already declared in this scope",
+ name);
+ break;
+ }
+ else if (duplicate_decls (new_fn, old_fn))
+ /* We're re-using something we already used
+ before. We don't need to add it again. */
+ break;
+ }
+
+ /* If we broke out of the loop, there's no reason to add
+ this function to the using declarations for this
+ scope. */
if (tmp1)
continue;
@@ -4856,7 +4886,20 @@ do_local_using_decl (decl)
do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
if (newval)
- push_local_binding (name, newval);
+ {
+ if (is_overloaded_fn (newval))
+ {
+ tree fn;
+
+ /* We only need to push declarations for those functions
+ that were not already bound in the current level. */
+ for (fn = newval; fn != oldval; fn = OVL_NEXT (fn))
+ push_overloaded_decl (OVL_CURRENT (fn),
+ PUSH_LOCAL | PUSH_USING);
+ }
+ else
+ push_local_binding (name, newval);
+ }
if (newtype)
set_identifier_type_value (name, newtype);
}