1 //===--- lib/CodeGen/DIE.h - DWARF Info Entries -----------------*- C++ -*-===// 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 // Data structures for DWARF info entries. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef CODEGEN_ASMPRINTER_DIE_H__ 15 #define CODEGEN_ASMPRINTER_DIE_H__ 16 17 #include "llvm/ADT/FoldingSet.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/Support/Compiler.h" 20 #include "llvm/Support/Dwarf.h" 21 #include <vector> 22 23 namespace llvm { 24 class AsmPrinter; 25 class MCSymbol; 26 class raw_ostream; 27 28 //===--------------------------------------------------------------------===// 29 /// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a 30 /// Dwarf abbreviation. 31 class DIEAbbrevData { 32 /// Attribute - Dwarf attribute code. 33 /// 34 unsigned Attribute; 35 36 /// Form - Dwarf form code. 37 /// 38 unsigned Form; 39 public: 40 DIEAbbrevData(unsigned A, unsigned F) : Attribute(A), Form(F) {} 41 42 // Accessors. 43 unsigned getAttribute() const { return Attribute; } 44 unsigned getForm() const { return Form; } 45 46 /// Profile - Used to gather unique data for the abbreviation folding set. 47 /// 48 void Profile(FoldingSetNodeID &ID) const; 49 }; 50 51 //===--------------------------------------------------------------------===// 52 /// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug 53 /// information object. 54 class DIEAbbrev : public FoldingSetNode { 55 /// Tag - Dwarf tag code. 56 /// 57 unsigned Tag; 58 59 /// Unique number for node. 60 /// 61 unsigned Number; 62 63 /// ChildrenFlag - Dwarf children flag. 64 /// 65 unsigned ChildrenFlag; 66 67 /// Data - Raw data bytes for abbreviation. 68 /// 69 SmallVector<DIEAbbrevData, 8> Data; 70 71 public: 72 DIEAbbrev(unsigned T, unsigned C) : Tag(T), ChildrenFlag(C), Data() {} 73 74 // Accessors. 75 unsigned getTag() const { return Tag; } 76 unsigned getNumber() const { return Number; } 77 unsigned getChildrenFlag() const { return ChildrenFlag; } 78 const SmallVector<DIEAbbrevData, 8> &getData() const { return Data; } 79 void setTag(unsigned T) { Tag = T; } 80 void setChildrenFlag(unsigned CF) { ChildrenFlag = CF; } 81 void setNumber(unsigned N) { Number = N; } 82 83 /// AddAttribute - Adds another set of attribute information to the 84 /// abbreviation. 85 void AddAttribute(unsigned Attribute, unsigned Form) { 86 Data.push_back(DIEAbbrevData(Attribute, Form)); 87 } 88 89 /// AddFirstAttribute - Adds a set of attribute information to the front 90 /// of the abbreviation. 91 void AddFirstAttribute(unsigned Attribute, unsigned Form) { 92 Data.insert(Data.begin(), DIEAbbrevData(Attribute, Form)); 93 } 94 95 /// Profile - Used to gather unique data for the abbreviation folding set. 96 /// 97 void Profile(FoldingSetNodeID &ID) const; 98 99 /// Emit - Print the abbreviation using the specified asm printer. 100 /// 101 void Emit(AsmPrinter *AP) const; 102 103 #ifndef NDEBUG 104 void print(raw_ostream &O); 105 void dump(); 106 #endif 107 }; 108 109 //===--------------------------------------------------------------------===// 110 /// DIE - A structured debug information entry. Has an abbreviation which 111 /// describes it's organization. 112 class DIEValue; 113 114 class DIE { 115 protected: 116 /// Abbrev - Buffer for constructing abbreviation. 117 /// 118 DIEAbbrev Abbrev; 119 120 /// Offset - Offset in debug info section. 121 /// 122 unsigned Offset; 123 124 /// Size - Size of instance + children. 125 /// 126 unsigned Size; 127 128 /// Children DIEs. 129 /// 130 std::vector<DIE *> Children; 131 132 DIE *Parent; 133 134 /// Attributes values. 135 /// 136 SmallVector<DIEValue*, 32> Values; 137 138 // Private data for print() 139 mutable unsigned IndentCount; 140 public: 141 explicit DIE(unsigned Tag) 142 : Abbrev(Tag, dwarf::DW_CHILDREN_no), Offset(0), 143 Size(0), Parent (0), IndentCount(0) {} 144 virtual ~DIE(); 145 146 // Accessors. 147 DIEAbbrev &getAbbrev() { return Abbrev; } 148 unsigned getAbbrevNumber() const { return Abbrev.getNumber(); } 149 unsigned getTag() const { return Abbrev.getTag(); } 150 unsigned getOffset() const { return Offset; } 151 unsigned getSize() const { return Size; } 152 const std::vector<DIE *> &getChildren() const { return Children; } 153 const SmallVector<DIEValue*, 32> &getValues() const { return Values; } 154 DIE *getParent() const { return Parent; } 155 void setTag(unsigned Tag) { Abbrev.setTag(Tag); } 156 void setOffset(unsigned O) { Offset = O; } 157 void setSize(unsigned S) { Size = S; } 158 159 /// addValue - Add a value and attributes to a DIE. 160 /// 161 void addValue(unsigned Attribute, unsigned Form, DIEValue *Value) { 162 Abbrev.AddAttribute(Attribute, Form); 163 Values.push_back(Value); 164 } 165 166 /// SiblingOffset - Return the offset of the debug information entry's 167 /// sibling. 168 unsigned getSiblingOffset() const { return Offset + Size; } 169 170 /// addSiblingOffset - Add a sibling offset field to the front of the DIE. 171 /// The caller is responsible for deleting the return value at or after the 172 /// same time it destroys this DIE. 173 /// 174 DIEValue *addSiblingOffset(BumpPtrAllocator &A); 175 176 /// addChild - Add a child to the DIE. 177 /// 178 void addChild(DIE *Child) { 179 if (Child->getParent()) { 180 assert (Child->getParent() == this && "Unexpected DIE Parent!"); 181 return; 182 } 183 Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes); 184 Children.push_back(Child); 185 Child->Parent = this; 186 } 187 188 #ifndef NDEBUG 189 void print(raw_ostream &O, unsigned IncIndent = 0); 190 void dump(); 191 #endif 192 }; 193 194 //===--------------------------------------------------------------------===// 195 /// DIEValue - A debug information entry value. 196 /// 197 class DIEValue { 198 public: 199 enum { 200 isInteger, 201 isString, 202 isLabel, 203 isSectionOffset, 204 isDelta, 205 isEntry, 206 isBlock 207 }; 208 protected: 209 /// Type - Type of data stored in the value. 210 /// 211 unsigned Type; 212 public: 213 explicit DIEValue(unsigned T) : Type(T) {} 214 virtual ~DIEValue() {} 215 216 // Accessors 217 unsigned getType() const { return Type; } 218 219 /// EmitValue - Emit value via the Dwarf writer. 220 /// 221 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const = 0; 222 223 /// SizeOf - Return the size of a value in bytes. 224 /// 225 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const = 0; 226 227 // Implement isa/cast/dyncast. 228 static bool classof(const DIEValue *) { return true; } 229 230 #ifndef NDEBUG 231 virtual void print(raw_ostream &O) = 0; 232 void dump(); 233 #endif 234 }; 235 236 //===--------------------------------------------------------------------===// 237 /// DIEInteger - An integer value DIE. 238 /// 239 class DIEInteger : public DIEValue { 240 uint64_t Integer; 241 public: 242 explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {} 243 244 /// BestForm - Choose the best form for integer. 245 /// 246 static unsigned BestForm(bool IsSigned, uint64_t Int) { 247 if (IsSigned) { 248 if ((char)Int == (signed)Int) return dwarf::DW_FORM_data1; 249 if ((short)Int == (signed)Int) return dwarf::DW_FORM_data2; 250 if ((int)Int == (signed)Int) return dwarf::DW_FORM_data4; 251 } else { 252 if ((unsigned char)Int == Int) return dwarf::DW_FORM_data1; 253 if ((unsigned short)Int == Int) return dwarf::DW_FORM_data2; 254 if ((unsigned int)Int == Int) return dwarf::DW_FORM_data4; 255 } 256 return dwarf::DW_FORM_data8; 257 } 258 259 /// EmitValue - Emit integer of appropriate size. 260 /// 261 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 262 263 uint64_t getValue() const { return Integer; } 264 265 /// SizeOf - Determine size of integer value in bytes. 266 /// 267 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; 268 269 // Implement isa/cast/dyncast. 270 static bool classof(const DIEInteger *) { return true; } 271 static bool classof(const DIEValue *I) { return I->getType() == isInteger; } 272 273 #ifndef NDEBUG 274 virtual void print(raw_ostream &O); 275 #endif 276 }; 277 278 //===--------------------------------------------------------------------===// 279 /// DIEString - A string value DIE. This DIE keeps string reference only. 280 /// 281 class DIEString : public DIEValue { 282 const StringRef Str; 283 public: 284 explicit DIEString(const StringRef S) : DIEValue(isString), Str(S) {} 285 286 /// EmitValue - Emit string value. 287 /// 288 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 289 290 /// SizeOf - Determine size of string value in bytes. 291 /// 292 virtual unsigned SizeOf(AsmPrinter *AP, unsigned /*Form*/) const { 293 return Str.size() + sizeof(char); // sizeof('\0'); 294 } 295 296 // Implement isa/cast/dyncast. 297 static bool classof(const DIEString *) { return true; } 298 static bool classof(const DIEValue *S) { return S->getType() == isString; } 299 300 #ifndef NDEBUG 301 virtual void print(raw_ostream &O); 302 #endif 303 }; 304 305 //===--------------------------------------------------------------------===// 306 /// DIELabel - A label expression DIE. 307 // 308 class DIELabel : public DIEValue { 309 const MCSymbol *Label; 310 public: 311 explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {} 312 313 /// EmitValue - Emit label value. 314 /// 315 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 316 317 /// getValue - Get MCSymbol. 318 /// 319 const MCSymbol *getValue() const { return Label; } 320 321 /// SizeOf - Determine size of label value in bytes. 322 /// 323 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; 324 325 // Implement isa/cast/dyncast. 326 static bool classof(const DIELabel *) { return true; } 327 static bool classof(const DIEValue *L) { return L->getType() == isLabel; } 328 329 #ifndef NDEBUG 330 virtual void print(raw_ostream &O); 331 #endif 332 }; 333 334 //===--------------------------------------------------------------------===// 335 /// DIEDelta - A simple label difference DIE. 336 /// 337 class DIEDelta : public DIEValue { 338 const MCSymbol *LabelHi; 339 const MCSymbol *LabelLo; 340 public: 341 DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) 342 : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {} 343 344 /// EmitValue - Emit delta value. 345 /// 346 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 347 348 /// SizeOf - Determine size of delta value in bytes. 349 /// 350 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; 351 352 // Implement isa/cast/dyncast. 353 static bool classof(const DIEDelta *) { return true; } 354 static bool classof(const DIEValue *D) { return D->getType() == isDelta; } 355 356 #ifndef NDEBUG 357 virtual void print(raw_ostream &O); 358 #endif 359 }; 360 361 //===--------------------------------------------------------------------===// 362 /// DIEntry - A pointer to another debug information entry. An instance of 363 /// this class can also be used as a proxy for a debug information entry not 364 /// yet defined (ie. types.) 365 class DIEEntry : public DIEValue { 366 DIE *const Entry; 367 public: 368 explicit DIEEntry(DIE *E) : DIEValue(isEntry), Entry(E) {} 369 370 DIE *getEntry() const { return Entry; } 371 372 /// EmitValue - Emit debug information entry offset. 373 /// 374 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 375 376 /// SizeOf - Determine size of debug information entry in bytes. 377 /// 378 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const { 379 return sizeof(int32_t); 380 } 381 382 // Implement isa/cast/dyncast. 383 static bool classof(const DIEEntry *) { return true; } 384 static bool classof(const DIEValue *E) { return E->getType() == isEntry; } 385 386 #ifndef NDEBUG 387 virtual void print(raw_ostream &O); 388 #endif 389 }; 390 391 //===--------------------------------------------------------------------===// 392 /// DIEBlock - A block of values. Primarily used for location expressions. 393 // 394 class DIEBlock : public DIEValue, public DIE { 395 unsigned Size; // Size in bytes excluding size header. 396 public: 397 DIEBlock() 398 : DIEValue(isBlock), DIE(0), Size(0) {} 399 virtual ~DIEBlock() {} 400 401 /// ComputeSize - calculate the size of the block. 402 /// 403 unsigned ComputeSize(AsmPrinter *AP); 404 405 /// BestForm - Choose the best form for data. 406 /// 407 unsigned BestForm() const { 408 if ((unsigned char)Size == Size) return dwarf::DW_FORM_block1; 409 if ((unsigned short)Size == Size) return dwarf::DW_FORM_block2; 410 if ((unsigned int)Size == Size) return dwarf::DW_FORM_block4; 411 return dwarf::DW_FORM_block; 412 } 413 414 /// EmitValue - Emit block data. 415 /// 416 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 417 418 /// SizeOf - Determine size of block data in bytes. 419 /// 420 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; 421 422 // Implement isa/cast/dyncast. 423 static bool classof(const DIEBlock *) { return true; } 424 static bool classof(const DIEValue *E) { return E->getType() == isBlock; } 425 426 #ifndef NDEBUG 427 virtual void print(raw_ostream &O); 428 #endif 429 }; 430 431 } // end llvm namespace 432 433 #endif 434