From: Jason Merrill Date: Mon, 3 Aug 1998 22:11:25 +0000 (+0000) Subject: method.c (set_mangled_name_for_decl): Change return type to void. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c1def683c1c18e090cd3f7a96fd44c055b41b106;p=platform%2Fupstream%2Fgcc.git method.c (set_mangled_name_for_decl): Change return type to void. * method.c (set_mangled_name_for_decl): Change return type to void. * decl.c (lookup_name_real): A namespace-level decl takes priority over implicit typename. Avoid doing the same lookup twice. * search.c (dependent_base_p): New fn. (dfs_pushdecls, dfs_compress_decls): Use it. * typeck.c (get_member_function_from_ptrfunc): Don't try to handle virtual functions if the type doesn't have any. From-SVN: r21551 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ee6b01f..2d2e7dc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +1998-08-03 Jason Merrill + + * method.c (set_mangled_name_for_decl): Change return type to void. + + * decl.c (lookup_name_real): A namespace-level decl takes priority + over implicit typename. Avoid doing the same lookup twice. + + * search.c (dependent_base_p): New fn. + (dfs_pushdecls, dfs_compress_decls): Use it. + + * typeck.c (get_member_function_from_ptrfunc): Don't try to handle + virtual functions if the type doesn't have any. + 1998-08-03 Mark Mitchell * decl2.c (grokfield): Don't mangle the name of a TYPE_DECL if it diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 72a1655..aa84e0f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2733,7 +2733,7 @@ extern tree build_static_name PROTO((tree, tree)); extern tree build_decl_overload PROTO((tree, tree, int)); extern tree build_decl_overload_real PROTO((tree, tree, tree, tree, tree, int)); -extern tree set_mangled_name_for_decl PROTO((tree)); +extern void set_mangled_name_for_decl PROTO((tree)); extern tree build_typename_overload PROTO((tree)); extern tree build_overload_with_type PROTO((tree, tree)); extern tree build_destructor_name PROTO((tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 0b32a3d..6841905 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5074,11 +5074,11 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only) /* Add implicit 'typename' to types from template bases. lookup_field will do this for us. If classval is actually from an enclosing scope, lookup_nested_field will get it for us. */ - if (processing_template_decl - && classval && TREE_CODE (classval) == TYPE_DECL - && ! currently_open_class (DECL_CONTEXT (classval)) - && uses_template_parms (current_class_type) - && ! DECL_ARTIFICIAL (classval)) + else if (processing_template_decl + && classval && TREE_CODE (classval) == TYPE_DECL + && ! currently_open_class (DECL_CONTEXT (classval)) + && uses_template_parms (current_class_type) + && ! DECL_ARTIFICIAL (classval)) classval = lookup_field (current_class_type, name, 0, 1); /* yylex() calls this with -2, since we should never start digging for @@ -5121,6 +5121,28 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only) else val = unqualified_namespace_lookup (name, flags); + if (classval && TREE_CODE (val) == TYPE_DECL + && TREE_CODE (TREE_TYPE (val)) == TYPENAME_TYPE + && TREE_TYPE (TREE_TYPE (val))) + { + tree nsval = unqualified_namespace_lookup (name, flags); + + if (val && nsval && TREE_CODE (nsval) == TYPE_DECL) + { + static int explained; + cp_warning ("namespace-scope type `%#D'", nsval); + cp_warning + (" is used instead of `%D' from dependent base class", val); + if (! explained) + { + explained = 1; + cp_warning (" (use `typename %D' if that's what you meant)", + val); + } + val = nsval; + } + } + done: if (val) { diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 18e638c..69ba1b0 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1663,7 +1663,7 @@ build_decl_overload (dname, parms, for_method) /* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL. */ -tree +void set_mangled_name_for_decl (decl) tree decl; { diff --git a/gcc/cp/search.c b/gcc/cp/search.c index bde0a29..79042e1 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -3480,6 +3480,23 @@ envelope_add_decl (type, decl, values) } } +/* Returns 1 iff BINFO is a base we shouldn't really be able to see into, + because it (or one of the intermediate bases) depends on template parms. */ + +static int +dependent_base_p (binfo) + tree binfo; +{ + for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo)) + { + if (binfo == current_class_type) + break; + if (uses_template_parms (TREE_TYPE (binfo))) + return 1; + } + return 0; +} + /* Add the instance variables which this class contributed to the current class binding contour. When a redefinition occurs, if the redefinition is strictly within a single inheritance path, we just @@ -3506,9 +3523,18 @@ dfs_pushdecls (binfo) tree type = BINFO_TYPE (binfo); tree fields, *methods, *end; tree method_vec; + int dummy = 0; + + /* Only record types if we're a template base. */ + if (processing_template_decl && type != current_class_type + && dependent_base_p (binfo)) + dummy = 1; for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) { + if (dummy && TREE_CODE (fields) != TYPE_DECL) + continue; + /* Unmark so that if we are in a constructor, and then find that this field was initialized by a base initializer, we can emit an error message. */ @@ -3546,7 +3572,7 @@ dfs_pushdecls (binfo) } method_vec = CLASSTYPE_METHOD_VEC (type); - if (method_vec) + if (method_vec && ! dummy) { /* Farm out constructors and destructors. */ methods = &TREE_VEC_ELT (method_vec, 2); @@ -3598,7 +3624,10 @@ dfs_compress_decls (binfo) tree type = BINFO_TYPE (binfo); tree method_vec = CLASSTYPE_METHOD_VEC (type); - if (method_vec != 0) + if (processing_template_decl && type != current_class_type + && dependent_base_p (binfo)) + /* We only record types if we're a template base. */; + else if (method_vec != 0) { /* Farm out constructors and destructors. */ tree *methods = &TREE_VEC_ELT (method_vec, 2); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 0ae703b..3e4fd0a 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2669,7 +2669,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function))) { tree fntype, idx, e1, delta, delta2, e2, e3, aref, vtbl; - tree instance; + tree instance, basetype; tree instance_ptr = *instance_ptrptr; @@ -2680,61 +2680,76 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) function = save_expr (function); fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function)); + basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype)); - /* Promoting idx before saving it improves performance on RISC - targets. Without promoting, the first compare used - load-with-sign-extend, while the second used normal load then - shift to sign-extend. An optimizer flaw, perhaps, but it's easier - to make this change. */ - idx = save_expr (default_conversion - (build_component_ref (function, - index_identifier, - NULL_TREE, 0))); - e1 = build_binary_op (GT_EXPR, idx, integer_zero_node, 1); delta = cp_convert (ptrdiff_type_node, build_component_ref (function, delta_identifier, NULL_TREE, 0)); - delta2 = DELTA2_FROM_PTRMEMFUNC (function); - - /* Convert down to the right base, before using the instance. */ - instance - = convert_pointer_to_real (TYPE_METHOD_BASETYPE (TREE_TYPE (fntype)), - instance_ptr); - if (instance == error_mark_node && instance_ptr != error_mark_node) - return instance; - - vtbl = convert_pointer_to (ptr_type_node, instance); - vtbl - = build (PLUS_EXPR, - build_pointer_type (build_pointer_type (vtable_entry_type)), - vtbl, cp_convert (ptrdiff_type_node, delta2)); - vtbl = build_indirect_ref (vtbl, NULL_PTR); - aref = build_array_ref (vtbl, build_binary_op (MINUS_EXPR, - idx, - integer_one_node, 1)); - if (! flag_vtable_thunks) - { - aref = save_expr (aref); - - delta = build_binary_op + e3 = PFN_FROM_PTRMEMFUNC (function); + + if (TYPE_SIZE (basetype) != NULL_TREE + && ! TYPE_VIRTUAL_P (basetype)) + /* If basetype doesn't have virtual functions, don't emit code to + handle that case. */ + e1 = e3; + else + { + /* Promoting idx before saving it improves performance on RISC + targets. Without promoting, the first compare used + load-with-sign-extend, while the second used normal load then + shift to sign-extend. An optimizer flaw, perhaps, but it's + easier to make this change. */ + idx = save_expr (default_conversion + (build_component_ref (function, + index_identifier, + NULL_TREE, 0))); + e1 = build_binary_op (GT_EXPR, idx, integer_zero_node, 1); + + /* Convert down to the right base, before using the instance. */ + instance = convert_pointer_to_real (basetype, instance_ptr); + if (instance == error_mark_node && instance_ptr != error_mark_node) + return instance; + + vtbl = convert_pointer_to (ptr_type_node, instance); + delta2 = DELTA2_FROM_PTRMEMFUNC (function); + vtbl = build (PLUS_EXPR, - build_conditional_expr (e1, build_component_ref (aref, + build_pointer_type (build_pointer_type (vtable_entry_type)), + vtbl, cp_convert (ptrdiff_type_node, delta2)); + vtbl = build_indirect_ref (vtbl, NULL_PTR); + aref = build_array_ref (vtbl, build_binary_op (MINUS_EXPR, + idx, + integer_one_node, 1)); + if (! flag_vtable_thunks) + { + aref = save_expr (aref); + + delta = build_binary_op + (PLUS_EXPR, + build_conditional_expr (e1, + build_component_ref (aref, delta_identifier, NULL_TREE, 0), - integer_zero_node), - delta, 1); + integer_zero_node), + delta, 1); + } + + if (flag_vtable_thunks) + e2 = aref; + else + e2 = build_component_ref (aref, pfn_identifier, NULL_TREE, 0); + TREE_TYPE (e2) = TREE_TYPE (e3); + e1 = build_conditional_expr (e1, e2, e3); + + /* Make sure this doesn't get evaluated first inside one of the + branches of the COND_EXPR. */ + if (TREE_CODE (instance_ptr) == SAVE_EXPR) + e1 = build (COMPOUND_EXPR, TREE_TYPE (e1), + instance_ptr, e1); } *instance_ptrptr = build (PLUS_EXPR, TREE_TYPE (instance_ptr), instance_ptr, delta); - if (flag_vtable_thunks) - e2 = aref; - else - e2 = build_component_ref (aref, pfn_identifier, NULL_TREE, 0); - - e3 = PFN_FROM_PTRMEMFUNC (function); - TREE_TYPE (e2) = TREE_TYPE (e3); - e1 = build_conditional_expr (e1, e2, e3); if (instance_ptr == error_mark_node && TREE_CODE (e1) != ADDR_EXPR @@ -2742,12 +2757,6 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) cp_error ("object missing in `%E'", function); function = e1; - - /* Make sure this doesn't get evaluated first inside one of the - branches of the COND_EXPR. */ - if (TREE_CODE (instance_ptr) == SAVE_EXPR) - function = build (COMPOUND_EXPR, TREE_TYPE (function), - instance_ptr, function); } return function; }