示例#1
0
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);
    }
  }
}
示例#2
0
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);
    }
  }
}