Linker: Copy over function metadata attachments
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 24 Apr 2015 22:07:31 +0000 (22:07 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 24 Apr 2015 22:07:31 +0000 (22:07 +0000)
Update `lib/Linker` to handle `Function` metadata attachments.  The
attachments stick with the function body.

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

lib/Linker/LinkModules.cpp
test/Linker/Inputs/metadata-function.ll [new file with mode: 0644]
test/Linker/metadata-function.ll [new file with mode: 0644]

index 65a02a71c709614eca7825eabac0be58b9683f14..34a353a6c82f37cb4ca83c11e90f0c71a68d99f8 100644 (file)
@@ -1205,6 +1205,13 @@ bool ModuleLinker::linkFunctionBody(Function &Dst, Function &Src) {
     ++DI;
   }
 
+  // Copy over the metadata attachments.
+  SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
+  Src.getAllMetadata(MDs);
+  for (const auto &I : MDs)
+    Dst.setMetadata(I.first, MapMetadata(I.second, ValueMap, RF_None, &TypeMap,
+                                         &ValMaterializer));
+
   // Splice the body of the source function into the dest function.
   Dst.getBasicBlockList().splice(Dst.end(), Src.getBasicBlockList());
 
diff --git a/test/Linker/Inputs/metadata-function.ll b/test/Linker/Inputs/metadata-function.ll
new file mode 100644 (file)
index 0000000..8572ff1
--- /dev/null
@@ -0,0 +1,13 @@
+define weak void @foo() !weak !0 {
+  unreachable
+}
+
+define void @baz() !baz !0 {
+  unreachable
+}
+
+define void @b() !b !0 {
+  unreachable
+}
+
+!0 = !{!"b"}
diff --git a/test/Linker/metadata-function.ll b/test/Linker/metadata-function.ll
new file mode 100644 (file)
index 0000000..0b17e0c
--- /dev/null
@@ -0,0 +1,26 @@
+; RUN: llvm-link %s %S/Inputs/metadata-function.ll -S | FileCheck %s
+; RUN: llvm-link %S/Inputs/metadata-function.ll %s -S | FileCheck %s
+
+; CHECK-DAG: define weak void @foo() !weak ![[B:[0-9]+]] {
+define linkonce void @foo() !linkonce !0 {
+  unreachable
+}
+
+; CHECK-DAG: define void @bar() !bar ![[A:[0-9]+]] {
+define void @bar() !bar !0 {
+  call void @baz()
+  unreachable
+}
+
+; CHECK-DAG: define void @baz() !baz ![[B]] {
+declare void @baz()
+
+; CHECK-DAG: define void @a() !a ![[A]] {
+; CHECK-DAG: define void @b() !b ![[B]] {
+define void @a() !a !0 {
+  unreachable
+}
+
+; CHECK-DAG: ![[A]] = !{!"a"}
+; CHECK-DAG: ![[B]] = !{!"b"}
+!0 = !{!"a"}