index cba15fc9a82c0ac209fa0e910a098201eac13822..d82087376638ec28a41d5f176dd3431bf2bebd10 100644 (file)
#include "DwarfDebug.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/DebugInfo.h"
+#include "llvm/IR/DIBuilder.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSection.h"
class ConstantInt;
class ConstantFP;
class DbgVariable;
+class DwarfCompileUnit;
// Data structure to hold a range for range lists.
class RangeSpan {
/// UniqueID - a numeric ID unique among all CUs in the module
unsigned UniqueID;
+ /// Node - MDNode for the compile unit.
+ DICompileUnit CUNode;
+
/// Unit debug information entry.
- const OwningPtr<DIE> UnitDie;
+ const std::unique_ptr<DIE> UnitDie;
/// Offset of the UnitDie from beginning of debug info section.
unsigned DebugInfoOffset;
/// DIEBlocks - A list of all the DIEBlocks in use.
std::vector<DIEBlock *> DIEBlocks;
+
+ /// DIELocs - A list of all the DIELocs in use.
+ std::vector<DIELoc *> DIELocs;
/// ContainingTypeMap - This map is used to keep track of subprogram DIEs that
/// need DW_AT_containing_type attribute. This attribute points to a DIE that
/// Skeleton unit associated with this unit.
DwarfUnit *Skeleton;
- DwarfUnit(unsigned UID, DIE *D, AsmPrinter *A, DwarfDebug *DW,
- DwarfFile *DWU);
+ DwarfUnit(unsigned UID, DIE *D, DICompileUnit CU, AsmPrinter *A,
+ DwarfDebug *DW, DwarfFile *DWU);
public:
virtual ~DwarfUnit();
// Accessors.
unsigned getUniqueID() const { return UniqueID; }
- virtual uint16_t getLanguage() const = 0;
+ uint16_t getLanguage() const { return CUNode.getLanguage(); }
+ DICompileUnit getCUNode() const { return CUNode; }
DIE *getUnitDie() const { return UnitDie.get(); }
const StringMap<const DIE *> &getGlobalNames() const { return GlobalNames; }
const StringMap<const DIE *> &getGlobalTypes() const { return GlobalTypes; }
bool hasContent() const { return !UnitDie->getChildren().empty(); }
/// addRange - Add an address range to the list of ranges for this unit.
- void addRange(RangeSpan Range) { CURanges.push_back(Range); }
+ void addRange(RangeSpan Range) {
+ // Only add a range for this unit if we're emitting full debug.
+ if (getCUNode().getEmissionKind() == DIBuilder::FullDebug)
+ CURanges.push_back(Range);
+ }
/// getRanges - Get the list of ranges for this unit.
const SmallVectorImpl<RangeSpan> &getRanges() const { return CURanges; }
/// kept in DwarfDebug.
DIE *getDIE(DIDescriptor D) const;
- /// getDIEBlock - Returns a fresh newly allocated DIEBlock.
- DIEBlock *getDIEBlock() { return new (DIEValueAllocator) DIEBlock(); }
+ /// getDIELoc - Returns a fresh newly allocated DIELoc.
+ DIELoc *getDIELoc() { return new (DIEValueAllocator) DIELoc(); }
/// insertDIE - Insert DIE into the map. We delegate the request to DwarfDebug
/// when the MDNode can be part of the type system, since DIEs for
void addUInt(DIE *Die, dwarf::Attribute Attribute, Optional<dwarf::Form> Form,
uint64_t Integer);
- void addUInt(DIEBlock *Block, dwarf::Form Form, uint64_t Integer);
+ void addUInt(DIE *Block, dwarf::Form Form, uint64_t Integer);
/// addSInt - Add an signed integer attribute data and value.
void addSInt(DIE *Die, dwarf::Attribute Attribute, Optional<dwarf::Form> Form,
int64_t Integer);
- void addSInt(DIEBlock *Die, Optional<dwarf::Form> Form, int64_t Integer);
+ void addSInt(DIELoc *Die, Optional<dwarf::Form> Form, int64_t Integer);
/// addString - Add a string attribute data and value.
void addString(DIE *Die, dwarf::Attribute Attribute, const StringRef Str);
const StringRef Str);
/// addExpr - Add a Dwarf expression attribute data and value.
- void addExpr(DIEBlock *Die, dwarf::Form Form, const MCExpr *Expr);
+ void addExpr(DIELoc *Die, dwarf::Form Form, const MCExpr *Expr);
/// addLabel - Add a Dwarf label attribute data and value.
void addLabel(DIE *Die, dwarf::Attribute Attribute, dwarf::Form Form,
const MCSymbol *Label);
- void addLabel(DIEBlock *Die, dwarf::Form Form, const MCSymbol *Label);
+ void addLabel(DIELoc *Die, dwarf::Form Form, const MCSymbol *Label);
+
+ /// addLocationList - Add a Dwarf loclistptr attribute data and value.
+ void addLocationList(DIE *Die, dwarf::Attribute Attribute, unsigned Index);
/// addSectionLabel - Add a Dwarf section label attribute data and value.
///
/// addOpAddress - Add a dwarf op address data and value using the
/// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index.
- void addOpAddress(DIEBlock *Die, const MCSymbol *Label);
+ void addOpAddress(DIELoc *Die, const MCSymbol *Label);
/// addSectionDelta - Add a label delta attribute data and value.
void addSectionDelta(DIE *Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
const MCSymbol *Lo);
+ /// addLabelDelta - Add a label delta attribute data and value.
+ void addLabelDelta(DIE *Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
+ const MCSymbol *Lo);
+
/// addDIEEntry - Add a DIE attribute data and value.
void addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIE *Entry);
void addDIETypeSignature(DIE *Die, const DwarfTypeUnit &Type);
+ /// addBlock - Add block data.
+ void addBlock(DIE *Die, dwarf::Attribute Attribute, DIELoc *Block);
+
/// addBlock - Add block data.
void addBlock(DIE *Die, dwarf::Attribute Attribute, DIEBlock *Block);
/// addSourceLine - Add location information to specified debug information
/// entry.
+ void addSourceLine(DIE *Die, unsigned Line, StringRef File,
+ StringRef Directory);
void addSourceLine(DIE *Die, DIVariable V);
void addSourceLine(DIE *Die, DIGlobalVariable G);
void addSourceLine(DIE *Die, DISubprogram SP);
void addTemplateParams(DIE &Buffer, DIArray TParams);
/// addRegisterOp - Add register operand.
- void addRegisterOp(DIEBlock *TheDie, unsigned Reg);
+ void addRegisterOp(DIELoc *TheDie, unsigned Reg);
/// addRegisterOffset - Add register offset.
- void addRegisterOffset(DIEBlock *TheDie, unsigned Reg, int64_t Offset);
+ void addRegisterOffset(DIELoc *TheDie, unsigned Reg, int64_t Offset);
/// addComplexAddress - Start with the address based on the location provided,
/// and generate the DWARF information necessary to find the actual variable
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
DIE *constructVariableDIE(DbgVariable &DV, bool isScopeAbstract);
+ /// constructSubprogramArguments - Construct function argument DIEs.
+ void constructSubprogramArguments(DIE &Buffer, DIArray Args);
+
/// Create a DIE with the given Tag, add the DIE to its parent, and
/// call insertDIE if MD is not null.
DIE *createAndAddDIE(unsigned Tag, DIE &Parent,
virtual void emitHeader(const MCSection *ASection,
const MCSymbol *ASectionSym) const;
+ virtual DwarfCompileUnit &getCU() = 0;
+
+ /// \brief Return whether this compilation unit has the
+ /// one-definition-rule (ODR). In C++ this allows the compiler to
+ /// perform type unique during LTO.
+ bool hasODR() const {
+ switch (getLanguage()) {
+ case dwarf::DW_LANG_C_plus_plus:
+ case dwarf::DW_LANG_C_plus_plus_03:
+ case dwarf::DW_LANG_C_plus_plus_11:
+ // For all we care, the C++ part of the language has the ODR and
+ // ObjC methods are not represented in a way that they could be
+ // confused with C++ member functions.
+ case dwarf::DW_LANG_ObjC_plus_plus:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /// \brief Unique C++ member function declarations based on their
+ /// context+mangled name.
+ DISubprogram getOdrUniqueSubprogram(DIScope Context, DISubprogram SP) const;
+
protected:
/// getOrCreateStaticMemberDIE - Create new static data member DIE.
DIE *getOrCreateStaticMemberDIE(DIDerivedType DT);
};
class DwarfCompileUnit : public DwarfUnit {
- /// Node - MDNode for the compile unit.
- DICompileUnit Node;
+ /// The attribute index of DW_AT_stmt_list in the compile unit DIE, avoiding
+ /// the need to search for it in applyStmtList.
+ unsigned stmtListIndex;
public:
DwarfCompileUnit(unsigned UID, DIE *D, DICompileUnit Node, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU);
- DICompileUnit getNode() const { return Node; }
- virtual ~DwarfCompileUnit() LLVM_OVERRIDE;
+
+ void initStmtList(MCSymbol *DwarfLineSectionSym);
+
+ /// Apply the DW_AT_stmt_list from this compile unit to the specified DIE.
+ void applyStmtList(DIE &D);
/// createGlobalVariableDIE - create global variable DIE.
void createGlobalVariableDIE(DIGlobalVariable GV);
/// either DW_FORM_addr or DW_FORM_GNU_addr_index.
void addLabelAddress(DIE *Die, dwarf::Attribute Attribute, MCSymbol *Label);
- uint16_t getLanguage() const LLVM_OVERRIDE { return getNode().getLanguage(); }
+ DwarfCompileUnit &getCU() override { return *this; }
};
class DwarfTypeUnit : public DwarfUnit {
private:
- uint16_t Language;
uint64_t TypeSignature;
const DIE *Ty;
+ DwarfCompileUnit &CU;
public:
- DwarfTypeUnit(unsigned UID, DIE *D, uint16_t Language, AsmPrinter *A,
+ DwarfTypeUnit(unsigned UID, DIE *D, DwarfCompileUnit &CU, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU);
- virtual ~DwarfTypeUnit() LLVM_OVERRIDE;
void setTypeSignature(uint64_t Signature) { TypeSignature = Signature; }
uint64_t getTypeSignature() const { return TypeSignature; }
void setType(const DIE *Ty) { this->Ty = Ty; }
- uint16_t getLanguage() const LLVM_OVERRIDE { return Language; }
/// Emit the header for this unit, not including the initial length field.
void emitHeader(const MCSection *ASection, const MCSymbol *ASectionSym) const
- LLVM_OVERRIDE;
- unsigned getHeaderSize() const LLVM_OVERRIDE {
+ override;
+ unsigned getHeaderSize() const override {
return DwarfUnit::getHeaderSize() + sizeof(uint64_t) + // Type Signature
sizeof(uint32_t); // Type DIE Offset
}
void initSection(const MCSection *Section);
+ DwarfCompileUnit &getCU() override { return CU; }
};
} // end llvm namespace
#endif