[cfe-commits] r74540 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/CXX/basic/basic.def.odr/p2-typeid.cpp test/SemaTemplate/recursive-template-instantiation.cpp

Douglas Gregor dgregor at apple.com
Tue Jun 30 10:20:24 PDT 2009


Author: dgregor
Date: Tue Jun 30 12:20:14 2009
New Revision: 74540

URL: http://llvm.org/viewvc/llvm-project?rev=74540&view=rev
Log:
When recursively instantiating function templates, keep track of the
instantiation stack so that we provide a full instantiation
backtrace. Previously, we performed all of the instantiations implied
by the recursion, but each looked like a "top-level" instantiation.

The included test case tests the previous fix for the instantiation of
DeclRefExprs. Note that the "instantiated from" diagnostics still
don't tell us which template arguments we're instantiating with.

Added:
    cfe/trunk/test/SemaTemplate/recursive-template-instantiation.cpp   (with props)
Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/CXX/basic/basic.def.odr/p2-typeid.cpp

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Jun 30 12:20:14 2009
@@ -29,9 +29,9 @@
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/OwningPtr.h"
+#include <deque>
 #include <list>
 #include <string>
-#include <queue>
 #include <vector>
 
 namespace llvm {
@@ -2581,7 +2581,7 @@
   
   /// \brief The queue of implicit template instantiations that are required
   /// but have not yet been performed.
-  std::queue<PendingImplicitInstantiation> PendingImplicitInstantiations;
+  std::deque<PendingImplicitInstantiation> PendingImplicitInstantiations;
 
   void PerformPendingImplicitInstantiations();
   
@@ -2636,7 +2636,8 @@
                                const TemplateArgumentList &TemplateArgs);
 
   void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
-                                     FunctionDecl *Function);
+                                     FunctionDecl *Function,
+                                     bool Recursive = false);
   void InstantiateVariableDefinition(VarDecl *Var);
 
   NamedDecl *InstantiateCurrentDeclRef(NamedDecl *D);

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jun 30 12:20:14 2009
@@ -5641,7 +5641,7 @@
       // instantiated, naturally).
       if (Function->getInstantiatedFromMemberFunction() ||
           Function->getPrimaryTemplate())
-        PendingImplicitInstantiations.push(std::make_pair(Function, Loc));
+        PendingImplicitInstantiations.push_back(std::make_pair(Function, Loc));
     }
     
     

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Jun 30 12:20:14 2009
@@ -663,10 +663,19 @@
 /// \brief Instantiate the definition of the given function from its
 /// template.
 ///
+/// \param PointOfInstantiation the point at which the instantiation was
+/// required. Note that this is not precisely a "point of instantiation"
+/// for the function, but it's close.
+///
 /// \param Function the already-instantiated declaration of a
-/// function.
+/// function template specialization or member function of a class template
+/// specialization.
+///
+/// \param Recursive if true, recursively instantiates any functions that
+/// are required by this instantiation.
 void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
-                                         FunctionDecl *Function) {
+                                         FunctionDecl *Function,
+                                         bool Recursive) {
   if (Function->isInvalidDecl())
     return;
 
@@ -689,6 +698,13 @@
   if (Inst)
     return;
 
+  // If we're performing recursive template instantiation, create our own
+  // queue of pending implicit instantiations that we will instantiate later,
+  // while we're still within our own instantiation context.
+  std::deque<PendingImplicitInstantiation> SavedPendingImplicitInstantiations;
+  if (Recursive)
+    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+  
   ActOnStartOfFunctionDef(0, DeclPtrTy::make(Function));
 
   // Introduce a new scope where local variable instantiations will be
@@ -717,6 +733,15 @@
 
   DeclGroupRef DG(Function);
   Consumer.HandleTopLevelDecl(DG);
+  
+  if (Recursive) {
+    // Instantiate any pending implicit instantiations found during the
+    // instantiation of this template. 
+    PerformPendingImplicitInstantiations();
+    
+    // Restore the set of pending implicit instantiations.
+    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+  }
 }
 
 /// \brief Instantiate the definition of the given variable from its
@@ -859,11 +884,11 @@
 void Sema::PerformPendingImplicitInstantiations() {
   while (!PendingImplicitInstantiations.empty()) {
     PendingImplicitInstantiation Inst = PendingImplicitInstantiations.front();
-    PendingImplicitInstantiations.pop();
+    PendingImplicitInstantiations.pop_front();
     
     if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first))
       if (!Function->getBody())
-        InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function);
+        InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true);
     
     // FIXME: instantiate static member variables
   }

Modified: cfe/trunk/test/CXX/basic/basic.def.odr/p2-typeid.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.def.odr/p2-typeid.cpp?rev=74540&r1=74539&r2=74540&view=diff

==============================================================================
--- cfe/trunk/test/CXX/basic/basic.def.odr/p2-typeid.cpp (original)
+++ cfe/trunk/test/CXX/basic/basic.def.odr/p2-typeid.cpp Tue Jun 30 12:20:14 2009
@@ -32,5 +32,5 @@
   xnpr.g(NonPoly());
 
   // Triggers an error (as it should);
-  xpr.g(Poly());
+  xpr.g(Poly()); // expected-note{{instantiation of member function}}
 }

Added: cfe/trunk/test/SemaTemplate/recursive-template-instantiation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/recursive-template-instantiation.cpp?rev=74540&view=auto

==============================================================================
--- cfe/trunk/test/SemaTemplate/recursive-template-instantiation.cpp (added)
+++ cfe/trunk/test/SemaTemplate/recursive-template-instantiation.cpp Tue Jun 30 12:20:14 2009
@@ -0,0 +1,10 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+template<typename T> void f(T* t) {
+  f(*t); // expected-error{{no matching function}}\
+         // expected-note 3{{requested here}}
+}
+
+void test_f(int ****p) {
+  f(p); // expected-note{{requested here}}
+}

Propchange: cfe/trunk/test/SemaTemplate/recursive-template-instantiation.cpp

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/SemaTemplate/recursive-template-instantiation.cpp

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/SemaTemplate/recursive-template-instantiation.cpp

------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list