[cfe-commits] r133055 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiate.cpp test/SemaTemplate/default-arguments.cpp

Douglas Gregor dgregor at apple.com
Wed Jun 15 07:20:43 PDT 2011


Author: dgregor
Date: Wed Jun 15 09:20:42 2011
New Revision: 133055

URL: http://llvm.org/viewvc/llvm-project?rev=133055&view=rev
Log:
When performing substitution of default template template parameters
before the template parameters have acquired a proper context (e.g.,
because the enclosing context has yet to be built), provide empty
parameter lists for all outer template parameter scopes to inhibit any
substitution for those template parameters. Fixes PR9643 /
<rdar://problem/9251019>.

Modified:
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/test/SemaTemplate/default-arguments.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=133055&r1=133054&r2=133055&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Jun 15 09:20:42 2011
@@ -2912,16 +2912,6 @@
     // arguments, just break out now and we'll fill in the argument pack below.
     if ((*Param)->isTemplateParameterPack())
       break;
-
-    // If our template is a template template parameter that hasn't acquired
-    // its proper context yet (e.g., because we're using the template template
-    // parameter in the signature of a function template, before we've built
-    // the function template itself), don't attempt substitution of default
-    // template arguments at this point: we don't have enough context to
-    // do it properly.
-    if (isTemplateTemplateParameter && 
-        Template->getDeclContext()->isTranslationUnit())
-      break;
     
     // We have a default template argument that we will use.
     TemplateArgumentLoc Arg;

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=133055&r1=133054&r2=133055&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Wed Jun 15 09:20:42 2011
@@ -62,8 +62,20 @@
   if (!Ctx) {
     Ctx = D->getDeclContext();
     
-    assert((!D->isTemplateParameter() || !Ctx->isTranslationUnit()) &&
-           "Template parameter doesn't have its context yet!");
+    // If we have a template template parameter with translation unit context,
+    // then we're performing substitution into a default template argument of
+    // this template template parameter before we've constructed the template
+    // that will own this template template parameter. In this case, we
+    // use empty template parameter lists for all of the outer templates
+    // to avoid performing any substitutions.
+    if (Ctx->isTranslationUnit()) {
+      if (TemplateTemplateParmDecl *TTP 
+                                      = dyn_cast<TemplateTemplateParmDecl>(D)) {
+        for (unsigned I = 0, N = TTP->getDepth() + 1; I != N; ++I)
+          Result.addOuterTemplateArguments(0, 0);
+        return Result;
+      }
+    }
   }
   
   while (!Ctx->isFileContext()) {

Modified: cfe/trunk/test/SemaTemplate/default-arguments.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/default-arguments.cpp?rev=133055&r1=133054&r2=133055&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/default-arguments.cpp (original)
+++ cfe/trunk/test/SemaTemplate/default-arguments.cpp Wed Jun 15 09:20:42 2011
@@ -121,3 +121,18 @@
 
 
 template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}}
+
+namespace PR9643 {
+  template<typename T> class allocator {};
+  template<typename T, typename U = allocator<T> > class vector {};
+
+  template<template<typename U, typename = allocator<U> > class container,
+           typename DT>
+  container<DT> initializer(const DT& d) {
+    return container<DT>();
+  }
+
+  void f() {
+    vector<int, allocator<int> > v = initializer<vector>(5);
+  }
+}





More information about the cfe-commits mailing list