]> granicus.if.org Git - clang/commitdiff
Default function arguments for function template specializations
authorDouglas Gregor <dgregor@apple.com>
Fri, 5 Feb 2010 07:33:43 +0000 (07:33 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 5 Feb 2010 07:33:43 +0000 (07:33 +0000)
always come from the primary template, so gather the instantiation
template arguments from the primary template.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95380 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaExpr.cpp
lib/Sema/SemaTemplateInstantiate.cpp
test/SemaTemplate/default-expr-arguments.cpp

index 19de095b2aa9dbf0442b726e963835e0916f5c58..6a7590997cde501dde28558482971e5b6ffcf689 100644 (file)
@@ -2959,7 +2959,8 @@ public:
   //
 
   MultiLevelTemplateArgumentList getTemplateInstantiationArgs(NamedDecl *D,
-                                     const TemplateArgumentList *Innermost = 0);
+                                     const TemplateArgumentList *Innermost = 0,
+                                     bool RelativeToPrimary = false);
 
   /// \brief A template instantiation that is currently in progress.
   struct ActiveTemplateInstantiation {
index 99714aee36114befbdfe9f3b81281175db0fc979..4e448d81976ca053c362aca17ea04ade0751e34e 100644 (file)
@@ -3280,7 +3280,8 @@ Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
       Expr *UninstExpr = Param->getUninstantiatedDefaultArg();
 
       // Instantiate the expression.
-      MultiLevelTemplateArgumentList ArgList = getTemplateInstantiationArgs(FD);
+      MultiLevelTemplateArgumentList ArgList
+        = getTemplateInstantiationArgs(FD, 0, /*RelativeToPrimary=*/true);
 
       InstantiatingTemplate Inst(*this, CallLoc, Param,
                                  ArgList.getInnermost().getFlatArgumentList(),
index b560fad25eca4509949044bc1cc0c2b5fe52b360..5c5701ac792dc0001eda79321b71ec79d9c64d57 100644 (file)
@@ -33,9 +33,15 @@ using namespace clang;
 /// arguments.
 ///
 /// \param Innermost if non-NULL, the innermost template argument list.
+///
+/// \param RelativeToPrimary true if we should get the template
+/// arguments relative to the primary template, even when we're
+/// dealing with a specialization. This is only relevant for function
+/// template specializations.
 MultiLevelTemplateArgumentList
 Sema::getTemplateInstantiationArgs(NamedDecl *D, 
-                                   const TemplateArgumentList *Innermost) {
+                                   const TemplateArgumentList *Innermost,
+                                   bool RelativeToPrimary) {
   // Accumulate the set of template argument lists in this structure.
   MultiLevelTemplateArgumentList Result;
 
@@ -64,8 +70,9 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D,
     }
     // Add template arguments from a function template specialization.
     else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Ctx)) {
-      if (Function->getTemplateSpecializationKind() 
-            == TSK_ExplicitSpecialization)
+      if (!RelativeToPrimary &&
+          Function->getTemplateSpecializationKind() 
+                                                  == TSK_ExplicitSpecialization)
         break;
           
       if (const TemplateArgumentList *TemplateArgs
@@ -86,11 +93,13 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D,
       if (Function->getFriendObjectKind() &&
           Function->getDeclContext()->isFileContext()) {
         Ctx = Function->getLexicalDeclContext();
+        RelativeToPrimary = false;
         continue;
       }
     }
 
     Ctx = Ctx->getParent();
+    RelativeToPrimary = false;
   }
 
   return Result;
index 131b80cb1f36e2417cac7875c2cb2f5413ead88b..3da43fa675022e7ffac225448dee0eb93b38cf9a 100644 (file)
@@ -177,3 +177,10 @@ namespace PR5810 {
     X<float> x; // expected-note{{member function}}
   }
 }
+
+template<typename T> void f4(T, int = 17);
+template<> void f4<int>(int, int);
+
+void f4_test(int i) {
+  f4(i);
+}