]> granicus.if.org Git - clang/commitdiff
Instantiate unresolved using declarations.
authorAnders Carlsson <andersca@mac.com>
Fri, 28 Aug 2009 15:18:15 +0000 (15:18 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 28 Aug 2009 15:18:15 +0000 (15:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80366 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclCXX.h
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaCXX/using-decl-templates.cpp [new file with mode: 0644]

index 45e85c0a49f2bb0e519bbd30d70e6e7a95796e8c..37a6d68f1bee47fd280f79d46ead84c835c4e5f0 100644 (file)
@@ -1610,7 +1610,7 @@ public:
     return TargetNestedNameDecl; 
   }
   
-  /// isTypeName - Return true if using decl had 'typename'.
+  /// isTypeName - Return true if using decl has 'typename'.
   bool isTypeName() const { return IsTypeName; }
 
   static UsingDecl *Create(ASTContext &C, DeclContext *DC,
@@ -1651,6 +1651,23 @@ class UnresolvedUsingDecl : public NamedDecl {
     IsTypeName(IsTypeNameArg) { }
 
 public:
+  /// \brief Returns the source range that covers the nested-name-specifier
+  /// preceding the namespace name.
+  SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
+  
+  /// \brief Get target nested name declaration.
+  NestedNameSpecifier* getTargetNestedNameSpecifier() { 
+    return TargetNestedNameSpecifier; 
+  }
+  
+  /// \brief Returns the source location of the target declaration name.
+  SourceLocation getTargetNameLocation() const { return TargetNameLocation; }
+  
+  /// \brief Returns the source location of the target declaration name.
+  DeclarationName getTargetName() const { return TargetName; }
+
+  bool isTypeName() const { return IsTypeName; }
+
   static UnresolvedUsingDecl *Create(ASTContext &C, DeclContext *DC,
                                      SourceLocation UsingLoc,
                                      SourceRange TargetNNR,
index 4874c92dece7b8a8e1c54bb3ecb07297c3fc7f35..5d1c059c7ff1d371e04eaa2731e6f80229b3ae82 100644 (file)
@@ -2160,8 +2160,9 @@ NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc,
         << NNS << RD->getDeclName();
       return 0;
     }
-    
-    LookupContext = cast<RecordType>(Ty)->getDecl();
+
+    QualType BaseTy = Context.getCanonicalType(QualType(Ty, 0));
+    LookupContext = BaseTy->getAs<RecordType>()->getDecl();
   } else {
     // C++0x N2914 [namespace.udecl]p8:
     // A using-declaration for a class member shall be a member-declaration.
index 0bf832f3ebdf06bf04ccc8a8bbacec2893eb29bf..4f9fcc3b9e0129ff465b625a16a5c2d38ce9d81b 100644 (file)
@@ -58,7 +58,8 @@ namespace {
     Decl *VisitClassTemplateDecl(ClassTemplateDecl *D);
     Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
     Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
-
+    Decl *VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D);
+      
     // Base case. FIXME: Remove once we can instantiate everything.
     Decl *VisitDecl(Decl *) { 
       assert(false && "Template instantiation of unknown declaration kind!");
@@ -740,6 +741,24 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
   return Inst;
 }
 
+Decl *
+TemplateDeclInstantiator::VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D) {
+  NestedNameSpecifier *NNS = 
+    SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(), 
+                                     D->getTargetNestedNameRange(), 
+                                     TemplateArgs);
+  if (!NNS)
+    return 0;
+  
+  CXXScopeSpec SS;
+  SS.setRange(D->getTargetNestedNameRange());
+  SS.setScopeRep(NNS);
+  
+  return SemaRef.BuildUsingDeclaration(D->getLocation(), SS, 
+                                       D->getTargetNameLocation(), 
+                                       D->getTargetName(), 0, D->isTypeName());
+}
+
 Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner,
                       const TemplateArgumentList &TemplateArgs) {
   TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
diff --git a/test/SemaCXX/using-decl-templates.cpp b/test/SemaCXX/using-decl-templates.cpp
new file mode 100644 (file)
index 0000000..13ee1b2
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+template<typename T> struct A {
+  void f() { }
+  struct N { };
+};
+
+template<typename T> struct B : A<T> {
+  using A<T>::f;
+  using A<T>::N;
+  
+  using A<T>::foo; // expected-error{{no member named 'foo'}}
+  using A<double>::f; // expected-error{{using declaration refers into 'A<double>::', which is not a base class of 'B'}}
+};
+
+B<int> a; // expected-note{{in instantiation of template class 'struct B<int>' requested here}}