void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) { llvm::LLVMContext &ctx = Module.getContext(); switch (linkLib.getKind()) { case LibraryKind::Library: { llvm::SmallString<32> opt = getTargetDependentLibraryOption(Triple, linkLib.getName()); AutolinkEntries.push_back( llvm::MDNode::get(ctx, llvm::MDString::get(ctx, opt))); break; } case LibraryKind::Framework: { // If we're supposed to disable autolinking of this framework, bail out. auto &frameworks = IRGen.Opts.DisableAutolinkFrameworks; if (std::find(frameworks.begin(), frameworks.end(), linkLib.getName()) != frameworks.end()) return; llvm::Metadata *args[] = { llvm::MDString::get(ctx, "-framework"), llvm::MDString::get(ctx, linkLib.getName()) }; AutolinkEntries.push_back(llvm::MDNode::get(ctx, args)); break; } } if (linkLib.shouldForceLoad()) { llvm::SmallString<64> buf; encodeForceLoadSymbolName(buf, linkLib.getName()); auto ForceImportThunk = Module.getOrInsertFunction(buf, llvm::FunctionType::get(VoidTy, false)); if (useDllStorage()) cast<llvm::GlobalValue>(ForceImportThunk) ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); buf += "_$"; appendEncodedName(buf, IRGen.Opts.ModuleName); if (!Module.getGlobalVariable(buf.str())) { auto ref = new llvm::GlobalVariable(Module, ForceImportThunk->getType(), /*isConstant=*/true, llvm::GlobalValue::WeakAnyLinkage, ForceImportThunk, buf.str()); ref->setVisibility(llvm::GlobalValue::HiddenVisibility); auto casted = llvm::ConstantExpr::getBitCast(ref, Int8PtrTy); LLVMUsed.push_back(casted); } } }
void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) { llvm::LLVMContext &ctx = Module.getContext(); switch (linkLib.getKind()) { case LibraryKind::Library: { // FIXME: Use target-independent linker option. // Clang uses CGM.getTargetCodeGenInfo().getDependentLibraryOption(...). llvm::SmallString<32> buf; buf += "-l"; buf += linkLib.getName(); auto flag = llvm::MDString::get(ctx, buf); AutolinkEntries.push_back(llvm::MDNode::get(ctx, flag)); break; } case LibraryKind::Framework: { // If we're supposed to disable autolinking of this framework, bail out. auto &frameworks = IRGen.Opts.DisableAutolinkFrameworks; if (std::find(frameworks.begin(), frameworks.end(), linkLib.getName()) != frameworks.end()) return; llvm::Metadata *args[] = { llvm::MDString::get(ctx, "-framework"), llvm::MDString::get(ctx, linkLib.getName()) }; AutolinkEntries.push_back(llvm::MDNode::get(ctx, args)); break; } } if (linkLib.shouldForceLoad()) { llvm::SmallString<64> buf; encodeForceLoadSymbolName(buf, linkLib.getName()); auto symbolAddr = Module.getOrInsertGlobal(buf.str(), Int1Ty); buf += "_$"; appendEncodedName(buf, IRGen.Opts.ModuleName); if (!Module.getGlobalVariable(buf.str())) { auto ref = new llvm::GlobalVariable(Module, symbolAddr->getType(), /*constant=*/true, llvm::GlobalValue::WeakAnyLinkage, symbolAddr, buf.str()); ref->setVisibility(llvm::GlobalValue::HiddenVisibility); auto casted = llvm::ConstantExpr::getBitCast(ref, Int8PtrTy); LLVMUsed.push_back(casted); } } }