-#include "llvm/Support/CommandLine.h"
-
-using namespace llvm;
-
-static cl::opt<bool> GenerateTypeUnits("generate-type-units", cl::Hidden,
- cl::desc("Generate DWARF4 type units."),
- cl::init(false));
-
-/// CompileUnit - Compile unit constructor.
-CompileUnit::CompileUnit(unsigned UID, DIE *D, DICompileUnit Node,
- AsmPrinter *A, DwarfDebug *DW, DwarfUnits *DWU)
- : UniqueID(UID), Node(Node), CUDie(D), Asm(A), DD(DW), DU(DWU),
- IndexTyDie(0), Language(Node.getLanguage()) {
- DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
- insertDIE(Node, D);
-}
-
-CompileUnit::CompileUnit(unsigned UID, DIE *D, uint16_t Language, AsmPrinter *A,
- DwarfDebug *DD, DwarfUnits *DU)
- : UniqueID(UID), Node(NULL), CUDie(D), Asm(A), DD(DD), DU(DU),
- IndexTyDie(0), Language(Language) {
- DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
-}
-
-/// ~CompileUnit - Destructor for compile unit.
-CompileUnit::~CompileUnit() {
- for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
- DIEBlocks[j]->~DIEBlock();
-}
-
-/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
-/// information entry.
-DIEEntry *CompileUnit::createDIEEntry(DIE *Entry) {
- DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
- return Value;
-}
-
-/// getDefaultLowerBound - Return the default lower bound for an array. If the
-/// DWARF version doesn't handle the language, return -1.
-int64_t CompileUnit::getDefaultLowerBound() const {
- switch (getLanguage()) {
- default:
- break;
-
- case dwarf::DW_LANG_C89:
- case dwarf::DW_LANG_C99:
- case dwarf::DW_LANG_C:
- case dwarf::DW_LANG_C_plus_plus:
- case dwarf::DW_LANG_ObjC:
- case dwarf::DW_LANG_ObjC_plus_plus:
- return 0;
-
- case dwarf::DW_LANG_Fortran77:
- case dwarf::DW_LANG_Fortran90:
- case dwarf::DW_LANG_Fortran95:
- return 1;
-
- // The languages below have valid values only if the DWARF version >= 4.
- case dwarf::DW_LANG_Java:
- case dwarf::DW_LANG_Python:
- case dwarf::DW_LANG_UPC:
- case dwarf::DW_LANG_D:
- if (dwarf::DWARF_VERSION >= 4)
- return 0;
- break;
-
- case dwarf::DW_LANG_Ada83:
- case dwarf::DW_LANG_Ada95:
- case dwarf::DW_LANG_Cobol74:
- case dwarf::DW_LANG_Cobol85:
- case dwarf::DW_LANG_Modula2:
- case dwarf::DW_LANG_Pascal83:
- case dwarf::DW_LANG_PLI:
- if (dwarf::DWARF_VERSION >= 4)
- return 1;
- break;
- }
-
- return -1;
-}
-
-/// Check whether the DIE for this MDNode can be shared across CUs.
-static bool isShareableAcrossCUs(DIDescriptor D) {
- // When the MDNode can be part of the type system, the DIE can be
- // shared across CUs.
- return (D.isType() ||
- (D.isSubprogram() && !DISubprogram(D).isDefinition())) &&
- !GenerateTypeUnits;
-}
-
-/// getDIE - Returns the debug information entry map slot for the
-/// specified debug variable. We delegate the request to DwarfDebug
-/// when the DIE for this MDNode can be shared across CUs. The mappings
-/// will be kept in DwarfDebug for shareable DIEs.
-DIE *CompileUnit::getDIE(DIDescriptor D) const {
- if (isShareableAcrossCUs(D))
- return DD->getDIE(D);
- return MDNodeToDieMap.lookup(D);
-}
-
-/// insertDIE - Insert DIE into the map. We delegate the request to DwarfDebug
-/// when the DIE for this MDNode can be shared across CUs. The mappings
-/// will be kept in DwarfDebug for shareable DIEs.
-void CompileUnit::insertDIE(DIDescriptor Desc, DIE *D) {
- if (isShareableAcrossCUs(Desc)) {
- DD->insertDIE(Desc, D);
- return;
- }
- MDNodeToDieMap.insert(std::make_pair(Desc, D));
-}
-
-/// addFlag - Add a flag that is true.
-void CompileUnit::addFlag(DIE *Die, dwarf::Attribute Attribute) {
- if (DD->getDwarfVersion() >= 4)
- Die->addValue(Attribute, dwarf::DW_FORM_flag_present, DIEIntegerOne);
- else
- Die->addValue(Attribute, dwarf::DW_FORM_flag, DIEIntegerOne);
-}
-
-/// addUInt - Add an unsigned integer attribute data and value.
-///
-void CompileUnit::addUInt(DIE *Die, dwarf::Attribute Attribute,
- Optional<dwarf::Form> Form, uint64_t Integer) {
- if (!Form)
- Form = DIEInteger::BestForm(false, Integer);
- DIEValue *Value = Integer == 1 ? DIEIntegerOne : new (DIEValueAllocator)
- DIEInteger(Integer);
- Die->addValue(Attribute, *Form, Value);
-}
-
-void CompileUnit::addUInt(DIEBlock *Block, dwarf::Form Form, uint64_t Integer) {
- addUInt(Block, (dwarf::Attribute)0, Form, Integer);
-}
-
-/// addSInt - Add an signed integer attribute data and value.
-///
-void CompileUnit::addSInt(DIE *Die, dwarf::Attribute Attribute,
- Optional<dwarf::Form> Form, int64_t Integer) {
- if (!Form)
- Form = DIEInteger::BestForm(true, Integer);
- DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
- Die->addValue(Attribute, *Form, Value);
-}
-
-void CompileUnit::addSInt(DIEBlock *Die, Optional<dwarf::Form> Form,
- int64_t Integer) {
- addSInt(Die, (dwarf::Attribute)0, Form, Integer);
-}
-
-/// addString - Add a string attribute data and value. We always emit a
-/// reference to the string pool instead of immediate strings so that DIEs have
-/// more predictable sizes. In the case of split dwarf we emit an index
-/// into another table which gets us the static offset into the string
-/// table.
-void CompileUnit::addString(DIE *Die, dwarf::Attribute Attribute,
- StringRef String) {
- DIEValue *Value;
- dwarf::Form Form;
- if (!DD->useSplitDwarf()) {
- MCSymbol *Symb = DU->getStringPoolEntry(String);
- if (Asm->needsRelocationsForDwarfStringPool())
- Value = new (DIEValueAllocator) DIELabel(Symb);
- else {
- MCSymbol *StringPool = DU->getStringPoolSym();
- Value = new (DIEValueAllocator) DIEDelta(Symb, StringPool);
- }
- Form = dwarf::DW_FORM_strp;
- } else {
- unsigned idx = DU->getStringPoolIndex(String);
- Value = new (DIEValueAllocator) DIEInteger(idx);
- Form = dwarf::DW_FORM_GNU_str_index;
- }
- DIEValue *Str = new (DIEValueAllocator) DIEString(Value, String);
- Die->addValue(Attribute, Form, Str);
-}
-
-/// addLocalString - Add a string attribute data and value. This is guaranteed
-/// to be in the local string pool instead of indirected.
-void CompileUnit::addLocalString(DIE *Die, dwarf::Attribute Attribute,
- StringRef String) {
- MCSymbol *Symb = DU->getStringPoolEntry(String);
- DIEValue *Value;
- if (Asm->needsRelocationsForDwarfStringPool())
- Value = new (DIEValueAllocator) DIELabel(Symb);
- else {
- MCSymbol *StringPool = DU->getStringPoolSym();
- Value = new (DIEValueAllocator) DIEDelta(Symb, StringPool);
- }
- Die->addValue(Attribute, dwarf::DW_FORM_strp, Value);
-}
-
-/// addExpr - Add a Dwarf expression attribute data and value.
-///
-void CompileUnit::addExpr(DIEBlock *Die, dwarf::Form Form, const MCExpr *Expr) {
- DIEValue *Value = new (DIEValueAllocator) DIEExpr(Expr);
- Die->addValue((dwarf::Attribute)0, Form, Value);
-}