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