1//===--- ModuleLinker.cpp - Shared bitcode link helpers -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "clang/CodeGen/ModuleLinker.h"
10
11#include "clang/Basic/CodeGenOptions.h"
12#include "clang/CodeGenUtils/BackendDiagnosticHandler.h"
13#include "clang/Frontend/CompilerInstance.h"
14#include "llvm/ADT/StringSet.h"
15#include "llvm/Bitcode/BitcodeReader.h"
16#include "llvm/IR/Module.h"
17#include "llvm/Linker/Linker.h"
18#include "llvm/Transforms/IPO/Internalize.h"
19
20using namespace clang;
21
22bool clang::loadLinkModules(CompilerInstance &CI, llvm::LLVMContext &Ctx,
23 llvm::SmallVectorImpl<LinkModule> &LinkModules) {
24 if (!LinkModules.empty())
25 return false;
26
27 for (const CodeGenOptions::BitcodeFileToLink &F :
28 CI.getCodeGenOpts().LinkBitcodeFiles) {
29 auto BCBuf = CI.getFileManager().getBufferForFile(Filename: F.Filename);
30 if (!BCBuf) {
31 CI.getDiagnostics().Report(DiagID: diag::err_cannot_open_file)
32 << F.Filename << BCBuf.getError().message();
33 LinkModules.clear();
34 return true;
35 }
36
37 llvm::Expected<std::unique_ptr<llvm::Module>> ModuleOrErr =
38 llvm::getOwningLazyBitcodeModule(Buffer: std::move(*BCBuf), Context&: Ctx);
39 if (!ModuleOrErr) {
40 llvm::handleAllErrors(
41 E: ModuleOrErr.takeError(), Handlers: [&](llvm::ErrorInfoBase &EIB) {
42 CI.getDiagnostics().Report(DiagID: diag::err_cannot_open_file)
43 << F.Filename << EIB.message();
44 });
45 LinkModules.clear();
46 return true;
47 }
48
49 LinkModules.push_back(Elt: {.Module: std::move(ModuleOrErr.get()), .PropagateAttrs: F.PropagateAttrs,
50 .Internalize: F.Internalize, .LinkFlags: F.LinkFlags});
51 }
52 return false;
53}
54
55bool clang::linkInModules(llvm::Module &M,
56 llvm::SmallVectorImpl<LinkModule> &LinkModules,
57 const CodeGenOptions &CodeGenOpts,
58 const LangOptions &LangOpts,
59 const TargetOptions &TargetOpts,
60 BackendDiagnosticConsumer &DiagConsumer) {
61 for (LinkModule &LM : LinkModules) {
62 assert(LM.Module && "LinkModule does not actually have a module");
63
64 if (LM.PropagateAttrs)
65 for (llvm::Function &F : *LM.Module) {
66 // Skip intrinsics. Keep consistent with how intrinsics are created
67 // in LLVM IR.
68 if (F.isIntrinsic())
69 continue;
70 CodeGen::mergeDefaultFunctionDefinitionAttributes(
71 F, CodeGenOpts, LangOpts, TargetOpts, WillInternalize: LM.Internalize);
72 }
73
74 DiagConsumer.setCurLinkModule(LM.Module.get());
75 bool Err;
76
77 if (LM.Internalize) {
78 Err = llvm::Linker::linkModules(
79 Dest&: M, Src: std::move(LM.Module), Flags: LM.LinkFlags,
80 InternalizeCallback: [](llvm::Module &M, const llvm::StringSet<> &GVS) {
81 llvm::internalizeModule(TheModule&: M, MustPreserveGV: [&GVS](const llvm::GlobalValue &GV) {
82 return !GV.hasName() || (GVS.count(Key: GV.getName()) == 0);
83 });
84 });
85 } else
86 Err = llvm::Linker::linkModules(Dest&: M, Src: std::move(LM.Module), Flags: LM.LinkFlags);
87
88 if (Err)
89 return true;
90 }
91
92 LinkModules.clear();
93 return false; // success
94}
95