]> granicus.if.org Git - clang/commitdiff
[modules] Fix merging of default template arguments onto friend templates.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 16 Jun 2015 21:57:05 +0000 (21:57 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 16 Jun 2015 21:57:05 +0000 (21:57 +0000)
Previously we'd complain about redefinition of default arguments when we
instantiated a class with a friend template that inherits its default argument,
because we propagate the default template arguemnt onto the friend when we
reload the AST.

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

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/Modules/Inputs/submodules-merge-defs/defs.h
test/Modules/submodules-merge-defs.cpp

index d0a573981bda5982eabb836c21288c0395b24f1d..f35d1aaf77e9a77c3a8711d4dc7754f81fbeb904 100644 (file)
@@ -1922,7 +1922,7 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
                                  D->isParameterPack());
   Inst->setAccess(AS_public);
 
-  if (D->hasDefaultArgument()) {
+  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
     TypeSourceInfo *InstantiatedDefaultArg =
         SemaRef.SubstType(D->getDefaultArgumentInfo(), TemplateArgs,
                           D->getDefaultArgumentLoc(), D->getDeclName());
@@ -2078,7 +2078,7 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
   if (Invalid)
     Param->setInvalidDecl();
 
-  if (D->hasDefaultArgument()) {
+  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
     ExprResult Value = SemaRef.SubstExpr(D->getDefaultArgument(), TemplateArgs);
     if (!Value.isInvalid())
       Param->setDefaultArgument(Value.get());
@@ -2205,7 +2205,7 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
                                              D->getPosition(),
                                              D->isParameterPack(),
                                              D->getIdentifier(), InstParams);
-  if (D->hasDefaultArgument()) {
+  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
     NestedNameSpecifierLoc QualifierLoc =
         D->getDefaultArgument().getTemplateQualifierLoc();
     QualifierLoc =
index b98cbc3a7641eb7a51e2344d0aec36f8406b19db..02a4ae946cd486cf61e9601cddebe45305667de9 100644 (file)
@@ -61,3 +61,14 @@ namespace StaticInline {
   static inline void f(X);
   static inline void g(X x) { f(x); }
 }
+
+namespace FriendDefArg {
+  template<typename = int> struct A;
+  template<int = 0> struct B;
+  template<template<typename> class = A> struct C;
+  template<typename U> struct Y {
+    template<typename> friend struct A;
+    template<int> friend struct B;
+    template<template<typename> class> friend struct C;
+  };
+}
index cbe2dcdf562eb4fbf8d92ac1ac73e63558b30eb2..0dd8680b5ff336634ee0e3aa266486bb4ae61148 100644 (file)
@@ -74,3 +74,4 @@ int post_fg = F<char>().g<int>();
 J<> post_j;
 template<typename T, int N, template<typename> class K> struct J;
 J<> post_j2;
+FriendDefArg::Y<int> friend_def_arg;