diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp')
| -rw-r--r-- | contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 214 | 
1 files changed, 130 insertions, 84 deletions
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 2a866c071f59..667afbb450bd 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -27,6 +27,7 @@  #include "llvm/IR/GlobalValue.h"  #include "llvm/IR/Metadata.h"  #include "llvm/MC/MachineLocation.h" +#include "llvm/MC/MCAsmInfo.h"  #include "llvm/MC/MCDwarf.h"  #include "llvm/MC/MCSection.h"  #include "llvm/MC/MCStreamer.h" @@ -54,15 +55,15 @@ DIEDwarfExpression::DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU,      : DwarfExpression(AP.getDwarfVersion()), AP(AP), DU(DU),        DIE(DIE) {} -void DIEDwarfExpression::EmitOp(uint8_t Op, const char* Comment) { +void DIEDwarfExpression::emitOp(uint8_t Op, const char* Comment) {    DU.addUInt(DIE, dwarf::DW_FORM_data1, Op);  } -void DIEDwarfExpression::EmitSigned(int64_t Value) { +void DIEDwarfExpression::emitSigned(int64_t Value) {    DU.addSInt(DIE, dwarf::DW_FORM_sdata, Value);  } -void DIEDwarfExpression::EmitUnsigned(uint64_t Value) { +void DIEDwarfExpression::emitUnsigned(uint64_t Value) {    DU.addUInt(DIE, dwarf::DW_FORM_udata, Value);  } @@ -73,8 +74,8 @@ bool DIEDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,  DwarfUnit::DwarfUnit(dwarf::Tag UnitTag, const DICompileUnit *Node,                       AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU) -    : DIEUnit(A->getDwarfVersion(), A->getPointerSize(), UnitTag), CUNode(Node), -      Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr) { +    : DIEUnit(A->getDwarfVersion(), A->MAI->getCodePointerSize(), UnitTag), +      CUNode(Node), Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr) {  }  DwarfTypeUnit::DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, @@ -98,25 +99,35 @@ int64_t DwarfUnit::getDefaultLowerBound() const {    default:      break; -  case dwarf::DW_LANG_C89: -  case dwarf::DW_LANG_C99: +  // The languages below have valid values in all DWARF versions.    case dwarf::DW_LANG_C: +  case dwarf::DW_LANG_C89:    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. +  // The languages below have valid values only if the DWARF version >= 3. +  case dwarf::DW_LANG_C99: +  case dwarf::DW_LANG_ObjC: +  case dwarf::DW_LANG_ObjC_plus_plus: +    if (DD->getDwarfVersion() >= 3) +      return 0; +    break; + +  case dwarf::DW_LANG_Fortran95: +    if (DD->getDwarfVersion() >= 3) +      return 1; +    break; + +  // Starting with DWARF v4, all defined languages have valid values. +  case dwarf::DW_LANG_D:    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) +    if (DD->getDwarfVersion() >= 4)        return 0;      break; @@ -127,31 +138,33 @@ int64_t DwarfUnit::getDefaultLowerBound() const {    case dwarf::DW_LANG_Modula2:    case dwarf::DW_LANG_Pascal83:    case dwarf::DW_LANG_PLI: -    if (dwarf::DWARF_VERSION >= 4) +    if (DD->getDwarfVersion() >= 4)        return 1;      break; -  // The languages below have valid values only if the DWARF version >= 5. -  case dwarf::DW_LANG_OpenCL: -  case dwarf::DW_LANG_Go: -  case dwarf::DW_LANG_Haskell: +  // The languages below are new in DWARF v5. +  case dwarf::DW_LANG_BLISS: +  case dwarf::DW_LANG_C11:    case dwarf::DW_LANG_C_plus_plus_03:    case dwarf::DW_LANG_C_plus_plus_11: +  case dwarf::DW_LANG_C_plus_plus_14: +  case dwarf::DW_LANG_Dylan: +  case dwarf::DW_LANG_Go: +  case dwarf::DW_LANG_Haskell:    case dwarf::DW_LANG_OCaml: +  case dwarf::DW_LANG_OpenCL: +  case dwarf::DW_LANG_RenderScript:    case dwarf::DW_LANG_Rust: -  case dwarf::DW_LANG_C11:    case dwarf::DW_LANG_Swift: -  case dwarf::DW_LANG_Dylan: -  case dwarf::DW_LANG_C_plus_plus_14: -    if (dwarf::DWARF_VERSION >= 5) +    if (DD->getDwarfVersion() >= 5)        return 0;      break; -  case dwarf::DW_LANG_Modula3: -  case dwarf::DW_LANG_Julia:    case dwarf::DW_LANG_Fortran03:    case dwarf::DW_LANG_Fortran08: -    if (dwarf::DWARF_VERSION >= 5) +  case dwarf::DW_LANG_Julia: +  case dwarf::DW_LANG_Modula3: +    if (DD->getDwarfVersion() >= 5)        return 1;      break;    } @@ -160,7 +173,7 @@ int64_t DwarfUnit::getDefaultLowerBound() const {  }  /// Check whether the DIE for this MDNode can be shared across CUs. -static bool isShareableAcrossCUs(const DINode *D) { +bool DwarfUnit::isShareableAcrossCUs(const DINode *D) const {    // When the MDNode can be part of the type system, the DIE can be shared    // across CUs.    // Combining type units and cross-CU DIE sharing is lower value (since @@ -168,6 +181,8 @@ static bool isShareableAcrossCUs(const DINode *D) {    // level already) but may be implementable for some value in projects    // building multiple independent libraries with LTO and then linking those    // together. +  if (isDwoUnit() && !DD->shareAcrossDWOCUs()) +    return false;    return (isa<DIType>(D) ||            (isa<DISubprogram>(D) && !cast<DISubprogram>(D)->isDefinition())) &&           !GenerateDwarfTypeUnits; @@ -285,13 +300,6 @@ void DwarfUnit::addDIETypeSignature(DIE &Die, uint64_t Signature) {                 dwarf::DW_FORM_ref_sig8, DIEInteger(Signature));  } -void DwarfUnit::addDIETypeSignature(DIE &Die, dwarf::Attribute Attribute, -                                    StringRef Identifier) { -  uint64_t Signature = DD->makeTypeSignature(Identifier); -  Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_ref_sig8, -               DIEInteger(Signature)); -} -  void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute,                              DIEEntry Entry) {    const DIEUnit *CU = Die.getUnit(); @@ -369,10 +377,6 @@ void DwarfUnit::addSourceLine(DIE &Die, const DIObjCProperty *Ty) {    addSourceLine(Die, Ty->getLine(), Ty->getFilename(), Ty->getDirectory());  } -void DwarfUnit::addSourceLine(DIE &Die, const DINamespace *NS) { -  addSourceLine(Die, NS->getLine(), NS->getFilename(), NS->getDirectory()); -} -  /* Byref variables, in Blocks, are declared by the programmer as "SomeType     VarName;", but the compiler creates a __Block_byref_x_VarName struct, and     gives the variable VarName either the struct, or a pointer to the struct, as @@ -465,50 +469,48 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die,    // Decode the original location, and use that as the start of the byref    // variable's location.    DIELoc *Loc = new (DIEValueAllocator) DIELoc; -  SmallVector<uint64_t, 6> DIExpr; -  DIEDwarfExpression Expr(*Asm, *this, *Loc); - -  bool validReg; -  if (Location.isReg()) -    validReg = Expr.AddMachineReg(*Asm->MF->getSubtarget().getRegisterInfo(), -                                  Location.getReg()); -  else -    validReg = -        Expr.AddMachineRegIndirect(*Asm->MF->getSubtarget().getRegisterInfo(), -                                   Location.getReg(), Location.getOffset()); - -  if (!validReg) -    return; - +  DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); +  if (Location.isIndirect()) +    DwarfExpr.setMemoryLocationKind(); + +  SmallVector<uint64_t, 9> Ops; +  if (Location.isIndirect() && Location.getOffset()) { +    Ops.push_back(dwarf::DW_OP_plus); +    Ops.push_back(Location.getOffset()); +  }    // If we started with a pointer to the __Block_byref... struct, then    // the first thing we need to do is dereference the pointer (DW_OP_deref).    if (isPointer) -    DIExpr.push_back(dwarf::DW_OP_deref); +    Ops.push_back(dwarf::DW_OP_deref);    // Next add the offset for the '__forwarding' field:    // DW_OP_plus_uconst ForwardingFieldOffset.  Note there's no point in    // adding the offset if it's 0.    if (forwardingFieldOffset > 0) { -    DIExpr.push_back(dwarf::DW_OP_plus); -    DIExpr.push_back(forwardingFieldOffset); +    Ops.push_back(dwarf::DW_OP_plus); +    Ops.push_back(forwardingFieldOffset);    }    // Now dereference the __forwarding field to get to the real __Block_byref    // struct:  DW_OP_deref. -  DIExpr.push_back(dwarf::DW_OP_deref); +  Ops.push_back(dwarf::DW_OP_deref);    // Now that we've got the real __Block_byref... struct, add the offset    // for the variable's field to get to the location of the actual variable:    // DW_OP_plus_uconst varFieldOffset.  Again, don't add if it's 0.    if (varFieldOffset > 0) { -    DIExpr.push_back(dwarf::DW_OP_plus); -    DIExpr.push_back(varFieldOffset); +    Ops.push_back(dwarf::DW_OP_plus); +    Ops.push_back(varFieldOffset);    } -  Expr.AddExpression(makeArrayRef(DIExpr)); -  Expr.finalize(); + +  DIExpressionCursor Cursor(Ops); +  const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); +  if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) +    return; +  DwarfExpr.addExpression(std::move(Cursor));    // Now attach the location information to the DIE. -  addBlock(Die, Attribute, Loc); +  addBlock(Die, Attribute, DwarfExpr.finalize());  }  /// Return true if type encoding is unsigned. @@ -645,7 +647,7 @@ void DwarfUnit::addLinkageName(DIE &Die, StringRef LinkageName) {      addString(Die,                DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name                                           : dwarf::DW_AT_MIPS_linkage_name, -              GlobalValue::getRealLinkageName(LinkageName)); +              GlobalValue::dropLLVMManglingEscape(LinkageName));  }  void DwarfUnit::addTemplateParams(DIE &Buffer, DINodeArray TParams) { @@ -658,6 +660,14 @@ void DwarfUnit::addTemplateParams(DIE &Buffer, DINodeArray TParams) {    }  } +/// Add thrown types. +void DwarfUnit::addThrownTypes(DIE &Die, DINodeArray ThrownTypes) { +  for (const auto *Ty : ThrownTypes) { +    DIE &TT = createAndAddDIE(dwarf::DW_TAG_thrown_type, Die); +    addType(TT, cast<DIType>(Ty)); +  } +} +  DIE *DwarfUnit::getOrCreateContextDIE(const DIScope *Context) {    if (!Context || isa<DIFile>(Context))      return &getUnitDie(); @@ -672,7 +682,7 @@ DIE *DwarfUnit::getOrCreateContextDIE(const DIScope *Context) {    return getDIE(Context);  } -DIE *DwarfUnit::createTypeDIE(const DICompositeType *Ty) { +DIE *DwarfTypeUnit::createTypeDIE(const DICompositeType *Ty) {    auto *Context = resolve(Ty->getScope());    DIE *ContextDIE = getOrCreateContextDIE(Context); @@ -684,8 +694,7 @@ DIE *DwarfUnit::createTypeDIE(const DICompositeType *Ty) {    constructTypeDIE(TyDIE, cast<DICompositeType>(Ty)); -  if (!Ty->isExternalTypeRef()) -    updateAcceleratorTables(Context, Ty, TyDIE); +  updateAcceleratorTables(Context, Ty, TyDIE);    return &TyDIE;  } @@ -841,6 +850,13 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) {    // Add source line info if available and TyDesc is not a forward declaration.    if (!DTy->isForwardDecl())      addSourceLine(Buffer, DTy); + +  // If DWARF address space value is other than None, add it for pointer and +  // reference types as DW_AT_address_class. +  if (DTy->getDWARFAddressSpace() && (Tag == dwarf::DW_TAG_pointer_type || +                                      Tag == dwarf::DW_TAG_reference_type)) +    addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4, +            DTy->getDWARFAddressSpace().getValue());  }  void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args) { @@ -892,13 +908,6 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy) {  }  void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { -  if (CTy->isExternalTypeRef()) { -    StringRef Identifier = CTy->getIdentifier(); -    assert(!Identifier.empty() && "external type ref without identifier"); -    addFlag(Buffer, dwarf::DW_AT_declaration); -    return addDIETypeSignature(Buffer, dwarf::DW_AT_signature, Identifier); -  } -    // Add name if not anonymous or intermediate type.    StringRef Name = CTy->getName(); @@ -1074,7 +1083,6 @@ DIE *DwarfUnit::getOrCreateNameSpace(const DINamespace *NS) {      Name = "(anonymous namespace)";    DD->addAccelNamespace(Name, NDie);    addGlobalName(Name, NDie, NS->getScope()); -  addSourceLine(NDie, NS);    if (NS->getExportSymbols())      addFlag(NDie, dwarf::DW_AT_export_symbols);    return &NDie; @@ -1180,8 +1188,12 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP,  }  void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, -                                          bool Minimal) { -  if (!Minimal) +                                          bool SkipSPAttributes) { +  // If -fdebug-info-for-profiling is enabled, need to emit the subprogram +  // and its source location. +  bool SkipSPSourceLocation = SkipSPAttributes && +                              !CUNode->getDebugInfoForProfiling(); +  if (!SkipSPSourceLocation)      if (applySubprogramDefinitionAttributes(SP, SPDie))        return; @@ -1189,12 +1201,13 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,    if (!SP->getName().empty())      addString(SPDie, dwarf::DW_AT_name, SP->getName()); +  if (!SkipSPSourceLocation) +    addSourceLine(SPDie, SP); +    // Skip the rest of the attributes under -gmlt to save space. -  if (Minimal) +  if (SkipSPAttributes)      return; -  addSourceLine(SPDie, SP); -    // Add the prototype if we have a prototype and we have a C like    // language.    uint16_t Language = getLanguage(); @@ -1241,6 +1254,8 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,      constructSubprogramArguments(SPDie, Args);    } +  addThrownTypes(SPDie, SP->getThrownTypes()); +    if (SP->isArtificial())      addFlag(SPDie, dwarf::DW_AT_artificial); @@ -1526,18 +1541,27 @@ DIE *DwarfUnit::getOrCreateStaticMemberDIE(const DIDerivedType *DT) {    return &StaticMemberDIE;  } -void DwarfUnit::emitHeader(bool UseOffsets) { +void DwarfUnit::emitCommonHeader(bool UseOffsets, dwarf::UnitType UT) {    // Emit size of content not including length itself    Asm->OutStreamer->AddComment("Length of Unit");    Asm->EmitInt32(getHeaderSize() + getUnitDie().getSize());    Asm->OutStreamer->AddComment("DWARF version number"); -  Asm->EmitInt16(DD->getDwarfVersion()); -  Asm->OutStreamer->AddComment("Offset Into Abbrev. Section"); +  unsigned Version = DD->getDwarfVersion(); +  Asm->EmitInt16(Version); + +  // DWARF v5 reorders the address size and adds a unit type. +  if (Version >= 5) { +    Asm->OutStreamer->AddComment("DWARF Unit Type"); +    Asm->EmitInt8(UT); +    Asm->OutStreamer->AddComment("Address Size (in bytes)"); +    Asm->EmitInt8(Asm->MAI->getCodePointerSize()); +  }    // We share one abbreviations table across all units so it's always at the    // start of the section. Use a relocatable offset where needed to ensure    // linking doesn't invalidate that offset. +  Asm->OutStreamer->AddComment("Offset Into Abbrev. Section");    const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();    if (UseOffsets)      Asm->EmitInt32(0); @@ -1545,12 +1569,16 @@ void DwarfUnit::emitHeader(bool UseOffsets) {      Asm->emitDwarfSymbolReference(          TLOF.getDwarfAbbrevSection()->getBeginSymbol(), false); -  Asm->OutStreamer->AddComment("Address Size (in bytes)"); -  Asm->EmitInt8(Asm->getDataLayout().getPointerSize()); +  if (Version <= 4) { +    Asm->OutStreamer->AddComment("Address Size (in bytes)"); +    Asm->EmitInt8(Asm->MAI->getCodePointerSize()); +  }  }  void DwarfTypeUnit::emitHeader(bool UseOffsets) { -  DwarfUnit::emitHeader(UseOffsets); +  DwarfUnit::emitCommonHeader(UseOffsets,  +                              DD->useSplitDwarf() ? dwarf::DW_UT_split_type +                                                  : dwarf::DW_UT_type);    Asm->OutStreamer->AddComment("Type Signature");    Asm->OutStreamer->EmitIntValue(TypeSignature, sizeof(TypeSignature));    Asm->OutStreamer->AddComment("Type DIE Offset"); @@ -1564,3 +1592,21 @@ bool DwarfTypeUnit::isDwoUnit() const {    // when split DWARF is being used.    return DD->useSplitDwarf();  } + +void DwarfTypeUnit::addGlobalName(StringRef Name, const DIE &Die, +                                  const DIScope *Context) { +  getCU().addGlobalNameForTypeUnit(Name, Context); +} + +void DwarfTypeUnit::addGlobalType(const DIType *Ty, const DIE &Die, +                                  const DIScope *Context) { +  getCU().addGlobalTypeUnitType(Ty, Context); +} + +const MCSymbol *DwarfUnit::getCrossSectionRelativeBaseAddress() const { +  if (!Asm->MAI->doesDwarfUseRelocationsAcrossSections()) +    return nullptr; +  if (isDwoUnit()) +    return nullptr; +  return getSection()->getBeginSymbol(); +}  | 
