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 /// Attribute 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; } 155 /// Climb up the parent chain to get the compile unit DIE this DIE belongs 156 /// to. 157 DIE *getCompileUnit() const; setTag(unsigned Tag)158 void setTag(unsigned Tag) { Abbrev.setTag(Tag); } setOffset(unsigned O)159 void setOffset(unsigned O) { Offset = O; } setSize(unsigned S)160 void setSize(unsigned S) { Size = S; } 161 162 /// addValue - Add a value and attributes to a DIE. 163 /// addValue(unsigned Attribute,unsigned Form,DIEValue * Value)164 void addValue(unsigned Attribute, unsigned Form, DIEValue *Value) { 165 Abbrev.AddAttribute(Attribute, Form); 166 Values.push_back(Value); 167 } 168 169 /// addChild - Add a child to the DIE. 170 /// addChild(DIE * Child)171 void addChild(DIE *Child) { 172 if (Child->getParent()) { 173 assert (Child->getParent() == this && "Unexpected DIE Parent!"); 174 return; 175 } 176 Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes); 177 Children.push_back(Child); 178 Child->Parent = this; 179 } 180 181 #ifndef NDEBUG 182 void print(raw_ostream &O, unsigned IncIndent = 0); 183 void dump(); 184 #endif 185 }; 186 187 //===--------------------------------------------------------------------===// 188 /// DIEValue - A debug information entry value. 189 /// 190 class DIEValue { 191 virtual void anchor(); 192 public: 193 enum { 194 isInteger, 195 isString, 196 isLabel, 197 isDelta, 198 isEntry, 199 isBlock 200 }; 201 protected: 202 /// Type - Type of data stored in the value. 203 /// 204 unsigned Type; 205 public: DIEValue(unsigned T)206 explicit DIEValue(unsigned T) : Type(T) {} ~DIEValue()207 virtual ~DIEValue() {} 208 209 // Accessors getType()210 unsigned getType() const { return Type; } 211 212 /// EmitValue - Emit value via the Dwarf writer. 213 /// 214 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const = 0; 215 216 /// SizeOf - Return the size of a value in bytes. 217 /// 218 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const = 0; 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 const int64_t SignedInt = Int; 239 if ((char)Int == SignedInt) return dwarf::DW_FORM_data1; 240 if ((short)Int == SignedInt) return dwarf::DW_FORM_data2; 241 if ((int)Int == SignedInt) return dwarf::DW_FORM_data4; 242 } else { 243 if ((unsigned char)Int == Int) return dwarf::DW_FORM_data1; 244 if ((unsigned short)Int == Int) return dwarf::DW_FORM_data2; 245 if ((unsigned int)Int == Int) return dwarf::DW_FORM_data4; 246 } 247 return dwarf::DW_FORM_data8; 248 } 249 250 /// EmitValue - Emit integer of appropriate size. 251 /// 252 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 253 getValue()254 uint64_t getValue() const { return Integer; } 255 256 /// SizeOf - Determine size of integer value in bytes. 257 /// 258 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; 259 260 // Implement isa/cast/dyncast. 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 DIEValue * L)289 static bool classof(const DIEValue *L) { return L->getType() == isLabel; } 290 291 #ifndef NDEBUG 292 virtual void print(raw_ostream &O); 293 #endif 294 }; 295 296 //===--------------------------------------------------------------------===// 297 /// DIEDelta - A simple label difference DIE. 298 /// 299 class DIEDelta : public DIEValue { 300 const MCSymbol *LabelHi; 301 const MCSymbol *LabelLo; 302 public: DIEDelta(const MCSymbol * Hi,const MCSymbol * Lo)303 DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) 304 : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {} 305 306 /// EmitValue - Emit delta value. 307 /// 308 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 309 310 /// SizeOf - Determine size of delta value in bytes. 311 /// 312 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; 313 314 // Implement isa/cast/dyncast. classof(const DIEValue * D)315 static bool classof(const DIEValue *D) { return D->getType() == isDelta; } 316 317 #ifndef NDEBUG 318 virtual void print(raw_ostream &O); 319 #endif 320 }; 321 322 //===--------------------------------------------------------------------===// 323 /// DIEEntry - A pointer to another debug information entry. An instance of 324 /// this class can also be used as a proxy for a debug information entry not 325 /// yet defined (ie. types.) 326 class DIEEntry : public DIEValue { 327 DIE *const Entry; 328 public: DIEEntry(DIE * E)329 explicit DIEEntry(DIE *E) : DIEValue(isEntry), Entry(E) {} 330 getEntry()331 DIE *getEntry() const { return Entry; } 332 333 /// EmitValue - Emit debug information entry offset. 334 /// 335 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 336 337 /// SizeOf - Determine size of debug information entry in bytes. 338 /// SizeOf(AsmPrinter * AP,unsigned Form)339 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const { 340 return sizeof(int32_t); 341 } 342 343 // Implement isa/cast/dyncast. classof(const DIEValue * E)344 static bool classof(const DIEValue *E) { return E->getType() == isEntry; } 345 346 #ifndef NDEBUG 347 virtual void print(raw_ostream &O); 348 #endif 349 }; 350 351 //===--------------------------------------------------------------------===// 352 /// DIEBlock - A block of values. Primarily used for location expressions. 353 // 354 class DIEBlock : public DIEValue, public DIE { 355 unsigned Size; // Size in bytes excluding size header. 356 public: DIEBlock()357 DIEBlock() 358 : DIEValue(isBlock), DIE(0), Size(0) {} ~DIEBlock()359 virtual ~DIEBlock() {} 360 361 /// ComputeSize - calculate the size of the block. 362 /// 363 unsigned ComputeSize(AsmPrinter *AP); 364 365 /// BestForm - Choose the best form for data. 366 /// BestForm()367 unsigned BestForm() const { 368 if ((unsigned char)Size == Size) return dwarf::DW_FORM_block1; 369 if ((unsigned short)Size == Size) return dwarf::DW_FORM_block2; 370 if ((unsigned int)Size == Size) return dwarf::DW_FORM_block4; 371 return dwarf::DW_FORM_block; 372 } 373 374 /// EmitValue - Emit block data. 375 /// 376 virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; 377 378 /// SizeOf - Determine size of block data in bytes. 379 /// 380 virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; 381 382 // Implement isa/cast/dyncast. classof(const DIEValue * E)383 static bool classof(const DIEValue *E) { return E->getType() == isBlock; } 384 385 #ifndef NDEBUG 386 virtual void print(raw_ostream &O); 387 #endif 388 }; 389 390 } // end llvm namespace 391 392 #endif 393