Reduce number of classes by merging DIHelper with ObjectFile.

DIHelper is a class having only one member, and ObjectFile has
a unique pointer to a DIHelper. So we can directly have ObjectFile
have the member.

Differential Revision: https://reviews.llvm.org/D26223

llvm-svn: 285850
This commit is contained in:
Rui Ueyama 2016-11-02 18:42:13 +00:00
parent 757d317c24
commit 7556f6b276
3 changed files with 31 additions and 57 deletions

View File

@ -35,7 +35,6 @@ using namespace llvm::sys::fs;
using namespace lld; using namespace lld;
using namespace lld::elf; using namespace lld::elf;
namespace { namespace {
// In ELF object file all section addresses are zero. If we have multiple // In ELF object file all section addresses are zero. If we have multiple
// .text sections (when using -ffunction-section or comdat group) then // .text sections (when using -ffunction-section or comdat group) then
@ -53,11 +52,10 @@ public:
}; };
} }
template <class ELFT> DIHelper<ELFT>::DIHelper(InputFile *F) { template <class ELFT> void ObjectFile<ELFT>::initializeDwarfLine() {
Expected<std::unique_ptr<object::ObjectFile>> Obj = std::unique_ptr<object::ObjectFile> Obj =
object::ObjectFile::createObjectFile(F->MB); check(object::ObjectFile::createObjectFile(this->MB),
if (!Obj) "createObjectFile failed");
return;
ObjectInfo ObjInfo; ObjectInfo ObjInfo;
DWARFContextInMemory Dwarf(*Obj.get(), &ObjInfo); DWARFContextInMemory Dwarf(*Obj.get(), &ObjInfo);
@ -65,35 +63,35 @@ template <class ELFT> DIHelper<ELFT>::DIHelper(InputFile *F) {
DataExtractor LineData(Dwarf.getLineSection().Data, DataExtractor LineData(Dwarf.getLineSection().Data,
ELFT::TargetEndianness == support::little, ELFT::TargetEndianness == support::little,
ELFT::Is64Bits ? 8 : 4); ELFT::Is64Bits ? 8 : 4);
// The second parameter is offset in .debug_line section // The second parameter is offset in .debug_line section
// for compilation unit (CU) of interest. We have only one // for compilation unit (CU) of interest. We have only one
// CU (object file), so offset is always 0. // CU (object file), so offset is always 0.
DwarfLine->getOrParseLineTable(LineData, 0); DwarfLine->getOrParseLineTable(LineData, 0);
} }
template <class ELFT> DIHelper<ELFT>::~DIHelper() {} // Returns source line information for a given offset
// using DWARF debug info.
template <class ELFT> template <class ELFT>
std::string DIHelper<ELFT>::getLineInfo(InputSectionBase<ELFT> *S, std::string ObjectFile<ELFT>::getLineInfo(InputSectionBase<ELFT> *S,
uintX_t Offset) { uintX_t Offset) {
if (!DwarfLine) if (!DwarfLine)
return ""; initializeDwarfLine();
DILineInfo LineInfo; // The offset to CU is 0.
DILineInfoSpecifier Spec; const DWARFDebugLine::LineTable *Tbl = DwarfLine->getLineTable(0);
// The offset to CU is 0 (see DIHelper constructor). if (!Tbl)
const DWARFDebugLine::LineTable *LineTbl = DwarfLine->getLineTable(0);
if (!LineTbl)
return ""; return "";
// Use fake address calcuated by adding section file offset and offset in // Use fake address calcuated by adding section file offset and offset in
// section. // section. See comments for ObjectInfo class.
// See comments for ObjectInfo class DILineInfo Info;
LineTbl->getFileLineInfoForAddress(S->Offset + Offset, nullptr, Spec.FLIKind, DILineInfoSpecifier Spec;
LineInfo); Tbl->getFileLineInfoForAddress(S->Offset + Offset, nullptr, Spec.FLIKind,
return LineInfo.Line != 0 Info);
? LineInfo.FileName + " (" + std::to_string(LineInfo.Line) + ")" if (Info.Line == 0)
: ""; return "";
return Info.FileName + " (" + std::to_string(Info.Line) + ")";
} }
// Returns "(internal)", "foo.a(bar.o)" or "baz.o". // Returns "(internal)", "foo.a(bar.o)" or "baz.o".
@ -185,13 +183,6 @@ ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getSymbols() {
return makeArrayRef(this->SymbolBodies).slice(1); return makeArrayRef(this->SymbolBodies).slice(1);
} }
template <class ELFT> DIHelper<ELFT> *elf::ObjectFile<ELFT>::getDIHelper() {
if (!DIH)
DIH.reset(new DIHelper<ELFT>(this));
return DIH.get();
}
template <class ELFT> uint32_t elf::ObjectFile<ELFT>::getMipsGp0() const { template <class ELFT> uint32_t elf::ObjectFile<ELFT>::getMipsGp0() const {
if (ELFT::Is64Bits && MipsOptions && MipsOptions->Reginfo) if (ELFT::Is64Bits && MipsOptions && MipsOptions->Reginfo)
return MipsOptions->Reginfo->ri_gp_value; return MipsOptions->Reginfo->ri_gp_value;
@ -968,8 +959,3 @@ template void BinaryFile::parse<ELF32LE>();
template void BinaryFile::parse<ELF32BE>(); template void BinaryFile::parse<ELF32BE>();
template void BinaryFile::parse<ELF64LE>(); template void BinaryFile::parse<ELF64LE>();
template void BinaryFile::parse<ELF64BE>(); template void BinaryFile::parse<ELF64BE>();
template class elf::DIHelper<ELF32LE>;
template class elf::DIHelper<ELF32BE>;
template class elf::DIHelper<ELF64LE>;
template class elf::DIHelper<ELF64BE>;

View File

@ -43,23 +43,6 @@ class InputFile;
class Lazy; class Lazy;
class SymbolBody; class SymbolBody;
// Debugging information helper class. The main purpose is to
// retrieve source file and line for error reporting. Linker may
// find reasonable number of errors in a single object file, so
// we cache debugging information in order to parse it only once
// for each object file we link.
template <class ELFT> class DIHelper {
typedef typename ELFT::uint uintX_t;
public:
DIHelper(InputFile *F);
~DIHelper();
std::string getLineInfo(InputSectionBase<ELFT> *S, uintX_t Offset);
private:
std::unique_ptr<llvm::DWARFDebugLine> DwarfLine;
};
// The root class of input files. // The root class of input files.
class InputFile { class InputFile {
public: public:
@ -175,9 +158,9 @@ public:
const Elf_Shdr *getSymbolTable() const { return this->Symtab; }; const Elf_Shdr *getSymbolTable() const { return this->Symtab; };
// DI helper allows manipilating debugging information for this // Returns source line information for a given offset.
// object file. Used for error reporting. // If no information is available, returns "".
DIHelper<ELFT> *getDIHelper(); std::string getLineInfo(InputSectionBase<ELFT> *S, uintX_t Offset);
// Get MIPS GP0 value defined by this file. This value represents the gp value // Get MIPS GP0 value defined by this file. This value represents the gp value
// used to create the relocatable object and required to support // used to create the relocatable object and required to support
@ -198,6 +181,7 @@ private:
initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
void initializeSymbols(); void initializeSymbols();
void initializeReverseDependencies(); void initializeReverseDependencies();
void initializeDwarfLine();
InputSectionBase<ELFT> *getRelocTarget(const Elf_Shdr &Sec); InputSectionBase<ELFT> *getRelocTarget(const Elf_Shdr &Sec);
InputSectionBase<ELFT> *createInputSection(const Elf_Shdr &Sec, InputSectionBase<ELFT> *createInputSection(const Elf_Shdr &Sec,
StringRef SectionStringTable); StringRef SectionStringTable);
@ -218,7 +202,11 @@ private:
// MIPS .MIPS.abiflags section defined by this file. // MIPS .MIPS.abiflags section defined by this file.
std::unique_ptr<MipsAbiFlagsInputSection<ELFT>> MipsAbiFlags; std::unique_ptr<MipsAbiFlagsInputSection<ELFT>> MipsAbiFlags;
std::unique_ptr<DIHelper<ELFT>> DIH; // Debugging information to retrieve source file and line for error
// reporting. Linker may find reasonable number of errors in a
// single object file, so we cache debugging information in order to
// parse it only once for each object file we link.
std::unique_ptr<llvm::DWARFDebugLine> DwarfLine;
}; };
// LazyObjectFile is analogous to ArchiveFile in the sense that // LazyObjectFile is analogous to ArchiveFile in the sense that

View File

@ -544,7 +544,7 @@ static std::string getLocation(SymbolBody &Sym, InputSectionBase<ELFT> &S,
ObjectFile<ELFT> *File = S.getFile(); ObjectFile<ELFT> *File = S.getFile();
// First check if we can get desired values from debugging information. // First check if we can get desired values from debugging information.
std::string LineInfo = File->getDIHelper()->getLineInfo(&S, Offset); std::string LineInfo = File->getLineInfo(&S, Offset);
if (!LineInfo.empty()) if (!LineInfo.empty())
return LineInfo; return LineInfo;