summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-03-05 17:19:27 +0000
committerDouglas Gregor <dgregor@apple.com>2011-03-05 17:19:27 +0000
commit20bf98b5f874cc828ee20025281dbd82b51bd13e (patch)
treeecc71c291ec86ab059afe6e8899d2226a00ac04f /clang
parent00d09428fe4d62b47b66e5a633c9b6cb1c4061ab (diff)
downloadbcm5719-llvm-20bf98b5f874cc828ee20025281dbd82b51bd13e.tar.gz
bcm5719-llvm-20bf98b5f874cc828ee20025281dbd82b51bd13e.zip
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. llvm-svn: 127091
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/TreeTransform.h23
-rw-r--r--clang/test/SemaTemplate/issue150.cpp26
2 files changed, 48 insertions, 1 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 1a5a98a23e6..94aac52e5b0 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4126,7 +4126,28 @@ template<typename Derived>
QualType TreeTransform<Derived>::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<SubstTemplateTypeParmTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
+ return Result;
+
}
template<typename Derived>
diff --git a/clang/test/SemaTemplate/issue150.cpp b/clang/test/SemaTemplate/issue150.cpp
index 0d7930723fc..2cfa8c5cb1e 100644
--- a/clang/test/SemaTemplate/issue150.cpp
+++ b/clang/test/SemaTemplate/issue150.cpp
@@ -69,3 +69,29 @@ namespace MultiReplacePartial {
int check0[is_same<X<int, int, Y>::type, Y<int, int*, int* const> >::value? 1 : -1];
}
+
+namespace PR9016 {
+ template<typename > struct allocator ;
+ template<typename > struct less ;
+
+ template<class T, template<class> class Compare, class Default,
+ template<class> class Alloc>
+ struct interval_set { };
+
+ template <class X, template<class> class = less> struct interval_type_default {
+ typedef X type;
+ };
+
+ template <class T,
+ template<class _T, template<class> class Compare = less,
+ class = typename interval_type_default<_T,Compare>::type,
+ template<class> class = allocator> class IntervalSet>
+ struct ZZZ
+ {
+ IntervalSet<T> IntervalSetT;
+ };
+
+ void test() {
+ ZZZ<int, interval_set> zzz;
+ }
+}
OpenPOWER on IntegriCloud