1239310Sdim//===--- llvm/Analysis/DebugInfo.h - Debug Information Helpers --*- C++ -*-===// 2239310Sdim// 3239310Sdim// The LLVM Compiler Infrastructure 4239310Sdim// 5239310Sdim// This file is distributed under the University of Illinois Open Source 6239310Sdim// License. See LICENSE.TXT for details. 7239310Sdim// 8239310Sdim//===----------------------------------------------------------------------===// 9239310Sdim// 10239310Sdim// This file defines a bunch of datatypes that are useful for creating and 11239310Sdim// walking debug info in LLVM IR form. They essentially provide wrappers around 12239310Sdim// the information in the global variables that's needed when constructing the 13239310Sdim// DWARF information. 14239310Sdim// 15239310Sdim//===----------------------------------------------------------------------===// 16239310Sdim 17252723Sdim#ifndef LLVM_DEBUGINFO_H 18252723Sdim#define LLVM_DEBUGINFO_H 19239310Sdim 20263509Sdim#include "llvm/Support/Casting.h" 21263509Sdim#include "llvm/ADT/DenseMap.h" 22252723Sdim#include "llvm/ADT/SmallPtrSet.h" 23239310Sdim#include "llvm/ADT/SmallVector.h" 24239310Sdim#include "llvm/ADT/StringRef.h" 25263509Sdim#include "llvm/IR/Metadata.h" 26239310Sdim#include "llvm/Support/Dwarf.h" 27239310Sdim 28239310Sdimnamespace llvm { 29263509Sdimclass BasicBlock; 30263509Sdimclass Constant; 31263509Sdimclass Function; 32263509Sdimclass GlobalVariable; 33263509Sdimclass Module; 34263509Sdimclass Type; 35263509Sdimclass Value; 36263509Sdimclass DbgDeclareInst; 37263509Sdimclass DbgValueInst; 38263509Sdimclass Instruction; 39263509Sdimclass MDNode; 40263509Sdimclass MDString; 41263509Sdimclass NamedMDNode; 42263509Sdimclass LLVMContext; 43263509Sdimclass raw_ostream; 44239310Sdim 45263509Sdimclass DIFile; 46263509Sdimclass DISubprogram; 47263509Sdimclass DILexicalBlock; 48263509Sdimclass DILexicalBlockFile; 49263509Sdimclass DIVariable; 50263509Sdimclass DIType; 51263509Sdimclass DIScope; 52263509Sdimclass DIObjCProperty; 53239310Sdim 54263509Sdim/// Maps from type identifier to the actual MDNode. 55263509Sdimtypedef DenseMap<const MDString *, MDNode *> DITypeIdentifierMap; 56239310Sdim 57263509Sdim/// DIDescriptor - A thin wraper around MDNode to access encoded debug info. 58263509Sdim/// This should not be stored in a container, because the underlying MDNode 59263509Sdim/// may change in certain situations. 60263509Sdimclass DIDescriptor { 61263509Sdim // Befriends DIRef so DIRef can befriend the protected member 62263509Sdim // function: getFieldAs<DIRef>. 63263509Sdim template <typename T> friend class DIRef; 64239310Sdim 65263509Sdimpublic: 66263509Sdim enum { 67263509Sdim FlagPrivate = 1 << 0, 68263509Sdim FlagProtected = 1 << 1, 69263509Sdim FlagFwdDecl = 1 << 2, 70263509Sdim FlagAppleBlock = 1 << 3, 71263509Sdim FlagBlockByrefStruct = 1 << 4, 72263509Sdim FlagVirtual = 1 << 5, 73263509Sdim FlagArtificial = 1 << 6, 74263509Sdim FlagExplicit = 1 << 7, 75263509Sdim FlagPrototyped = 1 << 8, 76263509Sdim FlagObjcClassComplete = 1 << 9, 77263509Sdim FlagObjectPointer = 1 << 10, 78263509Sdim FlagVector = 1 << 11, 79263509Sdim FlagStaticMember = 1 << 12, 80263509Sdim FlagIndirectVariable = 1 << 13 81263509Sdim }; 82239310Sdim 83263509Sdimprotected: 84263509Sdim const MDNode *DbgNode; 85239310Sdim 86263509Sdim StringRef getStringField(unsigned Elt) const; 87263509Sdim unsigned getUnsignedField(unsigned Elt) const { 88263509Sdim return (unsigned)getUInt64Field(Elt); 89263509Sdim } 90263509Sdim uint64_t getUInt64Field(unsigned Elt) const; 91263509Sdim int64_t getInt64Field(unsigned Elt) const; 92263509Sdim DIDescriptor getDescriptorField(unsigned Elt) const; 93239310Sdim 94263509Sdim template <typename DescTy> DescTy getFieldAs(unsigned Elt) const { 95263509Sdim return DescTy(getDescriptorField(Elt)); 96263509Sdim } 97239310Sdim 98263509Sdim GlobalVariable *getGlobalVariableField(unsigned Elt) const; 99263509Sdim Constant *getConstantField(unsigned Elt) const; 100263509Sdim Function *getFunctionField(unsigned Elt) const; 101263509Sdim void replaceFunctionField(unsigned Elt, Function *F); 102239310Sdim 103263509Sdimpublic: 104263509Sdim explicit DIDescriptor(const MDNode *N = 0) : DbgNode(N) {} 105239310Sdim 106263509Sdim bool Verify() const; 107239310Sdim 108263509Sdim operator MDNode *() const { return const_cast<MDNode *>(DbgNode); } 109263509Sdim MDNode *operator->() const { return const_cast<MDNode *>(DbgNode); } 110239310Sdim 111263509Sdim // An explicit operator bool so that we can do testing of DI values 112263509Sdim // easily. 113263509Sdim // FIXME: This operator bool isn't actually protecting anything at the 114263509Sdim // moment due to the conversion operator above making DIDescriptor nodes 115263509Sdim // implicitly convertable to bool. 116263509Sdim LLVM_EXPLICIT operator bool() const { return DbgNode != 0; } 117239310Sdim 118263509Sdim bool operator==(DIDescriptor Other) const { return DbgNode == Other.DbgNode; } 119263509Sdim bool operator!=(DIDescriptor Other) const { return !operator==(Other); } 120239310Sdim 121263509Sdim uint16_t getTag() const { 122263509Sdim return getUnsignedField(0) & ~LLVMDebugVersionMask; 123263509Sdim } 124239310Sdim 125263509Sdim bool isDerivedType() const; 126263509Sdim bool isCompositeType() const; 127263509Sdim bool isBasicType() const; 128263509Sdim bool isVariable() const; 129263509Sdim bool isSubprogram() const; 130263509Sdim bool isGlobalVariable() const; 131263509Sdim bool isScope() const; 132263509Sdim bool isFile() const; 133263509Sdim bool isCompileUnit() const; 134263509Sdim bool isNameSpace() const; 135263509Sdim bool isLexicalBlockFile() const; 136263509Sdim bool isLexicalBlock() const; 137263509Sdim bool isSubrange() const; 138263509Sdim bool isEnumerator() const; 139263509Sdim bool isType() const; 140263509Sdim bool isUnspecifiedParameter() const; 141263509Sdim bool isTemplateTypeParameter() const; 142263509Sdim bool isTemplateValueParameter() const; 143263509Sdim bool isObjCProperty() const; 144263509Sdim bool isImportedEntity() const; 145239310Sdim 146263509Sdim /// print - print descriptor. 147263509Sdim void print(raw_ostream &OS) const; 148239310Sdim 149263509Sdim /// dump - print descriptor to dbgs() with a newline. 150263509Sdim void dump() const; 151263509Sdim}; 152239310Sdim 153263509Sdim/// DISubrange - This is used to represent ranges, for array bounds. 154263509Sdimclass DISubrange : public DIDescriptor { 155263509Sdim friend class DIDescriptor; 156263509Sdim void printInternal(raw_ostream &OS) const; 157239310Sdim 158263509Sdimpublic: 159263509Sdim explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {} 160252723Sdim 161263509Sdim int64_t getLo() const { return getInt64Field(1); } 162263509Sdim int64_t getCount() const { return getInt64Field(2); } 163263509Sdim bool Verify() const; 164263509Sdim}; 165239310Sdim 166263509Sdim/// DIArray - This descriptor holds an array of descriptors. 167263509Sdimclass DIArray : public DIDescriptor { 168263509Sdimpublic: 169263509Sdim explicit DIArray(const MDNode *N = 0) : DIDescriptor(N) {} 170239310Sdim 171263509Sdim unsigned getNumElements() const; 172263509Sdim DIDescriptor getElement(unsigned Idx) const { 173263509Sdim return getDescriptorField(Idx); 174263509Sdim } 175263509Sdim}; 176239310Sdim 177263509Sdim/// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). 178263509Sdim/// FIXME: it seems strange that this doesn't have either a reference to the 179263509Sdim/// type/precision or a file/line pair for location info. 180263509Sdimclass DIEnumerator : public DIDescriptor { 181263509Sdim friend class DIDescriptor; 182263509Sdim void printInternal(raw_ostream &OS) const; 183239310Sdim 184263509Sdimpublic: 185263509Sdim explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {} 186252723Sdim 187263509Sdim StringRef getName() const { return getStringField(1); } 188263509Sdim int64_t getEnumValue() const { return getInt64Field(2); } 189263509Sdim bool Verify() const; 190263509Sdim}; 191239310Sdim 192263509Sdimtemplate <typename T> class DIRef; 193263509Sdimtypedef DIRef<DIScope> DIScopeRef; 194263509Sdimtypedef DIRef<DIType> DITypeRef; 195239310Sdim 196263509Sdim/// DIScope - A base class for various scopes. 197263509Sdimclass DIScope : public DIDescriptor { 198263509Sdimprotected: 199263509Sdim friend class DIDescriptor; 200263509Sdim void printInternal(raw_ostream &OS) const; 201239310Sdim 202263509Sdimpublic: 203263509Sdim explicit DIScope(const MDNode *N = 0) : DIDescriptor(N) {} 204239310Sdim 205263509Sdim /// Gets the parent scope for this scope node or returns a 206263509Sdim /// default constructed scope. 207263509Sdim DIScopeRef getContext() const; 208263509Sdim /// If the scope node has a name, return that, else return an empty string. 209263509Sdim StringRef getName() const; 210263509Sdim StringRef getFilename() const; 211263509Sdim StringRef getDirectory() const; 212239310Sdim 213263509Sdim /// Generate a reference to this DIScope. Uses the type identifier instead 214263509Sdim /// of the actual MDNode if possible, to help type uniquing. 215263509Sdim DIScopeRef getRef() const; 216263509Sdim}; 217239310Sdim 218263509Sdim/// Represents reference to a DIDescriptor, abstracts over direct and 219263509Sdim/// identifier-based metadata references. 220263509Sdimtemplate <typename T> class DIRef { 221263509Sdim template <typename DescTy> 222263509Sdim friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const; 223263509Sdim friend DIScopeRef DIScope::getContext() const; 224263509Sdim friend DIScopeRef DIScope::getRef() const; 225239310Sdim 226263509Sdim /// Val can be either a MDNode or a MDString, in the latter, 227263509Sdim /// MDString specifies the type identifier. 228263509Sdim const Value *Val; 229263509Sdim explicit DIRef(const Value *V); 230239310Sdim 231263509Sdimpublic: 232263509Sdim T resolve(const DITypeIdentifierMap &Map) const; 233263509Sdim StringRef getName() const; 234263509Sdim operator Value *() const { return const_cast<Value *>(Val); } 235263509Sdim}; 236239310Sdim 237263509Sdimtemplate <typename T> 238263509SdimT DIRef<T>::resolve(const DITypeIdentifierMap &Map) const { 239263509Sdim if (!Val) 240263509Sdim return T(); 241239310Sdim 242263509Sdim if (const MDNode *MD = dyn_cast<MDNode>(Val)) 243263509Sdim return T(MD); 244239310Sdim 245263509Sdim const MDString *MS = cast<MDString>(Val); 246263509Sdim // Find the corresponding MDNode. 247263509Sdim DITypeIdentifierMap::const_iterator Iter = Map.find(MS); 248263509Sdim assert(Iter != Map.end() && "Identifier not in the type map?"); 249263509Sdim assert(DIDescriptor(Iter->second).isType() && 250263509Sdim "MDNode in DITypeIdentifierMap should be a DIType."); 251263509Sdim return T(Iter->second); 252263509Sdim} 253239310Sdim 254263509Sdimtemplate <typename T> StringRef DIRef<T>::getName() const { 255263509Sdim if (!Val) 256263509Sdim return StringRef(); 257239310Sdim 258263509Sdim if (const MDNode *MD = dyn_cast<MDNode>(Val)) 259263509Sdim return T(MD).getName(); 260239310Sdim 261263509Sdim const MDString *MS = cast<MDString>(Val); 262263509Sdim return MS->getString(); 263263509Sdim} 264252723Sdim 265263509Sdim/// Specialize getFieldAs to handle fields that are references to DIScopes. 266263509Sdimtemplate <> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const; 267263509Sdim/// Specialize DIRef constructor for DIScopeRef. 268263509Sdimtemplate <> DIRef<DIScope>::DIRef(const Value *V); 269239310Sdim 270263509Sdim/// Specialize getFieldAs to handle fields that are references to DITypes. 271263509Sdimtemplate <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const; 272263509Sdim/// Specialize DIRef constructor for DITypeRef. 273263509Sdimtemplate <> DIRef<DIType>::DIRef(const Value *V); 274239310Sdim 275263509Sdim/// DIType - This is a wrapper for a type. 276263509Sdim/// FIXME: Types should be factored much better so that CV qualifiers and 277263509Sdim/// others do not require a huge and empty descriptor full of zeros. 278263509Sdimclass DIType : public DIScope { 279263509Sdimprotected: 280263509Sdim friend class DIDescriptor; 281263509Sdim void printInternal(raw_ostream &OS) const; 282239310Sdim 283263509Sdimpublic: 284263509Sdim explicit DIType(const MDNode *N = 0) : DIScope(N) {} 285239310Sdim 286263509Sdim /// Verify - Verify that a type descriptor is well formed. 287263509Sdim bool Verify() const; 288239310Sdim 289263509Sdim DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); } 290263509Sdim StringRef getName() const { return getStringField(3); } 291263509Sdim unsigned getLineNumber() const { return getUnsignedField(4); } 292263509Sdim uint64_t getSizeInBits() const { return getUInt64Field(5); } 293263509Sdim uint64_t getAlignInBits() const { return getUInt64Field(6); } 294263509Sdim // FIXME: Offset is only used for DW_TAG_member nodes. Making every type 295263509Sdim // carry this is just plain insane. 296263509Sdim uint64_t getOffsetInBits() const { return getUInt64Field(7); } 297263509Sdim unsigned getFlags() const { return getUnsignedField(8); } 298263509Sdim bool isPrivate() const { return (getFlags() & FlagPrivate) != 0; } 299263509Sdim bool isProtected() const { return (getFlags() & FlagProtected) != 0; } 300263509Sdim bool isForwardDecl() const { return (getFlags() & FlagFwdDecl) != 0; } 301263509Sdim // isAppleBlock - Return true if this is the Apple Blocks extension. 302263509Sdim bool isAppleBlockExtension() const { 303263509Sdim return (getFlags() & FlagAppleBlock) != 0; 304263509Sdim } 305263509Sdim bool isBlockByrefStruct() const { 306263509Sdim return (getFlags() & FlagBlockByrefStruct) != 0; 307263509Sdim } 308263509Sdim bool isVirtual() const { return (getFlags() & FlagVirtual) != 0; } 309263509Sdim bool isArtificial() const { return (getFlags() & FlagArtificial) != 0; } 310263509Sdim bool isObjectPointer() const { return (getFlags() & FlagObjectPointer) != 0; } 311263509Sdim bool isObjcClassComplete() const { 312263509Sdim return (getFlags() & FlagObjcClassComplete) != 0; 313263509Sdim } 314263509Sdim bool isVector() const { return (getFlags() & FlagVector) != 0; } 315263509Sdim bool isStaticMember() const { return (getFlags() & FlagStaticMember) != 0; } 316263509Sdim bool isValid() const { return DbgNode && isType(); } 317239310Sdim 318263509Sdim /// replaceAllUsesWith - Replace all uses of debug info referenced by 319263509Sdim /// this descriptor. 320263509Sdim void replaceAllUsesWith(DIDescriptor &D); 321263509Sdim void replaceAllUsesWith(MDNode *D); 322263509Sdim}; 323239310Sdim 324263509Sdim/// DIBasicType - A basic type, like 'int' or 'float'. 325263509Sdimclass DIBasicType : public DIType { 326263509Sdimpublic: 327263509Sdim explicit DIBasicType(const MDNode *N = 0) : DIType(N) {} 328239310Sdim 329263509Sdim unsigned getEncoding() const { return getUnsignedField(9); } 330239310Sdim 331263509Sdim /// Verify - Verify that a basic type descriptor is well formed. 332263509Sdim bool Verify() const; 333263509Sdim}; 334239310Sdim 335263509Sdim/// DIDerivedType - A simple derived type, like a const qualified type, 336263509Sdim/// a typedef, a pointer or reference, et cetera. Or, a data member of 337263509Sdim/// a class/struct/union. 338263509Sdimclass DIDerivedType : public DIType { 339263509Sdim friend class DIDescriptor; 340263509Sdim void printInternal(raw_ostream &OS) const; 341239310Sdim 342263509Sdimpublic: 343263509Sdim explicit DIDerivedType(const MDNode *N = 0) : DIType(N) {} 344239310Sdim 345263509Sdim DITypeRef getTypeDerivedFrom() const { return getFieldAs<DITypeRef>(9); } 346239310Sdim 347263509Sdim /// getObjCProperty - Return property node, if this ivar is 348263509Sdim /// associated with one. 349263509Sdim MDNode *getObjCProperty() const; 350239310Sdim 351263509Sdim DITypeRef getClassType() const { 352263509Sdim assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); 353263509Sdim return getFieldAs<DITypeRef>(10); 354263509Sdim } 355239310Sdim 356263509Sdim Constant *getConstant() const { 357263509Sdim assert((getTag() == dwarf::DW_TAG_member) && isStaticMember()); 358263509Sdim return getConstantField(10); 359263509Sdim } 360252723Sdim 361263509Sdim /// Verify - Verify that a derived type descriptor is well formed. 362263509Sdim bool Verify() const; 363263509Sdim}; 364239310Sdim 365263509Sdim/// DICompositeType - This descriptor holds a type that can refer to multiple 366263509Sdim/// other types, like a function or struct. 367263509Sdim/// DICompositeType is derived from DIDerivedType because some 368263509Sdim/// composite types (such as enums) can be derived from basic types 369263509Sdim// FIXME: Make this derive from DIType directly & just store the 370263509Sdim// base type in a single DIType field. 371263509Sdimclass DICompositeType : public DIDerivedType { 372263509Sdim friend class DIDescriptor; 373263509Sdim void printInternal(raw_ostream &OS) const; 374239310Sdim 375263509Sdimpublic: 376263509Sdim explicit DICompositeType(const MDNode *N = 0) : DIDerivedType(N) {} 377239310Sdim 378263509Sdim DIArray getTypeArray() const { return getFieldAs<DIArray>(10); } 379263509Sdim void setTypeArray(DIArray Elements, DIArray TParams = DIArray()); 380263509Sdim void addMember(DIDescriptor D); 381263509Sdim unsigned getRunTimeLang() const { return getUnsignedField(11); } 382263509Sdim DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); } 383263509Sdim void setContainingType(DICompositeType ContainingType); 384263509Sdim DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); } 385263509Sdim MDString *getIdentifier() const; 386239310Sdim 387263509Sdim /// Verify - Verify that a composite type descriptor is well formed. 388263509Sdim bool Verify() const; 389263509Sdim}; 390239310Sdim 391263509Sdim/// DIFile - This is a wrapper for a file. 392263509Sdimclass DIFile : public DIScope { 393263509Sdim friend class DIDescriptor; 394239310Sdim 395263509Sdimpublic: 396263509Sdim explicit DIFile(const MDNode *N = 0) : DIScope(N) {} 397263509Sdim MDNode *getFileNode() const; 398263509Sdim bool Verify() const; 399263509Sdim}; 400239310Sdim 401263509Sdim/// DICompileUnit - A wrapper for a compile unit. 402263509Sdimclass DICompileUnit : public DIScope { 403263509Sdim friend class DIDescriptor; 404263509Sdim void printInternal(raw_ostream &OS) const; 405239310Sdim 406263509Sdimpublic: 407263509Sdim explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {} 408239310Sdim 409263509Sdim unsigned getLanguage() const { return getUnsignedField(2); } 410263509Sdim StringRef getProducer() const { return getStringField(3); } 411239310Sdim 412263509Sdim bool isOptimized() const { return getUnsignedField(4) != 0; } 413263509Sdim StringRef getFlags() const { return getStringField(5); } 414263509Sdim unsigned getRunTimeVersion() const { return getUnsignedField(6); } 415239310Sdim 416263509Sdim DIArray getEnumTypes() const; 417263509Sdim DIArray getRetainedTypes() const; 418263509Sdim DIArray getSubprograms() const; 419263509Sdim DIArray getGlobalVariables() const; 420263509Sdim DIArray getImportedEntities() const; 421239310Sdim 422263509Sdim StringRef getSplitDebugFilename() const { return getStringField(12); } 423239310Sdim 424263509Sdim /// Verify - Verify that a compile unit is well formed. 425263509Sdim bool Verify() const; 426263509Sdim}; 427252723Sdim 428263509Sdim/// DISubprogram - This is a wrapper for a subprogram (e.g. a function). 429263509Sdimclass DISubprogram : public DIScope { 430263509Sdim friend class DIDescriptor; 431263509Sdim void printInternal(raw_ostream &OS) const; 432239310Sdim 433263509Sdimpublic: 434263509Sdim explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {} 435245431Sdim 436263509Sdim DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); } 437263509Sdim StringRef getName() const { return getStringField(3); } 438263509Sdim StringRef getDisplayName() const { return getStringField(4); } 439263509Sdim StringRef getLinkageName() const { return getStringField(5); } 440263509Sdim unsigned getLineNumber() const { return getUnsignedField(6); } 441263509Sdim DICompositeType getType() const { return getFieldAs<DICompositeType>(7); } 442239310Sdim 443263509Sdim /// isLocalToUnit - Return true if this subprogram is local to the current 444263509Sdim /// compile unit, like 'static' in C. 445263509Sdim unsigned isLocalToUnit() const { return getUnsignedField(8); } 446263509Sdim unsigned isDefinition() const { return getUnsignedField(9); } 447239310Sdim 448263509Sdim unsigned getVirtuality() const { return getUnsignedField(10); } 449263509Sdim unsigned getVirtualIndex() const { return getUnsignedField(11); } 450239310Sdim 451263509Sdim DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); } 452252723Sdim 453263509Sdim unsigned getFlags() const { return getUnsignedField(13); } 454239310Sdim 455263509Sdim unsigned isArtificial() const { 456263509Sdim return (getUnsignedField(13) & FlagArtificial) != 0; 457263509Sdim } 458263509Sdim /// isPrivate - Return true if this subprogram has "private" 459263509Sdim /// access specifier. 460263509Sdim bool isPrivate() const { return (getUnsignedField(13) & FlagPrivate) != 0; } 461263509Sdim /// isProtected - Return true if this subprogram has "protected" 462263509Sdim /// access specifier. 463263509Sdim bool isProtected() const { 464263509Sdim return (getUnsignedField(13) & FlagProtected) != 0; 465263509Sdim } 466263509Sdim /// isExplicit - Return true if this subprogram is marked as explicit. 467263509Sdim bool isExplicit() const { return (getUnsignedField(13) & FlagExplicit) != 0; } 468263509Sdim /// isPrototyped - Return true if this subprogram is prototyped. 469263509Sdim bool isPrototyped() const { 470263509Sdim return (getUnsignedField(13) & FlagPrototyped) != 0; 471263509Sdim } 472239310Sdim 473263509Sdim unsigned isOptimized() const; 474239310Sdim 475263509Sdim /// Verify - Verify that a subprogram descriptor is well formed. 476263509Sdim bool Verify() const; 477239310Sdim 478263509Sdim /// describes - Return true if this subprogram provides debugging 479263509Sdim /// information for the function F. 480263509Sdim bool describes(const Function *F); 481239310Sdim 482263509Sdim Function *getFunction() const { return getFunctionField(15); } 483263509Sdim void replaceFunction(Function *F) { replaceFunctionField(15, F); } 484263509Sdim DIArray getTemplateParams() const { return getFieldAs<DIArray>(16); } 485263509Sdim DISubprogram getFunctionDeclaration() const { 486263509Sdim return getFieldAs<DISubprogram>(17); 487263509Sdim } 488263509Sdim MDNode *getVariablesNodes() const; 489263509Sdim DIArray getVariables() const; 490239310Sdim 491263509Sdim /// getScopeLineNumber - Get the beginning of the scope of the 492263509Sdim /// function, not necessarily where the name of the program 493263509Sdim /// starts. 494263509Sdim unsigned getScopeLineNumber() const { return getUnsignedField(19); } 495263509Sdim}; 496239310Sdim 497263509Sdim/// DILexicalBlock - This is a wrapper for a lexical block. 498263509Sdimclass DILexicalBlock : public DIScope { 499263509Sdimpublic: 500263509Sdim explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {} 501263509Sdim DIScope getContext() const { return getFieldAs<DIScope>(2); } 502263509Sdim unsigned getLineNumber() const { return getUnsignedField(3); } 503263509Sdim unsigned getColumnNumber() const { return getUnsignedField(4); } 504263509Sdim bool Verify() const; 505263509Sdim}; 506239310Sdim 507263509Sdim/// DILexicalBlockFile - This is a wrapper for a lexical block with 508263509Sdim/// a filename change. 509263509Sdimclass DILexicalBlockFile : public DIScope { 510263509Sdimpublic: 511263509Sdim explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {} 512263509Sdim DIScope getContext() const { 513263509Sdim if (getScope().isSubprogram()) 514263509Sdim return getScope(); 515263509Sdim return getScope().getContext(); 516263509Sdim } 517263509Sdim unsigned getLineNumber() const { return getScope().getLineNumber(); } 518263509Sdim unsigned getColumnNumber() const { return getScope().getColumnNumber(); } 519263509Sdim DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); } 520263509Sdim bool Verify() const; 521263509Sdim}; 522239310Sdim 523263509Sdim/// DINameSpace - A wrapper for a C++ style name space. 524263509Sdimclass DINameSpace : public DIScope { 525263509Sdim friend class DIDescriptor; 526263509Sdim void printInternal(raw_ostream &OS) const; 527239310Sdim 528263509Sdimpublic: 529263509Sdim explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {} 530263509Sdim DIScope getContext() const { return getFieldAs<DIScope>(2); } 531263509Sdim StringRef getName() const { return getStringField(3); } 532263509Sdim unsigned getLineNumber() const { return getUnsignedField(4); } 533263509Sdim bool Verify() const; 534263509Sdim}; 535239310Sdim 536263509Sdim/// DITemplateTypeParameter - This is a wrapper for template type parameter. 537263509Sdimclass DITemplateTypeParameter : public DIDescriptor { 538263509Sdimpublic: 539263509Sdim explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {} 540239310Sdim 541263509Sdim DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); } 542263509Sdim StringRef getName() const { return getStringField(2); } 543263509Sdim DITypeRef getType() const { return getFieldAs<DITypeRef>(3); } 544263509Sdim StringRef getFilename() const { return getFieldAs<DIFile>(4).getFilename(); } 545263509Sdim StringRef getDirectory() const { 546263509Sdim return getFieldAs<DIFile>(4).getDirectory(); 547263509Sdim } 548263509Sdim unsigned getLineNumber() const { return getUnsignedField(5); } 549263509Sdim unsigned getColumnNumber() const { return getUnsignedField(6); } 550263509Sdim bool Verify() const; 551263509Sdim}; 552239310Sdim 553263509Sdim/// DITemplateValueParameter - This is a wrapper for template value parameter. 554263509Sdimclass DITemplateValueParameter : public DIDescriptor { 555263509Sdimpublic: 556263509Sdim explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {} 557239310Sdim 558263509Sdim DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); } 559263509Sdim StringRef getName() const { return getStringField(2); } 560263509Sdim DITypeRef getType() const { return getFieldAs<DITypeRef>(3); } 561263509Sdim Value *getValue() const; 562263509Sdim StringRef getFilename() const { return getFieldAs<DIFile>(5).getFilename(); } 563263509Sdim StringRef getDirectory() const { 564263509Sdim return getFieldAs<DIFile>(5).getDirectory(); 565263509Sdim } 566263509Sdim unsigned getLineNumber() const { return getUnsignedField(6); } 567263509Sdim unsigned getColumnNumber() const { return getUnsignedField(7); } 568263509Sdim bool Verify() const; 569263509Sdim}; 570252723Sdim 571263509Sdim/// DIGlobalVariable - This is a wrapper for a global variable. 572263509Sdimclass DIGlobalVariable : public DIDescriptor { 573263509Sdim friend class DIDescriptor; 574263509Sdim void printInternal(raw_ostream &OS) const; 575239310Sdim 576263509Sdimpublic: 577263509Sdim explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {} 578239310Sdim 579263509Sdim DIScope getContext() const { return getFieldAs<DIScope>(2); } 580263509Sdim StringRef getName() const { return getStringField(3); } 581263509Sdim StringRef getDisplayName() const { return getStringField(4); } 582263509Sdim StringRef getLinkageName() const { return getStringField(5); } 583263509Sdim StringRef getFilename() const { return getFieldAs<DIFile>(6).getFilename(); } 584263509Sdim StringRef getDirectory() const { 585263509Sdim return getFieldAs<DIFile>(6).getDirectory(); 586263509Sdim } 587239310Sdim 588263509Sdim unsigned getLineNumber() const { return getUnsignedField(7); } 589263509Sdim DIType getType() const { return getFieldAs<DIType>(8); } 590263509Sdim unsigned isLocalToUnit() const { return getUnsignedField(9); } 591263509Sdim unsigned isDefinition() const { return getUnsignedField(10); } 592239310Sdim 593263509Sdim GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } 594263509Sdim Constant *getConstant() const { return getConstantField(11); } 595263509Sdim DIDerivedType getStaticDataMemberDeclaration() const { 596263509Sdim return getFieldAs<DIDerivedType>(12); 597263509Sdim } 598239310Sdim 599263509Sdim /// Verify - Verify that a global variable descriptor is well formed. 600263509Sdim bool Verify() const; 601263509Sdim}; 602239310Sdim 603263509Sdim/// DIVariable - This is a wrapper for a variable (e.g. parameter, local, 604263509Sdim/// global etc). 605263509Sdimclass DIVariable : public DIDescriptor { 606263509Sdim friend class DIDescriptor; 607263509Sdim void printInternal(raw_ostream &OS) const; 608239310Sdim 609263509Sdimpublic: 610263509Sdim explicit DIVariable(const MDNode *N = 0) : DIDescriptor(N) {} 611239310Sdim 612263509Sdim DIScope getContext() const { return getFieldAs<DIScope>(1); } 613263509Sdim StringRef getName() const { return getStringField(2); } 614263509Sdim DIFile getFile() const { return getFieldAs<DIFile>(3); } 615263509Sdim unsigned getLineNumber() const { return (getUnsignedField(4) << 8) >> 8; } 616263509Sdim unsigned getArgNumber() const { 617263509Sdim unsigned L = getUnsignedField(4); 618263509Sdim return L >> 24; 619263509Sdim } 620263509Sdim DIType getType() const { return getFieldAs<DIType>(5); } 621239310Sdim 622263509Sdim /// isArtificial - Return true if this variable is marked as "artificial". 623263509Sdim bool isArtificial() const { 624263509Sdim return (getUnsignedField(6) & FlagArtificial) != 0; 625263509Sdim } 626239310Sdim 627263509Sdim bool isObjectPointer() const { 628263509Sdim return (getUnsignedField(6) & FlagObjectPointer) != 0; 629263509Sdim } 630239310Sdim 631263509Sdim /// \brief Return true if this variable is represented as a pointer. 632263509Sdim bool isIndirect() const { 633263509Sdim return (getUnsignedField(6) & FlagIndirectVariable) != 0; 634263509Sdim } 635239310Sdim 636263509Sdim /// getInlinedAt - If this variable is inlined then return inline location. 637263509Sdim MDNode *getInlinedAt() const; 638239310Sdim 639263509Sdim /// Verify - Verify that a variable descriptor is well formed. 640263509Sdim bool Verify() const; 641239310Sdim 642263509Sdim /// HasComplexAddr - Return true if the variable has a complex address. 643263509Sdim bool hasComplexAddress() const { return getNumAddrElements() > 0; } 644239310Sdim 645263509Sdim unsigned getNumAddrElements() const; 646239310Sdim 647263509Sdim uint64_t getAddrElement(unsigned Idx) const { 648263509Sdim return getUInt64Field(Idx + 8); 649263509Sdim } 650239310Sdim 651263509Sdim /// isBlockByrefVariable - Return true if the variable was declared as 652263509Sdim /// a "__block" variable (Apple Blocks). 653263509Sdim bool isBlockByrefVariable() const { return getType().isBlockByrefStruct(); } 654239310Sdim 655263509Sdim /// isInlinedFnArgument - Return true if this variable provides debugging 656263509Sdim /// information for an inlined function arguments. 657263509Sdim bool isInlinedFnArgument(const Function *CurFn); 658239310Sdim 659263509Sdim void printExtendedName(raw_ostream &OS) const; 660263509Sdim}; 661263509Sdim 662263509Sdim/// DILocation - This object holds location information. This object 663263509Sdim/// is not associated with any DWARF tag. 664263509Sdimclass DILocation : public DIDescriptor { 665263509Sdimpublic: 666263509Sdim explicit DILocation(const MDNode *N) : DIDescriptor(N) {} 667263509Sdim 668263509Sdim unsigned getLineNumber() const { return getUnsignedField(0); } 669263509Sdim unsigned getColumnNumber() const { return getUnsignedField(1); } 670263509Sdim DIScope getScope() const { return getFieldAs<DIScope>(2); } 671263509Sdim DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); } 672263509Sdim StringRef getFilename() const { return getScope().getFilename(); } 673263509Sdim StringRef getDirectory() const { return getScope().getDirectory(); } 674263509Sdim bool Verify() const; 675263509Sdim}; 676263509Sdim 677263509Sdimclass DIObjCProperty : public DIDescriptor { 678263509Sdim friend class DIDescriptor; 679263509Sdim void printInternal(raw_ostream &OS) const; 680263509Sdim 681263509Sdimpublic: 682263509Sdim explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) {} 683263509Sdim 684263509Sdim StringRef getObjCPropertyName() const { return getStringField(1); } 685263509Sdim DIFile getFile() const { return getFieldAs<DIFile>(2); } 686263509Sdim unsigned getLineNumber() const { return getUnsignedField(3); } 687263509Sdim 688263509Sdim StringRef getObjCPropertyGetterName() const { return getStringField(4); } 689263509Sdim StringRef getObjCPropertySetterName() const { return getStringField(5); } 690263509Sdim bool isReadOnlyObjCProperty() const { 691263509Sdim return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; 692263509Sdim } 693263509Sdim bool isReadWriteObjCProperty() const { 694263509Sdim return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; 695263509Sdim } 696263509Sdim bool isAssignObjCProperty() const { 697263509Sdim return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0; 698263509Sdim } 699263509Sdim bool isRetainObjCProperty() const { 700263509Sdim return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0; 701263509Sdim } 702263509Sdim bool isCopyObjCProperty() const { 703263509Sdim return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0; 704263509Sdim } 705263509Sdim bool isNonAtomicObjCProperty() const { 706263509Sdim return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; 707263509Sdim } 708263509Sdim 709263509Sdim DIType getType() const { return getFieldAs<DIType>(7); } 710263509Sdim 711263509Sdim /// Verify - Verify that a derived type descriptor is well formed. 712263509Sdim bool Verify() const; 713263509Sdim}; 714263509Sdim 715263509Sdim/// \brief An imported module (C++ using directive or similar). 716263509Sdimclass DIImportedEntity : public DIDescriptor { 717263509Sdim friend class DIDescriptor; 718263509Sdim void printInternal(raw_ostream &OS) const; 719263509Sdim 720263509Sdimpublic: 721263509Sdim explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {} 722263509Sdim DIScope getContext() const { return getFieldAs<DIScope>(1); } 723263509Sdim DIDescriptor getEntity() const { return getFieldAs<DIDescriptor>(2); } 724263509Sdim unsigned getLineNumber() const { return getUnsignedField(3); } 725263509Sdim StringRef getName() const { return getStringField(4); } 726263509Sdim bool Verify() const; 727263509Sdim}; 728263509Sdim 729263509Sdim/// getDISubprogram - Find subprogram that is enclosing this scope. 730263509SdimDISubprogram getDISubprogram(const MDNode *Scope); 731263509Sdim 732263509Sdim/// getDICompositeType - Find underlying composite type. 733263509SdimDICompositeType getDICompositeType(DIType T); 734263509Sdim 735263509Sdim/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable 736263509Sdim/// to hold function specific information. 737263509SdimNamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP); 738263509Sdim 739263509Sdim/// getFnSpecificMDNode - Return a NameMDNode, if available, that is 740263509Sdim/// suitable to hold function specific information. 741263509SdimNamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP); 742263509Sdim 743263509Sdim/// createInlinedVariable - Create a new inlined variable based on current 744263509Sdim/// variable. 745263509Sdim/// @param DV Current Variable. 746263509Sdim/// @param InlinedScope Location at current variable is inlined. 747263509SdimDIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope, 748263509Sdim LLVMContext &VMContext); 749263509Sdim 750263509Sdim/// cleanseInlinedVariable - Remove inlined scope from the variable. 751263509SdimDIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext); 752263509Sdim 753263509Sdim/// Construct DITypeIdentifierMap by going through retained types of each CU. 754263509SdimDITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes); 755263509Sdim 756263509Sdim/// Strip debug info in the module if it exists. 757263509Sdim/// To do this, we remove all calls to the debugger intrinsics and any named 758263509Sdim/// metadata for debugging. We also remove debug locations for instructions. 759263509Sdim/// Return true if module is modified. 760263509Sdimbool StripDebugInfo(Module &M); 761263509Sdim 762263509Sdim/// Return Debug Info Metadata Version by checking module flags. 763263509Sdimunsigned getDebugMetadataVersionFromModule(const Module &M); 764263509Sdim 765263509Sdim/// DebugInfoFinder tries to list all debug info MDNodes used in a module. To 766263509Sdim/// list debug info MDNodes used by an instruction, DebugInfoFinder uses 767263509Sdim/// processDeclare, processValue and processLocation to handle DbgDeclareInst, 768263509Sdim/// DbgValueInst and DbgLoc attached to instructions. processModule will go 769263509Sdim/// through all DICompileUnits in llvm.dbg.cu and list debug info MDNodes 770263509Sdim/// used by the CUs. 771263509Sdimclass DebugInfoFinder { 772263509Sdimpublic: 773263509Sdim DebugInfoFinder() : TypeMapInitialized(false) {} 774263509Sdim 775263509Sdim /// processModule - Process entire module and collect debug info 776263509Sdim /// anchors. 777263509Sdim void processModule(const Module &M); 778263509Sdim 779263509Sdim /// processDeclare - Process DbgDeclareInst. 780263509Sdim void processDeclare(const Module &M, const DbgDeclareInst *DDI); 781263509Sdim /// Process DbgValueInst. 782263509Sdim void processValue(const Module &M, const DbgValueInst *DVI); 783263509Sdim /// processLocation - Process DILocation. 784263509Sdim void processLocation(const Module &M, DILocation Loc); 785263509Sdim 786263509Sdim /// Clear all lists. 787263509Sdim void reset(); 788263509Sdim 789263509Sdimprivate: 790263509Sdim /// Initialize TypeIdentifierMap. 791263509Sdim void InitializeTypeMap(const Module &M); 792263509Sdim 793263509Sdim /// processType - Process DIType. 794263509Sdim void processType(DIType DT); 795263509Sdim 796263509Sdim /// processLexicalBlock - Process DILexicalBlock. 797263509Sdim void processLexicalBlock(DILexicalBlock LB); 798263509Sdim 799263509Sdim /// processSubprogram - Process DISubprogram. 800263509Sdim void processSubprogram(DISubprogram SP); 801263509Sdim 802263509Sdim void processScope(DIScope Scope); 803263509Sdim 804263509Sdim /// addCompileUnit - Add compile unit into CUs. 805263509Sdim bool addCompileUnit(DICompileUnit CU); 806263509Sdim 807263509Sdim /// addGlobalVariable - Add global variable into GVs. 808263509Sdim bool addGlobalVariable(DIGlobalVariable DIG); 809263509Sdim 810263509Sdim // addSubprogram - Add subprogram into SPs. 811263509Sdim bool addSubprogram(DISubprogram SP); 812263509Sdim 813263509Sdim /// addType - Add type into Tys. 814263509Sdim bool addType(DIType DT); 815263509Sdim 816263509Sdim bool addScope(DIScope Scope); 817263509Sdim 818263509Sdimpublic: 819263509Sdim typedef SmallVectorImpl<MDNode *>::const_iterator iterator; 820263509Sdim iterator compile_unit_begin() const { return CUs.begin(); } 821263509Sdim iterator compile_unit_end() const { return CUs.end(); } 822263509Sdim iterator subprogram_begin() const { return SPs.begin(); } 823263509Sdim iterator subprogram_end() const { return SPs.end(); } 824263509Sdim iterator global_variable_begin() const { return GVs.begin(); } 825263509Sdim iterator global_variable_end() const { return GVs.end(); } 826263509Sdim iterator type_begin() const { return TYs.begin(); } 827263509Sdim iterator type_end() const { return TYs.end(); } 828263509Sdim iterator scope_begin() const { return Scopes.begin(); } 829263509Sdim iterator scope_end() const { return Scopes.end(); } 830263509Sdim 831263509Sdim unsigned compile_unit_count() const { return CUs.size(); } 832263509Sdim unsigned global_variable_count() const { return GVs.size(); } 833263509Sdim unsigned subprogram_count() const { return SPs.size(); } 834263509Sdim unsigned type_count() const { return TYs.size(); } 835263509Sdim unsigned scope_count() const { return Scopes.size(); } 836263509Sdim 837263509Sdimprivate: 838263509Sdim SmallVector<MDNode *, 8> CUs; // Compile Units 839263509Sdim SmallVector<MDNode *, 8> SPs; // Subprograms 840263509Sdim SmallVector<MDNode *, 8> GVs; // Global Variables; 841263509Sdim SmallVector<MDNode *, 8> TYs; // Types 842263509Sdim SmallVector<MDNode *, 8> Scopes; // Scopes 843263509Sdim SmallPtrSet<MDNode *, 64> NodesSeen; 844263509Sdim DITypeIdentifierMap TypeIdentifierMap; 845263509Sdim /// Specify if TypeIdentifierMap is initialized. 846263509Sdim bool TypeMapInitialized; 847263509Sdim}; 848239310Sdim} // end namespace llvm 849239310Sdim 850239310Sdim#endif 851