Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
35271 views
//===-- llvm/CodeGen/DwarfUnit.cpp - Dwarf Type and Compile Units ---------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains support for constructing a dwarf compile unit.9//10//===----------------------------------------------------------------------===//1112#include "DwarfUnit.h"13#include "AddressPool.h"14#include "DwarfCompileUnit.h"15#include "DwarfExpression.h"16#include "llvm/ADT/APFloat.h"17#include "llvm/ADT/APInt.h"18#include "llvm/CodeGen/TargetRegisterInfo.h"19#include "llvm/IR/Constants.h"20#include "llvm/IR/DataLayout.h"21#include "llvm/IR/GlobalValue.h"22#include "llvm/IR/Metadata.h"23#include "llvm/MC/MCAsmInfo.h"24#include "llvm/MC/MCContext.h"25#include "llvm/MC/MCDwarf.h"26#include "llvm/MC/MCSection.h"27#include "llvm/MC/MCStreamer.h"28#include "llvm/Support/Casting.h"29#include "llvm/Target/TargetLoweringObjectFile.h"30#include <cassert>31#include <cstdint>32#include <limits>33#include <string>34#include <utility>3536using namespace llvm;3738#define DEBUG_TYPE "dwarfdebug"3940DIEDwarfExpression::DIEDwarfExpression(const AsmPrinter &AP,41DwarfCompileUnit &CU, DIELoc &DIE)42: DwarfExpression(AP.getDwarfVersion(), CU), AP(AP), OutDIE(DIE) {}4344void DIEDwarfExpression::emitOp(uint8_t Op, const char* Comment) {45CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Op);46}4748void DIEDwarfExpression::emitSigned(int64_t Value) {49CU.addSInt(getActiveDIE(), dwarf::DW_FORM_sdata, Value);50}5152void DIEDwarfExpression::emitUnsigned(uint64_t Value) {53CU.addUInt(getActiveDIE(), dwarf::DW_FORM_udata, Value);54}5556void DIEDwarfExpression::emitData1(uint8_t Value) {57CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Value);58}5960void DIEDwarfExpression::emitBaseTypeRef(uint64_t Idx) {61CU.addBaseTypeRef(getActiveDIE(), Idx);62}6364void DIEDwarfExpression::enableTemporaryBuffer() {65assert(!IsBuffering && "Already buffering?");66IsBuffering = true;67}6869void DIEDwarfExpression::disableTemporaryBuffer() { IsBuffering = false; }7071unsigned DIEDwarfExpression::getTemporaryBufferSize() {72return TmpDIE.computeSize(AP.getDwarfFormParams());73}7475void DIEDwarfExpression::commitTemporaryBuffer() { OutDIE.takeValues(TmpDIE); }7677bool DIEDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,78llvm::Register MachineReg) {79return MachineReg == TRI.getFrameRegister(*AP.MF);80}8182DwarfUnit::DwarfUnit(dwarf::Tag UnitTag, const DICompileUnit *Node,83AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU,84unsigned UniqueID)85: DIEUnit(UnitTag), UniqueID(UniqueID), CUNode(Node), Asm(A), DD(DW),86DU(DWU) {}8788DwarfTypeUnit::DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A,89DwarfDebug *DW, DwarfFile *DWU, unsigned UniqueID,90MCDwarfDwoLineTable *SplitLineTable)91: DwarfUnit(dwarf::DW_TAG_type_unit, CU.getCUNode(), A, DW, DWU, UniqueID),92CU(CU), SplitLineTable(SplitLineTable) {}9394DwarfUnit::~DwarfUnit() {95for (DIEBlock *B : DIEBlocks)96B->~DIEBlock();97for (DIELoc *L : DIELocs)98L->~DIELoc();99}100101int64_t DwarfUnit::getDefaultLowerBound() const {102switch (getLanguage()) {103default:104break;105106// The languages below have valid values in all DWARF versions.107case dwarf::DW_LANG_C:108case dwarf::DW_LANG_C89:109case dwarf::DW_LANG_C_plus_plus:110return 0;111112case dwarf::DW_LANG_Fortran77:113case dwarf::DW_LANG_Fortran90:114return 1;115116// The languages below have valid values only if the DWARF version >= 3.117case dwarf::DW_LANG_C99:118case dwarf::DW_LANG_ObjC:119case dwarf::DW_LANG_ObjC_plus_plus:120if (DD->getDwarfVersion() >= 3)121return 0;122break;123124case dwarf::DW_LANG_Fortran95:125if (DD->getDwarfVersion() >= 3)126return 1;127break;128129// Starting with DWARF v4, all defined languages have valid values.130case dwarf::DW_LANG_D:131case dwarf::DW_LANG_Java:132case dwarf::DW_LANG_Python:133case dwarf::DW_LANG_UPC:134if (DD->getDwarfVersion() >= 4)135return 0;136break;137138case dwarf::DW_LANG_Ada83:139case dwarf::DW_LANG_Ada95:140case dwarf::DW_LANG_Cobol74:141case dwarf::DW_LANG_Cobol85:142case dwarf::DW_LANG_Modula2:143case dwarf::DW_LANG_Pascal83:144case dwarf::DW_LANG_PLI:145if (DD->getDwarfVersion() >= 4)146return 1;147break;148149// The languages below are new in DWARF v5.150case dwarf::DW_LANG_BLISS:151case dwarf::DW_LANG_C11:152case dwarf::DW_LANG_C_plus_plus_03:153case dwarf::DW_LANG_C_plus_plus_11:154case dwarf::DW_LANG_C_plus_plus_14:155case dwarf::DW_LANG_Dylan:156case dwarf::DW_LANG_Go:157case dwarf::DW_LANG_Haskell:158case dwarf::DW_LANG_OCaml:159case dwarf::DW_LANG_OpenCL:160case dwarf::DW_LANG_RenderScript:161case dwarf::DW_LANG_Rust:162case dwarf::DW_LANG_Swift:163if (DD->getDwarfVersion() >= 5)164return 0;165break;166167case dwarf::DW_LANG_Fortran03:168case dwarf::DW_LANG_Fortran08:169case dwarf::DW_LANG_Julia:170case dwarf::DW_LANG_Modula3:171if (DD->getDwarfVersion() >= 5)172return 1;173break;174}175176return -1;177}178179/// Check whether the DIE for this MDNode can be shared across CUs.180bool DwarfUnit::isShareableAcrossCUs(const DINode *D) const {181// When the MDNode can be part of the type system, the DIE can be shared182// across CUs.183// Combining type units and cross-CU DIE sharing is lower value (since184// cross-CU DIE sharing is used in LTO and removes type redundancy at that185// level already) but may be implementable for some value in projects186// building multiple independent libraries with LTO and then linking those187// together.188if (isDwoUnit() && !DD->shareAcrossDWOCUs())189return false;190return (isa<DIType>(D) ||191(isa<DISubprogram>(D) && !cast<DISubprogram>(D)->isDefinition())) &&192!DD->generateTypeUnits();193}194195DIE *DwarfUnit::getDIE(const DINode *D) const {196if (isShareableAcrossCUs(D))197return DU->getDIE(D);198return MDNodeToDieMap.lookup(D);199}200201void DwarfUnit::insertDIE(const DINode *Desc, DIE *D) {202if (isShareableAcrossCUs(Desc)) {203DU->insertDIE(Desc, D);204return;205}206MDNodeToDieMap.insert(std::make_pair(Desc, D));207}208209void DwarfUnit::insertDIE(DIE *D) {210MDNodeToDieMap.insert(std::make_pair(nullptr, D));211}212213void DwarfUnit::addFlag(DIE &Die, dwarf::Attribute Attribute) {214if (DD->getDwarfVersion() >= 4)215addAttribute(Die, Attribute, dwarf::DW_FORM_flag_present, DIEInteger(1));216else217addAttribute(Die, Attribute, dwarf::DW_FORM_flag, DIEInteger(1));218}219220void DwarfUnit::addUInt(DIEValueList &Die, dwarf::Attribute Attribute,221std::optional<dwarf::Form> Form, uint64_t Integer) {222if (!Form)223Form = DIEInteger::BestForm(false, Integer);224assert(Form != dwarf::DW_FORM_implicit_const &&225"DW_FORM_implicit_const is used only for signed integers");226addAttribute(Die, Attribute, *Form, DIEInteger(Integer));227}228229void DwarfUnit::addUInt(DIEValueList &Block, dwarf::Form Form,230uint64_t Integer) {231addUInt(Block, (dwarf::Attribute)0, Form, Integer);232}233234void DwarfUnit::addSInt(DIEValueList &Die, dwarf::Attribute Attribute,235std::optional<dwarf::Form> Form, int64_t Integer) {236if (!Form)237Form = DIEInteger::BestForm(true, Integer);238addAttribute(Die, Attribute, *Form, DIEInteger(Integer));239}240241void DwarfUnit::addSInt(DIELoc &Die, std::optional<dwarf::Form> Form,242int64_t Integer) {243addSInt(Die, (dwarf::Attribute)0, Form, Integer);244}245246void DwarfUnit::addString(DIE &Die, dwarf::Attribute Attribute,247StringRef String) {248if (CUNode->isDebugDirectivesOnly())249return;250251if (DD->useInlineStrings()) {252addAttribute(Die, Attribute, dwarf::DW_FORM_string,253new (DIEValueAllocator)254DIEInlineString(String, DIEValueAllocator));255return;256}257dwarf::Form IxForm =258isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp;259260auto StringPoolEntry =261useSegmentedStringOffsetsTable() || IxForm == dwarf::DW_FORM_GNU_str_index262? DU->getStringPool().getIndexedEntry(*Asm, String)263: DU->getStringPool().getEntry(*Asm, String);264265// For DWARF v5 and beyond, use the smallest strx? form possible.266if (useSegmentedStringOffsetsTable()) {267IxForm = dwarf::DW_FORM_strx1;268unsigned Index = StringPoolEntry.getIndex();269if (Index > 0xffffff)270IxForm = dwarf::DW_FORM_strx4;271else if (Index > 0xffff)272IxForm = dwarf::DW_FORM_strx3;273else if (Index > 0xff)274IxForm = dwarf::DW_FORM_strx2;275}276addAttribute(Die, Attribute, IxForm, DIEString(StringPoolEntry));277}278279void DwarfUnit::addLabel(DIEValueList &Die, dwarf::Attribute Attribute,280dwarf::Form Form, const MCSymbol *Label) {281addAttribute(Die, Attribute, Form, DIELabel(Label));282}283284void DwarfUnit::addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label) {285addLabel(Die, (dwarf::Attribute)0, Form, Label);286}287288void DwarfUnit::addSectionOffset(DIE &Die, dwarf::Attribute Attribute,289uint64_t Integer) {290addUInt(Die, Attribute, DD->getDwarfSectionOffsetForm(), Integer);291}292293unsigned DwarfTypeUnit::getOrCreateSourceID(const DIFile *File) {294if (!SplitLineTable)295return getCU().getOrCreateSourceID(File);296if (!UsedLineTable) {297UsedLineTable = true;298// This is a split type unit that needs a line table.299addSectionOffset(getUnitDie(), dwarf::DW_AT_stmt_list, 0);300}301return SplitLineTable->getFile(302File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),303Asm->OutContext.getDwarfVersion(), File->getSource());304}305306void DwarfUnit::addPoolOpAddress(DIEValueList &Die, const MCSymbol *Label) {307bool UseAddrOffsetFormOrExpressions =308DD->useAddrOffsetForm() || DD->useAddrOffsetExpressions();309310const MCSymbol *Base = nullptr;311if (Label->isInSection() && UseAddrOffsetFormOrExpressions)312Base = DD->getSectionLabel(&Label->getSection());313314uint32_t Index = DD->getAddressPool().getIndex(Base ? Base : Label);315316if (DD->getDwarfVersion() >= 5) {317addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addrx);318addUInt(Die, dwarf::DW_FORM_addrx, Index);319} else {320addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index);321addUInt(Die, dwarf::DW_FORM_GNU_addr_index, Index);322}323324if (Base && Base != Label) {325addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_const4u);326addLabelDelta(Die, (dwarf::Attribute)0, Label, Base);327addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);328}329}330331void DwarfUnit::addOpAddress(DIELoc &Die, const MCSymbol *Sym) {332if (DD->getDwarfVersion() >= 5) {333addPoolOpAddress(Die, Sym);334return;335}336337if (DD->useSplitDwarf()) {338addPoolOpAddress(Die, Sym);339return;340}341342addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);343addLabel(Die, dwarf::DW_FORM_addr, Sym);344}345346void DwarfUnit::addLabelDelta(DIEValueList &Die, dwarf::Attribute Attribute,347const MCSymbol *Hi, const MCSymbol *Lo) {348addAttribute(Die, Attribute, dwarf::DW_FORM_data4,349new (DIEValueAllocator) DIEDelta(Hi, Lo));350}351352void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry) {353addDIEEntry(Die, Attribute, DIEEntry(Entry));354}355356void DwarfUnit::addDIETypeSignature(DIE &Die, uint64_t Signature) {357// Flag the type unit reference as a declaration so that if it contains358// members (implicit special members, static data member definitions, member359// declarations for definitions in this CU, etc) consumers don't get confused360// and think this is a full definition.361addFlag(Die, dwarf::DW_AT_declaration);362363addAttribute(Die, dwarf::DW_AT_signature, dwarf::DW_FORM_ref_sig8,364DIEInteger(Signature));365}366367void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute,368DIEEntry Entry) {369const DIEUnit *CU = Die.getUnit();370const DIEUnit *EntryCU = Entry.getEntry().getUnit();371if (!CU)372// We assume that Die belongs to this CU, if it is not linked to any CU yet.373CU = getUnitDie().getUnit();374if (!EntryCU)375EntryCU = getUnitDie().getUnit();376assert(EntryCU == CU || !DD->useSplitDwarf() || DD->shareAcrossDWOCUs() ||377!static_cast<const DwarfUnit*>(CU)->isDwoUnit());378addAttribute(Die, Attribute,379EntryCU == CU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr,380Entry);381}382383DIE &DwarfUnit::createAndAddDIE(dwarf::Tag Tag, DIE &Parent, const DINode *N) {384DIE &Die = Parent.addChild(DIE::get(DIEValueAllocator, Tag));385if (N)386insertDIE(N, &Die);387return Die;388}389390void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc) {391Loc->computeSize(Asm->getDwarfFormParams());392DIELocs.push_back(Loc); // Memoize so we can call the destructor later on.393addAttribute(Die, Attribute, Loc->BestForm(DD->getDwarfVersion()), Loc);394}395396void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, dwarf::Form Form,397DIEBlock *Block) {398Block->computeSize(Asm->getDwarfFormParams());399DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.400addAttribute(Die, Attribute, Form, Block);401}402403void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute,404DIEBlock *Block) {405addBlock(Die, Attribute, Block->BestForm(), Block);406}407408void DwarfUnit::addSourceLine(DIE &Die, unsigned Line, const DIFile *File) {409if (Line == 0)410return;411412unsigned FileID = getOrCreateSourceID(File);413addUInt(Die, dwarf::DW_AT_decl_file, std::nullopt, FileID);414addUInt(Die, dwarf::DW_AT_decl_line, std::nullopt, Line);415}416417void DwarfUnit::addSourceLine(DIE &Die, const DILocalVariable *V) {418assert(V);419420addSourceLine(Die, V->getLine(), V->getFile());421}422423void DwarfUnit::addSourceLine(DIE &Die, const DIGlobalVariable *G) {424assert(G);425426addSourceLine(Die, G->getLine(), G->getFile());427}428429void DwarfUnit::addSourceLine(DIE &Die, const DISubprogram *SP) {430assert(SP);431432addSourceLine(Die, SP->getLine(), SP->getFile());433}434435void DwarfUnit::addSourceLine(DIE &Die, const DILabel *L) {436assert(L);437438addSourceLine(Die, L->getLine(), L->getFile());439}440441void DwarfUnit::addSourceLine(DIE &Die, const DIType *Ty) {442assert(Ty);443444addSourceLine(Die, Ty->getLine(), Ty->getFile());445}446447void DwarfUnit::addSourceLine(DIE &Die, const DIObjCProperty *Ty) {448assert(Ty);449450addSourceLine(Die, Ty->getLine(), Ty->getFile());451}452453void DwarfUnit::addConstantFPValue(DIE &Die, const ConstantFP *CFP) {454// Pass this down to addConstantValue as an unsigned bag of bits.455addConstantValue(Die, CFP->getValueAPF().bitcastToAPInt(), true);456}457458void DwarfUnit::addConstantValue(DIE &Die, const ConstantInt *CI,459const DIType *Ty) {460addConstantValue(Die, CI->getValue(), Ty);461}462463void DwarfUnit::addConstantValue(DIE &Die, uint64_t Val, const DIType *Ty) {464addConstantValue(Die, DD->isUnsignedDIType(Ty), Val);465}466467void DwarfUnit::addConstantValue(DIE &Die, bool Unsigned, uint64_t Val) {468// FIXME: This is a bit conservative/simple - it emits negative values always469// sign extended to 64 bits rather than minimizing the number of bytes.470addUInt(Die, dwarf::DW_AT_const_value,471Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata, Val);472}473474void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, const DIType *Ty) {475addConstantValue(Die, Val, DD->isUnsignedDIType(Ty));476}477478void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, bool Unsigned) {479unsigned CIBitWidth = Val.getBitWidth();480if (CIBitWidth <= 64) {481addConstantValue(Die, Unsigned,482Unsigned ? Val.getZExtValue() : Val.getSExtValue());483return;484}485486DIEBlock *Block = new (DIEValueAllocator) DIEBlock;487488// Get the raw data form of the large APInt.489const uint64_t *Ptr64 = Val.getRawData();490491int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.492bool LittleEndian = Asm->getDataLayout().isLittleEndian();493494// Output the constant to DWARF one byte at a time.495for (int i = 0; i < NumBytes; i++) {496uint8_t c;497if (LittleEndian)498c = Ptr64[i / 8] >> (8 * (i & 7));499else500c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));501addUInt(*Block, dwarf::DW_FORM_data1, c);502}503504addBlock(Die, dwarf::DW_AT_const_value, Block);505}506507void DwarfUnit::addLinkageName(DIE &Die, StringRef LinkageName) {508if (!LinkageName.empty())509addString(Die,510DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name511: dwarf::DW_AT_MIPS_linkage_name,512GlobalValue::dropLLVMManglingEscape(LinkageName));513}514515void DwarfUnit::addTemplateParams(DIE &Buffer, DINodeArray TParams) {516// Add template parameters.517for (const auto *Element : TParams) {518if (auto *TTP = dyn_cast<DITemplateTypeParameter>(Element))519constructTemplateTypeParameterDIE(Buffer, TTP);520else if (auto *TVP = dyn_cast<DITemplateValueParameter>(Element))521constructTemplateValueParameterDIE(Buffer, TVP);522}523}524525/// Add thrown types.526void DwarfUnit::addThrownTypes(DIE &Die, DINodeArray ThrownTypes) {527for (const auto *Ty : ThrownTypes) {528DIE &TT = createAndAddDIE(dwarf::DW_TAG_thrown_type, Die);529addType(TT, cast<DIType>(Ty));530}531}532533void DwarfUnit::addAccess(DIE &Die, DINode::DIFlags Flags) {534if ((Flags & DINode::FlagAccessibility) == DINode::FlagProtected)535addUInt(Die, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,536dwarf::DW_ACCESS_protected);537else if ((Flags & DINode::FlagAccessibility) == DINode::FlagPrivate)538addUInt(Die, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,539dwarf::DW_ACCESS_private);540else if ((Flags & DINode::FlagAccessibility) == DINode::FlagPublic)541addUInt(Die, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,542dwarf::DW_ACCESS_public);543}544545DIE *DwarfUnit::getOrCreateContextDIE(const DIScope *Context) {546if (!Context || isa<DIFile>(Context) || isa<DICompileUnit>(Context))547return &getUnitDie();548if (auto *T = dyn_cast<DIType>(Context))549return getOrCreateTypeDIE(T);550if (auto *NS = dyn_cast<DINamespace>(Context))551return getOrCreateNameSpace(NS);552if (auto *SP = dyn_cast<DISubprogram>(Context))553return getOrCreateSubprogramDIE(SP);554if (auto *M = dyn_cast<DIModule>(Context))555return getOrCreateModule(M);556return getDIE(Context);557}558559DIE *DwarfUnit::createTypeDIE(const DICompositeType *Ty) {560auto *Context = Ty->getScope();561DIE *ContextDIE = getOrCreateContextDIE(Context);562563if (DIE *TyDIE = getDIE(Ty))564return TyDIE;565566// Create new type.567DIE &TyDIE = createAndAddDIE(Ty->getTag(), *ContextDIE, Ty);568569constructTypeDIE(TyDIE, cast<DICompositeType>(Ty));570571updateAcceleratorTables(Context, Ty, TyDIE);572return &TyDIE;573}574575DIE *DwarfUnit::createTypeDIE(const DIScope *Context, DIE &ContextDIE,576const DIType *Ty) {577// Create new type.578DIE &TyDIE = createAndAddDIE(Ty->getTag(), ContextDIE, Ty);579580auto construct = [&](const auto *Ty) {581updateAcceleratorTables(Context, Ty, TyDIE);582constructTypeDIE(TyDIE, Ty);583};584585if (auto *CTy = dyn_cast<DICompositeType>(Ty)) {586if (DD->generateTypeUnits() && !Ty->isForwardDecl() &&587(Ty->getRawName() || CTy->getRawIdentifier())) {588// Skip updating the accelerator tables since this is not the full type.589if (MDString *TypeId = CTy->getRawIdentifier()) {590addGlobalType(Ty, TyDIE, Context);591DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy);592} else {593updateAcceleratorTables(Context, Ty, TyDIE);594finishNonUnitTypeDIE(TyDIE, CTy);595}596return &TyDIE;597}598construct(CTy);599} else if (auto *BT = dyn_cast<DIBasicType>(Ty))600construct(BT);601else if (auto *ST = dyn_cast<DIStringType>(Ty))602construct(ST);603else if (auto *STy = dyn_cast<DISubroutineType>(Ty))604construct(STy);605else606construct(cast<DIDerivedType>(Ty));607608return &TyDIE;609}610611DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) {612if (!TyNode)613return nullptr;614615auto *Ty = cast<DIType>(TyNode);616617// DW_TAG_restrict_type is not supported in DWARF2618if (Ty->getTag() == dwarf::DW_TAG_restrict_type && DD->getDwarfVersion() <= 2)619return getOrCreateTypeDIE(cast<DIDerivedType>(Ty)->getBaseType());620621// DW_TAG_atomic_type is not supported in DWARF < 5622if (Ty->getTag() == dwarf::DW_TAG_atomic_type && DD->getDwarfVersion() < 5)623return getOrCreateTypeDIE(cast<DIDerivedType>(Ty)->getBaseType());624625// Construct the context before querying for the existence of the DIE in case626// such construction creates the DIE.627auto *Context = Ty->getScope();628DIE *ContextDIE = getOrCreateContextDIE(Context);629assert(ContextDIE);630631if (DIE *TyDIE = getDIE(Ty))632return TyDIE;633634return static_cast<DwarfUnit *>(ContextDIE->getUnit())635->createTypeDIE(Context, *ContextDIE, Ty);636}637638void DwarfUnit::updateAcceleratorTables(const DIScope *Context,639const DIType *Ty, const DIE &TyDIE) {640if (Ty->getName().empty())641return;642if (Ty->isForwardDecl())643return;644645// add temporary record for this type to be added later646647bool IsImplementation = false;648if (auto *CT = dyn_cast<DICompositeType>(Ty)) {649// A runtime language of 0 actually means C/C++ and that any650// non-negative value is some version of Objective-C/C++.651IsImplementation = CT->getRuntimeLang() == 0 || CT->isObjcClassComplete();652}653unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0;654DD->addAccelType(*this, CUNode->getNameTableKind(), Ty->getName(), TyDIE,655Flags);656657addGlobalType(Ty, TyDIE, Context);658}659660void DwarfUnit::addGlobalType(const DIType *Ty, const DIE &TyDIE,661const DIScope *Context) {662if (!Context || isa<DICompileUnit>(Context) || isa<DIFile>(Context) ||663isa<DINamespace>(Context) || isa<DICommonBlock>(Context))664addGlobalTypeImpl(Ty, TyDIE, Context);665}666667void DwarfUnit::addType(DIE &Entity, const DIType *Ty,668dwarf::Attribute Attribute) {669assert(Ty && "Trying to add a type that doesn't exist?");670addDIEEntry(Entity, Attribute, DIEEntry(*getOrCreateTypeDIE(Ty)));671}672673std::string DwarfUnit::getParentContextString(const DIScope *Context) const {674if (!Context)675return "";676677// FIXME: Decide whether to implement this for non-C++ languages.678if (!dwarf::isCPlusPlus((dwarf::SourceLanguage)getLanguage()))679return "";680681std::string CS;682SmallVector<const DIScope *, 1> Parents;683while (!isa<DICompileUnit>(Context)) {684Parents.push_back(Context);685if (const DIScope *S = Context->getScope())686Context = S;687else688// Structure, etc types will have a NULL context if they're at the top689// level.690break;691}692693// Reverse iterate over our list to go from the outermost construct to the694// innermost.695for (const DIScope *Ctx : llvm::reverse(Parents)) {696StringRef Name = Ctx->getName();697if (Name.empty() && isa<DINamespace>(Ctx))698Name = "(anonymous namespace)";699if (!Name.empty()) {700CS += Name;701CS += "::";702}703}704return CS;705}706707void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) {708// Get core information.709StringRef Name = BTy->getName();710// Add name if not anonymous or intermediate type.711if (!Name.empty())712addString(Buffer, dwarf::DW_AT_name, Name);713714// An unspecified type only has a name attribute.715if (BTy->getTag() == dwarf::DW_TAG_unspecified_type)716return;717718if (BTy->getTag() != dwarf::DW_TAG_string_type)719addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,720BTy->getEncoding());721722uint64_t Size = BTy->getSizeInBits() >> 3;723addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);724725if (BTy->isBigEndian())726addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_big);727else if (BTy->isLittleEndian())728addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_little);729}730731void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIStringType *STy) {732// Get core information.733StringRef Name = STy->getName();734// Add name if not anonymous or intermediate type.735if (!Name.empty())736addString(Buffer, dwarf::DW_AT_name, Name);737738if (DIVariable *Var = STy->getStringLength()) {739if (auto *VarDIE = getDIE(Var))740addDIEEntry(Buffer, dwarf::DW_AT_string_length, *VarDIE);741} else if (DIExpression *Expr = STy->getStringLengthExp()) {742DIELoc *Loc = new (DIEValueAllocator) DIELoc;743DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);744// This is to describe the memory location of the745// length of a Fortran deferred length string, so746// lock it down as such.747DwarfExpr.setMemoryLocationKind();748DwarfExpr.addExpression(Expr);749addBlock(Buffer, dwarf::DW_AT_string_length, DwarfExpr.finalize());750} else {751uint64_t Size = STy->getSizeInBits() >> 3;752addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);753}754755if (DIExpression *Expr = STy->getStringLocationExp()) {756DIELoc *Loc = new (DIEValueAllocator) DIELoc;757DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);758// This is to describe the memory location of the759// string, so lock it down as such.760DwarfExpr.setMemoryLocationKind();761DwarfExpr.addExpression(Expr);762addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize());763}764765if (STy->getEncoding()) {766// For eventual Unicode support.767addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,768STy->getEncoding());769}770}771772void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) {773// Get core information.774StringRef Name = DTy->getName();775uint64_t Size = DTy->getSizeInBits() >> 3;776uint16_t Tag = Buffer.getTag();777778// Map to main type, void will not have a type.779const DIType *FromTy = DTy->getBaseType();780if (FromTy)781addType(Buffer, FromTy);782783// Add name if not anonymous or intermediate type.784if (!Name.empty())785addString(Buffer, dwarf::DW_AT_name, Name);786787addAnnotation(Buffer, DTy->getAnnotations());788789// If alignment is specified for a typedef , create and insert DW_AT_alignment790// attribute in DW_TAG_typedef DIE.791if (Tag == dwarf::DW_TAG_typedef && DD->getDwarfVersion() >= 5) {792uint32_t AlignInBytes = DTy->getAlignInBytes();793if (AlignInBytes > 0)794addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,795AlignInBytes);796}797798// Add size if non-zero (derived types might be zero-sized.)799if (Size && Tag != dwarf::DW_TAG_pointer_type800&& Tag != dwarf::DW_TAG_ptr_to_member_type801&& Tag != dwarf::DW_TAG_reference_type802&& Tag != dwarf::DW_TAG_rvalue_reference_type)803addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);804805if (Tag == dwarf::DW_TAG_ptr_to_member_type)806addDIEEntry(Buffer, dwarf::DW_AT_containing_type,807*getOrCreateTypeDIE(cast<DIDerivedType>(DTy)->getClassType()));808809addAccess(Buffer, DTy->getFlags());810811// Add source line info if available and TyDesc is not a forward declaration.812if (!DTy->isForwardDecl())813addSourceLine(Buffer, DTy);814815// If DWARF address space value is other than None, add it. The IR816// verifier checks that DWARF address space only exists for pointer817// or reference types.818if (DTy->getDWARFAddressSpace())819addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4,820*DTy->getDWARFAddressSpace());821822// Add template alias template parameters.823if (Tag == dwarf::DW_TAG_template_alias)824addTemplateParams(Buffer, DTy->getTemplateParams());825826if (auto PtrAuthData = DTy->getPtrAuthData()) {827addUInt(Buffer, dwarf::DW_AT_LLVM_ptrauth_key, dwarf::DW_FORM_data1,828PtrAuthData->key());829if (PtrAuthData->isAddressDiscriminated())830addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_address_discriminated);831addUInt(Buffer, dwarf::DW_AT_LLVM_ptrauth_extra_discriminator,832dwarf::DW_FORM_data2, PtrAuthData->extraDiscriminator());833if (PtrAuthData->isaPointer())834addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_isa_pointer);835if (PtrAuthData->authenticatesNullValues())836addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_authenticates_null_values);837}838}839840void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args) {841for (unsigned i = 1, N = Args.size(); i < N; ++i) {842const DIType *Ty = Args[i];843if (!Ty) {844assert(i == N-1 && "Unspecified parameter must be the last argument");845createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, Buffer);846} else {847DIE &Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, Buffer);848addType(Arg, Ty);849if (Ty->isArtificial())850addFlag(Arg, dwarf::DW_AT_artificial);851}852}853}854855void DwarfUnit::constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy) {856// Add return type. A void return won't have a type.857auto Elements = cast<DISubroutineType>(CTy)->getTypeArray();858if (Elements.size())859if (auto RTy = Elements[0])860addType(Buffer, RTy);861862bool isPrototyped = true;863if (Elements.size() == 2 && !Elements[1])864isPrototyped = false;865866constructSubprogramArguments(Buffer, Elements);867868// Add prototype flag if we're dealing with a C language and the function has869// been prototyped.870if (isPrototyped && dwarf::isC((dwarf::SourceLanguage)getLanguage()))871addFlag(Buffer, dwarf::DW_AT_prototyped);872873// Add a DW_AT_calling_convention if this has an explicit convention.874if (CTy->getCC() && CTy->getCC() != dwarf::DW_CC_normal)875addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,876CTy->getCC());877878if (CTy->isLValueReference())879addFlag(Buffer, dwarf::DW_AT_reference);880881if (CTy->isRValueReference())882addFlag(Buffer, dwarf::DW_AT_rvalue_reference);883}884885void DwarfUnit::addAnnotation(DIE &Buffer, DINodeArray Annotations) {886if (!Annotations)887return;888889for (const Metadata *Annotation : Annotations->operands()) {890const MDNode *MD = cast<MDNode>(Annotation);891const MDString *Name = cast<MDString>(MD->getOperand(0));892const auto &Value = MD->getOperand(1);893894DIE &AnnotationDie = createAndAddDIE(dwarf::DW_TAG_LLVM_annotation, Buffer);895addString(AnnotationDie, dwarf::DW_AT_name, Name->getString());896if (const auto *Data = dyn_cast<MDString>(Value))897addString(AnnotationDie, dwarf::DW_AT_const_value, Data->getString());898else if (const auto *Data = dyn_cast<ConstantAsMetadata>(Value))899addConstantValue(AnnotationDie, Data->getValue()->getUniqueInteger(),900/*Unsigned=*/true);901else902assert(false && "Unsupported annotation value type");903}904}905906void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {907// Add name if not anonymous or intermediate type.908StringRef Name = CTy->getName();909910uint64_t Size = CTy->getSizeInBits() >> 3;911uint16_t Tag = Buffer.getTag();912913switch (Tag) {914case dwarf::DW_TAG_array_type:915constructArrayTypeDIE(Buffer, CTy);916break;917case dwarf::DW_TAG_enumeration_type:918constructEnumTypeDIE(Buffer, CTy);919break;920case dwarf::DW_TAG_variant_part:921case dwarf::DW_TAG_structure_type:922case dwarf::DW_TAG_union_type:923case dwarf::DW_TAG_class_type:924case dwarf::DW_TAG_namelist: {925// Emit the discriminator for a variant part.926DIDerivedType *Discriminator = nullptr;927if (Tag == dwarf::DW_TAG_variant_part) {928Discriminator = CTy->getDiscriminator();929if (Discriminator) {930// DWARF says:931// If the variant part has a discriminant, the discriminant is932// represented by a separate debugging information entry which is933// a child of the variant part entry.934DIE &DiscMember = constructMemberDIE(Buffer, Discriminator);935addDIEEntry(Buffer, dwarf::DW_AT_discr, DiscMember);936}937}938939// Add template parameters to a class, structure or union types.940if (Tag == dwarf::DW_TAG_class_type ||941Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)942addTemplateParams(Buffer, CTy->getTemplateParams());943944// Add elements to structure type.945DINodeArray Elements = CTy->getElements();946for (const auto *Element : Elements) {947if (!Element)948continue;949if (auto *SP = dyn_cast<DISubprogram>(Element))950getOrCreateSubprogramDIE(SP);951else if (auto *DDTy = dyn_cast<DIDerivedType>(Element)) {952if (DDTy->getTag() == dwarf::DW_TAG_friend) {953DIE &ElemDie = createAndAddDIE(dwarf::DW_TAG_friend, Buffer);954addType(ElemDie, DDTy->getBaseType(), dwarf::DW_AT_friend);955} else if (DDTy->isStaticMember()) {956getOrCreateStaticMemberDIE(DDTy);957} else if (Tag == dwarf::DW_TAG_variant_part) {958// When emitting a variant part, wrap each member in959// DW_TAG_variant.960DIE &Variant = createAndAddDIE(dwarf::DW_TAG_variant, Buffer);961if (const ConstantInt *CI =962dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) {963if (DD->isUnsignedDIType(Discriminator->getBaseType()))964addUInt(Variant, dwarf::DW_AT_discr_value, std::nullopt,965CI->getZExtValue());966else967addSInt(Variant, dwarf::DW_AT_discr_value, std::nullopt,968CI->getSExtValue());969}970constructMemberDIE(Variant, DDTy);971} else {972constructMemberDIE(Buffer, DDTy);973}974} else if (auto *Property = dyn_cast<DIObjCProperty>(Element)) {975DIE &ElemDie = createAndAddDIE(Property->getTag(), Buffer);976StringRef PropertyName = Property->getName();977addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);978if (Property->getType())979addType(ElemDie, Property->getType());980addSourceLine(ElemDie, Property);981StringRef GetterName = Property->getGetterName();982if (!GetterName.empty())983addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName);984StringRef SetterName = Property->getSetterName();985if (!SetterName.empty())986addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName);987if (unsigned PropertyAttributes = Property->getAttributes())988addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, std::nullopt,989PropertyAttributes);990} else if (auto *Composite = dyn_cast<DICompositeType>(Element)) {991if (Composite->getTag() == dwarf::DW_TAG_variant_part) {992DIE &VariantPart = createAndAddDIE(Composite->getTag(), Buffer);993constructTypeDIE(VariantPart, Composite);994}995} else if (Tag == dwarf::DW_TAG_namelist) {996auto *Var = dyn_cast<DINode>(Element);997auto *VarDIE = getDIE(Var);998if (VarDIE) {999DIE &ItemDie = createAndAddDIE(dwarf::DW_TAG_namelist_item, Buffer);1000addDIEEntry(ItemDie, dwarf::DW_AT_namelist_item, *VarDIE);1001}1002}1003}10041005if (CTy->isAppleBlockExtension())1006addFlag(Buffer, dwarf::DW_AT_APPLE_block);10071008if (CTy->getExportSymbols())1009addFlag(Buffer, dwarf::DW_AT_export_symbols);10101011// This is outside the DWARF spec, but GDB expects a DW_AT_containing_type1012// inside C++ composite types to point to the base class with the vtable.1013// Rust uses DW_AT_containing_type to link a vtable to the type1014// for which it was created.1015if (auto *ContainingType = CTy->getVTableHolder())1016addDIEEntry(Buffer, dwarf::DW_AT_containing_type,1017*getOrCreateTypeDIE(ContainingType));10181019if (CTy->isObjcClassComplete())1020addFlag(Buffer, dwarf::DW_AT_APPLE_objc_complete_type);10211022// Add the type's non-standard calling convention.1023// DW_CC_pass_by_value/DW_CC_pass_by_reference are introduced in DWARF 5.1024if (!Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= 5) {1025uint8_t CC = 0;1026if (CTy->isTypePassByValue())1027CC = dwarf::DW_CC_pass_by_value;1028else if (CTy->isTypePassByReference())1029CC = dwarf::DW_CC_pass_by_reference;1030if (CC)1031addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,1032CC);1033}1034break;1035}1036default:1037break;1038}10391040// Add name if not anonymous or intermediate type.1041if (!Name.empty())1042addString(Buffer, dwarf::DW_AT_name, Name);10431044addAnnotation(Buffer, CTy->getAnnotations());10451046if (Tag == dwarf::DW_TAG_enumeration_type ||1047Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type ||1048Tag == dwarf::DW_TAG_union_type) {1049// Add size if non-zero (derived types might be zero-sized.)1050// Ignore the size if it's a non-enum forward decl.1051// TODO: Do we care about size for enum forward declarations?1052if (Size &&1053(!CTy->isForwardDecl() || Tag == dwarf::DW_TAG_enumeration_type))1054addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);1055else if (!CTy->isForwardDecl())1056// Add zero size if it is not a forward declaration.1057addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, 0);10581059// If we're a forward decl, say so.1060if (CTy->isForwardDecl())1061addFlag(Buffer, dwarf::DW_AT_declaration);10621063// Add accessibility info if available.1064addAccess(Buffer, CTy->getFlags());10651066// Add source line info if available.1067if (!CTy->isForwardDecl())1068addSourceLine(Buffer, CTy);10691070// No harm in adding the runtime language to the declaration.1071unsigned RLang = CTy->getRuntimeLang();1072if (RLang)1073addUInt(Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1,1074RLang);10751076// Add align info if available.1077if (uint32_t AlignInBytes = CTy->getAlignInBytes())1078addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,1079AlignInBytes);1080}1081}10821083void DwarfUnit::constructTemplateTypeParameterDIE(1084DIE &Buffer, const DITemplateTypeParameter *TP) {1085DIE &ParamDIE =1086createAndAddDIE(dwarf::DW_TAG_template_type_parameter, Buffer);1087// Add the type if it exists, it could be void and therefore no type.1088if (TP->getType())1089addType(ParamDIE, TP->getType());1090if (!TP->getName().empty())1091addString(ParamDIE, dwarf::DW_AT_name, TP->getName());1092if (TP->isDefault() && isCompatibleWithVersion(5))1093addFlag(ParamDIE, dwarf::DW_AT_default_value);1094}10951096void DwarfUnit::constructTemplateValueParameterDIE(1097DIE &Buffer, const DITemplateValueParameter *VP) {1098DIE &ParamDIE = createAndAddDIE(VP->getTag(), Buffer);10991100// Add the type if there is one, template template and template parameter1101// packs will not have a type.1102if (VP->getTag() == dwarf::DW_TAG_template_value_parameter)1103addType(ParamDIE, VP->getType());1104if (!VP->getName().empty())1105addString(ParamDIE, dwarf::DW_AT_name, VP->getName());1106if (VP->isDefault() && isCompatibleWithVersion(5))1107addFlag(ParamDIE, dwarf::DW_AT_default_value);1108if (Metadata *Val = VP->getValue()) {1109if (ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(Val))1110addConstantValue(ParamDIE, CI, VP->getType());1111else if (GlobalValue *GV = mdconst::dyn_extract<GlobalValue>(Val)) {1112// We cannot describe the location of dllimport'd entities: the1113// computation of their address requires loads from the IAT.1114if (!GV->hasDLLImportStorageClass()) {1115// For declaration non-type template parameters (such as global values1116// and functions)1117DIELoc *Loc = new (DIEValueAllocator) DIELoc;1118addOpAddress(*Loc, Asm->getSymbol(GV));1119// Emit DW_OP_stack_value to use the address as the immediate value of1120// the parameter, rather than a pointer to it.1121addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);1122addBlock(ParamDIE, dwarf::DW_AT_location, Loc);1123}1124} else if (VP->getTag() == dwarf::DW_TAG_GNU_template_template_param) {1125assert(isa<MDString>(Val));1126addString(ParamDIE, dwarf::DW_AT_GNU_template_name,1127cast<MDString>(Val)->getString());1128} else if (VP->getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {1129addTemplateParams(ParamDIE, cast<MDTuple>(Val));1130}1131}1132}11331134DIE *DwarfUnit::getOrCreateNameSpace(const DINamespace *NS) {1135// Construct the context before querying for the existence of the DIE in case1136// such construction creates the DIE.1137DIE *ContextDIE = getOrCreateContextDIE(NS->getScope());11381139if (DIE *NDie = getDIE(NS))1140return NDie;1141DIE &NDie = createAndAddDIE(dwarf::DW_TAG_namespace, *ContextDIE, NS);11421143StringRef Name = NS->getName();1144if (!Name.empty())1145addString(NDie, dwarf::DW_AT_name, NS->getName());1146else1147Name = "(anonymous namespace)";1148DD->addAccelNamespace(*this, CUNode->getNameTableKind(), Name, NDie);1149addGlobalName(Name, NDie, NS->getScope());1150if (NS->getExportSymbols())1151addFlag(NDie, dwarf::DW_AT_export_symbols);1152return &NDie;1153}11541155DIE *DwarfUnit::getOrCreateModule(const DIModule *M) {1156// Construct the context before querying for the existence of the DIE in case1157// such construction creates the DIE.1158DIE *ContextDIE = getOrCreateContextDIE(M->getScope());11591160if (DIE *MDie = getDIE(M))1161return MDie;1162DIE &MDie = createAndAddDIE(dwarf::DW_TAG_module, *ContextDIE, M);11631164if (!M->getName().empty()) {1165addString(MDie, dwarf::DW_AT_name, M->getName());1166addGlobalName(M->getName(), MDie, M->getScope());1167}1168if (!M->getConfigurationMacros().empty())1169addString(MDie, dwarf::DW_AT_LLVM_config_macros,1170M->getConfigurationMacros());1171if (!M->getIncludePath().empty())1172addString(MDie, dwarf::DW_AT_LLVM_include_path, M->getIncludePath());1173if (!M->getAPINotesFile().empty())1174addString(MDie, dwarf::DW_AT_LLVM_apinotes, M->getAPINotesFile());1175if (M->getFile())1176addUInt(MDie, dwarf::DW_AT_decl_file, std::nullopt,1177getOrCreateSourceID(M->getFile()));1178if (M->getLineNo())1179addUInt(MDie, dwarf::DW_AT_decl_line, std::nullopt, M->getLineNo());1180if (M->getIsDecl())1181addFlag(MDie, dwarf::DW_AT_declaration);11821183return &MDie;1184}11851186DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) {1187// Construct the context before querying for the existence of the DIE in case1188// such construction creates the DIE (as is the case for member function1189// declarations).1190DIE *ContextDIE =1191Minimal ? &getUnitDie() : getOrCreateContextDIE(SP->getScope());11921193if (DIE *SPDie = getDIE(SP))1194return SPDie;11951196if (auto *SPDecl = SP->getDeclaration()) {1197if (!Minimal) {1198// Add subprogram definitions to the CU die directly.1199ContextDIE = &getUnitDie();1200// Build the decl now to ensure it precedes the definition.1201getOrCreateSubprogramDIE(SPDecl);1202}1203}12041205// DW_TAG_inlined_subroutine may refer to this DIE.1206DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP);12071208// Stop here and fill this in later, depending on whether or not this1209// subprogram turns out to have inlined instances or not.1210if (SP->isDefinition())1211return &SPDie;12121213static_cast<DwarfUnit *>(SPDie.getUnit())1214->applySubprogramAttributes(SP, SPDie);1215return &SPDie;1216}12171218bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP,1219DIE &SPDie, bool Minimal) {1220DIE *DeclDie = nullptr;1221StringRef DeclLinkageName;1222if (auto *SPDecl = SP->getDeclaration()) {1223if (!Minimal) {1224DITypeRefArray DeclArgs, DefinitionArgs;1225DeclArgs = SPDecl->getType()->getTypeArray();1226DefinitionArgs = SP->getType()->getTypeArray();12271228if (DeclArgs.size() && DefinitionArgs.size())1229if (DefinitionArgs[0] != nullptr && DeclArgs[0] != DefinitionArgs[0])1230addType(SPDie, DefinitionArgs[0]);12311232DeclDie = getDIE(SPDecl);1233assert(DeclDie && "This DIE should've already been constructed when the "1234"definition DIE was created in "1235"getOrCreateSubprogramDIE");1236// Look at the Decl's linkage name only if we emitted it.1237if (DD->useAllLinkageNames())1238DeclLinkageName = SPDecl->getLinkageName();1239unsigned DeclID = getOrCreateSourceID(SPDecl->getFile());1240unsigned DefID = getOrCreateSourceID(SP->getFile());1241if (DeclID != DefID)1242addUInt(SPDie, dwarf::DW_AT_decl_file, std::nullopt, DefID);12431244if (SP->getLine() != SPDecl->getLine())1245addUInt(SPDie, dwarf::DW_AT_decl_line, std::nullopt, SP->getLine());1246}1247}12481249// Add function template parameters.1250addTemplateParams(SPDie, SP->getTemplateParams());12511252// Add the linkage name if we have one and it isn't in the Decl.1253StringRef LinkageName = SP->getLinkageName();1254assert(((LinkageName.empty() || DeclLinkageName.empty()) ||1255LinkageName == DeclLinkageName) &&1256"decl has a linkage name and it is different");1257if (DeclLinkageName.empty() &&1258// Always emit it for abstract subprograms.1259(DD->useAllLinkageNames() || DU->getAbstractScopeDIEs().lookup(SP)))1260addLinkageName(SPDie, LinkageName);12611262if (!DeclDie)1263return false;12641265// Refer to the function declaration where all the other attributes will be1266// found.1267addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie);1268return true;1269}12701271void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,1272bool SkipSPAttributes) {1273// If -fdebug-info-for-profiling is enabled, need to emit the subprogram1274// and its source location.1275bool SkipSPSourceLocation = SkipSPAttributes &&1276!CUNode->getDebugInfoForProfiling();1277if (!SkipSPSourceLocation)1278if (applySubprogramDefinitionAttributes(SP, SPDie, SkipSPAttributes))1279return;12801281// Constructors and operators for anonymous aggregates do not have names.1282if (!SP->getName().empty())1283addString(SPDie, dwarf::DW_AT_name, SP->getName());12841285addAnnotation(SPDie, SP->getAnnotations());12861287if (!SkipSPSourceLocation)1288addSourceLine(SPDie, SP);12891290// Skip the rest of the attributes under -gmlt to save space.1291if (SkipSPAttributes)1292return;12931294// Add the prototype if we have a prototype and we have a C like1295// language.1296if (SP->isPrototyped() && dwarf::isC((dwarf::SourceLanguage)getLanguage()))1297addFlag(SPDie, dwarf::DW_AT_prototyped);12981299if (SP->isObjCDirect())1300addFlag(SPDie, dwarf::DW_AT_APPLE_objc_direct);13011302unsigned CC = 0;1303DITypeRefArray Args;1304if (const DISubroutineType *SPTy = SP->getType()) {1305Args = SPTy->getTypeArray();1306CC = SPTy->getCC();1307}13081309// Add a DW_AT_calling_convention if this has an explicit convention.1310if (CC && CC != dwarf::DW_CC_normal)1311addUInt(SPDie, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, CC);13121313// Add a return type. If this is a type like a C/C++ void type we don't add a1314// return type.1315if (Args.size())1316if (auto Ty = Args[0])1317addType(SPDie, Ty);13181319unsigned VK = SP->getVirtuality();1320if (VK) {1321addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);1322if (SP->getVirtualIndex() != -1u) {1323DIELoc *Block = getDIELoc();1324addUInt(*Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);1325addUInt(*Block, dwarf::DW_FORM_udata, SP->getVirtualIndex());1326addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, Block);1327}1328ContainingTypeMap.insert(std::make_pair(&SPDie, SP->getContainingType()));1329}13301331if (!SP->isDefinition()) {1332addFlag(SPDie, dwarf::DW_AT_declaration);13331334// Add arguments. Do not add arguments for subprogram definition. They will1335// be handled while processing variables.1336constructSubprogramArguments(SPDie, Args);1337}13381339addThrownTypes(SPDie, SP->getThrownTypes());13401341if (SP->isArtificial())1342addFlag(SPDie, dwarf::DW_AT_artificial);13431344if (!SP->isLocalToUnit())1345addFlag(SPDie, dwarf::DW_AT_external);13461347if (DD->useAppleExtensionAttributes()) {1348if (SP->isOptimized())1349addFlag(SPDie, dwarf::DW_AT_APPLE_optimized);13501351if (unsigned isa = Asm->getISAEncoding())1352addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);1353}13541355if (SP->isLValueReference())1356addFlag(SPDie, dwarf::DW_AT_reference);13571358if (SP->isRValueReference())1359addFlag(SPDie, dwarf::DW_AT_rvalue_reference);13601361if (SP->isNoReturn())1362addFlag(SPDie, dwarf::DW_AT_noreturn);13631364addAccess(SPDie, SP->getFlags());13651366if (SP->isExplicit())1367addFlag(SPDie, dwarf::DW_AT_explicit);13681369if (SP->isMainSubprogram())1370addFlag(SPDie, dwarf::DW_AT_main_subprogram);1371if (SP->isPure())1372addFlag(SPDie, dwarf::DW_AT_pure);1373if (SP->isElemental())1374addFlag(SPDie, dwarf::DW_AT_elemental);1375if (SP->isRecursive())1376addFlag(SPDie, dwarf::DW_AT_recursive);13771378if (!SP->getTargetFuncName().empty())1379addString(SPDie, dwarf::DW_AT_trampoline, SP->getTargetFuncName());13801381if (DD->getDwarfVersion() >= 5 && SP->isDeleted())1382addFlag(SPDie, dwarf::DW_AT_deleted);1383}13841385void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR,1386DIE *IndexTy) {1387DIE &DW_Subrange = createAndAddDIE(dwarf::DW_TAG_subrange_type, Buffer);1388addDIEEntry(DW_Subrange, dwarf::DW_AT_type, *IndexTy);13891390// The LowerBound value defines the lower bounds which is typically zero for1391// C/C++. The Count value is the number of elements. Values are 64 bit. If1392// Count == -1 then the array is unbounded and we do not emit1393// DW_AT_lower_bound and DW_AT_count attributes.1394int64_t DefaultLowerBound = getDefaultLowerBound();13951396auto AddBoundTypeEntry = [&](dwarf::Attribute Attr,1397DISubrange::BoundType Bound) -> void {1398if (auto *BV = dyn_cast_if_present<DIVariable *>(Bound)) {1399if (auto *VarDIE = getDIE(BV))1400addDIEEntry(DW_Subrange, Attr, *VarDIE);1401} else if (auto *BE = dyn_cast_if_present<DIExpression *>(Bound)) {1402DIELoc *Loc = new (DIEValueAllocator) DIELoc;1403DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);1404DwarfExpr.setMemoryLocationKind();1405DwarfExpr.addExpression(BE);1406addBlock(DW_Subrange, Attr, DwarfExpr.finalize());1407} else if (auto *BI = dyn_cast_if_present<ConstantInt *>(Bound)) {1408if (Attr == dwarf::DW_AT_count) {1409if (BI->getSExtValue() != -1)1410addUInt(DW_Subrange, Attr, std::nullopt, BI->getSExtValue());1411} else if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 ||1412BI->getSExtValue() != DefaultLowerBound)1413addSInt(DW_Subrange, Attr, dwarf::DW_FORM_sdata, BI->getSExtValue());1414}1415};14161417AddBoundTypeEntry(dwarf::DW_AT_lower_bound, SR->getLowerBound());14181419AddBoundTypeEntry(dwarf::DW_AT_count, SR->getCount());14201421AddBoundTypeEntry(dwarf::DW_AT_upper_bound, SR->getUpperBound());14221423AddBoundTypeEntry(dwarf::DW_AT_byte_stride, SR->getStride());1424}14251426void DwarfUnit::constructGenericSubrangeDIE(DIE &Buffer,1427const DIGenericSubrange *GSR,1428DIE *IndexTy) {1429DIE &DwGenericSubrange =1430createAndAddDIE(dwarf::DW_TAG_generic_subrange, Buffer);1431addDIEEntry(DwGenericSubrange, dwarf::DW_AT_type, *IndexTy);14321433int64_t DefaultLowerBound = getDefaultLowerBound();14341435auto AddBoundTypeEntry = [&](dwarf::Attribute Attr,1436DIGenericSubrange::BoundType Bound) -> void {1437if (auto *BV = dyn_cast_if_present<DIVariable *>(Bound)) {1438if (auto *VarDIE = getDIE(BV))1439addDIEEntry(DwGenericSubrange, Attr, *VarDIE);1440} else if (auto *BE = dyn_cast_if_present<DIExpression *>(Bound)) {1441if (BE->isConstant() &&1442DIExpression::SignedOrUnsignedConstant::SignedConstant ==1443*BE->isConstant()) {1444if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 ||1445static_cast<int64_t>(BE->getElement(1)) != DefaultLowerBound)1446addSInt(DwGenericSubrange, Attr, dwarf::DW_FORM_sdata,1447BE->getElement(1));1448} else {1449DIELoc *Loc = new (DIEValueAllocator) DIELoc;1450DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);1451DwarfExpr.setMemoryLocationKind();1452DwarfExpr.addExpression(BE);1453addBlock(DwGenericSubrange, Attr, DwarfExpr.finalize());1454}1455}1456};14571458AddBoundTypeEntry(dwarf::DW_AT_lower_bound, GSR->getLowerBound());1459AddBoundTypeEntry(dwarf::DW_AT_count, GSR->getCount());1460AddBoundTypeEntry(dwarf::DW_AT_upper_bound, GSR->getUpperBound());1461AddBoundTypeEntry(dwarf::DW_AT_byte_stride, GSR->getStride());1462}14631464DIE *DwarfUnit::getIndexTyDie() {1465if (IndexTyDie)1466return IndexTyDie;1467// Construct an integer type to use for indexes.1468IndexTyDie = &createAndAddDIE(dwarf::DW_TAG_base_type, getUnitDie());1469StringRef Name = "__ARRAY_SIZE_TYPE__";1470addString(*IndexTyDie, dwarf::DW_AT_name, Name);1471addUInt(*IndexTyDie, dwarf::DW_AT_byte_size, std::nullopt, sizeof(int64_t));1472addUInt(*IndexTyDie, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,1473dwarf::getArrayIndexTypeEncoding(1474(dwarf::SourceLanguage)getLanguage()));1475DD->addAccelType(*this, CUNode->getNameTableKind(), Name, *IndexTyDie,1476/*Flags*/ 0);1477return IndexTyDie;1478}14791480/// Returns true if the vector's size differs from the sum of sizes of elements1481/// the user specified. This can occur if the vector has been rounded up to1482/// fit memory alignment constraints.1483static bool hasVectorBeenPadded(const DICompositeType *CTy) {1484assert(CTy && CTy->isVector() && "Composite type is not a vector");1485const uint64_t ActualSize = CTy->getSizeInBits();14861487// Obtain the size of each element in the vector.1488DIType *BaseTy = CTy->getBaseType();1489assert(BaseTy && "Unknown vector element type.");1490const uint64_t ElementSize = BaseTy->getSizeInBits();14911492// Locate the number of elements in the vector.1493const DINodeArray Elements = CTy->getElements();1494assert(Elements.size() == 1 &&1495Elements[0]->getTag() == dwarf::DW_TAG_subrange_type &&1496"Invalid vector element array, expected one element of type subrange");1497const auto Subrange = cast<DISubrange>(Elements[0]);1498const auto NumVecElements =1499Subrange->getCount()1500? cast<ConstantInt *>(Subrange->getCount())->getSExtValue()1501: 0;15021503// Ensure we found the element count and that the actual size is wide1504// enough to contain the requested size.1505assert(ActualSize >= (NumVecElements * ElementSize) && "Invalid vector size");1506return ActualSize != (NumVecElements * ElementSize);1507}15081509void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {1510if (CTy->isVector()) {1511addFlag(Buffer, dwarf::DW_AT_GNU_vector);1512if (hasVectorBeenPadded(CTy))1513addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt,1514CTy->getSizeInBits() / CHAR_BIT);1515}15161517if (DIVariable *Var = CTy->getDataLocation()) {1518if (auto *VarDIE = getDIE(Var))1519addDIEEntry(Buffer, dwarf::DW_AT_data_location, *VarDIE);1520} else if (DIExpression *Expr = CTy->getDataLocationExp()) {1521DIELoc *Loc = new (DIEValueAllocator) DIELoc;1522DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);1523DwarfExpr.setMemoryLocationKind();1524DwarfExpr.addExpression(Expr);1525addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize());1526}15271528if (DIVariable *Var = CTy->getAssociated()) {1529if (auto *VarDIE = getDIE(Var))1530addDIEEntry(Buffer, dwarf::DW_AT_associated, *VarDIE);1531} else if (DIExpression *Expr = CTy->getAssociatedExp()) {1532DIELoc *Loc = new (DIEValueAllocator) DIELoc;1533DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);1534DwarfExpr.setMemoryLocationKind();1535DwarfExpr.addExpression(Expr);1536addBlock(Buffer, dwarf::DW_AT_associated, DwarfExpr.finalize());1537}15381539if (DIVariable *Var = CTy->getAllocated()) {1540if (auto *VarDIE = getDIE(Var))1541addDIEEntry(Buffer, dwarf::DW_AT_allocated, *VarDIE);1542} else if (DIExpression *Expr = CTy->getAllocatedExp()) {1543DIELoc *Loc = new (DIEValueAllocator) DIELoc;1544DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);1545DwarfExpr.setMemoryLocationKind();1546DwarfExpr.addExpression(Expr);1547addBlock(Buffer, dwarf::DW_AT_allocated, DwarfExpr.finalize());1548}15491550if (auto *RankConst = CTy->getRankConst()) {1551addSInt(Buffer, dwarf::DW_AT_rank, dwarf::DW_FORM_sdata,1552RankConst->getSExtValue());1553} else if (auto *RankExpr = CTy->getRankExp()) {1554DIELoc *Loc = new (DIEValueAllocator) DIELoc;1555DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);1556DwarfExpr.setMemoryLocationKind();1557DwarfExpr.addExpression(RankExpr);1558addBlock(Buffer, dwarf::DW_AT_rank, DwarfExpr.finalize());1559}15601561// Emit the element type.1562addType(Buffer, CTy->getBaseType());15631564// Get an anonymous type for index type.1565// FIXME: This type should be passed down from the front end1566// as different languages may have different sizes for indexes.1567DIE *IdxTy = getIndexTyDie();15681569// Add subranges to array type.1570DINodeArray Elements = CTy->getElements();1571for (DINode *E : Elements) {1572// FIXME: Should this really be such a loose cast?1573if (auto *Element = dyn_cast_or_null<DINode>(E)) {1574if (Element->getTag() == dwarf::DW_TAG_subrange_type)1575constructSubrangeDIE(Buffer, cast<DISubrange>(Element), IdxTy);1576else if (Element->getTag() == dwarf::DW_TAG_generic_subrange)1577constructGenericSubrangeDIE(Buffer, cast<DIGenericSubrange>(Element),1578IdxTy);1579}1580}1581}15821583void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) {1584const DIType *DTy = CTy->getBaseType();1585bool IsUnsigned = DTy && DD->isUnsignedDIType(DTy);1586if (DTy) {1587if (!Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= 3)1588addType(Buffer, DTy);1589if (DD->getDwarfVersion() >= 4 && (CTy->getFlags() & DINode::FlagEnumClass))1590addFlag(Buffer, dwarf::DW_AT_enum_class);1591}15921593auto *Context = CTy->getScope();1594bool IndexEnumerators = !Context || isa<DICompileUnit>(Context) || isa<DIFile>(Context) ||1595isa<DINamespace>(Context) || isa<DICommonBlock>(Context);1596DINodeArray Elements = CTy->getElements();15971598// Add enumerators to enumeration type.1599for (const DINode *E : Elements) {1600auto *Enum = dyn_cast_or_null<DIEnumerator>(E);1601if (Enum) {1602DIE &Enumerator = createAndAddDIE(dwarf::DW_TAG_enumerator, Buffer);1603StringRef Name = Enum->getName();1604addString(Enumerator, dwarf::DW_AT_name, Name);1605addConstantValue(Enumerator, Enum->getValue(), IsUnsigned);1606if (IndexEnumerators)1607addGlobalName(Name, Enumerator, Context);1608}1609}1610}16111612void DwarfUnit::constructContainingTypeDIEs() {1613for (auto &P : ContainingTypeMap) {1614DIE &SPDie = *P.first;1615const DINode *D = P.second;1616if (!D)1617continue;1618DIE *NDie = getDIE(D);1619if (!NDie)1620continue;1621addDIEEntry(SPDie, dwarf::DW_AT_containing_type, *NDie);1622}1623}16241625DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {1626DIE &MemberDie = createAndAddDIE(DT->getTag(), Buffer);1627StringRef Name = DT->getName();1628if (!Name.empty())1629addString(MemberDie, dwarf::DW_AT_name, Name);16301631addAnnotation(MemberDie, DT->getAnnotations());16321633if (DIType *Resolved = DT->getBaseType())1634addType(MemberDie, Resolved);16351636addSourceLine(MemberDie, DT);16371638if (DT->getTag() == dwarf::DW_TAG_inheritance && DT->isVirtual()) {16391640// For C++, virtual base classes are not at fixed offset. Use following1641// expression to extract appropriate offset from vtable.1642// BaseAddr = ObAddr + *((*ObAddr) - Offset)16431644DIELoc *VBaseLocationDie = new (DIEValueAllocator) DIELoc;1645addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);1646addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);1647addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);1648addUInt(*VBaseLocationDie, dwarf::DW_FORM_udata, DT->getOffsetInBits());1649addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);1650addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);1651addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);16521653addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);1654} else {1655uint64_t Size = DT->getSizeInBits();1656uint64_t FieldSize = DD->getBaseTypeSize(DT);1657uint32_t AlignInBytes = DT->getAlignInBytes();1658uint64_t OffsetInBytes;16591660bool IsBitfield = DT->isBitField();1661if (IsBitfield) {1662// Handle bitfield, assume bytes are 8 bits.1663if (DD->useDWARF2Bitfields())1664addUInt(MemberDie, dwarf::DW_AT_byte_size, std::nullopt, FieldSize / 8);1665addUInt(MemberDie, dwarf::DW_AT_bit_size, std::nullopt, Size);16661667assert(DT->getOffsetInBits() <=1668(uint64_t)std::numeric_limits<int64_t>::max());1669int64_t Offset = DT->getOffsetInBits();1670// We can't use DT->getAlignInBits() here: AlignInBits for member type1671// is non-zero if and only if alignment was forced (e.g. _Alignas()),1672// which can't be done with bitfields. Thus we use FieldSize here.1673uint32_t AlignInBits = FieldSize;1674uint32_t AlignMask = ~(AlignInBits - 1);1675// The bits from the start of the storage unit to the start of the field.1676uint64_t StartBitOffset = Offset - (Offset & AlignMask);1677// The byte offset of the field's aligned storage unit inside the struct.1678OffsetInBytes = (Offset - StartBitOffset) / 8;16791680if (DD->useDWARF2Bitfields()) {1681uint64_t HiMark = (Offset + FieldSize) & AlignMask;1682uint64_t FieldOffset = (HiMark - FieldSize);1683Offset -= FieldOffset;16841685// Maybe we need to work from the other end.1686if (Asm->getDataLayout().isLittleEndian())1687Offset = FieldSize - (Offset + Size);16881689if (Offset < 0)1690addSInt(MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata,1691Offset);1692else1693addUInt(MemberDie, dwarf::DW_AT_bit_offset, std::nullopt,1694(uint64_t)Offset);1695OffsetInBytes = FieldOffset >> 3;1696} else {1697addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt, Offset);1698}1699} else {1700// This is not a bitfield.1701OffsetInBytes = DT->getOffsetInBits() / 8;1702if (AlignInBytes)1703addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,1704AlignInBytes);1705}17061707if (DD->getDwarfVersion() <= 2) {1708DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc;1709addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);1710addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);1711addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);1712} else if (!IsBitfield || DD->useDWARF2Bitfields()) {1713// In DWARF v3, DW_FORM_data4/8 in DW_AT_data_member_location are1714// interpreted as location-list pointers. Interpreting constants as1715// pointers is not expected, so we use DW_FORM_udata to encode the1716// constants here.1717if (DD->getDwarfVersion() == 3)1718addUInt(MemberDie, dwarf::DW_AT_data_member_location,1719dwarf::DW_FORM_udata, OffsetInBytes);1720else1721addUInt(MemberDie, dwarf::DW_AT_data_member_location, std::nullopt,1722OffsetInBytes);1723}1724}17251726addAccess(MemberDie, DT->getFlags());17271728if (DT->isVirtual())1729addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1,1730dwarf::DW_VIRTUALITY_virtual);17311732// Objective-C properties.1733if (DINode *PNode = DT->getObjCProperty())1734if (DIE *PDie = getDIE(PNode))1735addAttribute(MemberDie, dwarf::DW_AT_APPLE_property,1736dwarf::DW_FORM_ref4, DIEEntry(*PDie));17371738if (DT->isArtificial())1739addFlag(MemberDie, dwarf::DW_AT_artificial);17401741return MemberDie;1742}17431744DIE *DwarfUnit::getOrCreateStaticMemberDIE(const DIDerivedType *DT) {1745if (!DT)1746return nullptr;17471748// Construct the context before querying for the existence of the DIE in case1749// such construction creates the DIE.1750DIE *ContextDIE = getOrCreateContextDIE(DT->getScope());1751assert(dwarf::isType(ContextDIE->getTag()) &&1752"Static member should belong to a type.");17531754if (DIE *StaticMemberDIE = getDIE(DT))1755return StaticMemberDIE;17561757DIE &StaticMemberDIE = createAndAddDIE(DT->getTag(), *ContextDIE, DT);17581759const DIType *Ty = DT->getBaseType();17601761addString(StaticMemberDIE, dwarf::DW_AT_name, DT->getName());1762addType(StaticMemberDIE, Ty);1763addSourceLine(StaticMemberDIE, DT);1764addFlag(StaticMemberDIE, dwarf::DW_AT_external);1765addFlag(StaticMemberDIE, dwarf::DW_AT_declaration);17661767// FIXME: We could omit private if the parent is a class_type, and1768// public if the parent is something else.1769addAccess(StaticMemberDIE, DT->getFlags());17701771if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT->getConstant()))1772addConstantValue(StaticMemberDIE, CI, Ty);1773if (const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT->getConstant()))1774addConstantFPValue(StaticMemberDIE, CFP);17751776if (uint32_t AlignInBytes = DT->getAlignInBytes())1777addUInt(StaticMemberDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,1778AlignInBytes);17791780return &StaticMemberDIE;1781}17821783void DwarfUnit::emitCommonHeader(bool UseOffsets, dwarf::UnitType UT) {1784// Emit size of content not including length itself1785if (!DD->useSectionsAsReferences())1786EndLabel = Asm->emitDwarfUnitLength(1787isDwoUnit() ? "debug_info_dwo" : "debug_info", "Length of Unit");1788else1789Asm->emitDwarfUnitLength(getHeaderSize() + getUnitDie().getSize(),1790"Length of Unit");17911792Asm->OutStreamer->AddComment("DWARF version number");1793unsigned Version = DD->getDwarfVersion();1794Asm->emitInt16(Version);17951796// DWARF v5 reorders the address size and adds a unit type.1797if (Version >= 5) {1798Asm->OutStreamer->AddComment("DWARF Unit Type");1799Asm->emitInt8(UT);1800Asm->OutStreamer->AddComment("Address Size (in bytes)");1801Asm->emitInt8(Asm->MAI->getCodePointerSize());1802}18031804// We share one abbreviations table across all units so it's always at the1805// start of the section. Use a relocatable offset where needed to ensure1806// linking doesn't invalidate that offset.1807Asm->OutStreamer->AddComment("Offset Into Abbrev. Section");1808const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();1809if (UseOffsets)1810Asm->emitDwarfLengthOrOffset(0);1811else1812Asm->emitDwarfSymbolReference(1813TLOF.getDwarfAbbrevSection()->getBeginSymbol(), false);18141815if (Version <= 4) {1816Asm->OutStreamer->AddComment("Address Size (in bytes)");1817Asm->emitInt8(Asm->MAI->getCodePointerSize());1818}1819}18201821void DwarfTypeUnit::emitHeader(bool UseOffsets) {1822if (!DD->useSplitDwarf()) {1823LabelBegin = Asm->createTempSymbol("tu_begin");1824Asm->OutStreamer->emitLabel(LabelBegin);1825}1826DwarfUnit::emitCommonHeader(UseOffsets,1827DD->useSplitDwarf() ? dwarf::DW_UT_split_type1828: dwarf::DW_UT_type);1829Asm->OutStreamer->AddComment("Type Signature");1830Asm->OutStreamer->emitIntValue(TypeSignature, sizeof(TypeSignature));1831Asm->OutStreamer->AddComment("Type DIE Offset");1832// In a skeleton type unit there is no type DIE so emit a zero offset.1833Asm->emitDwarfLengthOrOffset(Ty ? Ty->getOffset() : 0);1834}18351836void DwarfUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute,1837const MCSymbol *Hi, const MCSymbol *Lo) {1838addAttribute(Die, Attribute, DD->getDwarfSectionOffsetForm(),1839new (DIEValueAllocator) DIEDelta(Hi, Lo));1840}18411842void DwarfUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute,1843const MCSymbol *Label, const MCSymbol *Sec) {1844if (Asm->doesDwarfUseRelocationsAcrossSections())1845addLabel(Die, Attribute, DD->getDwarfSectionOffsetForm(), Label);1846else1847addSectionDelta(Die, Attribute, Label, Sec);1848}18491850bool DwarfTypeUnit::isDwoUnit() const {1851// Since there are no skeleton type units, all type units are dwo type units1852// when split DWARF is being used.1853return DD->useSplitDwarf();1854}18551856void DwarfTypeUnit::addGlobalName(StringRef Name, const DIE &Die,1857const DIScope *Context) {1858getCU().addGlobalNameForTypeUnit(Name, Context);1859}18601861void DwarfTypeUnit::addGlobalTypeImpl(const DIType *Ty, const DIE &Die,1862const DIScope *Context) {1863getCU().addGlobalTypeUnitType(Ty, Context);1864}18651866const MCSymbol *DwarfUnit::getCrossSectionRelativeBaseAddress() const {1867if (!Asm->doesDwarfUseRelocationsAcrossSections())1868return nullptr;1869if (isDwoUnit())1870return nullptr;1871return getSection()->getBeginSymbol();1872}18731874void DwarfUnit::addStringOffsetsStart() {1875const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();1876addSectionLabel(getUnitDie(), dwarf::DW_AT_str_offsets_base,1877DU->getStringOffsetsStartSym(),1878TLOF.getDwarfStrOffSection()->getBeginSymbol());1879}18801881void DwarfUnit::addRnglistsBase() {1882assert(DD->getDwarfVersion() >= 5 &&1883"DW_AT_rnglists_base requires DWARF version 5 or later");1884const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();1885addSectionLabel(getUnitDie(), dwarf::DW_AT_rnglists_base,1886DU->getRnglistsTableBaseSym(),1887TLOF.getDwarfRnglistsSection()->getBeginSymbol());1888}18891890void DwarfTypeUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) {1891DD->getAddressPool().resetUsedFlag(true);1892}18931894bool DwarfUnit::isCompatibleWithVersion(uint16_t Version) const {1895return !Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= Version;1896}189718981899