aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-10-27 02:23:16 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-10-27 02:23:16 +0000
commita5201a9197a9083b71098914c9dfd97249db5249 (patch)
tree62c200d8b2b8702e81da0dc741d655791644796a /gcc/cp
parent0a3d71f54af134bcafea29a8f8021d8bbf24cfb4 (diff)
downloadgcc-a5201a9197a9083b71098914c9dfd97249db5249.zip
gcc-a5201a9197a9083b71098914c9dfd97249db5249.tar.gz
gcc-a5201a9197a9083b71098914c9dfd97249db5249.tar.bz2
re PR c++/18093 (bogus conflict in namespace aliasing)
PR c++/18093 * search.c (current_scope): Return the innermost non-block scope, not the innermost non-block, non-namespace scope. (at_namespace_scope_p): Adjust accordingly. (dfs_accessible_post): Do not pass namespaces to is_friend. (dfs_walk_once_accessible_r): Likewise. * decl.c (grokvardecl): Adjust call to current_scope. (build_enumerator): Likewise. * parser.c (cp_parser_using_declaration): Likewise. (cp_parser_direct_declarator): Use at_namespace_scope_p instead of current_scope. (cp_parser_class_head): Adjust call to current_scope. * name-lookup.c (do_namespace_alias): Set the DECL_CONTEXT for the alias. PR c++/18020 * pt.c (tusbst_copy_and_build): Resolve enumeration constants to their underlying values. PR c++/18161 * typeck.c (build_binary_op): Honor build_type, even when in a template. PR c++/18093 * g++.dg/lookup/ns2.C: New test. PR c++/18020 * g++.dg/template/enum4.C: New test. PR c++/18161 * g++.dg/template/expr1.C: New test. From-SVN: r89627
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog25
-rw-r--r--gcc/cp/decl.c8
-rw-r--r--gcc/cp/name-lookup.c1
-rw-r--r--gcc/cp/parser.c10
-rw-r--r--gcc/cp/pt.c8
-rw-r--r--gcc/cp/search.c77
-rw-r--r--gcc/cp/typeck.c4
7 files changed, 86 insertions, 47 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 39f6e41..d9e8ce7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,28 @@
+2004-10-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18093
+ * search.c (current_scope): Return the innermost non-block scope,
+ not the innermost non-block, non-namespace scope.
+ (at_namespace_scope_p): Adjust accordingly.
+ (dfs_accessible_post): Do not pass namespaces to is_friend.
+ (dfs_walk_once_accessible_r): Likewise.
+ * decl.c (grokvardecl): Adjust call to current_scope.
+ (build_enumerator): Likewise.
+ * parser.c (cp_parser_using_declaration): Likewise.
+ (cp_parser_direct_declarator): Use at_namespace_scope_p instead of
+ current_scope.
+ (cp_parser_class_head): Adjust call to current_scope.
+ * name-lookup.c (do_namespace_alias): Set the DECL_CONTEXT for the
+ alias.
+
+ PR c++/18020
+ * pt.c (tusbst_copy_and_build): Resolve enumeration constants to
+ their underlying values.
+
+ PR c++/18161
+ * typeck.c (build_binary_op): Honor build_type, even when in a
+ template.
+
2004-10-26 Nathan Sidwell <nathan@codesourcery.com>
* parser.c (cp_lexer_get_preprocessor_token): Remove unneeded
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2aca629..9d9f70b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5918,11 +5918,7 @@ grokvardecl (tree type,
if (declspecs->storage_class == sc_extern)
scope = current_namespace;
else if (!at_function_scope_p ())
- {
- scope = current_scope ();
- if (!scope)
- scope = current_namespace;
- }
+ scope = current_scope ();
}
if (scope
@@ -9746,8 +9742,6 @@ build_enumerator (tree name, tree value, tree enumtype)
/* C++ associates enums with global, function, or class declarations. */
context = current_scope ();
- if (!context)
- context = current_namespace;
/* Build the actual enumeration constant. Note that the enumeration
constants have the type of their initializers until the
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 6634f87..423a4b9 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3227,6 +3227,7 @@ do_namespace_alias (tree alias, tree namespace)
alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
DECL_NAMESPACE_ALIAS (alias) = namespace;
DECL_EXTERNAL (alias) = 1;
+ DECL_CONTEXT (alias) = current_scope ();
pushdecl (alias);
/* Emit debug info for namespace alias. */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index fe3b3c6..b6e5432 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -10047,7 +10047,6 @@ cp_parser_using_declaration (cp_parser* parser)
bool global_scope_p;
tree decl;
tree identifier;
- tree scope;
tree qscope;
/* Look for the `using' keyword. */
@@ -10106,8 +10105,7 @@ cp_parser_using_declaration (cp_parser* parser)
error ("a template-id may not appear in a using-declaration");
else
{
- scope = current_scope ();
- if (scope && TYPE_P (scope))
+ if (at_class_scope_p ())
{
/* Create the USING_DECL. */
decl = do_class_using_decl (build_nt (SCOPE_REF,
@@ -10121,7 +10119,7 @@ cp_parser_using_declaration (cp_parser* parser)
decl = cp_parser_lookup_name_simple (parser, identifier);
if (decl == error_mark_node)
cp_parser_name_lookup_error (parser, identifier, decl, NULL);
- else if (scope)
+ else if (!at_namespace_scope_p ())
do_local_using_decl (decl, qscope, identifier);
else
do_toplevel_using_decl (decl, qscope, identifier);
@@ -10982,7 +10980,7 @@ cp_parser_direct_declarator (cp_parser* parser,
break;
}
- if (TREE_CODE (id) == SCOPE_REF && !current_scope ())
+ if (TREE_CODE (id) == SCOPE_REF && at_namespace_scope_p ())
{
tree scope = TREE_OPERAND (id, 0);
@@ -12560,8 +12558,6 @@ cp_parser_class_head (cp_parser* parser,
tree scope;
/* Figure out in what scope the declaration is being placed. */
scope = current_scope ();
- if (!scope)
- scope = current_namespace;
/* If that scope does not contain the scope in which the
class was originally declared, the program is invalid. */
if (scope && !is_ancestor (scope, nested_name_specifier))
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1ced238..99f4e7b 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8761,6 +8761,14 @@ tsubst_copy_and_build (tree t,
return stmt_expr;
}
+ case CONST_DECL:
+ t = tsubst_copy (t, args, complain, in_decl);
+ /* As in finish_id_expression, we resolve enumeration constants
+ to their underlying values. */
+ if (TREE_CODE (t) == CONST_DECL)
+ return DECL_INITIAL (t);
+ return t;
+
default:
return tsubst_copy (t, args, complain, in_decl);
}
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 5b060da5..5f8f081 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -497,7 +497,13 @@ lookup_field_1 (tree type, tree name, bool want_type)
return NULL_TREE;
}
-/* There are a number of cases we need to be aware of here:
+/* Return the FUNCTION_DECL, RECORD_TYPE, UNION_TYPE, or
+ NAMESPACE_DECL corresponding to the innermost non-block scope. */
+
+tree
+current_scope ()
+{
+ /* There are a number of cases we need to be aware of here:
current_class_type current_function_decl
global NULL NULL
fn-local NULL SET
@@ -505,30 +511,26 @@ lookup_field_1 (tree type, tree name, bool want_type)
class->fn SET SET
fn->class SET SET
- Those last two make life interesting. If we're in a function which is
- itself inside a class, we need decls to go into the fn's decls (our
- second case below). But if we're in a class and the class itself is
- inside a function, we need decls to go into the decls for the class. To
- achieve this last goal, we must see if, when both current_class_ptr and
- current_function_decl are set, the class was declared inside that
- function. If so, we know to put the decls into the class's scope. */
-
-tree
-current_scope (void)
-{
- if (current_function_decl == NULL_TREE)
- return current_class_type;
- if (current_class_type == NULL_TREE)
+ Those last two make life interesting. If we're in a function which is
+ itself inside a class, we need decls to go into the fn's decls (our
+ second case below). But if we're in a class and the class itself is
+ inside a function, we need decls to go into the decls for the class. To
+ achieve this last goal, we must see if, when both current_class_ptr and
+ current_function_decl are set, the class was declared inside that
+ function. If so, we know to put the decls into the class's scope. */
+ if (current_function_decl && current_class_type
+ && ((DECL_FUNCTION_MEMBER_P (current_function_decl)
+ && same_type_p (DECL_CONTEXT (current_function_decl),
+ current_class_type))
+ || (DECL_FRIEND_CONTEXT (current_function_decl)
+ && same_type_p (DECL_FRIEND_CONTEXT (current_function_decl),
+ current_class_type))))
return current_function_decl;
- if ((DECL_FUNCTION_MEMBER_P (current_function_decl)
- && same_type_p (DECL_CONTEXT (current_function_decl),
- current_class_type))
- || (DECL_FRIEND_CONTEXT (current_function_decl)
- && same_type_p (DECL_FRIEND_CONTEXT (current_function_decl),
- current_class_type)))
+ if (current_class_type)
+ return current_class_type;
+ if (current_function_decl)
return current_function_decl;
-
- return current_class_type;
+ return current_namespace;
}
/* Returns nonzero if we are currently in a function scope. Note
@@ -556,9 +558,8 @@ at_class_scope_p (void)
bool
at_namespace_scope_p (void)
{
- /* We are in a namespace scope if we are not it a class scope or a
- function scope. */
- return !current_scope();
+ tree cs = current_scope ();
+ return cs && TREE_CODE (cs) == NAMESPACE_DECL;
}
/* Return the scope of DECL, as appropriate when doing name-lookup. */
@@ -833,9 +834,13 @@ friend_accessible_p (tree scope, tree decl, tree binfo)
static tree
dfs_accessible_post (tree binfo, void *data ATTRIBUTE_UNUSED)
{
- if (BINFO_ACCESS (binfo) != ak_none
- && is_friend (BINFO_TYPE (binfo), current_scope ()))
- return binfo;
+ if (BINFO_ACCESS (binfo) != ak_none)
+ {
+ tree scope = current_scope ();
+ if (scope && TREE_CODE (scope) != NAMESPACE_DECL
+ && is_friend (BINFO_TYPE (binfo), scope))
+ return binfo;
+ }
return NULL_TREE;
}
@@ -1700,9 +1705,17 @@ dfs_walk_once_accessible_r (tree binfo, bool friends_p, bool once,
/* If the base is inherited via private or protected
inheritance, then we can't see it, unless we are a friend of
the current binfo. */
- if (BINFO_BASE_ACCESS (binfo, ix) != access_public_node
- && !(friends_p && is_friend (BINFO_TYPE (binfo), current_scope ())))
- continue;
+ if (BINFO_BASE_ACCESS (binfo, ix) != access_public_node)
+ {
+ tree scope;
+ if (!friends_p)
+ continue;
+ scope = current_scope ();
+ if (!scope
+ || TREE_CODE (scope) == NAMESPACE_DECL
+ || !is_friend (BINFO_TYPE (binfo), scope))
+ continue;
+ }
if (mark)
BINFO_MARKED (base_binfo) = 1;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index cc91b65..5e7bf90 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -3201,7 +3201,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
/* If we're in a template, the only thing we need to know is the
RESULT_TYPE. */
if (processing_template_decl)
- return build2 (resultcode, result_type, op0, op1);
+ return build2 (resultcode,
+ build_type ? build_type : result_type,
+ op0, op1);
if (arithmetic_types_p)
{