aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-02-13 06:05:33 +0000
committerDouglas Gregor <dgregor@apple.com>2010-02-13 06:05:33 +0000
commitae6288981b77d6230bf62055d3bb6380580aa1e8 (patch)
tree0f625c5a3838de4cac4e5939f7c25db2e1400492
parentfe3310697028d8d3d35a11b0877bb2bc47e55b8d (diff)
Fix a fiendinshly fun little type-canonicalization bug, where we were
rebuilding a typename type terminating in a template-id (with dependent template name, naturally) as a TypenameType when, because its context could be fully resolved, we should have been building it as a QualifiedNameType. Fixes PR6268. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96084 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/TreeTransform.h8
-rw-r--r--test/SemaTemplate/typename-specifier-4.cpp19
2 files changed, 25 insertions, 2 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 02dabbb2f5..fc069f7ba3 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -525,9 +525,13 @@ public:
/// and the given type. Subclasses may override this routine to provide
/// different behavior.
QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
- if (NNS->isDependent())
- return SemaRef.Context.getTypenameType(NNS,
+ if (NNS->isDependent()) {
+ CXXScopeSpec SS;
+ SS.setScopeRep(NNS);
+ if (!SemaRef.computeDeclContext(SS))
+ return SemaRef.Context.getTypenameType(NNS,
cast<TemplateSpecializationType>(T));
+ }
return SemaRef.Context.getQualifiedNameType(NNS, T);
}
diff --git a/test/SemaTemplate/typename-specifier-4.cpp b/test/SemaTemplate/typename-specifier-4.cpp
index 9c757c5ad0..0a6fef74c3 100644
--- a/test/SemaTemplate/typename-specifier-4.cpp
+++ b/test/SemaTemplate/typename-specifier-4.cpp
@@ -80,3 +80,22 @@ namespace PR6236 {
}
};
}
+
+namespace PR6268 {
+ template <typename T>
+ struct Outer {
+ template <typename U>
+ struct Inner {};
+
+ template <typename U>
+ typename Outer<T>::template Inner<U>
+ foo(typename Outer<T>::template Inner<U>);
+ };
+
+ template <typename T>
+ template <typename U>
+ typename Outer<T>::template Inner<U>
+ Outer<T>::foo(typename Outer<T>::template Inner<U>) {
+ return Inner<U>();
+ }
+}