From: Douglas Gregor Date: Sat, 5 Mar 2011 17:19:27 +0000 (+0000) Subject: When transforming a substituted template type parameter, try to X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68;p=clang When transforming a substituted template type parameter, try to transform the type that replaces the template type parameter. In the vast majority of cases, there's nothing to do, because most template type parameters are replaced with something non-dependent that doesn't need further transformation. However, when we're dealing with the default template arguments of template template parameters, we might end up replacing a template parameter (of the template template parameter) with a template parameter of the enclosing template. This addresses part of PR9016, but not within function templates. That's a separate issue. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127091 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 1a5a98a23e..94aac52e5b 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -4126,7 +4126,28 @@ template QualType TreeTransform::TransformSubstTemplateTypeParmType( TypeLocBuilder &TLB, SubstTemplateTypeParmTypeLoc TL) { - return TransformTypeSpecType(TLB, TL); + const SubstTemplateTypeParmType *T = TL.getTypePtr(); + + // Substitute into the replacement type, which itself might involve something + // that needs to be transformed. This only tends to occur with default + // template arguments of template template parameters. + TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName()); + QualType Replacement = getDerived().TransformType(T->getReplacementType()); + if (Replacement.isNull()) + return QualType(); + + // Always canonicalize the replacement type. + Replacement = SemaRef.Context.getCanonicalType(Replacement); + QualType Result + = SemaRef.Context.getSubstTemplateTypeParmType(T->getReplacedParameter(), + Replacement); + + // Propagate type-source information. + SubstTemplateTypeParmTypeLoc NewTL + = TLB.push(Result); + NewTL.setNameLoc(TL.getNameLoc()); + return Result; + } template diff --git a/test/SemaTemplate/issue150.cpp b/test/SemaTemplate/issue150.cpp index 0d7930723f..2cfa8c5cb1 100644 --- a/test/SemaTemplate/issue150.cpp +++ b/test/SemaTemplate/issue150.cpp @@ -69,3 +69,29 @@ namespace MultiReplacePartial { int check0[is_same::type, Y >::value? 1 : -1]; } + +namespace PR9016 { + template struct allocator ; + template struct less ; + + template class Compare, class Default, + template class Alloc> + struct interval_set { }; + + template class = less> struct interval_type_default { + typedef X type; + }; + + template class Compare = less, + class = typename interval_type_default<_T,Compare>::type, + template class = allocator> class IntervalSet> + struct ZZZ + { + IntervalSet IntervalSetT; + }; + + void test() { + ZZZ zzz; + } +}