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 uint16_t Attribute; 35 36 /// Form - Dwarf form code. 37 /// 38 uint16_t Form; 39 public: DIEAbbrevData(uint16_t A,uint16_t F)40 DIEAbbrevData(uint16_t A, uint16_t F) : Attribute(A), Form(F) {} 41 42 // Accessors. getAttribute()43 uint16_t getAttribute() const { return Attribute; } getForm()44 uint16_t 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 uint16_t Tag; 58 59 /// ChildrenFlag - Dwarf children flag. 60 /// 61 uint16_t ChildrenFlag; 62 63 /// Unique number for node. 64 /// 65 unsigned Number; 66 67 /// Data - Raw data bytes for abbreviation. 68 /// 69 SmallVector<DIEAbbrevData, 8> Data; 70 71 public: DIEAbbrev(uint16_t T,uint16_t C)72 DIEAbbrev(uint16_t T, uint16_t C) : Tag(T), ChildrenFlag(C), Data() {} 73 74 // Accessors. getTag()75 uint16_t getTag() const { return Tag; } getNumber()76 unsigned getNumber() const { return Number; } getChildrenFlag()77 uint16_t getChildrenFlag() const { return ChildrenFlag; } getData()78 const SmallVector<DIEAbbrevData, 8> &getData() const { return Data; } setTag(uint16_t T)79 void setTag(uint16_t T) { Tag = T; } setChildrenFlag(uint16_t CF)80 void setChildrenFlag(uint16_t CF) { ChildrenFlag = CF; } setNumber(unsigned N)81 void setNumber(unsigned N) { Number = N; } 82 83 /// AddAttribute - Adds another set of attribute information to the 84 /// abbreviation. AddAttribute(uint16_t Attribute,uint16_t Form)85 void AddAttribute(uint16_t Attribute, uint16_t 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. AddFirstAttribute(uint16_t Attribute,uint16_t Form)91 void AddFirstAttribute(uint16_t Attribute, uint16_t 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 /// Offset - Offset in debug info section. 117 /// 118 unsigned Offset; 119 120 /// Size - Size of instance + children. 121 /// 122 unsigned Size; 123 124 /// Abbrev - Buffer for constructing abbreviation. 125 /// 126 DIEAbbrev Abbrev; 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: DIE(unsigned Tag)141 explicit DIE(unsigned Tag) 142 : Offset(0), Size(0), Abbrev(Tag, dwarf::DW_CHILDREN_no), Parent(0), 143 IndentCount(0) {} 144 virtual ~DIE(); 145 146 // Accessors. getAbbrev()147 DIEAbbrev &getAbbrev() { return Abbrev; } getAbbrevNumber()148 unsigned getAbbrevNumber() const { return Abbrev.getNumber(); } getTag()149 unsigned getTag() const { return Abbrev.getTag(); } getOffset()150 unsigned getOffset() const { return Offset; } getSize()151 unsigned getSize() const { return Size; } getChildren()152 const std::vector<DIE *> &getChildren() const { return Children; } getValues()153 const SmallVector<DIEValue*, 32> &getValues() const { return Values; } getParent()154 DIE *getParent() const { return Parent; } setTag(unsigned Tag)155 void setTag(unsigned Tag) { Abbrev.setTag(Tag); } setOffset(unsigned O)156 void setOffset(unsigned O) { Offset = O; } setSize(unsigned S)157 void setSize(unsigned S) { Size = S; } 158 159 /// addValue - Add a value and attributes to a DIE. 160 /// addValue(unsigned Attribute,unsigned Form,DIEValue * Value)161 void addValue(unsigned Attribute, unsigned Form, DIEValue *Value) { 162 Abbrev.AddAttribute(Attribute, Form); 163 Values.push_back(Value); 164 } 165 166 /// addChild - Add a child to the DIE. 167 /// addChild(DIE * Child)168 void addChild(DIE *Child) { 169 if (Child->getParent()) { 170 assert (Child->getParent() == this && "Unexpected DIE Parent!"); 171 return; 172 } 173 Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes); 174 Children.push_back(Child); 175 Child->Parent = this; 176 } 177 178 #ifndef NDEBUG 179 void print(raw_ostream &O, unsigned IncIndent = 0); 180 void dump(); 181 #endif 182 }; 183 184 //===--------------------------------------------------------------------===// 185 /// DIEValue - A debug information entry value. 186 /// 187 class DIEValue { 188 virtual void anchor(); 189 public: 190 enum { 191 isInteger, 192 isString, 193 isLabel, 194 isDelta, 195 isEntry, 196 isBlock 197 }; 198 protected: 199 /// Type - Type of data stored in the value. 200 /// 201 unsigned Type; 202 public: DIEValue(unsigned T)203 explicit DIEValue(unsigned T) : Type(T) {} ~DIEValue()204 virtual ~DIEValue() {} 205 206 // Accessors getType()207 unsigned getType() const { return Type; } 208 209 /// EmitValue - Emit value via the Dwarf writer. 210 /// 211 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const = 0; 212 213 /// SizeOf - Return the size of a value in bytes. 214 /// 215 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const = 0; 216 217 // Implement isa/cast/dyncast. classof(const DIEValue *)218 static bool classof(const DIEValue *) { return true; } 219 220 #ifndef NDEBUG 221 virtual void print(raw_ostream &O) = 0; 222 void dump(); 223 #endif 224 }; 225 226 //===--------------------------------------------------------------------===// 227 /// DIEInteger - An integer value DIE. 228 /// 229 class DIEInteger : public DIEValue { 230 uint64_t Integer; 231 public: DIEInteger(uint64_t I)232 explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {} 233 234 /// BestForm - Choose the best form for integer. 235 /// BestForm(bool IsSigned,uint64_t Int)236 static unsigned BestForm(bool IsSigned, uint64_t Int) { 237 if (IsSigned) { 238 if ((char)Int == (signed)Int) return dwarf::DW_FORM_data1; 239 if ((short)Int == (signed)Int) return dwarf::DW_FORM_data2; 240 if ((int)Int == (signed)Int) return dwarf::DW_FORM_data4; 241 } else { 242 if ((unsigned char)Int == Int) return dwarf::DW_FORM_data1; 243 if ((unsigned short)Int == Int) return dwarf::DW_FORM_data2; 244 if ((unsigned int)Int == Int) return dwarf::DW_FORM_data4; 245 } 246 return dwarf::DW_FORM_data8; 247 } 248 249 /// EmitValue - Emit integer of appropriate size. 250 /// 251 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 252 getValue()253 uint64_t getValue() const { return Integer; } 254 255 /// SizeOf - Determine size of integer value in bytes. 256 /// 257 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; 258 259 // Implement isa/cast/dyncast. classof(const DIEInteger *)260 static bool classof(const DIEInteger *) { return true; } classof(const DIEValue * I)261 static bool classof(const DIEValue *I) { return I->getType() == isInteger; } 262 263 #ifndef NDEBUG 264 virtual void print(raw_ostream &O); 265 #endif 266 }; 267 268 //===--------------------------------------------------------------------===// 269 /// DIELabel - A label expression DIE. 270 // 271 class DIELabel : public DIEValue { 272 const MCSymbol *Label; 273 public: DIELabel(const MCSymbol * L)274 explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {} 275 276 /// EmitValue - Emit label value. 277 /// 278 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 279 280 /// getValue - Get MCSymbol. 281 /// getValue()282 const MCSymbol *getValue() const { return Label; } 283 284 /// SizeOf - Determine size of label value in bytes. 285 /// 286 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; 287 288 // Implement isa/cast/dyncast. classof(const DIELabel *)289 static bool classof(const DIELabel *) { return true; } classof(const DIEValue * L)290 static bool classof(const DIEValue *L) { return L->getType() == isLabel; } 291 292 #ifndef NDEBUG 293 virtual void print(raw_ostream &O); 294 #endif 295 }; 296 297 //===--------------------------------------------------------------------===// 298 /// DIEDelta - A simple label difference DIE. 299 /// 300 class DIEDelta : public DIEValue { 301 const MCSymbol *LabelHi; 302 const MCSymbol *LabelLo; 303 public: DIEDelta(const MCSymbol * Hi,const MCSymbol * Lo)304 DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) 305 : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {} 306 307 /// EmitValue - Emit delta value. 308 /// 309 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 310 311 /// SizeOf - Determine size of delta value in bytes. 312 /// 313 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; 314 315 // Implement isa/cast/dyncast. classof(const DIEDelta *)316 static bool classof(const DIEDelta *) { return true; } classof(const DIEValue * D)317 static bool classof(const DIEValue *D) { return D->getType() == isDelta; } 318 319 #ifndef NDEBUG 320 virtual void print(raw_ostream &O); 321 #endif 322 }; 323 324 //===--------------------------------------------------------------------===// 325 /// DIEEntry - A pointer to another debug information entry. An instance of 326 /// this class can also be used as a proxy for a debug information entry not 327 /// yet defined (ie. types.) 328 class DIEEntry : public DIEValue { 329 DIE *const Entry; 330 public: DIEEntry(DIE * E)331 explicit DIEEntry(DIE *E) : DIEValue(isEntry), Entry(E) {} 332 getEntry()333 DIE *getEntry() const { return Entry; } 334 335 /// EmitValue - Emit debug information entry offset. 336 /// 337 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 338 339 /// SizeOf - Determine size of debug information entry in bytes. 340 /// SizeOf(AsmPrinter * AP,unsigned Form)341 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const { 342 return sizeof(int32_t); 343 } 344 345 // Implement isa/cast/dyncast. classof(const DIEEntry *)346 static bool classof(const DIEEntry *) { return true; } classof(const DIEValue * E)347 static bool classof(const DIEValue *E) { return E->getType() == isEntry; } 348 349 #ifndef NDEBUG 350 virtual void print(raw_ostream &O); 351 #endif 352 }; 353 354 //===--------------------------------------------------------------------===// 355 /// DIEBlock - A block of values. Primarily used for location expressions. 356 // 357 class DIEBlock : public DIEValue, public DIE { 358 unsigned Size; // Size in bytes excluding size header. 359 public: DIEBlock()360 DIEBlock() 361 : DIEValue(isBlock), DIE(0), Size(0) {} ~DIEBlock()362 virtual ~DIEBlock() {} 363 364 /// ComputeSize - calculate the size of the block. 365 /// 366 unsigned ComputeSize(AsmPrinter *AP); 367 368 /// BestForm - Choose the best form for data. 369 /// BestForm()370 unsigned BestForm() const { 371 if ((unsigned char)Size == Size) return dwarf::DW_FORM_block1; 372 if ((unsigned short)Size == Size) return dwarf::DW_FORM_block2; 373 if ((unsigned int)Size == Size) return dwarf::DW_FORM_block4; 374 return dwarf::DW_FORM_block; 375 } 376 377 /// EmitValue - Emit block data. 378 /// 379 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 380 381 /// SizeOf - Determine size of block data in bytes. 382 /// 383 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; 384 385 // Implement isa/cast/dyncast. classof(const DIEBlock *)386 static bool classof(const DIEBlock *) { return true; } classof(const DIEValue * E)387 static bool classof(const DIEValue *E) { return E->getType() == isBlock; } 388 389 #ifndef NDEBUG 390 virtual void print(raw_ostream &O); 391 #endif 392 }; 393 394 } // end llvm namespace 395 396 #endif 397