diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c2f00998967..01b8371c5cc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,16 @@ +1998-09-09 Kriang Lerdsuwanakij + + * class.c (get_enclosing_class): New function. + (is_base_of_enclosing_class): Likewise. + * cp-tree.h (get_enclosing_class): Declare. + (is_base_of_enclosing_class): Likewise. + * pt.c (coerce_template_parms): Use them. + 1998-09-09 Jason Merrill + * g++spec.c (lang_specific_driver): Check whether MATH_LIBRARY is + null to decide whether to use it. + * error.c (dump_type_real): Handle NAMESPACE_DECL. * parse.y (base_class.1): Avoid crash on error. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 173c69a2830..e5863a4194d 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5449,3 +5449,49 @@ is_empty_class (type) t = TREE_CHAIN (t); return (t == NULL_TREE); } + +/* Find the enclosing class of the given NODE. NODE can be a *_DECL or + a *_TYPE node. NODE can also be a local class. */ + +tree +get_enclosing_class (type) + tree type; +{ + tree node = type; + + while (node && TREE_CODE (node) != NAMESPACE_DECL) + { + switch (TREE_CODE_CLASS (TREE_CODE (node))) + { + case 'd': + node = DECL_CONTEXT (node); + break; + + case 't': + if (node != type) + return node; + node = TYPE_CONTEXT (node); + break; + + default: + my_friendly_abort (0); + } + } + return NULL_TREE; +} + +/* Return 1 if TYPE or one of its enclosing classes is derived from BASE. */ + +int +is_base_of_enclosing_class (base, type) + tree base, type; +{ + while (type) + { + if (get_binfo (base, type, 0)) + return 1; + + type = get_enclosing_class (type); + } + return 0; +} diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 2939275d859..4dbfc9e6c3a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2425,6 +2425,8 @@ extern void maybe_push_cache_obstack PROTO((void)); extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *)); extern tree build_self_reference PROTO((void)); extern void warn_hidden PROTO((tree)); +extern tree get_enclosing_class PROTO((tree)); +int is_base_of_enclosing_class PROTO((tree, tree)); /* in cvt.c */ extern tree convert_to_reference PROTO((tree, tree, int, int, tree)); diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c index 542ca06f889..22060cd222d 100644 --- a/gcc/cp/g++spec.c +++ b/gcc/cp/g++spec.c @@ -34,9 +34,6 @@ Boston, MA 02111-1307, USA. */ #ifndef MATH_LIBRARY #define MATH_LIBRARY "-lm" #endif -#ifndef NEED_MATH_LIBRARY -#define NEED_MATH_LIBRARY 1 /* Default is pass MATH_LIBRARY to linker */ -#endif extern char *xmalloc PROTO((size_t)); @@ -83,8 +80,8 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) LANGSPEC, MATHLIB, or WITHLIBC. */ int *args; - /* By default, we throw on the math library. */ - int need_math = NEED_MATH_LIBRARY; + /* By default, we throw on the math library if we have one. */ + int need_math = (MATH_LIBRARY[0] != '\0'); /* The total number of arguments with the new stuff. */ int argc; @@ -128,6 +125,7 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) } else if (strcmp (argv[i], "-lm") == 0 || strcmp (argv[i], "-lmath") == 0 + || strcmp (argv[i], MATH_LIBRARY) == 0 #ifdef ALT_LIBM || strcmp (argv[i], ALT_LIBM) == 0 #endif diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e95d7d1e70c..5136383275d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2806,9 +2806,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl) && TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL && DECL_ARTIFICIAL (TYPE_NAME (arg)) && requires_tmpl_type - && current_class_type - /* FIXME what about nested types? */ - && get_binfo (arg, current_class_type, 0))); + && is_base_of_enclosing_class (arg, current_class_type))); if (is_tmpl_type && TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) arg = TYPE_STUB_DECL (arg); else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE)