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 17249423Sdim#ifndef LLVM_DEBUGINFO_H 18249423Sdim#define LLVM_DEBUGINFO_H 19239310Sdim 20263508Sdim#include "llvm/Support/Casting.h" 21263508Sdim#include "llvm/ADT/DenseMap.h" 22249423Sdim#include "llvm/ADT/SmallPtrSet.h" 23239310Sdim#include "llvm/ADT/SmallVector.h" 24239310Sdim#include "llvm/ADT/StringRef.h" 25263508Sdim#include "llvm/IR/Metadata.h" 26239310Sdim#include "llvm/Support/Dwarf.h" 27239310Sdim 28239310Sdimnamespace llvm { 29263508Sdimclass BasicBlock; 30263508Sdimclass Constant; 31263508Sdimclass Function; 32263508Sdimclass GlobalVariable; 33263508Sdimclass Module; 34263508Sdimclass Type; 35263508Sdimclass Value; 36263508Sdimclass DbgDeclareInst; 37263508Sdimclass DbgValueInst; 38263508Sdimclass Instruction; 39263508Sdimclass MDNode; 40263508Sdimclass MDString; 41263508Sdimclass NamedMDNode; 42263508Sdimclass LLVMContext; 43263508Sdimclass raw_ostream; 44239310Sdim 45263508Sdimclass DIFile; 46263508Sdimclass DISubprogram; 47263508Sdimclass DILexicalBlock; 48263508Sdimclass DILexicalBlockFile; 49263508Sdimclass DIVariable; 50263508Sdimclass DIType; 51263508Sdimclass DIScope; 52263508Sdimclass DIObjCProperty; 53239310Sdim 54263508Sdim/// Maps from type identifier to the actual MDNode. 55263508Sdimtypedef DenseMap<const MDString *, MDNode *> DITypeIdentifierMap; 56239310Sdim 57263508Sdim/// DIDescriptor - A thin wraper around MDNode to access encoded debug info. 58263508Sdim/// This should not be stored in a container, because the underlying MDNode 59263508Sdim/// may change in certain situations. 60263508Sdimclass DIDescriptor { 61263508Sdim // Befriends DIRef so DIRef can befriend the protected member 62263508Sdim // function: getFieldAs<DIRef>. 63263508Sdim template <typename T> friend class DIRef; 64239310Sdim 65263508Sdimpublic: 66263508Sdim enum { 67263508Sdim FlagPrivate = 1 << 0, 68263508Sdim FlagProtected = 1 << 1, 69263508Sdim FlagFwdDecl = 1 << 2, 70263508Sdim FlagAppleBlock = 1 << 3, 71263508Sdim FlagBlockByrefStruct = 1 << 4, 72263508Sdim FlagVirtual = 1 << 5, 73263508Sdim FlagArtificial = 1 << 6, 74263508Sdim FlagExplicit = 1 << 7, 75263508Sdim FlagPrototyped = 1 << 8, 76263508Sdim FlagObjcClassComplete = 1 << 9, 77263508Sdim FlagObjectPointer = 1 << 10, 78263508Sdim FlagVector = 1 << 11, 79263508Sdim FlagStaticMember = 1 << 12, 80263508Sdim FlagIndirectVariable = 1 << 13 81263508Sdim }; 82239310Sdim 83263508Sdimprotected: 84263508Sdim const MDNode *DbgNode; 85239310Sdim 86263508Sdim StringRef getStringField(unsigned Elt) const; 87263508Sdim unsigned getUnsignedField(unsigned Elt) const { 88263508Sdim return (unsigned)getUInt64Field(Elt); 89263508Sdim } 90263508Sdim uint64_t getUInt64Field(unsigned Elt) const; 91263508Sdim int64_t getInt64Field(unsigned Elt) const; 92263508Sdim DIDescriptor getDescriptorField(unsigned Elt) const; 93239310Sdim 94263508Sdim template <typename DescTy> DescTy getFieldAs(unsigned Elt) const { 95263508Sdim return DescTy(getDescriptorField(Elt)); 96263508Sdim } 97239310Sdim 98263508Sdim GlobalVariable *getGlobalVariableField(unsigned Elt) const; 99263508Sdim Constant *getConstantField(unsigned Elt) const; 100263508Sdim Function *getFunctionField(unsigned Elt) const; 101263508Sdim void replaceFunctionField(unsigned Elt, Function *F); 102239310Sdim 103263508Sdimpublic: 104263508Sdim explicit DIDescriptor(const MDNode *N = 0) : DbgNode(N) {} 105239310Sdim 106263508Sdim bool Verify() const; 107239310Sdim 108263508Sdim operator MDNode *() const { return const_cast<MDNode *>(DbgNode); } 109263508Sdim MDNode *operator->() const { return const_cast<MDNode *>(DbgNode); } 110239310Sdim 111263508Sdim // An explicit operator bool so that we can do testing of DI values 112263508Sdim // easily. 113263508Sdim // FIXME: This operator bool isn't actually protecting anything at the 114263508Sdim // moment due to the conversion operator above making DIDescriptor nodes 115263508Sdim // implicitly convertable to bool. 116263508Sdim LLVM_EXPLICIT operator bool() const { return DbgNode != 0; } 117239310Sdim 118263508Sdim bool operator==(DIDescriptor Other) const { return DbgNode == Other.DbgNode; } 119263508Sdim bool operator!=(DIDescriptor Other) const { return !operator==(Other); } 120239310Sdim 121263508Sdim uint16_t getTag() const { 122263508Sdim return getUnsignedField(0) & ~LLVMDebugVersionMask; 123263508Sdim } 124239310Sdim 125263508Sdim bool isDerivedType() const; 126263508Sdim bool isCompositeType() const; 127263508Sdim bool isBasicType() const; 128263508Sdim bool isVariable() const; 129263508Sdim bool isSubprogram() const; 130263508Sdim bool isGlobalVariable() const; 131263508Sdim bool isScope() const; 132263508Sdim bool isFile() const; 133263508Sdim bool isCompileUnit() const; 134263508Sdim bool isNameSpace() const; 135263508Sdim bool isLexicalBlockFile() const; 136263508Sdim bool isLexicalBlock() const; 137263508Sdim bool isSubrange() const; 138263508Sdim bool isEnumerator() const; 139263508Sdim bool isType() const; 140263508Sdim bool isUnspecifiedParameter() const; 141263508Sdim bool isTemplateTypeParameter() const; 142263508Sdim bool isTemplateValueParameter() const; 143263508Sdim bool isObjCProperty() const; 144263508Sdim bool isImportedEntity() const; 145239310Sdim 146263508Sdim /// print - print descriptor. 147263508Sdim void print(raw_ostream &OS) const; 148239310Sdim 149263508Sdim /// dump - print descriptor to dbgs() with a newline. 150263508Sdim void dump() const; 151263508Sdim}; 152239310Sdim 153263508Sdim/// DISubrange - This is used to represent ranges, for array bounds. 154263508Sdimclass DISubrange : public DIDescriptor { 155263508Sdim friend class DIDescriptor; 156263508Sdim void printInternal(raw_ostream &OS) const; 157239310Sdim 158263508Sdimpublic: 159263508Sdim explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {} 160249423Sdim 161263508Sdim int64_t getLo() const { return getInt64Field(1); } 162263508Sdim int64_t getCount() const { return getInt64Field(2); } 163263508Sdim bool Verify() const; 164263508Sdim}; 165239310Sdim 166263508Sdim/// DIArray - This descriptor holds an array of descriptors. 167263508Sdimclass DIArray : public DIDescriptor { 168263508Sdimpublic: 169263508Sdim explicit DIArray(const MDNode *N = 0) : DIDescriptor(N) {} 170239310Sdim 171263508Sdim unsigned getNumElements() const; 172263508Sdim DIDescriptor getElement(unsigned Idx) const { 173263508Sdim return getDescriptorField(Idx); 174263508Sdim } 175263508Sdim}; 176239310Sdim 177263508Sdim/// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). 178263508Sdim/// FIXME: it seems strange that this doesn't have either a reference to the 179263508Sdim/// type/precision or a file/line pair for location info. 180263508Sdimclass DIEnumerator : public DIDescriptor { 181263508Sdim friend class DIDescriptor; 182263508Sdim void printInternal(raw_ostream &OS) const; 183239310Sdim 184263508Sdimpublic: 185263508Sdim explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {} 186249423Sdim 187263508Sdim StringRef getName() const { return getStringField(1); } 188263508Sdim int64_t getEnumValue() const { return getInt64Field(2); } 189263508Sdim bool Verify() const; 190263508Sdim}; 191239310Sdim 192263508Sdimtemplate <typename T> class DIRef; 193263508Sdimtypedef DIRef<DIScope> DIScopeRef; 194263508Sdimtypedef DIRef<DIType> DITypeRef; 195239310Sdim 196263508Sdim/// DIScope - A base class for various scopes. 197263508Sdimclass DIScope : public DIDescriptor { 198263508Sdimprotected: 199263508Sdim friend class DIDescriptor; 200263508Sdim void printInternal(raw_ostream &OS) const; 201239310Sdim 202263508Sdimpublic: 203263508Sdim explicit DIScope(const MDNode *N = 0) : DIDescriptor(N) {} 204239310Sdim 205263508Sdim /// Gets the parent scope for this scope node or returns a 206263508Sdim /// default constructed scope. 207263508Sdim DIScopeRef getContext() const; 208263508Sdim /// If the scope node has a name, return that, else return an empty string. 209263508Sdim StringRef getName() const; 210263508Sdim StringRef getFilename() const; 211263508Sdim StringRef getDirectory() const; 212239310Sdim 213263508Sdim /// Generate a reference to this DIScope. Uses the type identifier instead 214263508Sdim /// of the actual MDNode if possible, to help type uniquing. 215263508Sdim DIScopeRef getRef() const; 216263508Sdim}; 217239310Sdim 218263508Sdim/// Represents reference to a DIDescriptor, abstracts over direct and 219263508Sdim/// identifier-based metadata references. 220263508Sdimtemplate <typename T> class DIRef { 221263508Sdim template <typename DescTy> 222263508Sdim friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const; 223263508Sdim friend DIScopeRef DIScope::getContext() const; 224263508Sdim friend DIScopeRef DIScope::getRef() const; 225239310Sdim 226263508Sdim /// Val can be either a MDNode or a MDString, in the latter, 227263508Sdim /// MDString specifies the type identifier. 228263508Sdim const Value *Val; 229263508Sdim explicit DIRef(const Value *V); 230239310Sdim 231263508Sdimpublic: 232263508Sdim T resolve(const DITypeIdentifierMap &Map) const; 233263508Sdim StringRef getName() const; 234263508Sdim operator Value *() const { return const_cast<Value *>(Val); } 235263508Sdim}; 236239310Sdim 237263508Sdimtemplate <typename T> 238263508SdimT DIRef<T>::resolve(const DITypeIdentifierMap &Map) const { 239263508Sdim if (!Val) 240263508Sdim return T(); 241239310Sdim 242263508Sdim if (const MDNode *MD = dyn_cast<MDNode>(Val)) 243263508Sdim return T(MD); 244239310Sdim 245263508Sdim const MDString *MS = cast<MDString>(Val); 246263508Sdim // Find the corresponding MDNode. 247263508Sdim DITypeIdentifierMap::const_iterator Iter = Map.find(MS); 248263508Sdim assert(Iter != Map.end() && "Identifier not in the type map?"); 249263508Sdim assert(DIDescriptor(Iter->second).isType() && 250263508Sdim "MDNode in DITypeIdentifierMap should be a DIType."); 251263508Sdim return T(Iter->second); 252263508Sdim} 253239310Sdim 254263508Sdimtemplate <typename T> StringRef DIRef<T>::getName() const { 255263508Sdim if (!Val) 256263508Sdim return StringRef(); 257239310Sdim 258263508Sdim if (const MDNode *MD = dyn_cast<MDNode>(Val)) 259263508Sdim return T(MD).getName(); 260239310Sdim 261263508Sdim const MDString *MS = cast<MDString>(Val); 262263508Sdim return MS->getString(); 263263508Sdim} 264249423Sdim 265263508Sdim/// Specialize getFieldAs to handle fields that are references to DIScopes. 266263508Sdimtemplate <> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const; 267263508Sdim/// Specialize DIRef constructor for DIScopeRef. 268263508Sdimtemplate <> DIRef<DIScope>::DIRef(const Value *V); 269239310Sdim 270263508Sdim/// Specialize getFieldAs to handle fields that are references to DITypes. 271263508Sdimtemplate <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const; 272263508Sdim/// Specialize DIRef constructor for DITypeRef. 273263508Sdimtemplate <> DIRef<DIType>::DIRef(const Value *V); 274239310Sdim 275263508Sdim/// DIType - This is a wrapper for a type. 276263508Sdim/// FIXME: Types should be factored much better so that CV qualifiers and 277263508Sdim/// others do not require a huge and empty descriptor full of zeros. 278263508Sdimclass DIType : public DIScope { 279263508Sdimprotected: 280263508Sdim friend class DIDescriptor; 281263508Sdim void printInternal(raw_ostream &OS) const; 282239310Sdim 283263508Sdimpublic: 284263508Sdim explicit DIType(const MDNode *N = 0) : DIScope(N) {} 285239310Sdim 286263508Sdim /// Verify - Verify that a type descriptor is well formed. 287263508Sdim bool Verify() const; 288239310Sdim 289263508Sdim DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); } 290263508Sdim StringRef getName() const { return getStringField(3); } 291263508Sdim unsigned getLineNumber() const { return getUnsignedField(4); } 292263508Sdim uint64_t getSizeInBits() const { return getUInt64Field(5); } 293263508Sdim uint64_t getAlignInBits() const { return getUInt64Field(6); } 294263508Sdim // FIXME: Offset is only used for DW_TAG_member nodes. Making every type 295263508Sdim // carry this is just plain insane. 296263508Sdim uint64_t getOffsetInBits() const { return getUInt64Field(7); } 297263508Sdim unsigned getFlags() const { return getUnsignedField(8); } 298263508Sdim bool isPrivate() const { return (getFlags() & FlagPrivate) != 0; } 299263508Sdim bool isProtected() const { return (getFlags() & FlagProtected) != 0; } 300263508Sdim bool isForwardDecl() const { return (getFlags() & FlagFwdDecl) != 0; } 301263508Sdim // isAppleBlock - Return true if this is the Apple Blocks extension. 302263508Sdim bool isAppleBlockExtension() const { 303263508Sdim return (getFlags() & FlagAppleBlock) != 0; 304263508Sdim } 305263508Sdim bool isBlockByrefStruct() const { 306263508Sdim return (getFlags() & FlagBlockByrefStruct) != 0; 307263508Sdim } 308263508Sdim bool isVirtual() const { return (getFlags() & FlagVirtual) != 0; } 309263508Sdim bool isArtificial() const { return (getFlags() & FlagArtificial) != 0; } 310263508Sdim bool isObjectPointer() const { return (getFlags() & FlagObjectPointer) != 0; } 311263508Sdim bool isObjcClassComplete() const { 312263508Sdim return (getFlags() & FlagObjcClassComplete) != 0; 313263508Sdim } 314263508Sdim bool isVector() const { return (getFlags() & FlagVector) != 0; } 315263508Sdim bool isStaticMember() const { return (getFlags() & FlagStaticMember) != 0; } 316263508Sdim bool isValid() const { return DbgNode && isType(); } 317239310Sdim 318263508Sdim /// replaceAllUsesWith - Replace all uses of debug info referenced by 319263508Sdim /// this descriptor. 320263508Sdim void replaceAllUsesWith(DIDescriptor &D); 321263508Sdim void replaceAllUsesWith(MDNode *D); 322263508Sdim}; 323239310Sdim 324263508Sdim/// DIBasicType - A basic type, like 'int' or 'float'. 325263508Sdimclass DIBasicType : public DIType { 326263508Sdimpublic: 327263508Sdim explicit DIBasicType(const MDNode *N = 0) : DIType(N) {} 328239310Sdim 329263508Sdim unsigned getEncoding() const { return getUnsignedField(9); } 330239310Sdim 331263508Sdim /// Verify - Verify that a basic type descriptor is well formed. 332263508Sdim bool Verify() const; 333263508Sdim}; 334239310Sdim 335263508Sdim/// DIDerivedType - A simple derived type, like a const qualified type, 336263508Sdim/// a typedef, a pointer or reference, et cetera. Or, a data member of 337263508Sdim/// a class/struct/union. 338263508Sdimclass DIDerivedType : public DIType { 339263508Sdim friend class DIDescriptor; 340263508Sdim void printInternal(raw_ostream &OS) const; 341239310Sdim 342263508Sdimpublic: 343263508Sdim explicit DIDerivedType(const MDNode *N = 0) : DIType(N) {} 344239310Sdim 345263508Sdim DITypeRef getTypeDerivedFrom() const { return getFieldAs<DITypeRef>(9); } 346239310Sdim 347263508Sdim /// getObjCProperty - Return property node, if this ivar is 348263508Sdim /// associated with one. 349263508Sdim MDNode *getObjCProperty() const; 350239310Sdim 351263508Sdim DITypeRef getClassType() const { 352263508Sdim assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); 353263508Sdim return getFieldAs<DITypeRef>(10); 354263508Sdim } 355239310Sdim 356263508Sdim Constant *getConstant() const { 357263508Sdim assert((getTag() == dwarf::DW_TAG_member) && isStaticMember()); 358263508Sdim return getConstantField(10); 359263508Sdim } 360249423Sdim 361263508Sdim /// Verify - Verify that a derived type descriptor is well formed. 362263508Sdim bool Verify() const; 363263508Sdim}; 364239310Sdim 365263508Sdim/// DICompositeType - This descriptor holds a type that can refer to multiple 366263508Sdim/// other types, like a function or struct. 367263508Sdim/// DICompositeType is derived from DIDerivedType because some 368263508Sdim/// composite types (such as enums) can be derived from basic types 369263508Sdim// FIXME: Make this derive from DIType directly & just store the 370263508Sdim// base type in a single DIType field. 371263508Sdimclass DICompositeType : public DIDerivedType { 372263508Sdim friend class DIDescriptor; 373263508Sdim void printInternal(raw_ostream &OS) const; 374239310Sdim 375263508Sdimpublic: 376263508Sdim explicit DICompositeType(const MDNode *N = 0) : DIDerivedType(N) {} 377239310Sdim 378263508Sdim DIArray getTypeArray() const { return getFieldAs<DIArray>(10); } 379263508Sdim void setTypeArray(DIArray Elements, DIArray TParams = DIArray()); 380263508Sdim void addMember(DIDescriptor D); 381263508Sdim unsigned getRunTimeLang() const { return getUnsignedField(11); } 382263508Sdim DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); } 383263508Sdim void setContainingType(DICompositeType ContainingType); 384263508Sdim DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); } 385263508Sdim MDString *getIdentifier() const; 386239310Sdim 387263508Sdim /// Verify - Verify that a composite type descriptor is well formed. 388263508Sdim bool Verify() const; 389263508Sdim}; 390239310Sdim 391263508Sdim/// DIFile - This is a wrapper for a file. 392263508Sdimclass DIFile : public DIScope { 393263508Sdim friend class DIDescriptor; 394239310Sdim 395263508Sdimpublic: 396263508Sdim explicit DIFile(const MDNode *N = 0) : DIScope(N) {} 397263508Sdim MDNode *getFileNode() const; 398263508Sdim bool Verify() const; 399263508Sdim}; 400239310Sdim 401263508Sdim/// DICompileUnit - A wrapper for a compile unit. 402263508Sdimclass DICompileUnit : public DIScope { 403263508Sdim friend class DIDescriptor; 404263508Sdim void printInternal(raw_ostream &OS) const; 405239310Sdim 406263508Sdimpublic: 407263508Sdim explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {} 408239310Sdim 409263508Sdim unsigned getLanguage() const { return getUnsignedField(2); } 410263508Sdim StringRef getProducer() const { return getStringField(3); } 411239310Sdim 412263508Sdim bool isOptimized() const { return getUnsignedField(4) != 0; } 413263508Sdim StringRef getFlags() const { return getStringField(5); } 414263508Sdim unsigned getRunTimeVersion() const { return getUnsignedField(6); } 415239310Sdim 416263508Sdim DIArray getEnumTypes() const; 417263508Sdim DIArray getRetainedTypes() const; 418263508Sdim DIArray getSubprograms() const; 419263508Sdim DIArray getGlobalVariables() const; 420263508Sdim DIArray getImportedEntities() const; 421239310Sdim 422263508Sdim StringRef getSplitDebugFilename() const { return getStringField(12); } 423239310Sdim 424263508Sdim /// Verify - Verify that a compile unit is well formed. 425263508Sdim bool Verify() const; 426263508Sdim}; 427249423Sdim 428263508Sdim/// DISubprogram - This is a wrapper for a subprogram (e.g. a function). 429263508Sdimclass DISubprogram : public DIScope { 430263508Sdim friend class DIDescriptor; 431263508Sdim void printInternal(raw_ostream &OS) const; 432239310Sdim 433263508Sdimpublic: 434263508Sdim explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {} 435243830Sdim 436263508Sdim DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); } 437263508Sdim StringRef getName() const { return getStringField(3); } 438263508Sdim StringRef getDisplayName() const { return getStringField(4); } 439263508Sdim StringRef getLinkageName() const { return getStringField(5); } 440263508Sdim unsigned getLineNumber() const { return getUnsignedField(6); } 441263508Sdim DICompositeType getType() const { return getFieldAs<DICompositeType>(7); } 442239310Sdim 443263508Sdim /// isLocalToUnit - Return true if this subprogram is local to the current 444263508Sdim /// compile unit, like 'static' in C. 445263508Sdim unsigned isLocalToUnit() const { return getUnsignedField(8); } 446263508Sdim unsigned isDefinition() const { return getUnsignedField(9); } 447239310Sdim 448263508Sdim unsigned getVirtuality() const { return getUnsignedField(10); } 449263508Sdim unsigned getVirtualIndex() const { return getUnsignedField(11); } 450239310Sdim 451263508Sdim DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); } 452249423Sdim 453263508Sdim unsigned getFlags() const { return getUnsignedField(13); } 454239310Sdim 455263508Sdim unsigned isArtificial() const { 456263508Sdim return (getUnsignedField(13) & FlagArtificial) != 0; 457263508Sdim } 458263508Sdim /// isPrivate - Return true if this subprogram has "private" 459263508Sdim /// access specifier. 460263508Sdim bool isPrivate() const { return (getUnsignedField(13) & FlagPrivate) != 0; } 461263508Sdim /// isProtected - Return true if this subprogram has "protected" 462263508Sdim /// access specifier. 463263508Sdim bool isProtected() const { 464263508Sdim return (getUnsignedField(13) & FlagProtected) != 0; 465263508Sdim } 466263508Sdim /// isExplicit - Return true if this subprogram is marked as explicit. 467263508Sdim bool isExplicit() const { return (getUnsignedField(13) & FlagExplicit) != 0; } 468263508Sdim /// isPrototyped - Return true if this subprogram is prototyped. 469263508Sdim bool isPrototyped() const { 470263508Sdim return (getUnsignedField(13) & FlagPrototyped) != 0; 471263508Sdim } 472239310Sdim 473263508Sdim unsigned isOptimized() const; 474239310Sdim 475263508Sdim /// Verify - Verify that a subprogram descriptor is well formed. 476263508Sdim bool Verify() const; 477239310Sdim 478263508Sdim /// describes - Return true if this subprogram provides debugging 479263508Sdim /// information for the function F. 480263508Sdim bool describes(const Function *F); 481239310Sdim 482263508Sdim Function *getFunction() const { return getFunctionField(15); } 483263508Sdim void replaceFunction(Function *F) { replaceFunctionField(15, F); } 484263508Sdim DIArray getTemplateParams() const { return getFieldAs<DIArray>(16); } 485263508Sdim DISubprogram getFunctionDeclaration() const { 486263508Sdim return getFieldAs<DISubprogram>(17); 487263508Sdim } 488263508Sdim MDNode *getVariablesNodes() const; 489263508Sdim DIArray getVariables() const; 490239310Sdim 491263508Sdim /// getScopeLineNumber - Get the beginning of the scope of the 492263508Sdim /// function, not necessarily where the name of the program 493263508Sdim /// starts. 494263508Sdim unsigned getScopeLineNumber() const { return getUnsignedField(19); } 495263508Sdim}; 496239310Sdim 497263508Sdim/// DILexicalBlock - This is a wrapper for a lexical block. 498263508Sdimclass DILexicalBlock : public DIScope { 499263508Sdimpublic: 500263508Sdim explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {} 501263508Sdim DIScope getContext() const { return getFieldAs<DIScope>(2); } 502263508Sdim unsigned getLineNumber() const { return getUnsignedField(3); } 503263508Sdim unsigned getColumnNumber() const { return getUnsignedField(4); } 504263508Sdim bool Verify() const; 505263508Sdim}; 506239310Sdim 507263508Sdim/// DILexicalBlockFile - This is a wrapper for a lexical block with 508263508Sdim/// a filename change. 509263508Sdimclass DILexicalBlockFile : public DIScope { 510263508Sdimpublic: 511263508Sdim explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {} 512263508Sdim DIScope getContext() const { 513263508Sdim if (getScope().isSubprogram()) 514263508Sdim return getScope(); 515263508Sdim return getScope().getContext(); 516263508Sdim } 517263508Sdim unsigned getLineNumber() const { return getScope().getLineNumber(); } 518263508Sdim unsigned getColumnNumber() const { return getScope().getColumnNumber(); } 519263508Sdim DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); } 520263508Sdim bool Verify() const; 521263508Sdim}; 522239310Sdim 523263508Sdim/// DINameSpace - A wrapper for a C++ style name space. 524263508Sdimclass DINameSpace : public DIScope { 525263508Sdim friend class DIDescriptor; 526263508Sdim void printInternal(raw_ostream &OS) const; 527239310Sdim 528263508Sdimpublic: 529263508Sdim explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {} 530263508Sdim DIScope getContext() const { return getFieldAs<DIScope>(2); } 531263508Sdim StringRef getName() const { return getStringField(3); } 532263508Sdim unsigned getLineNumber() const { return getUnsignedField(4); } 533263508Sdim bool Verify() const; 534263508Sdim}; 535239310Sdim 536263508Sdim/// DITemplateTypeParameter - This is a wrapper for template type parameter. 537263508Sdimclass DITemplateTypeParameter : public DIDescriptor { 538263508Sdimpublic: 539263508Sdim explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {} 540239310Sdim 541263508Sdim DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); } 542263508Sdim StringRef getName() const { return getStringField(2); } 543263508Sdim DITypeRef getType() const { return getFieldAs<DITypeRef>(3); } 544263508Sdim StringRef getFilename() const { return getFieldAs<DIFile>(4).getFilename(); } 545263508Sdim StringRef getDirectory() const { 546263508Sdim return getFieldAs<DIFile>(4).getDirectory(); 547263508Sdim } 548263508Sdim unsigned getLineNumber() const { return getUnsignedField(5); } 549263508Sdim unsigned getColumnNumber() const { return getUnsignedField(6); } 550263508Sdim bool Verify() const; 551263508Sdim}; 552239310Sdim 553263508Sdim/// DITemplateValueParameter - This is a wrapper for template value parameter. 554263508Sdimclass DITemplateValueParameter : public DIDescriptor { 555263508Sdimpublic: 556263508Sdim explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {} 557239310Sdim 558263508Sdim DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); } 559263508Sdim StringRef getName() const { return getStringField(2); } 560263508Sdim DITypeRef getType() const { return getFieldAs<DITypeRef>(3); } 561263508Sdim Value *getValue() const; 562263508Sdim StringRef getFilename() const { return getFieldAs<DIFile>(5).getFilename(); } 563263508Sdim StringRef getDirectory() const { 564263508Sdim return getFieldAs<DIFile>(5).getDirectory(); 565263508Sdim } 566263508Sdim unsigned getLineNumber() const { return getUnsignedField(6); } 567263508Sdim unsigned getColumnNumber() const { return getUnsignedField(7); } 568263508Sdim bool Verify() const; 569263508Sdim}; 570251662Sdim 571263508Sdim/// DIGlobalVariable - This is a wrapper for a global variable. 572263508Sdimclass DIGlobalVariable : public DIDescriptor { 573263508Sdim friend class DIDescriptor; 574263508Sdim void printInternal(raw_ostream &OS) const; 575239310Sdim 576263508Sdimpublic: 577263508Sdim explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {} 578239310Sdim 579263508Sdim DIScope getContext() const { return getFieldAs<DIScope>(2); } 580263508Sdim StringRef getName() const { return getStringField(3); } 581263508Sdim StringRef getDisplayName() const { return getStringField(4); } 582263508Sdim StringRef getLinkageName() const { return getStringField(5); } 583263508Sdim StringRef getFilename() const { return getFieldAs<DIFile>(6).getFilename(); } 584263508Sdim StringRef getDirectory() const { 585263508Sdim return getFieldAs<DIFile>(6).getDirectory(); 586263508Sdim } 587239310Sdim 588263508Sdim unsigned getLineNumber() const { return getUnsignedField(7); } 589263508Sdim DIType getType() const { return getFieldAs<DIType>(8); } 590263508Sdim unsigned isLocalToUnit() const { return getUnsignedField(9); } 591263508Sdim unsigned isDefinition() const { return getUnsignedField(10); } 592239310Sdim 593263508Sdim GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } 594263508Sdim Constant *getConstant() const { return getConstantField(11); } 595263508Sdim DIDerivedType getStaticDataMemberDeclaration() const { 596263508Sdim return getFieldAs<DIDerivedType>(12); 597263508Sdim } 598239310Sdim 599263508Sdim /// Verify - Verify that a global variable descriptor is well formed. 600263508Sdim bool Verify() const; 601263508Sdim}; 602239310Sdim 603263508Sdim/// DIVariable - This is a wrapper for a variable (e.g. parameter, local, 604263508Sdim/// global etc). 605263508Sdimclass DIVariable : public DIDescriptor { 606263508Sdim friend class DIDescriptor; 607263508Sdim void printInternal(raw_ostream &OS) const; 608239310Sdim 609263508Sdimpublic: 610263508Sdim explicit DIVariable(const MDNode *N = 0) : DIDescriptor(N) {} 611239310Sdim 612263508Sdim DIScope getContext() const { return getFieldAs<DIScope>(1); } 613263508Sdim StringRef getName() const { return getStringField(2); } 614263508Sdim DIFile getFile() const { return getFieldAs<DIFile>(3); } 615263508Sdim unsigned getLineNumber() const { return (getUnsignedField(4) << 8) >> 8; } 616263508Sdim unsigned getArgNumber() const { 617263508Sdim unsigned L = getUnsignedField(4); 618263508Sdim return L >> 24; 619263508Sdim } 620263508Sdim DIType getType() const { return getFieldAs<DIType>(5); } 621239310Sdim 622263508Sdim /// isArtificial - Return true if this variable is marked as "artificial". 623263508Sdim bool isArtificial() const { 624263508Sdim return (getUnsignedField(6) & FlagArtificial) != 0; 625263508Sdim } 626239310Sdim 627263508Sdim bool isObjectPointer() const { 628263508Sdim return (getUnsignedField(6) & FlagObjectPointer) != 0; 629263508Sdim } 630239310Sdim 631263508Sdim /// \brief Return true if this variable is represented as a pointer. 632263508Sdim bool isIndirect() const { 633263508Sdim return (getUnsignedField(6) & FlagIndirectVariable) != 0; 634263508Sdim } 635239310Sdim 636263508Sdim /// getInlinedAt - If this variable is inlined then return inline location. 637263508Sdim MDNode *getInlinedAt() const; 638239310Sdim 639263508Sdim /// Verify - Verify that a variable descriptor is well formed. 640263508Sdim bool Verify() const; 641239310Sdim 642263508Sdim /// HasComplexAddr - Return true if the variable has a complex address. 643263508Sdim bool hasComplexAddress() const { return getNumAddrElements() > 0; } 644239310Sdim 645263508Sdim unsigned getNumAddrElements() const; 646239310Sdim 647263508Sdim uint64_t getAddrElement(unsigned Idx) const { 648263508Sdim return getUInt64Field(Idx + 8); 649263508Sdim } 650239310Sdim 651263508Sdim /// isBlockByrefVariable - Return true if the variable was declared as 652263508Sdim /// a "__block" variable (Apple Blocks). 653263508Sdim bool isBlockByrefVariable() const { return getType().isBlockByrefStruct(); } 654239310Sdim 655263508Sdim /// isInlinedFnArgument - Return true if this variable provides debugging 656263508Sdim /// information for an inlined function arguments. 657263508Sdim bool isInlinedFnArgument(const Function *CurFn); 658239310Sdim 659263508Sdim void printExtendedName(raw_ostream &OS) const; 660263508Sdim}; 661263508Sdim 662263508Sdim/// DILocation - This object holds location information. This object 663263508Sdim/// is not associated with any DWARF tag. 664263508Sdimclass DILocation : public DIDescriptor { 665263508Sdimpublic: 666263508Sdim explicit DILocation(const MDNode *N) : DIDescriptor(N) {} 667263508Sdim 668263508Sdim unsigned getLineNumber() const { return getUnsignedField(0); } 669263508Sdim unsigned getColumnNumber() const { return getUnsignedField(1); } 670263508Sdim DIScope getScope() const { return getFieldAs<DIScope>(2); } 671263508Sdim DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); } 672263508Sdim StringRef getFilename() const { return getScope().getFilename(); } 673263508Sdim StringRef getDirectory() const { return getScope().getDirectory(); } 674263508Sdim bool Verify() const; 675263508Sdim}; 676263508Sdim 677263508Sdimclass DIObjCProperty : public DIDescriptor { 678263508Sdim friend class DIDescriptor; 679263508Sdim void printInternal(raw_ostream &OS) const; 680263508Sdim 681263508Sdimpublic: 682263508Sdim explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) {} 683263508Sdim 684263508Sdim StringRef getObjCPropertyName() const { return getStringField(1); } 685263508Sdim DIFile getFile() const { return getFieldAs<DIFile>(2); } 686263508Sdim unsigned getLineNumber() const { return getUnsignedField(3); } 687263508Sdim 688263508Sdim StringRef getObjCPropertyGetterName() const { return getStringField(4); } 689263508Sdim StringRef getObjCPropertySetterName() const { return getStringField(5); } 690263508Sdim bool isReadOnlyObjCProperty() const { 691263508Sdim return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; 692263508Sdim } 693263508Sdim bool isReadWriteObjCProperty() const { 694263508Sdim return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; 695263508Sdim } 696263508Sdim bool isAssignObjCProperty() const { 697263508Sdim return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0; 698263508Sdim } 699263508Sdim bool isRetainObjCProperty() const { 700263508Sdim return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0; 701263508Sdim } 702263508Sdim bool isCopyObjCProperty() const { 703263508Sdim return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0; 704263508Sdim } 705263508Sdim bool isNonAtomicObjCProperty() const { 706263508Sdim return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; 707263508Sdim } 708263508Sdim 709263508Sdim DIType getType() const { return getFieldAs<DIType>(7); } 710263508Sdim 711263508Sdim /// Verify - Verify that a derived type descriptor is well formed. 712263508Sdim bool Verify() const; 713263508Sdim}; 714263508Sdim 715263508Sdim/// \brief An imported module (C++ using directive or similar). 716263508Sdimclass DIImportedEntity : public DIDescriptor { 717263508Sdim friend class DIDescriptor; 718263508Sdim void printInternal(raw_ostream &OS) const; 719263508Sdim 720263508Sdimpublic: 721263508Sdim explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {} 722263508Sdim DIScope getContext() const { return getFieldAs<DIScope>(1); } 723263508Sdim DIDescriptor getEntity() const { return getFieldAs<DIDescriptor>(2); } 724263508Sdim unsigned getLineNumber() const { return getUnsignedField(3); } 725263508Sdim StringRef getName() const { return getStringField(4); } 726263508Sdim bool Verify() const; 727263508Sdim}; 728263508Sdim 729263508Sdim/// getDISubprogram - Find subprogram that is enclosing this scope. 730263508SdimDISubprogram getDISubprogram(const MDNode *Scope); 731263508Sdim 732263508Sdim/// getDICompositeType - Find underlying composite type. 733263508SdimDICompositeType getDICompositeType(DIType T); 734263508Sdim 735263508Sdim/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable 736263508Sdim/// to hold function specific information. 737263508SdimNamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP); 738263508Sdim 739263508Sdim/// getFnSpecificMDNode - Return a NameMDNode, if available, that is 740263508Sdim/// suitable to hold function specific information. 741263508SdimNamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP); 742263508Sdim 743263508Sdim/// createInlinedVariable - Create a new inlined variable based on current 744263508Sdim/// variable. 745263508Sdim/// @param DV Current Variable. 746263508Sdim/// @param InlinedScope Location at current variable is inlined. 747263508SdimDIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope, 748263508Sdim LLVMContext &VMContext); 749263508Sdim 750263508Sdim/// cleanseInlinedVariable - Remove inlined scope from the variable. 751263508SdimDIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext); 752263508Sdim 753263508Sdim/// Construct DITypeIdentifierMap by going through retained types of each CU. 754263508SdimDITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes); 755263508Sdim 756263508Sdim/// Strip debug info in the module if it exists. 757263508Sdim/// To do this, we remove all calls to the debugger intrinsics and any named 758263508Sdim/// metadata for debugging. We also remove debug locations for instructions. 759263508Sdim/// Return true if module is modified. 760263508Sdimbool StripDebugInfo(Module &M); 761263508Sdim 762263508Sdim/// Return Debug Info Metadata Version by checking module flags. 763263508Sdimunsigned getDebugMetadataVersionFromModule(const Module &M); 764263508Sdim 765263508Sdim/// DebugInfoFinder tries to list all debug info MDNodes used in a module. To 766263508Sdim/// list debug info MDNodes used by an instruction, DebugInfoFinder uses 767263508Sdim/// processDeclare, processValue and processLocation to handle DbgDeclareInst, 768263508Sdim/// DbgValueInst and DbgLoc attached to instructions. processModule will go 769263508Sdim/// through all DICompileUnits in llvm.dbg.cu and list debug info MDNodes 770263508Sdim/// used by the CUs. 771263508Sdimclass DebugInfoFinder { 772263508Sdimpublic: 773263508Sdim DebugInfoFinder() : TypeMapInitialized(false) {} 774263508Sdim 775263508Sdim /// processModule - Process entire module and collect debug info 776263508Sdim /// anchors. 777263508Sdim void processModule(const Module &M); 778263508Sdim 779263508Sdim /// processDeclare - Process DbgDeclareInst. 780263508Sdim void processDeclare(const Module &M, const DbgDeclareInst *DDI); 781263508Sdim /// Process DbgValueInst. 782263508Sdim void processValue(const Module &M, const DbgValueInst *DVI); 783263508Sdim /// processLocation - Process DILocation. 784263508Sdim void processLocation(const Module &M, DILocation Loc); 785263508Sdim 786263508Sdim /// Clear all lists. 787263508Sdim void reset(); 788263508Sdim 789263508Sdimprivate: 790263508Sdim /// Initialize TypeIdentifierMap. 791263508Sdim void InitializeTypeMap(const Module &M); 792263508Sdim 793263508Sdim /// processType - Process DIType. 794263508Sdim void processType(DIType DT); 795263508Sdim 796263508Sdim /// processLexicalBlock - Process DILexicalBlock. 797263508Sdim void processLexicalBlock(DILexicalBlock LB); 798263508Sdim 799263508Sdim /// processSubprogram - Process DISubprogram. 800263508Sdim void processSubprogram(DISubprogram SP); 801263508Sdim 802263508Sdim void processScope(DIScope Scope); 803263508Sdim 804263508Sdim /// addCompileUnit - Add compile unit into CUs. 805263508Sdim bool addCompileUnit(DICompileUnit CU); 806263508Sdim 807263508Sdim /// addGlobalVariable - Add global variable into GVs. 808263508Sdim bool addGlobalVariable(DIGlobalVariable DIG); 809263508Sdim 810263508Sdim // addSubprogram - Add subprogram into SPs. 811263508Sdim bool addSubprogram(DISubprogram SP); 812263508Sdim 813263508Sdim /// addType - Add type into Tys. 814263508Sdim bool addType(DIType DT); 815263508Sdim 816263508Sdim bool addScope(DIScope Scope); 817263508Sdim 818263508Sdimpublic: 819263508Sdim typedef SmallVectorImpl<MDNode *>::const_iterator iterator; 820263508Sdim iterator compile_unit_begin() const { return CUs.begin(); } 821263508Sdim iterator compile_unit_end() const { return CUs.end(); } 822263508Sdim iterator subprogram_begin() const { return SPs.begin(); } 823263508Sdim iterator subprogram_end() const { return SPs.end(); } 824263508Sdim iterator global_variable_begin() const { return GVs.begin(); } 825263508Sdim iterator global_variable_end() const { return GVs.end(); } 826263508Sdim iterator type_begin() const { return TYs.begin(); } 827263508Sdim iterator type_end() const { return TYs.end(); } 828263508Sdim iterator scope_begin() const { return Scopes.begin(); } 829263508Sdim iterator scope_end() const { return Scopes.end(); } 830263508Sdim 831263508Sdim unsigned compile_unit_count() const { return CUs.size(); } 832263508Sdim unsigned global_variable_count() const { return GVs.size(); } 833263508Sdim unsigned subprogram_count() const { return SPs.size(); } 834263508Sdim unsigned type_count() const { return TYs.size(); } 835263508Sdim unsigned scope_count() const { return Scopes.size(); } 836263508Sdim 837263508Sdimprivate: 838263508Sdim SmallVector<MDNode *, 8> CUs; // Compile Units 839263508Sdim SmallVector<MDNode *, 8> SPs; // Subprograms 840263508Sdim SmallVector<MDNode *, 8> GVs; // Global Variables; 841263508Sdim SmallVector<MDNode *, 8> TYs; // Types 842263508Sdim SmallVector<MDNode *, 8> Scopes; // Scopes 843263508Sdim SmallPtrSet<MDNode *, 64> NodesSeen; 844263508Sdim DITypeIdentifierMap TypeIdentifierMap; 845263508Sdim /// Specify if TypeIdentifierMap is initialized. 846263508Sdim bool TypeMapInitialized; 847263508Sdim}; 848239310Sdim} // end namespace llvm 849239310Sdim 850239310Sdim#endif 851