]> granicus.if.org Git - clang/commitdiff
Fix handling of dependent nested namespace specifiers in UsingDecls
authorDouglas Gregor <dgregor@apple.com>
Wed, 29 Sep 2010 17:58:28 +0000 (17:58 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 29 Sep 2010 17:58:28 +0000 (17:58 +0000)
during template instantiation, from Martin Vejnar!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@115051 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaTemplate/instantiate-using-decl.cpp

index d87629151ebe59492e2f8ac18788f0a04ac0ee93..d0df7fae755049eac96740d9f59c5e6a2b37da58 100644 (file)
@@ -1558,8 +1558,24 @@ Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
 }
 
 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 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
   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) {
index 257904490daab7c22f73e2e614c9c9d1d80ea3d6..1bfcb7a86508eb55dc45884773f369c3ff28c6c5 100644 (file)
@@ -61,3 +61,22 @@ namespace test2 {
 
   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();
+  }
+}