aeubanks created this revision.
rsmith added inline comments.
aeubanks published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:2174
+      Args.addOuterTemplateArguments(SubstArgs);
+      Args.addOuterRetainedLevel();
+      NamedDecl *NewParam = transformTemplateParameter(Param, Args);
----------------
This outer retained level would correspond to the parameters you're building -- 
we shouldn't add this. Instead, we should have two different `SubstArgs` lists, 
one for the outer parameters and one for the inner parameters; we should add 
just the outer parameters here, and add the inner and outer parameters below. 
(And at the end of each iteration of this loop we should accumulate arguments 
onto the outer arguments list like we accumulate arguments onto the inner 
arguments list in the next loop.)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116983

Files:
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/Modules/Inputs/ctad/a.h
  clang/test/Modules/Inputs/ctad/b.h
  clang/test/Modules/Inputs/ctad/module.modulemap
  clang/test/Modules/ctad.cpp

Index: clang/test/Modules/ctad.cpp
===================================================================
--- /dev/null
+++ clang/test/Modules/ctad.cpp
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fmodules -fno-implicit-modules -x c++ -emit-module %S/Inputs/ctad/module.modulemap -fmodule-name=a -o %t/a.pcm -std=c++17
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fmodules -fno-implicit-modules -x c++ -emit-module %S/Inputs/ctad/module.modulemap -fmodule-name=b -o %t/b.pcm -std=c++17
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fmodules -fno-implicit-modules -x c++ -emit-llvm -I%S/Inputs/ctad -o - %s -fmodule-file=%t/a.pcm -fmodule-file=%t/b.pcm -std=c++17 | FileCheck %s
+
+// CHECK: @_a = global
+// CHECK: @_b = global
+// CHECK: call void @__cxx_global_var_init()
+// CHECK: call void @__cxx_global_var_init.1()
+
+#include "a.h"
+#include "b.h"
Index: clang/test/Modules/Inputs/ctad/module.modulemap
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/ctad/module.modulemap
@@ -0,0 +1,2 @@
+module a { header "a.h" export * }
+module b { header "b.h" export * }
Index: clang/test/Modules/Inputs/ctad/b.h
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/ctad/b.h
@@ -0,0 +1,8 @@
+#pragma once
+
+template<typename T=int> struct A {
+  template <typename U = float>
+  A(T, U) {}
+};
+
+A _b(5, 1.2);
Index: clang/test/Modules/Inputs/ctad/a.h
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/ctad/a.h
@@ -0,0 +1,9 @@
+#pragma once
+
+template <typename T = int>
+struct A {
+  template <typename U = float>
+  A(T, U) {}
+};
+
+A _a(2, 2);
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -2162,12 +2162,22 @@
     //       template followed by the template parameters (including default
     //       template arguments) of the constructor, if any.
     TemplateParameterList *TemplateParams = Template->getTemplateParameters();
-    if (FTD) {
-      TemplateParameterList *InnerParams = FTD->getTemplateParameters();
-      SmallVector<NamedDecl *, 16> AllParams;
-      AllParams.reserve(TemplateParams->size() + InnerParams->size());
-      AllParams.insert(AllParams.begin(),
-                       TemplateParams->begin(), TemplateParams->end());
+    TemplateParameterList *InnerParams =
+        FTD ? FTD->getTemplateParameters() : nullptr;
+    SmallVector<NamedDecl *, 16> AllParams;
+    AllParams.reserve(TemplateParams->size() +
+                      (InnerParams ? InnerParams->size() : 0));
+    for (NamedDecl *Param : *TemplateParams) {
+      MultiLevelTemplateArgumentList Args;
+      Args.setKind(TemplateSubstitutionKind::Rewrite);
+      Args.addOuterTemplateArguments(SubstArgs);
+      Args.addOuterRetainedLevel();
+      NamedDecl *NewParam = transformTemplateParameter(Param, Args);
+      if (!NewParam)
+        return nullptr;
+      AllParams.push_back(NewParam);
+    }
+    if (InnerParams) {
       SubstArgs.reserve(InnerParams->size());
 
       // Later template parameters could refer to earlier ones, so build up
@@ -2184,11 +2194,14 @@
         SubstArgs.push_back(SemaRef.Context.getCanonicalTemplateArgument(
             SemaRef.Context.getInjectedTemplateArg(NewParam)));
       }
-      TemplateParams = TemplateParameterList::Create(
-          SemaRef.Context, InnerParams->getTemplateLoc(),
-          InnerParams->getLAngleLoc(), AllParams, InnerParams->getRAngleLoc(),
-          /*FIXME: RequiresClause*/ nullptr);
     }
+    TemplateParameterList *InheritParameters =
+        InnerParams ? InnerParams : TemplateParams;
+    TemplateParams = TemplateParameterList::Create(
+        SemaRef.Context, InheritParameters->getTemplateLoc(),
+        InheritParameters->getLAngleLoc(), AllParams,
+        InheritParameters->getRAngleLoc(),
+        /*FIXME: RequiresClause*/ nullptr);
 
     // If we built a new template-parameter-list, track that we need to
     // substitute references to the old parameters into references to the
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D116983: ... Arthur Eubanks via Phabricator via cfe-commits

Reply via email to