[cfe-commits] r72486 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/SemaTemplateInstantiateExpr.cpp test/SemaTemplate/instantiate-declref.cpp

Douglas Gregor dgregor at apple.com
Wed May 27 10:55:05 PDT 2009


Author: dgregor
Date: Wed May 27 12:54:46 2009
New Revision: 72486

URL: http://llvm.org/viewvc/llvm-project?rev=72486&view=rev
Log:
Simplify, and improve the performance of, template instantiation for
declaration references. The key realization is that dependent Decls,
which actually require instantiation, can only refer to the current
instantiation or members thereof. And, since the current context
during instantiation contains all of those members of the current
instantiation, we can simply find the real instantiate that matches up
with the "current instantiation" template.

Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp
    cfe/trunk/test/SemaTemplate/instantiate-declref.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=72486&r1=72485&r2=72486&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed May 27 12:54:46 2009
@@ -2250,8 +2250,7 @@
                                      FunctionDecl *Function);
   void InstantiateVariableDefinition(VarDecl *Var);
 
-  NamedDecl *
-  InstantiateDeclRef(NamedDecl *D, const TemplateArgumentList &TemplateArgs);
+  NamedDecl *InstantiateCurrentDeclRef(NamedDecl *D);
   
   // Simple function for cloning expressions.
   template<typename T> 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Wed May 27 12:54:46 2009
@@ -407,8 +407,8 @@
 TemplateTypeInstantiator::InstantiateTypedefType(const TypedefType *T,
                                                  unsigned Quals) const {
   TypedefDecl *Typedef 
-    = cast_or_null<TypedefDecl>(SemaRef.InstantiateDeclRef(T->getDecl(), 
-                                                           TemplateArgs));
+    = cast_or_null<TypedefDecl>(
+                           SemaRef.InstantiateCurrentDeclRef(T->getDecl()));
   if (!Typedef)
     return QualType();
   
@@ -440,8 +440,7 @@
 TemplateTypeInstantiator::InstantiateRecordType(const RecordType *T,
                                                 unsigned Quals) const {
   RecordDecl *Record 
-    = cast_or_null<RecordDecl>(SemaRef.InstantiateDeclRef(T->getDecl(), 
-                                                          TemplateArgs));
+    = cast_or_null<RecordDecl>(SemaRef.InstantiateCurrentDeclRef(T->getDecl()));
   if (!Record)
     return QualType();
   
@@ -452,8 +451,7 @@
 TemplateTypeInstantiator::InstantiateEnumType(const EnumType *T,
                                               unsigned Quals) const {
   EnumDecl *Enum 
-    = cast_or_null<EnumDecl>(SemaRef.InstantiateDeclRef(T->getDecl(), 
-                                                        TemplateArgs));
+    = cast_or_null<EnumDecl>(SemaRef.InstantiateCurrentDeclRef(T->getDecl()));
   if (!Enum)
     return QualType();
   

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed May 27 12:54:46 2009
@@ -671,8 +671,8 @@
   return 0;
 }
 
-/// \brief Find the instantiation of the given declaration with the
-/// given template arguments.
+/// \brief Find the instantiation of the given declaration within the
+/// current instantiation.
 ///
 /// This routine is intended to be used when \p D is a declaration
 /// referenced from within a template, that needs to mapped into the
@@ -695,10 +695,9 @@
 /// In the instantiation of X<int>::getKind(), we need to map the
 /// EnumConstantDecl for KnownValue (which refers to
 /// X<T>::<Kind>::KnownValue) to its instantiation
-/// (X<int>::<Kind>::KnownValue). InstantiateDeclRef() performs this
-/// mapping, given the template arguments 'int'.
-NamedDecl *
-Sema::InstantiateDeclRef(NamedDecl *D, const TemplateArgumentList &TemplateArgs) {
+/// (X<int>::<Kind>::KnownValue). InstantiateCurrentDeclRef() performs
+/// this mapping from within the instantiation of X<int>.
+NamedDecl * Sema::InstantiateCurrentDeclRef(NamedDecl *D) {
   DeclContext *ParentDC = D->getDeclContext();
   if (isa<ParmVarDecl>(D) || ParentDC->isFunctionOrMethod()) {
     // D is a local of some kind. Look into the map of local
@@ -707,7 +706,7 @@
   }
 
   if (NamedDecl *ParentDecl = dyn_cast<NamedDecl>(ParentDC)) {
-    ParentDecl = InstantiateDeclRef(ParentDecl, TemplateArgs);
+    ParentDecl = InstantiateCurrentDeclRef(ParentDecl);
     if (!ParentDecl)
       return 0;
 
@@ -740,20 +739,27 @@
     D = Result;
   }
 
-  // D itself might be a class template that we need to instantiate
-  // with the given template arguments.
   if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D))
-    if (ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate()) {
-      QualType InjectedClassName 
-        = ClassTemplate->getInjectedClassNameType(Context);
-      QualType InstantiatedType = InstantiateType(InjectedClassName,
-                                                  TemplateArgs,
-                                                  Record->getLocation(), 
-                                                  Record->getDeclName());
-      if (InstantiatedType.isNull())
-        return 0;
-      if (const RecordType *RT = InstantiatedType->getAsRecordType())
-        D = RT->getDecl();
+    if (ClassTemplateDecl *ClassTemplate 
+          = Record->getDescribedClassTemplate()) {
+      // When the declaration D was parsed, it referred to the current
+      // instantiation. Therefore, look through the current context,
+      // which contains actual instantiations, to find the
+      // instantiation of the "current instantiation" that D refers
+      // to. Alternatively, we could just instantiate the
+      // injected-class-name with the current template arguments, but
+      // such an instantiation is far more expensive.
+      for (DeclContext *DC = CurContext; !DC->isFileContext(); 
+           DC = DC->getParent()) {
+        if (ClassTemplateSpecializationDecl *Spec 
+              = dyn_cast<ClassTemplateSpecializationDecl>(DC))
+          if (Context.getCanonicalDecl(Spec->getSpecializedTemplate())
+              == Context.getCanonicalDecl(ClassTemplate))
+            return Spec;
+      }
+
+      assert(false && 
+             "Unable to find declaration for the current instantiation");
     }
 
   return D;

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp Wed May 27 12:54:46 2009
@@ -108,7 +108,6 @@
 
 Sema::OwningExprResult
 TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
-  // FIXME: Recast this in terms of Sema::InstantiateDeclRef.
   NamedDecl *D = E->getDecl();
   if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
     assert(NTTP->getDepth() == 0 && "No nested templates yet");
@@ -141,7 +140,7 @@
   }
 
   ValueDecl *NewD 
-    = dyn_cast_or_null<ValueDecl>(SemaRef.InstantiateDeclRef(D, TemplateArgs));
+    = dyn_cast_or_null<ValueDecl>(SemaRef.InstantiateCurrentDeclRef(D));
   if (!NewD)
     return SemaRef.ExprError();
 

Modified: cfe/trunk/test/SemaTemplate/instantiate-declref.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-declref.cpp?rev=72486&r1=72485&r2=72486&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-declref.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-declref.cpp Wed May 27 12:54:46 2009
@@ -24,6 +24,9 @@
               K1 k1 = K1Val;
               Kind1 = K1Val;
               Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
+
+              InnerTemplate t;
+              InnerTemplate<type> t2;
             }
           };
         };





More information about the cfe-commits mailing list