Hi, this patch fixes what is written in subject. In particular, the
following program
template <typename T> struct t {
struct s1 {
T f1();
};
struct s2 : s1 {
using s1::f1;
};
};
template struct t<int>;
is now parsed without errors. Originally, no substitution was performed on
`s1` in the UsingDecl, which resulted in an error (t<T>::s1 is not a base
class of t<int>::s2).
A test case is included as well.
--
Martin
Index: test/SemaTemplate/instantiate-using-decl.cpp
===================================================================
--- test/SemaTemplate/instantiate-using-decl.cpp (revision 114637)
+++ test/SemaTemplate/instantiate-using-decl.cpp (working copy)
@@ -61,3 +61,22 @@
template void bar(char *);
}
+
+namespace test3 {
+ template <typename T> struct t {
+ struct s1 {
+ T f1() const;
+ };
+ struct s2 : s1 {
+ using s1::f1;
+ T f1() const;
+ };
+ };
+
+ void f2()
+ {
+ t<int>::s2 a;
+ t<int>::s2 const & b = a;
+ b.f1();
+ }
+}
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp (revision 114637)
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp (working copy)
@@ -1558,8 +1558,24 @@
}
Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
- // The nested name specifier is non-dependent, so no transformation
- // is required. The same holds for the name info.
+
+ // The nested name specifier may be dependent, for example
+ // template <typename T> struct t {
+ // struct s1 { T f1(); };
+ // struct s2 : s1 { using s1::f1; };
+ // };
+ // template struct t<int>;
+ // Here, in using s1::f1, s1 refers to t<T>::s1;
+ // we need to substitute for t<int>::s1.
+ NestedNameSpecifier *NNS =
+ SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameDecl(),
+ D->getNestedNameRange(),
+ TemplateArgs);
+ if (!NNS)
+ return 0;
+
+ // The name info is non-dependent, so no transformation
+ // is required.
DeclarationNameInfo NameInfo = D->getNameInfo();
// We only need to do redeclaration lookups if we're in a class
@@ -1573,12 +1589,12 @@
UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner,
D->getNestedNameRange(),
D->getUsingLocation(),
- D->getTargetNestedNameDecl(),
+ NNS,
NameInfo,
D->isTypeName());
CXXScopeSpec SS;
- SS.setScopeRep(D->getTargetNestedNameDecl());
+ SS.setScopeRep(NNS);
SS.setRange(D->getNestedNameRange());
if (CheckRedeclaration) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits