Index: COFF/Driver.cpp =================================================================== --- COFF/Driver.cpp +++ COFF/Driver.cpp @@ -131,7 +131,7 @@ case file_magic::archive: if (WholeArchive) { std::unique_ptr File = - check(Archive::create(MBRef), + CHECK(Archive::create(MBRef), MBRef.getBufferIdentifier() + ": failed to parse archive"); for (MemoryBufferRef M : getArchiveMembers(File.get())) @@ -196,7 +196,7 @@ StringRef SymName, StringRef ParentName) { if (!C.getParent()->isThin()) { - MemoryBufferRef MB = check( + MemoryBufferRef MB = CHECK( C.getMemoryBufferRef(), "could not get the buffer for the member defining symbol " + SymName); enqueueTask([=]() { Driver->addArchiveBuffer(MB, SymName, ParentName); }); @@ -204,7 +204,7 @@ } auto Future = std::make_shared>(createFutureForFile( - check(C.getFullName(), + CHECK(C.getFullName(), "could not get the filename for the member defining symbol " + SymName))); enqueueTask([=]() { @@ -531,8 +531,8 @@ } static void parseModuleDefs(StringRef Path) { - std::unique_ptr MB = check( - MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); + std::unique_ptr MB = CHECK( + MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); COFFModuleDefinition M = check(parseCOFFModuleDefinition( MB->getMemBufferRef(), Config->Machine, Config->MinGW)); @@ -577,7 +577,7 @@ // The MSVC linker doesn't support thin archives, so if it's a thin // archive, we always need to rebuild it. std::unique_ptr File = - check(Archive::create(MB), "Failed to read " + MB.getBufferIdentifier()); + CHECK(Archive::create(MB), "Failed to read " + MB.getBufferIdentifier()); if (File->isThin()) return true; @@ -598,7 +598,7 @@ // its path is returned. static Optional filterBitcodeFiles(StringRef Path, std::vector &TemporaryFiles) { - std::unique_ptr MB = check( + std::unique_ptr MB = CHECK( MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); MemoryBufferRef MBRef = MB->getMemBufferRef(); file_magic Magic = identify_magic(MBRef.getBuffer()); @@ -611,7 +611,7 @@ return Path.str(); std::unique_ptr File = - check(Archive::create(MBRef), + CHECK(Archive::create(MBRef), MBRef.getBufferIdentifier() + ": failed to parse archive"); std::vector New; @@ -957,7 +957,7 @@ // Handle /lldsavecachepolicy if (auto *Arg = Args.getLastArg(OPT_lldltocachepolicy)) - Config->LTOCachePolicy = check( + Config->LTOCachePolicy = CHECK( parseCachePruningPolicy(Arg->getValue()), Twine("/lldltocachepolicy: invalid cache policy: ") + Arg->getValue()); Index: COFF/DriverUtils.cpp =================================================================== --- COFF/DriverUtils.cpp +++ COFF/DriverUtils.cpp @@ -317,7 +317,7 @@ // is called (you cannot remove an opened file on Windows.) std::unique_ptr getMemoryBuffer() { // IsVolatileSize=true forces MemoryBuffer to not use mmap(). - return check(MemoryBuffer::getFile(Path, /*FileSize=*/-1, + return CHECK(MemoryBuffer::getFile(Path, /*FileSize=*/-1, /*RequiresNullTerminator=*/false, /*IsVolatileSize=*/true), "could not open " + Path); @@ -402,7 +402,7 @@ E.add("/out:" + StringRef(User.Path)); E.run(); - return check(MemoryBuffer::getFile(User.Path), "could not open " + User.Path) + return CHECK(MemoryBuffer::getFile(User.Path), "could not open " + User.Path) .get() ->getBuffer(); } Index: COFF/InputFiles.cpp =================================================================== --- COFF/InputFiles.cpp +++ COFF/InputFiles.cpp @@ -63,7 +63,7 @@ void ArchiveFile::parse() { // Parse a MemoryBufferRef as an archive file. - File = check(Archive::create(MB), toString(this)); + File = CHECK(Archive::create(MB), toString(this)); // Read the symbol table to construct Lazy objects. for (const Archive::Symbol &Sym : File->symbols()) @@ -73,7 +73,7 @@ // Returns a buffer pointing to a member file containing a given symbol. void ArchiveFile::addMember(const Archive::Symbol *Sym) { const Archive::Child &C = - check(Sym->getMember(), + CHECK(Sym->getMember(), "could not get the member for symbol " + Sym->getName()); // Return an empty buffer if we have already returned the same buffer. @@ -88,10 +88,10 @@ Error Err = Error::success(); for (const ErrorOr &COrErr : File->children(Err)) { Archive::Child C = - check(COrErr, + CHECK(COrErr, File->getFileName() + ": could not get the child of the archive"); MemoryBufferRef MBRef = - check(C.getMemoryBufferRef(), + CHECK(C.getMemoryBufferRef(), File->getFileName() + ": could not get the buffer for a child of the archive"); V.push_back(MBRef); @@ -104,7 +104,7 @@ void ObjFile::parse() { // Parse a memory buffer as a COFF file. - std::unique_ptr Bin = check(createBinary(MB), toString(this)); + std::unique_ptr Bin = CHECK(createBinary(MB), toString(this)); if (auto *Obj = dyn_cast(Bin.get())) { Bin.release(); Index: COFF/Writer.cpp =================================================================== --- COFF/Writer.cpp +++ COFF/Writer.cpp @@ -784,7 +784,7 @@ } void Writer::openFile(StringRef Path) { - Buffer = check( + Buffer = CHECK( FileOutputBuffer::create(Path, FileSize, FileOutputBuffer::F_executable), "failed to open " + Path); } Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -136,7 +136,7 @@ std::vector> static getArchiveMembers( MemoryBufferRef MB) { std::unique_ptr File = - check(Archive::create(MB), + CHECK(Archive::create(MB), MB.getBufferIdentifier() + ": failed to parse archive"); std::vector> V; @@ -144,10 +144,10 @@ bool AddToTar = File->isThin() && Tar; for (const ErrorOr &COrErr : File->children(Err)) { Archive::Child C = - check(COrErr, MB.getBufferIdentifier() + + CHECK(COrErr, MB.getBufferIdentifier() + ": could not get the child of the archive"); MemoryBufferRef MBRef = - check(C.getMemoryBufferRef(), + CHECK(C.getMemoryBufferRef(), MB.getBufferIdentifier() + ": could not get the buffer for a child of the archive"); if (AddToTar) @@ -192,7 +192,7 @@ } std::unique_ptr File = - check(Archive::create(MBRef), Path + ": failed to parse archive"); + CHECK(Archive::create(MBRef), Path + ": failed to parse archive"); // If an archive file has no symbol table, it is likely that a user // is attempting LTO and using a default ar command that doesn't @@ -651,7 +651,7 @@ Config->Target1Rel = Args.hasFlag(OPT_target1_rel, OPT_target1_abs, false); Config->Target2 = getTarget2(Args); Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir); - Config->ThinLTOCachePolicy = check( + Config->ThinLTOCachePolicy = CHECK( parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)), "--thinlto-cache-policy: invalid cache policy"); Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u); Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -209,19 +209,19 @@ template uint32_t ELFFileBase::getSectionIndex(const Elf_Sym &Sym) const { - return checkLazy(getObj().getSectionIndex(&Sym, ELFSyms, SymtabSHNDX), - [=]() { return toString(this); }); + return CHECK(getObj().getSectionIndex(&Sym, ELFSyms, SymtabSHNDX), + toString(this)); } template void ELFFileBase::initSymtab(ArrayRef Sections, const Elf_Shdr *Symtab) { FirstNonLocal = Symtab->sh_info; - ELFSyms = check(getObj().symbols(Symtab), toString(this)); + ELFSyms = CHECK(getObj().symbols(Symtab), toString(this)); if (FirstNonLocal == 0 || FirstNonLocal > ELFSyms.size()) fatal(toString(this) + ": invalid sh_info in symbol table"); - StringTable = check(getObj().getStringTableForSymtab(*Symtab, Sections), + StringTable = CHECK(getObj().getStringTableForSymtab(*Symtab, Sections), toString(this)); } @@ -253,15 +253,13 @@ // Group signatures are stored as symbol names in object files. // sh_info contains a symbol index, so we fetch a symbol and read its name. if (this->ELFSyms.empty()) - this->initSymtab(Sections, - checkLazy(object::getSection(Sections, Sec.sh_link), - [=]() { return toString(this); })); - - const Elf_Sym *Sym = - checkLazy(object::getSymbol(this->ELFSyms, Sec.sh_info), - [=]() { return toString(this); }); - StringRef Signature = checkLazy(Sym->getName(this->StringTable), - [=]() { return toString(this); }); + this->initSymtab( + Sections, + CHECK(object::getSection(Sections, Sec.sh_link), toString(this))); + + const Elf_Sym *Sym = CHECK( + object::getSymbol(this->ELFSyms, Sec.sh_info), toString(this)); + StringRef Signature = CHECK(Sym->getName(this->StringTable), toString(this)); // As a special case, if a symbol is a section symbol and has no name, // we use a section name as a signature. @@ -279,9 +277,8 @@ ArrayRef::Elf_Word> ObjFile::getShtGroupEntries(const Elf_Shdr &Sec) { const ELFFile &Obj = this->getObj(); - ArrayRef Entries = - checkLazy(Obj.template getSectionContentsAsArray(&Sec), - [=]() { return toString(this); }); + ArrayRef Entries = CHECK( + Obj.template getSectionContentsAsArray(&Sec), toString(this)); if (Entries.empty() || Entries[0] != GRP_COMDAT) fatal(toString(this) + ": unsupported SHT_GROUP format"); return Entries.slice(1); @@ -327,11 +324,11 @@ const ELFFile &Obj = this->getObj(); ArrayRef ObjSections = - check(this->getObj().sections(), toString(this)); + CHECK(this->getObj().sections(), toString(this)); uint64_t Size = ObjSections.size(); this->Sections.resize(Size); this->SectionStringTable = - check(Obj.getSectionStringTable(ObjSections), toString(this)); + CHECK(Obj.getSectionStringTable(ObjSections), toString(this)); for (size_t I = 0, E = ObjSections.size(); I < E; I++) { if (this->Sections[I] == &InputSection::Discarded) @@ -378,7 +375,7 @@ break; case SHT_SYMTAB_SHNDX: this->SymtabSHNDX = - check(Obj.getSHNDXTable(Sec, ObjSections), toString(this)); + CHECK(Obj.getSHNDXTable(Sec, ObjSections), toString(this)); break; case SHT_STRTAB: case SHT_NULL: @@ -523,14 +520,13 @@ size_t NumRelocations; if (Sec.sh_type == SHT_RELA) { - ArrayRef Rels = checkLazy(this->getObj().relas(&Sec), - [=]() { return toString(this); }); + ArrayRef Rels = + CHECK(this->getObj().relas(&Sec), toString(this)); Target->FirstRelocation = Rels.begin(); NumRelocations = Rels.size(); Target->AreRelocsRela = true; } else { - ArrayRef Rels = checkLazy(this->getObj().rels(&Sec), - [=]() { return toString(this); }); + ArrayRef Rels = CHECK(this->getObj().rels(&Sec), toString(this)); Target->FirstRelocation = Rels.begin(); NumRelocations = Rels.size(); Target->AreRelocsRela = false; @@ -599,8 +595,8 @@ template StringRef ObjFile::getSectionName(const Elf_Shdr &Sec) { - return checkLazy(this->getObj().getSectionName(&Sec, SectionStringTable), - [=]() { return toString(this); }); + return CHECK(this->getObj().getSectionName(&Sec, SectionStringTable), + toString(this)); } template void ObjFile::initializeSymbols() { @@ -632,7 +628,7 @@ if (Binding == STB_LOCAL) { if (Sym->getType() == STT_FILE) - SourceFile = check(Sym->getName(this->StringTable), toString(this)); + SourceFile = CHECK(Sym->getName(this->StringTable), toString(this)); if (this->StringTable.size() <= Sym->st_name) fatal(toString(this) + ": invalid symbol name offset"); @@ -644,8 +640,7 @@ return make(this, Name, Binding, StOther, Type, Value, Size, Sec); } - StringRef Name = checkLazy(Sym->getName(this->StringTable), - [=]() { return toString(this); }); + StringRef Name = CHECK(Sym->getName(this->StringTable), toString(this)); switch (Sym->st_shndx) { case SHN_UNDEF: @@ -686,7 +681,7 @@ std::pair ArchiveFile::getMember(const Archive::Symbol *Sym) { Archive::Child C = - check(Sym->getMember(), toString(this) + + CHECK(Sym->getMember(), toString(this) + ": could not get the member for symbol " + Sym->getName()); @@ -694,13 +689,13 @@ return {MemoryBufferRef(), 0}; MemoryBufferRef Ret = - check(C.getMemoryBufferRef(), + CHECK(C.getMemoryBufferRef(), toString(this) + ": could not get the buffer for the member defining symbol " + Sym->getName()); if (C.getParent()->isThin() && Tar) - Tar->append(relativeToRoot(check(C.getFullName(), toString(this))), + Tar->append(relativeToRoot(CHECK(C.getFullName(), toString(this))), Ret.getBuffer()); if (C.getParent()->isThin()) return {Ret, 0}; @@ -717,7 +712,7 @@ template void SharedFile::parseSoName() { const Elf_Shdr *DynamicSec = nullptr; const ELFFile Obj = this->getObj(); - ArrayRef Sections = check(Obj.sections(), toString(this)); + ArrayRef Sections = CHECK(Obj.sections(), toString(this)); // Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d. for (const Elf_Shdr &Sec : Sections) { @@ -732,7 +727,7 @@ break; case SHT_SYMTAB_SHNDX: this->SymtabSHNDX = - check(Obj.getSHNDXTable(Sec, Sections), toString(this)); + CHECK(Obj.getSHNDXTable(Sec, Sections), toString(this)); break; case SHT_GNU_versym: this->VersymSec = &Sec; @@ -750,7 +745,7 @@ if (!DynamicSec) return; ArrayRef Arr = - check(Obj.template getSectionContentsAsArray(DynamicSec), + CHECK(Obj.template getSectionContentsAsArray(DynamicSec), toString(this)); for (const Elf_Dyn &Dyn : Arr) { if (Dyn.d_tag == DT_SONAME) { @@ -811,7 +806,7 @@ std::vector Verdefs = parseVerdefs(Versym); ArrayRef Sections = - check(this->getObj().sections(), toString(this)); + CHECK(this->getObj().sections(), toString(this)); // Add symbols to the symbol table. Elf_Sym_Range Syms = this->getGlobalELFSyms(); @@ -824,7 +819,7 @@ bool Hidden = VersymIndex & VERSYM_HIDDEN; VersymIndex = VersymIndex & ~VERSYM_HIDDEN; - StringRef Name = check(Sym.getName(this->StringTable), toString(this)); + StringRef Name = CHECK(Sym.getName(this->StringTable), toString(this)); if (Sym.isUndefined()) { Undefs.push_back(Name); continue; @@ -921,7 +916,7 @@ MemoryBufferRef MBRef(MB.getBuffer(), Saver.save(ArchiveName + MB.getBufferIdentifier() + utostr(OffsetInArchive))); - Obj = check(lto::InputFile::create(MBRef), toString(this)); + Obj = CHECK(lto::InputFile::create(MBRef), toString(this)); Triple T(Obj->getTargetTriple()); EKind = getBitcodeELFKind(T); @@ -1086,20 +1081,20 @@ typedef typename ELFT::SymRange Elf_Sym_Range; ELFFile Obj = check(ELFFile::create(this->MB.getBuffer())); - ArrayRef Sections = check(Obj.sections(), toString(this)); + ArrayRef Sections = CHECK(Obj.sections(), toString(this)); for (const Elf_Shdr &Sec : Sections) { if (Sec.sh_type != SHT_SYMTAB) continue; - Elf_Sym_Range Syms = check(Obj.symbols(&Sec), toString(this)); + Elf_Sym_Range Syms = CHECK(Obj.symbols(&Sec), toString(this)); uint32_t FirstNonLocal = Sec.sh_info; StringRef StringTable = - check(Obj.getStringTableForSymtab(Sec, Sections), toString(this)); + CHECK(Obj.getStringTableForSymtab(Sec, Sections), toString(this)); std::vector V; for (const Elf_Sym &Sym : Syms.slice(FirstNonLocal)) if (Sym.st_shndx != SHN_UNDEF) - V.push_back(check(Sym.getName(StringTable), toString(this))); + V.push_back(CHECK(Sym.getName(StringTable), toString(this))); return V; } return {}; @@ -1107,7 +1102,7 @@ std::vector LazyObjFile::getBitcodeSymbols() { std::unique_ptr Obj = - check(lto::InputFile::create(this->MB), toString(this)); + CHECK(lto::InputFile::create(this->MB), toString(this)); std::vector V; for (const lto::InputFile::Symbol &Sym : Obj->symbols()) if (!Sym.isUndefined()) Index: include/lld/Common/ErrorHandler.h =================================================================== --- include/lld/Common/ErrorHandler.h +++ include/lld/Common/ErrorHandler.h @@ -74,7 +74,7 @@ LLVM_ATTRIBUTE_NORETURN void exitLld(int Val); -// check() functions are convenient functions to strip errors +// check functions are convenient functions to strip errors // from error-or-value objects. template T check(ErrorOr E) { if (auto EC = E.getError()) @@ -88,25 +88,27 @@ return std::move(*E); } -template T check(ErrorOr E, const Twine &Prefix) { +template +T check2(ErrorOr E, llvm::function_ref Prefix) { if (auto EC = E.getError()) - fatal(Prefix + ": " + EC.message()); - return std::move(*E); -} - -template T check(Expected E, const Twine &Prefix) { - if (!E) - fatal(Prefix + ": " + toString(E.takeError())); + fatal(Prefix() + ": " + EC.message()); return std::move(*E); } -// A lazy variant that only allocates error messages when there is an error. template -T checkLazy(Expected E, llvm::function_ref getPrefix) { +T check2(Expected E, llvm::function_ref Prefix) { if (!E) - fatal(getPrefix() + ": " + toString(E.takeError())); + fatal(Prefix() + ": " + toString(E.takeError())); return std::move(*E); } + +inline std::string checkToString(const Twine &S) { return S.str(); } +inline std::string checkToString(std::string S) { return S; } +inline std::string checkToString(const char *S) { return S; } + +// To evaluate the second argument lazily, we use C macro. +#define CHECK(E, S) check2(E, [&] { return checkToString(S); }) + } // namespace lld #endif Index: wasm/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ wasm/InputFiles.cpp @@ -104,7 +104,7 @@ void ObjFile::parse() { // Parse a memory buffer as a wasm file. DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n"); - std::unique_ptr Bin = check(createBinary(MB), toString(this)); + std::unique_ptr Bin = CHECK(createBinary(MB), toString(this)); auto *Obj = dyn_cast(Bin.get()); if (!Obj) @@ -223,7 +223,7 @@ void ArchiveFile::parse() { // Parse a MemoryBufferRef as an archive file. DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n"); - File = check(Archive::create(MB), toString(this)); + File = CHECK(Archive::create(MB), toString(this)); // Read the symbol table to construct Lazy symbols. int Count = 0; @@ -236,7 +236,7 @@ void ArchiveFile::addMember(const Archive::Symbol *Sym) { const Archive::Child &C = - check(Sym->getMember(), + CHECK(Sym->getMember(), "could not get the member for symbol " + Sym->getName()); // Don't try to load the same member twice (this can happen when members @@ -248,7 +248,7 @@ DEBUG(dbgs() << "from archive: " << toString(this) << "\n"); MemoryBufferRef MB = - check(C.getMemoryBufferRef(), + CHECK(C.getMemoryBufferRef(), "could not get the buffer for the member defining symbol " + Sym->getName());