LTOModule *LTOModule::createFromOpenFileSlice(int fd, const char *path, size_t map_size, off_t offset, TargetOptions options, std::string &errMsg) { ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getOpenFileSlice(fd, path, map_size, offset); if (std::error_code EC = BufferOrErr.getError()) { errMsg = EC.message(); return nullptr; } std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get()); return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg, &getGlobalContext()); }
static int checkAllExpressions(RuntimeDyldChecker &Checker) { for (const auto& CheckerFileName : CheckFiles) { ErrorOr<std::unique_ptr<MemoryBuffer>> CheckerFileBuf = MemoryBuffer::getFileOrSTDIN(CheckerFileName); if (std::error_code EC = CheckerFileBuf.getError()) return Error("unable to read input '" + CheckerFileName + "': " + EC.message()); if (!Checker.checkAllRulesInBuffer("# rtdyld-check:", CheckerFileBuf.get().get())) return Error("some checks in '" + CheckerFileName + "' failed"); } return 0; }
LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, TargetOptions options, std::string &errMsg) { // parse bitcode buffer ErrorOr<Module *> ModuleOrErr = getLazyBitcodeModule(buffer, getGlobalContext()); if (error_code EC = ModuleOrErr.getError()) { errMsg = EC.message(); delete buffer; return NULL; } OwningPtr<Module> m(ModuleOrErr.get()); std::string TripleStr = m->getTargetTriple(); if (TripleStr.empty()) TripleStr = sys::getDefaultTargetTriple(); llvm::Triple Triple(TripleStr); // find machine architecture for this module const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg); if (!march) return NULL; // construct LTOModule, hand over ownership of module and target SubtargetFeatures Features; Features.getDefaultSubtargetFeatures(Triple); std::string FeatureStr = Features.getString(); // Set a default CPU for Darwin triples. std::string CPU; if (Triple.isOSDarwin()) { if (Triple.getArch() == llvm::Triple::x86_64) CPU = "core2"; else if (Triple.getArch() == llvm::Triple::x86) CPU = "yonah"; } TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr, options); m->materializeAllPermanently(); LTOModule *Ret = new LTOModule(m.take(), target); if (Ret->parseSymbols(errMsg)) { delete Ret; return NULL; } Ret->parseMetadata(); return Ret; }
// Load problem header list. std::error_code ModularizeUtilities::loadProblemHeaderList( llvm::StringRef InputPath) { // By default, use the path component of the list file name. SmallString<256> HeaderDirectory(InputPath); llvm::sys::path::remove_filename(HeaderDirectory); SmallString<256> CurrentDirectory; llvm::sys::fs::current_path(CurrentDirectory); // Get the prefix if we have one. if (HeaderPrefix.size() != 0) HeaderDirectory = HeaderPrefix; // Read the header list file into a buffer. ErrorOr<std::unique_ptr<MemoryBuffer>> listBuffer = MemoryBuffer::getFile(InputPath); if (std::error_code EC = listBuffer.getError()) return EC; // Parse the header list into strings. SmallVector<StringRef, 32> Strings; listBuffer.get()->getBuffer().split(Strings, "\n", -1, false); // Collect the header file names from the string list. for (SmallVectorImpl<StringRef>::iterator I = Strings.begin(), E = Strings.end(); I != E; ++I) { StringRef Line = I->trim(); // Ignore comments and empty lines. if (Line.empty() || (Line[0] == '#')) continue; SmallString<256> HeaderFileName; // Prepend header file name prefix if it's not absolute. if (llvm::sys::path::is_absolute(Line)) llvm::sys::path::native(Line, HeaderFileName); else { if (HeaderDirectory.size() != 0) HeaderFileName = HeaderDirectory; else HeaderFileName = CurrentDirectory; llvm::sys::path::append(HeaderFileName, Line); llvm::sys::path::native(HeaderFileName); } // Get canonical form. HeaderFileName = getCanonicalPath(HeaderFileName); // Save the resulting header file path. ProblemFileNames.push_back(HeaderFileName.str()); } return std::error_code(); }
bool LTOModule::isBitcodeFile(StringRef Path) { ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFile(Path); if (!BufferOrErr) return false; Expected<MemoryBufferRef> BCData = IRObjectFile::findBitcodeInMemBuffer( BufferOrErr.get()->getMemBufferRef()); if (!BCData) { consumeError(BCData.takeError()); return false; } return true; }
ErrorOr<std::unique_ptr<LTOModule>> LTOModule::createFromOpenFileSlice(LLVMContext &Context, int fd, StringRef path, size_t map_size, off_t offset, const TargetOptions &options) { ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getOpenFileSlice(fd, path, map_size, offset); if (std::error_code EC = BufferOrErr.getError()) { Context.emitError(EC.message()); return EC; } std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get()); return makeLTOModule(Buffer->getMemBufferRef(), options, Context, /* ShouldBeLazy */ false); }
/// Bundle the files. Return true if an error was found. static bool BundleFiles() { std::error_code EC; // Create output file. raw_fd_ostream OutputFile(OutputFileNames.front(), EC, sys::fs::F_None); if (EC) { errs() << "error: Can't open file " << OutputFileNames.front() << ".\n"; return true; } // Open input files. std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers( InputFileNames.size()); unsigned Idx = 0; for (auto &I : InputFileNames) { ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr = MemoryBuffer::getFileOrSTDIN(I); if (std::error_code EC = CodeOrErr.getError()) { errs() << "error: Can't open file " << I << ": " << EC.message() << "\n"; return true; } InputBuffers[Idx++] = std::move(CodeOrErr.get()); } // Get the file handler. We use the host buffer as reference. assert(HostInputIndex != ~0u && "Host input index undefined??"); std::unique_ptr<FileHandler> FH; FH.reset(CreateFileHandler(*InputBuffers[HostInputIndex].get())); // Quit if we don't have a handler. if (!FH.get()) return true; // Write header. FH.get()->WriteHeader(OutputFile, InputBuffers); // Write all bundles along with the start/end markers. If an error was found // writing the end of the bundle component, abort the bundle writing. auto Input = InputBuffers.begin(); for (auto &Triple : TargetNames) { FH.get()->WriteBundleStart(OutputFile, Triple); FH.get()->WriteBundle(OutputFile, *Input->get()); if (FH.get()->WriteBundleEnd(OutputFile, Triple)) return true; ++Input; } return false; }
uint64_t MCJIT::getSymbolAddress(const std::string &Name, bool CheckFunctionsOnly) { MutexGuard locked(lock); // First, check to see if we already have this symbol. uint64_t Addr = getExistingSymbolAddress(Name); if (Addr) return Addr; for (object::OwningBinary<object::Archive> &OB : Archives) { object::Archive *A = OB.getBinary().get(); // Look for our symbols in each Archive object::Archive::child_iterator ChildIt = A->findSym(Name); if (ChildIt != A->child_end()) { // FIXME: Support nested archives? ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr = ChildIt->getAsBinary(); if (ChildBinOrErr.getError()) continue; std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get(); if (ChildBin->isObject()) { std::unique_ptr<object::ObjectFile> OF( static_cast<object::ObjectFile *>(ChildBin.release())); // This causes the object file to be loaded. addObjectFile(std::move(OF)); // The address should be here now. Addr = getExistingSymbolAddress(Name); if (Addr) return Addr; } } } // If it hasn't already been generated, see if it's in one of our modules. Module *M = findModuleForSymbol(Name, CheckFunctionsOnly); if (M) { generateCodeForModule(M); // Check the RuntimeDyld table again, it should be there now. return getExistingSymbolAddress(Name); } // If a LazyFunctionCreator is installed, use it to get/create the function. // FIXME: Should we instead have a LazySymbolCreator callback? if (LazyFunctionCreator) Addr = (uint64_t)LazyFunctionCreator(Name); return Addr; }
/// @brief Print the section sizes for @p file. If @p file is an archive, print /// the section sizes for each archive member. static void PrintFileSectionSizes(StringRef file) { // If file is not stdin, check that it exists. if (file != "-") { bool exists; if (sys::fs::exists(file, exists) || !exists) { errs() << ToolName << ": '" << file << "': " << "No such file\n"; return; } } // Attempt to open the binary. ErrorOr<Binary *> BinaryOrErr = createBinary(file); if (error_code EC = BinaryOrErr.getError()) { errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; return; } OwningPtr<Binary> binary(BinaryOrErr.get()); if (Archive *a = dyn_cast<Archive>(binary.get())) { // This is an archive. Iterate over each member and display its sizes. for (object::Archive::child_iterator i = a->child_begin(), e = a->child_end(); i != e; ++i) { OwningPtr<Binary> child; if (error_code ec = i->getAsBinary(child)) { errs() << ToolName << ": " << file << ": " << ec.message() << ".\n"; continue; } if (ObjectFile *o = dyn_cast<ObjectFile>(child.get())) { if (OutputFormat == sysv) outs() << o->getFileName() << " (ex " << a->getFileName() << "):\n"; PrintObjectSectionSizes(o); if (OutputFormat == berkeley) outs() << o->getFileName() << " (ex " << a->getFileName() << ")\n"; } } } else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get())) { if (OutputFormat == sysv) outs() << o->getFileName() << " :\n"; PrintObjectSectionSizes(o); if (OutputFormat == berkeley) outs() << o->getFileName() << "\n"; } else { errs() << ToolName << ": " << file << ": " << "Unrecognized file type.\n"; } // System V adds an extra newline at the end of each file. if (OutputFormat == sysv) outs() << "\n"; }
static error_code dumpInput(StringRef File) { if (File != "-" && !sys::fs::exists(File)) return obj2yaml_error::file_not_found; ErrorOr<Binary *> BinaryOrErr = createBinary(File); if (error_code EC = BinaryOrErr.getError()) return EC; std::unique_ptr<Binary> Binary(BinaryOrErr.get()); // TODO: If this is an archive, then burst it and dump each entry if (ObjectFile *Obj = dyn_cast<ObjectFile>(Binary.get())) return dumpObject(*Obj); return obj2yaml_error::unrecognized_file_format; }
Expected<OwningBinary<Binary>> object::createBinary(StringRef Path) { ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = MemoryBuffer::getFileOrSTDIN(Path); if (std::error_code EC = FileOrErr.getError()) return errorCodeToError(EC); std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get(); Expected<std::unique_ptr<Binary>> BinOrErr = createBinary(Buffer->getMemBufferRef()); if (!BinOrErr) return BinOrErr.takeError(); std::unique_ptr<Binary> &Bin = BinOrErr.get(); return OwningBinary<Binary>(std::move(Bin), std::move(Buffer)); }
std::error_code MachOUniversalBinary::ObjectForArch::getAsArchive( std::unique_ptr<Archive> &Result) const { if (Parent) { StringRef ParentData = Parent->getData(); StringRef ObjectData = ParentData.substr(Header.offset, Header.size); StringRef ObjectName = Parent->getFileName(); MemoryBufferRef ObjBuffer(ObjectData, ObjectName); ErrorOr<std::unique_ptr<Archive>> Obj = Archive::create(ObjBuffer); if (std::error_code EC = Obj.getError()) return EC; Result = std::move(Obj.get()); return object_error::success; } return object_error::parse_failed; }
std::error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S) { S.Type = Shdr->sh_type; S.Flags = Shdr->sh_flags; S.Address = Shdr->sh_addr; S.AddressAlign = Shdr->sh_addralign; ErrorOr<StringRef> NameOrErr = Obj.getSectionName(Shdr); if (std::error_code EC = NameOrErr.getError()) return EC; S.Name = NameOrErr.get(); if (Shdr->sh_link != ELF::SHN_UNDEF) { ErrorOr<const Elf_Shdr *> LinkSection = Obj.getSection(Shdr->sh_link); if (std::error_code EC = LinkSection.getError()) return EC; NameOrErr = Obj.getSectionName(*LinkSection); if (std::error_code EC = NameOrErr.getError()) return EC; S.Link = NameOrErr.get(); } return obj2yaml_error::success; }
ErrorOr<ELFYAML::RawContentSection *> ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) { auto S = make_unique<ELFYAML::RawContentSection>(); if (std::error_code EC = dumpCommonSection(Shdr, *S)) return EC; ErrorOr<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr); if (std::error_code EC = ContentOrErr.getError()) return EC; S->Content = yaml::BinaryRef(ContentOrErr.get()); S->Size = S->Content.binary_size(); return S.release(); }
/// \brief Get the weight for an instruction. /// /// The "weight" of an instruction \p Inst is the number of samples /// collected on that instruction at runtime. To retrieve it, we /// need to compute the line number of \p Inst relative to the start of its /// function. We use HeaderLineno to compute the offset. We then /// look up the samples collected for \p Inst using BodySamples. /// /// \param Inst Instruction to query. /// /// \returns the weight of \p Inst. ErrorOr<uint64_t> SampleProfileLoader::getInstWeight(const Instruction &Inst) const { DebugLoc DLoc = Inst.getDebugLoc(); if (!DLoc) return std::error_code(); const FunctionSamples *FS = findFunctionSamples(Inst); if (!FS) return std::error_code(); const DILocation *DIL = DLoc; unsigned Lineno = DLoc.getLine(); unsigned HeaderLineno = DIL->getScope()->getSubprogram()->getLine(); uint32_t LineOffset = getOffset(Lineno, HeaderLineno); uint32_t Discriminator = DIL->getDiscriminator(); ErrorOr<uint64_t> R = FS->findSamplesAt(LineOffset, Discriminator); if (R) { bool FirstMark = CoverageTracker.markSamplesUsed(FS, LineOffset, Discriminator, R.get()); if (FirstMark) { const Function *F = Inst.getParent()->getParent(); LLVMContext &Ctx = F->getContext(); emitOptimizationRemark( Ctx, DEBUG_TYPE, *F, DLoc, Twine("Applied ") + Twine(*R) + " samples from profile (offset: " + Twine(LineOffset) + ((Discriminator) ? Twine(".") + Twine(Discriminator) : "") + ")"); } DEBUG(dbgs() << " " << Lineno << "." << DIL->getDiscriminator() << ":" << Inst << " (line offset: " << Lineno - HeaderLineno << "." << DIL->getDiscriminator() << " - weight: " << R.get() << ")\n"); } return R; }
/// \brief Compute and store the weights of every basic block. /// /// This populates the BlockWeights map by computing /// the weights of every basic block in the CFG. /// /// \param F The function to query. bool SampleProfileLoader::computeBlockWeights(Function &F) { bool Changed = false; DEBUG(dbgs() << "Block weights\n"); for (const auto &BB : F) { ErrorOr<uint64_t> Weight = getBlockWeight(&BB); if (Weight) { BlockWeights[&BB] = Weight.get(); VisitedBlocks.insert(&BB); Changed = true; } DEBUG(printBlockWeight(dbgs(), &BB)); } return Changed; }
LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef, LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule) { MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); LLVMContext &Ctx = *unwrap(ContextRef); ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); if (ModuleOrErr.getError()) { *OutModule = wrap((Module *)nullptr); return 1; } *OutModule = wrap(ModuleOrErr.get().release()); return 0; }
static bool readLocationInfo(LocationInfoTy &LocationInfo) { ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getFileOrSTDIN(InputFileName); if (std::error_code EC = Buf.getError()) { errs() << "error: Can't open file " << InputFileName << ": " << EC.message() << "\n"; return false; } SourceMgr SM; yaml::Stream Stream(Buf.get()->getBuffer(), SM); collectLocationInfo(Stream, LocationInfo); return true; }
static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L, const cl::list<std::string> &Files, unsigned Flags) { // Filter out flags that don't apply to the first file we load. unsigned ApplicableFlags = Flags & Linker::Flags::OverrideFromSrc; for (const auto &File : Files) { std::unique_ptr<Module> M = loadFile(argv0, File, Context); if (!M.get()) { errs() << argv0 << ": error loading file '" << File << "'\n"; return false; } // Note that when ODR merging types cannot verify input files in here When // doing that debug metadata in the src module might already be pointing to // the destination. if (DisableDITypeMap && verifyModule(*M, &errs())) { errs() << argv0 << ": " << File << ": error: input module is broken!\n"; return false; } // If a module summary index is supplied, load it so linkInModule can treat // local functions/variables as exported and promote if necessary. if (!SummaryIndex.empty()) { ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr = llvm::getModuleSummaryIndexForFile(SummaryIndex, diagnosticHandler); std::error_code EC = IndexOrErr.getError(); if (EC) { errs() << EC.message() << '\n'; return false; } auto Index = std::move(IndexOrErr.get()); // Promotion if (renameModuleForThinLTO(*M, *Index)) return true; } if (Verbose) errs() << "Linking in '" << File << "'\n"; if (L.linkInModule(std::move(M), ApplicableFlags)) return false; // All linker flags apply to linking of subsequent files. ApplicableFlags = Flags; } return true; }
static void dumpInput(StringRef File) { // Attempt to open the binary. ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(File); if (std::error_code EC = BinaryOrErr.getError()) { reportError(File, EC); return; } Binary &Binary = *BinaryOrErr.get().getBinary(); if (Archive *Arc = dyn_cast<Archive>(&Binary)) dumpArchive(Arc); else if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary)) dumpCXXData(Obj); else reportError(File, cxxdump_error::unrecognized_file_format); }
// Implement the 't' operation. This function prints out just // the file names of each of the members. However, if verbose mode is requested // ('v' modifier) then the file type, permission mode, user, group, size, and // modification time are also printed. static void doDisplayTable(StringRef Name, const object::Archive::Child &C) { if (Verbose) { sys::fs::perms Mode = C.getAccessMode(); printMode((Mode >> 6) & 007); printMode((Mode >> 3) & 007); printMode(Mode & 007); outs() << ' ' << C.getUID(); outs() << '/' << C.getGID(); ErrorOr<uint64_t> Size = C.getSize(); failIfError(Size.getError()); outs() << ' ' << format("%6llu", Size.get()); outs() << ' ' << C.getLastModified().str(); outs() << ' '; } outs() << Name << "\n"; }
Expected<OwningBinary<ObjectFile>> ObjectFile::createObjectFile(StringRef ObjectPath) { ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = MemoryBuffer::getFile(ObjectPath); if (std::error_code EC = FileOrErr.getError()) return errorCodeToError(EC); std::unique_ptr<MemoryBuffer> Buffer = std::move(FileOrErr.get()); Expected<std::unique_ptr<ObjectFile>> ObjOrErr = createObjectFile(Buffer->getMemBufferRef()); if (Error Err = ObjOrErr.takeError()) return std::move(Err); std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get()); return OwningBinary<ObjectFile>(std::move(Obj), std::move(Buffer)); }
Expected<std::unique_ptr<IRObjectFile>> llvm::object::IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) { ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); if (!BCOrErr) return errorCodeToError(BCOrErr.getError()); Expected<std::unique_ptr<Module>> MOrErr = getLazyBitcodeModule(*BCOrErr, Context, /*ShouldLazyLoadMetadata*/ true); if (!MOrErr) return MOrErr.takeError(); std::unique_ptr<Module> &M = MOrErr.get(); return llvm::make_unique<IRObjectFile>(BCOrErr.get(), std::move(M)); }
Archive::child_iterator Archive::findSym(StringRef name) const { Archive::symbol_iterator bs = symbol_begin(); Archive::symbol_iterator es = symbol_end(); for (; bs != es; ++bs) { StringRef SymName = bs->getName(); if (SymName == name) { ErrorOr<Archive::child_iterator> ResultOrErr = bs->getMember(); // FIXME: Should we really eat the error? if (ResultOrErr.getError()) return child_end(); return ResultOrErr.get(); } } return child_end(); }
IRObjectFile::IRObjectFile(MemoryBuffer *Object, error_code &EC, LLVMContext &Context, bool BufferOwned) : SymbolicFile(Binary::ID_IR, Object, BufferOwned) { ErrorOr<Module*> MOrErr = parseBitcodeFile(Object, Context); if ((EC = MOrErr.getError())) return; M.reset(MOrErr.get()); // If we have a DataLayout, setup a mangler. const DataLayout *DL = M->getDataLayout(); if (!DL) return; Mang.reset(new Mangler(DL)); }
LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule, char **OutMessage) { ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(unwrap(MemBuf)->getMemBufferRef(), *unwrap(ContextRef)); if (std::error_code EC = ModuleOrErr.getError()) { if (OutMessage) *OutMessage = strdup(EC.message().c_str()); *OutModule = wrap((Module*)nullptr); return 1; } *OutModule = wrap(ModuleOrErr.get()); return 0; }
static std::unique_ptr<LTOModule> getLocalLTOModule(StringRef Path, std::unique_ptr<MemoryBuffer> &Buffer, const TargetOptions &Options) { ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFile(Path); error(BufferOrErr, "error loading file '" + Path + "'"); Buffer = std::move(BufferOrErr.get()); CurrentActivity = ("loading file '" + Path + "'").str(); std::unique_ptr<LLVMContext> Context = llvm::make_unique<LLVMContext>(); Context->setDiagnosticHandler(diagnosticHandlerWithContext, nullptr, true); ErrorOr<std::unique_ptr<LTOModule>> Ret = LTOModule::createInLocalContext( std::move(Context), Buffer->getBufferStart(), Buffer->getBufferSize(), Options, Path); CurrentActivity = ""; return std::move(*Ret); }
/// @brief Dumps each object file in \a Arc; static void dumpArchive(const Archive *Arc) { for (const auto &Child : Arc->children()) { ErrorOr<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary(); if (std::error_code EC = ChildOrErr.getError()) { // Ignore non-object files. if (EC != object_error::invalid_file_type) reportError(Arc->getFileName(), EC.message()); continue; } if (ObjectFile *Obj = dyn_cast<ObjectFile>(&*ChildOrErr.get())) dumpObject(Obj); else reportError(Arc->getFileName(), readobj_error::unrecognized_file_format); } }
// Parse module summary index in the given memory buffer. // Return new ModuleSummaryIndexObjectFile instance containing parsed // module summary/index. Expected<std::unique_ptr<ModuleSummaryIndexObjectFile>> ModuleSummaryIndexObjectFile::create(MemoryBufferRef Object) { ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); if (!BCOrErr) return errorCodeToError(BCOrErr.getError()); Expected<std::unique_ptr<ModuleSummaryIndex>> IOrErr = getModuleSummaryIndex(BCOrErr.get()); if (!IOrErr) return IOrErr.takeError(); std::unique_ptr<ModuleSummaryIndex> Index = std::move(IOrErr.get()); return llvm::make_unique<ModuleSummaryIndexObjectFile>(Object, std::move(Index)); }
static ErrorOr<StringRef> findFile(ELFLinkingContext &ctx, StringRef path, bool dashL) { // If the path was referred to by using a -l argument, let's search // for the file in the search path. if (dashL) { ErrorOr<StringRef> pathOrErr = ctx.searchLibrary(path); if (std::error_code ec = pathOrErr.getError()) return make_dynamic_error_code( Twine("Unable to find library -l") + path + ": " + ec.message()); path = pathOrErr.get(); } if (!llvm::sys::fs::exists(path)) return make_dynamic_error_code( Twine("lld: cannot find file ") + path); return path; }