Commit a759e627 by Martin v. Löwis Committed by Jason Merrill

decl2.c (build_expr_from_tree): Change calls of do_identifier.

	* decl2.c (build_expr_from_tree): Change calls of do_identifier.
	Do Koenig lookup in CALL_EXPR.
	(arg_assoc): Handle error_mark.
	* lex.c (is_global): New function.
	(do_identifier): Expect arguments for Koenig lookup.
	* parse.y (primary): Add rules for calls of unqualified function calls.
	(do_id): Change call of do_identifier.
	* pt.c (finish_stmt_expr): Likewise.
	* semantics.c (finish_id_expr): Likewise.
	(finish_call_expr): Add integer parameter to indicate
	argument-dependent lookup.

From-SVN: r21091
parent 894ded60
1998-07-12 Martin von Lwis <loewis@informatik.hu-berlin.de> 1998-07-12 Martin von Lwis <loewis@informatik.hu-berlin.de>
* decl2.c (build_expr_from_tree): Change calls of do_identifier.
Do Koenig lookup in CALL_EXPR.
(arg_assoc): Handle error_mark.
* lex.c (is_global): New function.
(do_identifier): Expect arguments for Koenig lookup.
* parse.y (primary): Add rules for calls of unqualified function calls.
(do_id): Change call of do_identifier.
* pt.c (finish_stmt_expr): Likewise.
* semantics.c (finish_id_expr): Likewise.
(finish_call_expr): Add integer parameter to indicate
argument-dependent lookup.
* decl.c (struct binding_level): New field using_directives. * decl.c (struct binding_level): New field using_directives.
(push_using_decl): Not sorry anymore. (push_using_decl): Not sorry anymore.
(push_using_directive): New function. (push_using_directive): New function.
......
...@@ -2606,7 +2606,7 @@ extern void note_list_got_semicolon PROTO((tree)); ...@@ -2606,7 +2606,7 @@ extern void note_list_got_semicolon PROTO((tree));
extern void do_pending_lang_change PROTO((void)); extern void do_pending_lang_change PROTO((void));
extern int identifier_type PROTO((tree)); extern int identifier_type PROTO((tree));
extern void see_typename PROTO((void)); extern void see_typename PROTO((void));
extern tree do_identifier PROTO((tree, int)); extern tree do_identifier PROTO((tree, int, tree));
extern tree do_scoped_id PROTO((tree, int)); extern tree do_scoped_id PROTO((tree, int));
extern tree identifier_typedecl_value PROTO((tree)); extern tree identifier_typedecl_value PROTO((tree));
extern int real_yylex PROTO((void)); extern int real_yylex PROTO((void));
...@@ -2798,7 +2798,7 @@ extern void finish_asm_stmt PROTO((tree, tree, tree, tree, t ...@@ -2798,7 +2798,7 @@ extern void finish_asm_stmt PROTO((tree, tree, tree, tree, t
extern tree finish_parenthesized_expr PROTO((tree)); extern tree finish_parenthesized_expr PROTO((tree));
extern tree begin_stmt_expr PROTO((void)); extern tree begin_stmt_expr PROTO((void));
extern tree finish_stmt_expr PROTO((tree, tree)); extern tree finish_stmt_expr PROTO((tree, tree));
extern tree finish_call_expr PROTO((tree, tree)); extern tree finish_call_expr PROTO((tree, tree, int));
extern tree finish_increment_expr PROTO((tree, enum tree_code)); extern tree finish_increment_expr PROTO((tree, enum tree_code));
extern tree finish_this_expr PROTO((void)); extern tree finish_this_expr PROTO((void));
extern tree finish_object_call_expr PROTO((tree, tree, tree)); extern tree finish_object_call_expr PROTO((tree, tree, tree));
......
...@@ -3480,13 +3480,13 @@ build_expr_from_tree (t) ...@@ -3480,13 +3480,13 @@ build_expr_from_tree (t)
switch (TREE_CODE (t)) switch (TREE_CODE (t))
{ {
case IDENTIFIER_NODE: case IDENTIFIER_NODE:
return do_identifier (t, 0); return do_identifier (t, 0, NULL_TREE);
case LOOKUP_EXPR: case LOOKUP_EXPR:
if (LOOKUP_EXPR_GLOBAL (t)) if (LOOKUP_EXPR_GLOBAL (t))
return do_scoped_id (TREE_OPERAND (t, 0), 0); return do_scoped_id (TREE_OPERAND (t, 0), 0);
else else
return do_identifier (TREE_OPERAND (t, 0), 0); return do_identifier (TREE_OPERAND (t, 0), 0, NULL_TREE);
case TEMPLATE_ID_EXPR: case TEMPLATE_ID_EXPR:
return (lookup_template_function return (lookup_template_function
...@@ -3651,12 +3651,21 @@ build_expr_from_tree (t) ...@@ -3651,12 +3651,21 @@ build_expr_from_tree (t)
else else
{ {
tree name = TREE_OPERAND (t, 0); tree name = TREE_OPERAND (t, 0);
if (TREE_CODE (name) == TEMPLATE_ID_EXPR tree id;
tree args = build_expr_from_tree (TREE_OPERAND (t, 1));
if (args != NULL_TREE && TREE_CODE (name) == LOOKUP_EXPR
&& !LOOKUP_EXPR_GLOBAL (name)
&& TREE_CODE ((id = TREE_OPERAND (name, 0))) == IDENTIFIER_NODE
&& (!current_class_type
|| !lookup_member (current_class_type, id, 0, 0)))
{
/* Do Koenig lookup if there are no class members. */
name = do_identifier (id, 0, args);
}
else if (TREE_CODE (name) == TEMPLATE_ID_EXPR
|| ! really_overloaded_fn (name)) || ! really_overloaded_fn (name))
name = build_expr_from_tree (name); name = build_expr_from_tree (name);
return build_x_function_call return build_x_function_call (name, args, current_class_ref);
(name, build_expr_from_tree (TREE_OPERAND (t, 1)),
current_class_ref);
} }
case COND_EXPR: case COND_EXPR:
...@@ -4329,6 +4338,13 @@ arg_assoc (k, n) ...@@ -4329,6 +4338,13 @@ arg_assoc (k, n)
if (arg_assoc_type (k, DECL_CLASS_CONTEXT (n))) if (arg_assoc_type (k, DECL_CLASS_CONTEXT (n)))
return 1; return 1;
return 0; return 0;
case TEMPLATE_DECL:
/* XXX Type of a function template in the context of Koenig lookup?
Assume that template parameters are non-deduced for the moment. */
n = DECL_RESULT (n);
continue;
case ERROR_MARK:
return 0;
default: default:
cp_error ("sorry, Koenig lookup for `%s' of type `%T' failed", cp_error ("sorry, Koenig lookup for `%s' of type `%T' failed",
tree_code_name [(int)TREE_CODE (n)], TREE_TYPE (n)); tree_code_name [(int)TREE_CODE (n)], TREE_TYPE (n));
......
...@@ -2792,10 +2792,29 @@ see_typename () ...@@ -2792,10 +2792,29 @@ see_typename ()
} }
} }
/* Return true if d is in a global scope. */
static int
is_global (d)
tree d;
{
while (1)
switch (TREE_CODE (d))
{
case OVERLOAD: d = OVL_FUNCTION (d); continue;
case TREE_LIST: d = TREE_VALUE (d); continue;
default:
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (d)) == 'd', 980629);
d = CP_DECL_CONTEXT (d);
return TREE_CODE (d) == NAMESPACE_DECL;
}
}
tree tree
do_identifier (token, parsing) do_identifier (token, parsing, args)
register tree token; register tree token;
int parsing; int parsing;
tree args;
{ {
register tree id; register tree id;
...@@ -2808,7 +2827,7 @@ do_identifier (token, parsing) ...@@ -2808,7 +2827,7 @@ do_identifier (token, parsing)
yychar = yylex (); yychar = yylex ();
/* Scope class declarations before global /* Scope class declarations before global
declarations. */ declarations. */
if (id == IDENTIFIER_NAMESPACE_VALUE (token) if (id && is_global (id)
&& current_class_type != 0 && current_class_type != 0
&& TYPE_SIZE (current_class_type) == 0) && TYPE_SIZE (current_class_type) == 0)
{ {
...@@ -2835,6 +2854,15 @@ do_identifier (token, parsing) ...@@ -2835,6 +2854,15 @@ do_identifier (token, parsing)
} }
} }
/* Do Koenig lookup if appropriate (inside templates we build lookup
expressions instead). */
if (args && !current_template_parms && (!id || is_global (id)))
{
/* If we have arguments and we only found global names,
do Koenig lookup. */
id = lookup_arg_dependent (token, id, args);
}
/* Remember that this name has been used in the class definition, as per /* Remember that this name has been used in the class definition, as per
[class.scope0] */ [class.scope0] */
if (id && current_class_type && parsing if (id && current_class_type && parsing
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -1264,7 +1264,7 @@ notype_unqualified_id: ...@@ -1264,7 +1264,7 @@ notype_unqualified_id:
; ;
do_id: do_id:
{ $$ = do_identifier ($<ttype>-1, 1); } { $$ = do_identifier ($<ttype>-1, 1, NULL_TREE); }
template_id: template_id:
PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket
...@@ -1351,10 +1351,17 @@ primary: ...@@ -1351,10 +1351,17 @@ primary:
} }
compstmt ')' compstmt ')'
{ $$ = finish_stmt_expr ($<ttype>2, $3); } { $$ = finish_stmt_expr ($<ttype>2, $3); }
/* Koenig lookup support
We could store lastiddecl in $1 to avoid another lookup,
but that would result in many additional reduce/reduce conflicts. */
| IDENTIFIER '(' nonnull_exprlist ')'
{ $$ = finish_call_expr ($1, $3, 1); }
| IDENTIFIER LEFT_RIGHT
{ $$ = finish_call_expr ($1, NULL_TREE, 1); }
| primary '(' nonnull_exprlist ')' | primary '(' nonnull_exprlist ')'
{ $$ = finish_call_expr ($1, $3); } { $$ = finish_call_expr ($1, $3, 0); }
| primary LEFT_RIGHT | primary LEFT_RIGHT
{ $$ = finish_call_expr ($1, NULL_TREE); } { $$ = finish_call_expr ($1, NULL_TREE, 0); }
| primary '[' expr ']' | primary '[' expr ']'
{ $$ = grok_array_decl ($$, $3); } { $$ = grok_array_decl ($$, $3); }
| primary PLUSPLUS | primary PLUSPLUS
......
...@@ -5229,7 +5229,7 @@ tsubst_copy (t, args, in_decl) ...@@ -5229,7 +5229,7 @@ tsubst_copy (t, args, in_decl)
switch (code) switch (code)
{ {
case PARM_DECL: case PARM_DECL:
return do_identifier (DECL_NAME (t), 0); return do_identifier (DECL_NAME (t), 0, NULL_TREE);
case CONST_DECL: case CONST_DECL:
case FIELD_DECL: case FIELD_DECL:
......
...@@ -836,11 +836,16 @@ finish_stmt_expr (rtl_expr, expr) ...@@ -836,11 +836,16 @@ finish_stmt_expr (rtl_expr, expr)
call. */ call. */
tree tree
finish_call_expr (fn, args) finish_call_expr (fn, args, koenig)
tree fn; tree fn;
tree args; tree args;
int koenig;
{ {
tree result = build_x_function_call (fn, args, current_class_ref); tree result;
if (koenig)
fn = do_identifier (fn, 0, args);
result = build_x_function_call (fn, args, current_class_ref);
if (TREE_CODE (result) == CALL_EXPR if (TREE_CODE (result) == CALL_EXPR
&& TREE_TYPE (result) != void_type_node) && TREE_TYPE (result) != void_type_node)
...@@ -1028,7 +1033,7 @@ finish_id_expr (expr) ...@@ -1028,7 +1033,7 @@ finish_id_expr (expr)
tree expr; tree expr;
{ {
if (TREE_CODE (expr) == IDENTIFIER_NODE) if (TREE_CODE (expr) == IDENTIFIER_NODE)
expr = do_identifier (expr, 1); expr = do_identifier (expr, 1, NULL_TREE);
return expr; return expr;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment