diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1d25e8615ef..b491c2b720b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,41 @@ +2003-07-15 Mark Mitchell + + * cp-tree.def (LOOKUP_EXPR): Remove. + * cp-tree.h (cp_id_kind): Add CP_ID_KIND_UNQUALIFIED_DEPENDENT. + (LOOKUP_EXPR_GLOBAL): Remove. + (get_bindings): Remove. + (is_aggr_type_2): Remove. + * call.c (resolved_scoped_fn_name): Remove support for + LOOKUP_EXPR. + * decl.c (grokfndecl): Likewise. + (grokdeclarator): Likewise. + * error.c (dump_decl): Likewise. + (dump_expr): Likewise. + * friend.c (do_friend): Likewise. + * init.c (build_offset_ref): Likewise. + * lex.c (unqualified_fn_lookup_error): Use pedwarn. Do not create + LOOKUP_EXPRs + * mangle.c (write_expression): Remove support for LOOKUP_EXPR. + * parser.c (cp_parser_postfix_expression): Modify Koenig lookup + test. + * pt.c (get_bindings): Give it internal linkage. + (check_explicit_specialization): Remove support for LOOKUP_EXPR. + (lookup_template_function): Likewise. + (for_each_tempalte_parm_r): Likewise. + (tsubst_decl): Likewise. + (tsubst_qualified_id): Handle template template parameters. + (tsubst_copy): Remove support for LOOKUP_EXPR. + (tsubst_copy_and_build): Likewise. + (most_general_template): Likewise. + (value_dependent_expression_p): Likewise. + (type_dependent_expression_p): Note that IDENTIFIER_NODEs are + always dependent. + * semantics.c (perform_koenig_lookup): Do not create + IDENTIFIER_NODEs. + (finish_fname): Likewise. + (finish_id_expression): Likewise. + * tree.c (is_aggr_type_2): Remove. + 2003-07-16 Gabriel Dos Reis PR c++/11531 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index bd947f7a8aa..a9323cc1f91 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -2607,7 +2607,7 @@ build_user_type_conversion (tree totype, tree expr, int flags) /* Find the possibly overloaded set of functions corresponding to a call of the form SCOPE::NAME (...). NAME might be a - TEMPLATE_ID_EXPR, OVERLOAD, _DECL, IDENTIFIER_NODE or LOOKUP_EXPR. */ + TEMPLATE_ID_EXPR, OVERLOAD, _DECL, or IDENTIFIER_NODE. */ tree resolve_scoped_fn_name (tree scope, tree name) @@ -2623,8 +2623,6 @@ resolve_scoped_fn_name (tree scope, tree name) } if (TREE_CODE (name) == OVERLOAD) name = DECL_NAME (get_first_fn (name)); - else if (TREE_CODE (name) == LOOKUP_EXPR) - name = TREE_OPERAND (name, 0); if (TREE_CODE (scope) == NAMESPACE_DECL) fn = lookup_namespace_name (scope, name); diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index f9819ec1cad..5e853fea085 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -208,8 +208,7 @@ DEFTREECODE (DEFAULT_ARG, "default_arg", 'x', 0) The second is the TREE_LIST or TREE_VEC of explicitly specified arguments. The template will be a FUNCTION_DECL, TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a member template, the - template may be an IDENTIFIER_NODE. In an uninstantiated template, - the template may be a LOOKUP_EXPR. */ + template may be an IDENTIFIER_NODE. */ DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2) /* A list-like node for chaining overloading candidates. TREE_TYPE is @@ -220,12 +219,6 @@ DEFTREECODE (OVERLOAD, "overload", 'x', 0) tree structure. */ DEFTREECODE (WRAPPER, "wrapper", 'x', 0) -/* Used to represent deferred name lookup for dependent names while - parsing a template declaration. The first argument is an - IDENTIFIER_NODE for the name in question. The TREE_TYPE is - unused. */ -DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 1) - /* A whole bunch of tree codes for the initial, superficial parsing of templates. */ DEFTREECODE (MODOP_EXPR, "modop_expr", 'e', 3) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index acc4528f9ef..8272adc4db4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -39,7 +39,6 @@ struct diagnostic_context; IDENTIFIER_MARKED (IDENTIFIER_NODEs) NEW_EXPR_USE_GLOBAL (in NEW_EXPR). DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR). - LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR). TREE_INDIRECT_USING (in NAMESPACE_DECL). ICS_USER_FLAG (in _CONV) CLEANUP_P (in TRY_BLOCK) @@ -359,6 +358,8 @@ typedef enum cp_id_kind CP_ID_KIND_NONE, /* An unqualified-id that is not a template-id. */ CP_ID_KIND_UNQUALIFIED, + /* An uqualified-id that is a dependent name. */ + CP_ID_KIND_UNQUALIFIED_DEPENDENT, /* An unqualified template-id. */ CP_ID_KIND_TEMPLATE_ID, /* A qualified-id. */ @@ -2257,14 +2258,13 @@ struct lang_decl GTY(()) DECL_TI_TEMPLATE, `template S::f'. As a special case, for a member friend template of a template - class, this value will not be a TEMPLATE_DECL, but rather a - LOOKUP_EXPR, IDENTIFIER_NODE or OVERLOAD indicating the name of - the template and any explicit template arguments provided. For - example, in: + class, this value will not be a TEMPLATE_DECL, but rather an + IDENTIFIER_NODE or OVERLOAD indicating the name of the template and + any explicit template arguments provided. For example, in: template struct S { friend void f(int, double); } - the DECL_TI_TEMPLATE will be a LOOKUP_EXPR for `f' and the + the DECL_TI_TEMPLATE will be an IDENTIFIER_NODE for `f' and the DECL_TI_ARGS will be {int}. */ #define DECL_TI_TEMPLATE(NODE) TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE)) @@ -2312,7 +2312,6 @@ struct lang_decl GTY(()) #define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) #define DELETE_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) #define DELETE_EXPR_USE_VEC(NODE) TREE_LANG_FLAG_1 (NODE) -#define LOOKUP_EXPR_GLOBAL(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. */ @@ -3965,7 +3964,6 @@ extern void mark_class_instantiated (tree, int); extern void do_decl_instantiation (tree, tree); extern void do_type_instantiation (tree, tree, tsubst_flags_t); extern tree instantiate_decl (tree, int); -extern tree get_bindings (tree, tree, tree); extern int push_tinst_level (tree); extern void pop_tinst_level (void); extern int more_specialized_class (tree, tree, tree); @@ -4211,7 +4209,6 @@ extern tree ovl_cons (tree, tree); extern tree build_overload (tree, tree); extern tree function_arg_chain (tree); extern int promotes_to_aggr_type (tree, enum tree_code); -extern int is_aggr_type_2 (tree, tree); extern const char *cxx_printable_name (tree, int); extern tree build_exception_variant (tree, tree); extern tree bind_template_template_parm (tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 2daaee60c0e..9147caffa66 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8982,7 +8982,6 @@ grokfndecl (tree ctype, fns = TREE_OPERAND (fns, 1); } my_friendly_assert (TREE_CODE (fns) == IDENTIFIER_NODE - || TREE_CODE (fns) == LOOKUP_EXPR || TREE_CODE (fns) == OVERLOAD, 20001120); DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE); @@ -9804,9 +9803,6 @@ grokdeclarator (tree declarator, { tree fns = TREE_OPERAND (decl, 0); - if (TREE_CODE (fns) == LOOKUP_EXPR) - fns = TREE_OPERAND (fns, 0); - dname = fns; if (TREE_CODE (dname) == COMPONENT_REF) dname = TREE_OPERAND (dname, 1); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index b9bc9b2e791..c547d672bc6 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -956,10 +956,6 @@ dump_decl (tree t, int flags) } break; - case LOOKUP_EXPR: - dump_decl (TREE_OPERAND (t, 0), flags); - break; - case LABEL_DECL: print_tree_identifier (scratch_buffer, DECL_NAME (t)); break; @@ -1957,10 +1953,6 @@ dump_expr (tree t, int flags) print_right_paren (scratch_buffer); break; - case LOOKUP_EXPR: - print_tree_identifier (scratch_buffer, TREE_OPERAND (t, 0)); - break; - case ARROW_EXPR: dump_expr (TREE_OPERAND (t, 0), flags); output_add_string (scratch_buffer, "->"); diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index 8d149a27c4b..220b01214bb 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -333,8 +333,6 @@ do_friend (tree ctype, tree declarator, tree decl, tree parmdecls, if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) { declarator = TREE_OPERAND (declarator, 0); - if (TREE_CODE (declarator) == LOOKUP_EXPR) - declarator = TREE_OPERAND (declarator, 0); if (is_overloaded_fn (declarator)) declarator = DECL_NAME (get_first_fn (declarator)); } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 4a11b4319fa..dad52284e63 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1374,16 +1374,10 @@ build_offset_ref (tree type, tree name) name = DECL_NAME (name); else { - if (TREE_CODE (name) == LOOKUP_EXPR) - /* This can happen during tsubst'ing. */ - name = TREE_OPERAND (name, 0); - else - { - if (TREE_CODE (name) == COMPONENT_REF) - name = TREE_OPERAND (name, 1); - if (TREE_CODE (name) == OVERLOAD) - name = DECL_NAME (OVL_CURRENT (name)); - } + if (TREE_CODE (name) == COMPONENT_REF) + name = TREE_OPERAND (name, 1); + if (TREE_CODE (name) == OVERLOAD) + name = DECL_NAME (OVL_CURRENT (name)); } my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0); diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 039de435a65..2266f04080e 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -710,10 +710,9 @@ unqualified_fn_lookup_error (tree name) declaration of "f" is available. Historically, G++ and most other compilers accepted that usage; explain to the user what is going wrong. */ - (flag_permissive ? warning : error) - ("there are no arguments to `%D' that depend on a template " - "parameter, so a declaration of `%D' must be available", name, - name); + pedwarn ("there are no arguments to `%D' that depend on a template " + "parameter, so a declaration of `%D' must be available", + name, name); if (!flag_permissive) { @@ -726,7 +725,7 @@ unqualified_fn_lookup_error (tree name) hint = true; } } - return build_min_nt (LOOKUP_EXPR, name); + return name; } return unqualified_name_lookup_error (name); diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 29fd523c727..ba7cf92c052 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -1926,8 +1926,6 @@ write_expression (tree expr) { template_args = TREE_OPERAND (member, 1); member = TREE_OPERAND (member, 0); - if (TREE_CODE (member) == LOOKUP_EXPR) - member = TREE_OPERAND (member, 0); } else template_args = NULL_TREE; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index bfce0ca8d34..33f1d793ce0 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3438,7 +3438,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) /* Keep looping until the postfix-expression is complete. */ while (true) { - if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE + if (idk == CP_ID_KIND_UNQUALIFIED + && TREE_CODE (postfix_expression) == IDENTIFIER_NODE && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)) /* It is not a Koenig lookup function call. */ postfix_expression diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 90b52afe3fd..8712ce6efb7 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -132,6 +132,7 @@ static int template_parm_this_level_p (tree, void *); static tree tsubst_friend_function (tree, tree); static tree tsubst_friend_class (tree, tree); static int can_complete_type_without_circularity (tree); +static tree get_bindings (tree, tree, tree); static tree get_bindings_real (tree, tree, tree, int, int, int); static int template_decl_level (tree); static int check_cv_quals_for_unify (int, tree, tree); @@ -1639,15 +1640,6 @@ check_explicit_specialization (tree declarator, return decl; } - else if (TREE_CODE (TREE_OPERAND (declarator, 0)) == LOOKUP_EXPR) - { - /* A friend declaration. We can't do much, because we don't - know what this resolves to, yet. */ - my_friendly_assert (is_friend != 0, 0); - my_friendly_assert (!explicit_instantiation, 0); - SET_DECL_IMPLICIT_INSTANTIATION (decl); - return decl; - } else if (ctype != NULL_TREE && (TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE)) @@ -3905,8 +3897,7 @@ lookup_template_function (tree fns, tree arglist) my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL || TREE_CODE (fns) == OVERLOAD || BASELINK_P (fns) - || TREE_CODE (fns) == IDENTIFIER_NODE - || TREE_CODE (fns) == LOOKUP_EXPR, + || TREE_CODE (fns) == IDENTIFIER_NODE, 20020730); if (BASELINK_P (fns)) @@ -4579,7 +4570,6 @@ for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d) case ARROW_EXPR: case DOTSTAR_EXPR: case TYPEID_EXPR: - case LOOKUP_EXPR: case PSEUDO_DTOR_EXPR: if (!fn) return error_mark_node; @@ -5965,10 +5955,10 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) }; Here, the DECL_TI_TEMPLATE for the friend declaration - will be a LOOKUP_EXPR or an IDENTIFIER_NODE. We are - being called from tsubst_friend_function, and we want - only to create a new decl (R) with appropriate types so - that we can call determine_specialization. */ + will be an IDENTIFIER_NODE. We are being called from + tsubst_friend_function, and we want only to create a + new decl (R) with appropriate types so that we can call + determine_specialization. */ gen_tmpl = NULL_TREE; } @@ -7143,6 +7133,18 @@ tsubst_qualified_id (tree qualified_id, tree args, } else expr = name; + + /* This case can occur while determining which of two templates is + the more specialized. After performing argument deduction, we + check that no invalid types are created. During that phase, we + may seem uninstantiated template parameters. */ + if (TREE_CODE (scope) == BOUND_TEMPLATE_TEMPLATE_PARM) + { + if (is_template) + expr = lookup_template_function (expr, template_args); + return build_nt (SCOPE_REF, scope, expr); + } + if (!BASELINK_P (name) && !DECL_P (expr)) expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, (complain & tf_error) != 0); @@ -7160,7 +7162,7 @@ tsubst_qualified_id (tree qualified_id, tree args, } if (is_template) - lookup_template_function (expr, template_args); + expr = lookup_template_function (expr, template_args); if (TYPE_P (scope)) { @@ -7286,25 +7288,6 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* Ordinary template template argument. */ return t; - case LOOKUP_EXPR: - { - /* We must tsubst into a LOOKUP_EXPR in case the names to - which it refers is a conversion operator; in that case the - name will change. We avoid making unnecessary copies, - however. */ - - tree id = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl); - - if (id != TREE_OPERAND (t, 0)) - { - r = build_nt (LOOKUP_EXPR, id); - LOOKUP_EXPR_GLOBAL (r) = LOOKUP_EXPR_GLOBAL (t); - t = r; - } - - return t; - } - case CAST_EXPR: case REINTERPRET_CAST_EXPR: case CONST_CAST_EXPR: @@ -7907,26 +7890,14 @@ tsubst_copy_and_build (tree t, switch (TREE_CODE (t)) { - case LOOKUP_EXPR: case IDENTIFIER_NODE: { tree decl; - tree scope; cp_id_kind idk; tree qualifying_class; bool non_constant_expression_p; const char *error_msg; - /* Remember whether this identifier was explicitly qualified - with "::". */ - if (TREE_CODE (t) == LOOKUP_EXPR && LOOKUP_EXPR_GLOBAL (t)) - scope = global_namespace; - else - scope = NULL_TREE; - /* Get at the underlying identifier. */ - if (TREE_CODE (t) == LOOKUP_EXPR) - t = TREE_OPERAND (t, 0); - if (IDENTIFIER_TYPENAME_P (t)) { tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); @@ -7934,17 +7905,14 @@ tsubst_copy_and_build (tree t, } /* Look up the name. */ - if (scope == global_namespace) - decl = IDENTIFIER_GLOBAL_VALUE (t); - else - decl = lookup_name (t, 0); + decl = lookup_name (t, 0); /* By convention, expressions use ERROR_MARK_NODE to indicate failure, not NULL_TREE. */ if (decl == NULL_TREE) decl = error_mark_node; - decl = finish_id_expression (t, decl, scope, + decl = finish_id_expression (t, decl, NULL_TREE, &idk, &qualifying_class, /*constant_expression_p=*/false, @@ -10203,8 +10171,8 @@ most_general_template (tree decl) /* Look for more and more general templates. */ while (DECL_TEMPLATE_INFO (decl)) { - /* The DECL_TI_TEMPLATE can be a LOOKUP_EXPR or IDENTIFIER_NODE - in some cases. (See cp-tree.h for details.) */ + /* The DECL_TI_TEMPLATE can be an IDENTIFIER_NODE in some cases. + (See cp-tree.h for details.) */ if (TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL) break; @@ -11493,7 +11461,7 @@ value_dependent_expression_p (tree expression) return false; /* A name declared with a dependent type. */ - if (TREE_CODE (expression) == LOOKUP_EXPR + if (TREE_CODE (expression) == IDENTIFIER_NODE || (DECL_P (expression) && type_dependent_expression_p (expression))) return true; @@ -11595,6 +11563,10 @@ type_dependent_expression_p (tree expression) if (expression == error_mark_node) return false; + + /* An unresolved name is always dependent. */ + if (TREE_CODE (expression) == IDENTIFIER_NODE) + return true; /* Some expression forms are never type-dependent. */ if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 9a9ae20e1be..02783859cb4 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1512,7 +1512,7 @@ perform_koenig_lookup (tree fn, tree args) fn = unqualified_fn_lookup_error (identifier); } else - fn = build_min_nt (LOOKUP_EXPR, identifier); + fn = identifier; return fn; } @@ -1819,7 +1819,7 @@ finish_fname (tree id) decl = fname_decl (C_RID_CODE (id), id); if (processing_template_decl) - decl = build_min_nt (LOOKUP_EXPR, DECL_NAME (decl)); + decl = DECL_NAME (decl); return decl; } @@ -2372,12 +2372,6 @@ finish_id_expression (tree id_expression, An id-expression is type-dependent if it contains an identifier that was declared with a dependent type. - As an optimization, we could choose not to create a - LOOKUP_EXPR for a name that resolved to a local variable in - the template function that we are currently declaring; such a - name cannot ever resolve to anything else. If we did that we - would not have to look up these names at instantiation time. - The standard is not very specific about an id-expression that names a set of overloaded functions. What if some of them have dependent types and some of them do not? Presumably, @@ -2469,8 +2463,8 @@ finish_id_expression (tree id_expression, constant when things are instantiated. */ if (constant_expression_p) *non_constant_expression_p = true; - /* Create a LOOKUP_EXPR for other unqualified names. */ - return build_min_nt (LOOKUP_EXPR, id_expression); + *idk = CP_ID_KIND_UNQUALIFIED_DEPENDENT; + return id_expression; } /* Only certain kinds of names are allowed in constant diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 7f137343686..72173fe48bb 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -988,13 +988,6 @@ build_overload (tree decl, tree chain) return ovl_cons (decl, chain); } -int -is_aggr_type_2 (tree t1, tree t2) -{ - if (TREE_CODE (t1) != TREE_CODE (t2)) - return 0; - return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2); -} #define PRINT_RING_SIZE 4