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