[cfe-commits] r80434 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/instantiate-using-decl.cpp

Anders Carlsson andersca at mac.com
Sat Aug 29 12:37:28 PDT 2009


Author: andersca
Date: Sat Aug 29 14:37:28 2009
New Revision: 80434

URL: http://llvm.org/viewvc/llvm-project?rev=80434&view=rev
Log:
Improve instantiation of UnresolvedUsingDecls.

Added:
    cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=80434&r1=80433&r2=80434&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Sat Aug 29 14:37:28 2009
@@ -44,16 +44,18 @@
   class TargetInfo;
   // Decls
   class Decl;
+  class FieldDecl;
+  class ObjCIvarDecl;
+  class ObjCIvarRefExpr;
   class ObjCPropertyDecl;
   class RecordDecl;
   class TagDecl;
+  class TemplateTypeParmDecl;
   class TranslationUnitDecl;
   class TypeDecl;
   class TypedefDecl;
-  class TemplateTypeParmDecl;
-  class FieldDecl;
-  class ObjCIvarRefExpr;
-  class ObjCIvarDecl;
+  class UnresolvedUsingDecl;
+  class UsingDecl;
   
   namespace Builtin { class Context; }
   
@@ -171,6 +173,29 @@
   /// class template X). 
   llvm::DenseMap<VarDecl *, VarDecl *> InstantiatedFromStaticDataMember;
   
+  /// \brief Keeps track of the UnresolvedUsingDecls from which UsingDecls
+  /// where created during instantiation.
+  ///
+  /// For example:
+  /// \code
+  /// template<typename T>
+  /// struct A {
+  ///   void f();
+  /// };
+  ///
+  /// template<typename T>
+  /// struct B : A<T> {
+  ///   using A<T>::f;
+  /// };
+  ///
+  /// template struct B<int>;
+  /// \endcode
+  ///
+  /// This mapping will contain an entry that maps from the UsingDecl in
+  /// B<int> to the UnresolvedUsingDecl in B<T>.
+  llvm::DenseMap<UsingDecl *, UnresolvedUsingDecl *>
+    InstantiatedFromUnresolvedUsingDecl;
+  
   TranslationUnitDecl *TUDecl;
 
   /// SourceMgr - The associated SourceManager object.
@@ -242,6 +267,10 @@
   /// the static data member template \p Tmpl of a class template.
   void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl);  
   
+  UnresolvedUsingDecl *getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD);
+  void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *UD,
+                                              UnresolvedUsingDecl *UUD);
+  
   TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
 
   const char *getCommentForDecl(const Decl *D);

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=80434&r1=80433&r2=80434&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sat Aug 29 14:37:28 2009
@@ -242,6 +242,24 @@
   InstantiatedFromStaticDataMember[Inst] = Tmpl;
 }
 
+UnresolvedUsingDecl *
+ASTContext::getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD) {
+  llvm::DenseMap<UsingDecl *, UnresolvedUsingDecl *>::iterator Pos 
+    = InstantiatedFromUnresolvedUsingDecl.find(UUD);
+  if (Pos == InstantiatedFromUnresolvedUsingDecl.end())
+    return 0;
+  
+  return Pos->second;
+}
+
+void
+ASTContext::setInstantiatedFromUnresolvedUsingDecl(UsingDecl *UD,
+                                                   UnresolvedUsingDecl *UUD) {
+  assert(!InstantiatedFromUnresolvedUsingDecl[UD] &&
+         "Already noted what using decl what instantiated from");
+  InstantiatedFromUnresolvedUsingDecl[UD] = UUD;
+}
+
 namespace {
   class BeforeInTranslationUnit 
     : std::binary_function<SourceRange, SourceRange, bool> {

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=80434&r1=80433&r2=80434&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Sat Aug 29 14:37:28 2009
@@ -477,6 +477,11 @@
   if (!InstD)
     return SemaRef.ExprError();
   
+  // If we instantiated an UnresolvedUsingDecl and got back an UsingDecl,
+  // we need to get the underlying decl. 
+  // FIXME: Is this correct? Maybe FindInstantiatedDecl should do this?
+  InstD = InstD->getUnderlyingDecl();
+  
   // FIXME: nested-name-specifier for QualifiedDeclRefExpr
   return SemaRef.BuildDeclarationNameExpr(E->getLocation(), InstD, 
                                           /*FIXME:*/false,
@@ -685,6 +690,8 @@
         Invalid = true;
       else if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember))
         Fields.push_back(DeclPtrTy::make(Field));
+      else if (UsingDecl *UD = dyn_cast<UsingDecl>(NewMember))
+        Instantiation->addDecl(UD);
     } else {
       // FIXME: Eventually, a NULL return will mean that one of the
       // instantiations was a semantic disaster, and we'll want to set Invalid =

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=80434&r1=80433&r2=80434&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sat Aug 29 14:37:28 2009
@@ -757,9 +757,14 @@
   SS.setRange(D->getTargetNestedNameRange());
   SS.setScopeRep(NNS);
   
-  return SemaRef.BuildUsingDeclaration(D->getLocation(), SS, 
-                                       D->getTargetNameLocation(), 
-                                       D->getTargetName(), 0, D->isTypeName());
+  NamedDecl *UD = 
+    SemaRef.BuildUsingDeclaration(D->getLocation(), SS, 
+                                  D->getTargetNameLocation(), 
+                                  D->getTargetName(), 0, D->isTypeName());
+  if (UD)
+    SemaRef.Context.setInstantiatedFromUnresolvedUsingDecl(cast<UsingDecl>(UD), 
+                                                           D);
+  return UD;
 }
 
 Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner,
@@ -1220,6 +1225,12 @@
   return false;
 }
 
+static bool isInstantiationOf(UnresolvedUsingDecl *Pattern,
+                              UsingDecl *Instance,
+                              ASTContext &C) {
+  return C.getInstantiatedFromUnresolvedUsingDecl(Instance) == Pattern;
+}
+
 static bool isInstantiationOfStaticDataMember(VarDecl *Pattern,
                                               VarDecl *Instance) {
   assert(Instance->isStaticDataMember());
@@ -1236,9 +1247,16 @@
 }
 
 static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {
-  if (D->getKind() != Other->getKind())
-    return false;
+  if (D->getKind() != Other->getKind()) {
+    if (UnresolvedUsingDecl *UUD = dyn_cast<UnresolvedUsingDecl>(D)) {
+      if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {
+        return isInstantiationOf(UUD, UD, Ctx);
+      }
+    }
 
+    return false;
+  }
+  
   if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Other))
     return isInstantiationOf(cast<CXXRecordDecl>(D), Record);
   

Added: cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp?rev=80434&view=auto

==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp (added)
+++ cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp Sat Aug 29 14:37:28 2009
@@ -0,0 +1,17 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+template<typename T>
+struct A {
+  void f();
+};
+
+template<typename T>
+struct B : A<T> {
+  using A<T>::f;
+  
+  void g() {
+    f();
+  }
+};
+
+template struct B<int>;





More information about the cfe-commits mailing list