[PATCH] D69779: -fmodules-codegen should not emit extern templates

Luboš Luňák via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Nov 3 13:42:53 PST 2019


llunak created this revision.
llunak added a reviewer: dblaikie.
llunak added a project: clang.
Herald added a subscriber: cfe-commits.

See the test for a testcase. If a header contains 'extern template', then the template should be provided somewhere by an explicit instantiation, so it is not necessary to generate a copy. Worse (at least with PCH -building-pch-with-obj), the current code actually leads to an unresolved symbol, because the PCH's object file will not actually contain functions from such a template (because of the GVA_AvailableExternally?), but the object file for the explicit instantiation will not contain them either because it will be blocked by the information provided by the PCH. I don't know if the same problem exists with modules (nor I know how to check for sure), all tests pass. If the problem is not there for modules, I can make the change PCH-specific.


Repository:
  rC Clang

https://reviews.llvm.org/D69779

Files:
  clang/lib/Serialization/ASTWriterDecl.cpp
  clang/test/PCH/codegen-extern-template.cpp
  clang/test/PCH/codegen-extern-template.h


Index: clang/test/PCH/codegen-extern-template.h
===================================================================
--- /dev/null
+++ clang/test/PCH/codegen-extern-template.h
@@ -0,0 +1,16 @@
+// header for codegen-extern-template.cpp
+#pragma once
+
+template< typename T >
+struct A
+{
+   T foo() { return 10;}
+};
+
+extern template struct A< int >;
+
+inline
+int bar(A<int>* p)
+{
+    return p->foo();
+}
Index: clang/test/PCH/codegen-extern-template.cpp
===================================================================
--- /dev/null
+++ clang/test/PCH/codegen-extern-template.cpp
@@ -0,0 +1,21 @@
+// Build the PCH with extern template.
+// RUN: %clang -x c++-header %S/codegen-extern-template.h -o %t.pch -Xclang -building-pch-with-obj -Xclang -fmodules-codegen
+// Build the PCH's object file.
+// RUN: %clang -c %s -include-pch %t.pch -Xclang -building-pch-with-obj -Xclang -fmodules-codegen -o %t.1.o
+// Build source with explicit template instantiation.
+// RUN: %clang -c %s -DMAIN -include-pch %t.pch -o %t.2.o
+// There should be no unresolved symbol.
+// RUN: %clang %t.1.o %t.2.o
+// expected-no-diagnostics
+
+#include "codegen-extern-template.h"
+
+#ifdef MAIN
+template struct A< int >;
+int main()
+{
+    A< int > a;
+    return bar(&a);
+}
+
+#endif
Index: clang/lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTWriterDecl.cpp
+++ clang/lib/Serialization/ASTWriterDecl.cpp
@@ -2412,11 +2412,12 @@
     }
     if (Writer->Context->getLangOpts().ModulesCodegen) {
       // Under -fmodules-codegen, codegen is performed for all non-internal,
-      // non-always_inline functions.
+      // non-always_inline functions, unless they are available elsewhere.
       if (!FD->hasAttr<AlwaysInlineAttr>()) {
         if (!Linkage)
           Linkage = Writer->Context->GetGVALinkageForFunction(FD);
-        ModulesCodegen = *Linkage != GVA_Internal;
+        ModulesCodegen =
+            *Linkage != GVA_Internal && *Linkage != GVA_AvailableExternally;
       }
     }
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D69779.227635.patch
Type: text/x-patch
Size: 2084 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191103/c4d0be31/attachment.bin>


More information about the cfe-commits mailing list