| @@ -1,836 +1,1956 @@ | | | @@ -1,836 +1,1956 @@ |
| | | 1 | //===-- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Unit ------------===// |
| | | 2 | // |
| | | 3 | // The LLVM Compiler Infrastructure |
| | | 4 | // |
| | | 5 | // This file is distributed under the University of Illinois Open Source |
| | | 6 | // License. See LICENSE.TXT for details. |
| | | 7 | // |
| | | 8 | //===----------------------------------------------------------------------===// |
| | | 9 | // |
| | | 10 | // This file contains support for constructing a dwarf compile unit. |
| | | 11 | // |
| | | 12 | //===----------------------------------------------------------------------===// |
| | | 13 | |
| | | 14 | #define DEBUG_TYPE "dwarfdebug" |
| | | 15 | |
1 | #include "DwarfCompileUnit.h" | | 16 | #include "DwarfCompileUnit.h" |
2 | #include "DwarfExpression.h" | | 17 | #include "DwarfAccelTable.h" |
3 | #include "llvm/CodeGen/MachineFunction.h" | | 18 | #include "DwarfDebug.h" |
| | | 19 | #include "llvm/ADT/APFloat.h" |
| | | 20 | #include "llvm/DIBuilder.h" |
| | | 21 | #include "llvm/IR/Constants.h" |
4 | #include "llvm/IR/DataLayout.h" | | 22 | #include "llvm/IR/DataLayout.h" |
5 | #include "llvm/IR/GlobalValue.h" | | | |
6 | #include "llvm/IR/GlobalVariable.h" | | 23 | #include "llvm/IR/GlobalVariable.h" |
7 | #include "llvm/IR/Instruction.h" | | 24 | #include "llvm/IR/Instructions.h" |
8 | #include "llvm/MC/MCAsmInfo.h" | | 25 | #include "llvm/MC/MCSection.h" |
9 | #include "llvm/MC/MCStreamer.h" | | 26 | #include "llvm/MC/MCStreamer.h" |
| | | 27 | #include "llvm/Target/Mangler.h" |
10 | #include "llvm/Target/TargetFrameLowering.h" | | 28 | #include "llvm/Target/TargetFrameLowering.h" |
11 | #include "llvm/Target/TargetLoweringObjectFile.h" | | | |
12 | #include "llvm/Target/TargetMachine.h" | | 29 | #include "llvm/Target/TargetMachine.h" |
| | | 30 | #include "llvm/Target/TargetLoweringObjectFile.h" |
13 | #include "llvm/Target/TargetRegisterInfo.h" | | 31 | #include "llvm/Target/TargetRegisterInfo.h" |
14 | #include "llvm/Target/TargetSubtargetInfo.h" | | | |
15 | | | 32 | |
16 | namespace llvm { | | 33 | using namespace llvm; |
17 | | | 34 | |
18 | DwarfCompileUnit::DwarfCompileUnit(unsigned UID, DICompileUnit Node, | | 35 | /// CompileUnit - Compile unit constructor. |
19 | AsmPrinter *A, DwarfDebug *DW, | | 36 | CompileUnit::CompileUnit(unsigned UID, DIE *D, DICompileUnit Node, |
20 | DwarfFile *DWU) | | 37 | AsmPrinter *A, DwarfDebug *DW, DwarfUnits *DWU) |
21 | : DwarfUnit(UID, dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), | | 38 | : UniqueID(UID), Node(Node), CUDie(D), Asm(A), DD(DW), DU(DWU), |
22 | Skeleton(nullptr), LabelBegin(nullptr), BaseAddress(nullptr) { | | 39 | IndexTyDie(0), DebugInfoOffset(0) { |
23 | insertDIE(Node, &getUnitDie()); | | 40 | DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1); |
| | | 41 | insertDIE(Node, D); |
| | | 42 | } |
| | | 43 | |
| | | 44 | /// ~CompileUnit - Destructor for compile unit. |
| | | 45 | CompileUnit::~CompileUnit() { |
| | | 46 | for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j) |
| | | 47 | DIEBlocks[j]->~DIEBlock(); |
| | | 48 | } |
| | | 49 | |
| | | 50 | /// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug |
| | | 51 | /// information entry. |
| | | 52 | DIEEntry *CompileUnit::createDIEEntry(DIE *Entry) { |
| | | 53 | DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry); |
| | | 54 | return Value; |
| | | 55 | } |
| | | 56 | |
| | | 57 | /// getDefaultLowerBound - Return the default lower bound for an array. If the |
| | | 58 | /// DWARF version doesn't handle the language, return -1. |
| | | 59 | int64_t CompileUnit::getDefaultLowerBound() const { |
| | | 60 | switch (getLanguage()) { |
| | | 61 | default: |
| | | 62 | break; |
| | | 63 | |
| | | 64 | case dwarf::DW_LANG_C89: |
| | | 65 | case dwarf::DW_LANG_C99: |
| | | 66 | case dwarf::DW_LANG_C: |
| | | 67 | case dwarf::DW_LANG_C_plus_plus: |
| | | 68 | case dwarf::DW_LANG_ObjC: |
| | | 69 | case dwarf::DW_LANG_ObjC_plus_plus: |
| | | 70 | return 0; |
| | | 71 | |
| | | 72 | case dwarf::DW_LANG_Fortran77: |
| | | 73 | case dwarf::DW_LANG_Fortran90: |
| | | 74 | case dwarf::DW_LANG_Fortran95: |
| | | 75 | return 1; |
| | | 76 | |
| | | 77 | // The languages below have valid values only if the DWARF version >= 4. |
| | | 78 | case dwarf::DW_LANG_Java: |
| | | 79 | case dwarf::DW_LANG_Python: |
| | | 80 | case dwarf::DW_LANG_UPC: |
| | | 81 | case dwarf::DW_LANG_D: |
| | | 82 | if (dwarf::DWARF_VERSION >= 4) |
| | | 83 | return 0; |
| | | 84 | break; |
| | | 85 | |
| | | 86 | case dwarf::DW_LANG_Ada83: |
| | | 87 | case dwarf::DW_LANG_Ada95: |
| | | 88 | case dwarf::DW_LANG_Cobol74: |
| | | 89 | case dwarf::DW_LANG_Cobol85: |
| | | 90 | case dwarf::DW_LANG_Modula2: |
| | | 91 | case dwarf::DW_LANG_Pascal83: |
| | | 92 | case dwarf::DW_LANG_PLI: |
| | | 93 | if (dwarf::DWARF_VERSION >= 4) |
| | | 94 | return 1; |
| | | 95 | break; |
| | | 96 | } |
| | | 97 | |
| | | 98 | return -1; |
24 | } | | 99 | } |
25 | | | 100 | |
26 | /// addLabelAddress - Add a dwarf label attribute data and value using | | 101 | /// Check whether the DIE for this MDNode can be shared across CUs. |
27 | /// DW_FORM_addr or DW_FORM_GNU_addr_index. | | 102 | static bool isShareableAcrossCUs(DIDescriptor D) { |
| | | 103 | // When the MDNode can be part of the type system, the DIE can be |
| | | 104 | // shared across CUs. |
| | | 105 | return D.isType() || |
| | | 106 | (D.isSubprogram() && !DISubprogram(D).isDefinition()); |
| | | 107 | } |
| | | 108 | |
| | | 109 | /// getDIE - Returns the debug information entry map slot for the |
| | | 110 | /// specified debug variable. We delegate the request to DwarfDebug |
| | | 111 | /// when the DIE for this MDNode can be shared across CUs. The mappings |
| | | 112 | /// will be kept in DwarfDebug for shareable DIEs. |
| | | 113 | DIE *CompileUnit::getDIE(DIDescriptor D) const { |
| | | 114 | if (isShareableAcrossCUs(D)) |
| | | 115 | return DD->getDIE(D); |
| | | 116 | return MDNodeToDieMap.lookup(D); |
| | | 117 | } |
| | | 118 | |
| | | 119 | /// insertDIE - Insert DIE into the map. We delegate the request to DwarfDebug |
| | | 120 | /// when the DIE for this MDNode can be shared across CUs. The mappings |
| | | 121 | /// will be kept in DwarfDebug for shareable DIEs. |
| | | 122 | void CompileUnit::insertDIE(DIDescriptor Desc, DIE *D) { |
| | | 123 | if (isShareableAcrossCUs(Desc)) { |
| | | 124 | DD->insertDIE(Desc, D); |
| | | 125 | return; |
| | | 126 | } |
| | | 127 | MDNodeToDieMap.insert(std::make_pair(Desc, D)); |
| | | 128 | } |
| | | 129 | |
| | | 130 | /// addFlag - Add a flag that is true. |
| | | 131 | void CompileUnit::addFlag(DIE *Die, dwarf::Attribute Attribute) { |
| | | 132 | if (DD->getDwarfVersion() >= 4) |
| | | 133 | Die->addValue(Attribute, dwarf::DW_FORM_flag_present, DIEIntegerOne); |
| | | 134 | else |
| | | 135 | Die->addValue(Attribute, dwarf::DW_FORM_flag, DIEIntegerOne); |
| | | 136 | } |
| | | 137 | |
| | | 138 | /// addUInt - Add an unsigned integer attribute data and value. |
28 | /// | | 139 | /// |
29 | void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute, | | 140 | void CompileUnit::addUInt(DIE *Die, dwarf::Attribute Attribute, |
30 | const MCSymbol *Label) { | | 141 | Optional<dwarf::Form> Form, uint64_t Integer) { |
| | | 142 | if (!Form) |
| | | 143 | Form = DIEInteger::BestForm(false, Integer); |
| | | 144 | DIEValue *Value = Integer == 1 ? DIEIntegerOne : new (DIEValueAllocator) |
| | | 145 | DIEInteger(Integer); |
| | | 146 | Die->addValue(Attribute, *Form, Value); |
| | | 147 | } |
31 | | | 148 | |
32 | // Don't use the address pool in non-fission or in the skeleton unit itself. | | 149 | void CompileUnit::addUInt(DIEBlock *Block, dwarf::Form Form, uint64_t Integer) { |
33 | // FIXME: Once GDB supports this, it's probably worthwhile using the address | | 150 | addUInt(Block, (dwarf::Attribute)0, Form, Integer); |
34 | // pool from the skeleton - maybe even in non-fission (possibly fewer | | 151 | } |
35 | // relocations by sharing them in the pool, but we have other ideas about how | | | |
36 | // to reduce the number of relocations as well/instead). | | | |
37 | if (!DD->useSplitDwarf() || !Skeleton) | | | |
38 | return addLocalLabelAddress(Die, Attribute, Label); | | | |
39 | | | 152 | |
40 | if (Label) | | 153 | /// addSInt - Add an signed integer attribute data and value. |
41 | DD->addArangeLabel(SymbolCU(this, Label)); | | 154 | /// |
| | | 155 | void CompileUnit::addSInt(DIE *Die, dwarf::Attribute Attribute, |
| | | 156 | Optional<dwarf::Form> Form, int64_t Integer) { |
| | | 157 | if (!Form) |
| | | 158 | Form = DIEInteger::BestForm(true, Integer); |
| | | 159 | DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer); |
| | | 160 | Die->addValue(Attribute, *Form, Value); |
| | | 161 | } |
| | | 162 | |
| | | 163 | void CompileUnit::addSInt(DIEBlock *Die, Optional<dwarf::Form> Form, |
| | | 164 | int64_t Integer) { |
| | | 165 | addSInt(Die, (dwarf::Attribute)0, Form, Integer); |
| | | 166 | } |
| | | 167 | |
| | | 168 | /// addString - Add a string attribute data and value. We always emit a |
| | | 169 | /// reference to the string pool instead of immediate strings so that DIEs have |
| | | 170 | /// more predictable sizes. In the case of split dwarf we emit an index |
| | | 171 | /// into another table which gets us the static offset into the string |
| | | 172 | /// table. |
| | | 173 | void CompileUnit::addString(DIE *Die, dwarf::Attribute Attribute, |
| | | 174 | StringRef String) { |
| | | 175 | DIEValue *Value; |
| | | 176 | dwarf::Form Form; |
| | | 177 | if (!DD->useSplitDwarf()) { |
| | | 178 | MCSymbol *Symb = DU->getStringPoolEntry(String); |
| | | 179 | if (Asm->needsRelocationsForDwarfStringPool()) |
| | | 180 | Value = new (DIEValueAllocator) DIELabel(Symb); |
| | | 181 | else { |
| | | 182 | MCSymbol *StringPool = DU->getStringPoolSym(); |
| | | 183 | Value = new (DIEValueAllocator) DIEDelta(Symb, StringPool); |
| | | 184 | } |
| | | 185 | Form = dwarf::DW_FORM_strp; |
| | | 186 | } else { |
| | | 187 | unsigned idx = DU->getStringPoolIndex(String); |
| | | 188 | Value = new (DIEValueAllocator) DIEInteger(idx); |
| | | 189 | Form = dwarf::DW_FORM_GNU_str_index; |
| | | 190 | } |
| | | 191 | DIEValue *Str = new (DIEValueAllocator) DIEString(Value, String); |
| | | 192 | Die->addValue(Attribute, Form, Str); |
| | | 193 | } |
42 | | | 194 | |
43 | unsigned idx = DD->getAddressPool().getIndex(Label); | | 195 | /// addLocalString - Add a string attribute data and value. This is guaranteed |
44 | DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx); | | 196 | /// to be in the local string pool instead of indirected. |
45 | Die.addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value); | | 197 | void CompileUnit::addLocalString(DIE *Die, dwarf::Attribute Attribute, |
| | | 198 | StringRef String) { |
| | | 199 | MCSymbol *Symb = DU->getStringPoolEntry(String); |
| | | 200 | DIEValue *Value; |
| | | 201 | if (Asm->needsRelocationsForDwarfStringPool()) |
| | | 202 | Value = new (DIEValueAllocator) DIELabel(Symb); |
| | | 203 | else { |
| | | 204 | MCSymbol *StringPool = DU->getStringPoolSym(); |
| | | 205 | Value = new (DIEValueAllocator) DIEDelta(Symb, StringPool); |
| | | 206 | } |
| | | 207 | Die->addValue(Attribute, dwarf::DW_FORM_strp, Value); |
46 | } | | 208 | } |
47 | | | 209 | |
48 | void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, | | 210 | /// addExpr - Add a Dwarf expression attribute data and value. |
49 | dwarf::Attribute Attribute, | | 211 | /// |
50 | const MCSymbol *Label) { | | 212 | void CompileUnit::addExpr(DIEBlock *Die, dwarf::Form Form, const MCExpr *Expr) { |
| | | 213 | DIEValue *Value = new (DIEValueAllocator) DIEExpr(Expr); |
| | | 214 | Die->addValue((dwarf::Attribute)0, Form, Value); |
| | | 215 | } |
| | | 216 | |
| | | 217 | /// addLabel - Add a Dwarf label attribute data and value. |
| | | 218 | /// |
| | | 219 | void CompileUnit::addLabel(DIE *Die, dwarf::Attribute Attribute, |
| | | 220 | dwarf::Form Form, const MCSymbol *Label) { |
| | | 221 | DIEValue *Value = new (DIEValueAllocator) DIELabel(Label); |
| | | 222 | Die->addValue(Attribute, Form, Value); |
| | | 223 | } |
| | | 224 | |
| | | 225 | void CompileUnit::addLabel(DIEBlock *Die, dwarf::Form Form, |
| | | 226 | const MCSymbol *Label) { |
| | | 227 | addLabel(Die, (dwarf::Attribute)0, Form, Label); |
| | | 228 | } |
| | | 229 | |
| | | 230 | /// addLabelAddress - Add a dwarf label attribute data and value using |
| | | 231 | /// DW_FORM_addr or DW_FORM_GNU_addr_index. |
| | | 232 | /// |
| | | 233 | void CompileUnit::addLabelAddress(DIE *Die, dwarf::Attribute Attribute, |
| | | 234 | MCSymbol *Label) { |
51 | if (Label) | | 235 | if (Label) |
52 | DD->addArangeLabel(SymbolCU(this, Label)); | | 236 | DD->addArangeLabel(SymbolCU(this, Label)); |
53 | | | 237 | |
54 | Die.addValue(Attribute, dwarf::DW_FORM_addr, | | 238 | if (!DD->useSplitDwarf()) { |
55 | Label ? (DIEValue *)new (DIEValueAllocator) DIELabel(Label) | | 239 | if (Label != NULL) { |
56 | : new (DIEValueAllocator) DIEInteger(0)); | | 240 | DIEValue *Value = new (DIEValueAllocator) DIELabel(Label); |
| | | 241 | Die->addValue(Attribute, dwarf::DW_FORM_addr, Value); |
| | | 242 | } else { |
| | | 243 | DIEValue *Value = new (DIEValueAllocator) DIEInteger(0); |
| | | 244 | Die->addValue(Attribute, dwarf::DW_FORM_addr, Value); |
| | | 245 | } |
| | | 246 | } else { |
| | | 247 | unsigned idx = DU->getAddrPoolIndex(Label); |
| | | 248 | DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx); |
| | | 249 | Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value); |
| | | 250 | } |
| | | 251 | } |
| | | 252 | |
| | | 253 | /// addOpAddress - Add a dwarf op address data and value using the |
| | | 254 | /// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index. |
| | | 255 | /// |
| | | 256 | void CompileUnit::addOpAddress(DIEBlock *Die, const MCSymbol *Sym) { |
| | | 257 | DD->addArangeLabel(SymbolCU(this, Sym)); |
| | | 258 | if (!DD->useSplitDwarf()) { |
| | | 259 | addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); |
| | | 260 | addLabel(Die, dwarf::DW_FORM_udata, Sym); |
| | | 261 | } else { |
| | | 262 | addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index); |
| | | 263 | addUInt(Die, dwarf::DW_FORM_GNU_addr_index, DU->getAddrPoolIndex(Sym)); |
| | | 264 | } |
| | | 265 | } |
| | | 266 | |
| | | 267 | /// addDelta - Add a label delta attribute data and value. |
| | | 268 | /// |
| | | 269 | void CompileUnit::addDelta(DIE *Die, dwarf::Attribute Attribute, |
| | | 270 | dwarf::Form Form, const MCSymbol *Hi, |
| | | 271 | const MCSymbol *Lo) { |
| | | 272 | DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo); |
| | | 273 | Die->addValue(Attribute, Form, Value); |
| | | 274 | } |
| | | 275 | |
| | | 276 | /// addDIEEntry - Add a DIE attribute data and value. |
| | | 277 | /// |
| | | 278 | void CompileUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute, |
| | | 279 | DIE *Entry) { |
| | | 280 | addDIEEntry(Die, Attribute, createDIEEntry(Entry)); |
| | | 281 | } |
| | | 282 | |
| | | 283 | void CompileUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute, |
| | | 284 | DIEEntry *Entry) { |
| | | 285 | const DIE *DieCU = Die->getCompileUnitOrNull(); |
| | | 286 | const DIE *EntryCU = Entry->getEntry()->getCompileUnitOrNull(); |
| | | 287 | if (!DieCU) |
| | | 288 | // We assume that Die belongs to this CU, if it is not linked to any CU yet. |
| | | 289 | DieCU = getCUDie(); |
| | | 290 | if (!EntryCU) |
| | | 291 | EntryCU = getCUDie(); |
| | | 292 | Die->addValue(Attribute, EntryCU == DieCU ? dwarf::DW_FORM_ref4 |
| | | 293 | : dwarf::DW_FORM_ref_addr, |
| | | 294 | Entry); |
| | | 295 | } |
| | | 296 | |
| | | 297 | /// Create a DIE with the given Tag, add the DIE to its parent, and |
| | | 298 | /// call insertDIE if MD is not null. |
| | | 299 | DIE *CompileUnit::createAndAddDIE(unsigned Tag, DIE &Parent, DIDescriptor N) { |
| | | 300 | DIE *Die = new DIE(Tag); |
| | | 301 | Parent.addChild(Die); |
| | | 302 | if (N) |
| | | 303 | insertDIE(N, Die); |
| | | 304 | return Die; |
| | | 305 | } |
| | | 306 | |
| | | 307 | /// addBlock - Add block data. |
| | | 308 | /// |
| | | 309 | void CompileUnit::addBlock(DIE *Die, dwarf::Attribute Attribute, |
| | | 310 | DIEBlock *Block) { |
| | | 311 | Block->ComputeSize(Asm); |
| | | 312 | DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on. |
| | | 313 | Die->addValue(Attribute, Block->BestForm(), Block); |
| | | 314 | } |
| | | 315 | |
| | | 316 | /// addSourceLine - Add location information to specified debug information |
| | | 317 | /// entry. |
| | | 318 | void CompileUnit::addSourceLine(DIE *Die, DIVariable V) { |
| | | 319 | // Verify variable. |
| | | 320 | if (!V.isVariable()) |
| | | 321 | return; |
| | | 322 | |
| | | 323 | unsigned Line = V.getLineNumber(); |
| | | 324 | if (Line == 0) |
| | | 325 | return; |
| | | 326 | unsigned FileID = |
| | | 327 | DD->getOrCreateSourceID(V.getContext().getFilename(), |
| | | 328 | V.getContext().getDirectory(), getUniqueID()); |
| | | 329 | assert(FileID && "Invalid file id"); |
| | | 330 | addUInt(Die, dwarf::DW_AT_decl_file, None, FileID); |
| | | 331 | addUInt(Die, dwarf::DW_AT_decl_line, None, Line); |
| | | 332 | } |
| | | 333 | |
| | | 334 | /// addSourceLine - Add location information to specified debug information |
| | | 335 | /// entry. |
| | | 336 | void CompileUnit::addSourceLine(DIE *Die, DIGlobalVariable G) { |
| | | 337 | // Verify global variable. |
| | | 338 | if (!G.isGlobalVariable()) |
| | | 339 | return; |
| | | 340 | |
| | | 341 | unsigned Line = G.getLineNumber(); |
| | | 342 | if (Line == 0) |
| | | 343 | return; |
| | | 344 | unsigned FileID = |
| | | 345 | DD->getOrCreateSourceID(G.getFilename(), G.getDirectory(), getUniqueID()); |
| | | 346 | assert(FileID && "Invalid file id"); |
| | | 347 | addUInt(Die, dwarf::DW_AT_decl_file, None, FileID); |
| | | 348 | addUInt(Die, dwarf::DW_AT_decl_line, None, Line); |
| | | 349 | } |
| | | 350 | |
| | | 351 | /// addSourceLine - Add location information to specified debug information |
| | | 352 | /// entry. |
| | | 353 | void CompileUnit::addSourceLine(DIE *Die, DISubprogram SP) { |
| | | 354 | // Verify subprogram. |
| | | 355 | if (!SP.isSubprogram()) |
| | | 356 | return; |
| | | 357 | |
| | | 358 | // If the line number is 0, don't add it. |
| | | 359 | unsigned Line = SP.getLineNumber(); |
| | | 360 | if (Line == 0) |
| | | 361 | return; |
| | | 362 | |
| | | 363 | unsigned FileID = DD->getOrCreateSourceID(SP.getFilename(), SP.getDirectory(), |
| | | 364 | getUniqueID()); |
| | | 365 | assert(FileID && "Invalid file id"); |
| | | 366 | addUInt(Die, dwarf::DW_AT_decl_file, None, FileID); |
| | | 367 | addUInt(Die, dwarf::DW_AT_decl_line, None, Line); |
| | | 368 | } |
| | | 369 | |
| | | 370 | /// addSourceLine - Add location information to specified debug information |
| | | 371 | /// entry. |
| | | 372 | void CompileUnit::addSourceLine(DIE *Die, DIType Ty) { |
| | | 373 | // Verify type. |
| | | 374 | if (!Ty.isType()) |
| | | 375 | return; |
| | | 376 | |
| | | 377 | unsigned Line = Ty.getLineNumber(); |
| | | 378 | if (Line == 0) |
| | | 379 | return; |
| | | 380 | unsigned FileID = DD->getOrCreateSourceID(Ty.getFilename(), Ty.getDirectory(), |
| | | 381 | getUniqueID()); |
| | | 382 | assert(FileID && "Invalid file id"); |
| | | 383 | addUInt(Die, dwarf::DW_AT_decl_file, None, FileID); |
| | | 384 | addUInt(Die, dwarf::DW_AT_decl_line, None, Line); |
| | | 385 | } |
| | | 386 | |
| | | 387 | /// addSourceLine - Add location information to specified debug information |
| | | 388 | /// entry. |
| | | 389 | void CompileUnit::addSourceLine(DIE *Die, DIObjCProperty Ty) { |
| | | 390 | // Verify type. |
| | | 391 | if (!Ty.isObjCProperty()) |
| | | 392 | return; |
| | | 393 | |
| | | 394 | unsigned Line = Ty.getLineNumber(); |
| | | 395 | if (Line == 0) |
| | | 396 | return; |
| | | 397 | DIFile File = Ty.getFile(); |
| | | 398 | unsigned FileID = DD->getOrCreateSourceID(File.getFilename(), |
| | | 399 | File.getDirectory(), getUniqueID()); |
| | | 400 | assert(FileID && "Invalid file id"); |
| | | 401 | addUInt(Die, dwarf::DW_AT_decl_file, None, FileID); |
| | | 402 | addUInt(Die, dwarf::DW_AT_decl_line, None, Line); |
| | | 403 | } |
| | | 404 | |
| | | 405 | /// addSourceLine - Add location information to specified debug information |
| | | 406 | /// entry. |
| | | 407 | void CompileUnit::addSourceLine(DIE *Die, DINameSpace NS) { |
| | | 408 | // Verify namespace. |
| | | 409 | if (!NS.Verify()) |
| | | 410 | return; |
| | | 411 | |
| | | 412 | unsigned Line = NS.getLineNumber(); |
| | | 413 | if (Line == 0) |
| | | 414 | return; |
| | | 415 | StringRef FN = NS.getFilename(); |
| | | 416 | |
| | | 417 | unsigned FileID = |
| | | 418 | DD->getOrCreateSourceID(FN, NS.getDirectory(), getUniqueID()); |
| | | 419 | assert(FileID && "Invalid file id"); |
| | | 420 | addUInt(Die, dwarf::DW_AT_decl_file, None, FileID); |
| | | 421 | addUInt(Die, dwarf::DW_AT_decl_line, None, Line); |
| | | 422 | } |
| | | 423 | |
| | | 424 | /// addVariableAddress - Add DW_AT_location attribute for a |
| | | 425 | /// DbgVariable based on provided MachineLocation. |
| | | 426 | void CompileUnit::addVariableAddress(const DbgVariable &DV, DIE *Die, |
| | | 427 | MachineLocation Location) { |
| | | 428 | if (DV.variableHasComplexAddress()) |
| | | 429 | addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); |
| | | 430 | else if (DV.isBlockByrefVariable()) |
| | | 431 | addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location); |
| | | 432 | else |
| | | 433 | addAddress(Die, dwarf::DW_AT_location, Location, |
| | | 434 | DV.getVariable().isIndirect()); |
| | | 435 | } |
| | | 436 | |
| | | 437 | /// addRegisterOp - Add register operand. |
| | | 438 | void CompileUnit::addRegisterOp(DIEBlock *TheDie, unsigned Reg) { |
| | | 439 | const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); |
| | | 440 | unsigned DWReg = RI->getDwarfRegNum(Reg, false); |
| | | 441 | if (DWReg < 32) |
| | | 442 | addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + DWReg); |
| | | 443 | else { |
| | | 444 | addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_regx); |
| | | 445 | addUInt(TheDie, dwarf::DW_FORM_udata, DWReg); |
| | | 446 | } |
| | | 447 | } |
| | | 448 | |
| | | 449 | /// addRegisterOffset - Add register offset. |
| | | 450 | void CompileUnit::addRegisterOffset(DIEBlock *TheDie, unsigned Reg, |
| | | 451 | int64_t Offset) { |
| | | 452 | const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); |
| | | 453 | unsigned DWReg = RI->getDwarfRegNum(Reg, false); |
| | | 454 | const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo(); |
| | | 455 | if (Reg == TRI->getFrameRegister(*Asm->MF)) |
| | | 456 | // If variable offset is based in frame register then use fbreg. |
| | | 457 | addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_fbreg); |
| | | 458 | else if (DWReg < 32) |
| | | 459 | addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DWReg); |
| | | 460 | else { |
| | | 461 | addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx); |
| | | 462 | addUInt(TheDie, dwarf::DW_FORM_udata, DWReg); |
| | | 463 | } |
| | | 464 | addSInt(TheDie, dwarf::DW_FORM_sdata, Offset); |
| | | 465 | } |
| | | 466 | |
| | | 467 | /// addAddress - Add an address attribute to a die based on the location |
| | | 468 | /// provided. |
| | | 469 | void CompileUnit::addAddress(DIE *Die, dwarf::Attribute Attribute, |
| | | 470 | const MachineLocation &Location, bool Indirect) { |
| | | 471 | DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); |
| | | 472 | |
| | | 473 | if (Location.isReg() && !Indirect) |
| | | 474 | addRegisterOp(Block, Location.getReg()); |
| | | 475 | else { |
| | | 476 | addRegisterOffset(Block, Location.getReg(), Location.getOffset()); |
| | | 477 | if (Indirect && !Location.isReg()) { |
| | | 478 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); |
| | | 479 | } |
| | | 480 | } |
| | | 481 | |
| | | 482 | // Now attach the location information to the DIE. |
| | | 483 | addBlock(Die, Attribute, Block); |
| | | 484 | } |
| | | 485 | |
| | | 486 | /// addComplexAddress - Start with the address based on the location provided, |
| | | 487 | /// and generate the DWARF information necessary to find the actual variable |
| | | 488 | /// given the extra address information encoded in the DIVariable, starting from |
| | | 489 | /// the starting location. Add the DWARF information to the die. |
| | | 490 | /// |
| | | 491 | void CompileUnit::addComplexAddress(const DbgVariable &DV, DIE *Die, |
| | | 492 | dwarf::Attribute Attribute, |
| | | 493 | const MachineLocation &Location) { |
| | | 494 | DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); |
| | | 495 | unsigned N = DV.getNumAddrElements(); |
| | | 496 | unsigned i = 0; |
| | | 497 | if (Location.isReg()) { |
| | | 498 | if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) { |
| | | 499 | // If first address element is OpPlus then emit |
| | | 500 | // DW_OP_breg + Offset instead of DW_OP_reg + Offset. |
| | | 501 | addRegisterOffset(Block, Location.getReg(), DV.getAddrElement(1)); |
| | | 502 | i = 2; |
| | | 503 | } else |
| | | 504 | addRegisterOp(Block, Location.getReg()); |
| | | 505 | } else |
| | | 506 | addRegisterOffset(Block, Location.getReg(), Location.getOffset()); |
| | | 507 | |
| | | 508 | for (; i < N; ++i) { |
| | | 509 | uint64_t Element = DV.getAddrElement(i); |
| | | 510 | if (Element == DIBuilder::OpPlus) { |
| | | 511 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); |
| | | 512 | addUInt(Block, dwarf::DW_FORM_udata, DV.getAddrElement(++i)); |
| | | 513 | } else if (Element == DIBuilder::OpDeref) { |
| | | 514 | if (!Location.isReg()) |
| | | 515 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); |
| | | 516 | } else |
| | | 517 | llvm_unreachable("unknown DIBuilder Opcode"); |
| | | 518 | } |
| | | 519 | |
| | | 520 | // Now attach the location information to the DIE. |
| | | 521 | addBlock(Die, Attribute, Block); |
| | | 522 | } |
| | | 523 | |
| | | 524 | /* Byref variables, in Blocks, are declared by the programmer as "SomeType |
| | | 525 | VarName;", but the compiler creates a __Block_byref_x_VarName struct, and |
| | | 526 | gives the variable VarName either the struct, or a pointer to the struct, as |
| | | 527 | its type. This is necessary for various behind-the-scenes things the |
| | | 528 | compiler needs to do with by-reference variables in Blocks. |
| | | 529 | |
| | | 530 | However, as far as the original *programmer* is concerned, the variable |
| | | 531 | should still have type 'SomeType', as originally declared. |
| | | 532 | |
| | | 533 | The function getBlockByrefType dives into the __Block_byref_x_VarName |
| | | 534 | struct to find the original type of the variable, which is then assigned to |
| | | 535 | the variable's Debug Information Entry as its real type. So far, so good. |
| | | 536 | However now the debugger will expect the variable VarName to have the type |
| | | 537 | SomeType. So we need the location attribute for the variable to be an |
| | | 538 | expression that explains to the debugger how to navigate through the |
| | | 539 | pointers and struct to find the actual variable of type SomeType. |
| | | 540 | |
| | | 541 | The following function does just that. We start by getting |
| | | 542 | the "normal" location for the variable. This will be the location |
| | | 543 | of either the struct __Block_byref_x_VarName or the pointer to the |
| | | 544 | struct __Block_byref_x_VarName. |
| | | 545 | |
| | | 546 | The struct will look something like: |
| | | 547 | |
| | | 548 | struct __Block_byref_x_VarName { |
| | | 549 | ... <various fields> |
| | | 550 | struct __Block_byref_x_VarName *forwarding; |
| | | 551 | ... <various other fields> |
| | | 552 | SomeType VarName; |
| | | 553 | ... <maybe more fields> |
| | | 554 | }; |
| | | 555 | |
| | | 556 | If we are given the struct directly (as our starting point) we |
| | | 557 | need to tell the debugger to: |
| | | 558 | |
| | | 559 | 1). Add the offset of the forwarding field. |
| | | 560 | |
| | | 561 | 2). Follow that pointer to get the real __Block_byref_x_VarName |
| | | 562 | struct to use (the real one may have been copied onto the heap). |
| | | 563 | |
| | | 564 | 3). Add the offset for the field VarName, to find the actual variable. |
| | | 565 | |
| | | 566 | If we started with a pointer to the struct, then we need to |
| | | 567 | dereference that pointer first, before the other steps. |
| | | 568 | Translating this into DWARF ops, we will need to append the following |
| | | 569 | to the current location description for the variable: |
| | | 570 | |
| | | 571 | DW_OP_deref -- optional, if we start with a pointer |
| | | 572 | DW_OP_plus_uconst <forward_fld_offset> |
| | | 573 | DW_OP_deref |
| | | 574 | DW_OP_plus_uconst <varName_fld_offset> |
| | | 575 | |
| | | 576 | That is what this function does. */ |
| | | 577 | |
| | | 578 | /// addBlockByrefAddress - Start with the address based on the location |
| | | 579 | /// provided, and generate the DWARF information necessary to find the |
| | | 580 | /// actual Block variable (navigating the Block struct) based on the |
| | | 581 | /// starting location. Add the DWARF information to the die. For |
| | | 582 | /// more information, read large comment just above here. |
| | | 583 | /// |
| | | 584 | void CompileUnit::addBlockByrefAddress(const DbgVariable &DV, DIE *Die, |
| | | 585 | dwarf::Attribute Attribute, |
| | | 586 | const MachineLocation &Location) { |
| | | 587 | DIType Ty = DV.getType(); |
| | | 588 | DIType TmpTy = Ty; |
| | | 589 | uint16_t Tag = Ty.getTag(); |
| | | 590 | bool isPointer = false; |
| | | 591 | |
| | | 592 | StringRef varName = DV.getName(); |
| | | 593 | |
| | | 594 | if (Tag == dwarf::DW_TAG_pointer_type) { |
| | | 595 | DIDerivedType DTy(Ty); |
| | | 596 | TmpTy = resolve(DTy.getTypeDerivedFrom()); |
| | | 597 | isPointer = true; |
| | | 598 | } |
| | | 599 | |
| | | 600 | DICompositeType blockStruct(TmpTy); |
| | | 601 | |
| | | 602 | // Find the __forwarding field and the variable field in the __Block_byref |
| | | 603 | // struct. |
| | | 604 | DIArray Fields = blockStruct.getTypeArray(); |
| | | 605 | DIDerivedType varField; |
| | | 606 | DIDerivedType forwardingField; |
| | | 607 | |
| | | 608 | for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) { |
| | | 609 | DIDerivedType DT(Fields.getElement(i)); |
| | | 610 | StringRef fieldName = DT.getName(); |
| | | 611 | if (fieldName == "__forwarding") |
| | | 612 | forwardingField = DT; |
| | | 613 | else if (fieldName == varName) |
| | | 614 | varField = DT; |
| | | 615 | } |
| | | 616 | |
| | | 617 | // Get the offsets for the forwarding field and the variable field. |
| | | 618 | unsigned forwardingFieldOffset = forwardingField.getOffsetInBits() >> 3; |
| | | 619 | unsigned varFieldOffset = varField.getOffsetInBits() >> 2; |
| | | 620 | |
| | | 621 | // Decode the original location, and use that as the start of the byref |
| | | 622 | // variable's location. |
| | | 623 | DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); |
| | | 624 | |
| | | 625 | if (Location.isReg()) |
| | | 626 | addRegisterOp(Block, Location.getReg()); |
| | | 627 | else |
| | | 628 | addRegisterOffset(Block, Location.getReg(), Location.getOffset()); |
| | | 629 | |
| | | 630 | // If we started with a pointer to the __Block_byref... struct, then |
| | | 631 | // the first thing we need to do is dereference the pointer (DW_OP_deref). |
| | | 632 | if (isPointer) |
| | | 633 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); |
| | | 634 | |
| | | 635 | // Next add the offset for the '__forwarding' field: |
| | | 636 | // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in |
| | | 637 | // adding the offset if it's 0. |
| | | 638 | if (forwardingFieldOffset > 0) { |
| | | 639 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); |
| | | 640 | addUInt(Block, dwarf::DW_FORM_udata, forwardingFieldOffset); |
| | | 641 | } |
| | | 642 | |
| | | 643 | // Now dereference the __forwarding field to get to the real __Block_byref |
| | | 644 | // struct: DW_OP_deref. |
| | | 645 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); |
| | | 646 | |
| | | 647 | // Now that we've got the real __Block_byref... struct, add the offset |
| | | 648 | // for the variable's field to get to the location of the actual variable: |
| | | 649 | // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0. |
| | | 650 | if (varFieldOffset > 0) { |
| | | 651 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); |
| | | 652 | addUInt(Block, dwarf::DW_FORM_udata, varFieldOffset); |
| | | 653 | } |
| | | 654 | |
| | | 655 | // Now attach the location information to the DIE. |
| | | 656 | addBlock(Die, Attribute, Block); |
| | | 657 | } |
| | | 658 | |
| | | 659 | /// isTypeSigned - Return true if the type is signed. |
| | | 660 | static bool isTypeSigned(DwarfDebug *DD, DIType Ty, int *SizeInBits) { |
| | | 661 | if (Ty.isDerivedType()) |
| | | 662 | return isTypeSigned(DD, DD->resolve(DIDerivedType(Ty).getTypeDerivedFrom()), |
| | | 663 | SizeInBits); |
| | | 664 | if (Ty.isBasicType()) |
| | | 665 | if (DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed || |
| | | 666 | DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed_char) { |
| | | 667 | *SizeInBits = Ty.getSizeInBits(); |
| | | 668 | return true; |
| | | 669 | } |
| | | 670 | return false; |
| | | 671 | } |
| | | 672 | |
| | | 673 | /// Return true if type encoding is unsigned. |
| | | 674 | static bool isUnsignedDIType(DwarfDebug *DD, DIType Ty) { |
| | | 675 | DIDerivedType DTy(Ty); |
| | | 676 | if (DTy.isDerivedType()) |
| | | 677 | return isUnsignedDIType(DD, DD->resolve(DTy.getTypeDerivedFrom())); |
| | | 678 | |
| | | 679 | DIBasicType BTy(Ty); |
| | | 680 | if (BTy.isBasicType()) { |
| | | 681 | unsigned Encoding = BTy.getEncoding(); |
| | | 682 | if (Encoding == dwarf::DW_ATE_unsigned || |
| | | 683 | Encoding == dwarf::DW_ATE_unsigned_char || |
| | | 684 | Encoding == dwarf::DW_ATE_boolean) |
| | | 685 | return true; |
| | | 686 | } |
| | | 687 | return false; |
| | | 688 | } |
| | | 689 | |
| | | 690 | /// If this type is derived from a base type then return base type size. |
| | | 691 | static uint64_t getBaseTypeSize(DwarfDebug *DD, DIDerivedType Ty) { |
| | | 692 | unsigned Tag = Ty.getTag(); |
| | | 693 | |
| | | 694 | if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef && |
| | | 695 | Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type && |
| | | 696 | Tag != dwarf::DW_TAG_restrict_type) |
| | | 697 | return Ty.getSizeInBits(); |
| | | 698 | |
| | | 699 | DIType BaseType = DD->resolve(Ty.getTypeDerivedFrom()); |
| | | 700 | |
| | | 701 | // If this type is not derived from any type then take conservative approach. |
| | | 702 | if (!BaseType.isValid()) |
| | | 703 | return Ty.getSizeInBits(); |
| | | 704 | |
| | | 705 | // If this is a derived type, go ahead and get the base type, unless it's a |
| | | 706 | // reference then it's just the size of the field. Pointer types have no need |
| | | 707 | // of this since they're a different type of qualification on the type. |
| | | 708 | if (BaseType.getTag() == dwarf::DW_TAG_reference_type || |
| | | 709 | BaseType.getTag() == dwarf::DW_TAG_rvalue_reference_type) |
| | | 710 | return Ty.getSizeInBits(); |
| | | 711 | |
| | | 712 | if (BaseType.isDerivedType()) |
| | | 713 | return getBaseTypeSize(DD, DIDerivedType(BaseType)); |
| | | 714 | |
| | | 715 | return BaseType.getSizeInBits(); |
| | | 716 | } |
| | | 717 | |
| | | 718 | /// addConstantValue - Add constant value entry in variable DIE. |
| | | 719 | void CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO, |
| | | 720 | DIType Ty) { |
| | | 721 | // FIXME: This is a bit conservative/simple - it emits negative values at |
| | | 722 | // their maximum bit width which is a bit unfortunate (& doesn't prefer |
| | | 723 | // udata/sdata over dataN as suggested by the DWARF spec) |
| | | 724 | assert(MO.isImm() && "Invalid machine operand!"); |
| | | 725 | int SizeInBits = -1; |
| | | 726 | bool SignedConstant = isTypeSigned(DD, Ty, &SizeInBits); |
| | | 727 | dwarf::Form Form; |
| | | 728 | |
| | | 729 | // If we're a signed constant definitely use sdata. |
| | | 730 | if (SignedConstant) { |
| | | 731 | addSInt(Die, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, MO.getImm()); |
| | | 732 | return; |
| | | 733 | } |
| | | 734 | |
| | | 735 | // Else use data for now unless it's larger than we can deal with. |
| | | 736 | switch (SizeInBits) { |
| | | 737 | case 8: |
| | | 738 | Form = dwarf::DW_FORM_data1; |
| | | 739 | break; |
| | | 740 | case 16: |
| | | 741 | Form = dwarf::DW_FORM_data2; |
| | | 742 | break; |
| | | 743 | case 32: |
| | | 744 | Form = dwarf::DW_FORM_data4; |
| | | 745 | break; |
| | | 746 | case 64: |
| | | 747 | Form = dwarf::DW_FORM_data8; |
| | | 748 | break; |
| | | 749 | default: |
| | | 750 | Form = dwarf::DW_FORM_udata; |
| | | 751 | addUInt(Die, dwarf::DW_AT_const_value, Form, MO.getImm()); |
| | | 752 | return; |
| | | 753 | } |
| | | 754 | addUInt(Die, dwarf::DW_AT_const_value, Form, MO.getImm()); |
| | | 755 | } |
| | | 756 | |
| | | 757 | /// addConstantFPValue - Add constant value entry in variable DIE. |
| | | 758 | void CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) { |
| | | 759 | assert(MO.isFPImm() && "Invalid machine operand!"); |
| | | 760 | DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); |
| | | 761 | APFloat FPImm = MO.getFPImm()->getValueAPF(); |
| | | 762 | |
| | | 763 | // Get the raw data form of the floating point. |
| | | 764 | const APInt FltVal = FPImm.bitcastToAPInt(); |
| | | 765 | const char *FltPtr = (const char *)FltVal.getRawData(); |
| | | 766 | |
| | | 767 | int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte. |
| | | 768 | bool LittleEndian = Asm->getDataLayout().isLittleEndian(); |
| | | 769 | int Incr = (LittleEndian ? 1 : -1); |
| | | 770 | int Start = (LittleEndian ? 0 : NumBytes - 1); |
| | | 771 | int Stop = (LittleEndian ? NumBytes : -1); |
| | | 772 | |
| | | 773 | // Output the constant to DWARF one byte at a time. |
| | | 774 | for (; Start != Stop; Start += Incr) |
| | | 775 | addUInt(Block, dwarf::DW_FORM_data1, (unsigned char)0xFF & FltPtr[Start]); |
| | | 776 | |
| | | 777 | addBlock(Die, dwarf::DW_AT_const_value, Block); |
| | | 778 | } |
| | | 779 | |
| | | 780 | /// addConstantFPValue - Add constant value entry in variable DIE. |
| | | 781 | void CompileUnit::addConstantFPValue(DIE *Die, const ConstantFP *CFP) { |
| | | 782 | // Pass this down to addConstantValue as an unsigned bag of bits. |
| | | 783 | addConstantValue(Die, CFP->getValueAPF().bitcastToAPInt(), true); |
| | | 784 | } |
| | | 785 | |
| | | 786 | /// addConstantValue - Add constant value entry in variable DIE. |
| | | 787 | void CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI, |
| | | 788 | bool Unsigned) { |
| | | 789 | addConstantValue(Die, CI->getValue(), Unsigned); |
| | | 790 | } |
| | | 791 | |
| | | 792 | // addConstantValue - Add constant value entry in variable DIE. |
| | | 793 | void CompileUnit::addConstantValue(DIE *Die, const APInt &Val, bool Unsigned) { |
| | | 794 | unsigned CIBitWidth = Val.getBitWidth(); |
| | | 795 | if (CIBitWidth <= 64) { |
| | | 796 | // If we're a signed constant definitely use sdata. |
| | | 797 | if (!Unsigned) { |
| | | 798 | addSInt(Die, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, |
| | | 799 | Val.getSExtValue()); |
| | | 800 | return; |
| | | 801 | } |
| | | 802 | |
| | | 803 | // Else use data for now unless it's larger than we can deal with. |
| | | 804 | dwarf::Form Form; |
| | | 805 | switch (CIBitWidth) { |
| | | 806 | case 8: |
| | | 807 | Form = dwarf::DW_FORM_data1; |
| | | 808 | break; |
| | | 809 | case 16: |
| | | 810 | Form = dwarf::DW_FORM_data2; |
| | | 811 | break; |
| | | 812 | case 32: |
| | | 813 | Form = dwarf::DW_FORM_data4; |
| | | 814 | break; |
| | | 815 | case 64: |
| | | 816 | Form = dwarf::DW_FORM_data8; |
| | | 817 | break; |
| | | 818 | default: |
| | | 819 | addUInt(Die, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata, |
| | | 820 | Val.getZExtValue()); |
| | | 821 | return; |
| | | 822 | } |
| | | 823 | addUInt(Die, dwarf::DW_AT_const_value, Form, Val.getZExtValue()); |
| | | 824 | return; |
| | | 825 | } |
| | | 826 | |
| | | 827 | DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); |
| | | 828 | |
| | | 829 | // Get the raw data form of the large APInt. |
| | | 830 | const uint64_t *Ptr64 = Val.getRawData(); |
| | | 831 | |
| | | 832 | int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte. |
| | | 833 | bool LittleEndian = Asm->getDataLayout().isLittleEndian(); |
| | | 834 | |
| | | 835 | // Output the constant to DWARF one byte at a time. |
| | | 836 | for (int i = 0; i < NumBytes; i++) { |
| | | 837 | uint8_t c; |
| | | 838 | if (LittleEndian) |
| | | 839 | c = Ptr64[i / 8] >> (8 * (i & 7)); |
| | | 840 | else |
| | | 841 | c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7)); |
| | | 842 | addUInt(Block, dwarf::DW_FORM_data1, c); |
| | | 843 | } |
| | | 844 | |
| | | 845 | addBlock(Die, dwarf::DW_AT_const_value, Block); |
| | | 846 | } |
| | | 847 | |
| | | 848 | /// addTemplateParams - Add template parameters into buffer. |
| | | 849 | void CompileUnit::addTemplateParams(DIE &Buffer, DIArray TParams) { |
| | | 850 | // Add template parameters. |
| | | 851 | for (unsigned i = 0, e = TParams.getNumElements(); i != e; ++i) { |
| | | 852 | DIDescriptor Element = TParams.getElement(i); |
| | | 853 | if (Element.isTemplateTypeParameter()) |
| | | 854 | constructTemplateTypeParameterDIE(Buffer, |
| | | 855 | DITemplateTypeParameter(Element)); |
| | | 856 | else if (Element.isTemplateValueParameter()) |
| | | 857 | constructTemplateValueParameterDIE(Buffer, |
| | | 858 | DITemplateValueParameter(Element)); |
| | | 859 | } |
| | | 860 | } |
| | | 861 | |
| | | 862 | /// getOrCreateContextDIE - Get context owner's DIE. |
| | | 863 | DIE *CompileUnit::getOrCreateContextDIE(DIScope Context) { |
| | | 864 | if (!Context || Context.isFile()) |
| | | 865 | return getCUDie(); |
| | | 866 | if (Context.isType()) |
| | | 867 | return getOrCreateTypeDIE(DIType(Context)); |
| | | 868 | if (Context.isNameSpace()) |
| | | 869 | return getOrCreateNameSpace(DINameSpace(Context)); |
| | | 870 | if (Context.isSubprogram()) |
| | | 871 | return getOrCreateSubprogramDIE(DISubprogram(Context)); |
| | | 872 | return getDIE(Context); |
| | | 873 | } |
| | | 874 | |
| | | 875 | /// getOrCreateTypeDIE - Find existing DIE or create new DIE for the |
| | | 876 | /// given DIType. |
| | | 877 | DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) { |
| | | 878 | if (!TyNode) |
| | | 879 | return NULL; |
| | | 880 | |
| | | 881 | DIType Ty(TyNode); |
| | | 882 | assert(Ty.isType()); |
| | | 883 | |
| | | 884 | // Construct the context before querying for the existence of the DIE in case |
| | | 885 | // such construction creates the DIE. |
| | | 886 | DIE *ContextDIE = getOrCreateContextDIE(resolve(Ty.getContext())); |
| | | 887 | assert(ContextDIE); |
| | | 888 | |
| | | 889 | DIE *TyDIE = getDIE(Ty); |
| | | 890 | if (TyDIE) |
| | | 891 | return TyDIE; |
| | | 892 | |
| | | 893 | // Create new type. |
| | | 894 | TyDIE = createAndAddDIE(Ty.getTag(), *ContextDIE, Ty); |
| | | 895 | |
| | | 896 | if (Ty.isBasicType()) |
| | | 897 | constructTypeDIE(*TyDIE, DIBasicType(Ty)); |
| | | 898 | else if (Ty.isCompositeType()) |
| | | 899 | constructTypeDIE(*TyDIE, DICompositeType(Ty)); |
| | | 900 | else { |
| | | 901 | assert(Ty.isDerivedType() && "Unknown kind of DIType"); |
| | | 902 | constructTypeDIE(*TyDIE, DIDerivedType(Ty)); |
| | | 903 | } |
| | | 904 | // If this is a named finished type then include it in the list of types |
| | | 905 | // for the accelerator tables. |
| | | 906 | if (!Ty.getName().empty() && !Ty.isForwardDecl()) { |
| | | 907 | bool IsImplementation = 0; |
| | | 908 | if (Ty.isCompositeType()) { |
| | | 909 | DICompositeType CT(Ty); |
| | | 910 | // A runtime language of 0 actually means C/C++ and that any |
| | | 911 | // non-negative value is some version of Objective-C/C++. |
| | | 912 | IsImplementation = (CT.getRunTimeLang() == 0) || CT.isObjcClassComplete(); |
| | | 913 | } |
| | | 914 | unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0; |
| | | 915 | addAccelType(Ty.getName(), std::make_pair(TyDIE, Flags)); |
| | | 916 | } |
| | | 917 | |
| | | 918 | return TyDIE; |
| | | 919 | } |
| | | 920 | |
| | | 921 | /// addType - Add a new type attribute to the specified entity. |
| | | 922 | void CompileUnit::addType(DIE *Entity, DIType Ty, dwarf::Attribute Attribute) { |
| | | 923 | assert(Ty && "Trying to add a type that doesn't exist?"); |
| | | 924 | |
| | | 925 | // Check for pre-existence. |
| | | 926 | DIEEntry *Entry = getDIEEntry(Ty); |
| | | 927 | // If it exists then use the existing value. |
| | | 928 | if (Entry) { |
| | | 929 | addDIEEntry(Entity, Attribute, Entry); |
| | | 930 | return; |
| | | 931 | } |
| | | 932 | |
| | | 933 | // Construct type. |
| | | 934 | DIE *Buffer = getOrCreateTypeDIE(Ty); |
| | | 935 | |
| | | 936 | // Set up proxy. |
| | | 937 | Entry = createDIEEntry(Buffer); |
| | | 938 | insertDIEEntry(Ty, Entry); |
| | | 939 | addDIEEntry(Entity, Attribute, Entry); |
| | | 940 | |
| | | 941 | // If this is a complete composite type then include it in the |
| | | 942 | // list of global types. |
| | | 943 | addGlobalType(Ty); |
| | | 944 | } |
| | | 945 | |
| | | 946 | // Accelerator table mutators - add each name along with its companion |
| | | 947 | // DIE to the proper table while ensuring that the name that we're going |
| | | 948 | // to reference is in the string table. We do this since the names we |
| | | 949 | // add may not only be identical to the names in the DIE. |
| | | 950 | void CompileUnit::addAccelName(StringRef Name, DIE *Die) { |
| | | 951 | DU->getStringPoolEntry(Name); |
| | | 952 | std::vector<DIE *> &DIEs = AccelNames[Name]; |
| | | 953 | DIEs.push_back(Die); |
| | | 954 | } |
| | | 955 | |
| | | 956 | void CompileUnit::addAccelObjC(StringRef Name, DIE *Die) { |
| | | 957 | DU->getStringPoolEntry(Name); |
| | | 958 | std::vector<DIE *> &DIEs = AccelObjC[Name]; |
| | | 959 | DIEs.push_back(Die); |
| | | 960 | } |
| | | 961 | |
| | | 962 | void CompileUnit::addAccelNamespace(StringRef Name, DIE *Die) { |
| | | 963 | DU->getStringPoolEntry(Name); |
| | | 964 | std::vector<DIE *> &DIEs = AccelNamespace[Name]; |
| | | 965 | DIEs.push_back(Die); |
| | | 966 | } |
| | | 967 | |
| | | 968 | void CompileUnit::addAccelType(StringRef Name, std::pair<DIE *, unsigned> Die) { |
| | | 969 | DU->getStringPoolEntry(Name); |
| | | 970 | std::vector<std::pair<DIE *, unsigned> > &DIEs = AccelTypes[Name]; |
| | | 971 | DIEs.push_back(Die); |
| | | 972 | } |
| | | 973 | |
| | | 974 | /// addGlobalName - Add a new global name to the compile unit. |
| | | 975 | void CompileUnit::addGlobalName(StringRef Name, DIE *Die, DIScope Context) { |
| | | 976 | std::string FullName = getParentContextString(Context) + Name.str(); |
| | | 977 | GlobalNames[FullName] = Die; |
| | | 978 | } |
| | | 979 | |
| | | 980 | /// addGlobalType - Add a new global type to the compile unit. |
| | | 981 | /// |
| | | 982 | void CompileUnit::addGlobalType(DIType Ty) { |
| | | 983 | DIScope Context = resolve(Ty.getContext()); |
| | | 984 | if (!Ty.getName().empty() && !Ty.isForwardDecl() && |
| | | 985 | (!Context || Context.isCompileUnit() || Context.isFile() || |
| | | 986 | Context.isNameSpace())) |
| | | 987 | if (DIEEntry *Entry = getDIEEntry(Ty)) { |
| | | 988 | std::string FullName = |
| | | 989 | getParentContextString(Context) + Ty.getName().str(); |
| | | 990 | GlobalTypes[FullName] = Entry->getEntry(); |
| | | 991 | } |
| | | 992 | } |
| | | 993 | |
| | | 994 | /// getParentContextString - Walks the metadata parent chain in a language |
| | | 995 | /// specific manner (using the compile unit language) and returns |
| | | 996 | /// it as a string. This is done at the metadata level because DIEs may |
| | | 997 | /// not currently have been added to the parent context and walking the |
| | | 998 | /// DIEs looking for names is more expensive than walking the metadata. |
| | | 999 | std::string CompileUnit::getParentContextString(DIScope Context) const { |
| | | 1000 | if (!Context) |
| | | 1001 | return ""; |
| | | 1002 | |
| | | 1003 | // FIXME: Decide whether to implement this for non-C++ languages. |
| | | 1004 | if (getLanguage() != dwarf::DW_LANG_C_plus_plus) |
| | | 1005 | return ""; |
| | | 1006 | |
| | | 1007 | std::string CS; |
| | | 1008 | SmallVector<DIScope, 1> Parents; |
| | | 1009 | while (!Context.isCompileUnit()) { |
| | | 1010 | Parents.push_back(Context); |
| | | 1011 | if (Context.getContext()) |
| | | 1012 | Context = resolve(Context.getContext()); |
| | | 1013 | else |
| | | 1014 | // Structure, etc types will have a NULL context if they're at the top |
| | | 1015 | // level. |
| | | 1016 | break; |
| | | 1017 | } |
| | | 1018 | |
| | | 1019 | // Reverse iterate over our list to go from the outermost construct to the |
| | | 1020 | // innermost. |
| | | 1021 | for (SmallVectorImpl<DIScope>::reverse_iterator I = Parents.rbegin(), |
| | | 1022 | E = Parents.rend(); |
| | | 1023 | I != E; ++I) { |
| | | 1024 | DIScope Ctx = *I; |
| | | 1025 | StringRef Name = Ctx.getName(); |
| | | 1026 | if (!Name.empty()) { |
| | | 1027 | CS += Name; |
| | | 1028 | CS += "::"; |
| | | 1029 | } |
| | | 1030 | } |
| | | 1031 | return CS; |
| | | 1032 | } |
| | | 1033 | |
| | | 1034 | /// addPubTypes - Add subprogram argument types for pubtypes section. |
| | | 1035 | void CompileUnit::addPubTypes(DISubprogram SP) { |
| | | 1036 | DICompositeType SPTy = SP.getType(); |
| | | 1037 | uint16_t SPTag = SPTy.getTag(); |
| | | 1038 | if (SPTag != dwarf::DW_TAG_subroutine_type) |
| | | 1039 | return; |
| | | 1040 | |
| | | 1041 | DIArray Args = SPTy.getTypeArray(); |
| | | 1042 | for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) { |
| | | 1043 | DIType ATy(Args.getElement(i)); |
| | | 1044 | if (!ATy.isType()) |
| | | 1045 | continue; |
| | | 1046 | addGlobalType(ATy); |
| | | 1047 | } |
57 | } | | 1048 | } |
58 | | | 1049 | |
59 | unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName, | | 1050 | /// constructTypeDIE - Construct basic type die from DIBasicType. |
60 | StringRef DirName) { | | 1051 | void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) { |
61 | // If we print assembly, we can't separate .file entries according to | | 1052 | // Get core information. |
62 | // compile units. Thus all files will belong to the default compile unit. | | 1053 | StringRef Name = BTy.getName(); |
63 | | | 1054 | // Add name if not anonymous or intermediate type. |
64 | // FIXME: add a better feature test than hasRawTextSupport. Even better, | | 1055 | if (!Name.empty()) |
65 | // extend .file to support this. | | 1056 | addString(&Buffer, dwarf::DW_AT_name, Name); |
66 | return Asm->OutStreamer.EmitDwarfFileDirective( | | 1057 | |
67 | 0, DirName, FileName, | | 1058 | // An unspecified type only has a name attribute. |
68 | Asm->OutStreamer.hasRawTextSupport() ? 0 : getUniqueID()); | | 1059 | if (BTy.getTag() == dwarf::DW_TAG_unspecified_type) |
| | | 1060 | return; |
| | | 1061 | |
| | | 1062 | addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, |
| | | 1063 | BTy.getEncoding()); |
| | | 1064 | |
| | | 1065 | uint64_t Size = BTy.getSizeInBits() >> 3; |
| | | 1066 | addUInt(&Buffer, dwarf::DW_AT_byte_size, None, Size); |
| | | 1067 | } |
| | | 1068 | |
| | | 1069 | /// constructTypeDIE - Construct derived type die from DIDerivedType. |
| | | 1070 | void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) { |
| | | 1071 | // Get core information. |
| | | 1072 | StringRef Name = DTy.getName(); |
| | | 1073 | uint64_t Size = DTy.getSizeInBits() >> 3; |
| | | 1074 | uint16_t Tag = Buffer.getTag(); |
| | | 1075 | |
| | | 1076 | // Map to main type, void will not have a type. |
| | | 1077 | DIType FromTy = resolve(DTy.getTypeDerivedFrom()); |
| | | 1078 | if (FromTy) |
| | | 1079 | addType(&Buffer, FromTy); |
| | | 1080 | |
| | | 1081 | // Add name if not anonymous or intermediate type. |
| | | 1082 | if (!Name.empty()) |
| | | 1083 | addString(&Buffer, dwarf::DW_AT_name, Name); |
| | | 1084 | |
| | | 1085 | // Add size if non-zero (derived types might be zero-sized.) |
| | | 1086 | if (Size && Tag != dwarf::DW_TAG_pointer_type) |
| | | 1087 | addUInt(&Buffer, dwarf::DW_AT_byte_size, None, Size); |
| | | 1088 | |
| | | 1089 | if (Tag == dwarf::DW_TAG_ptr_to_member_type) |
| | | 1090 | addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, |
| | | 1091 | getOrCreateTypeDIE(resolve(DTy.getClassType()))); |
| | | 1092 | // Add source line info if available and TyDesc is not a forward declaration. |
| | | 1093 | if (!DTy.isForwardDecl()) |
| | | 1094 | addSourceLine(&Buffer, DTy); |
| | | 1095 | } |
| | | 1096 | |
| | | 1097 | /// Return true if the type is appropriately scoped to be contained inside |
| | | 1098 | /// its own type unit. |
| | | 1099 | static bool isTypeUnitScoped(DIType Ty, const DwarfDebug *DD) { |
| | | 1100 | DIScope Parent = DD->resolve(Ty.getContext()); |
| | | 1101 | while (Parent) { |
| | | 1102 | // Don't generate a hash for anything scoped inside a function. |
| | | 1103 | if (Parent.isSubprogram()) |
| | | 1104 | return false; |
| | | 1105 | Parent = DD->resolve(Parent.getContext()); |
| | | 1106 | } |
| | | 1107 | return true; |
| | | 1108 | } |
| | | 1109 | |
| | | 1110 | /// Return true if the type should be split out into a type unit. |
| | | 1111 | static bool shouldCreateTypeUnit(DICompositeType CTy, const DwarfDebug *DD) { |
| | | 1112 | uint16_t Tag = CTy.getTag(); |
| | | 1113 | |
| | | 1114 | switch (Tag) { |
| | | 1115 | case dwarf::DW_TAG_structure_type: |
| | | 1116 | case dwarf::DW_TAG_union_type: |
| | | 1117 | case dwarf::DW_TAG_enumeration_type: |
| | | 1118 | case dwarf::DW_TAG_class_type: |
| | | 1119 | // If this is a class, structure, union, or enumeration type |
| | | 1120 | // that is a definition (not a declaration), and not scoped |
| | | 1121 | // inside a function then separate this out as a type unit. |
| | | 1122 | return !CTy.isForwardDecl() && isTypeUnitScoped(CTy, DD); |
| | | 1123 | default: |
| | | 1124 | return false; |
| | | 1125 | } |
| | | 1126 | } |
| | | 1127 | |
| | | 1128 | /// constructTypeDIE - Construct type DIE from DICompositeType. |
| | | 1129 | void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { |
| | | 1130 | // Get core information. |
| | | 1131 | StringRef Name = CTy.getName(); |
| | | 1132 | |
| | | 1133 | uint64_t Size = CTy.getSizeInBits() >> 3; |
| | | 1134 | uint16_t Tag = Buffer.getTag(); |
| | | 1135 | |
| | | 1136 | switch (Tag) { |
| | | 1137 | case dwarf::DW_TAG_array_type: |
| | | 1138 | constructArrayTypeDIE(Buffer, CTy); |
| | | 1139 | break; |
| | | 1140 | case dwarf::DW_TAG_enumeration_type: |
| | | 1141 | constructEnumTypeDIE(Buffer, CTy); |
| | | 1142 | break; |
| | | 1143 | case dwarf::DW_TAG_subroutine_type: { |
| | | 1144 | // Add return type. A void return won't have a type. |
| | | 1145 | DIArray Elements = CTy.getTypeArray(); |
| | | 1146 | DIType RTy(Elements.getElement(0)); |
| | | 1147 | if (RTy) |
| | | 1148 | addType(&Buffer, RTy); |
| | | 1149 | |
| | | 1150 | bool isPrototyped = true; |
| | | 1151 | // Add arguments. |
| | | 1152 | for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) { |
| | | 1153 | DIDescriptor Ty = Elements.getElement(i); |
| | | 1154 | if (Ty.isUnspecifiedParameter()) { |
| | | 1155 | createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, Buffer); |
| | | 1156 | isPrototyped = false; |
| | | 1157 | } else { |
| | | 1158 | DIE *Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, Buffer); |
| | | 1159 | addType(Arg, DIType(Ty)); |
| | | 1160 | if (DIType(Ty).isArtificial()) |
| | | 1161 | addFlag(Arg, dwarf::DW_AT_artificial); |
| | | 1162 | } |
| | | 1163 | } |
| | | 1164 | // Add prototype flag if we're dealing with a C language and the |
| | | 1165 | // function has been prototyped. |
| | | 1166 | uint16_t Language = getLanguage(); |
| | | 1167 | if (isPrototyped && |
| | | 1168 | (Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 || |
| | | 1169 | Language == dwarf::DW_LANG_ObjC)) |
| | | 1170 | addFlag(&Buffer, dwarf::DW_AT_prototyped); |
| | | 1171 | } break; |
| | | 1172 | case dwarf::DW_TAG_structure_type: |
| | | 1173 | case dwarf::DW_TAG_union_type: |
| | | 1174 | case dwarf::DW_TAG_class_type: { |
| | | 1175 | // Add elements to structure type. |
| | | 1176 | DIArray Elements = CTy.getTypeArray(); |
| | | 1177 | for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { |
| | | 1178 | DIDescriptor Element = Elements.getElement(i); |
| | | 1179 | DIE *ElemDie = NULL; |
| | | 1180 | if (Element.isSubprogram()) { |
| | | 1181 | DISubprogram SP(Element); |
| | | 1182 | ElemDie = getOrCreateSubprogramDIE(SP); |
| | | 1183 | if (SP.isProtected()) |
| | | 1184 | addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, |
| | | 1185 | dwarf::DW_ACCESS_protected); |
| | | 1186 | else if (SP.isPrivate()) |
| | | 1187 | addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, |
| | | 1188 | dwarf::DW_ACCESS_private); |
| | | 1189 | else |
| | | 1190 | addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, |
| | | 1191 | dwarf::DW_ACCESS_public); |
| | | 1192 | if (SP.isExplicit()) |
| | | 1193 | addFlag(ElemDie, dwarf::DW_AT_explicit); |
| | | 1194 | } else if (Element.isDerivedType()) { |
| | | 1195 | DIDerivedType DDTy(Element); |
| | | 1196 | if (DDTy.getTag() == dwarf::DW_TAG_friend) { |
| | | 1197 | ElemDie = createAndAddDIE(dwarf::DW_TAG_friend, Buffer); |
| | | 1198 | addType(ElemDie, resolve(DDTy.getTypeDerivedFrom()), |
| | | 1199 | dwarf::DW_AT_friend); |
| | | 1200 | } else if (DDTy.isStaticMember()) { |
| | | 1201 | getOrCreateStaticMemberDIE(DDTy); |
| | | 1202 | } else { |
| | | 1203 | constructMemberDIE(Buffer, DDTy); |
| | | 1204 | } |
| | | 1205 | } else if (Element.isObjCProperty()) { |
| | | 1206 | DIObjCProperty Property(Element); |
| | | 1207 | ElemDie = createAndAddDIE(Property.getTag(), Buffer); |
| | | 1208 | StringRef PropertyName = Property.getObjCPropertyName(); |
| | | 1209 | addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName); |
| | | 1210 | addType(ElemDie, Property.getType()); |
| | | 1211 | addSourceLine(ElemDie, Property); |
| | | 1212 | StringRef GetterName = Property.getObjCPropertyGetterName(); |
| | | 1213 | if (!GetterName.empty()) |
| | | 1214 | addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName); |
| | | 1215 | StringRef SetterName = Property.getObjCPropertySetterName(); |
| | | 1216 | if (!SetterName.empty()) |
| | | 1217 | addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName); |
| | | 1218 | unsigned PropertyAttributes = 0; |
| | | 1219 | if (Property.isReadOnlyObjCProperty()) |
| | | 1220 | PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly; |
| | | 1221 | if (Property.isReadWriteObjCProperty()) |
| | | 1222 | PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite; |
| | | 1223 | if (Property.isAssignObjCProperty()) |
| | | 1224 | PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign; |
| | | 1225 | if (Property.isRetainObjCProperty()) |
| | | 1226 | PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain; |
| | | 1227 | if (Property.isCopyObjCProperty()) |
| | | 1228 | PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy; |
| | | 1229 | if (Property.isNonAtomicObjCProperty()) |
| | | 1230 | PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic; |
| | | 1231 | if (PropertyAttributes) |
| | | 1232 | addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, None, |
| | | 1233 | PropertyAttributes); |
| | | 1234 | |
| | | 1235 | DIEEntry *Entry = getDIEEntry(Element); |
| | | 1236 | if (!Entry) { |
| | | 1237 | Entry = createDIEEntry(ElemDie); |
| | | 1238 | insertDIEEntry(Element, Entry); |
| | | 1239 | } |
| | | 1240 | } else |
| | | 1241 | continue; |
| | | 1242 | } |
| | | 1243 | |
| | | 1244 | if (CTy.isAppleBlockExtension()) |
| | | 1245 | addFlag(&Buffer, dwarf::DW_AT_APPLE_block); |
| | | 1246 | |
| | | 1247 | DICompositeType ContainingType(resolve(CTy.getContainingType())); |
| | | 1248 | if (ContainingType) |
| | | 1249 | addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, |
| | | 1250 | getOrCreateTypeDIE(ContainingType)); |
| | | 1251 | |
| | | 1252 | if (CTy.isObjcClassComplete()) |
| | | 1253 | addFlag(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type); |
| | | 1254 | |
| | | 1255 | // Add template parameters to a class, structure or union types. |
| | | 1256 | // FIXME: The support isn't in the metadata for this yet. |
| | | 1257 | if (Tag == dwarf::DW_TAG_class_type || |
| | | 1258 | Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) |
| | | 1259 | addTemplateParams(Buffer, CTy.getTemplateParams()); |
| | | 1260 | |
| | | 1261 | break; |
| | | 1262 | } |
| | | 1263 | default: |
| | | 1264 | break; |
| | | 1265 | } |
| | | 1266 | |
| | | 1267 | // Add name if not anonymous or intermediate type. |
| | | 1268 | if (!Name.empty()) |
| | | 1269 | addString(&Buffer, dwarf::DW_AT_name, Name); |
| | | 1270 | |
| | | 1271 | if (Tag == dwarf::DW_TAG_enumeration_type || |
| | | 1272 | Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type || |
| | | 1273 | Tag == dwarf::DW_TAG_union_type) { |
| | | 1274 | // Add size if non-zero (derived types might be zero-sized.) |
| | | 1275 | // TODO: Do we care about size for enum forward declarations? |
| | | 1276 | if (Size) |
| | | 1277 | addUInt(&Buffer, dwarf::DW_AT_byte_size, None, Size); |
| | | 1278 | else if (!CTy.isForwardDecl()) |
| | | 1279 | // Add zero size if it is not a forward declaration. |
| | | 1280 | addUInt(&Buffer, dwarf::DW_AT_byte_size, None, 0); |
| | | 1281 | |
| | | 1282 | // If we're a forward decl, say so. |
| | | 1283 | if (CTy.isForwardDecl()) |
| | | 1284 | addFlag(&Buffer, dwarf::DW_AT_declaration); |
| | | 1285 | |
| | | 1286 | // Add source line info if available. |
| | | 1287 | if (!CTy.isForwardDecl()) |
| | | 1288 | addSourceLine(&Buffer, CTy); |
| | | 1289 | |
| | | 1290 | // No harm in adding the runtime language to the declaration. |
| | | 1291 | unsigned RLang = CTy.getRunTimeLang(); |
| | | 1292 | if (RLang) |
| | | 1293 | addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1, |
| | | 1294 | RLang); |
| | | 1295 | } |
| | | 1296 | // If this is a type applicable to a type unit it then add it to the |
| | | 1297 | // list of types we'll compute a hash for later. |
| | | 1298 | if (shouldCreateTypeUnit(CTy, DD)) |
| | | 1299 | DD->addTypeUnitType(&Buffer); |
| | | 1300 | } |
| | | 1301 | |
| | | 1302 | /// constructTemplateTypeParameterDIE - Construct new DIE for the given |
| | | 1303 | /// DITemplateTypeParameter. |
| | | 1304 | void |
| | | 1305 | CompileUnit::constructTemplateTypeParameterDIE(DIE &Buffer, |
| | | 1306 | DITemplateTypeParameter TP) { |
| | | 1307 | DIE *ParamDIE = |
| | | 1308 | createAndAddDIE(dwarf::DW_TAG_template_type_parameter, Buffer); |
| | | 1309 | // Add the type if it exists, it could be void and therefore no type. |
| | | 1310 | if (TP.getType()) |
| | | 1311 | addType(ParamDIE, resolve(TP.getType())); |
| | | 1312 | if (!TP.getName().empty()) |
| | | 1313 | addString(ParamDIE, dwarf::DW_AT_name, TP.getName()); |
| | | 1314 | } |
| | | 1315 | |
| | | 1316 | /// constructTemplateValueParameterDIE - Construct new DIE for the given |
| | | 1317 | /// DITemplateValueParameter. |
| | | 1318 | void |
| | | 1319 | CompileUnit::constructTemplateValueParameterDIE(DIE &Buffer, |
| | | 1320 | DITemplateValueParameter VP) { |
| | | 1321 | DIE *ParamDIE = createAndAddDIE(VP.getTag(), Buffer); |
| | | 1322 | |
| | | 1323 | // Add the type if there is one, template template and template parameter |
| | | 1324 | // packs will not have a type. |
| | | 1325 | if (VP.getTag() == dwarf::DW_TAG_template_value_parameter) |
| | | 1326 | addType(ParamDIE, resolve(VP.getType())); |
| | | 1327 | if (!VP.getName().empty()) |
| | | 1328 | addString(ParamDIE, dwarf::DW_AT_name, VP.getName()); |
| | | 1329 | if (Value *Val = VP.getValue()) { |
| | | 1330 | if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) |
| | | 1331 | addConstantValue(ParamDIE, CI, |
| | | 1332 | isUnsignedDIType(DD, resolve(VP.getType()))); |
| | | 1333 | else if (GlobalValue *GV = dyn_cast<GlobalValue>(Val)) { |
| | | 1334 | // For declaration non-type template parameters (such as global values and |
| | | 1335 | // functions) |
| | | 1336 | DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); |
| | | 1337 | addOpAddress(Block, Asm->getSymbol(GV)); |
| | | 1338 | // Emit DW_OP_stack_value to use the address as the immediate value of the |
| | | 1339 | // parameter, rather than a pointer to it. |
| | | 1340 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value); |
| | | 1341 | addBlock(ParamDIE, dwarf::DW_AT_location, Block); |
| | | 1342 | } else if (VP.getTag() == dwarf::DW_TAG_GNU_template_template_param) { |
| | | 1343 | assert(isa<MDString>(Val)); |
| | | 1344 | addString(ParamDIE, dwarf::DW_AT_GNU_template_name, |
| | | 1345 | cast<MDString>(Val)->getString()); |
| | | 1346 | } else if (VP.getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) { |
| | | 1347 | assert(isa<MDNode>(Val)); |
| | | 1348 | DIArray A(cast<MDNode>(Val)); |
| | | 1349 | addTemplateParams(*ParamDIE, A); |
| | | 1350 | } |
| | | 1351 | } |
| | | 1352 | } |
| | | 1353 | |
| | | 1354 | /// getOrCreateNameSpace - Create a DIE for DINameSpace. |
| | | 1355 | DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) { |
| | | 1356 | // Construct the context before querying for the existence of the DIE in case |
| | | 1357 | // such construction creates the DIE. |
| | | 1358 | DIE *ContextDIE = getOrCreateContextDIE(NS.getContext()); |
| | | 1359 | |
| | | 1360 | DIE *NDie = getDIE(NS); |
| | | 1361 | if (NDie) |
| | | 1362 | return NDie; |
| | | 1363 | NDie = createAndAddDIE(dwarf::DW_TAG_namespace, *ContextDIE, NS); |
| | | 1364 | |
| | | 1365 | if (!NS.getName().empty()) { |
| | | 1366 | addString(NDie, dwarf::DW_AT_name, NS.getName()); |
| | | 1367 | addAccelNamespace(NS.getName(), NDie); |
| | | 1368 | addGlobalName(NS.getName(), NDie, NS.getContext()); |
| | | 1369 | } else |
| | | 1370 | addAccelNamespace("(anonymous namespace)", NDie); |
| | | 1371 | addSourceLine(NDie, NS); |
| | | 1372 | return NDie; |
| | | 1373 | } |
| | | 1374 | |
| | | 1375 | /// getOrCreateSubprogramDIE - Create new DIE using SP. |
| | | 1376 | DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) { |
| | | 1377 | // Construct the context before querying for the existence of the DIE in case |
| | | 1378 | // such construction creates the DIE (as is the case for member function |
| | | 1379 | // declarations). |
| | | 1380 | DIE *ContextDIE = getOrCreateContextDIE(resolve(SP.getContext())); |
| | | 1381 | |
| | | 1382 | DIE *SPDie = getDIE(SP); |
| | | 1383 | if (SPDie) |
| | | 1384 | return SPDie; |
| | | 1385 | |
| | | 1386 | DISubprogram SPDecl = SP.getFunctionDeclaration(); |
| | | 1387 | if (SPDecl.isSubprogram()) |
| | | 1388 | // Add subprogram definitions to the CU die directly. |
| | | 1389 | ContextDIE = CUDie.get(); |
| | | 1390 | |
| | | 1391 | // DW_TAG_inlined_subroutine may refer to this DIE. |
| | | 1392 | SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP); |
| | | 1393 | |
| | | 1394 | DIE *DeclDie = NULL; |
| | | 1395 | if (SPDecl.isSubprogram()) |
| | | 1396 | DeclDie = getOrCreateSubprogramDIE(SPDecl); |
| | | 1397 | |
| | | 1398 | // Add function template parameters. |
| | | 1399 | addTemplateParams(*SPDie, SP.getTemplateParams()); |
| | | 1400 | |
| | | 1401 | // If this DIE is going to refer declaration info using AT_specification |
| | | 1402 | // then there is no need to add other attributes. |
| | | 1403 | if (DeclDie) { |
| | | 1404 | // Refer function declaration directly. |
| | | 1405 | addDIEEntry(SPDie, dwarf::DW_AT_specification, DeclDie); |
| | | 1406 | |
| | | 1407 | return SPDie; |
| | | 1408 | } |
| | | 1409 | |
| | | 1410 | // Add the linkage name if we have one. |
| | | 1411 | StringRef LinkageName = SP.getLinkageName(); |
| | | 1412 | if (!LinkageName.empty()) |
| | | 1413 | addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, |
| | | 1414 | GlobalValue::getRealLinkageName(LinkageName)); |
| | | 1415 | |
| | | 1416 | // Constructors and operators for anonymous aggregates do not have names. |
| | | 1417 | if (!SP.getName().empty()) |
| | | 1418 | addString(SPDie, dwarf::DW_AT_name, SP.getName()); |
| | | 1419 | |
| | | 1420 | addSourceLine(SPDie, SP); |
| | | 1421 | |
| | | 1422 | // Add the prototype if we have a prototype and we have a C like |
| | | 1423 | // language. |
| | | 1424 | uint16_t Language = getLanguage(); |
| | | 1425 | if (SP.isPrototyped() && |
| | | 1426 | (Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 || |
| | | 1427 | Language == dwarf::DW_LANG_ObjC)) |
| | | 1428 | addFlag(SPDie, dwarf::DW_AT_prototyped); |
| | | 1429 | |
| | | 1430 | DICompositeType SPTy = SP.getType(); |
| | | 1431 | assert(SPTy.getTag() == dwarf::DW_TAG_subroutine_type && |
| | | 1432 | "the type of a subprogram should be a subroutine"); |
| | | 1433 | |
| | | 1434 | DIArray Args = SPTy.getTypeArray(); |
| | | 1435 | // Add a return type. If this is a type like a C/C++ void type we don't add a |
| | | 1436 | // return type. |
| | | 1437 | if (Args.getElement(0)) |
| | | 1438 | addType(SPDie, DIType(Args.getElement(0))); |
| | | 1439 | |
| | | 1440 | unsigned VK = SP.getVirtuality(); |
| | | 1441 | if (VK) { |
| | | 1442 | addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK); |
| | | 1443 | DIEBlock *Block = getDIEBlock(); |
| | | 1444 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); |
| | | 1445 | addUInt(Block, dwarf::DW_FORM_udata, SP.getVirtualIndex()); |
| | | 1446 | addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, Block); |
| | | 1447 | ContainingTypeMap.insert( |
| | | 1448 | std::make_pair(SPDie, resolve(SP.getContainingType()))); |
| | | 1449 | } |
| | | 1450 | |
| | | 1451 | if (!SP.isDefinition()) { |
| | | 1452 | addFlag(SPDie, dwarf::DW_AT_declaration); |
| | | 1453 | |
| | | 1454 | // Add arguments. Do not add arguments for subprogram definition. They will |
| | | 1455 | // be handled while processing variables. |
| | | 1456 | for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { |
| | | 1457 | DIE *Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, *SPDie); |
| | | 1458 | DIType ATy(Args.getElement(i)); |
| | | 1459 | addType(Arg, ATy); |
| | | 1460 | if (ATy.isArtificial()) |
| | | 1461 | addFlag(Arg, dwarf::DW_AT_artificial); |
| | | 1462 | } |
| | | 1463 | } |
| | | 1464 | |
| | | 1465 | if (SP.isArtificial()) |
| | | 1466 | addFlag(SPDie, dwarf::DW_AT_artificial); |
| | | 1467 | |
| | | 1468 | if (!SP.isLocalToUnit()) |
| | | 1469 | addFlag(SPDie, dwarf::DW_AT_external); |
| | | 1470 | |
| | | 1471 | if (SP.isOptimized()) |
| | | 1472 | addFlag(SPDie, dwarf::DW_AT_APPLE_optimized); |
| | | 1473 | |
| | | 1474 | if (unsigned isa = Asm->getISAEncoding()) { |
| | | 1475 | addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa); |
| | | 1476 | } |
| | | 1477 | |
| | | 1478 | return SPDie; |
69 | } | | 1479 | } |
70 | | | 1480 | |
71 | // Return const expression if value is a GEP to access merged global | | 1481 | // Return const expression if value is a GEP to access merged global |
72 | // constant. e.g. | | 1482 | // constant. e.g. |
73 | // i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0) | | 1483 | // i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0) |
74 | static const ConstantExpr *getMergedGlobalExpr(const Value *V) { | | 1484 | static const ConstantExpr *getMergedGlobalExpr(const Value *V) { |
75 | const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V); | | 1485 | const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V); |
76 | if (!CE || CE->getNumOperands() != 3 || | | 1486 | if (!CE || CE->getNumOperands() != 3 || |
77 | CE->getOpcode() != Instruction::GetElementPtr) | | 1487 | CE->getOpcode() != Instruction::GetElementPtr) |
78 | return nullptr; | | 1488 | return NULL; |
79 | | | 1489 | |
80 | // First operand points to a global struct. | | 1490 | // First operand points to a global struct. |
81 | Value *Ptr = CE->getOperand(0); | | 1491 | Value *Ptr = CE->getOperand(0); |
82 | if (!isa<GlobalValue>(Ptr) || | | 1492 | if (!isa<GlobalValue>(Ptr) || |
83 | !isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType())) | | 1493 | !isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType())) |
84 | return nullptr; | | 1494 | return NULL; |
85 | | | 1495 | |
86 | // Second operand is zero. | | 1496 | // Second operand is zero. |
87 | const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1)); | | 1497 | const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1)); |
88 | if (!CI || !CI->isZero()) | | 1498 | if (!CI || !CI->isZero()) |
89 | return nullptr; | | 1499 | return NULL; |
90 | | | 1500 | |
91 | // Third operand is offset. | | 1501 | // Third operand is offset. |
92 | if (!isa<ConstantInt>(CE->getOperand(2))) | | 1502 | if (!isa<ConstantInt>(CE->getOperand(2))) |
93 | return nullptr; | | 1503 | return NULL; |
94 | | | 1504 | |
95 | return CE; | | 1505 | return CE; |
96 | } | | 1506 | } |
97 | | | 1507 | |
98 | /// getOrCreateGlobalVariableDIE - get or create global variable DIE. | | 1508 | /// createGlobalVariableDIE - create global variable DIE. |
99 | DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(DIGlobalVariable GV) { | | 1509 | void CompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) { |
| | | 1510 | |
100 | // Check for pre-existence. | | 1511 | // Check for pre-existence. |
101 | if (DIE *Die = getDIE(GV)) | | 1512 | if (getDIE(GV)) |
102 | return Die; | | 1513 | return; |
103 | | | 1514 | |
104 | assert(GV.isGlobalVariable()); | | 1515 | if (!GV.isGlobalVariable()) |
| | | 1516 | return; |
105 | | | 1517 | |
106 | DIScope GVContext = GV.getContext(); | | 1518 | DIScope GVContext = GV.getContext(); |
107 | DIType GTy = DD->resolve(GV.getType()); | | 1519 | DIType GTy = GV.getType(); |
108 | | | | |
109 | // Construct the context before querying for the existence of the DIE in | | | |
110 | // case such construction creates the DIE. | | | |
111 | DIE *ContextDIE = getOrCreateContextDIE(GVContext); | | | |
112 | | | | |
113 | // Add to map. | | | |
114 | DIE *VariableDIE = &createAndAddDIE(GV.getTag(), *ContextDIE, GV); | | | |
115 | DIScope DeclContext; | | | |
116 | | | 1520 | |
117 | if (DIDerivedType SDMDecl = GV.getStaticDataMemberDeclaration()) { | | 1521 | // If this is a static data member definition, some attributes belong |
118 | DeclContext = resolve(SDMDecl.getContext()); | | 1522 | // to the declaration DIE. |
| | | 1523 | DIE *VariableDIE = NULL; |
| | | 1524 | bool IsStaticMember = false; |
| | | 1525 | DIDerivedType SDMDecl = GV.getStaticDataMemberDeclaration(); |
| | | 1526 | if (SDMDecl.Verify()) { |
119 | assert(SDMDecl.isStaticMember() && "Expected static member decl"); | | 1527 | assert(SDMDecl.isStaticMember() && "Expected static member decl"); |
120 | assert(GV.isDefinition()); | | | |
121 | // We need the declaration DIE that is in the static member's class. | | 1528 | // We need the declaration DIE that is in the static member's class. |
122 | DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl); | | 1529 | VariableDIE = getOrCreateStaticMemberDIE(SDMDecl); |
123 | addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE); | | 1530 | IsStaticMember = true; |
124 | } else { | | 1531 | } |
125 | DeclContext = GV.getContext(); | | 1532 | |
| | | 1533 | // If this is not a static data member definition, create the variable |
| | | 1534 | // DIE and add the initial set of attributes to it. |
| | | 1535 | if (!VariableDIE) { |
| | | 1536 | // Construct the context before querying for the existence of the DIE in |
| | | 1537 | // case such construction creates the DIE. |
| | | 1538 | DIE *ContextDIE = getOrCreateContextDIE(GVContext); |
| | | 1539 | |
| | | 1540 | // Add to map. |
| | | 1541 | VariableDIE = createAndAddDIE(GV.getTag(), *ContextDIE, GV); |
| | | 1542 | |
126 | // Add name and type. | | 1543 | // Add name and type. |
127 | addString(*VariableDIE, dwarf::DW_AT_name, GV.getDisplayName()); | | 1544 | addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName()); |
128 | addType(*VariableDIE, GTy); | | 1545 | addType(VariableDIE, GTy); |
129 | | | 1546 | |
130 | // Add scoping info. | | 1547 | // Add scoping info. |
131 | if (!GV.isLocalToUnit()) | | 1548 | if (!GV.isLocalToUnit()) |
132 | addFlag(*VariableDIE, dwarf::DW_AT_external); | | 1549 | addFlag(VariableDIE, dwarf::DW_AT_external); |
133 | | | 1550 | |
134 | // Add line number info. | | 1551 | // Add line number info. |
135 | addSourceLine(*VariableDIE, GV); | | 1552 | addSourceLine(VariableDIE, GV); |
136 | } | | 1553 | } |
137 | | | 1554 | |
138 | if (!GV.isDefinition()) | | | |
139 | addFlag(*VariableDIE, dwarf::DW_AT_declaration); | | | |
140 | | | | |
141 | // Add location. | | 1555 | // Add location. |
142 | bool addToAccelTable = false; | | 1556 | bool addToAccelTable = false; |
143 | bool isGlobalVariable = GV.getGlobal() != nullptr; | | 1557 | DIE *VariableSpecDIE = NULL; |
| | | 1558 | bool isGlobalVariable = GV.getGlobal() != NULL; |
144 | if (isGlobalVariable) { | | 1559 | if (isGlobalVariable) { |
145 | addToAccelTable = true; | | 1560 | addToAccelTable = true; |
146 | DIELoc *Loc = new (DIEValueAllocator) DIELoc(); | | 1561 | DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); |
147 | const MCSymbol *Sym = Asm->getSymbol(GV.getGlobal()); | | 1562 | const MCSymbol *Sym = Asm->getSymbol(GV.getGlobal()); |
148 | if (GV.getGlobal()->isThreadLocal()) { | | 1563 | if (GV.getGlobal()->isThreadLocal()) { |
149 | // FIXME: Make this work with -gsplit-dwarf. | | 1564 | // FIXME: Make this work with -gsplit-dwarf. |
150 | unsigned PointerSize = Asm->getDataLayout().getPointerSize(); | | 1565 | unsigned PointerSize = Asm->getDataLayout().getPointerSize(); |
151 | assert((PointerSize == 4 || PointerSize == 8) && | | 1566 | assert((PointerSize == 4 || PointerSize == 8) && |
152 | "Add support for other sizes if necessary"); | | 1567 | "Add support for other sizes if necessary"); |
| | | 1568 | const MCExpr *Expr = |
| | | 1569 | Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym); |
153 | // Based on GCC's support for TLS: | | 1570 | // Based on GCC's support for TLS: |
154 | if (!DD->useSplitDwarf()) { | | 1571 | if (!DD->useSplitDwarf()) { |
155 | // 1) Start with a constNu of the appropriate pointer size | | 1572 | // 1) Start with a constNu of the appropriate pointer size |
156 | addUInt(*Loc, dwarf::DW_FORM_data1, | | 1573 | addUInt(Block, dwarf::DW_FORM_data1, |
157 | PointerSize == 4 ? dwarf::DW_OP_const4u : dwarf::DW_OP_const8u); | | 1574 | PointerSize == 4 ? dwarf::DW_OP_const4u : dwarf::DW_OP_const8u); |
158 | // 2) containing the (relocated) offset of the TLS variable | | 1575 | // 2) containing the (relocated) offset of the TLS variable |
159 | // within the module's TLS block. | | 1576 | // within the module's TLS block. |
160 | addExpr(*Loc, dwarf::DW_FORM_udata, | | 1577 | addExpr(Block, dwarf::DW_FORM_udata, Expr); |
161 | Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym)); | | | |
162 | } else { | | 1578 | } else { |
163 | addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index); | | 1579 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index); |
164 | addUInt(*Loc, dwarf::DW_FORM_udata, | | 1580 | addUInt(Block, dwarf::DW_FORM_udata, DU->getAddrPoolIndex(Expr)); |
165 | DD->getAddressPool().getIndex(Sym, /* TLS */ true)); | | | |
166 | } | | 1581 | } |
167 | // 3) followed by a custom OP to make the debugger do a TLS lookup. | | 1582 | // 3) followed by a custom OP to make the debugger do a TLS lookup. |
168 | addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address); | | 1583 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address); |
| | | 1584 | } else |
| | | 1585 | addOpAddress(Block, Sym); |
| | | 1586 | // Do not create specification DIE if context is either compile unit |
| | | 1587 | // or a subprogram. |
| | | 1588 | if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() && |
| | | 1589 | !GVContext.isFile() && !DD->isSubprogramContext(GVContext)) { |
| | | 1590 | // Create specification DIE. |
| | | 1591 | VariableSpecDIE = createAndAddDIE(dwarf::DW_TAG_variable, *CUDie); |
| | | 1592 | addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification, VariableDIE); |
| | | 1593 | addBlock(VariableSpecDIE, dwarf::DW_AT_location, Block); |
| | | 1594 | // A static member's declaration is already flagged as such. |
| | | 1595 | if (!SDMDecl.Verify()) |
| | | 1596 | addFlag(VariableDIE, dwarf::DW_AT_declaration); |
169 | } else { | | 1597 | } else { |
170 | DD->addArangeLabel(SymbolCU(this, Sym)); | | 1598 | addBlock(VariableDIE, dwarf::DW_AT_location, Block); |
171 | addOpAddress(*Loc, Sym); | | | |
172 | } | | 1599 | } |
173 | | | | |
174 | addBlock(*VariableDIE, dwarf::DW_AT_location, Loc); | | | |
175 | // Add the linkage name. | | 1600 | // Add the linkage name. |
176 | StringRef LinkageName = GV.getLinkageName(); | | 1601 | StringRef LinkageName = GV.getLinkageName(); |
177 | if (!LinkageName.empty()) | | 1602 | if (!LinkageName.empty()) |
178 | // From DWARF4: DIEs to which DW_AT_linkage_name may apply include: | | 1603 | // From DWARF4: DIEs to which DW_AT_linkage_name may apply include: |
179 | // TAG_common_block, TAG_constant, TAG_entry_point, TAG_subprogram and | | 1604 | // TAG_common_block, TAG_constant, TAG_entry_point, TAG_subprogram and |
180 | // TAG_variable. | | 1605 | // TAG_variable. |
181 | addString(*VariableDIE, | | 1606 | addString(IsStaticMember && VariableSpecDIE ? VariableSpecDIE |
182 | DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name | | 1607 | : VariableDIE, |
183 | : dwarf::DW_AT_MIPS_linkage_name, | | 1608 | dwarf::DW_AT_MIPS_linkage_name, |
184 | GlobalValue::getRealLinkageName(LinkageName)); | | 1609 | GlobalValue::getRealLinkageName(LinkageName)); |
185 | } else if (const ConstantInt *CI = | | 1610 | } else if (const ConstantInt *CI = |
186 | dyn_cast_or_null<ConstantInt>(GV.getConstant())) { | | 1611 | dyn_cast_or_null<ConstantInt>(GV.getConstant())) { |
187 | addConstantValue(*VariableDIE, CI, GTy); | | 1612 | // AT_const_value was added when the static member was created. To avoid |
188 | } else if (const ConstantExpr *CE = getMergedGlobalExpr(GV.getConstant())) { | | 1613 | // emitting AT_const_value multiple times, we only add AT_const_value when |
| | | 1614 | // it is not a static member. |
| | | 1615 | if (!IsStaticMember) |
| | | 1616 | addConstantValue(VariableDIE, CI, isUnsignedDIType(DD, GTy)); |
| | | 1617 | } else if (const ConstantExpr *CE = getMergedGlobalExpr(GV->getOperand(11))) { |
189 | addToAccelTable = true; | | 1618 | addToAccelTable = true; |
190 | // GV is a merged global. | | 1619 | // GV is a merged global. |
191 | DIELoc *Loc = new (DIEValueAllocator) DIELoc(); | | 1620 | DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); |
192 | Value *Ptr = CE->getOperand(0); | | 1621 | Value *Ptr = CE->getOperand(0); |
193 | MCSymbol *Sym = Asm->getSymbol(cast<GlobalValue>(Ptr)); | | 1622 | addOpAddress(Block, Asm->getSymbol(cast<GlobalValue>(Ptr))); |
194 | DD->addArangeLabel(SymbolCU(this, Sym)); | | 1623 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); |
195 | addOpAddress(*Loc, Sym); | | | |
196 | addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); | | | |
197 | SmallVector<Value *, 3> Idx(CE->op_begin() + 1, CE->op_end()); | | 1624 | SmallVector<Value *, 3> Idx(CE->op_begin() + 1, CE->op_end()); |
198 | addUInt(*Loc, dwarf::DW_FORM_udata, | | 1625 | addUInt(Block, dwarf::DW_FORM_udata, |
199 | Asm->getDataLayout().getIndexedOffset(Ptr->getType(), Idx)); | | 1626 | Asm->getDataLayout().getIndexedOffset(Ptr->getType(), Idx)); |
200 | addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); | | 1627 | addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); |
201 | addBlock(*VariableDIE, dwarf::DW_AT_location, Loc); | | 1628 | addBlock(VariableDIE, dwarf::DW_AT_location, Block); |
202 | } | | 1629 | } |
203 | | | 1630 | |
204 | if (addToAccelTable) { | | 1631 | if (addToAccelTable) { |
205 | DD->addAccelName(GV.getName(), *VariableDIE); | | 1632 | DIE *AddrDIE = VariableSpecDIE ? VariableSpecDIE : VariableDIE; |
| | | 1633 | addAccelName(GV.getName(), AddrDIE); |
206 | | | 1634 | |
207 | // If the linkage name is different than the name, go ahead and output | | 1635 | // If the linkage name is different than the name, go ahead and output |
208 | // that as well into the name table. | | 1636 | // that as well into the name table. |
209 | if (GV.getLinkageName() != "" && GV.getName() != GV.getLinkageName()) | | 1637 | if (GV.getLinkageName() != "" && GV.getName() != GV.getLinkageName()) |
210 | DD->addAccelName(GV.getLinkageName(), *VariableDIE); | | 1638 | addAccelName(GV.getLinkageName(), AddrDIE); |
211 | } | | 1639 | } |
212 | | | 1640 | |
213 | addGlobalName(GV.getName(), *VariableDIE, DeclContext); | | 1641 | if (!GV.isLocalToUnit()) |
214 | return VariableDIE; | | 1642 | addGlobalName(GV.getName(), VariableSpecDIE ? VariableSpecDIE : VariableDIE, |
215 | } | | 1643 | GV.getContext()); |
216 | | | 1644 | } |
217 | void DwarfCompileUnit::addRange(RangeSpan Range) { | | 1645 | |
218 | bool SameAsPrevCU = this == DD->getPrevCU(); | | 1646 | /// constructSubrangeDIE - Construct subrange DIE from DISubrange. |
219 | DD->setPrevCU(this); | | 1647 | void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, |
220 | // If we have no current ranges just add the range and return, otherwise, | | 1648 | DIE *IndexTy) { |
221 | // check the current section and CU against the previous section and CU we | | 1649 | DIE *DW_Subrange = createAndAddDIE(dwarf::DW_TAG_subrange_type, Buffer); |
222 | // emitted into and the subprogram was contained within. If these are the | | 1650 | addDIEEntry(DW_Subrange, dwarf::DW_AT_type, IndexTy); |
223 | // same then extend our current range, otherwise add this as a new range. | | 1651 | |
224 | if (CURanges.empty() || !SameAsPrevCU || | | 1652 | // The LowerBound value defines the lower bounds which is typically zero for |
225 | (&CURanges.back().getEnd()->getSection() != | | 1653 | // C/C++. The Count value is the number of elements. Values are 64 bit. If |
226 | &Range.getEnd()->getSection())) { | | 1654 | // Count == -1 then the array is unbounded and we do not emit |
227 | CURanges.push_back(Range); | | 1655 | // DW_AT_lower_bound and DW_AT_upper_bound attributes. If LowerBound == 0 and |
228 | return; | | 1656 | // Count == 0, then the array has zero elements in which case we do not emit |
| | | 1657 | // an upper bound. |
| | | 1658 | int64_t LowerBound = SR.getLo(); |
| | | 1659 | int64_t DefaultLowerBound = getDefaultLowerBound(); |
| | | 1660 | int64_t Count = SR.getCount(); |
| | | 1661 | |
| | | 1662 | if (DefaultLowerBound == -1 || LowerBound != DefaultLowerBound) |
| | | 1663 | addUInt(DW_Subrange, dwarf::DW_AT_lower_bound, None, LowerBound); |
| | | 1664 | |
| | | 1665 | if (Count != -1 && Count != 0) |
| | | 1666 | // FIXME: An unbounded array should reference the expression that defines |
| | | 1667 | // the array. |
| | | 1668 | addUInt(DW_Subrange, dwarf::DW_AT_upper_bound, None, |
| | | 1669 | LowerBound + Count - 1); |
| | | 1670 | } |
| | | 1671 | |
| | | 1672 | /// constructArrayTypeDIE - Construct array type DIE from DICompositeType. |
| | | 1673 | void CompileUnit::constructArrayTypeDIE(DIE &Buffer, DICompositeType CTy) { |
| | | 1674 | if (CTy.isVector()) |
| | | 1675 | addFlag(&Buffer, dwarf::DW_AT_GNU_vector); |
| | | 1676 | |
| | | 1677 | // Emit the element type. |
| | | 1678 | addType(&Buffer, resolve(CTy.getTypeDerivedFrom())); |
| | | 1679 | |
| | | 1680 | // Get an anonymous type for index type. |
| | | 1681 | // FIXME: This type should be passed down from the front end |
| | | 1682 | // as different languages may have different sizes for indexes. |
| | | 1683 | DIE *IdxTy = getIndexTyDie(); |
| | | 1684 | if (!IdxTy) { |
| | | 1685 | // Construct an anonymous type for index type. |
| | | 1686 | IdxTy = createAndAddDIE(dwarf::DW_TAG_base_type, *CUDie.get()); |
| | | 1687 | addString(IdxTy, dwarf::DW_AT_name, "int"); |
| | | 1688 | addUInt(IdxTy, dwarf::DW_AT_byte_size, None, sizeof(int32_t)); |
| | | 1689 | addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, |
| | | 1690 | dwarf::DW_ATE_signed); |
| | | 1691 | setIndexTyDie(IdxTy); |
229 | } | | 1692 | } |
230 | | | 1693 | |
231 | CURanges.back().setEnd(Range.getEnd()); | | 1694 | // Add subranges to array type. |
232 | } | | 1695 | DIArray Elements = CTy.getTypeArray(); |
233 | | | 1696 | for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { |
234 | void DwarfCompileUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute, | | 1697 | DIDescriptor Element = Elements.getElement(i); |
235 | const MCSymbol *Label, | | 1698 | if (Element.getTag() == dwarf::DW_TAG_subrange_type) |
236 | const MCSymbol *Sec) { | | 1699 | constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy); |
237 | if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) | | | |
238 | addLabel(Die, Attribute, | | | |
239 | DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset | | | |
240 | : dwarf::DW_FORM_data4, | | | |
241 | Label); | | | |
242 | else | | | |
243 | addSectionDelta(Die, Attribute, Label, Sec); | | | |
244 | } | | | |
245 | | | | |
246 | void DwarfCompileUnit::initStmtList(MCSymbol *DwarfLineSectionSym) { | | | |
247 | // Define start line table label for each Compile Unit. | | | |
248 | MCSymbol *LineTableStartSym = | | | |
249 | Asm->OutStreamer.getDwarfLineTableSymbol(getUniqueID()); | | | |
250 | | | | |
251 | stmtListIndex = UnitDie.getValues().size(); | | | |
252 | | | | |
253 | // DW_AT_stmt_list is a offset of line number information for this | | | |
254 | // compile unit in debug_line section. For split dwarf this is | | | |
255 | // left in the skeleton CU and so not included. | | | |
256 | // The line table entries are not always emitted in assembly, so it | | | |
257 | // is not okay to use line_table_start here. | | | |
258 | addSectionLabel(UnitDie, dwarf::DW_AT_stmt_list, LineTableStartSym, | | | |
259 | DwarfLineSectionSym); | | | |
260 | } | | | |
261 | | | | |
262 | void DwarfCompileUnit::applyStmtList(DIE &D) { | | | |
263 | D.addValue(dwarf::DW_AT_stmt_list, | | | |
264 | UnitDie.getAbbrev().getData()[stmtListIndex].getForm(), | | | |
265 | UnitDie.getValues()[stmtListIndex]); | | | |
266 | } | | | |
267 | | | | |
268 | void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin, | | | |
269 | const MCSymbol *End) { | | | |
270 | assert(Begin && "Begin label should not be null!"); | | | |
271 | assert(End && "End label should not be null!"); | | | |
272 | assert(Begin->isDefined() && "Invalid starting label"); | | | |
273 | assert(End->isDefined() && "Invalid end label"); | | | |
274 | | | | |
275 | addLabelAddress(D, dwarf::DW_AT_low_pc, Begin); | | | |
276 | if (DD->getDwarfVersion() < 4) | | | |
277 | addLabelAddress(D, dwarf::DW_AT_high_pc, End); | | | |
278 | else | | | |
279 | addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin); | | | |
280 | } | | | |
281 | | | | |
282 | // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc | | | |
283 | // and DW_AT_high_pc attributes. If there are global variables in this | | | |
284 | // scope then create and insert DIEs for these variables. | | | |
285 | DIE &DwarfCompileUnit::updateSubprogramScopeDIE(DISubprogram SP) { | | | |
286 | DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes()); | | | |
287 | | | | |
288 | attachLowHighPC(*SPDie, DD->getFunctionBeginSym(), DD->getFunctionEndSym()); | | | |
289 | if (!DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim( | | | |
290 | *DD->getCurrentFunction())) | | | |
291 | addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr); | | | |
292 | | | | |
293 | // Only include DW_AT_frame_base in full debug info | | | |
294 | if (!includeMinimalInlineScopes()) { | | | |
295 | const TargetRegisterInfo *RI = | | | |
296 | Asm->TM.getSubtargetImpl()->getRegisterInfo(); | | | |
297 | MachineLocation Location(RI->getFrameRegister(*Asm->MF)); | | | |
298 | if (RI->isPhysicalRegister(Location.getReg())) | | | |
299 | addAddress(*SPDie, dwarf::DW_AT_frame_base, Location); | | | |
300 | } | | 1700 | } |
301 | | | | |
302 | // Add name to the name table, we do this here because we're guaranteed | | | |
303 | // to have concrete versions of our DW_TAG_subprogram nodes. | | | |
304 | DD->addSubprogramNames(SP, *SPDie); | | | |
305 | | | | |
306 | return *SPDie; | | | |
307 | } | | 1701 | } |
308 | | | 1702 | |
309 | // Construct a DIE for this scope. | | 1703 | /// constructEnumTypeDIE - Construct an enum type DIE from DICompositeType. |
310 | void DwarfCompileUnit::constructScopeDIE( | | 1704 | void CompileUnit::constructEnumTypeDIE(DIE &Buffer, DICompositeType CTy) { |
311 | LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren) { | | 1705 | DIArray Elements = CTy.getTypeArray(); |
312 | if (!Scope || !Scope->getScopeNode()) | | 1706 | |
313 | return; | | 1707 | // Add enumerators to enumeration type. |
314 | | | 1708 | for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { |
315 | DIScope DS(Scope->getScopeNode()); | | 1709 | DIEnumerator Enum(Elements.getElement(i)); |
316 | | | 1710 | if (Enum.isEnumerator()) { |
317 | assert((Scope->getInlinedAt() || !DS.isSubprogram()) && | | 1711 | DIE *Enumerator = createAndAddDIE(dwarf::DW_TAG_enumerator, Buffer); |
318 | "Only handle inlined subprograms here, use " | | 1712 | StringRef Name = Enum.getName(); |
319 | "constructSubprogramScopeDIE for non-inlined " | | 1713 | addString(Enumerator, dwarf::DW_AT_name, Name); |
320 | "subprograms"); | | 1714 | int64_t Value = Enum.getEnumValue(); |
321 | | | 1715 | addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value); |
322 | SmallVector<std::unique_ptr<DIE>, 8> Children; | | | |
323 | | | | |
324 | // We try to create the scope DIE first, then the children DIEs. This will | | | |
325 | // avoid creating un-used children then removing them later when we find out | | | |
326 | // the scope DIE is null. | | | |
327 | std::unique_ptr<DIE> ScopeDIE; | | | |
328 | if (Scope->getParent() && DS.isSubprogram()) { | | | |
329 | ScopeDIE = constructInlinedScopeDIE(Scope); | | | |
330 | if (!ScopeDIE) | | | |
331 | return; | | | |
332 | // We create children when the scope DIE is not null. | | | |
333 | createScopeChildrenDIE(Scope, Children); | | | |
334 | } else { | | | |
335 | // Early exit when we know the scope DIE is going to be null. | | | |
336 | if (DD->isLexicalScopeDIENull(Scope)) | | | |
337 | return; | | | |
338 | | | | |
339 | unsigned ChildScopeCount; | | | |
340 | | | | |
341 | // We create children here when we know the scope DIE is not going to be | | | |
342 | // null and the children will be added to the scope DIE. | | | |
343 | createScopeChildrenDIE(Scope, Children, &ChildScopeCount); | | | |
344 | | | | |
345 | // Skip imported directives in gmlt-like data. | | | |
346 | if (!includeMinimalInlineScopes()) { | | | |
347 | // There is no need to emit empty lexical block DIE. | | | |
348 | for (const auto &E : DD->findImportedEntitiesForScope(DS)) | | | |
349 | Children.push_back( | | | |
350 | constructImportedEntityDIE(DIImportedEntity(E.second))); | | | |
351 | } | | | |
352 | | | | |
353 | // If there are only other scopes as children, put them directly in the | | | |
354 | // parent instead, as this scope would serve no purpose. | | | |
355 | if (Children.size() == ChildScopeCount) { | | | |
356 | FinalChildren.insert(FinalChildren.end(), | | | |
357 | std::make_move_iterator(Children.begin()), | | | |
358 | std::make_move_iterator(Children.end())); | | | |
359 | return; | | | |
360 | } | | 1716 | } |
361 | ScopeDIE = constructLexicalScopeDIE(Scope); | | | |
362 | assert(ScopeDIE && "Scope DIE should not be null."); | | | |
363 | } | | 1717 | } |
364 | | | 1718 | DIType DTy = resolve(CTy.getTypeDerivedFrom()); |
365 | // Add children | | 1719 | if (DTy) { |
366 | for (auto &I : Children) | | 1720 | addType(&Buffer, DTy); |
367 | ScopeDIE->addChild(std::move(I)); | | 1721 | addFlag(&Buffer, dwarf::DW_AT_enum_class); |
368 | | | 1722 | } |
369 | FinalChildren.push_back(std::move(ScopeDIE)); | | | |
370 | } | | | |
371 | | | | |
372 | void DwarfCompileUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute, | | | |
373 | const MCSymbol *Hi, const MCSymbol *Lo) { | | | |
374 | DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo); | | | |
375 | Die.addValue(Attribute, DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset | | | |
376 | : dwarf::DW_FORM_data4, | | | |
377 | Value); | | | |
378 | } | | | |
379 | | | | |
380 | void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, | | | |
381 | SmallVector<RangeSpan, 2> Range) { | | | |
382 | // Emit offset in .debug_range as a relocatable label. emitDIE will handle | | | |
383 | // emitting it appropriately. | | | |
384 | auto *RangeSectionSym = DD->getRangeSectionSym(); | | | |
385 | | | | |
386 | RangeSpanList List( | | | |
387 | Asm->GetTempSymbol("debug_ranges", DD->getNextRangeNumber()), | | | |
388 | std::move(Range)); | | | |
389 | | | | |
390 | // Under fission, ranges are specified by constant offsets relative to the | | | |
391 | // CU's DW_AT_GNU_ranges_base. | | | |
392 | if (isDwoUnit()) | | | |
393 | addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), | | | |
394 | RangeSectionSym); | | | |
395 | else | | | |
396 | addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), | | | |
397 | RangeSectionSym); | | | |
398 | | | | |
399 | // Add the range list to the set of ranges to be emitted. | | | |
400 | (Skeleton ? Skeleton : this)->CURangeLists.push_back(std::move(List)); | | | |
401 | } | | | |
402 | | | | |
403 | void DwarfCompileUnit::attachRangesOrLowHighPC( | | | |
404 | DIE &Die, SmallVector<RangeSpan, 2> Ranges) { | | | |
405 | if (Ranges.size() == 1) { | | | |
406 | const auto &single = Ranges.front(); | | | |
407 | attachLowHighPC(Die, single.getStart(), single.getEnd()); | | | |
408 | } else | | | |
409 | addScopeRangeList(Die, std::move(Ranges)); | | | |
410 | } | | 1723 | } |
411 | | | 1724 | |
412 | void DwarfCompileUnit::attachRangesOrLowHighPC( | | 1725 | /// constructContainingTypeDIEs - Construct DIEs for types that contain |
413 | DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) { | | 1726 | /// vtables. |
414 | SmallVector<RangeSpan, 2> List; | | 1727 | void CompileUnit::constructContainingTypeDIEs() { |
415 | List.reserve(Ranges.size()); | | 1728 | for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(), |
416 | for (const InsnRange &R : Ranges) | | 1729 | CE = ContainingTypeMap.end(); |
417 | List.push_back(RangeSpan(DD->getLabelBeforeInsn(R.first), | | 1730 | CI != CE; ++CI) { |
418 | DD->getLabelAfterInsn(R.second))); | | 1731 | DIE *SPDie = CI->first; |
419 | attachRangesOrLowHighPC(Die, std::move(List)); | | 1732 | DIDescriptor D(CI->second); |
420 | } | | 1733 | if (!D) |
421 | | | 1734 | continue; |
422 | // This scope represents inlined body of a function. Construct DIE to | | 1735 | DIE *NDie = getDIE(D); |
423 | // represent this concrete inlined copy of the function. | | 1736 | if (!NDie) |
424 | std::unique_ptr<DIE> | | 1737 | continue; |
425 | DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) { | | 1738 | addDIEEntry(SPDie, dwarf::DW_AT_containing_type, NDie); |
426 | assert(Scope->getScopeNode()); | | 1739 | } |
427 | DIScope DS(Scope->getScopeNode()); | | | |
428 | DISubprogram InlinedSP = getDISubprogram(DS); | | | |
429 | // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram | | | |
430 | // was inlined from another compile unit. | | | |
431 | DIE *OriginDIE = DU->getAbstractSPDies()[InlinedSP]; | | | |
432 | assert(OriginDIE && "Unable to find original DIE for an inlined subprogram."); | | | |
433 | | | | |
434 | auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_inlined_subroutine); | | | |
435 | addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE); | | | |
436 | | | | |
437 | attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); | | | |
438 | | | | |
439 | // Add the call site information to the DIE. | | | |
440 | DILocation DL(Scope->getInlinedAt()); | | | |
441 | addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None, | | | |
442 | getOrCreateSourceID(DL.getFilename(), DL.getDirectory())); | | | |
443 | addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, DL.getLineNumber()); | | | |
444 | | | | |
445 | // Add name to the name table, we do this here because we're guaranteed | | | |
446 | // to have concrete versions of our DW_TAG_inlined_subprogram nodes. | | | |
447 | DD->addSubprogramNames(InlinedSP, *ScopeDIE); | | | |
448 | | | | |
449 | return ScopeDIE; | | | |
450 | } | | | |
451 | | | | |
452 | // Construct new DW_TAG_lexical_block for this scope and attach | | | |
453 | // DW_AT_low_pc/DW_AT_high_pc labels. | | | |
454 | std::unique_ptr<DIE> | | | |
455 | DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) { | | | |
456 | if (DD->isLexicalScopeDIENull(Scope)) | | | |
457 | return nullptr; | | | |
458 | | | | |
459 | auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_lexical_block); | | | |
460 | if (Scope->isAbstractScope()) | | | |
461 | return ScopeDIE; | | | |
462 | | | | |
463 | attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); | | | |
464 | | | | |
465 | return ScopeDIE; | | | |
466 | } | | 1740 | } |
467 | | | 1741 | |
468 | /// constructVariableDIE - Construct a DIE for the given DbgVariable. | | 1742 | /// constructVariableDIE - Construct a DIE for the given DbgVariable. |
469 | std::unique_ptr<DIE> DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, | | 1743 | DIE *CompileUnit::constructVariableDIE(DbgVariable &DV, bool isScopeAbstract) { |
470 | bool Abstract) { | | 1744 | StringRef Name = DV.getName(); |
471 | auto D = constructVariableDIEImpl(DV, Abstract); | | | |
472 | DV.setDIE(*D); | | | |
473 | return D; | | | |
474 | } | | | |
475 | | | 1745 | |
476 | std::unique_ptr<DIE> | | | |
477 | DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, | | | |
478 | bool Abstract) { | | | |
479 | // Define variable debug information entry. | | 1746 | // Define variable debug information entry. |
480 | auto VariableDie = make_unique<DIE>(DV.getTag()); | | 1747 | DIE *VariableDie = new DIE(DV.getTag()); |
| | | 1748 | DbgVariable *AbsVar = DV.getAbstractVariable(); |
| | | 1749 | DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : NULL; |
| | | 1750 | if (AbsDIE) |
| | | 1751 | addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin, AbsDIE); |
| | | 1752 | else { |
| | | 1753 | if (!Name.empty()) |
| | | 1754 | addString(VariableDie, dwarf::DW_AT_name, Name); |
| | | 1755 | addSourceLine(VariableDie, DV.getVariable()); |
| | | 1756 | addType(VariableDie, DV.getType()); |
| | | 1757 | } |
| | | 1758 | |
| | | 1759 | if (DV.isArtificial()) |
| | | 1760 | addFlag(VariableDie, dwarf::DW_AT_artificial); |
481 | | | 1761 | |
482 | if (Abstract) { | | 1762 | if (isScopeAbstract) { |
483 | applyVariableAttributes(DV, *VariableDie); | | 1763 | DV.setDIE(VariableDie); |
484 | return VariableDie; | | 1764 | return VariableDie; |
485 | } | | 1765 | } |
486 | | | 1766 | |
487 | // Add variable address. | | 1767 | // Add variable address. |
488 | | | 1768 | |
489 | unsigned Offset = DV.getDotDebugLocOffset(); | | 1769 | unsigned Offset = DV.getDotDebugLocOffset(); |
490 | if (Offset != ~0U) { | | 1770 | if (Offset != ~0U) { |
491 | addLocationList(*VariableDie, dwarf::DW_AT_location, Offset); | | 1771 | addLabel(VariableDie, dwarf::DW_AT_location, |
| | | 1772 | DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset |
| | | 1773 | : dwarf::DW_FORM_data4, |
| | | 1774 | Asm->GetTempSymbol("debug_loc", Offset)); |
| | | 1775 | DV.setDIE(VariableDie); |
492 | return VariableDie; | | 1776 | return VariableDie; |
493 | } | | 1777 | } |
494 | | | 1778 | |
495 | // Check if variable is described by a DBG_VALUE instruction. | | 1779 | // Check if variable is described by a DBG_VALUE instruction. |
496 | if (const MachineInstr *DVInsn = DV.getMInsn()) { | | 1780 | if (const MachineInstr *DVInsn = DV.getMInsn()) { |
497 | assert(DVInsn->getNumOperands() == 4); | | 1781 | assert(DVInsn->getNumOperands() == 3); |
498 | if (DVInsn->getOperand(0).isReg()) { | | 1782 | if (DVInsn->getOperand(0).isReg()) { |
499 | const MachineOperand RegOp = DVInsn->getOperand(0); | | 1783 | const MachineOperand RegOp = DVInsn->getOperand(0); |
500 | // If the second operand is an immediate, this is an indirect value. | | 1784 | // If the second operand is an immediate, this is an indirect value. |
501 | if (DVInsn->getOperand(1).isImm()) { | | 1785 | if (DVInsn->getOperand(1).isImm()) { |
502 | MachineLocation Location(RegOp.getReg(), | | 1786 | MachineLocation Location(RegOp.getReg(), |
503 | DVInsn->getOperand(1).getImm()); | | 1787 | DVInsn->getOperand(1).getImm()); |
504 | addVariableAddress(DV, *VariableDie, Location); | | 1788 | addVariableAddress(DV, VariableDie, Location); |
505 | } else if (RegOp.getReg()) | | 1789 | } else if (RegOp.getReg()) |
506 | addVariableAddress(DV, *VariableDie, MachineLocation(RegOp.getReg())); | | 1790 | addVariableAddress(DV, VariableDie, MachineLocation(RegOp.getReg())); |
507 | } else if (DVInsn->getOperand(0).isImm()) | | 1791 | } else if (DVInsn->getOperand(0).isImm()) |
508 | addConstantValue(*VariableDie, DVInsn->getOperand(0), DV.getType()); | | 1792 | addConstantValue(VariableDie, DVInsn->getOperand(0), DV.getType()); |
509 | else if (DVInsn->getOperand(0).isFPImm()) | | 1793 | else if (DVInsn->getOperand(0).isFPImm()) |
510 | addConstantFPValue(*VariableDie, DVInsn->getOperand(0)); | | 1794 | addConstantFPValue(VariableDie, DVInsn->getOperand(0)); |
511 | else if (DVInsn->getOperand(0).isCImm()) | | 1795 | else if (DVInsn->getOperand(0).isCImm()) |
512 | addConstantValue(*VariableDie, DVInsn->getOperand(0).getCImm(), | | 1796 | addConstantValue(VariableDie, DVInsn->getOperand(0).getCImm(), |
513 | DV.getType()); | | 1797 | isUnsignedDIType(DD, DV.getType())); |
514 | | | 1798 | |
| | | 1799 | DV.setDIE(VariableDie); |
515 | return VariableDie; | | 1800 | return VariableDie; |
| | | 1801 | } else { |
| | | 1802 | // .. else use frame index. |
| | | 1803 | int FI = DV.getFrameIndex(); |
| | | 1804 | if (FI != ~0) { |
| | | 1805 | unsigned FrameReg = 0; |
| | | 1806 | const TargetFrameLowering *TFI = Asm->TM.getFrameLowering(); |
| | | 1807 | int Offset = TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg); |
| | | 1808 | MachineLocation Location(FrameReg, Offset); |
| | | 1809 | addVariableAddress(DV, VariableDie, Location); |
| | | 1810 | } |
516 | } | | 1811 | } |
517 | | | 1812 | |
518 | // .. else use frame index. | | 1813 | DV.setDIE(VariableDie); |
519 | int FI = DV.getFrameIndex(); | | | |
520 | if (FI != ~0) { | | | |
521 | unsigned FrameReg = 0; | | | |
522 | const TargetFrameLowering *TFI = | | | |
523 | Asm->TM.getSubtargetImpl()->getFrameLowering(); | | | |
524 | int Offset = TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg); | | | |
525 | MachineLocation Location(FrameReg, Offset); | | | |
526 | addVariableAddress(DV, *VariableDie, Location); | | | |
527 | } | | | |
528 | | | | |
529 | return VariableDie; | | 1814 | return VariableDie; |
530 | } | | 1815 | } |
531 | | | 1816 | |
532 | std::unique_ptr<DIE> DwarfCompileUnit::constructVariableDIE( | | 1817 | /// constructMemberDIE - Construct member DIE from DIDerivedType. |
533 | DbgVariable &DV, const LexicalScope &Scope, DIE *&ObjectPointer) { | | 1818 | void CompileUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) { |
534 | auto Var = constructVariableDIE(DV, Scope.isAbstractScope()); | | 1819 | DIE *MemberDie = createAndAddDIE(DT.getTag(), Buffer); |
535 | if (DV.isObjectPointer()) | | 1820 | StringRef Name = DT.getName(); |
536 | ObjectPointer = Var.get(); | | 1821 | if (!Name.empty()) |
537 | return Var; | | 1822 | addString(MemberDie, dwarf::DW_AT_name, Name); |
538 | } | | | |
539 | | | | |
540 | DIE *DwarfCompileUnit::createScopeChildrenDIE( | | | |
541 | LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &Children, | | | |
542 | unsigned *ChildScopeCount) { | | | |
543 | DIE *ObjectPointer = nullptr; | | | |
544 | | | | |
545 | for (DbgVariable *DV : DU->getScopeVariables().lookup(Scope)) | | | |
546 | Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer)); | | | |
547 | | | | |
548 | unsigned ChildCountWithoutScopes = Children.size(); | | | |
549 | | | | |
550 | for (LexicalScope *LS : Scope->getChildren()) | | | |
551 | constructScopeDIE(LS, Children); | | | |
552 | | | | |
553 | if (ChildScopeCount) | | | |
554 | *ChildScopeCount = Children.size() - ChildCountWithoutScopes; | | | |
555 | | | | |
556 | return ObjectPointer; | | | |
557 | } | | | |
558 | | | | |
559 | void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) { | | | |
560 | assert(Scope && Scope->getScopeNode()); | | | |
561 | assert(!Scope->getInlinedAt()); | | | |
562 | assert(!Scope->isAbstractScope()); | | | |
563 | DISubprogram Sub(Scope->getScopeNode()); | | | |
564 | | | | |
565 | assert(Sub.isSubprogram()); | | | |
566 | | | | |
567 | DD->getProcessedSPNodes().insert(Sub); | | | |
568 | | | 1823 | |
569 | DIE &ScopeDIE = updateSubprogramScopeDIE(Sub); | | 1824 | addType(MemberDie, resolve(DT.getTypeDerivedFrom())); |
570 | | | 1825 | |
571 | // If this is a variadic function, add an unspecified parameter. | | 1826 | addSourceLine(MemberDie, DT); |
572 | DITypeArray FnArgs = Sub.getType().getTypeArray(); | | | |
573 | | | 1827 | |
574 | // Collect lexical scope children first. | | 1828 | DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock(); |
575 | // ObjectPointer might be a local (non-argument) local variable if it's a | | 1829 | addUInt(MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); |
576 | // block's synthetic this pointer. | | | |
577 | if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE)) | | | |
578 | addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); | | | |
579 | | | 1830 | |
580 | // If we have a single element of null, it is a function that returns void. | | 1831 | if (DT.getTag() == dwarf::DW_TAG_inheritance && DT.isVirtual()) { |
581 | // If we have more than one elements and the last one is null, it is a | | | |
582 | // variadic function. | | | |
583 | if (FnArgs.getNumElements() > 1 && | | | |
584 | !FnArgs.getElement(FnArgs.getNumElements() - 1) && | | | |
585 | !includeMinimalInlineScopes()) | | | |
586 | ScopeDIE.addChild(make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters)); | | | |
587 | } | | | |
588 | | | 1832 | |
589 | DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope, | | 1833 | // For C++, virtual base classes are not at fixed offset. Use following |
590 | DIE &ScopeDIE) { | | 1834 | // expression to extract appropriate offset from vtable. |
591 | // We create children when the scope DIE is not null. | | 1835 | // BaseAddr = ObAddr + *((*ObAddr) - Offset) |
592 | SmallVector<std::unique_ptr<DIE>, 8> Children; | | | |
593 | DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children); | | | |
594 | | | 1836 | |
595 | // Add children | | 1837 | DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock(); |
596 | for (auto &I : Children) | | 1838 | addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup); |
597 | ScopeDIE.addChild(std::move(I)); | | 1839 | addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); |
| | | 1840 | addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); |
| | | 1841 | addUInt(VBaseLocationDie, dwarf::DW_FORM_udata, DT.getOffsetInBits()); |
| | | 1842 | addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_minus); |
| | | 1843 | addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); |
| | | 1844 | addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); |
598 | | | 1845 | |
599 | return ObjectPointer; | | 1846 | addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie); |
600 | } | | | |
601 | | | | |
602 | void | | | |
603 | DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) { | | | |
604 | DIE *&AbsDef = DU->getAbstractSPDies()[Scope->getScopeNode()]; | | | |
605 | if (AbsDef) | | | |
606 | return; | | | |
607 | | | | |
608 | DISubprogram SP(Scope->getScopeNode()); | | | |
609 | | | | |
610 | DIE *ContextDIE; | | | |
611 | | | | |
612 | if (includeMinimalInlineScopes()) | | | |
613 | ContextDIE = &getUnitDie(); | | | |
614 | // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with | | | |
615 | // the important distinction that the DIDescriptor is not associated with the | | | |
616 | // DIE (since the DIDescriptor will be associated with the concrete DIE, if | | | |
617 | // any). It could be refactored to some common utility function. | | | |
618 | else if (DISubprogram SPDecl = SP.getFunctionDeclaration()) { | | | |
619 | ContextDIE = &getUnitDie(); | | | |
620 | getOrCreateSubprogramDIE(SPDecl); | | | |
621 | } else | | | |
622 | ContextDIE = getOrCreateContextDIE(resolve(SP.getContext())); | | | |
623 | | | | |
624 | // Passing null as the associated DIDescriptor because the abstract definition | | | |
625 | // shouldn't be found by lookup. | | | |
626 | AbsDef = | | | |
627 | &createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, DIDescriptor()); | | | |
628 | applySubprogramAttributesToDefinition(SP, *AbsDef); | | | |
629 | | | | |
630 | if (!includeMinimalInlineScopes()) | | | |
631 | addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); | | | |
632 | if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, *AbsDef)) | | | |
633 | addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); | | | |
634 | } | | | |
635 | | | | |
636 | std::unique_ptr<DIE> | | | |
637 | DwarfCompileUnit::constructImportedEntityDIE(const DIImportedEntity &Module) { | | | |
638 | assert(Module.Verify() && | | | |
639 | "Use one of the MDNode * overloads to handle invalid metadata"); | | | |
640 | std::unique_ptr<DIE> IMDie = make_unique<DIE>((dwarf::Tag)Module.getTag()); | | | |
641 | insertDIE(Module, IMDie.get()); | | | |
642 | DIE *EntityDie; | | | |
643 | DIDescriptor Entity = resolve(Module.getEntity()); | | | |
644 | if (Entity.isNameSpace()) | | | |
645 | EntityDie = getOrCreateNameSpace(DINameSpace(Entity)); | | | |
646 | else if (Entity.isSubprogram()) | | | |
647 | EntityDie = getOrCreateSubprogramDIE(DISubprogram(Entity)); | | | |
648 | else if (Entity.isType()) | | | |
649 | EntityDie = getOrCreateTypeDIE(DIType(Entity)); | | | |
650 | else if (Entity.isGlobalVariable()) | | | |
651 | EntityDie = getOrCreateGlobalVariableDIE(DIGlobalVariable(Entity)); | | | |
652 | else | | | |
653 | EntityDie = getDIE(Entity); | | | |
654 | assert(EntityDie); | | | |
655 | addSourceLine(*IMDie, Module.getLineNumber(), | | | |
656 | Module.getContext().getFilename(), | | | |
657 | Module.getContext().getDirectory()); | | | |
658 | addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie); | | | |
659 | StringRef Name = Module.getName(); | | | |
660 | if (!Name.empty()) | | | |
661 | addString(*IMDie, dwarf::DW_AT_name, Name); | | | |
662 | | | | |
663 | return IMDie; | | | |
664 | } | | | |
665 | | | | |
666 | void DwarfCompileUnit::finishSubprogramDefinition(DISubprogram SP) { | | | |
667 | DIE *D = getDIE(SP); | | | |
668 | if (DIE *AbsSPDIE = DU->getAbstractSPDies().lookup(SP)) { | | | |
669 | if (D) | | | |
670 | // If this subprogram has an abstract definition, reference that | | | |
671 | addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE); | | | |
672 | } else { | | 1847 | } else { |
673 | if (!D && !includeMinimalInlineScopes()) | | 1848 | uint64_t Size = DT.getSizeInBits(); |
674 | // Lazily construct the subprogram if we didn't see either concrete or | | 1849 | uint64_t FieldSize = getBaseTypeSize(DD, DT); |
675 | // inlined versions during codegen. (except in -gmlt ^ where we want | | 1850 | uint64_t OffsetInBytes; |
676 | // to omit these entirely) | | 1851 | |
677 | D = getOrCreateSubprogramDIE(SP); | | 1852 | if (Size != FieldSize) { |
678 | if (D) | | 1853 | // Handle bitfield. |
679 | // And attach the attributes | | 1854 | addUInt(MemberDie, dwarf::DW_AT_byte_size, None, |
680 | applySubprogramAttributesToDefinition(SP, *D); | | 1855 | getBaseTypeSize(DD, DT) >> 3); |
681 | } | | 1856 | addUInt(MemberDie, dwarf::DW_AT_bit_size, None, DT.getSizeInBits()); |
682 | } | | 1857 | |
683 | void DwarfCompileUnit::collectDeadVariables(DISubprogram SP) { | | 1858 | uint64_t Offset = DT.getOffsetInBits(); |
684 | assert(SP.isSubprogram() && "CU's subprogram list contains a non-subprogram"); | | 1859 | uint64_t AlignMask = ~(DT.getAlignInBits() - 1); |
685 | assert(SP.isDefinition() && | | 1860 | uint64_t HiMark = (Offset + FieldSize) & AlignMask; |
686 | "CU's subprogram list contains a subprogram declaration"); | | 1861 | uint64_t FieldOffset = (HiMark - FieldSize); |
687 | DIArray Variables = SP.getVariables(); | | 1862 | Offset -= FieldOffset; |
688 | if (Variables.getNumElements() == 0) | | 1863 | |
689 | return; | | 1864 | // Maybe we need to work from the other end. |
690 | | | 1865 | if (Asm->getDataLayout().isLittleEndian()) |
691 | DIE *SPDIE = DU->getAbstractSPDies().lookup(SP); | | 1866 | Offset = FieldSize - (Offset + Size); |
692 | if (!SPDIE) | | 1867 | addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, Offset); |
693 | SPDIE = getDIE(SP); | | 1868 | |
694 | assert(SPDIE); | | 1869 | // Here WD_AT_data_member_location points to the anonymous |
695 | for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) { | | 1870 | // field that includes this bit field. |
696 | DIVariable DV(Variables.getElement(vi)); | | 1871 | OffsetInBytes = FieldOffset >> 3; |
697 | assert(DV.isVariable()); | | 1872 | } else |
698 | DbgVariable NewVar(DV, DIExpression(nullptr), DD); | | 1873 | // This is not a bitfield. |
699 | auto VariableDie = constructVariableDIE(NewVar); | | 1874 | OffsetInBytes = DT.getOffsetInBits() >> 3; |
700 | applyVariableAttributes(NewVar, *VariableDie); | | 1875 | addUInt(MemberDie, dwarf::DW_AT_data_member_location, None, OffsetInBytes); |
701 | SPDIE->addChild(std::move(VariableDie)); | | | |
702 | } | | 1876 | } |
703 | } | | | |
704 | | | | |
705 | void DwarfCompileUnit::emitHeader(const MCSymbol *ASectionSym) const { | | | |
706 | // Don't bother labeling the .dwo unit, as its offset isn't used. | | | |
707 | if (!Skeleton) | | | |
708 | Asm->OutStreamer.EmitLabel(LabelBegin); | | | |
709 | | | | |
710 | DwarfUnit::emitHeader(ASectionSym); | | | |
711 | } | | | |
712 | | | | |
713 | /// addGlobalName - Add a new global name to the compile unit. | | | |
714 | void DwarfCompileUnit::addGlobalName(StringRef Name, DIE &Die, | | | |
715 | DIScope Context) { | | | |
716 | if (includeMinimalInlineScopes()) | | | |
717 | return; | | | |
718 | std::string FullName = getParentContextString(Context) + Name.str(); | | | |
719 | GlobalNames[FullName] = &Die; | | | |
720 | } | | | |
721 | | | | |
722 | /// Add a new global type to the unit. | | | |
723 | void DwarfCompileUnit::addGlobalType(DIType Ty, const DIE &Die, | | | |
724 | DIScope Context) { | | | |
725 | if (includeMinimalInlineScopes()) | | | |
726 | return; | | | |
727 | std::string FullName = getParentContextString(Context) + Ty.getName().str(); | | | |
728 | GlobalTypes[FullName] = &Die; | | | |
729 | } | | | |
730 | | | 1877 | |
731 | /// addVariableAddress - Add DW_AT_location attribute for a | | 1878 | if (DT.isProtected()) |
732 | /// DbgVariable based on provided MachineLocation. | | 1879 | addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, |
733 | void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, | | 1880 | dwarf::DW_ACCESS_protected); |
734 | MachineLocation Location) { | | 1881 | else if (DT.isPrivate()) |
735 | if (DV.variableHasComplexAddress()) | | 1882 | addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, |
736 | addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); | | 1883 | dwarf::DW_ACCESS_private); |
737 | else if (DV.isBlockByrefVariable()) | | 1884 | // Otherwise C++ member and base classes are considered public. |
738 | addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location); | | | |
739 | else | | 1885 | else |
740 | addAddress(Die, dwarf::DW_AT_location, Location, | | 1886 | addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, |
741 | DV.getVariable().isIndirect()); | | 1887 | dwarf::DW_ACCESS_public); |
742 | } | | 1888 | if (DT.isVirtual()) |
743 | | | 1889 | addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, |
744 | /// Add an address attribute to a die based on the location provided. | | 1890 | dwarf::DW_VIRTUALITY_virtual); |
745 | void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, | | 1891 | |
746 | const MachineLocation &Location, | | 1892 | // Objective-C properties. |
747 | bool Indirect) { | | 1893 | if (MDNode *PNode = DT.getObjCProperty()) |
748 | DIELoc *Loc = new (DIEValueAllocator) DIELoc(); | | 1894 | if (DIEEntry *PropertyDie = getDIEEntry(PNode)) |
749 | | | 1895 | MemberDie->addValue(dwarf::DW_AT_APPLE_property, dwarf::DW_FORM_ref4, |
750 | bool validReg; | | 1896 | PropertyDie); |
751 | if (Location.isReg() && !Indirect) | | 1897 | |
752 | validReg = addRegisterOpPiece(*Loc, Location.getReg()); | | 1898 | if (DT.isArtificial()) |
| | | 1899 | addFlag(MemberDie, dwarf::DW_AT_artificial); |
| | | 1900 | } |
| | | 1901 | |
| | | 1902 | /// getOrCreateStaticMemberDIE - Create new DIE for C++ static member. |
| | | 1903 | DIE *CompileUnit::getOrCreateStaticMemberDIE(DIDerivedType DT) { |
| | | 1904 | if (!DT.Verify()) |
| | | 1905 | return NULL; |
| | | 1906 | |
| | | 1907 | // Construct the context before querying for the existence of the DIE in case |
| | | 1908 | // such construction creates the DIE. |
| | | 1909 | DIE *ContextDIE = getOrCreateContextDIE(resolve(DT.getContext())); |
| | | 1910 | assert(dwarf::isType(ContextDIE->getTag()) && |
| | | 1911 | "Static member should belong to a type."); |
| | | 1912 | |
| | | 1913 | DIE *StaticMemberDIE = getDIE(DT); |
| | | 1914 | if (StaticMemberDIE) |
| | | 1915 | return StaticMemberDIE; |
| | | 1916 | |
| | | 1917 | StaticMemberDIE = createAndAddDIE(DT.getTag(), *ContextDIE, DT); |
| | | 1918 | |
| | | 1919 | DIType Ty = resolve(DT.getTypeDerivedFrom()); |
| | | 1920 | |
| | | 1921 | addString(StaticMemberDIE, dwarf::DW_AT_name, DT.getName()); |
| | | 1922 | addType(StaticMemberDIE, Ty); |
| | | 1923 | addSourceLine(StaticMemberDIE, DT); |
| | | 1924 | addFlag(StaticMemberDIE, dwarf::DW_AT_external); |
| | | 1925 | addFlag(StaticMemberDIE, dwarf::DW_AT_declaration); |
| | | 1926 | |
| | | 1927 | // FIXME: We could omit private if the parent is a class_type, and |
| | | 1928 | // public if the parent is something else. |
| | | 1929 | if (DT.isProtected()) |
| | | 1930 | addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, |
| | | 1931 | dwarf::DW_ACCESS_protected); |
| | | 1932 | else if (DT.isPrivate()) |
| | | 1933 | addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, |
| | | 1934 | dwarf::DW_ACCESS_private); |
753 | else | | 1935 | else |
754 | validReg = addRegisterOffset(*Loc, Location.getReg(), Location.getOffset()); | | 1936 | addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, |
755 | | | 1937 | dwarf::DW_ACCESS_public); |
756 | if (!validReg) | | | |
757 | return; | | | |
758 | | | | |
759 | if (!Location.isReg() && Indirect) | | | |
760 | addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); | | | |
761 | | | | |
762 | // Now attach the location information to the DIE. | | | |
763 | addBlock(Die, Attribute, Loc); | | | |
764 | } | | | |
765 | | | | |
766 | /// Start with the address based on the location provided, and generate the | | | |
767 | /// DWARF information necessary to find the actual variable given the extra | | | |
768 | /// address information encoded in the DbgVariable, starting from the starting | | | |
769 | /// location. Add the DWARF information to the die. | | | |
770 | void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, | | | |
771 | dwarf::Attribute Attribute, | | | |
772 | const MachineLocation &Location) { | | | |
773 | DIELoc *Loc = new (DIEValueAllocator) DIELoc(); | | | |
774 | DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); | | | |
775 | DIExpression Expr = DV.getExpression(); | | | |
776 | if (Location.getOffset()) { | | | |
777 | if (DwarfExpr.AddMachineRegIndirect(Location.getReg(), | | | |
778 | Location.getOffset())) { | | | |
779 | DwarfExpr.AddExpression(Expr); | | | |
780 | assert(!DV.getVariable().isIndirect() | | | |
781 | && "double indirection not handled"); | | | |
782 | } | | | |
783 | } else { | | | |
784 | if (DwarfExpr.AddMachineRegExpression(Expr, Location.getReg())) | | | |
785 | if (DV.getVariable().isIndirect()) | | | |
786 | DwarfExpr.EmitOp(dwarf::DW_OP_deref); | | | |
787 | } | | | |
788 | | | | |
789 | // Now attach the location information to the DIE. | | | |
790 | addBlock(Die, Attribute, Loc); | | | |
791 | } | | | |
792 | | | | |
793 | /// Add a Dwarf loclistptr attribute data and value. | | | |
794 | void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute, | | | |
795 | unsigned Index) { | | | |
796 | DIEValue *Value = new (DIEValueAllocator) DIELocList(Index); | | | |
797 | dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset | | | |
798 | : dwarf::DW_FORM_data4; | | | |
799 | Die.addValue(Attribute, Form, Value); | | | |
800 | } | | | |
801 | | | | |
802 | void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var, | | | |
803 | DIE &VariableDie) { | | | |
804 | StringRef Name = Var.getName(); | | | |
805 | if (!Name.empty()) | | | |
806 | addString(VariableDie, dwarf::DW_AT_name, Name); | | | |
807 | addSourceLine(VariableDie, Var.getVariable()); | | | |
808 | addType(VariableDie, Var.getType()); | | | |
809 | if (Var.isArtificial()) | | | |
810 | addFlag(VariableDie, dwarf::DW_AT_artificial); | | | |
811 | } | | | |
812 | | | | |
813 | /// Add a Dwarf expression attribute data and value. | | | |
814 | void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form, | | | |
815 | const MCExpr *Expr) { | | | |
816 | DIEValue *Value = new (DIEValueAllocator) DIEExpr(Expr); | | | |
817 | Die.addValue((dwarf::Attribute)0, Form, Value); | | | |
818 | } | | | |
819 | | | | |
820 | void DwarfCompileUnit::applySubprogramAttributesToDefinition(DISubprogram SP, | | | |
821 | DIE &SPDie) { | | | |
822 | DISubprogram SPDecl = SP.getFunctionDeclaration(); | | | |
823 | DIScope Context = resolve(SPDecl ? SPDecl.getContext() : SP.getContext()); | | | |
824 | applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes()); | | | |
825 | addGlobalName(SP.getName(), SPDie, Context); | | | |
826 | } | | | |
827 | | | | |
828 | bool DwarfCompileUnit::isDwoUnit() const { | | | |
829 | return DD->useSplitDwarf() && Skeleton; | | | |
830 | } | | | |
831 | | | 1938 | |
832 | bool DwarfCompileUnit::includeMinimalInlineScopes() const { | | 1939 | if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT.getConstant())) |
833 | return getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly || | | 1940 | addConstantValue(StaticMemberDIE, CI, isUnsignedDIType(DD, Ty)); |
834 | (DD->useSplitDwarf() && !Skeleton); | | 1941 | if (const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT.getConstant())) |
| | | 1942 | addConstantFPValue(StaticMemberDIE, CFP); |
| | | 1943 | |
| | | 1944 | return StaticMemberDIE; |
| | | 1945 | } |
| | | 1946 | |
| | | 1947 | void CompileUnit::emitHeader(const MCSection *ASection, |
| | | 1948 | const MCSymbol *ASectionSym) { |
| | | 1949 | Asm->OutStreamer.AddComment("DWARF version number"); |
| | | 1950 | Asm->EmitInt16(DD->getDwarfVersion()); |
| | | 1951 | Asm->OutStreamer.AddComment("Offset Into Abbrev. Section"); |
| | | 1952 | Asm->EmitSectionOffset(Asm->GetTempSymbol(ASection->getLabelBeginName()), |
| | | 1953 | ASectionSym); |
| | | 1954 | Asm->OutStreamer.AddComment("Address Size (in bytes)"); |
| | | 1955 | Asm->EmitInt8(Asm->getDataLayout().getPointerSize()); |
835 | } | | 1956 | } |
836 | } // end llvm namespace | | | |