gcc/cp/ChangeLog:
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.
gcc/testsuite/ChangeLog:
PR c++/43206
* g++.dg/template/typedef30.C: New test case.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157730
138bc75d-0d04-0410-961f-
82ee72b054a4
+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
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);
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. */
/* 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));
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)
+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
--- /dev/null
+// 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;
+