1 //===--- llvm/Analysis/DebugInfo.h - Debug Information Helpers --*- 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 // This file defines a bunch of datatypes that are useful for creating and 11 // walking debug info in LLVM IR form. They essentially provide wrappers around 12 // the information in the global variables that's needed when constructing the 13 // DWARF information. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_ANALYSIS_DEBUGINFO_H 18 #define LLVM_ANALYSIS_DEBUGINFO_H 19 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/ADT/SmallPtrSet.h" 22 #include "llvm/ADT/StringRef.h" 23 #include "llvm/Support/Dwarf.h" 24 25 namespace llvm { 26 class BasicBlock; 27 class Constant; 28 class Function; 29 class GlobalVariable; 30 class Module; 31 class Type; 32 class Value; 33 class DbgDeclareInst; 34 class Instruction; 35 class MDNode; 36 class NamedMDNode; 37 class LLVMContext; 38 class raw_ostream; 39 40 class DIFile; 41 class DISubprogram; 42 class DILexicalBlock; 43 class DILexicalBlockFile; 44 class DIVariable; 45 class DIType; 46 class DIObjCProperty; 47 48 /// DIDescriptor - A thin wraper around MDNode to access encoded debug info. 49 /// This should not be stored in a container, because underly MDNode may 50 /// change in certain situations. 51 class DIDescriptor { 52 public: 53 enum { 54 FlagPrivate = 1 << 0, 55 FlagProtected = 1 << 1, 56 FlagFwdDecl = 1 << 2, 57 FlagAppleBlock = 1 << 3, 58 FlagBlockByrefStruct = 1 << 4, 59 FlagVirtual = 1 << 5, 60 FlagArtificial = 1 << 6, 61 FlagExplicit = 1 << 7, 62 FlagPrototyped = 1 << 8, 63 FlagObjcClassComplete = 1 << 9 64 }; 65 protected: 66 const MDNode *DbgNode; 67 68 StringRef getStringField(unsigned Elt) const; getUnsignedField(unsigned Elt)69 unsigned getUnsignedField(unsigned Elt) const { 70 return (unsigned)getUInt64Field(Elt); 71 } 72 uint64_t getUInt64Field(unsigned Elt) const; 73 DIDescriptor getDescriptorField(unsigned Elt) const; 74 75 template <typename DescTy> getFieldAs(unsigned Elt)76 DescTy getFieldAs(unsigned Elt) const { 77 return DescTy(getDescriptorField(Elt)); 78 } 79 80 GlobalVariable *getGlobalVariableField(unsigned Elt) const; 81 Constant *getConstantField(unsigned Elt) const; 82 Function *getFunctionField(unsigned Elt) const; 83 84 public: DIDescriptor()85 explicit DIDescriptor() : DbgNode(0) {} DIDescriptor(const MDNode * N)86 explicit DIDescriptor(const MDNode *N) : DbgNode(N) {} 87 explicit DIDescriptor(const DIFile F); 88 explicit DIDescriptor(const DISubprogram F); 89 explicit DIDescriptor(const DILexicalBlockFile F); 90 explicit DIDescriptor(const DILexicalBlock F); 91 explicit DIDescriptor(const DIVariable F); 92 explicit DIDescriptor(const DIType F); 93 Verify()94 bool Verify() const { return DbgNode != 0; } 95 96 operator MDNode *() const { return const_cast<MDNode*>(DbgNode); } 97 MDNode *operator ->() const { return const_cast<MDNode*>(DbgNode); } 98 getVersion()99 unsigned getVersion() const { 100 return getUnsignedField(0) & LLVMDebugVersionMask; 101 } 102 getTag()103 unsigned getTag() const { 104 return getUnsignedField(0) & ~LLVMDebugVersionMask; 105 } 106 107 /// print - print descriptor. 108 void print(raw_ostream &OS) const; 109 110 /// dump - print descriptor to dbgs() with a newline. 111 void dump() const; 112 113 bool isDerivedType() const; 114 bool isCompositeType() const; 115 bool isBasicType() const; 116 bool isVariable() const; 117 bool isSubprogram() const; 118 bool isGlobalVariable() const; 119 bool isScope() const; 120 bool isFile() const; 121 bool isCompileUnit() const; 122 bool isNameSpace() const; 123 bool isLexicalBlockFile() const; 124 bool isLexicalBlock() const; 125 bool isSubrange() const; 126 bool isEnumerator() const; 127 bool isType() const; 128 bool isGlobal() const; 129 bool isUnspecifiedParameter() const; 130 bool isTemplateTypeParameter() const; 131 bool isTemplateValueParameter() const; 132 bool isObjCProperty() const; 133 }; 134 135 /// DISubrange - This is used to represent ranges, for array bounds. 136 class DISubrange : public DIDescriptor { 137 public: DIDescriptor(N)138 explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {} 139 getLo()140 uint64_t getLo() const { return getUInt64Field(1); } getHi()141 uint64_t getHi() const { return getUInt64Field(2); } 142 }; 143 144 /// DIArray - This descriptor holds an array of descriptors. 145 class DIArray : public DIDescriptor { 146 public: 147 explicit DIArray(const MDNode *N = 0) DIDescriptor(N)148 : DIDescriptor(N) {} 149 150 unsigned getNumElements() const; getElement(unsigned Idx)151 DIDescriptor getElement(unsigned Idx) const { 152 return getDescriptorField(Idx); 153 } 154 }; 155 156 /// DIScope - A base class for various scopes. 157 class DIScope : public DIDescriptor { 158 virtual void anchor(); 159 public: DIDescriptor(N)160 explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {} ~DIScope()161 virtual ~DIScope() {} 162 163 StringRef getFilename() const; 164 StringRef getDirectory() const; 165 }; 166 167 /// DICompileUnit - A wrapper for a compile unit. 168 class DICompileUnit : public DIScope { 169 virtual void anchor(); 170 public: DIScope(N)171 explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {} 172 getLanguage()173 unsigned getLanguage() const { return getUnsignedField(2); } getFilename()174 StringRef getFilename() const { return getStringField(3); } getDirectory()175 StringRef getDirectory() const { return getStringField(4); } getProducer()176 StringRef getProducer() const { return getStringField(5); } 177 178 /// isMain - Each input file is encoded as a separate compile unit in LLVM 179 /// debugging information output. However, many target specific tool chains 180 /// prefer to encode only one compile unit in an object file. In this 181 /// situation, the LLVM code generator will include debugging information 182 /// entities in the compile unit that is marked as main compile unit. The 183 /// code generator accepts maximum one main compile unit per module. If a 184 /// module does not contain any main compile unit then the code generator 185 /// will emit multiple compile units in the output object file. 186 isMain()187 bool isMain() const { return getUnsignedField(6) != 0; } isOptimized()188 bool isOptimized() const { return getUnsignedField(7) != 0; } getFlags()189 StringRef getFlags() const { return getStringField(8); } getRunTimeVersion()190 unsigned getRunTimeVersion() const { return getUnsignedField(9); } 191 192 DIArray getEnumTypes() const; 193 DIArray getRetainedTypes() const; 194 DIArray getSubprograms() const; 195 DIArray getGlobalVariables() const; 196 197 /// Verify - Verify that a compile unit is well formed. 198 bool Verify() const; 199 200 /// print - print compile unit. 201 void print(raw_ostream &OS) const; 202 203 /// dump - print compile unit to dbgs() with a newline. 204 void dump() const; 205 }; 206 207 /// DIFile - This is a wrapper for a file. 208 class DIFile : public DIScope { 209 virtual void anchor(); 210 public: DIScope(N)211 explicit DIFile(const MDNode *N = 0) : DIScope(N) { 212 if (DbgNode && !isFile()) 213 DbgNode = 0; 214 } getFilename()215 StringRef getFilename() const { return getStringField(1); } getDirectory()216 StringRef getDirectory() const { return getStringField(2); } getCompileUnit()217 DICompileUnit getCompileUnit() const{ 218 assert (getVersion() <= LLVMDebugVersion10 && "Invalid CompileUnit!"); 219 return getFieldAs<DICompileUnit>(3); 220 } 221 }; 222 223 /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). 224 /// FIXME: it seems strange that this doesn't have either a reference to the 225 /// type/precision or a file/line pair for location info. 226 class DIEnumerator : public DIDescriptor { 227 public: DIDescriptor(N)228 explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {} 229 getName()230 StringRef getName() const { return getStringField(1); } getEnumValue()231 uint64_t getEnumValue() const { return getUInt64Field(2); } 232 }; 233 234 /// DIType - This is a wrapper for a type. 235 /// FIXME: Types should be factored much better so that CV qualifiers and 236 /// others do not require a huge and empty descriptor full of zeros. 237 class DIType : public DIScope { 238 virtual void anchor(); 239 protected: 240 // This ctor is used when the Tag has already been validated by a derived 241 // ctor. DIType(const MDNode * N,bool,bool)242 DIType(const MDNode *N, bool, bool) : DIScope(N) {} 243 244 public: 245 246 /// Verify - Verify that a type descriptor is well formed. 247 bool Verify() const; 248 explicit DIType(const MDNode *N); DIType()249 explicit DIType() {} ~DIType()250 virtual ~DIType() {} 251 getContext()252 DIScope getContext() const { return getFieldAs<DIScope>(1); } getName()253 StringRef getName() const { return getStringField(2); } getCompileUnit()254 DICompileUnit getCompileUnit() const{ 255 assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); 256 if (getVersion() == llvm::LLVMDebugVersion7) 257 return getFieldAs<DICompileUnit>(3); 258 259 return getFieldAs<DIFile>(3).getCompileUnit(); 260 } getFile()261 DIFile getFile() const { return getFieldAs<DIFile>(3); } getLineNumber()262 unsigned getLineNumber() const { return getUnsignedField(4); } getSizeInBits()263 uint64_t getSizeInBits() const { return getUInt64Field(5); } getAlignInBits()264 uint64_t getAlignInBits() const { return getUInt64Field(6); } 265 // FIXME: Offset is only used for DW_TAG_member nodes. Making every type 266 // carry this is just plain insane. getOffsetInBits()267 uint64_t getOffsetInBits() const { return getUInt64Field(7); } getFlags()268 unsigned getFlags() const { return getUnsignedField(8); } isPrivate()269 bool isPrivate() const { 270 return (getFlags() & FlagPrivate) != 0; 271 } isProtected()272 bool isProtected() const { 273 return (getFlags() & FlagProtected) != 0; 274 } isForwardDecl()275 bool isForwardDecl() const { 276 return (getFlags() & FlagFwdDecl) != 0; 277 } 278 // isAppleBlock - Return true if this is the Apple Blocks extension. isAppleBlockExtension()279 bool isAppleBlockExtension() const { 280 return (getFlags() & FlagAppleBlock) != 0; 281 } isBlockByrefStruct()282 bool isBlockByrefStruct() const { 283 return (getFlags() & FlagBlockByrefStruct) != 0; 284 } isVirtual()285 bool isVirtual() const { 286 return (getFlags() & FlagVirtual) != 0; 287 } isArtificial()288 bool isArtificial() const { 289 return (getFlags() & FlagArtificial) != 0; 290 } isObjcClassComplete()291 bool isObjcClassComplete() const { 292 return (getFlags() & FlagObjcClassComplete) != 0; 293 } isValid()294 bool isValid() const { 295 return DbgNode && (isBasicType() || isDerivedType() || isCompositeType()); 296 } getDirectory()297 StringRef getDirectory() const { 298 if (getVersion() == llvm::LLVMDebugVersion7) 299 return getCompileUnit().getDirectory(); 300 301 return getFieldAs<DIFile>(3).getDirectory(); 302 } getFilename()303 StringRef getFilename() const { 304 if (getVersion() == llvm::LLVMDebugVersion7) 305 return getCompileUnit().getFilename(); 306 307 return getFieldAs<DIFile>(3).getFilename(); 308 } 309 310 /// isUnsignedDIType - Return true if type encoding is unsigned. 311 bool isUnsignedDIType(); 312 313 /// replaceAllUsesWith - Replace all uses of debug info referenced by 314 /// this descriptor. 315 void replaceAllUsesWith(DIDescriptor &D); 316 void replaceAllUsesWith(MDNode *D); 317 318 /// print - print type. 319 void print(raw_ostream &OS) const; 320 321 /// dump - print type to dbgs() with a newline. 322 void dump() const; 323 }; 324 325 /// DIBasicType - A basic type, like 'int' or 'float'. 326 class DIBasicType : public DIType { 327 virtual void anchor(); 328 public: DIType(N)329 explicit DIBasicType(const MDNode *N = 0) : DIType(N) {} 330 getEncoding()331 unsigned getEncoding() const { return getUnsignedField(9); } 332 333 /// Verify - Verify that a basic type descriptor is well formed. 334 bool Verify() const; 335 336 /// print - print basic type. 337 void print(raw_ostream &OS) const; 338 339 /// dump - print basic type to dbgs() with a newline. 340 void dump() const; 341 }; 342 343 /// DIDerivedType - A simple derived type, like a const qualified type, 344 /// a typedef, a pointer or reference, etc. 345 class DIDerivedType : public DIType { 346 virtual void anchor(); 347 protected: DIDerivedType(const MDNode * N,bool,bool)348 explicit DIDerivedType(const MDNode *N, bool, bool) 349 : DIType(N, true, true) {} 350 public: 351 explicit DIDerivedType(const MDNode *N = 0) DIType(N,true,true)352 : DIType(N, true, true) {} 353 getTypeDerivedFrom()354 DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); } 355 356 /// getOriginalTypeSize - If this type is derived from a base type then 357 /// return base type size. 358 uint64_t getOriginalTypeSize() const; 359 360 /// getObjCProperty - Return property node, if this ivar is 361 /// associated with one. 362 MDNode *getObjCProperty() const; 363 getObjCPropertyName()364 StringRef getObjCPropertyName() const { 365 if (getVersion() > LLVMDebugVersion11) 366 return StringRef(); 367 return getStringField(10); 368 } getObjCPropertyGetterName()369 StringRef getObjCPropertyGetterName() const { 370 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); 371 return getStringField(11); 372 } getObjCPropertySetterName()373 StringRef getObjCPropertySetterName() const { 374 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); 375 return getStringField(12); 376 } isReadOnlyObjCProperty()377 bool isReadOnlyObjCProperty() { 378 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); 379 return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; 380 } isReadWriteObjCProperty()381 bool isReadWriteObjCProperty() { 382 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); 383 return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; 384 } isAssignObjCProperty()385 bool isAssignObjCProperty() { 386 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); 387 return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_assign) != 0; 388 } isRetainObjCProperty()389 bool isRetainObjCProperty() { 390 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); 391 return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_retain) != 0; 392 } isCopyObjCProperty()393 bool isCopyObjCProperty() { 394 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); 395 return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_copy) != 0; 396 } isNonAtomicObjCProperty()397 bool isNonAtomicObjCProperty() { 398 assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); 399 return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; 400 } 401 402 /// Verify - Verify that a derived type descriptor is well formed. 403 bool Verify() const; 404 405 /// print - print derived type. 406 void print(raw_ostream &OS) const; 407 408 /// dump - print derived type to dbgs() with a newline. 409 void dump() const; 410 }; 411 412 /// DICompositeType - This descriptor holds a type that can refer to multiple 413 /// other types, like a function or struct. 414 /// FIXME: Why is this a DIDerivedType?? 415 class DICompositeType : public DIDerivedType { 416 virtual void anchor(); 417 public: 418 explicit DICompositeType(const MDNode *N = 0) DIDerivedType(N,true,true)419 : DIDerivedType(N, true, true) { 420 if (N && !isCompositeType()) 421 DbgNode = 0; 422 } 423 getTypeArray()424 DIArray getTypeArray() const { return getFieldAs<DIArray>(10); } getRunTimeLang()425 unsigned getRunTimeLang() const { return getUnsignedField(11); } getContainingType()426 DICompositeType getContainingType() const { 427 return getFieldAs<DICompositeType>(12); 428 } getTemplateParams()429 DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); } 430 431 /// Verify - Verify that a composite type descriptor is well formed. 432 bool Verify() const; 433 434 /// print - print composite type. 435 void print(raw_ostream &OS) const; 436 437 /// dump - print composite type to dbgs() with a newline. 438 void dump() const; 439 }; 440 441 /// DITemplateTypeParameter - This is a wrapper for template type parameter. 442 class DITemplateTypeParameter : public DIDescriptor { 443 public: DIDescriptor(N)444 explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {} 445 getContext()446 DIScope getContext() const { return getFieldAs<DIScope>(1); } getName()447 StringRef getName() const { return getStringField(2); } getType()448 DIType getType() const { return getFieldAs<DIType>(3); } getFilename()449 StringRef getFilename() const { 450 return getFieldAs<DIFile>(4).getFilename(); 451 } getDirectory()452 StringRef getDirectory() const { 453 return getFieldAs<DIFile>(4).getDirectory(); 454 } getLineNumber()455 unsigned getLineNumber() const { return getUnsignedField(5); } getColumnNumber()456 unsigned getColumnNumber() const { return getUnsignedField(6); } 457 }; 458 459 /// DITemplateValueParameter - This is a wrapper for template value parameter. 460 class DITemplateValueParameter : public DIDescriptor { 461 public: DIDescriptor(N)462 explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {} 463 getContext()464 DIScope getContext() const { return getFieldAs<DIScope>(1); } getName()465 StringRef getName() const { return getStringField(2); } getType()466 DIType getType() const { return getFieldAs<DIType>(3); } getValue()467 uint64_t getValue() const { return getUInt64Field(4); } getFilename()468 StringRef getFilename() const { 469 return getFieldAs<DIFile>(5).getFilename(); 470 } getDirectory()471 StringRef getDirectory() const { 472 return getFieldAs<DIFile>(5).getDirectory(); 473 } getLineNumber()474 unsigned getLineNumber() const { return getUnsignedField(6); } getColumnNumber()475 unsigned getColumnNumber() const { return getUnsignedField(7); } 476 }; 477 478 /// DISubprogram - This is a wrapper for a subprogram (e.g. a function). 479 class DISubprogram : public DIScope { 480 virtual void anchor(); 481 public: DIScope(N)482 explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {} 483 getContext()484 DIScope getContext() const { return getFieldAs<DIScope>(2); } getName()485 StringRef getName() const { return getStringField(3); } getDisplayName()486 StringRef getDisplayName() const { return getStringField(4); } getLinkageName()487 StringRef getLinkageName() const { return getStringField(5); } getCompileUnit()488 DICompileUnit getCompileUnit() const{ 489 assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); 490 if (getVersion() == llvm::LLVMDebugVersion7) 491 return getFieldAs<DICompileUnit>(6); 492 493 return getFieldAs<DIFile>(6).getCompileUnit(); 494 } getLineNumber()495 unsigned getLineNumber() const { return getUnsignedField(7); } getType()496 DICompositeType getType() const { return getFieldAs<DICompositeType>(8); } 497 498 /// getReturnTypeName - Subprogram return types are encoded either as 499 /// DIType or as DICompositeType. getReturnTypeName()500 StringRef getReturnTypeName() const { 501 DICompositeType DCT(getFieldAs<DICompositeType>(8)); 502 if (DCT.Verify()) { 503 DIArray A = DCT.getTypeArray(); 504 DIType T(A.getElement(0)); 505 return T.getName(); 506 } 507 DIType T(getFieldAs<DIType>(8)); 508 return T.getName(); 509 } 510 511 /// isLocalToUnit - Return true if this subprogram is local to the current 512 /// compile unit, like 'static' in C. isLocalToUnit()513 unsigned isLocalToUnit() const { return getUnsignedField(9); } isDefinition()514 unsigned isDefinition() const { return getUnsignedField(10); } 515 getVirtuality()516 unsigned getVirtuality() const { return getUnsignedField(11); } getVirtualIndex()517 unsigned getVirtualIndex() const { return getUnsignedField(12); } 518 getContainingType()519 DICompositeType getContainingType() const { 520 return getFieldAs<DICompositeType>(13); 521 } 522 isArtificial()523 unsigned isArtificial() const { 524 if (getVersion() <= llvm::LLVMDebugVersion8) 525 return getUnsignedField(14); 526 return (getUnsignedField(14) & FlagArtificial) != 0; 527 } 528 /// isPrivate - Return true if this subprogram has "private" 529 /// access specifier. isPrivate()530 bool isPrivate() const { 531 if (getVersion() <= llvm::LLVMDebugVersion8) 532 return false; 533 return (getUnsignedField(14) & FlagPrivate) != 0; 534 } 535 /// isProtected - Return true if this subprogram has "protected" 536 /// access specifier. isProtected()537 bool isProtected() const { 538 if (getVersion() <= llvm::LLVMDebugVersion8) 539 return false; 540 return (getUnsignedField(14) & FlagProtected) != 0; 541 } 542 /// isExplicit - Return true if this subprogram is marked as explicit. isExplicit()543 bool isExplicit() const { 544 if (getVersion() <= llvm::LLVMDebugVersion8) 545 return false; 546 return (getUnsignedField(14) & FlagExplicit) != 0; 547 } 548 /// isPrototyped - Return true if this subprogram is prototyped. isPrototyped()549 bool isPrototyped() const { 550 if (getVersion() <= llvm::LLVMDebugVersion8) 551 return false; 552 return (getUnsignedField(14) & FlagPrototyped) != 0; 553 } 554 555 unsigned isOptimized() const; 556 getFilename()557 StringRef getFilename() const { 558 if (getVersion() == llvm::LLVMDebugVersion7) 559 return getCompileUnit().getFilename(); 560 561 return getFieldAs<DIFile>(6).getFilename(); 562 } 563 getDirectory()564 StringRef getDirectory() const { 565 if (getVersion() == llvm::LLVMDebugVersion7) 566 return getCompileUnit().getFilename(); 567 568 return getFieldAs<DIFile>(6).getDirectory(); 569 } 570 571 /// getScopeLineNumber - Get the beginning of the scope of the 572 /// function, not necessarily where the name of the program 573 /// starts. getScopeLineNumber()574 unsigned getScopeLineNumber() const { return getUnsignedField(20); } 575 576 /// Verify - Verify that a subprogram descriptor is well formed. 577 bool Verify() const; 578 579 /// print - print subprogram. 580 void print(raw_ostream &OS) const; 581 582 /// dump - print subprogram to dbgs() with a newline. 583 void dump() const; 584 585 /// describes - Return true if this subprogram provides debugging 586 /// information for the function F. 587 bool describes(const Function *F); 588 getFunction()589 Function *getFunction() const { return getFunctionField(16); } getTemplateParams()590 DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); } getFunctionDeclaration()591 DISubprogram getFunctionDeclaration() const { 592 return getFieldAs<DISubprogram>(18); 593 } 594 MDNode *getVariablesNodes() const; 595 DIArray getVariables() const; 596 }; 597 598 /// DIGlobalVariable - This is a wrapper for a global variable. 599 class DIGlobalVariable : public DIDescriptor { 600 public: DIDescriptor(N)601 explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {} 602 getContext()603 DIScope getContext() const { return getFieldAs<DIScope>(2); } getName()604 StringRef getName() const { return getStringField(3); } getDisplayName()605 StringRef getDisplayName() const { return getStringField(4); } getLinkageName()606 StringRef getLinkageName() const { return getStringField(5); } getCompileUnit()607 DICompileUnit getCompileUnit() const{ 608 assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); 609 if (getVersion() == llvm::LLVMDebugVersion7) 610 return getFieldAs<DICompileUnit>(6); 611 612 DIFile F = getFieldAs<DIFile>(6); 613 return F.getCompileUnit(); 614 } getFilename()615 StringRef getFilename() const { 616 if (getVersion() <= llvm::LLVMDebugVersion10) 617 return getContext().getFilename(); 618 return getFieldAs<DIFile>(6).getFilename(); 619 } getDirectory()620 StringRef getDirectory() const { 621 if (getVersion() <= llvm::LLVMDebugVersion10) 622 return getContext().getDirectory(); 623 return getFieldAs<DIFile>(6).getDirectory(); 624 625 } 626 getLineNumber()627 unsigned getLineNumber() const { return getUnsignedField(7); } getType()628 DIType getType() const { return getFieldAs<DIType>(8); } isLocalToUnit()629 unsigned isLocalToUnit() const { return getUnsignedField(9); } isDefinition()630 unsigned isDefinition() const { return getUnsignedField(10); } 631 getGlobal()632 GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } getConstant()633 Constant *getConstant() const { return getConstantField(11); } 634 635 /// Verify - Verify that a global variable descriptor is well formed. 636 bool Verify() const; 637 638 /// print - print global variable. 639 void print(raw_ostream &OS) const; 640 641 /// dump - print global variable to dbgs() with a newline. 642 void dump() const; 643 }; 644 645 /// DIVariable - This is a wrapper for a variable (e.g. parameter, local, 646 /// global etc). 647 class DIVariable : public DIDescriptor { 648 public: 649 explicit DIVariable(const MDNode *N = 0) DIDescriptor(N)650 : DIDescriptor(N) {} 651 getContext()652 DIScope getContext() const { return getFieldAs<DIScope>(1); } getName()653 StringRef getName() const { return getStringField(2); } getCompileUnit()654 DICompileUnit getCompileUnit() const { 655 assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); 656 if (getVersion() == llvm::LLVMDebugVersion7) 657 return getFieldAs<DICompileUnit>(3); 658 659 DIFile F = getFieldAs<DIFile>(3); 660 return F.getCompileUnit(); 661 } getLineNumber()662 unsigned getLineNumber() const { 663 return (getUnsignedField(4) << 8) >> 8; 664 } getArgNumber()665 unsigned getArgNumber() const { 666 unsigned L = getUnsignedField(4); 667 return L >> 24; 668 } getType()669 DIType getType() const { return getFieldAs<DIType>(5); } 670 671 /// isArtificial - Return true if this variable is marked as "artificial". isArtificial()672 bool isArtificial() const { 673 if (getVersion() <= llvm::LLVMDebugVersion8) 674 return false; 675 return (getUnsignedField(6) & FlagArtificial) != 0; 676 } 677 678 /// getInlinedAt - If this variable is inlined then return inline location. 679 MDNode *getInlinedAt() const; 680 681 /// Verify - Verify that a variable descriptor is well formed. 682 bool Verify() const; 683 684 /// HasComplexAddr - Return true if the variable has a complex address. hasComplexAddress()685 bool hasComplexAddress() const { 686 return getNumAddrElements() > 0; 687 } 688 689 unsigned getNumAddrElements() const; 690 getAddrElement(unsigned Idx)691 uint64_t getAddrElement(unsigned Idx) const { 692 if (getVersion() <= llvm::LLVMDebugVersion8) 693 return getUInt64Field(Idx+6); 694 if (getVersion() == llvm::LLVMDebugVersion9) 695 return getUInt64Field(Idx+7); 696 return getUInt64Field(Idx+8); 697 } 698 699 /// isBlockByrefVariable - Return true if the variable was declared as 700 /// a "__block" variable (Apple Blocks). isBlockByrefVariable()701 bool isBlockByrefVariable() const { 702 return getType().isBlockByrefStruct(); 703 } 704 705 /// isInlinedFnArgument - Return trule if this variable provides debugging 706 /// information for an inlined function arguments. 707 bool isInlinedFnArgument(const Function *CurFn); 708 709 /// print - print variable. 710 void print(raw_ostream &OS) const; 711 712 void printExtendedName(raw_ostream &OS) const; 713 714 /// dump - print variable to dbgs() with a newline. 715 void dump() const; 716 }; 717 718 /// DILexicalBlock - This is a wrapper for a lexical block. 719 class DILexicalBlock : public DIScope { 720 virtual void anchor(); 721 public: DIScope(N)722 explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {} getContext()723 DIScope getContext() const { return getFieldAs<DIScope>(1); } getLineNumber()724 unsigned getLineNumber() const { return getUnsignedField(2); } getColumnNumber()725 unsigned getColumnNumber() const { return getUnsignedField(3); } getDirectory()726 StringRef getDirectory() const { 727 StringRef dir = getFieldAs<DIFile>(4).getDirectory(); 728 return !dir.empty() ? dir : getContext().getDirectory(); 729 } getFilename()730 StringRef getFilename() const { 731 StringRef filename = getFieldAs<DIFile>(4).getFilename(); 732 return !filename.empty() ? filename : getContext().getFilename(); 733 } 734 }; 735 736 /// DILexicalBlockFile - This is a wrapper for a lexical block with 737 /// a filename change. 738 class DILexicalBlockFile : public DIScope { 739 virtual void anchor(); 740 public: DIScope(N)741 explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {} getContext()742 DIScope getContext() const { return getScope().getContext(); } getLineNumber()743 unsigned getLineNumber() const { return getScope().getLineNumber(); } getColumnNumber()744 unsigned getColumnNumber() const { return getScope().getColumnNumber(); } getDirectory()745 StringRef getDirectory() const { 746 StringRef dir = getFieldAs<DIFile>(2).getDirectory(); 747 return !dir.empty() ? dir : getContext().getDirectory(); 748 } getFilename()749 StringRef getFilename() const { 750 StringRef filename = getFieldAs<DIFile>(2).getFilename(); 751 assert(!filename.empty() && "Why'd you create this then?"); 752 return filename; 753 } getScope()754 DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(1); } 755 }; 756 757 /// DINameSpace - A wrapper for a C++ style name space. 758 class DINameSpace : public DIScope { 759 virtual void anchor(); 760 public: DIScope(N)761 explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {} getContext()762 DIScope getContext() const { return getFieldAs<DIScope>(1); } getName()763 StringRef getName() const { return getStringField(2); } getDirectory()764 StringRef getDirectory() const { 765 return getFieldAs<DIFile>(3).getDirectory(); 766 } getFilename()767 StringRef getFilename() const { 768 return getFieldAs<DIFile>(3).getFilename(); 769 } getCompileUnit()770 DICompileUnit getCompileUnit() const{ 771 assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); 772 if (getVersion() == llvm::LLVMDebugVersion7) 773 return getFieldAs<DICompileUnit>(3); 774 775 return getFieldAs<DIFile>(3).getCompileUnit(); 776 } getLineNumber()777 unsigned getLineNumber() const { return getUnsignedField(4); } 778 bool Verify() const; 779 }; 780 781 /// DILocation - This object holds location information. This object 782 /// is not associated with any DWARF tag. 783 class DILocation : public DIDescriptor { 784 public: DILocation(const MDNode * N)785 explicit DILocation(const MDNode *N) : DIDescriptor(N) { } 786 getLineNumber()787 unsigned getLineNumber() const { return getUnsignedField(0); } getColumnNumber()788 unsigned getColumnNumber() const { return getUnsignedField(1); } getScope()789 DIScope getScope() const { return getFieldAs<DIScope>(2); } getOrigLocation()790 DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); } getFilename()791 StringRef getFilename() const { return getScope().getFilename(); } getDirectory()792 StringRef getDirectory() const { return getScope().getDirectory(); } 793 bool Verify() const; 794 }; 795 796 class DIObjCProperty : public DIDescriptor { 797 public: DIObjCProperty(const MDNode * N)798 explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) { } 799 getObjCPropertyName()800 StringRef getObjCPropertyName() const { return getStringField(1); } getFile()801 DIFile getFile() const { return getFieldAs<DIFile>(2); } getLineNumber()802 unsigned getLineNumber() const { return getUnsignedField(3); } 803 getObjCPropertyGetterName()804 StringRef getObjCPropertyGetterName() const { 805 return getStringField(4); 806 } getObjCPropertySetterName()807 StringRef getObjCPropertySetterName() const { 808 return getStringField(5); 809 } isReadOnlyObjCProperty()810 bool isReadOnlyObjCProperty() { 811 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; 812 } isReadWriteObjCProperty()813 bool isReadWriteObjCProperty() { 814 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; 815 } isAssignObjCProperty()816 bool isAssignObjCProperty() { 817 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0; 818 } isRetainObjCProperty()819 bool isRetainObjCProperty() { 820 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0; 821 } isCopyObjCProperty()822 bool isCopyObjCProperty() { 823 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0; 824 } isNonAtomicObjCProperty()825 bool isNonAtomicObjCProperty() { 826 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; 827 } 828 getType()829 DIType getType() const { return getFieldAs<DIType>(7); } 830 831 /// Verify - Verify that a derived type descriptor is well formed. 832 bool Verify() const; 833 834 /// print - print derived type. 835 void print(raw_ostream &OS) const; 836 837 /// dump - print derived type to dbgs() with a newline. 838 void dump() const; 839 }; 840 841 /// getDISubprogram - Find subprogram that is enclosing this scope. 842 DISubprogram getDISubprogram(const MDNode *Scope); 843 844 /// getDICompositeType - Find underlying composite type. 845 DICompositeType getDICompositeType(DIType T); 846 847 /// isSubprogramContext - Return true if Context is either a subprogram 848 /// or another context nested inside a subprogram. 849 bool isSubprogramContext(const MDNode *Context); 850 851 /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable 852 /// to hold function specific information. 853 NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP); 854 855 /// getFnSpecificMDNode - Return a NameMDNode, if available, that is 856 /// suitable to hold function specific information. 857 NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP); 858 859 /// createInlinedVariable - Create a new inlined variable based on current 860 /// variable. 861 /// @param DV Current Variable. 862 /// @param InlinedScope Location at current variable is inlined. 863 DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope, 864 LLVMContext &VMContext); 865 866 /// cleanseInlinedVariable - Remove inlined scope from the variable. 867 DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext); 868 869 class DebugInfoFinder { 870 public: 871 /// processModule - Process entire module and collect debug info 872 /// anchors. 873 void processModule(Module &M); 874 875 private: 876 /// processType - Process DIType. 877 void processType(DIType DT); 878 879 /// processLexicalBlock - Process DILexicalBlock. 880 void processLexicalBlock(DILexicalBlock LB); 881 882 /// processSubprogram - Process DISubprogram. 883 void processSubprogram(DISubprogram SP); 884 885 /// processDeclare - Process DbgDeclareInst. 886 void processDeclare(DbgDeclareInst *DDI); 887 888 /// processLocation - Process DILocation. 889 void processLocation(DILocation Loc); 890 891 /// addCompileUnit - Add compile unit into CUs. 892 bool addCompileUnit(DICompileUnit CU); 893 894 /// addGlobalVariable - Add global variable into GVs. 895 bool addGlobalVariable(DIGlobalVariable DIG); 896 897 // addSubprogram - Add subprogram into SPs. 898 bool addSubprogram(DISubprogram SP); 899 900 /// addType - Add type into Tys. 901 bool addType(DIType DT); 902 903 public: 904 typedef SmallVector<MDNode *, 8>::const_iterator iterator; compile_unit_begin()905 iterator compile_unit_begin() const { return CUs.begin(); } compile_unit_end()906 iterator compile_unit_end() const { return CUs.end(); } subprogram_begin()907 iterator subprogram_begin() const { return SPs.begin(); } subprogram_end()908 iterator subprogram_end() const { return SPs.end(); } global_variable_begin()909 iterator global_variable_begin() const { return GVs.begin(); } global_variable_end()910 iterator global_variable_end() const { return GVs.end(); } type_begin()911 iterator type_begin() const { return TYs.begin(); } type_end()912 iterator type_end() const { return TYs.end(); } 913 compile_unit_count()914 unsigned compile_unit_count() const { return CUs.size(); } global_variable_count()915 unsigned global_variable_count() const { return GVs.size(); } subprogram_count()916 unsigned subprogram_count() const { return SPs.size(); } type_count()917 unsigned type_count() const { return TYs.size(); } 918 919 private: 920 SmallVector<MDNode *, 8> CUs; // Compile Units 921 SmallVector<MDNode *, 8> SPs; // Subprograms 922 SmallVector<MDNode *, 8> GVs; // Global Variables; 923 SmallVector<MDNode *, 8> TYs; // Types 924 SmallPtrSet<MDNode *, 64> NodesSeen; 925 }; 926 } // end namespace llvm 927 928 #endif 929