diff options
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 7 | ||||
-rw-r--r-- | gcc/cp/parser.c | 15 | ||||
-rw-r--r-- | gcc/cp/pt.c | 33 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/call1.C | 16 |
7 files changed, 70 insertions, 29 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 326da4b..e28ff5b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2003-09-02 Mark Mitchell <mark@codesourcery.com> + + PR c++/11808 + * cp-tree.h (KOENIG_LOOKUP_P): New macro. + (finish_call_expr): Change prototype. + * parser.c (cp_parser_postfix_expression): Adjust call to + finish_call_expr. + * pt.c (tsubst_copy_and_build): Use KOENIG_LOOKUP_P. + * semantics.c (finish_call_expr): Add koenig_p parameter. + 2003-09-01 Mark Mitchell <mark@codesourcery.com> PR c++/12114 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f17b67c..cf4b8ce 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -46,6 +46,7 @@ struct diagnostic_context; PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF) PARMLIST_ELLIPSIS_P (in PARMLIST) DECL_PRETTY_FUNCTION_P (in VAR_DECL) + KOENIG_LOOKUP_P (in CALL_EXPR) 1: IDENTIFIER_VIRTUAL_P. TI_PENDING_TEMPLATE_FLAG. TEMPLATE_PARMS_FOR_INLINE. @@ -2293,6 +2294,10 @@ struct lang_decl GTY(()) #define DELETE_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) #define DELETE_EXPR_USE_VEC(NODE) TREE_LANG_FLAG_1 (NODE) +/* In a CALL_EXPR appearing in a template, true if Koenig lookup + should be performed at instantiation time. */ +#define KOENIG_LOOKUP_P(NODE) TREE_LANG_FLAG_0(NODE) + /* Nonzero if this AGGR_INIT_EXPR provides for initialization via a constructor call, rather than an ordinary function call. */ #define AGGR_INIT_VIA_CTOR_P(NODE) \ @@ -4105,7 +4110,7 @@ extern tree begin_stmt_expr (void); extern tree finish_stmt_expr_expr (tree); extern tree finish_stmt_expr (tree, bool); extern tree perform_koenig_lookup (tree, tree); -extern tree finish_call_expr (tree, tree, bool); +extern tree finish_call_expr (tree, tree, bool, bool); extern tree finish_increment_expr (tree, enum tree_code); extern tree finish_this_expr (void); extern tree finish_object_call_expr (tree, tree, tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 735d592..01d6dba 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3506,6 +3506,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) case CPP_OPEN_PAREN: /* postfix-expression ( expression-list [opt] ) */ { + bool koenig_p; tree args = (cp_parser_parenthesized_expression_list (parser, false, /*non_constant_p=*/NULL)); @@ -3524,14 +3525,18 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) parser->non_constant_expression_p = true; } + koenig_p = false; if (idk == CP_ID_KIND_UNQUALIFIED) { if (args && (is_overloaded_fn (postfix_expression) || DECL_P (postfix_expression) || TREE_CODE (postfix_expression) == IDENTIFIER_NODE)) - postfix_expression - = perform_koenig_lookup (postfix_expression, args); + { + koenig_p = true; + postfix_expression + = perform_koenig_lookup (postfix_expression, args); + } else if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE) postfix_expression = unqualified_fn_lookup_error (postfix_expression); @@ -3570,12 +3575,14 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) function. */ postfix_expression = finish_call_expr (postfix_expression, args, - /*disallow_virtual=*/true); + /*disallow_virtual=*/true, + koenig_p); else /* All other function calls. */ postfix_expression = finish_call_expr (postfix_expression, args, - /*disallow_virtual=*/false); + /*disallow_virtual=*/false, + koenig_p); /* The POSTFIX_EXPRESSION is certainly no longer an id. */ idk = CP_ID_KIND_NONE; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8cf8d15..ae47b60 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8090,18 +8090,9 @@ tsubst_copy_and_build (tree t, bool koenig_p; function = TREE_OPERAND (t, 0); - /* To determine whether or not we should perform Koenig lookup - we must look at the form of the FUNCTION. */ - koenig_p = !(/* Koenig lookup does not apply to qualified - names. */ - TREE_CODE (function) == SCOPE_REF - /* Or to references to members of classes. */ - || TREE_CODE (function) == COMPONENT_REF - /* If it is a FUNCTION_DECL or a baselink, then - the name was already resolved when the - template was parsed. */ - || TREE_CODE (function) == FUNCTION_DECL - || TREE_CODE (function) == BASELINK); + /* When we parsed the expression, we determined whether or + not Koenig lookup should be performed. */ + koenig_p = KOENIG_LOOKUP_P (t); if (TREE_CODE (function) == SCOPE_REF) { qualified_p = true; @@ -8117,23 +8108,22 @@ tsubst_copy_and_build (tree t, function = tsubst_copy_and_build (function, args, complain, in_decl, !qualified_p); + if (BASELINK_P (function)) + qualified_p = true; } call_args = RECUR (TREE_OPERAND (t, 1)); - if (BASELINK_P (function)) - qualified_p = 1; - if (koenig_p - && TREE_CODE (function) != TEMPLATE_ID_EXPR && (is_overloaded_fn (function) || DECL_P (function) || TREE_CODE (function) == IDENTIFIER_NODE)) + function = perform_koenig_lookup (function, call_args); + + if (TREE_CODE (function) == IDENTIFIER_NODE) { - if (call_args) - function = perform_koenig_lookup (function, call_args); - else if (TREE_CODE (function) == IDENTIFIER_NODE) - function = unqualified_name_lookup_error (function); + unqualified_name_lookup_error (function); + return error_mark_node; } /* Remember that there was a reference to this entity. */ @@ -8151,7 +8141,8 @@ tsubst_copy_and_build (tree t, call_args, NULL_TREE, qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL)); return finish_call_expr (function, call_args, - /*disallow_virtual=*/qualified_p); + /*disallow_virtual=*/qualified_p, + koenig_p); } case COND_EXPR: diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index c9f3675..8670f8b 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1585,7 +1585,7 @@ perform_koenig_lookup (tree fn, tree args) Returns code for the call. */ tree -finish_call_expr (tree fn, tree args, bool disallow_virtual) +finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p) { tree result; tree orig_fn; @@ -1605,7 +1605,11 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual) { if (type_dependent_expression_p (fn) || any_type_dependent_arguments_p (args)) - return build_nt (CALL_EXPR, fn, args); + { + result = build_nt (CALL_EXPR, fn, args); + KOENIG_LOOKUP_P (result) = koenig_p; + return result; + } if (!BASELINK_P (fn) && TREE_CODE (fn) != PSEUDO_DTOR_EXPR && TREE_TYPE (fn) != unknown_type_node) @@ -1707,7 +1711,10 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual) result = build_function_call (fn, args); if (processing_template_decl) - return build (CALL_EXPR, TREE_TYPE (result), orig_fn, orig_args); + { + result = build (CALL_EXPR, TREE_TYPE (result), orig_fn, orig_args); + KOENIG_LOOKUP_P (result) = koenig_p; + } return result; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b62f69c..f2d74d8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-09-02 Mark Mitchell <mark@codesourcery.com> + + PR c++/11808 + * g++.dg/expr/call1.C: New test. + 2003-09-01 Mark Mitchell <mark@codesourcery.com> PR c++/12114 diff --git a/gcc/testsuite/g++.dg/expr/call1.C b/gcc/testsuite/g++.dg/expr/call1.C new file mode 100644 index 0000000..42d18db --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/call1.C @@ -0,0 +1,16 @@ +namespace NS_1 { + struct A {}; + struct foo {}; +} + +namespace NS_2 { + template <typename T> void foo(T); + + template <typename T> + void bar() { + NS_1::A a; + NS_2::foo(a); + } + + template void bar<int>(); +} |