diff options
-rw-r--r-- | gcc/cp/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/pt.c | 19 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/typedef30.C | 20 |
6 files changed, 79 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0aad33c..ff66a20 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2010-03-25 Dodji Seketeli <dodji@redhat.com> + + PR c++/43206 + * cp-tree.h (get_template_parms_at_level): Declare ... + * pt.c (get_template_parms_at_level): ... new function. + * typeck.c (get_template_parms_of_dependent_type): If a template + type parm's DECL_CONTEXT isn't yet set, get its siblings from + current_template_parms. Use get_template_parms_at_level. Remove + useless test. + (incompatible_dependent_types_p): If we get empty parms from just one + of the template type parms we are comparing then the template parms are + incompatible. + 2010-03-24 Jason Merrill <jason@redhat.com> PR c++/43502 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5604a9d..5648827 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4973,6 +4973,7 @@ extern void init_template_processing (void); bool template_template_parameter_p (const_tree); extern bool primary_template_instantiation_p (const_tree); extern tree get_primary_template_innermost_parameters (const_tree); +extern tree get_template_parms_at_level (tree, unsigned); extern tree get_template_innermost_arguments (const_tree); extern tree get_template_argument_pack_elems (const_tree); extern tree get_function_template_decl (const_tree); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f5d68f8..59fdc44 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2839,6 +2839,25 @@ get_primary_template_innermost_parameters (const_tree t) return parms; } +/* Return the template parameters of the LEVELth level from the full list + of template parameters PARMS. */ + +tree +get_template_parms_at_level (tree parms, unsigned level) +{ + tree p; + if (!parms + || TREE_CODE (parms) != TREE_LIST + || level > TMPL_PARMS_DEPTH (parms)) + return NULL_TREE; + + for (p = parms; p; p = TREE_CHAIN (p)) + if (TMPL_PARMS_DEPTH (p) == level) + return p; + + return NULL_TREE; +} + /* Returns the template arguments of T if T is a template instantiation, NULL otherwise. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index b9ef78f..a4c64ea 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1113,9 +1113,17 @@ get_template_parms_of_dependent_type (tree t) /* If T1 is a typedef or whatever has a template info associated to its context, get the template parameters from that context. */ else if (typedef_variant_p (t) - && DECL_CONTEXT (TYPE_NAME (t)) - && !NAMESPACE_SCOPE_P (TYPE_NAME (t))) + && !NAMESPACE_SCOPE_P (TYPE_NAME (t))) tinfo = get_template_info (DECL_CONTEXT (TYPE_NAME (t))); + else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM + && DECL_CONTEXT (TYPE_NAME (t)) == NULL_TREE) + /* We have not yet created the DECL_TEMPLATE this + template type parm belongs to. It probably means + that we are in the middle of parsing the template parameters + of a template, and T is one of the parameters we have parsed. + Let's return the list of template parms we have parsed so far. */ + return get_template_parms_at_level (current_template_parms, + TEMPLATE_TYPE_LEVEL (t)); else if (TYPE_CONTEXT (t) && !NAMESPACE_SCOPE_P (t)) tinfo = get_template_info (TYPE_CONTEXT (t)); @@ -1170,6 +1178,17 @@ incompatible_dependent_types_p (tree t1, tree t2) tparms1 = get_template_parms_of_dependent_type (t1); tparms2 = get_template_parms_of_dependent_type (t2); + /* If T2 is a template type parm and if we could not get the template + parms it belongs to, that means we have not finished parsing the + full set of template parameters of the template declaration it + belongs to yet. If we could get the template parms T1 belongs to, + that mostly means T1 and T2 belongs to templates that are + different and incompatible. */ + if (TREE_CODE (t1) == TEMPLATE_TYPE_PARM + && (tparms1 == NULL_TREE || tparms2 == NULL_TREE) + && tparms1 != tparms2) + return true; + if (tparms1 == NULL_TREE || tparms2 == NULL_TREE || tparms1 == tparms2) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 93083bf..8c7bc15 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-03-25 Dodji Seketeli <dodji@redhat.com> + + PR c++/43206 + * g++.dg/template/typedef30.C: New test case. + 2010-03-25 Jakub Jelinek <jakub@redhat.com> PR c/43385 diff --git a/gcc/testsuite/g++.dg/template/typedef30.C b/gcc/testsuite/g++.dg/template/typedef30.C new file mode 100644 index 0000000..2f9362a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef30.C @@ -0,0 +1,20 @@ +// Origin: PR c++/43206 +// { dg-do compile } + +template<class A> struct NumericTraits{ typedef A TInputImage;}; +template<class B> class CovariantVector{}; +template<class C> struct Image{ typedef C PixelType;}; +template<class H, class E, class D> +class F { + typedef H G; + typedef + typename NumericTraits<typename G::PixelType>::RealType + InputRealType; +}; + +template<typename TInputImage, + typename TOutputImage=Image<CovariantVector<typename NumericTraits<typename TInputImage::PixelType>::TInputImage> > > +class XXX{}; + +XXX<Image<float> > x; + |