4040#include " llvm/IR/DebugInfo.h"
4141#include " llvm/IR/DiagnosticInfo.h"
4242#include " llvm/IR/DiagnosticPrinter.h"
43+ #include " llvm/IR/Function.h"
4344#include " llvm/IR/GlobalValue.h"
4445#include " llvm/IR/LLVMContext.h"
4546#include " llvm/IR/LLVMRemarkStreamer.h"
4849#include " llvm/LTO/LTOBackend.h"
4950#include " llvm/Linker/Linker.h"
5051#include " llvm/Pass.h"
52+ #include " llvm/Support/Error.h"
5153#include " llvm/Support/MemoryBuffer.h"
5254#include " llvm/Support/Path.h"
5355#include " llvm/Support/Signals.h"
@@ -127,6 +129,27 @@ class CIRGenConsumer : public clang::ASTConsumer {
127129 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
128130 std::unique_ptr<CIRGenerator> Gen;
129131
132+ // / NOTE: LinkModule is taken from clang/include/clang/CodeGen/CodeGenAction.h
133+ // / This is clearly suboptimal and we should reuse their functionality.
134+ // / Info about module to link into a module we're generating.
135+ struct LinkModule {
136+ // / The module to link in.
137+ std::unique_ptr<llvm::Module> Module;
138+
139+ // / If true, we set attributes on Module's functions according to our
140+ // / CodeGenOptions and LangOptions, as though we were generating the
141+ // / function ourselves.
142+ bool PropagateAttrs;
143+
144+ // / If true, we use LLVM module internalizer.
145+ bool Internalize;
146+
147+ // / Bitwise combination of llvm::LinkerFlags used when we link the module.
148+ unsigned LinkFlags;
149+ };
150+ // / Bitcode modules to link in to our module.
151+ SmallVector<LinkModule, 4 > LinkModules;
152+
130153public:
131154 CIRGenConsumer (CIRGenAction::OutputType Action, class CompilerInstance &CI,
132155 class DiagnosticsEngine &Diags,
@@ -344,14 +367,27 @@ class CIRGenConsumer : public clang::ASTConsumer {
344367 case CIRGenAction::OutputType::EmitBC:
345368 case CIRGenAction::OutputType::EmitObj:
346369 case CIRGenAction::OutputType::EmitAssembly: {
370+ auto &CGOpts = CI.getCodeGenOpts ();
371+
347372 llvm::LLVMContext LlvmCtx;
373+ LlvmCtx.setDefaultTargetCPU (TargetOpts.CPU );
374+ LlvmCtx.setDefaultTargetFeatures (llvm::join (TargetOpts.Features , " ," ));
375+
348376 bool DisableDebugInfo =
349377 CodeGenOpts.getDebugInfo () == llvm::codegenoptions::NoDebugInfo;
378+
379+ LoadLinkModules (LlvmCtx);
380+
350381 auto LlvmModule = lowerFromCIRToLLVMIR (
351382 FeOptions, MlirMod, std::move (MlirCtx), LlvmCtx,
352383 FeOptions.ClangIRDisableCIRVerifier ,
353384 !FeOptions.ClangIRCallConvLowering , DisableDebugInfo);
354385
386+ LlvmModule->setTargetTriple (llvm::Triple (CI.getTargetOpts ().Triple ));
387+ LlvmModule->setDataLayout (C.getTargetInfo ().getDataLayoutString ());
388+
389+ LinkInModules (*LlvmModule);
390+
355391 BackendAction BackendAction = getBackendActionFromOutputType (Action);
356392
357393 emitBackendOutput (
@@ -364,6 +400,47 @@ class CIRGenConsumer : public clang::ASTConsumer {
364400 }
365401 }
366402
403+ void LoadLinkModules (llvm::LLVMContext &LlvmCtx) {
404+ for (const CodeGenOptions::BitcodeFileToLink &F :
405+ CI.getCodeGenOpts ().LinkBitcodeFiles ) {
406+ auto BCBuf = CI.getFileManager ().getBufferForFile (F.Filename );
407+ if (!BCBuf) {
408+ CI.getDiagnostics ().Report (diag::err_cannot_open_file)
409+ << F.Filename << BCBuf.getError ().message ();
410+ LinkModules.clear ();
411+ return ;
412+ }
413+
414+ Expected<std::unique_ptr<llvm::Module>> ModuleOrErr =
415+ getOwningLazyBitcodeModule (std::move (*BCBuf), LlvmCtx);
416+ if (!ModuleOrErr) {
417+ handleAllErrors (ModuleOrErr.takeError (), [&](llvm::ErrorInfoBase &EIB) {
418+ CI.getDiagnostics ().Report (diag::err_cannot_open_file)
419+ << F.Filename << EIB.message ();
420+ });
421+ LinkModules.clear ();
422+ return ;
423+ }
424+ LinkModules.push_back ({std::move (ModuleOrErr.get ()), F.PropagateAttrs ,
425+ F.Internalize , F.LinkFlags });
426+ }
427+ return ;
428+ }
429+
430+ // Links each entry in LinkModules into our module. Returns true on error.
431+ void LinkInModules (llvm::Module &M) {
432+ llvm::Linker L (M);
433+
434+ for (auto &LM : LinkModules) {
435+ // Link the module using LLVM's linker
436+ if (llvm::Linker::linkModules (M, std::move (LM.Module ), LM.LinkFlags )) {
437+ CI.getDiagnostics ().Report (diag::err_fe_linking_module)
438+ << M.getModuleIdentifier () << LM.Module ->getModuleIdentifier ();
439+ return ;
440+ }
441+ }
442+ }
443+
367444 void HandleTagDeclDefinition (TagDecl *D) override {
368445 PrettyStackTraceDecl CrashInfo (D, SourceLocation (),
369446 AstContext->getSourceManager (),
0 commit comments