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_DEBUGINFO_H 18 #define LLVM_DEBUGINFO_H 19 20 #include "llvm/ADT/SmallPtrSet.h" 21 #include "llvm/ADT/SmallVector.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 DbgValueInst; 35 class Instruction; 36 class MDNode; 37 class NamedMDNode; 38 class LLVMContext; 39 class raw_ostream; 40 41 class DIFile; 42 class DISubprogram; 43 class DILexicalBlock; 44 class DILexicalBlockFile; 45 class DIVariable; 46 class DIType; 47 class DIObjCProperty; 48 49 /// DIDescriptor - A thin wraper around MDNode to access encoded debug info. 50 /// This should not be stored in a container, because the underlying MDNode 51 /// may change in certain situations. 52 class DIDescriptor { 53 public: 54 enum { 55 FlagPrivate = 1 << 0, 56 FlagProtected = 1 << 1, 57 FlagFwdDecl = 1 << 2, 58 FlagAppleBlock = 1 << 3, 59 FlagBlockByrefStruct = 1 << 4, 60 FlagVirtual = 1 << 5, 61 FlagArtificial = 1 << 6, 62 FlagExplicit = 1 << 7, 63 FlagPrototyped = 1 << 8, 64 FlagObjcClassComplete = 1 << 9, 65 FlagObjectPointer = 1 << 10, 66 FlagVector = 1 << 11, 67 FlagStaticMember = 1 << 12, 68 FlagIndirectVariable = 1 << 13 69 }; 70 protected: 71 const MDNode *DbgNode; 72 73 StringRef getStringField(unsigned Elt) const; getUnsignedField(unsigned Elt)74 unsigned getUnsignedField(unsigned Elt) const { 75 return (unsigned)getUInt64Field(Elt); 76 } 77 uint64_t getUInt64Field(unsigned Elt) const; 78 int64_t getInt64Field(unsigned Elt) const; 79 DIDescriptor getDescriptorField(unsigned Elt) const; 80 81 template <typename DescTy> getFieldAs(unsigned Elt)82 DescTy getFieldAs(unsigned Elt) const { 83 return DescTy(getDescriptorField(Elt)); 84 } 85 86 GlobalVariable *getGlobalVariableField(unsigned Elt) const; 87 Constant *getConstantField(unsigned Elt) const; 88 Function *getFunctionField(unsigned Elt) const; 89 void replaceFunctionField(unsigned Elt, Function *F); 90 91 public: DbgNode(N)92 explicit DIDescriptor(const MDNode *N = 0) : DbgNode(N) {} 93 94 bool Verify() const; 95 96 operator MDNode *() const { return const_cast<MDNode*>(DbgNode); } 97 MDNode *operator ->() const { return const_cast<MDNode*>(DbgNode); } 98 99 // An explicit operator bool so that we can do testing of DI values 100 // easily. 101 // FIXME: This operator bool isn't actually protecting anything at the 102 // moment due to the conversion operator above making DIDescriptor nodes 103 // implicitly convertable to bool. 104 LLVM_EXPLICIT operator bool() const { return DbgNode != 0; } 105 106 bool operator==(DIDescriptor Other) const { 107 return DbgNode == Other.DbgNode; 108 } 109 bool operator!=(DIDescriptor Other) const { 110 return !operator==(Other); 111 } 112 getTag()113 unsigned getTag() const { 114 return getUnsignedField(0) & ~LLVMDebugVersionMask; 115 } 116 117 bool isDerivedType() const; 118 bool isCompositeType() const; 119 bool isBasicType() const; 120 bool isVariable() const; 121 bool isSubprogram() const; 122 bool isGlobalVariable() const; 123 bool isScope() const; 124 bool isFile() const; 125 bool isCompileUnit() const; 126 bool isNameSpace() const; 127 bool isLexicalBlockFile() const; 128 bool isLexicalBlock() const; 129 bool isSubrange() const; 130 bool isEnumerator() const; 131 bool isType() const; 132 bool isUnspecifiedParameter() const; 133 bool isTemplateTypeParameter() const; 134 bool isTemplateValueParameter() const; 135 bool isObjCProperty() const; 136 bool isImportedEntity() const; 137 138 /// print - print descriptor. 139 void print(raw_ostream &OS) const; 140 141 /// dump - print descriptor to dbgs() with a newline. 142 void dump() const; 143 }; 144 145 /// DISubrange - This is used to represent ranges, for array bounds. 146 class DISubrange : public DIDescriptor { 147 friend class DIDescriptor; 148 void printInternal(raw_ostream &OS) const; 149 public: DIDescriptor(N)150 explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {} 151 getLo()152 int64_t getLo() const { return getInt64Field(1); } getCount()153 int64_t getCount() const { return getInt64Field(2); } 154 bool Verify() const; 155 }; 156 157 /// DIArray - This descriptor holds an array of descriptors. 158 class DIArray : public DIDescriptor { 159 public: DIDescriptor(N)160 explicit DIArray(const MDNode *N = 0) : DIDescriptor(N) {} 161 162 unsigned getNumElements() const; getElement(unsigned Idx)163 DIDescriptor getElement(unsigned Idx) const { 164 return getDescriptorField(Idx); 165 } 166 }; 167 168 /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). 169 /// FIXME: it seems strange that this doesn't have either a reference to the 170 /// type/precision or a file/line pair for location info. 171 class DIEnumerator : public DIDescriptor { 172 friend class DIDescriptor; 173 void printInternal(raw_ostream &OS) const; 174 public: DIDescriptor(N)175 explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {} 176 getName()177 StringRef getName() const { return getStringField(1); } getEnumValue()178 int64_t getEnumValue() const { return getInt64Field(2); } 179 bool Verify() const; 180 }; 181 182 /// DIScope - A base class for various scopes. 183 class DIScope : public DIDescriptor { 184 protected: 185 friend class DIDescriptor; 186 void printInternal(raw_ostream &OS) const; 187 public: DIDescriptor(N)188 explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {} 189 190 /// Gets the parent scope for this scope node or returns a 191 /// default constructed scope. 192 DIScope getContext() const; 193 StringRef getFilename() const; 194 StringRef getDirectory() const; 195 }; 196 197 /// DIType - This is a wrapper for a type. 198 /// FIXME: Types should be factored much better so that CV qualifiers and 199 /// others do not require a huge and empty descriptor full of zeros. 200 class DIType : public DIScope { 201 protected: 202 friend class DIDescriptor; 203 void printInternal(raw_ostream &OS) const; 204 205 public: DIScope(N)206 DIType(const MDNode *N = 0) : DIScope(N) {} 207 208 /// Verify - Verify that a type descriptor is well formed. 209 bool Verify() const; 210 getContext()211 DIScope getContext() const { return getFieldAs<DIScope>(2); } getName()212 StringRef getName() const { return getStringField(3); } getLineNumber()213 unsigned getLineNumber() const { return getUnsignedField(4); } getSizeInBits()214 uint64_t getSizeInBits() const { return getUInt64Field(5); } getAlignInBits()215 uint64_t getAlignInBits() const { return getUInt64Field(6); } 216 // FIXME: Offset is only used for DW_TAG_member nodes. Making every type 217 // carry this is just plain insane. getOffsetInBits()218 uint64_t getOffsetInBits() const { return getUInt64Field(7); } getFlags()219 unsigned getFlags() const { return getUnsignedField(8); } isPrivate()220 bool isPrivate() const { 221 return (getFlags() & FlagPrivate) != 0; 222 } isProtected()223 bool isProtected() const { 224 return (getFlags() & FlagProtected) != 0; 225 } isForwardDecl()226 bool isForwardDecl() const { 227 return (getFlags() & FlagFwdDecl) != 0; 228 } 229 // isAppleBlock - Return true if this is the Apple Blocks extension. isAppleBlockExtension()230 bool isAppleBlockExtension() const { 231 return (getFlags() & FlagAppleBlock) != 0; 232 } isBlockByrefStruct()233 bool isBlockByrefStruct() const { 234 return (getFlags() & FlagBlockByrefStruct) != 0; 235 } isVirtual()236 bool isVirtual() const { 237 return (getFlags() & FlagVirtual) != 0; 238 } isArtificial()239 bool isArtificial() const { 240 return (getFlags() & FlagArtificial) != 0; 241 } isObjectPointer()242 bool isObjectPointer() const { 243 return (getFlags() & FlagObjectPointer) != 0; 244 } isObjcClassComplete()245 bool isObjcClassComplete() const { 246 return (getFlags() & FlagObjcClassComplete) != 0; 247 } isVector()248 bool isVector() const { 249 return (getFlags() & FlagVector) != 0; 250 } isStaticMember()251 bool isStaticMember() const { 252 return (getFlags() & FlagStaticMember) != 0; 253 } isValid()254 bool isValid() const { 255 return DbgNode && isType(); 256 } 257 258 /// isUnsignedDIType - Return true if type encoding is unsigned. 259 bool isUnsignedDIType(); 260 261 /// replaceAllUsesWith - Replace all uses of debug info referenced by 262 /// this descriptor. 263 void replaceAllUsesWith(DIDescriptor &D); 264 void replaceAllUsesWith(MDNode *D); 265 }; 266 267 /// DIBasicType - A basic type, like 'int' or 'float'. 268 class DIBasicType : public DIType { 269 public: DIType(N)270 explicit DIBasicType(const MDNode *N = 0) : DIType(N) {} 271 getEncoding()272 unsigned getEncoding() const { return getUnsignedField(9); } 273 274 /// Verify - Verify that a basic type descriptor is well formed. 275 bool Verify() const; 276 }; 277 278 /// DIDerivedType - A simple derived type, like a const qualified type, 279 /// a typedef, a pointer or reference, et cetera. Or, a data member of 280 /// a class/struct/union. 281 class DIDerivedType : public DIType { 282 friend class DIDescriptor; 283 void printInternal(raw_ostream &OS) const; 284 285 public: DIType(N)286 explicit DIDerivedType(const MDNode *N = 0) : DIType(N) {} 287 getTypeDerivedFrom()288 DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); } 289 290 /// getOriginalTypeSize - If this type is derived from a base type then 291 /// return base type size. 292 uint64_t getOriginalTypeSize() const; 293 294 /// getObjCProperty - Return property node, if this ivar is 295 /// associated with one. 296 MDNode *getObjCProperty() const; 297 getClassType()298 DIType getClassType() const { 299 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); 300 return getFieldAs<DIType>(10); 301 } 302 getConstant()303 Constant *getConstant() const { 304 assert((getTag() == dwarf::DW_TAG_member) && isStaticMember()); 305 return getConstantField(10); 306 } 307 308 /// Verify - Verify that a derived type descriptor is well formed. 309 bool Verify() const; 310 }; 311 312 /// DICompositeType - This descriptor holds a type that can refer to multiple 313 /// other types, like a function or struct. 314 /// DICompositeType is derived from DIDerivedType because some 315 /// composite types (such as enums) can be derived from basic types 316 // FIXME: Make this derive from DIType directly & just store the 317 // base type in a single DIType field. 318 class DICompositeType : public DIDerivedType { 319 friend class DIDescriptor; 320 void printInternal(raw_ostream &OS) const; 321 public: DIDerivedType(N)322 explicit DICompositeType(const MDNode *N = 0) : DIDerivedType(N) {} 323 getTypeArray()324 DIArray getTypeArray() const { return getFieldAs<DIArray>(10); } 325 void setTypeArray(DIArray Elements, DIArray TParams = DIArray()); getRunTimeLang()326 unsigned getRunTimeLang() const { return getUnsignedField(11); } getContainingType()327 DICompositeType getContainingType() const { 328 return getFieldAs<DICompositeType>(12); 329 } 330 void setContainingType(DICompositeType ContainingType); getTemplateParams()331 DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); } 332 333 /// Verify - Verify that a composite type descriptor is well formed. 334 bool Verify() const; 335 }; 336 337 /// DIFile - This is a wrapper for a file. 338 class DIFile : public DIScope { 339 friend class DIDescriptor; 340 public: DIScope(N)341 explicit DIFile(const MDNode *N = 0) : DIScope(N) {} 342 MDNode *getFileNode() const; 343 bool Verify() const; 344 }; 345 346 /// DICompileUnit - A wrapper for a compile unit. 347 class DICompileUnit : public DIScope { 348 friend class DIDescriptor; 349 void printInternal(raw_ostream &OS) const; 350 public: DIScope(N)351 explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {} 352 getLanguage()353 unsigned getLanguage() const { return getUnsignedField(2); } getProducer()354 StringRef getProducer() const { return getStringField(3); } 355 isOptimized()356 bool isOptimized() const { return getUnsignedField(4) != 0; } getFlags()357 StringRef getFlags() const { return getStringField(5); } getRunTimeVersion()358 unsigned getRunTimeVersion() const { return getUnsignedField(6); } 359 360 DIArray getEnumTypes() const; 361 DIArray getRetainedTypes() const; 362 DIArray getSubprograms() const; 363 DIArray getGlobalVariables() const; 364 DIArray getImportedEntities() const; 365 getSplitDebugFilename()366 StringRef getSplitDebugFilename() const { return getStringField(12); } 367 368 /// Verify - Verify that a compile unit is well formed. 369 bool Verify() const; 370 }; 371 372 /// DISubprogram - This is a wrapper for a subprogram (e.g. a function). 373 class DISubprogram : public DIScope { 374 friend class DIDescriptor; 375 void printInternal(raw_ostream &OS) const; 376 public: DIScope(N)377 explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {} 378 getContext()379 DIScope getContext() const { return getFieldAs<DIScope>(2); } getName()380 StringRef getName() const { return getStringField(3); } getDisplayName()381 StringRef getDisplayName() const { return getStringField(4); } getLinkageName()382 StringRef getLinkageName() const { return getStringField(5); } getLineNumber()383 unsigned getLineNumber() const { return getUnsignedField(6); } getType()384 DICompositeType getType() const { return getFieldAs<DICompositeType>(7); } 385 386 /// isLocalToUnit - Return true if this subprogram is local to the current 387 /// compile unit, like 'static' in C. isLocalToUnit()388 unsigned isLocalToUnit() const { return getUnsignedField(8); } isDefinition()389 unsigned isDefinition() const { return getUnsignedField(9); } 390 getVirtuality()391 unsigned getVirtuality() const { return getUnsignedField(10); } getVirtualIndex()392 unsigned getVirtualIndex() const { return getUnsignedField(11); } 393 getContainingType()394 DICompositeType getContainingType() const { 395 return getFieldAs<DICompositeType>(12); 396 } 397 getFlags()398 unsigned getFlags() const { 399 return getUnsignedField(13); 400 } 401 isArtificial()402 unsigned isArtificial() const { 403 return (getUnsignedField(13) & FlagArtificial) != 0; 404 } 405 /// isPrivate - Return true if this subprogram has "private" 406 /// access specifier. isPrivate()407 bool isPrivate() const { 408 return (getUnsignedField(13) & FlagPrivate) != 0; 409 } 410 /// isProtected - Return true if this subprogram has "protected" 411 /// access specifier. isProtected()412 bool isProtected() const { 413 return (getUnsignedField(13) & FlagProtected) != 0; 414 } 415 /// isExplicit - Return true if this subprogram is marked as explicit. isExplicit()416 bool isExplicit() const { 417 return (getUnsignedField(13) & FlagExplicit) != 0; 418 } 419 /// isPrototyped - Return true if this subprogram is prototyped. isPrototyped()420 bool isPrototyped() const { 421 return (getUnsignedField(13) & FlagPrototyped) != 0; 422 } 423 424 unsigned isOptimized() const; 425 426 /// Verify - Verify that a subprogram descriptor is well formed. 427 bool Verify() const; 428 429 /// describes - Return true if this subprogram provides debugging 430 /// information for the function F. 431 bool describes(const Function *F); 432 getFunction()433 Function *getFunction() const { return getFunctionField(15); } replaceFunction(Function * F)434 void replaceFunction(Function *F) { replaceFunctionField(15, F); } getTemplateParams()435 DIArray getTemplateParams() const { return getFieldAs<DIArray>(16); } getFunctionDeclaration()436 DISubprogram getFunctionDeclaration() const { 437 return getFieldAs<DISubprogram>(17); 438 } 439 MDNode *getVariablesNodes() const; 440 DIArray getVariables() const; 441 442 /// getScopeLineNumber - Get the beginning of the scope of the 443 /// function, not necessarily where the name of the program 444 /// starts. getScopeLineNumber()445 unsigned getScopeLineNumber() const { return getUnsignedField(19); } 446 }; 447 448 /// DILexicalBlock - This is a wrapper for a lexical block. 449 class DILexicalBlock : public DIScope { 450 public: DIScope(N)451 explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {} getContext()452 DIScope getContext() const { return getFieldAs<DIScope>(2); } getLineNumber()453 unsigned getLineNumber() const { return getUnsignedField(3); } getColumnNumber()454 unsigned getColumnNumber() const { return getUnsignedField(4); } 455 bool Verify() const; 456 }; 457 458 /// DILexicalBlockFile - This is a wrapper for a lexical block with 459 /// a filename change. 460 class DILexicalBlockFile : public DIScope { 461 public: DIScope(N)462 explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {} getContext()463 DIScope getContext() const { 464 if (getScope().isSubprogram()) 465 return getScope(); 466 return getScope().getContext(); 467 } getLineNumber()468 unsigned getLineNumber() const { return getScope().getLineNumber(); } getColumnNumber()469 unsigned getColumnNumber() const { return getScope().getColumnNumber(); } getScope()470 DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); } 471 bool Verify() const; 472 }; 473 474 /// DINameSpace - A wrapper for a C++ style name space. 475 class DINameSpace : public DIScope { 476 friend class DIDescriptor; 477 void printInternal(raw_ostream &OS) const; 478 public: DIScope(N)479 explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {} getContext()480 DIScope getContext() const { return getFieldAs<DIScope>(2); } getName()481 StringRef getName() const { return getStringField(3); } getLineNumber()482 unsigned getLineNumber() const { return getUnsignedField(4); } 483 bool Verify() const; 484 }; 485 486 /// DITemplateTypeParameter - This is a wrapper for template type parameter. 487 class DITemplateTypeParameter : public DIDescriptor { 488 public: DIDescriptor(N)489 explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {} 490 getContext()491 DIScope getContext() const { return getFieldAs<DIScope>(1); } getName()492 StringRef getName() const { return getStringField(2); } getType()493 DIType getType() const { return getFieldAs<DIType>(3); } getFilename()494 StringRef getFilename() const { 495 return getFieldAs<DIFile>(4).getFilename(); 496 } getDirectory()497 StringRef getDirectory() const { 498 return getFieldAs<DIFile>(4).getDirectory(); 499 } getLineNumber()500 unsigned getLineNumber() const { return getUnsignedField(5); } getColumnNumber()501 unsigned getColumnNumber() const { return getUnsignedField(6); } 502 bool Verify() const; 503 }; 504 505 /// DITemplateValueParameter - This is a wrapper for template value parameter. 506 class DITemplateValueParameter : public DIDescriptor { 507 public: DIDescriptor(N)508 explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {} 509 getContext()510 DIScope getContext() const { return getFieldAs<DIScope>(1); } getName()511 StringRef getName() const { return getStringField(2); } getType()512 DIType getType() const { return getFieldAs<DIType>(3); } 513 Value *getValue() const; getFilename()514 StringRef getFilename() const { 515 return getFieldAs<DIFile>(5).getFilename(); 516 } getDirectory()517 StringRef getDirectory() const { 518 return getFieldAs<DIFile>(5).getDirectory(); 519 } getLineNumber()520 unsigned getLineNumber() const { return getUnsignedField(6); } getColumnNumber()521 unsigned getColumnNumber() const { return getUnsignedField(7); } 522 bool Verify() const; 523 }; 524 525 /// DIGlobalVariable - This is a wrapper for a global variable. 526 class DIGlobalVariable : public DIDescriptor { 527 friend class DIDescriptor; 528 void printInternal(raw_ostream &OS) const; 529 public: DIDescriptor(N)530 explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {} 531 getContext()532 DIScope getContext() const { return getFieldAs<DIScope>(2); } getName()533 StringRef getName() const { return getStringField(3); } getDisplayName()534 StringRef getDisplayName() const { return getStringField(4); } getLinkageName()535 StringRef getLinkageName() const { return getStringField(5); } getFilename()536 StringRef getFilename() const { 537 return getFieldAs<DIFile>(6).getFilename(); 538 } getDirectory()539 StringRef getDirectory() const { 540 return getFieldAs<DIFile>(6).getDirectory(); 541 542 } 543 getLineNumber()544 unsigned getLineNumber() const { return getUnsignedField(7); } getType()545 DIType getType() const { return getFieldAs<DIType>(8); } isLocalToUnit()546 unsigned isLocalToUnit() const { return getUnsignedField(9); } isDefinition()547 unsigned isDefinition() const { return getUnsignedField(10); } 548 getGlobal()549 GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } getConstant()550 Constant *getConstant() const { return getConstantField(11); } getStaticDataMemberDeclaration()551 DIDerivedType getStaticDataMemberDeclaration() const { 552 return getFieldAs<DIDerivedType>(12); 553 } 554 555 /// Verify - Verify that a global variable descriptor is well formed. 556 bool Verify() const; 557 }; 558 559 /// DIVariable - This is a wrapper for a variable (e.g. parameter, local, 560 /// global etc). 561 class DIVariable : public DIDescriptor { 562 friend class DIDescriptor; 563 void printInternal(raw_ostream &OS) const; 564 public: DIDescriptor(N)565 explicit DIVariable(const MDNode *N = 0) : DIDescriptor(N) {} 566 getContext()567 DIScope getContext() const { return getFieldAs<DIScope>(1); } getName()568 StringRef getName() const { return getStringField(2); } getFile()569 DIFile getFile() const { return getFieldAs<DIFile>(3); } getLineNumber()570 unsigned getLineNumber() const { 571 return (getUnsignedField(4) << 8) >> 8; 572 } getArgNumber()573 unsigned getArgNumber() const { 574 unsigned L = getUnsignedField(4); 575 return L >> 24; 576 } getType()577 DIType getType() const { return getFieldAs<DIType>(5); } 578 579 /// isArtificial - Return true if this variable is marked as "artificial". isArtificial()580 bool isArtificial() const { 581 return (getUnsignedField(6) & FlagArtificial) != 0; 582 } 583 isObjectPointer()584 bool isObjectPointer() const { 585 return (getUnsignedField(6) & FlagObjectPointer) != 0; 586 } 587 588 /// \brief Return true if this variable is represented as a pointer. isIndirect()589 bool isIndirect() const { 590 return (getUnsignedField(6) & FlagIndirectVariable) != 0; 591 } 592 593 /// getInlinedAt - If this variable is inlined then return inline location. 594 MDNode *getInlinedAt() const; 595 596 /// Verify - Verify that a variable descriptor is well formed. 597 bool Verify() const; 598 599 /// HasComplexAddr - Return true if the variable has a complex address. hasComplexAddress()600 bool hasComplexAddress() const { 601 return getNumAddrElements() > 0; 602 } 603 604 unsigned getNumAddrElements() const; 605 getAddrElement(unsigned Idx)606 uint64_t getAddrElement(unsigned Idx) const { 607 return getUInt64Field(Idx+8); 608 } 609 610 /// isBlockByrefVariable - Return true if the variable was declared as 611 /// a "__block" variable (Apple Blocks). isBlockByrefVariable()612 bool isBlockByrefVariable() const { 613 return getType().isBlockByrefStruct(); 614 } 615 616 /// isInlinedFnArgument - Return true if this variable provides debugging 617 /// information for an inlined function arguments. 618 bool isInlinedFnArgument(const Function *CurFn); 619 620 void printExtendedName(raw_ostream &OS) const; 621 }; 622 623 /// DILocation - This object holds location information. This object 624 /// is not associated with any DWARF tag. 625 class DILocation : public DIDescriptor { 626 public: DILocation(const MDNode * N)627 explicit DILocation(const MDNode *N) : DIDescriptor(N) { } 628 getLineNumber()629 unsigned getLineNumber() const { return getUnsignedField(0); } getColumnNumber()630 unsigned getColumnNumber() const { return getUnsignedField(1); } getScope()631 DIScope getScope() const { return getFieldAs<DIScope>(2); } getOrigLocation()632 DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); } getFilename()633 StringRef getFilename() const { return getScope().getFilename(); } getDirectory()634 StringRef getDirectory() const { return getScope().getDirectory(); } 635 bool Verify() const; 636 }; 637 638 class DIObjCProperty : public DIDescriptor { 639 friend class DIDescriptor; 640 void printInternal(raw_ostream &OS) const; 641 public: DIObjCProperty(const MDNode * N)642 explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) { } 643 getObjCPropertyName()644 StringRef getObjCPropertyName() const { return getStringField(1); } getFile()645 DIFile getFile() const { return getFieldAs<DIFile>(2); } getLineNumber()646 unsigned getLineNumber() const { return getUnsignedField(3); } 647 getObjCPropertyGetterName()648 StringRef getObjCPropertyGetterName() const { 649 return getStringField(4); 650 } getObjCPropertySetterName()651 StringRef getObjCPropertySetterName() const { 652 return getStringField(5); 653 } isReadOnlyObjCProperty()654 bool isReadOnlyObjCProperty() const { 655 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; 656 } isReadWriteObjCProperty()657 bool isReadWriteObjCProperty() const { 658 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; 659 } isAssignObjCProperty()660 bool isAssignObjCProperty() const { 661 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0; 662 } isRetainObjCProperty()663 bool isRetainObjCProperty() const { 664 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0; 665 } isCopyObjCProperty()666 bool isCopyObjCProperty() const { 667 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0; 668 } isNonAtomicObjCProperty()669 bool isNonAtomicObjCProperty() const { 670 return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; 671 } 672 getType()673 DIType getType() const { return getFieldAs<DIType>(7); } 674 675 /// Verify - Verify that a derived type descriptor is well formed. 676 bool Verify() const; 677 }; 678 679 /// \brief An imported module (C++ using directive or similar). 680 class DIImportedEntity : public DIDescriptor { 681 friend class DIDescriptor; 682 void printInternal(raw_ostream &OS) const; 683 public: DIImportedEntity(const MDNode * N)684 explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) { } getContext()685 DIScope getContext() const { return getFieldAs<DIScope>(1); } getEntity()686 DIDescriptor getEntity() const { return getFieldAs<DIDescriptor>(2); } getLineNumber()687 unsigned getLineNumber() const { return getUnsignedField(3); } getName()688 StringRef getName() const { return getStringField(4); } 689 bool Verify() const; 690 }; 691 692 /// getDISubprogram - Find subprogram that is enclosing this scope. 693 DISubprogram getDISubprogram(const MDNode *Scope); 694 695 /// getDICompositeType - Find underlying composite type. 696 DICompositeType getDICompositeType(DIType T); 697 698 /// isSubprogramContext - Return true if Context is either a subprogram 699 /// or another context nested inside a subprogram. 700 bool isSubprogramContext(const MDNode *Context); 701 702 /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable 703 /// to hold function specific information. 704 NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP); 705 706 /// getFnSpecificMDNode - Return a NameMDNode, if available, that is 707 /// suitable to hold function specific information. 708 NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP); 709 710 /// createInlinedVariable - Create a new inlined variable based on current 711 /// variable. 712 /// @param DV Current Variable. 713 /// @param InlinedScope Location at current variable is inlined. 714 DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope, 715 LLVMContext &VMContext); 716 717 /// cleanseInlinedVariable - Remove inlined scope from the variable. 718 DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext); 719 720 /// DebugInfoFinder tries to list all debug info MDNodes used in a module. To 721 /// list debug info MDNodes used by an instruction, DebugInfoFinder uses 722 /// processDeclare, processValue and processLocation to handle DbgDeclareInst, 723 /// DbgValueInst and DbgLoc attached to instructions. processModule will go 724 /// through all DICompileUnits in llvm.dbg.cu and list debug info MDNodes 725 /// used by the CUs. 726 class DebugInfoFinder { 727 public: 728 /// processModule - Process entire module and collect debug info 729 /// anchors. 730 void processModule(const Module &M); 731 732 /// processDeclare - Process DbgDeclareInst. 733 void processDeclare(const DbgDeclareInst *DDI); 734 /// Process DbgValueInst. 735 void processValue(const DbgValueInst *DVI); 736 /// processLocation - Process DILocation. 737 void processLocation(DILocation Loc); 738 739 /// Clear all lists. 740 void reset(); 741 private: 742 /// processType - Process DIType. 743 void processType(DIType DT); 744 745 /// processLexicalBlock - Process DILexicalBlock. 746 void processLexicalBlock(DILexicalBlock LB); 747 748 /// processSubprogram - Process DISubprogram. 749 void processSubprogram(DISubprogram SP); 750 751 void processScope(DIScope Scope); 752 753 /// addCompileUnit - Add compile unit into CUs. 754 bool addCompileUnit(DICompileUnit CU); 755 756 /// addGlobalVariable - Add global variable into GVs. 757 bool addGlobalVariable(DIGlobalVariable DIG); 758 759 // addSubprogram - Add subprogram into SPs. 760 bool addSubprogram(DISubprogram SP); 761 762 /// addType - Add type into Tys. 763 bool addType(DIType DT); 764 765 bool addScope(DIScope Scope); 766 767 public: 768 typedef SmallVectorImpl<MDNode *>::const_iterator iterator; compile_unit_begin()769 iterator compile_unit_begin() const { return CUs.begin(); } compile_unit_end()770 iterator compile_unit_end() const { return CUs.end(); } subprogram_begin()771 iterator subprogram_begin() const { return SPs.begin(); } subprogram_end()772 iterator subprogram_end() const { return SPs.end(); } global_variable_begin()773 iterator global_variable_begin() const { return GVs.begin(); } global_variable_end()774 iterator global_variable_end() const { return GVs.end(); } type_begin()775 iterator type_begin() const { return TYs.begin(); } type_end()776 iterator type_end() const { return TYs.end(); } scope_begin()777 iterator scope_begin() const { return Scopes.begin(); } scope_end()778 iterator scope_end() const { return Scopes.end(); } 779 compile_unit_count()780 unsigned compile_unit_count() const { return CUs.size(); } global_variable_count()781 unsigned global_variable_count() const { return GVs.size(); } subprogram_count()782 unsigned subprogram_count() const { return SPs.size(); } type_count()783 unsigned type_count() const { return TYs.size(); } scope_count()784 unsigned scope_count() const { return Scopes.size(); } 785 786 private: 787 SmallVector<MDNode *, 8> CUs; // Compile Units 788 SmallVector<MDNode *, 8> SPs; // Subprograms 789 SmallVector<MDNode *, 8> GVs; // Global Variables; 790 SmallVector<MDNode *, 8> TYs; // Types 791 SmallVector<MDNode *, 8> Scopes; // Scopes 792 SmallPtrSet<MDNode *, 64> NodesSeen; 793 }; 794 } // end namespace llvm 795 796 #endif 797