From: Bill Wendling Date: Thu, 28 Jun 2012 00:05:13 +0000 (+0000) Subject: Move lib/Analysis/DebugInfo.cpp to lib/VMCore/DebugInfo.cpp and X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0bcbd1df7a204e1e512f1a27066d725309de1b13;p=oota-llvm.git Move lib/Analysis/DebugInfo.cpp to lib/VMCore/DebugInfo.cpp and include/llvm/Analysis/DebugInfo.h to include/llvm/DebugInfo.h. The reasoning is because the DebugInfo module is simply an interface to the debug info MDNodes and has nothing to do with analysis. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159312 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h deleted file mode 100644 index 78c48917117..00000000000 --- a/include/llvm/Analysis/DebugInfo.h +++ /dev/null @@ -1,895 +0,0 @@ -//===--- llvm/Analysis/DebugInfo.h - Debug Information Helpers --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a bunch of datatypes that are useful for creating and -// walking debug info in LLVM IR form. They essentially provide wrappers around -// the information in the global variables that's needed when constructing the -// DWARF information. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ANALYSIS_DEBUGINFO_H -#define LLVM_ANALYSIS_DEBUGINFO_H - -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Dwarf.h" - -namespace llvm { - class BasicBlock; - class Constant; - class Function; - class GlobalVariable; - class Module; - class Type; - class Value; - class DbgDeclareInst; - class Instruction; - class MDNode; - class NamedMDNode; - class LLVMContext; - class raw_ostream; - - class DIFile; - class DISubprogram; - class DILexicalBlock; - class DILexicalBlockFile; - class DIVariable; - class DIType; - class DIObjCProperty; - - /// DIDescriptor - A thin wraper around MDNode to access encoded debug info. - /// This should not be stored in a container, because the underlying MDNode - /// may change in certain situations. - class DIDescriptor { - public: - enum { - FlagPrivate = 1 << 0, - FlagProtected = 1 << 1, - FlagFwdDecl = 1 << 2, - FlagAppleBlock = 1 << 3, - FlagBlockByrefStruct = 1 << 4, - FlagVirtual = 1 << 5, - FlagArtificial = 1 << 6, - FlagExplicit = 1 << 7, - FlagPrototyped = 1 << 8, - FlagObjcClassComplete = 1 << 9 - }; - protected: - const MDNode *DbgNode; - - StringRef getStringField(unsigned Elt) const; - unsigned getUnsignedField(unsigned Elt) const { - return (unsigned)getUInt64Field(Elt); - } - uint64_t getUInt64Field(unsigned Elt) const; - DIDescriptor getDescriptorField(unsigned Elt) const; - - template - DescTy getFieldAs(unsigned Elt) const { - return DescTy(getDescriptorField(Elt)); - } - - GlobalVariable *getGlobalVariableField(unsigned Elt) const; - Constant *getConstantField(unsigned Elt) const; - Function *getFunctionField(unsigned Elt) const; - - public: - explicit DIDescriptor() : DbgNode(0) {} - explicit DIDescriptor(const MDNode *N) : DbgNode(N) {} - explicit DIDescriptor(const DIFile F); - explicit DIDescriptor(const DISubprogram F); - explicit DIDescriptor(const DILexicalBlockFile F); - explicit DIDescriptor(const DILexicalBlock F); - explicit DIDescriptor(const DIVariable F); - explicit DIDescriptor(const DIType F); - - bool Verify() const { return DbgNode != 0; } - - operator MDNode *() const { return const_cast(DbgNode); } - MDNode *operator ->() const { return const_cast(DbgNode); } - - unsigned getVersion() const { - return getUnsignedField(0) & LLVMDebugVersionMask; - } - - unsigned getTag() const { - return getUnsignedField(0) & ~LLVMDebugVersionMask; - } - - bool isDerivedType() const; - bool isCompositeType() const; - bool isBasicType() const; - bool isVariable() const; - bool isSubprogram() const; - bool isGlobalVariable() const; - bool isScope() const; - bool isFile() const; - bool isCompileUnit() const; - bool isNameSpace() const; - bool isLexicalBlockFile() const; - bool isLexicalBlock() const; - bool isSubrange() const; - bool isEnumerator() const; - bool isType() const; - bool isGlobal() const; - bool isUnspecifiedParameter() const; - bool isTemplateTypeParameter() const; - bool isTemplateValueParameter() const; - bool isObjCProperty() const; - - /// print - print descriptor. - void print(raw_ostream &OS) const; - - /// dump - print descriptor to dbgs() with a newline. - void dump() const; - }; - - /// DISubrange - This is used to represent ranges, for array bounds. - class DISubrange : public DIDescriptor { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: - explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {} - - uint64_t getLo() const { return getUInt64Field(1); } - uint64_t getHi() const { return getUInt64Field(2); } - }; - - /// DIArray - This descriptor holds an array of descriptors. - class DIArray : public DIDescriptor { - public: - explicit DIArray(const MDNode *N = 0) - : DIDescriptor(N) {} - - unsigned getNumElements() const; - DIDescriptor getElement(unsigned Idx) const { - return getDescriptorField(Idx); - } - }; - - /// DIScope - A base class for various scopes. - class DIScope : public DIDescriptor { - virtual void anchor(); - protected: - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: - explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {} - virtual ~DIScope() {} - - StringRef getFilename() const; - StringRef getDirectory() const; - }; - - /// DICompileUnit - A wrapper for a compile unit. - class DICompileUnit : public DIScope { - virtual void anchor(); - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: - explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {} - - unsigned getLanguage() const { return getUnsignedField(2); } - StringRef getFilename() const { return getStringField(3); } - StringRef getDirectory() const { return getStringField(4); } - StringRef getProducer() const { return getStringField(5); } - - /// isMain - Each input file is encoded as a separate compile unit in LLVM - /// debugging information output. However, many target specific tool chains - /// prefer to encode only one compile unit in an object file. In this - /// situation, the LLVM code generator will include debugging information - /// entities in the compile unit that is marked as main compile unit. The - /// code generator accepts maximum one main compile unit per module. If a - /// module does not contain any main compile unit then the code generator - /// will emit multiple compile units in the output object file. - - bool isMain() const { return getUnsignedField(6) != 0; } - bool isOptimized() const { return getUnsignedField(7) != 0; } - StringRef getFlags() const { return getStringField(8); } - unsigned getRunTimeVersion() const { return getUnsignedField(9); } - - DIArray getEnumTypes() const; - DIArray getRetainedTypes() const; - DIArray getSubprograms() const; - DIArray getGlobalVariables() const; - - /// Verify - Verify that a compile unit is well formed. - bool Verify() const; - }; - - /// DIFile - This is a wrapper for a file. - class DIFile : public DIScope { - virtual void anchor(); - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const {} // FIXME: Output something? - public: - explicit DIFile(const MDNode *N = 0) : DIScope(N) { - if (DbgNode && !isFile()) - DbgNode = 0; - } - StringRef getFilename() const { return getStringField(1); } - StringRef getDirectory() const { return getStringField(2); } - DICompileUnit getCompileUnit() const{ - assert (getVersion() <= LLVMDebugVersion10 && "Invalid CompileUnit!"); - return getFieldAs(3); - } - }; - - /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). - /// FIXME: it seems strange that this doesn't have either a reference to the - /// type/precision or a file/line pair for location info. - class DIEnumerator : public DIDescriptor { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: - explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {} - - StringRef getName() const { return getStringField(1); } - uint64_t getEnumValue() const { return getUInt64Field(2); } - }; - - /// DIType - This is a wrapper for a type. - /// FIXME: Types should be factored much better so that CV qualifiers and - /// others do not require a huge and empty descriptor full of zeros. - class DIType : public DIScope { - virtual void anchor(); - protected: - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - // This ctor is used when the Tag has already been validated by a derived - // ctor. - DIType(const MDNode *N, bool, bool) : DIScope(N) {} - public: - /// Verify - Verify that a type descriptor is well formed. - bool Verify() const; - explicit DIType(const MDNode *N); - explicit DIType() {} - virtual ~DIType() {} - - DIScope getContext() const { return getFieldAs(1); } - StringRef getName() const { return getStringField(2); } - DICompileUnit getCompileUnit() const{ - assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); - if (getVersion() == llvm::LLVMDebugVersion7) - return getFieldAs(3); - - return getFieldAs(3).getCompileUnit(); - } - DIFile getFile() const { return getFieldAs(3); } - unsigned getLineNumber() const { return getUnsignedField(4); } - uint64_t getSizeInBits() const { return getUInt64Field(5); } - uint64_t getAlignInBits() const { return getUInt64Field(6); } - // FIXME: Offset is only used for DW_TAG_member nodes. Making every type - // carry this is just plain insane. - uint64_t getOffsetInBits() const { return getUInt64Field(7); } - unsigned getFlags() const { return getUnsignedField(8); } - bool isPrivate() const { - return (getFlags() & FlagPrivate) != 0; - } - bool isProtected() const { - return (getFlags() & FlagProtected) != 0; - } - bool isForwardDecl() const { - return (getFlags() & FlagFwdDecl) != 0; - } - // isAppleBlock - Return true if this is the Apple Blocks extension. - bool isAppleBlockExtension() const { - return (getFlags() & FlagAppleBlock) != 0; - } - bool isBlockByrefStruct() const { - return (getFlags() & FlagBlockByrefStruct) != 0; - } - bool isVirtual() const { - return (getFlags() & FlagVirtual) != 0; - } - bool isArtificial() const { - return (getFlags() & FlagArtificial) != 0; - } - bool isObjcClassComplete() const { - return (getFlags() & FlagObjcClassComplete) != 0; - } - bool isValid() const { - return DbgNode && (isBasicType() || isDerivedType() || isCompositeType()); - } - StringRef getDirectory() const { - if (getVersion() == llvm::LLVMDebugVersion7) - return getCompileUnit().getDirectory(); - - return getFieldAs(3).getDirectory(); - } - StringRef getFilename() const { - if (getVersion() == llvm::LLVMDebugVersion7) - return getCompileUnit().getFilename(); - - return getFieldAs(3).getFilename(); - } - - /// isUnsignedDIType - Return true if type encoding is unsigned. - bool isUnsignedDIType(); - - /// replaceAllUsesWith - Replace all uses of debug info referenced by - /// this descriptor. - void replaceAllUsesWith(DIDescriptor &D); - void replaceAllUsesWith(MDNode *D); - }; - - /// DIBasicType - A basic type, like 'int' or 'float'. - class DIBasicType : public DIType { - virtual void anchor(); - public: - explicit DIBasicType(const MDNode *N = 0) : DIType(N) {} - - unsigned getEncoding() const { return getUnsignedField(9); } - - /// Verify - Verify that a basic type descriptor is well formed. - bool Verify() const; - }; - - /// DIDerivedType - A simple derived type, like a const qualified type, - /// a typedef, a pointer or reference, etc. - class DIDerivedType : public DIType { - virtual void anchor(); - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - protected: - explicit DIDerivedType(const MDNode *N, bool, bool) - : DIType(N, true, true) {} - public: - explicit DIDerivedType(const MDNode *N = 0) - : DIType(N, true, true) {} - - DIType getTypeDerivedFrom() const { return getFieldAs(9); } - - /// getOriginalTypeSize - If this type is derived from a base type then - /// return base type size. - uint64_t getOriginalTypeSize() const; - - /// getObjCProperty - Return property node, if this ivar is - /// associated with one. - MDNode *getObjCProperty() const; - - StringRef getObjCPropertyName() const { - if (getVersion() > LLVMDebugVersion11) - return StringRef(); - return getStringField(10); - } - StringRef getObjCPropertyGetterName() const { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return getStringField(11); - } - StringRef getObjCPropertySetterName() const { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return getStringField(12); - } - bool isReadOnlyObjCProperty() { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; - } - bool isReadWriteObjCProperty() { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; - } - bool isAssignObjCProperty() { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_assign) != 0; - } - bool isRetainObjCProperty() { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_retain) != 0; - } - bool isCopyObjCProperty() { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_copy) != 0; - } - bool isNonAtomicObjCProperty() { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; - } - - /// Verify - Verify that a derived type descriptor is well formed. - bool Verify() const; - }; - - /// DICompositeType - This descriptor holds a type that can refer to multiple - /// other types, like a function or struct. - /// FIXME: Why is this a DIDerivedType?? - class DICompositeType : public DIDerivedType { - virtual void anchor(); - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: - explicit DICompositeType(const MDNode *N = 0) - : DIDerivedType(N, true, true) { - if (N && !isCompositeType()) - DbgNode = 0; - } - - DIArray getTypeArray() const { return getFieldAs(10); } - unsigned getRunTimeLang() const { return getUnsignedField(11); } - DICompositeType getContainingType() const { - return getFieldAs(12); - } - DIArray getTemplateParams() const { return getFieldAs(13); } - - /// Verify - Verify that a composite type descriptor is well formed. - bool Verify() const; - }; - - /// DITemplateTypeParameter - This is a wrapper for template type parameter. - class DITemplateTypeParameter : public DIDescriptor { - public: - explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {} - - DIScope getContext() const { return getFieldAs(1); } - StringRef getName() const { return getStringField(2); } - DIType getType() const { return getFieldAs(3); } - StringRef getFilename() const { - return getFieldAs(4).getFilename(); - } - StringRef getDirectory() const { - return getFieldAs(4).getDirectory(); - } - unsigned getLineNumber() const { return getUnsignedField(5); } - unsigned getColumnNumber() const { return getUnsignedField(6); } - }; - - /// DITemplateValueParameter - This is a wrapper for template value parameter. - class DITemplateValueParameter : public DIDescriptor { - public: - explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {} - - DIScope getContext() const { return getFieldAs(1); } - StringRef getName() const { return getStringField(2); } - DIType getType() const { return getFieldAs(3); } - uint64_t getValue() const { return getUInt64Field(4); } - StringRef getFilename() const { - return getFieldAs(5).getFilename(); - } - StringRef getDirectory() const { - return getFieldAs(5).getDirectory(); - } - unsigned getLineNumber() const { return getUnsignedField(6); } - unsigned getColumnNumber() const { return getUnsignedField(7); } - }; - - /// DISubprogram - This is a wrapper for a subprogram (e.g. a function). - class DISubprogram : public DIScope { - virtual void anchor(); - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: - explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {} - - DIScope getContext() const { return getFieldAs(2); } - StringRef getName() const { return getStringField(3); } - StringRef getDisplayName() const { return getStringField(4); } - StringRef getLinkageName() const { return getStringField(5); } - DICompileUnit getCompileUnit() const{ - assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); - if (getVersion() == llvm::LLVMDebugVersion7) - return getFieldAs(6); - - return getFieldAs(6).getCompileUnit(); - } - unsigned getLineNumber() const { return getUnsignedField(7); } - DICompositeType getType() const { return getFieldAs(8); } - - /// getReturnTypeName - Subprogram return types are encoded either as - /// DIType or as DICompositeType. - StringRef getReturnTypeName() const { - DICompositeType DCT(getFieldAs(8)); - if (DCT.Verify()) { - DIArray A = DCT.getTypeArray(); - DIType T(A.getElement(0)); - return T.getName(); - } - DIType T(getFieldAs(8)); - return T.getName(); - } - - /// isLocalToUnit - Return true if this subprogram is local to the current - /// compile unit, like 'static' in C. - unsigned isLocalToUnit() const { return getUnsignedField(9); } - unsigned isDefinition() const { return getUnsignedField(10); } - - unsigned getVirtuality() const { return getUnsignedField(11); } - unsigned getVirtualIndex() const { return getUnsignedField(12); } - - DICompositeType getContainingType() const { - return getFieldAs(13); - } - - unsigned isArtificial() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return getUnsignedField(14); - return (getUnsignedField(14) & FlagArtificial) != 0; - } - /// isPrivate - Return true if this subprogram has "private" - /// access specifier. - bool isPrivate() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return false; - return (getUnsignedField(14) & FlagPrivate) != 0; - } - /// isProtected - Return true if this subprogram has "protected" - /// access specifier. - bool isProtected() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return false; - return (getUnsignedField(14) & FlagProtected) != 0; - } - /// isExplicit - Return true if this subprogram is marked as explicit. - bool isExplicit() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return false; - return (getUnsignedField(14) & FlagExplicit) != 0; - } - /// isPrototyped - Return true if this subprogram is prototyped. - bool isPrototyped() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return false; - return (getUnsignedField(14) & FlagPrototyped) != 0; - } - - unsigned isOptimized() const; - - StringRef getFilename() const { - if (getVersion() == llvm::LLVMDebugVersion7) - return getCompileUnit().getFilename(); - - return getFieldAs(6).getFilename(); - } - - StringRef getDirectory() const { - if (getVersion() == llvm::LLVMDebugVersion7) - return getCompileUnit().getFilename(); - - return getFieldAs(6).getDirectory(); - } - - /// getScopeLineNumber - Get the beginning of the scope of the - /// function, not necessarily where the name of the program - /// starts. - unsigned getScopeLineNumber() const { return getUnsignedField(20); } - - /// Verify - Verify that a subprogram descriptor is well formed. - bool Verify() const; - - /// describes - Return true if this subprogram provides debugging - /// information for the function F. - bool describes(const Function *F); - - Function *getFunction() const { return getFunctionField(16); } - DIArray getTemplateParams() const { return getFieldAs(17); } - DISubprogram getFunctionDeclaration() const { - return getFieldAs(18); - } - MDNode *getVariablesNodes() const; - DIArray getVariables() const; - }; - - /// DIGlobalVariable - This is a wrapper for a global variable. - class DIGlobalVariable : public DIDescriptor { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: - explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {} - - DIScope getContext() const { return getFieldAs(2); } - StringRef getName() const { return getStringField(3); } - StringRef getDisplayName() const { return getStringField(4); } - StringRef getLinkageName() const { return getStringField(5); } - DICompileUnit getCompileUnit() const{ - assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); - if (getVersion() == llvm::LLVMDebugVersion7) - return getFieldAs(6); - - DIFile F = getFieldAs(6); - return F.getCompileUnit(); - } - StringRef getFilename() const { - if (getVersion() <= llvm::LLVMDebugVersion10) - return getContext().getFilename(); - return getFieldAs(6).getFilename(); - } - StringRef getDirectory() const { - if (getVersion() <= llvm::LLVMDebugVersion10) - return getContext().getDirectory(); - return getFieldAs(6).getDirectory(); - - } - - unsigned getLineNumber() const { return getUnsignedField(7); } - DIType getType() const { return getFieldAs(8); } - unsigned isLocalToUnit() const { return getUnsignedField(9); } - unsigned isDefinition() const { return getUnsignedField(10); } - - GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } - Constant *getConstant() const { return getConstantField(11); } - - /// Verify - Verify that a global variable descriptor is well formed. - bool Verify() const; - }; - - /// DIVariable - This is a wrapper for a variable (e.g. parameter, local, - /// global etc). - class DIVariable : public DIDescriptor { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: - explicit DIVariable(const MDNode *N = 0) - : DIDescriptor(N) {} - - DIScope getContext() const { return getFieldAs(1); } - StringRef getName() const { return getStringField(2); } - DICompileUnit getCompileUnit() const { - assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); - if (getVersion() == llvm::LLVMDebugVersion7) - return getFieldAs(3); - - DIFile F = getFieldAs(3); - return F.getCompileUnit(); - } - unsigned getLineNumber() const { - return (getUnsignedField(4) << 8) >> 8; - } - unsigned getArgNumber() const { - unsigned L = getUnsignedField(4); - return L >> 24; - } - DIType getType() const { return getFieldAs(5); } - - /// isArtificial - Return true if this variable is marked as "artificial". - bool isArtificial() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return false; - return (getUnsignedField(6) & FlagArtificial) != 0; - } - - /// getInlinedAt - If this variable is inlined then return inline location. - MDNode *getInlinedAt() const; - - /// Verify - Verify that a variable descriptor is well formed. - bool Verify() const; - - /// HasComplexAddr - Return true if the variable has a complex address. - bool hasComplexAddress() const { - return getNumAddrElements() > 0; - } - - unsigned getNumAddrElements() const; - - uint64_t getAddrElement(unsigned Idx) const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return getUInt64Field(Idx+6); - if (getVersion() == llvm::LLVMDebugVersion9) - return getUInt64Field(Idx+7); - return getUInt64Field(Idx+8); - } - - /// isBlockByrefVariable - Return true if the variable was declared as - /// a "__block" variable (Apple Blocks). - bool isBlockByrefVariable() const { - return getType().isBlockByrefStruct(); - } - - /// isInlinedFnArgument - Return trule if this variable provides debugging - /// information for an inlined function arguments. - bool isInlinedFnArgument(const Function *CurFn); - - void printExtendedName(raw_ostream &OS) const; - }; - - /// DILexicalBlock - This is a wrapper for a lexical block. - class DILexicalBlock : public DIScope { - virtual void anchor(); - public: - explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {} - DIScope getContext() const { return getFieldAs(1); } - unsigned getLineNumber() const { return getUnsignedField(2); } - unsigned getColumnNumber() const { return getUnsignedField(3); } - StringRef getDirectory() const { - StringRef dir = getFieldAs(4).getDirectory(); - return !dir.empty() ? dir : getContext().getDirectory(); - } - StringRef getFilename() const { - StringRef filename = getFieldAs(4).getFilename(); - return !filename.empty() ? filename : getContext().getFilename(); - } - }; - - /// DILexicalBlockFile - This is a wrapper for a lexical block with - /// a filename change. - class DILexicalBlockFile : public DIScope { - virtual void anchor(); - public: - explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {} - DIScope getContext() const { return getScope().getContext(); } - unsigned getLineNumber() const { return getScope().getLineNumber(); } - unsigned getColumnNumber() const { return getScope().getColumnNumber(); } - StringRef getDirectory() const { - StringRef dir = getFieldAs(2).getDirectory(); - return !dir.empty() ? dir : getContext().getDirectory(); - } - StringRef getFilename() const { - StringRef filename = getFieldAs(2).getFilename(); - assert(!filename.empty() && "Why'd you create this then?"); - return filename; - } - DILexicalBlock getScope() const { return getFieldAs(1); } - }; - - /// DINameSpace - A wrapper for a C++ style name space. - class DINameSpace : public DIScope { - virtual void anchor(); - public: - explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {} - DIScope getContext() const { return getFieldAs(1); } - StringRef getName() const { return getStringField(2); } - StringRef getDirectory() const { - return getFieldAs(3).getDirectory(); - } - StringRef getFilename() const { - return getFieldAs(3).getFilename(); - } - DICompileUnit getCompileUnit() const{ - assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); - if (getVersion() == llvm::LLVMDebugVersion7) - return getFieldAs(3); - - return getFieldAs(3).getCompileUnit(); - } - unsigned getLineNumber() const { return getUnsignedField(4); } - bool Verify() const; - }; - - /// DILocation - This object holds location information. This object - /// is not associated with any DWARF tag. - class DILocation : public DIDescriptor { - public: - explicit DILocation(const MDNode *N) : DIDescriptor(N) { } - - unsigned getLineNumber() const { return getUnsignedField(0); } - unsigned getColumnNumber() const { return getUnsignedField(1); } - DIScope getScope() const { return getFieldAs(2); } - DILocation getOrigLocation() const { return getFieldAs(3); } - StringRef getFilename() const { return getScope().getFilename(); } - StringRef getDirectory() const { return getScope().getDirectory(); } - bool Verify() const; - }; - - class DIObjCProperty : public DIDescriptor { - public: - explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) { } - - StringRef getObjCPropertyName() const { return getStringField(1); } - DIFile getFile() const { return getFieldAs(2); } - unsigned getLineNumber() const { return getUnsignedField(3); } - - StringRef getObjCPropertyGetterName() const { - return getStringField(4); - } - StringRef getObjCPropertySetterName() const { - return getStringField(5); - } - bool isReadOnlyObjCProperty() { - return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; - } - bool isReadWriteObjCProperty() { - return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; - } - bool isAssignObjCProperty() { - return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0; - } - bool isRetainObjCProperty() { - return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0; - } - bool isCopyObjCProperty() { - return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0; - } - bool isNonAtomicObjCProperty() { - return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; - } - - DIType getType() const { return getFieldAs(7); } - - /// Verify - Verify that a derived type descriptor is well formed. - bool Verify() const; - }; - - /// getDISubprogram - Find subprogram that is enclosing this scope. - DISubprogram getDISubprogram(const MDNode *Scope); - - /// getDICompositeType - Find underlying composite type. - DICompositeType getDICompositeType(DIType T); - - /// isSubprogramContext - Return true if Context is either a subprogram - /// or another context nested inside a subprogram. - bool isSubprogramContext(const MDNode *Context); - - /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable - /// to hold function specific information. - NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP); - - /// getFnSpecificMDNode - Return a NameMDNode, if available, that is - /// suitable to hold function specific information. - NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP); - - /// createInlinedVariable - Create a new inlined variable based on current - /// variable. - /// @param DV Current Variable. - /// @param InlinedScope Location at current variable is inlined. - DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope, - LLVMContext &VMContext); - - /// cleanseInlinedVariable - Remove inlined scope from the variable. - DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext); - - class DebugInfoFinder { - public: - /// processModule - Process entire module and collect debug info - /// anchors. - void processModule(Module &M); - - private: - /// processType - Process DIType. - void processType(DIType DT); - - /// processLexicalBlock - Process DILexicalBlock. - void processLexicalBlock(DILexicalBlock LB); - - /// processSubprogram - Process DISubprogram. - void processSubprogram(DISubprogram SP); - - /// processDeclare - Process DbgDeclareInst. - void processDeclare(DbgDeclareInst *DDI); - - /// processLocation - Process DILocation. - void processLocation(DILocation Loc); - - /// addCompileUnit - Add compile unit into CUs. - bool addCompileUnit(DICompileUnit CU); - - /// addGlobalVariable - Add global variable into GVs. - bool addGlobalVariable(DIGlobalVariable DIG); - - // addSubprogram - Add subprogram into SPs. - bool addSubprogram(DISubprogram SP); - - /// addType - Add type into Tys. - bool addType(DIType DT); - - public: - typedef SmallVector::const_iterator iterator; - iterator compile_unit_begin() const { return CUs.begin(); } - iterator compile_unit_end() const { return CUs.end(); } - iterator subprogram_begin() const { return SPs.begin(); } - iterator subprogram_end() const { return SPs.end(); } - iterator global_variable_begin() const { return GVs.begin(); } - iterator global_variable_end() const { return GVs.end(); } - iterator type_begin() const { return TYs.begin(); } - iterator type_end() const { return TYs.end(); } - - unsigned compile_unit_count() const { return CUs.size(); } - unsigned global_variable_count() const { return GVs.size(); } - unsigned subprogram_count() const { return SPs.size(); } - unsigned type_count() const { return TYs.size(); } - - private: - SmallVector CUs; // Compile Units - SmallVector SPs; // Subprograms - SmallVector GVs; // Global Variables; - SmallVector TYs; // Types - SmallPtrSet NodesSeen; - }; -} // end namespace llvm - -#endif diff --git a/include/llvm/DebugInfo.h b/include/llvm/DebugInfo.h new file mode 100644 index 00000000000..78c48917117 --- /dev/null +++ b/include/llvm/DebugInfo.h @@ -0,0 +1,895 @@ +//===--- llvm/Analysis/DebugInfo.h - Debug Information Helpers --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines a bunch of datatypes that are useful for creating and +// walking debug info in LLVM IR form. They essentially provide wrappers around +// the information in the global variables that's needed when constructing the +// DWARF information. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_DEBUGINFO_H +#define LLVM_ANALYSIS_DEBUGINFO_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Dwarf.h" + +namespace llvm { + class BasicBlock; + class Constant; + class Function; + class GlobalVariable; + class Module; + class Type; + class Value; + class DbgDeclareInst; + class Instruction; + class MDNode; + class NamedMDNode; + class LLVMContext; + class raw_ostream; + + class DIFile; + class DISubprogram; + class DILexicalBlock; + class DILexicalBlockFile; + class DIVariable; + class DIType; + class DIObjCProperty; + + /// DIDescriptor - A thin wraper around MDNode to access encoded debug info. + /// This should not be stored in a container, because the underlying MDNode + /// may change in certain situations. + class DIDescriptor { + public: + enum { + FlagPrivate = 1 << 0, + FlagProtected = 1 << 1, + FlagFwdDecl = 1 << 2, + FlagAppleBlock = 1 << 3, + FlagBlockByrefStruct = 1 << 4, + FlagVirtual = 1 << 5, + FlagArtificial = 1 << 6, + FlagExplicit = 1 << 7, + FlagPrototyped = 1 << 8, + FlagObjcClassComplete = 1 << 9 + }; + protected: + const MDNode *DbgNode; + + StringRef getStringField(unsigned Elt) const; + unsigned getUnsignedField(unsigned Elt) const { + return (unsigned)getUInt64Field(Elt); + } + uint64_t getUInt64Field(unsigned Elt) const; + DIDescriptor getDescriptorField(unsigned Elt) const; + + template + DescTy getFieldAs(unsigned Elt) const { + return DescTy(getDescriptorField(Elt)); + } + + GlobalVariable *getGlobalVariableField(unsigned Elt) const; + Constant *getConstantField(unsigned Elt) const; + Function *getFunctionField(unsigned Elt) const; + + public: + explicit DIDescriptor() : DbgNode(0) {} + explicit DIDescriptor(const MDNode *N) : DbgNode(N) {} + explicit DIDescriptor(const DIFile F); + explicit DIDescriptor(const DISubprogram F); + explicit DIDescriptor(const DILexicalBlockFile F); + explicit DIDescriptor(const DILexicalBlock F); + explicit DIDescriptor(const DIVariable F); + explicit DIDescriptor(const DIType F); + + bool Verify() const { return DbgNode != 0; } + + operator MDNode *() const { return const_cast(DbgNode); } + MDNode *operator ->() const { return const_cast(DbgNode); } + + unsigned getVersion() const { + return getUnsignedField(0) & LLVMDebugVersionMask; + } + + unsigned getTag() const { + return getUnsignedField(0) & ~LLVMDebugVersionMask; + } + + bool isDerivedType() const; + bool isCompositeType() const; + bool isBasicType() const; + bool isVariable() const; + bool isSubprogram() const; + bool isGlobalVariable() const; + bool isScope() const; + bool isFile() const; + bool isCompileUnit() const; + bool isNameSpace() const; + bool isLexicalBlockFile() const; + bool isLexicalBlock() const; + bool isSubrange() const; + bool isEnumerator() const; + bool isType() const; + bool isGlobal() const; + bool isUnspecifiedParameter() const; + bool isTemplateTypeParameter() const; + bool isTemplateValueParameter() const; + bool isObjCProperty() const; + + /// print - print descriptor. + void print(raw_ostream &OS) const; + + /// dump - print descriptor to dbgs() with a newline. + void dump() const; + }; + + /// DISubrange - This is used to represent ranges, for array bounds. + class DISubrange : public DIDescriptor { + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; + public: + explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {} + + uint64_t getLo() const { return getUInt64Field(1); } + uint64_t getHi() const { return getUInt64Field(2); } + }; + + /// DIArray - This descriptor holds an array of descriptors. + class DIArray : public DIDescriptor { + public: + explicit DIArray(const MDNode *N = 0) + : DIDescriptor(N) {} + + unsigned getNumElements() const; + DIDescriptor getElement(unsigned Idx) const { + return getDescriptorField(Idx); + } + }; + + /// DIScope - A base class for various scopes. + class DIScope : public DIDescriptor { + virtual void anchor(); + protected: + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; + public: + explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {} + virtual ~DIScope() {} + + StringRef getFilename() const; + StringRef getDirectory() const; + }; + + /// DICompileUnit - A wrapper for a compile unit. + class DICompileUnit : public DIScope { + virtual void anchor(); + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; + public: + explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {} + + unsigned getLanguage() const { return getUnsignedField(2); } + StringRef getFilename() const { return getStringField(3); } + StringRef getDirectory() const { return getStringField(4); } + StringRef getProducer() const { return getStringField(5); } + + /// isMain - Each input file is encoded as a separate compile unit in LLVM + /// debugging information output. However, many target specific tool chains + /// prefer to encode only one compile unit in an object file. In this + /// situation, the LLVM code generator will include debugging information + /// entities in the compile unit that is marked as main compile unit. The + /// code generator accepts maximum one main compile unit per module. If a + /// module does not contain any main compile unit then the code generator + /// will emit multiple compile units in the output object file. + + bool isMain() const { return getUnsignedField(6) != 0; } + bool isOptimized() const { return getUnsignedField(7) != 0; } + StringRef getFlags() const { return getStringField(8); } + unsigned getRunTimeVersion() const { return getUnsignedField(9); } + + DIArray getEnumTypes() const; + DIArray getRetainedTypes() const; + DIArray getSubprograms() const; + DIArray getGlobalVariables() const; + + /// Verify - Verify that a compile unit is well formed. + bool Verify() const; + }; + + /// DIFile - This is a wrapper for a file. + class DIFile : public DIScope { + virtual void anchor(); + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const {} // FIXME: Output something? + public: + explicit DIFile(const MDNode *N = 0) : DIScope(N) { + if (DbgNode && !isFile()) + DbgNode = 0; + } + StringRef getFilename() const { return getStringField(1); } + StringRef getDirectory() const { return getStringField(2); } + DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid CompileUnit!"); + return getFieldAs(3); + } + }; + + /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). + /// FIXME: it seems strange that this doesn't have either a reference to the + /// type/precision or a file/line pair for location info. + class DIEnumerator : public DIDescriptor { + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; + public: + explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {} + + StringRef getName() const { return getStringField(1); } + uint64_t getEnumValue() const { return getUInt64Field(2); } + }; + + /// DIType - This is a wrapper for a type. + /// FIXME: Types should be factored much better so that CV qualifiers and + /// others do not require a huge and empty descriptor full of zeros. + class DIType : public DIScope { + virtual void anchor(); + protected: + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; + // This ctor is used when the Tag has already been validated by a derived + // ctor. + DIType(const MDNode *N, bool, bool) : DIScope(N) {} + public: + /// Verify - Verify that a type descriptor is well formed. + bool Verify() const; + explicit DIType(const MDNode *N); + explicit DIType() {} + virtual ~DIType() {} + + DIScope getContext() const { return getFieldAs(1); } + StringRef getName() const { return getStringField(2); } + DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); + if (getVersion() == llvm::LLVMDebugVersion7) + return getFieldAs(3); + + return getFieldAs(3).getCompileUnit(); + } + DIFile getFile() const { return getFieldAs(3); } + unsigned getLineNumber() const { return getUnsignedField(4); } + uint64_t getSizeInBits() const { return getUInt64Field(5); } + uint64_t getAlignInBits() const { return getUInt64Field(6); } + // FIXME: Offset is only used for DW_TAG_member nodes. Making every type + // carry this is just plain insane. + uint64_t getOffsetInBits() const { return getUInt64Field(7); } + unsigned getFlags() const { return getUnsignedField(8); } + bool isPrivate() const { + return (getFlags() & FlagPrivate) != 0; + } + bool isProtected() const { + return (getFlags() & FlagProtected) != 0; + } + bool isForwardDecl() const { + return (getFlags() & FlagFwdDecl) != 0; + } + // isAppleBlock - Return true if this is the Apple Blocks extension. + bool isAppleBlockExtension() const { + return (getFlags() & FlagAppleBlock) != 0; + } + bool isBlockByrefStruct() const { + return (getFlags() & FlagBlockByrefStruct) != 0; + } + bool isVirtual() const { + return (getFlags() & FlagVirtual) != 0; + } + bool isArtificial() const { + return (getFlags() & FlagArtificial) != 0; + } + bool isObjcClassComplete() const { + return (getFlags() & FlagObjcClassComplete) != 0; + } + bool isValid() const { + return DbgNode && (isBasicType() || isDerivedType() || isCompositeType()); + } + StringRef getDirectory() const { + if (getVersion() == llvm::LLVMDebugVersion7) + return getCompileUnit().getDirectory(); + + return getFieldAs(3).getDirectory(); + } + StringRef getFilename() const { + if (getVersion() == llvm::LLVMDebugVersion7) + return getCompileUnit().getFilename(); + + return getFieldAs(3).getFilename(); + } + + /// isUnsignedDIType - Return true if type encoding is unsigned. + bool isUnsignedDIType(); + + /// replaceAllUsesWith - Replace all uses of debug info referenced by + /// this descriptor. + void replaceAllUsesWith(DIDescriptor &D); + void replaceAllUsesWith(MDNode *D); + }; + + /// DIBasicType - A basic type, like 'int' or 'float'. + class DIBasicType : public DIType { + virtual void anchor(); + public: + explicit DIBasicType(const MDNode *N = 0) : DIType(N) {} + + unsigned getEncoding() const { return getUnsignedField(9); } + + /// Verify - Verify that a basic type descriptor is well formed. + bool Verify() const; + }; + + /// DIDerivedType - A simple derived type, like a const qualified type, + /// a typedef, a pointer or reference, etc. + class DIDerivedType : public DIType { + virtual void anchor(); + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; + protected: + explicit DIDerivedType(const MDNode *N, bool, bool) + : DIType(N, true, true) {} + public: + explicit DIDerivedType(const MDNode *N = 0) + : DIType(N, true, true) {} + + DIType getTypeDerivedFrom() const { return getFieldAs(9); } + + /// getOriginalTypeSize - If this type is derived from a base type then + /// return base type size. + uint64_t getOriginalTypeSize() const; + + /// getObjCProperty - Return property node, if this ivar is + /// associated with one. + MDNode *getObjCProperty() const; + + StringRef getObjCPropertyName() const { + if (getVersion() > LLVMDebugVersion11) + return StringRef(); + return getStringField(10); + } + StringRef getObjCPropertyGetterName() const { + assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); + return getStringField(11); + } + StringRef getObjCPropertySetterName() const { + assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); + return getStringField(12); + } + bool isReadOnlyObjCProperty() { + assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); + return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; + } + bool isReadWriteObjCProperty() { + assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); + return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; + } + bool isAssignObjCProperty() { + assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); + return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_assign) != 0; + } + bool isRetainObjCProperty() { + assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); + return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_retain) != 0; + } + bool isCopyObjCProperty() { + assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); + return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_copy) != 0; + } + bool isNonAtomicObjCProperty() { + assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); + return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; + } + + /// Verify - Verify that a derived type descriptor is well formed. + bool Verify() const; + }; + + /// DICompositeType - This descriptor holds a type that can refer to multiple + /// other types, like a function or struct. + /// FIXME: Why is this a DIDerivedType?? + class DICompositeType : public DIDerivedType { + virtual void anchor(); + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; + public: + explicit DICompositeType(const MDNode *N = 0) + : DIDerivedType(N, true, true) { + if (N && !isCompositeType()) + DbgNode = 0; + } + + DIArray getTypeArray() const { return getFieldAs(10); } + unsigned getRunTimeLang() const { return getUnsignedField(11); } + DICompositeType getContainingType() const { + return getFieldAs(12); + } + DIArray getTemplateParams() const { return getFieldAs(13); } + + /// Verify - Verify that a composite type descriptor is well formed. + bool Verify() const; + }; + + /// DITemplateTypeParameter - This is a wrapper for template type parameter. + class DITemplateTypeParameter : public DIDescriptor { + public: + explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {} + + DIScope getContext() const { return getFieldAs(1); } + StringRef getName() const { return getStringField(2); } + DIType getType() const { return getFieldAs(3); } + StringRef getFilename() const { + return getFieldAs(4).getFilename(); + } + StringRef getDirectory() const { + return getFieldAs(4).getDirectory(); + } + unsigned getLineNumber() const { return getUnsignedField(5); } + unsigned getColumnNumber() const { return getUnsignedField(6); } + }; + + /// DITemplateValueParameter - This is a wrapper for template value parameter. + class DITemplateValueParameter : public DIDescriptor { + public: + explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {} + + DIScope getContext() const { return getFieldAs(1); } + StringRef getName() const { return getStringField(2); } + DIType getType() const { return getFieldAs(3); } + uint64_t getValue() const { return getUInt64Field(4); } + StringRef getFilename() const { + return getFieldAs(5).getFilename(); + } + StringRef getDirectory() const { + return getFieldAs(5).getDirectory(); + } + unsigned getLineNumber() const { return getUnsignedField(6); } + unsigned getColumnNumber() const { return getUnsignedField(7); } + }; + + /// DISubprogram - This is a wrapper for a subprogram (e.g. a function). + class DISubprogram : public DIScope { + virtual void anchor(); + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; + public: + explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {} + + DIScope getContext() const { return getFieldAs(2); } + StringRef getName() const { return getStringField(3); } + StringRef getDisplayName() const { return getStringField(4); } + StringRef getLinkageName() const { return getStringField(5); } + DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); + if (getVersion() == llvm::LLVMDebugVersion7) + return getFieldAs(6); + + return getFieldAs(6).getCompileUnit(); + } + unsigned getLineNumber() const { return getUnsignedField(7); } + DICompositeType getType() const { return getFieldAs(8); } + + /// getReturnTypeName - Subprogram return types are encoded either as + /// DIType or as DICompositeType. + StringRef getReturnTypeName() const { + DICompositeType DCT(getFieldAs(8)); + if (DCT.Verify()) { + DIArray A = DCT.getTypeArray(); + DIType T(A.getElement(0)); + return T.getName(); + } + DIType T(getFieldAs(8)); + return T.getName(); + } + + /// isLocalToUnit - Return true if this subprogram is local to the current + /// compile unit, like 'static' in C. + unsigned isLocalToUnit() const { return getUnsignedField(9); } + unsigned isDefinition() const { return getUnsignedField(10); } + + unsigned getVirtuality() const { return getUnsignedField(11); } + unsigned getVirtualIndex() const { return getUnsignedField(12); } + + DICompositeType getContainingType() const { + return getFieldAs(13); + } + + unsigned isArtificial() const { + if (getVersion() <= llvm::LLVMDebugVersion8) + return getUnsignedField(14); + return (getUnsignedField(14) & FlagArtificial) != 0; + } + /// isPrivate - Return true if this subprogram has "private" + /// access specifier. + bool isPrivate() const { + if (getVersion() <= llvm::LLVMDebugVersion8) + return false; + return (getUnsignedField(14) & FlagPrivate) != 0; + } + /// isProtected - Return true if this subprogram has "protected" + /// access specifier. + bool isProtected() const { + if (getVersion() <= llvm::LLVMDebugVersion8) + return false; + return (getUnsignedField(14) & FlagProtected) != 0; + } + /// isExplicit - Return true if this subprogram is marked as explicit. + bool isExplicit() const { + if (getVersion() <= llvm::LLVMDebugVersion8) + return false; + return (getUnsignedField(14) & FlagExplicit) != 0; + } + /// isPrototyped - Return true if this subprogram is prototyped. + bool isPrototyped() const { + if (getVersion() <= llvm::LLVMDebugVersion8) + return false; + return (getUnsignedField(14) & FlagPrototyped) != 0; + } + + unsigned isOptimized() const; + + StringRef getFilename() const { + if (getVersion() == llvm::LLVMDebugVersion7) + return getCompileUnit().getFilename(); + + return getFieldAs(6).getFilename(); + } + + StringRef getDirectory() const { + if (getVersion() == llvm::LLVMDebugVersion7) + return getCompileUnit().getFilename(); + + return getFieldAs(6).getDirectory(); + } + + /// getScopeLineNumber - Get the beginning of the scope of the + /// function, not necessarily where the name of the program + /// starts. + unsigned getScopeLineNumber() const { return getUnsignedField(20); } + + /// Verify - Verify that a subprogram descriptor is well formed. + bool Verify() const; + + /// describes - Return true if this subprogram provides debugging + /// information for the function F. + bool describes(const Function *F); + + Function *getFunction() const { return getFunctionField(16); } + DIArray getTemplateParams() const { return getFieldAs(17); } + DISubprogram getFunctionDeclaration() const { + return getFieldAs(18); + } + MDNode *getVariablesNodes() const; + DIArray getVariables() const; + }; + + /// DIGlobalVariable - This is a wrapper for a global variable. + class DIGlobalVariable : public DIDescriptor { + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; + public: + explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {} + + DIScope getContext() const { return getFieldAs(2); } + StringRef getName() const { return getStringField(3); } + StringRef getDisplayName() const { return getStringField(4); } + StringRef getLinkageName() const { return getStringField(5); } + DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); + if (getVersion() == llvm::LLVMDebugVersion7) + return getFieldAs(6); + + DIFile F = getFieldAs(6); + return F.getCompileUnit(); + } + StringRef getFilename() const { + if (getVersion() <= llvm::LLVMDebugVersion10) + return getContext().getFilename(); + return getFieldAs(6).getFilename(); + } + StringRef getDirectory() const { + if (getVersion() <= llvm::LLVMDebugVersion10) + return getContext().getDirectory(); + return getFieldAs(6).getDirectory(); + + } + + unsigned getLineNumber() const { return getUnsignedField(7); } + DIType getType() const { return getFieldAs(8); } + unsigned isLocalToUnit() const { return getUnsignedField(9); } + unsigned isDefinition() const { return getUnsignedField(10); } + + GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } + Constant *getConstant() const { return getConstantField(11); } + + /// Verify - Verify that a global variable descriptor is well formed. + bool Verify() const; + }; + + /// DIVariable - This is a wrapper for a variable (e.g. parameter, local, + /// global etc). + class DIVariable : public DIDescriptor { + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; + public: + explicit DIVariable(const MDNode *N = 0) + : DIDescriptor(N) {} + + DIScope getContext() const { return getFieldAs(1); } + StringRef getName() const { return getStringField(2); } + DICompileUnit getCompileUnit() const { + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); + if (getVersion() == llvm::LLVMDebugVersion7) + return getFieldAs(3); + + DIFile F = getFieldAs(3); + return F.getCompileUnit(); + } + unsigned getLineNumber() const { + return (getUnsignedField(4) << 8) >> 8; + } + unsigned getArgNumber() const { + unsigned L = getUnsignedField(4); + return L >> 24; + } + DIType getType() const { return getFieldAs(5); } + + /// isArtificial - Return true if this variable is marked as "artificial". + bool isArtificial() const { + if (getVersion() <= llvm::LLVMDebugVersion8) + return false; + return (getUnsignedField(6) & FlagArtificial) != 0; + } + + /// getInlinedAt - If this variable is inlined then return inline location. + MDNode *getInlinedAt() const; + + /// Verify - Verify that a variable descriptor is well formed. + bool Verify() const; + + /// HasComplexAddr - Return true if the variable has a complex address. + bool hasComplexAddress() const { + return getNumAddrElements() > 0; + } + + unsigned getNumAddrElements() const; + + uint64_t getAddrElement(unsigned Idx) const { + if (getVersion() <= llvm::LLVMDebugVersion8) + return getUInt64Field(Idx+6); + if (getVersion() == llvm::LLVMDebugVersion9) + return getUInt64Field(Idx+7); + return getUInt64Field(Idx+8); + } + + /// isBlockByrefVariable - Return true if the variable was declared as + /// a "__block" variable (Apple Blocks). + bool isBlockByrefVariable() const { + return getType().isBlockByrefStruct(); + } + + /// isInlinedFnArgument - Return trule if this variable provides debugging + /// information for an inlined function arguments. + bool isInlinedFnArgument(const Function *CurFn); + + void printExtendedName(raw_ostream &OS) const; + }; + + /// DILexicalBlock - This is a wrapper for a lexical block. + class DILexicalBlock : public DIScope { + virtual void anchor(); + public: + explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {} + DIScope getContext() const { return getFieldAs(1); } + unsigned getLineNumber() const { return getUnsignedField(2); } + unsigned getColumnNumber() const { return getUnsignedField(3); } + StringRef getDirectory() const { + StringRef dir = getFieldAs(4).getDirectory(); + return !dir.empty() ? dir : getContext().getDirectory(); + } + StringRef getFilename() const { + StringRef filename = getFieldAs(4).getFilename(); + return !filename.empty() ? filename : getContext().getFilename(); + } + }; + + /// DILexicalBlockFile - This is a wrapper for a lexical block with + /// a filename change. + class DILexicalBlockFile : public DIScope { + virtual void anchor(); + public: + explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {} + DIScope getContext() const { return getScope().getContext(); } + unsigned getLineNumber() const { return getScope().getLineNumber(); } + unsigned getColumnNumber() const { return getScope().getColumnNumber(); } + StringRef getDirectory() const { + StringRef dir = getFieldAs(2).getDirectory(); + return !dir.empty() ? dir : getContext().getDirectory(); + } + StringRef getFilename() const { + StringRef filename = getFieldAs(2).getFilename(); + assert(!filename.empty() && "Why'd you create this then?"); + return filename; + } + DILexicalBlock getScope() const { return getFieldAs(1); } + }; + + /// DINameSpace - A wrapper for a C++ style name space. + class DINameSpace : public DIScope { + virtual void anchor(); + public: + explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {} + DIScope getContext() const { return getFieldAs(1); } + StringRef getName() const { return getStringField(2); } + StringRef getDirectory() const { + return getFieldAs(3).getDirectory(); + } + StringRef getFilename() const { + return getFieldAs(3).getFilename(); + } + DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); + if (getVersion() == llvm::LLVMDebugVersion7) + return getFieldAs(3); + + return getFieldAs(3).getCompileUnit(); + } + unsigned getLineNumber() const { return getUnsignedField(4); } + bool Verify() const; + }; + + /// DILocation - This object holds location information. This object + /// is not associated with any DWARF tag. + class DILocation : public DIDescriptor { + public: + explicit DILocation(const MDNode *N) : DIDescriptor(N) { } + + unsigned getLineNumber() const { return getUnsignedField(0); } + unsigned getColumnNumber() const { return getUnsignedField(1); } + DIScope getScope() const { return getFieldAs(2); } + DILocation getOrigLocation() const { return getFieldAs(3); } + StringRef getFilename() const { return getScope().getFilename(); } + StringRef getDirectory() const { return getScope().getDirectory(); } + bool Verify() const; + }; + + class DIObjCProperty : public DIDescriptor { + public: + explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) { } + + StringRef getObjCPropertyName() const { return getStringField(1); } + DIFile getFile() const { return getFieldAs(2); } + unsigned getLineNumber() const { return getUnsignedField(3); } + + StringRef getObjCPropertyGetterName() const { + return getStringField(4); + } + StringRef getObjCPropertySetterName() const { + return getStringField(5); + } + bool isReadOnlyObjCProperty() { + return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; + } + bool isReadWriteObjCProperty() { + return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; + } + bool isAssignObjCProperty() { + return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0; + } + bool isRetainObjCProperty() { + return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0; + } + bool isCopyObjCProperty() { + return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0; + } + bool isNonAtomicObjCProperty() { + return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; + } + + DIType getType() const { return getFieldAs(7); } + + /// Verify - Verify that a derived type descriptor is well formed. + bool Verify() const; + }; + + /// getDISubprogram - Find subprogram that is enclosing this scope. + DISubprogram getDISubprogram(const MDNode *Scope); + + /// getDICompositeType - Find underlying composite type. + DICompositeType getDICompositeType(DIType T); + + /// isSubprogramContext - Return true if Context is either a subprogram + /// or another context nested inside a subprogram. + bool isSubprogramContext(const MDNode *Context); + + /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable + /// to hold function specific information. + NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP); + + /// getFnSpecificMDNode - Return a NameMDNode, if available, that is + /// suitable to hold function specific information. + NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP); + + /// createInlinedVariable - Create a new inlined variable based on current + /// variable. + /// @param DV Current Variable. + /// @param InlinedScope Location at current variable is inlined. + DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope, + LLVMContext &VMContext); + + /// cleanseInlinedVariable - Remove inlined scope from the variable. + DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext); + + class DebugInfoFinder { + public: + /// processModule - Process entire module and collect debug info + /// anchors. + void processModule(Module &M); + + private: + /// processType - Process DIType. + void processType(DIType DT); + + /// processLexicalBlock - Process DILexicalBlock. + void processLexicalBlock(DILexicalBlock LB); + + /// processSubprogram - Process DISubprogram. + void processSubprogram(DISubprogram SP); + + /// processDeclare - Process DbgDeclareInst. + void processDeclare(DbgDeclareInst *DDI); + + /// processLocation - Process DILocation. + void processLocation(DILocation Loc); + + /// addCompileUnit - Add compile unit into CUs. + bool addCompileUnit(DICompileUnit CU); + + /// addGlobalVariable - Add global variable into GVs. + bool addGlobalVariable(DIGlobalVariable DIG); + + // addSubprogram - Add subprogram into SPs. + bool addSubprogram(DISubprogram SP); + + /// addType - Add type into Tys. + bool addType(DIType DT); + + public: + typedef SmallVector::const_iterator iterator; + iterator compile_unit_begin() const { return CUs.begin(); } + iterator compile_unit_end() const { return CUs.end(); } + iterator subprogram_begin() const { return SPs.begin(); } + iterator subprogram_end() const { return SPs.end(); } + iterator global_variable_begin() const { return GVs.begin(); } + iterator global_variable_end() const { return GVs.end(); } + iterator type_begin() const { return TYs.begin(); } + iterator type_end() const { return TYs.end(); } + + unsigned compile_unit_count() const { return CUs.size(); } + unsigned global_variable_count() const { return GVs.size(); } + unsigned subprogram_count() const { return SPs.size(); } + unsigned type_count() const { return TYs.size(); } + + private: + SmallVector CUs; // Compile Units + SmallVector SPs; // Subprograms + SmallVector GVs; // Global Variables; + SmallVector TYs; // Types + SmallPtrSet NodesSeen; + }; +} // end namespace llvm + +#endif diff --git a/lib/Analysis/DIBuilder.cpp b/lib/Analysis/DIBuilder.cpp index 4fe0fc26f1a..b8d4ba36d54 100644 --- a/lib/Analysis/DIBuilder.cpp +++ b/lib/Analysis/DIBuilder.cpp @@ -12,8 +12,8 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/DIBuilder.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/IntrinsicInst.h" #include "llvm/Module.h" #include "llvm/ADT/STLExtras.h" diff --git a/lib/Analysis/DbgInfoPrinter.cpp b/lib/Analysis/DbgInfoPrinter.cpp index cd832abeba5..41cd34c07be 100644 --- a/lib/Analysis/DbgInfoPrinter.cpp +++ b/lib/Analysis/DbgInfoPrinter.cpp @@ -16,14 +16,14 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Pass.h" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" #include "llvm/IntrinsicInst.h" #include "llvm/Metadata.h" #include "llvm/Module.h" -#include "llvm/Assembly/Writer.h" -#include "llvm/Analysis/DebugInfo.h" +#include "llvm/Pass.h" #include "llvm/Analysis/Passes.h" +#include "llvm/Assembly/Writer.h" #include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/raw_ostream.h" diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp deleted file mode 100644 index 44bd6f15e12..00000000000 --- a/lib/Analysis/DebugInfo.cpp +++ /dev/null @@ -1,1182 +0,0 @@ -//===--- DebugInfo.cpp - Debug Information Helper Classes -----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the helper classes used to build and interpret debug -// information in LLVM IR form. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/DebugInfo.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Intrinsics.h" -#include "llvm/IntrinsicInst.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/Analysis/ValueTracking.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Dwarf.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; -using namespace llvm::dwarf; - -//===----------------------------------------------------------------------===// -// DIDescriptor -//===----------------------------------------------------------------------===// - -DIDescriptor::DIDescriptor(const DIFile F) : DbgNode(F.DbgNode) { -} - -DIDescriptor::DIDescriptor(const DISubprogram F) : DbgNode(F.DbgNode) { -} - -DIDescriptor::DIDescriptor(const DILexicalBlockFile F) : DbgNode(F.DbgNode) { -} - -DIDescriptor::DIDescriptor(const DILexicalBlock F) : DbgNode(F.DbgNode) { -} - -DIDescriptor::DIDescriptor(const DIVariable F) : DbgNode(F.DbgNode) { -} - -DIDescriptor::DIDescriptor(const DIType F) : DbgNode(F.DbgNode) { -} - -StringRef -DIDescriptor::getStringField(unsigned Elt) const { - if (DbgNode == 0) - return StringRef(); - - if (Elt < DbgNode->getNumOperands()) - if (MDString *MDS = dyn_cast_or_null(DbgNode->getOperand(Elt))) - return MDS->getString(); - - return StringRef(); -} - -uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const { - if (DbgNode == 0) - return 0; - - if (Elt < DbgNode->getNumOperands()) - if (ConstantInt *CI = dyn_cast_or_null(DbgNode->getOperand(Elt))) - return CI->getZExtValue(); - - return 0; -} - -DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const { - if (DbgNode == 0) - return DIDescriptor(); - - if (Elt < DbgNode->getNumOperands()) - return - DIDescriptor(dyn_cast_or_null(DbgNode->getOperand(Elt))); - return DIDescriptor(); -} - -GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const { - if (DbgNode == 0) - return 0; - - if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null(DbgNode->getOperand(Elt)); - return 0; -} - -Constant *DIDescriptor::getConstantField(unsigned Elt) const { - if (DbgNode == 0) - return 0; - - if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null(DbgNode->getOperand(Elt)); - return 0; -} - -Function *DIDescriptor::getFunctionField(unsigned Elt) const { - if (DbgNode == 0) - return 0; - - if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null(DbgNode->getOperand(Elt)); - return 0; -} - -unsigned DIVariable::getNumAddrElements() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return DbgNode->getNumOperands()-6; - if (getVersion() == llvm::LLVMDebugVersion9) - return DbgNode->getNumOperands()-7; - return DbgNode->getNumOperands()-8; -} - -/// getInlinedAt - If this variable is inlined then return inline location. -MDNode *DIVariable::getInlinedAt() const { - if (getVersion() <= llvm::LLVMDebugVersion9) - return NULL; - return dyn_cast_or_null(DbgNode->getOperand(7)); -} - -//===----------------------------------------------------------------------===// -// Predicates -//===----------------------------------------------------------------------===// - -/// isBasicType - Return true if the specified tag is legal for -/// DIBasicType. -bool DIDescriptor::isBasicType() const { - if (!DbgNode) return false; - switch (getTag()) { - case dwarf::DW_TAG_base_type: - case dwarf::DW_TAG_unspecified_type: - return true; - default: - return false; - } -} - -/// isDerivedType - Return true if the specified tag is legal for DIDerivedType. -bool DIDescriptor::isDerivedType() const { - if (!DbgNode) return false; - switch (getTag()) { - case dwarf::DW_TAG_typedef: - case dwarf::DW_TAG_pointer_type: - case dwarf::DW_TAG_reference_type: - case dwarf::DW_TAG_rvalue_reference_type: - case dwarf::DW_TAG_const_type: - case dwarf::DW_TAG_volatile_type: - case dwarf::DW_TAG_restrict_type: - case dwarf::DW_TAG_member: - case dwarf::DW_TAG_inheritance: - case dwarf::DW_TAG_friend: - return true; - default: - // CompositeTypes are currently modelled as DerivedTypes. - return isCompositeType(); - } -} - -/// isCompositeType - Return true if the specified tag is legal for -/// DICompositeType. -bool DIDescriptor::isCompositeType() const { - if (!DbgNode) return false; - switch (getTag()) { - case dwarf::DW_TAG_array_type: - case dwarf::DW_TAG_structure_type: - case dwarf::DW_TAG_union_type: - case dwarf::DW_TAG_enumeration_type: - case dwarf::DW_TAG_vector_type: - case dwarf::DW_TAG_subroutine_type: - case dwarf::DW_TAG_class_type: - return true; - default: - return false; - } -} - -/// isVariable - Return true if the specified tag is legal for DIVariable. -bool DIDescriptor::isVariable() const { - if (!DbgNode) return false; - switch (getTag()) { - case dwarf::DW_TAG_auto_variable: - case dwarf::DW_TAG_arg_variable: - case dwarf::DW_TAG_return_variable: - return true; - default: - return false; - } -} - -/// isType - Return true if the specified tag is legal for DIType. -bool DIDescriptor::isType() const { - return isBasicType() || isCompositeType() || isDerivedType(); -} - -/// isSubprogram - Return true if the specified tag is legal for -/// DISubprogram. -bool DIDescriptor::isSubprogram() const { - return DbgNode && getTag() == dwarf::DW_TAG_subprogram; -} - -/// isGlobalVariable - Return true if the specified tag is legal for -/// DIGlobalVariable. -bool DIDescriptor::isGlobalVariable() const { - return DbgNode && (getTag() == dwarf::DW_TAG_variable || - getTag() == dwarf::DW_TAG_constant); -} - -/// isGlobal - Return true if the specified tag is legal for DIGlobal. -bool DIDescriptor::isGlobal() const { - return isGlobalVariable(); -} - -/// isUnspecifiedParmeter - Return true if the specified tag is -/// DW_TAG_unspecified_parameters. -bool DIDescriptor::isUnspecifiedParameter() const { - return DbgNode && getTag() == dwarf::DW_TAG_unspecified_parameters; -} - -/// isScope - Return true if the specified tag is one of the scope -/// related tag. -bool DIDescriptor::isScope() const { - if (!DbgNode) return false; - switch (getTag()) { - case dwarf::DW_TAG_compile_unit: - case dwarf::DW_TAG_lexical_block: - case dwarf::DW_TAG_subprogram: - case dwarf::DW_TAG_namespace: - return true; - default: - break; - } - return false; -} - -/// isTemplateTypeParameter - Return true if the specified tag is -/// DW_TAG_template_type_parameter. -bool DIDescriptor::isTemplateTypeParameter() const { - return DbgNode && getTag() == dwarf::DW_TAG_template_type_parameter; -} - -/// isTemplateValueParameter - Return true if the specified tag is -/// DW_TAG_template_value_parameter. -bool DIDescriptor::isTemplateValueParameter() const { - return DbgNode && getTag() == dwarf::DW_TAG_template_value_parameter; -} - -/// isCompileUnit - Return true if the specified tag is DW_TAG_compile_unit. -bool DIDescriptor::isCompileUnit() const { - return DbgNode && getTag() == dwarf::DW_TAG_compile_unit; -} - -/// isFile - Return true if the specified tag is DW_TAG_file_type. -bool DIDescriptor::isFile() const { - return DbgNode && getTag() == dwarf::DW_TAG_file_type; -} - -/// isNameSpace - Return true if the specified tag is DW_TAG_namespace. -bool DIDescriptor::isNameSpace() const { - return DbgNode && getTag() == dwarf::DW_TAG_namespace; -} - -/// isLexicalBlockFile - Return true if the specified descriptor is a -/// lexical block with an extra file. -bool DIDescriptor::isLexicalBlockFile() const { - return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && - (DbgNode->getNumOperands() == 3); -} - -/// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block. -bool DIDescriptor::isLexicalBlock() const { - return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && - (DbgNode->getNumOperands() > 3); -} - -/// isSubrange - Return true if the specified tag is DW_TAG_subrange_type. -bool DIDescriptor::isSubrange() const { - return DbgNode && getTag() == dwarf::DW_TAG_subrange_type; -} - -/// isEnumerator - Return true if the specified tag is DW_TAG_enumerator. -bool DIDescriptor::isEnumerator() const { - return DbgNode && getTag() == dwarf::DW_TAG_enumerator; -} - -/// isObjCProperty - Return true if the specified tag is DW_TAG -bool DIDescriptor::isObjCProperty() const { - return DbgNode && getTag() == dwarf::DW_TAG_APPLE_property; -} -//===----------------------------------------------------------------------===// -// Simple Descriptor Constructors and other Methods -//===----------------------------------------------------------------------===// - -DIType::DIType(const MDNode *N) : DIScope(N) { - if (!N) return; - if (!isBasicType() && !isDerivedType() && !isCompositeType()) { - DbgNode = 0; - } -} - -unsigned DIArray::getNumElements() const { - if (!DbgNode) - return 0; - return DbgNode->getNumOperands(); -} - -/// replaceAllUsesWith - Replace all uses of debug info referenced by -/// this descriptor. -void DIType::replaceAllUsesWith(DIDescriptor &D) { - if (!DbgNode) - return; - - // Since we use a TrackingVH for the node, its easy for clients to manufacture - // legitimate situations where they want to replaceAllUsesWith() on something - // which, due to uniquing, has merged with the source. We shield clients from - // this detail by allowing a value to be replaced with replaceAllUsesWith() - // itself. - if (DbgNode != D) { - MDNode *Node = const_cast(DbgNode); - const MDNode *DN = D; - const Value *V = cast_or_null(DN); - Node->replaceAllUsesWith(const_cast(V)); - MDNode::deleteTemporary(Node); - } -} - -/// replaceAllUsesWith - Replace all uses of debug info referenced by -/// this descriptor. -void DIType::replaceAllUsesWith(MDNode *D) { - if (!DbgNode) - return; - - // Since we use a TrackingVH for the node, its easy for clients to manufacture - // legitimate situations where they want to replaceAllUsesWith() on something - // which, due to uniquing, has merged with the source. We shield clients from - // this detail by allowing a value to be replaced with replaceAllUsesWith() - // itself. - if (DbgNode != D) { - MDNode *Node = const_cast(DbgNode); - const MDNode *DN = D; - const Value *V = cast_or_null(DN); - Node->replaceAllUsesWith(const_cast(V)); - MDNode::deleteTemporary(Node); - } -} - -/// isUnsignedDIType - Return true if type encoding is unsigned. -bool DIType::isUnsignedDIType() { - DIDerivedType DTy(DbgNode); - if (DTy.Verify()) - return DTy.getTypeDerivedFrom().isUnsignedDIType(); - - DIBasicType BTy(DbgNode); - if (BTy.Verify()) { - unsigned Encoding = BTy.getEncoding(); - if (Encoding == dwarf::DW_ATE_unsigned || - Encoding == dwarf::DW_ATE_unsigned_char) - return true; - } - return false; -} - -/// Verify - Verify that a compile unit is well formed. -bool DICompileUnit::Verify() const { - if (!DbgNode) - return false; - StringRef N = getFilename(); - if (N.empty()) - return false; - // It is possible that directory and produce string is empty. - return true; -} - -/// Verify - Verify that an ObjC property is well formed. -bool DIObjCProperty::Verify() const { - if (!DbgNode) - return false; - unsigned Tag = getTag(); - if (Tag != dwarf::DW_TAG_APPLE_property) return false; - DIType Ty = getType(); - if (!Ty.Verify()) return false; - - // Don't worry about the rest of the strings for now. - return true; -} - -/// Verify - Verify that a type descriptor is well formed. -bool DIType::Verify() const { - if (!DbgNode) - return false; - if (getContext() && !getContext().Verify()) - return false; - unsigned Tag = getTag(); - if (!isBasicType() && Tag != dwarf::DW_TAG_const_type && - Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_pointer_type && - Tag != dwarf::DW_TAG_reference_type && - Tag != dwarf::DW_TAG_rvalue_reference_type && - Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_vector_type && - Tag != dwarf::DW_TAG_array_type && - Tag != dwarf::DW_TAG_enumeration_type && - Tag != dwarf::DW_TAG_subroutine_type && - getFilename().empty()) - return false; - return true; -} - -/// Verify - Verify that a basic type descriptor is well formed. -bool DIBasicType::Verify() const { - return isBasicType(); -} - -/// Verify - Verify that a derived type descriptor is well formed. -bool DIDerivedType::Verify() const { - return isDerivedType(); -} - -/// Verify - Verify that a composite type descriptor is well formed. -bool DICompositeType::Verify() const { - if (!DbgNode) - return false; - if (getContext() && !getContext().Verify()) - return false; - - return true; -} - -/// Verify - Verify that a subprogram descriptor is well formed. -bool DISubprogram::Verify() const { - if (!DbgNode) - return false; - - if (getContext() && !getContext().Verify()) - return false; - - DICompositeType Ty = getType(); - if (!Ty.Verify()) - return false; - return true; -} - -/// Verify - Verify that a global variable descriptor is well formed. -bool DIGlobalVariable::Verify() const { - if (!DbgNode) - return false; - - if (getDisplayName().empty()) - return false; - - if (getContext() && !getContext().Verify()) - return false; - - DIType Ty = getType(); - if (!Ty.Verify()) - return false; - - if (!getGlobal() && !getConstant()) - return false; - - return true; -} - -/// Verify - Verify that a variable descriptor is well formed. -bool DIVariable::Verify() const { - if (!DbgNode) - return false; - - if (getContext() && !getContext().Verify()) - return false; - - DIType Ty = getType(); - if (!Ty.Verify()) - return false; - - return true; -} - -/// Verify - Verify that a location descriptor is well formed. -bool DILocation::Verify() const { - if (!DbgNode) - return false; - - return DbgNode->getNumOperands() == 4; -} - -/// Verify - Verify that a namespace descriptor is well formed. -bool DINameSpace::Verify() const { - if (!DbgNode) - return false; - if (getName().empty()) - return false; - return true; -} - -/// getOriginalTypeSize - If this type is derived from a base type then -/// return base type size. -uint64_t DIDerivedType::getOriginalTypeSize() const { - unsigned Tag = getTag(); - - if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef && - Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type && - Tag != dwarf::DW_TAG_restrict_type) - return getSizeInBits(); - - DIType BaseType = getTypeDerivedFrom(); - - // If this type is not derived from any type then take conservative approach. - if (!BaseType.isValid()) - return getSizeInBits(); - - // If this is a derived type, go ahead and get the base type, unless it's a - // reference then it's just the size of the field. Pointer types have no need - // of this since they're a different type of qualification on the type. - if (BaseType.getTag() == dwarf::DW_TAG_reference_type || - BaseType.getTag() == dwarf::DW_TAG_rvalue_reference_type) - return getSizeInBits(); - - if (BaseType.isDerivedType()) - return DIDerivedType(BaseType).getOriginalTypeSize(); - - return BaseType.getSizeInBits(); -} - -/// getObjCProperty - Return property node, if this ivar is associated with one. -MDNode *DIDerivedType::getObjCProperty() const { - if (getVersion() <= LLVMDebugVersion11 || DbgNode->getNumOperands() <= 10) - return NULL; - return dyn_cast_or_null(DbgNode->getOperand(10)); -} - -/// isInlinedFnArgument - Return true if this variable provides debugging -/// information for an inlined function arguments. -bool DIVariable::isInlinedFnArgument(const Function *CurFn) { - assert(CurFn && "Invalid function"); - if (!getContext().isSubprogram()) - return false; - // This variable is not inlined function argument if its scope - // does not describe current function. - return !DISubprogram(getContext()).describes(CurFn); -} - -/// describes - Return true if this subprogram provides debugging -/// information for the function F. -bool DISubprogram::describes(const Function *F) { - assert(F && "Invalid function"); - if (F == getFunction()) - return true; - StringRef Name = getLinkageName(); - if (Name.empty()) - Name = getName(); - if (F->getName() == Name) - return true; - return false; -} - -unsigned DISubprogram::isOptimized() const { - assert (DbgNode && "Invalid subprogram descriptor!"); - if (DbgNode->getNumOperands() == 16) - return getUnsignedField(15); - return 0; -} - -MDNode *DISubprogram::getVariablesNodes() const { - if (!DbgNode || DbgNode->getNumOperands() <= 19) - return NULL; - if (MDNode *Temp = dyn_cast_or_null(DbgNode->getOperand(19))) - return dyn_cast_or_null(Temp->getOperand(0)); - return NULL; -} - -DIArray DISubprogram::getVariables() const { - if (!DbgNode || DbgNode->getNumOperands() <= 19) - return DIArray(); - if (MDNode *T = dyn_cast_or_null(DbgNode->getOperand(19))) - if (MDNode *A = dyn_cast_or_null(T->getOperand(0))) - return DIArray(A); - return DIArray(); -} - -StringRef DIScope::getFilename() const { - if (!DbgNode) - return StringRef(); - if (isLexicalBlockFile()) - return DILexicalBlockFile(DbgNode).getFilename(); - if (isLexicalBlock()) - return DILexicalBlock(DbgNode).getFilename(); - if (isSubprogram()) - return DISubprogram(DbgNode).getFilename(); - if (isCompileUnit()) - return DICompileUnit(DbgNode).getFilename(); - if (isNameSpace()) - return DINameSpace(DbgNode).getFilename(); - if (isType()) - return DIType(DbgNode).getFilename(); - if (isFile()) - return DIFile(DbgNode).getFilename(); - llvm_unreachable("Invalid DIScope!"); -} - -StringRef DIScope::getDirectory() const { - if (!DbgNode) - return StringRef(); - if (isLexicalBlockFile()) - return DILexicalBlockFile(DbgNode).getDirectory(); - if (isLexicalBlock()) - return DILexicalBlock(DbgNode).getDirectory(); - if (isSubprogram()) - return DISubprogram(DbgNode).getDirectory(); - if (isCompileUnit()) - return DICompileUnit(DbgNode).getDirectory(); - if (isNameSpace()) - return DINameSpace(DbgNode).getDirectory(); - if (isType()) - return DIType(DbgNode).getDirectory(); - if (isFile()) - return DIFile(DbgNode).getDirectory(); - llvm_unreachable("Invalid DIScope!"); -} - -DIArray DICompileUnit::getEnumTypes() const { - if (!DbgNode || DbgNode->getNumOperands() < 14) - return DIArray(); - - if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(10))) - if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) - return DIArray(A); - return DIArray(); -} - -DIArray DICompileUnit::getRetainedTypes() const { - if (!DbgNode || DbgNode->getNumOperands() < 14) - return DIArray(); - - if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(11))) - if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) - return DIArray(A); - return DIArray(); -} - -DIArray DICompileUnit::getSubprograms() const { - if (!DbgNode || DbgNode->getNumOperands() < 14) - return DIArray(); - - if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(12))) - if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) - return DIArray(A); - return DIArray(); -} - - -DIArray DICompileUnit::getGlobalVariables() const { - if (!DbgNode || DbgNode->getNumOperands() < 14) - return DIArray(); - - if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(13))) - if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) - return DIArray(A); - return DIArray(); -} - -/// fixupObjcLikeName - Replace contains special characters used -/// in a typical Objective-C names with '.' in a given string. -static void fixupObjcLikeName(StringRef Str, SmallVectorImpl &Out) { - bool isObjCLike = false; - for (size_t i = 0, e = Str.size(); i < e; ++i) { - char C = Str[i]; - if (C == '[') - isObjCLike = true; - - if (isObjCLike && (C == '[' || C == ']' || C == ' ' || C == ':' || - C == '+' || C == '(' || C == ')')) - Out.push_back('.'); - else - Out.push_back(C); - } -} - -/// getFnSpecificMDNode - Return a NameMDNode, if available, that is -/// suitable to hold function specific information. -NamedMDNode *llvm::getFnSpecificMDNode(const Module &M, DISubprogram Fn) { - SmallString<32> Name = StringRef("llvm.dbg.lv."); - StringRef FName = "fn"; - if (Fn.getFunction()) - FName = Fn.getFunction()->getName(); - else - FName = Fn.getName(); - char One = '\1'; - if (FName.startswith(StringRef(&One, 1))) - FName = FName.substr(1); - fixupObjcLikeName(FName, Name); - return M.getNamedMetadata(Name.str()); -} - -/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable -/// to hold function specific information. -NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, DISubprogram Fn) { - SmallString<32> Name = StringRef("llvm.dbg.lv."); - StringRef FName = "fn"; - if (Fn.getFunction()) - FName = Fn.getFunction()->getName(); - else - FName = Fn.getName(); - char One = '\1'; - if (FName.startswith(StringRef(&One, 1))) - FName = FName.substr(1); - fixupObjcLikeName(FName, Name); - - return M.getOrInsertNamedMetadata(Name.str()); -} - -/// createInlinedVariable - Create a new inlined variable based on current -/// variable. -/// @param DV Current Variable. -/// @param InlinedScope Location at current variable is inlined. -DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope, - LLVMContext &VMContext) { - SmallVector Elts; - // Insert inlined scope as 7th element. - for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i) - i == 7 ? Elts.push_back(InlinedScope) : - Elts.push_back(DV->getOperand(i)); - return DIVariable(MDNode::get(VMContext, Elts)); -} - -/// cleanseInlinedVariable - Remove inlined scope from the variable. -DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) { - SmallVector Elts; - // Insert inlined scope as 7th element. - for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i) - i == 7 ? - Elts.push_back(llvm::Constant::getNullValue(Type::getInt32Ty(VMContext))): - Elts.push_back(DV->getOperand(i)); - return DIVariable(MDNode::get(VMContext, Elts)); -} - -//===----------------------------------------------------------------------===// -// DebugInfoFinder implementations. -//===----------------------------------------------------------------------===// - -/// processModule - Process entire module and collect debug info. -void DebugInfoFinder::processModule(Module &M) { - if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) { - for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { - DICompileUnit CU(CU_Nodes->getOperand(i)); - addCompileUnit(CU); - if (CU.getVersion() > LLVMDebugVersion10) { - DIArray GVs = CU.getGlobalVariables(); - for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) { - DIGlobalVariable DIG(GVs.getElement(i)); - if (addGlobalVariable(DIG)) - processType(DIG.getType()); - } - DIArray SPs = CU.getSubprograms(); - for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) - processSubprogram(DISubprogram(SPs.getElement(i))); - DIArray EnumTypes = CU.getEnumTypes(); - for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) - processType(DIType(EnumTypes.getElement(i))); - DIArray RetainedTypes = CU.getRetainedTypes(); - for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) - processType(DIType(RetainedTypes.getElement(i))); - return; - } - } - } - - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI) - for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end(); BI != BE; - ++BI) { - if (DbgDeclareInst *DDI = dyn_cast(BI)) - processDeclare(DDI); - - DebugLoc Loc = BI->getDebugLoc(); - if (Loc.isUnknown()) - continue; - - LLVMContext &Ctx = BI->getContext(); - DIDescriptor Scope(Loc.getScope(Ctx)); - - if (Scope.isCompileUnit()) - addCompileUnit(DICompileUnit(Scope)); - else if (Scope.isSubprogram()) - processSubprogram(DISubprogram(Scope)); - else if (Scope.isLexicalBlockFile()) { - DILexicalBlockFile DBF = DILexicalBlockFile(Scope); - processLexicalBlock(DILexicalBlock(DBF.getScope())); - } - else if (Scope.isLexicalBlock()) - processLexicalBlock(DILexicalBlock(Scope)); - - if (MDNode *IA = Loc.getInlinedAt(Ctx)) - processLocation(DILocation(IA)); - } - - if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv")) { - for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { - DIGlobalVariable DIG(cast(NMD->getOperand(i))); - if (addGlobalVariable(DIG)) { - if (DIG.getVersion() <= LLVMDebugVersion10) - addCompileUnit(DIG.getCompileUnit()); - processType(DIG.getType()); - } - } - } - - if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) - for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) - processSubprogram(DISubprogram(NMD->getOperand(i))); -} - -/// processLocation - Process DILocation. -void DebugInfoFinder::processLocation(DILocation Loc) { - if (!Loc.Verify()) return; - DIDescriptor S(Loc.getScope()); - if (S.isCompileUnit()) - addCompileUnit(DICompileUnit(S)); - else if (S.isSubprogram()) - processSubprogram(DISubprogram(S)); - else if (S.isLexicalBlock()) - processLexicalBlock(DILexicalBlock(S)); - else if (S.isLexicalBlockFile()) { - DILexicalBlockFile DBF = DILexicalBlockFile(S); - processLexicalBlock(DILexicalBlock(DBF.getScope())); - } - processLocation(Loc.getOrigLocation()); -} - -/// processType - Process DIType. -void DebugInfoFinder::processType(DIType DT) { - if (!addType(DT)) - return; - if (DT.getVersion() <= LLVMDebugVersion10) - addCompileUnit(DT.getCompileUnit()); - if (DT.isCompositeType()) { - DICompositeType DCT(DT); - processType(DCT.getTypeDerivedFrom()); - DIArray DA = DCT.getTypeArray(); - for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) { - DIDescriptor D = DA.getElement(i); - if (D.isType()) - processType(DIType(D)); - else if (D.isSubprogram()) - processSubprogram(DISubprogram(D)); - } - } else if (DT.isDerivedType()) { - DIDerivedType DDT(DT); - processType(DDT.getTypeDerivedFrom()); - } -} - -/// processLexicalBlock -void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { - DIScope Context = LB.getContext(); - if (Context.isLexicalBlock()) - return processLexicalBlock(DILexicalBlock(Context)); - else if (Context.isLexicalBlockFile()) { - DILexicalBlockFile DBF = DILexicalBlockFile(Context); - return processLexicalBlock(DILexicalBlock(DBF.getScope())); - } - else - return processSubprogram(DISubprogram(Context)); -} - -/// processSubprogram - Process DISubprogram. -void DebugInfoFinder::processSubprogram(DISubprogram SP) { - if (!addSubprogram(SP)) - return; - if (SP.getVersion() <= LLVMDebugVersion10) - addCompileUnit(SP.getCompileUnit()); - processType(SP.getType()); -} - -/// processDeclare - Process DbgDeclareInst. -void DebugInfoFinder::processDeclare(DbgDeclareInst *DDI) { - MDNode *N = dyn_cast(DDI->getVariable()); - if (!N) return; - - DIDescriptor DV(N); - if (!DV.isVariable()) - return; - - if (!NodesSeen.insert(DV)) - return; - if (DIVariable(N).getVersion() <= LLVMDebugVersion10) - addCompileUnit(DIVariable(N).getCompileUnit()); - processType(DIVariable(N).getType()); -} - -/// addType - Add type into Tys. -bool DebugInfoFinder::addType(DIType DT) { - if (!DT.isValid()) - return false; - - if (!NodesSeen.insert(DT)) - return false; - - TYs.push_back(DT); - return true; -} - -/// addCompileUnit - Add compile unit into CUs. -bool DebugInfoFinder::addCompileUnit(DICompileUnit CU) { - if (!CU.Verify()) - return false; - - if (!NodesSeen.insert(CU)) - return false; - - CUs.push_back(CU); - return true; -} - -/// addGlobalVariable - Add global variable into GVs. -bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable DIG) { - if (!DIDescriptor(DIG).isGlobalVariable()) - return false; - - if (!NodesSeen.insert(DIG)) - return false; - - GVs.push_back(DIG); - return true; -} - -// addSubprogram - Add subprgoram into SPs. -bool DebugInfoFinder::addSubprogram(DISubprogram SP) { - if (!DIDescriptor(SP).isSubprogram()) - return false; - - if (!NodesSeen.insert(SP)) - return false; - - SPs.push_back(SP); - return true; -} - -/// getDISubprogram - Find subprogram that is enclosing this scope. -DISubprogram llvm::getDISubprogram(const MDNode *Scope) { - DIDescriptor D(Scope); - if (D.isSubprogram()) - return DISubprogram(Scope); - - if (D.isLexicalBlockFile()) - return getDISubprogram(DILexicalBlockFile(Scope).getContext()); - - if (D.isLexicalBlock()) - return getDISubprogram(DILexicalBlock(Scope).getContext()); - - return DISubprogram(); -} - -/// getDICompositeType - Find underlying composite type. -DICompositeType llvm::getDICompositeType(DIType T) { - if (T.isCompositeType()) - return DICompositeType(T); - - if (T.isDerivedType()) - return getDICompositeType(DIDerivedType(T).getTypeDerivedFrom()); - - return DICompositeType(); -} - -/// isSubprogramContext - Return true if Context is either a subprogram -/// or another context nested inside a subprogram. -bool llvm::isSubprogramContext(const MDNode *Context) { - if (!Context) - return false; - DIDescriptor D(Context); - if (D.isSubprogram()) - return true; - if (D.isType()) - return isSubprogramContext(DIType(Context).getContext()); - return false; -} - -//===----------------------------------------------------------------------===// -// DIDescriptor: dump routines for all descriptors. -//===----------------------------------------------------------------------===// - -/// dump - Print descriptor to dbgs() with a newline. -void DIDescriptor::dump() const { - print(dbgs()); dbgs() << '\n'; -} - -/// print - Print descriptor. -void DIDescriptor::print(raw_ostream &OS) const { - if (!DbgNode) return; - - OS << "[" << dwarf::TagString(getTag()) << ']'; - - if (this->isSubrange()) { - DISubrange(DbgNode).printInternal(OS); - } else if (this->isScope()) { - DIScope(DbgNode).printInternal(OS); - } else if (this->isCompileUnit()) { - DICompileUnit(DbgNode).printInternal(OS); - } else if (this->isFile()) { - DIFile(DbgNode).printInternal(OS); - } else if (this->isEnumerator()) { - DIEnumerator(DbgNode).printInternal(OS); - } else if (this->isBasicType()) { - DIType(DbgNode).printInternal(OS); - } else if (this->isDerivedType()) { - DIDerivedType(DbgNode).printInternal(OS); - } else if (this->isCompositeType()) { - DICompositeType(DbgNode).printInternal(OS); - } else if (this->isSubprogram()) { - DISubprogram(DbgNode).printInternal(OS); - } else if (this->isGlobalVariable()) { - DIGlobalVariable(DbgNode).printInternal(OS); - } else if (this->isVariable()) { - DIVariable(DbgNode).printInternal(OS); - } -} - -void DISubrange::printInternal(raw_ostream &OS) const { - OS << " [" << getLo() << ", " << getHi() << ']'; -} - -void DIScope::printInternal(raw_ostream &OS) const { - OS << " [" << getDirectory() << "/" << getFilename() << ']'; -} - -void DICompileUnit::printInternal(raw_ostream &OS) const { - DIScope::printInternal(OS); - if (unsigned Lang = getLanguage()) - OS << " [" << dwarf::LanguageString(Lang) << ']'; -} - -void DIEnumerator::printInternal(raw_ostream &OS) const { - OS << " [" << getName() << " :: " << getEnumValue() << ']'; -} - -void DIType::printInternal(raw_ostream &OS) const { - if (!DbgNode) return; - - StringRef Res = getName(); - if (!Res.empty()) - OS << " [" << Res << "]"; - - // TODO: Print context? - - OS << " [line " << getLineNumber() - << ", size " << getSizeInBits() - << ", align " << getAlignInBits() - << ", offset " << getOffsetInBits(); - if (isBasicType()) - OS << ", enc " - << dwarf::AttributeEncodingString(DIBasicType(DbgNode).getEncoding()); - OS << "]"; - - if (isPrivate()) - OS << " [private]"; - else if (isProtected()) - OS << " [protected]"; - - if (isForwardDecl()) - OS << " [fwd]"; -} - -void DIDerivedType::printInternal(raw_ostream &OS) const { - DIType::printInternal(OS); - OS << " [from " << getTypeDerivedFrom().getName() << ']'; -} - -void DICompositeType::printInternal(raw_ostream &OS) const { - DIType::printInternal(OS); - DIArray A = getTypeArray(); - OS << " [" << A.getNumElements() << " elements]"; -} - -void DISubprogram::printInternal(raw_ostream &OS) const { - StringRef Res = getName(); - if (!Res.empty()) - OS << " [" << Res << ']'; - - // TODO : Print context - - OS << " [line " << getLineNumber() << ']'; - - if (isLocalToUnit()) - OS << " [local]"; - - if (isDefinition()) - OS << " [def]"; - - if (getScopeLineNumber() != getLineNumber()) - OS << " [scope " << getScopeLineNumber() << "]"; -} - -void DIGlobalVariable::printInternal(raw_ostream &OS) const { - StringRef Res = getName(); - if (!Res.empty()) - OS << " [" << Res << ']'; - - OS << " [line " << getLineNumber() << ']'; - - // TODO : Print context - - if (isLocalToUnit()) - OS << " [local]"; - - if (isDefinition()) - OS << " [def]"; -} - -void DIVariable::printInternal(raw_ostream &OS) const { - StringRef Res = getName(); - if (!Res.empty()) - OS << " [" << Res << ']'; - - OS << " [line " << getLineNumber() << ']'; -} - -static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS, - const LLVMContext &Ctx) { - if (!DL.isUnknown()) { // Print source line info. - DIScope Scope(DL.getScope(Ctx)); - // Omit the directory, because it's likely to be long and uninteresting. - if (Scope.Verify()) - CommentOS << Scope.getFilename(); - else - CommentOS << ""; - CommentOS << ':' << DL.getLine(); - if (DL.getCol() != 0) - CommentOS << ':' << DL.getCol(); - DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx)); - if (!InlinedAtDL.isUnknown()) { - CommentOS << " @[ "; - printDebugLoc(InlinedAtDL, CommentOS, Ctx); - CommentOS << " ]"; - } - } -} - -void DIVariable::printExtendedName(raw_ostream &OS) const { - const LLVMContext &Ctx = DbgNode->getContext(); - StringRef Res = getName(); - if (!Res.empty()) - OS << Res << "," << getLineNumber(); - if (MDNode *InlinedAt = getInlinedAt()) { - DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt); - if (!InlinedAtDL.isUnknown()) { - OS << " @["; - printDebugLoc(InlinedAtDL, OS, Ctx); - OS << "]"; - } - } -} - -//===----------------------------------------------------------------------===// -// DIDescriptor: vtable anchors for all descriptors. -//===----------------------------------------------------------------------===// - -void DIScope::anchor() { } - -void DICompileUnit::anchor() { } - -void DIFile::anchor() { } - -void DIType::anchor() { } - -void DIBasicType::anchor() { } - -void DIDerivedType::anchor() { } - -void DICompositeType::anchor() { } - -void DISubprogram::anchor() { } - -void DILexicalBlock::anchor() { } - -void DINameSpace::anchor() { } - -void DILexicalBlockFile::anchor() { } diff --git a/lib/Analysis/ModuleDebugInfoPrinter.cpp b/lib/Analysis/ModuleDebugInfoPrinter.cpp index e7e999cebeb..f8c75148197 100644 --- a/lib/Analysis/ModuleDebugInfoPrinter.cpp +++ b/lib/Analysis/ModuleDebugInfoPrinter.cpp @@ -16,10 +16,10 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Assembly/Writer.h" -#include "llvm/Pass.h" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" +#include "llvm/Pass.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/Statistic.h" diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index d8647616ac1..d9be7a1a58f 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -15,6 +15,7 @@ #include "llvm/CodeGen/AsmPrinter.h" #include "DwarfDebug.h" #include "DwarfException.h" +#include "llvm/DebugInfo.h" #include "llvm/Module.h" #include "llvm/CodeGen/GCMetadataPrinter.h" #include "llvm/CodeGen/MachineConstantPool.h" @@ -24,7 +25,6 @@ #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/Analysis/ConstantFolding.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 45e407e27ff..b4ff9e8d69d 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -15,7 +15,7 @@ #define CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H #include "DIE.h" -#include "llvm/Analysis/DebugInfo.h" +#include "llvm/DebugInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/OwningPtr.h" diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index d0ab258b29c..3e79a6dc78b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -17,6 +17,7 @@ #include "DwarfAccelTable.h" #include "DwarfCompileUnit.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/Module.h" #include "llvm/Instructions.h" #include "llvm/ADT/Triple.h" @@ -32,7 +33,6 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Analysis/DIBuilder.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index a4580734a82..7c84c2479b6 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -14,11 +14,11 @@ #ifndef CODEGEN_ASMPRINTER_DWARFDEBUG_H__ #define CODEGEN_ASMPRINTER_DWARFDEBUG_H__ +#include "DIE.h" +#include "llvm/DebugInfo.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/LexicalScopes.h" #include "llvm/MC/MachineLocation.h" -#include "llvm/Analysis/DebugInfo.h" -#include "DIE.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallPtrSet.h" diff --git a/lib/CodeGen/LexicalScopes.cpp b/lib/CodeGen/LexicalScopes.cpp index f1abcbb1dd5..6b6b9d084e1 100644 --- a/lib/CodeGen/LexicalScopes.cpp +++ b/lib/CodeGen/LexicalScopes.cpp @@ -16,8 +16,8 @@ #define DEBUG_TYPE "lexicalscopes" #include "llvm/CodeGen/LexicalScopes.h" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/Support/Debug.h" diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index c32ce2df780..d631726538e 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -23,9 +23,9 @@ #include "LiveDebugVariables.h" #include "VirtRegMap.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/Metadata.h" #include "llvm/Value.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/LexicalScopes.h" diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index d48928b4827..d4aede8a7ef 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -26,7 +27,6 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/Analysis/ConstantFolding.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index a35978b5cde..5d16c20460c 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -13,6 +13,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" #include "llvm/InlineAsm.h" #include "llvm/LLVMContext.h" @@ -33,7 +34,6 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/LeakDetector.h" diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index 6464cf4ecc6..07dc36577f9 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -40,6 +40,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "isel" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" #include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" @@ -51,7 +52,6 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Analysis/Loads.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrInfo.h" diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index 8dde919079d..3e18ea7ac95 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -15,13 +15,13 @@ #define DEBUG_TYPE "function-lowering-info" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/CodeGen/FunctionLoweringInfo.h" +#include "llvm/DebugInfo.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" #include "llvm/Module.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 1f2fe8a8d84..a36137db4a6 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -11,7 +11,11 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/DebugInfo.h" +#include "llvm/CallingConv.h" +#include "llvm/Constants.h" +#include "llvm/DebugInfo.h" +#include "llvm/DerivedTypes.h" +#include "llvm/LLVMContext.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" @@ -20,10 +24,6 @@ #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/CallingConv.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/LLVMContext.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index ff0877c9819..a8dce2176fb 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -14,16 +14,16 @@ #include "llvm/CodeGen/SelectionDAG.h" #include "SDNodeOrdering.h" #include "SDNodeDbgValue.h" +#include "llvm/CallingConv.h" #include "llvm/Constants.h" -#include "llvm/Analysis/DebugInfo.h" -#include "llvm/Analysis/ValueTracking.h" +#include "llvm/DebugInfo.h" +#include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/GlobalAlias.h" #include "llvm/GlobalVariable.h" #include "llvm/Intrinsics.h" -#include "llvm/DerivedTypes.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/Assembly/Writer.h" -#include "llvm/CallingConv.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFrameInfo.h" diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 50fd45e88bc..0d2d9dae2bc 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -21,6 +21,7 @@ #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Constants.h" #include "llvm/CallingConv.h" +#include "llvm/DebugInfo.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/GlobalVariable.h" @@ -42,7 +43,6 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SelectionDAG.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetInstrInfo.h" diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp index 14e9ec33ebe..9fc225f9bc8 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "ScheduleDAGSDNodes.h" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" #include "llvm/Intrinsics.h" #include "llvm/Assembly/Writer.h" @@ -19,7 +20,6 @@ #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetIntrinsicInfo.h" #include "llvm/Target/TargetMachine.h" diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 4add002890a..90f2bd37b23 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -14,12 +14,8 @@ #define DEBUG_TYPE "isel" #include "ScheduleDAGSDNodes.h" #include "SelectionDAGBuilder.h" -#include "llvm/CodeGen/FunctionLoweringInfo.h" -#include "llvm/CodeGen/SelectionDAGISel.h" -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/BranchProbabilityInfo.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" @@ -27,7 +23,10 @@ #include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" #include "llvm/Module.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/CodeGen/FastISel.h" +#include "llvm/CodeGen/FunctionLoweringInfo.h" #include "llvm/CodeGen/GCStrategy.h" #include "llvm/CodeGen/GCMetadata.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -38,6 +37,7 @@ #include "llvm/CodeGen/ScheduleHazardRecognizer.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetIntrinsicInfo.h" #include "llvm/Target/TargetInstrInfo.h" diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp index 6cde05aea82..173ffac329c 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp @@ -13,13 +13,13 @@ #include "ScheduleDAGSDNodes.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Debug.h" diff --git a/lib/ExecutionEngine/EventListenerCommon.h b/lib/ExecutionEngine/EventListenerCommon.h index 1c07c947142..911d1d68b23 100644 --- a/lib/ExecutionEngine/EventListenerCommon.h +++ b/lib/ExecutionEngine/EventListenerCommon.h @@ -14,8 +14,8 @@ #ifndef EVENT_LISTENER_COMMON_H #define EVENT_LISTENER_COMMON_H +#include "llvm/DebugInfo.h" #include "llvm/Metadata.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/ValueHandle.h" #include "llvm/Support/Path.h" diff --git a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp index 5dfa78f34a3..56cea42a4f2 100644 --- a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp +++ b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp @@ -16,11 +16,11 @@ #include "llvm/ExecutionEngine/JITEventListener.h" #define DEBUG_TYPE "amplifier-jit-event-listener" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" #include "llvm/Metadata.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/ExecutionEngine/IntelJITEventsWrapper.h" #include "llvm/Support/Debug.h" diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index 0d108848b23..ff3a9dc23c5 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -17,9 +17,9 @@ #include "JITDwarfEmitter.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Constants.h" -#include "llvm/Module.h" +#include "llvm/DebugInfo.h" #include "llvm/DerivedTypes.h" -#include "llvm/Analysis/DebugInfo.h" +#include "llvm/Module.h" #include "llvm/CodeGen/JITCodeEmitter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineCodeInfo.h" diff --git a/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp b/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp index e6142e3678d..6b8e9d1954b 100644 --- a/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp +++ b/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp @@ -16,9 +16,9 @@ #include "llvm/ExecutionEngine/JITEventListener.h" #define DEBUG_TYPE "oprofile-jit-event-listener" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/ExecutionEngine/OProfileWrapper.h" #include "llvm/Support/Debug.h" diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index e4bc23e1abd..9a1ce06f3a3 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -23,8 +23,8 @@ #include "InstPrinter/ARMInstPrinter.h" #include "MCTargetDesc/ARMAddressingModes.h" #include "MCTargetDesc/ARMMCExpr.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/Module.h" #include "llvm/Type.h" #include "llvm/Assembly/Writer.h" diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index abf5d0f1b7d..0609241df2c 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -18,12 +18,12 @@ #include "MipsInstrInfo.h" #include "InstPrinter/MipsInstPrinter.h" #include "MCTargetDesc/MipsBaseInfo.h" +#include "llvm/BasicBlock.h" +#include "llvm/DebugInfo.h" +#include "llvm/Instructions.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" -#include "llvm/Analysis/DebugInfo.h" -#include "llvm/BasicBlock.h" -#include "llvm/Instructions.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFrameInfo.h" diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp index 0257e0bb1c6..c7a168a51fd 100644 --- a/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/lib/Target/Mips/MipsRegisterInfo.cpp @@ -20,6 +20,7 @@ #include "MipsSubtarget.h" #include "MipsMachineFunction.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/Type.h" #include "llvm/Function.h" #include "llvm/CodeGen/ValueTypes.h" @@ -36,7 +37,6 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Analysis/DebugInfo.h" #define GET_REGINFO_TARGET_DESC #include "MipsGenRegisterInfo.inc" diff --git a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp index d3357cace24..ade40497d16 100644 --- a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -12,17 +12,19 @@ // //===----------------------------------------------------------------------===// +#include "NVPTXAsmPrinter.h" #include "NVPTX.h" #include "NVPTXInstrInfo.h" #include "NVPTXTargetMachine.h" #include "NVPTXRegisterInfo.h" -#include "NVPTXAsmPrinter.h" +#include "NVPTXUtilities.h" #include "MCTargetDesc/NVPTXMCAsmInfo.h" #include "NVPTXNumRegisters.h" -#include "../lib/CodeGen/AsmPrinter/DwarfDebug.h" +#include "../lib/CodeGen/AsmPrinter/DwarfDebug.h" // FIXME: layering violation! #include "llvm/ADT/StringExtras.h" -#include "llvm/GlobalVariable.h" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" +#include "llvm/GlobalVariable.h" #include "llvm/Module.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -36,17 +38,13 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" #include "llvm/DerivedTypes.h" -#include "NVPTXUtilities.h" #include "llvm/Support/TimeValue.h" -#include #include "llvm/Support/CommandLine.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Support/Path.h" #include "llvm/Assembly/Writer.h" #include "cl_common_defines.h" - - +#include using namespace llvm; diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index 13a696bc598..f76b89c803a 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -22,8 +22,8 @@ #include "PPCSubtarget.h" #include "InstPrinter/PPCInstPrinter.h" #include "MCTargetDesc/PPCPredicates.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/Assembly/Writer.h" diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 97d2d9045ac..db71e275155 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -20,10 +20,10 @@ #include "X86TargetMachine.h" #include "InstPrinter/X86ATTInstPrinter.h" #include "llvm/CallingConv.h" +#include "llvm/DebugInfo.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/Type.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Assembly/Writer.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" diff --git a/lib/Target/XCore/XCoreAsmPrinter.cpp b/lib/Target/XCore/XCoreAsmPrinter.cpp index 72c6c187472..c76866f47be 100644 --- a/lib/Target/XCore/XCoreAsmPrinter.cpp +++ b/lib/Target/XCore/XCoreAsmPrinter.cpp @@ -18,9 +18,9 @@ #include "XCoreSubtarget.h" #include "XCoreTargetMachine.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" diff --git a/lib/Transforms/IPO/StripSymbols.cpp b/lib/Transforms/IPO/StripSymbols.cpp index b5caa9a557c..d8e8cf77dde 100644 --- a/lib/Transforms/IPO/StripSymbols.cpp +++ b/lib/Transforms/IPO/StripSymbols.cpp @@ -22,11 +22,11 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Pass.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/ValueSymbolTable.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/ADT/DenseMap.h" diff --git a/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/lib/Transforms/Instrumentation/GCOVProfiling.cpp index 60804794f2c..35d7d6d0a93 100644 --- a/lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ b/lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -18,7 +18,7 @@ #include "ProfilingUtils.h" #include "llvm/Transforms/Instrumentation.h" -#include "llvm/Analysis/DebugInfo.h" +#include "llvm/DebugInfo.h" #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Instructions.h" diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 1c2bbfafcd0..7994b080fb6 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -22,6 +22,7 @@ #define DEBUG_TYPE "scalarrepl" #include "llvm/Transforms/Scalar.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/GlobalVariable.h" @@ -31,7 +32,6 @@ #include "llvm/Module.h" #include "llvm/Operator.h" #include "llvm/Pass.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Analysis/DIBuilder.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/Loads.h" diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp index 20052a41227..99237b8390e 100644 --- a/lib/Transforms/Utils/CloneFunction.cpp +++ b/lib/Transforms/Utils/CloneFunction.cpp @@ -15,6 +15,7 @@ #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" @@ -28,7 +29,6 @@ #include "llvm/Transforms/Utils/ValueMapper.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/InstructionSimplify.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/ADT/SmallVector.h" #include using namespace llvm; diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index 9f8043d6fa8..7a2940f8a6e 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -14,6 +14,7 @@ #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/Instructions.h" @@ -21,7 +22,6 @@ #include "llvm/Intrinsics.h" #include "llvm/Attributes.h" #include "llvm/Analysis/CallGraph.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/Local.h" diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index ed8bfb5b80f..3bcc9f09a7a 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -14,9 +14,10 @@ #include "llvm/Transforms/Utils/Local.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" +#include "llvm/DerivedTypes.h" #include "llvm/GlobalAlias.h" #include "llvm/GlobalVariable.h" -#include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" @@ -24,7 +25,6 @@ #include "llvm/Operator.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Analysis/DIBuilder.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp index 2357d81916a..1c531038bab 100644 --- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -28,13 +28,13 @@ #define DEBUG_TYPE "mem2reg" #include "llvm/Transforms/Utils/PromoteMemToReg.h" #include "llvm/Constants.h" +#include "llvm/DebugInfo.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" #include "llvm/Metadata.h" #include "llvm/Analysis/AliasSetTracker.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Analysis/DIBuilder.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" diff --git a/lib/VMCore/DebugInfo.cpp b/lib/VMCore/DebugInfo.cpp new file mode 100644 index 00000000000..4ca4c6f9614 --- /dev/null +++ b/lib/VMCore/DebugInfo.cpp @@ -0,0 +1,1182 @@ +//===--- DebugInfo.cpp - Debug Information Helper Classes -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the helper classes used to build and interpret debug +// information in LLVM IR form. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Intrinsics.h" +#include "llvm/IntrinsicInst.h" +#include "llvm/Instructions.h" +#include "llvm/Module.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; +using namespace llvm::dwarf; + +//===----------------------------------------------------------------------===// +// DIDescriptor +//===----------------------------------------------------------------------===// + +DIDescriptor::DIDescriptor(const DIFile F) : DbgNode(F.DbgNode) { +} + +DIDescriptor::DIDescriptor(const DISubprogram F) : DbgNode(F.DbgNode) { +} + +DIDescriptor::DIDescriptor(const DILexicalBlockFile F) : DbgNode(F.DbgNode) { +} + +DIDescriptor::DIDescriptor(const DILexicalBlock F) : DbgNode(F.DbgNode) { +} + +DIDescriptor::DIDescriptor(const DIVariable F) : DbgNode(F.DbgNode) { +} + +DIDescriptor::DIDescriptor(const DIType F) : DbgNode(F.DbgNode) { +} + +StringRef +DIDescriptor::getStringField(unsigned Elt) const { + if (DbgNode == 0) + return StringRef(); + + if (Elt < DbgNode->getNumOperands()) + if (MDString *MDS = dyn_cast_or_null(DbgNode->getOperand(Elt))) + return MDS->getString(); + + return StringRef(); +} + +uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const { + if (DbgNode == 0) + return 0; + + if (Elt < DbgNode->getNumOperands()) + if (ConstantInt *CI = dyn_cast_or_null(DbgNode->getOperand(Elt))) + return CI->getZExtValue(); + + return 0; +} + +DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const { + if (DbgNode == 0) + return DIDescriptor(); + + if (Elt < DbgNode->getNumOperands()) + return + DIDescriptor(dyn_cast_or_null(DbgNode->getOperand(Elt))); + return DIDescriptor(); +} + +GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const { + if (DbgNode == 0) + return 0; + + if (Elt < DbgNode->getNumOperands()) + return dyn_cast_or_null(DbgNode->getOperand(Elt)); + return 0; +} + +Constant *DIDescriptor::getConstantField(unsigned Elt) const { + if (DbgNode == 0) + return 0; + + if (Elt < DbgNode->getNumOperands()) + return dyn_cast_or_null(DbgNode->getOperand(Elt)); + return 0; +} + +Function *DIDescriptor::getFunctionField(unsigned Elt) const { + if (DbgNode == 0) + return 0; + + if (Elt < DbgNode->getNumOperands()) + return dyn_cast_or_null(DbgNode->getOperand(Elt)); + return 0; +} + +unsigned DIVariable::getNumAddrElements() const { + if (getVersion() <= llvm::LLVMDebugVersion8) + return DbgNode->getNumOperands()-6; + if (getVersion() == llvm::LLVMDebugVersion9) + return DbgNode->getNumOperands()-7; + return DbgNode->getNumOperands()-8; +} + +/// getInlinedAt - If this variable is inlined then return inline location. +MDNode *DIVariable::getInlinedAt() const { + if (getVersion() <= llvm::LLVMDebugVersion9) + return NULL; + return dyn_cast_or_null(DbgNode->getOperand(7)); +} + +//===----------------------------------------------------------------------===// +// Predicates +//===----------------------------------------------------------------------===// + +/// isBasicType - Return true if the specified tag is legal for +/// DIBasicType. +bool DIDescriptor::isBasicType() const { + if (!DbgNode) return false; + switch (getTag()) { + case dwarf::DW_TAG_base_type: + case dwarf::DW_TAG_unspecified_type: + return true; + default: + return false; + } +} + +/// isDerivedType - Return true if the specified tag is legal for DIDerivedType. +bool DIDescriptor::isDerivedType() const { + if (!DbgNode) return false; + switch (getTag()) { + case dwarf::DW_TAG_typedef: + case dwarf::DW_TAG_pointer_type: + case dwarf::DW_TAG_reference_type: + case dwarf::DW_TAG_rvalue_reference_type: + case dwarf::DW_TAG_const_type: + case dwarf::DW_TAG_volatile_type: + case dwarf::DW_TAG_restrict_type: + case dwarf::DW_TAG_member: + case dwarf::DW_TAG_inheritance: + case dwarf::DW_TAG_friend: + return true; + default: + // CompositeTypes are currently modelled as DerivedTypes. + return isCompositeType(); + } +} + +/// isCompositeType - Return true if the specified tag is legal for +/// DICompositeType. +bool DIDescriptor::isCompositeType() const { + if (!DbgNode) return false; + switch (getTag()) { + case dwarf::DW_TAG_array_type: + case dwarf::DW_TAG_structure_type: + case dwarf::DW_TAG_union_type: + case dwarf::DW_TAG_enumeration_type: + case dwarf::DW_TAG_vector_type: + case dwarf::DW_TAG_subroutine_type: + case dwarf::DW_TAG_class_type: + return true; + default: + return false; + } +} + +/// isVariable - Return true if the specified tag is legal for DIVariable. +bool DIDescriptor::isVariable() const { + if (!DbgNode) return false; + switch (getTag()) { + case dwarf::DW_TAG_auto_variable: + case dwarf::DW_TAG_arg_variable: + case dwarf::DW_TAG_return_variable: + return true; + default: + return false; + } +} + +/// isType - Return true if the specified tag is legal for DIType. +bool DIDescriptor::isType() const { + return isBasicType() || isCompositeType() || isDerivedType(); +} + +/// isSubprogram - Return true if the specified tag is legal for +/// DISubprogram. +bool DIDescriptor::isSubprogram() const { + return DbgNode && getTag() == dwarf::DW_TAG_subprogram; +} + +/// isGlobalVariable - Return true if the specified tag is legal for +/// DIGlobalVariable. +bool DIDescriptor::isGlobalVariable() const { + return DbgNode && (getTag() == dwarf::DW_TAG_variable || + getTag() == dwarf::DW_TAG_constant); +} + +/// isGlobal - Return true if the specified tag is legal for DIGlobal. +bool DIDescriptor::isGlobal() const { + return isGlobalVariable(); +} + +/// isUnspecifiedParmeter - Return true if the specified tag is +/// DW_TAG_unspecified_parameters. +bool DIDescriptor::isUnspecifiedParameter() const { + return DbgNode && getTag() == dwarf::DW_TAG_unspecified_parameters; +} + +/// isScope - Return true if the specified tag is one of the scope +/// related tag. +bool DIDescriptor::isScope() const { + if (!DbgNode) return false; + switch (getTag()) { + case dwarf::DW_TAG_compile_unit: + case dwarf::DW_TAG_lexical_block: + case dwarf::DW_TAG_subprogram: + case dwarf::DW_TAG_namespace: + return true; + default: + break; + } + return false; +} + +/// isTemplateTypeParameter - Return true if the specified tag is +/// DW_TAG_template_type_parameter. +bool DIDescriptor::isTemplateTypeParameter() const { + return DbgNode && getTag() == dwarf::DW_TAG_template_type_parameter; +} + +/// isTemplateValueParameter - Return true if the specified tag is +/// DW_TAG_template_value_parameter. +bool DIDescriptor::isTemplateValueParameter() const { + return DbgNode && getTag() == dwarf::DW_TAG_template_value_parameter; +} + +/// isCompileUnit - Return true if the specified tag is DW_TAG_compile_unit. +bool DIDescriptor::isCompileUnit() const { + return DbgNode && getTag() == dwarf::DW_TAG_compile_unit; +} + +/// isFile - Return true if the specified tag is DW_TAG_file_type. +bool DIDescriptor::isFile() const { + return DbgNode && getTag() == dwarf::DW_TAG_file_type; +} + +/// isNameSpace - Return true if the specified tag is DW_TAG_namespace. +bool DIDescriptor::isNameSpace() const { + return DbgNode && getTag() == dwarf::DW_TAG_namespace; +} + +/// isLexicalBlockFile - Return true if the specified descriptor is a +/// lexical block with an extra file. +bool DIDescriptor::isLexicalBlockFile() const { + return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && + (DbgNode->getNumOperands() == 3); +} + +/// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block. +bool DIDescriptor::isLexicalBlock() const { + return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && + (DbgNode->getNumOperands() > 3); +} + +/// isSubrange - Return true if the specified tag is DW_TAG_subrange_type. +bool DIDescriptor::isSubrange() const { + return DbgNode && getTag() == dwarf::DW_TAG_subrange_type; +} + +/// isEnumerator - Return true if the specified tag is DW_TAG_enumerator. +bool DIDescriptor::isEnumerator() const { + return DbgNode && getTag() == dwarf::DW_TAG_enumerator; +} + +/// isObjCProperty - Return true if the specified tag is DW_TAG +bool DIDescriptor::isObjCProperty() const { + return DbgNode && getTag() == dwarf::DW_TAG_APPLE_property; +} +//===----------------------------------------------------------------------===// +// Simple Descriptor Constructors and other Methods +//===----------------------------------------------------------------------===// + +DIType::DIType(const MDNode *N) : DIScope(N) { + if (!N) return; + if (!isBasicType() && !isDerivedType() && !isCompositeType()) { + DbgNode = 0; + } +} + +unsigned DIArray::getNumElements() const { + if (!DbgNode) + return 0; + return DbgNode->getNumOperands(); +} + +/// replaceAllUsesWith - Replace all uses of debug info referenced by +/// this descriptor. +void DIType::replaceAllUsesWith(DIDescriptor &D) { + if (!DbgNode) + return; + + // Since we use a TrackingVH for the node, its easy for clients to manufacture + // legitimate situations where they want to replaceAllUsesWith() on something + // which, due to uniquing, has merged with the source. We shield clients from + // this detail by allowing a value to be replaced with replaceAllUsesWith() + // itself. + if (DbgNode != D) { + MDNode *Node = const_cast(DbgNode); + const MDNode *DN = D; + const Value *V = cast_or_null(DN); + Node->replaceAllUsesWith(const_cast(V)); + MDNode::deleteTemporary(Node); + } +} + +/// replaceAllUsesWith - Replace all uses of debug info referenced by +/// this descriptor. +void DIType::replaceAllUsesWith(MDNode *D) { + if (!DbgNode) + return; + + // Since we use a TrackingVH for the node, its easy for clients to manufacture + // legitimate situations where they want to replaceAllUsesWith() on something + // which, due to uniquing, has merged with the source. We shield clients from + // this detail by allowing a value to be replaced with replaceAllUsesWith() + // itself. + if (DbgNode != D) { + MDNode *Node = const_cast(DbgNode); + const MDNode *DN = D; + const Value *V = cast_or_null(DN); + Node->replaceAllUsesWith(const_cast(V)); + MDNode::deleteTemporary(Node); + } +} + +/// isUnsignedDIType - Return true if type encoding is unsigned. +bool DIType::isUnsignedDIType() { + DIDerivedType DTy(DbgNode); + if (DTy.Verify()) + return DTy.getTypeDerivedFrom().isUnsignedDIType(); + + DIBasicType BTy(DbgNode); + if (BTy.Verify()) { + unsigned Encoding = BTy.getEncoding(); + if (Encoding == dwarf::DW_ATE_unsigned || + Encoding == dwarf::DW_ATE_unsigned_char) + return true; + } + return false; +} + +/// Verify - Verify that a compile unit is well formed. +bool DICompileUnit::Verify() const { + if (!DbgNode) + return false; + StringRef N = getFilename(); + if (N.empty()) + return false; + // It is possible that directory and produce string is empty. + return true; +} + +/// Verify - Verify that an ObjC property is well formed. +bool DIObjCProperty::Verify() const { + if (!DbgNode) + return false; + unsigned Tag = getTag(); + if (Tag != dwarf::DW_TAG_APPLE_property) return false; + DIType Ty = getType(); + if (!Ty.Verify()) return false; + + // Don't worry about the rest of the strings for now. + return true; +} + +/// Verify - Verify that a type descriptor is well formed. +bool DIType::Verify() const { + if (!DbgNode) + return false; + if (getContext() && !getContext().Verify()) + return false; + unsigned Tag = getTag(); + if (!isBasicType() && Tag != dwarf::DW_TAG_const_type && + Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_pointer_type && + Tag != dwarf::DW_TAG_reference_type && + Tag != dwarf::DW_TAG_rvalue_reference_type && + Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_vector_type && + Tag != dwarf::DW_TAG_array_type && + Tag != dwarf::DW_TAG_enumeration_type && + Tag != dwarf::DW_TAG_subroutine_type && + getFilename().empty()) + return false; + return true; +} + +/// Verify - Verify that a basic type descriptor is well formed. +bool DIBasicType::Verify() const { + return isBasicType(); +} + +/// Verify - Verify that a derived type descriptor is well formed. +bool DIDerivedType::Verify() const { + return isDerivedType(); +} + +/// Verify - Verify that a composite type descriptor is well formed. +bool DICompositeType::Verify() const { + if (!DbgNode) + return false; + if (getContext() && !getContext().Verify()) + return false; + + return true; +} + +/// Verify - Verify that a subprogram descriptor is well formed. +bool DISubprogram::Verify() const { + if (!DbgNode) + return false; + + if (getContext() && !getContext().Verify()) + return false; + + DICompositeType Ty = getType(); + if (!Ty.Verify()) + return false; + return true; +} + +/// Verify - Verify that a global variable descriptor is well formed. +bool DIGlobalVariable::Verify() const { + if (!DbgNode) + return false; + + if (getDisplayName().empty()) + return false; + + if (getContext() && !getContext().Verify()) + return false; + + DIType Ty = getType(); + if (!Ty.Verify()) + return false; + + if (!getGlobal() && !getConstant()) + return false; + + return true; +} + +/// Verify - Verify that a variable descriptor is well formed. +bool DIVariable::Verify() const { + if (!DbgNode) + return false; + + if (getContext() && !getContext().Verify()) + return false; + + DIType Ty = getType(); + if (!Ty.Verify()) + return false; + + return true; +} + +/// Verify - Verify that a location descriptor is well formed. +bool DILocation::Verify() const { + if (!DbgNode) + return false; + + return DbgNode->getNumOperands() == 4; +} + +/// Verify - Verify that a namespace descriptor is well formed. +bool DINameSpace::Verify() const { + if (!DbgNode) + return false; + if (getName().empty()) + return false; + return true; +} + +/// getOriginalTypeSize - If this type is derived from a base type then +/// return base type size. +uint64_t DIDerivedType::getOriginalTypeSize() const { + unsigned Tag = getTag(); + + if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef && + Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type && + Tag != dwarf::DW_TAG_restrict_type) + return getSizeInBits(); + + DIType BaseType = getTypeDerivedFrom(); + + // If this type is not derived from any type then take conservative approach. + if (!BaseType.isValid()) + return getSizeInBits(); + + // If this is a derived type, go ahead and get the base type, unless it's a + // reference then it's just the size of the field. Pointer types have no need + // of this since they're a different type of qualification on the type. + if (BaseType.getTag() == dwarf::DW_TAG_reference_type || + BaseType.getTag() == dwarf::DW_TAG_rvalue_reference_type) + return getSizeInBits(); + + if (BaseType.isDerivedType()) + return DIDerivedType(BaseType).getOriginalTypeSize(); + + return BaseType.getSizeInBits(); +} + +/// getObjCProperty - Return property node, if this ivar is associated with one. +MDNode *DIDerivedType::getObjCProperty() const { + if (getVersion() <= LLVMDebugVersion11 || DbgNode->getNumOperands() <= 10) + return NULL; + return dyn_cast_or_null(DbgNode->getOperand(10)); +} + +/// isInlinedFnArgument - Return true if this variable provides debugging +/// information for an inlined function arguments. +bool DIVariable::isInlinedFnArgument(const Function *CurFn) { + assert(CurFn && "Invalid function"); + if (!getContext().isSubprogram()) + return false; + // This variable is not inlined function argument if its scope + // does not describe current function. + return !DISubprogram(getContext()).describes(CurFn); +} + +/// describes - Return true if this subprogram provides debugging +/// information for the function F. +bool DISubprogram::describes(const Function *F) { + assert(F && "Invalid function"); + if (F == getFunction()) + return true; + StringRef Name = getLinkageName(); + if (Name.empty()) + Name = getName(); + if (F->getName() == Name) + return true; + return false; +} + +unsigned DISubprogram::isOptimized() const { + assert (DbgNode && "Invalid subprogram descriptor!"); + if (DbgNode->getNumOperands() == 16) + return getUnsignedField(15); + return 0; +} + +MDNode *DISubprogram::getVariablesNodes() const { + if (!DbgNode || DbgNode->getNumOperands() <= 19) + return NULL; + if (MDNode *Temp = dyn_cast_or_null(DbgNode->getOperand(19))) + return dyn_cast_or_null(Temp->getOperand(0)); + return NULL; +} + +DIArray DISubprogram::getVariables() const { + if (!DbgNode || DbgNode->getNumOperands() <= 19) + return DIArray(); + if (MDNode *T = dyn_cast_or_null(DbgNode->getOperand(19))) + if (MDNode *A = dyn_cast_or_null(T->getOperand(0))) + return DIArray(A); + return DIArray(); +} + +StringRef DIScope::getFilename() const { + if (!DbgNode) + return StringRef(); + if (isLexicalBlockFile()) + return DILexicalBlockFile(DbgNode).getFilename(); + if (isLexicalBlock()) + return DILexicalBlock(DbgNode).getFilename(); + if (isSubprogram()) + return DISubprogram(DbgNode).getFilename(); + if (isCompileUnit()) + return DICompileUnit(DbgNode).getFilename(); + if (isNameSpace()) + return DINameSpace(DbgNode).getFilename(); + if (isType()) + return DIType(DbgNode).getFilename(); + if (isFile()) + return DIFile(DbgNode).getFilename(); + llvm_unreachable("Invalid DIScope!"); +} + +StringRef DIScope::getDirectory() const { + if (!DbgNode) + return StringRef(); + if (isLexicalBlockFile()) + return DILexicalBlockFile(DbgNode).getDirectory(); + if (isLexicalBlock()) + return DILexicalBlock(DbgNode).getDirectory(); + if (isSubprogram()) + return DISubprogram(DbgNode).getDirectory(); + if (isCompileUnit()) + return DICompileUnit(DbgNode).getDirectory(); + if (isNameSpace()) + return DINameSpace(DbgNode).getDirectory(); + if (isType()) + return DIType(DbgNode).getDirectory(); + if (isFile()) + return DIFile(DbgNode).getDirectory(); + llvm_unreachable("Invalid DIScope!"); +} + +DIArray DICompileUnit::getEnumTypes() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(10))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + +DIArray DICompileUnit::getRetainedTypes() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(11))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + +DIArray DICompileUnit::getSubprograms() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(12))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + + +DIArray DICompileUnit::getGlobalVariables() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(13))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + +/// fixupObjcLikeName - Replace contains special characters used +/// in a typical Objective-C names with '.' in a given string. +static void fixupObjcLikeName(StringRef Str, SmallVectorImpl &Out) { + bool isObjCLike = false; + for (size_t i = 0, e = Str.size(); i < e; ++i) { + char C = Str[i]; + if (C == '[') + isObjCLike = true; + + if (isObjCLike && (C == '[' || C == ']' || C == ' ' || C == ':' || + C == '+' || C == '(' || C == ')')) + Out.push_back('.'); + else + Out.push_back(C); + } +} + +/// getFnSpecificMDNode - Return a NameMDNode, if available, that is +/// suitable to hold function specific information. +NamedMDNode *llvm::getFnSpecificMDNode(const Module &M, DISubprogram Fn) { + SmallString<32> Name = StringRef("llvm.dbg.lv."); + StringRef FName = "fn"; + if (Fn.getFunction()) + FName = Fn.getFunction()->getName(); + else + FName = Fn.getName(); + char One = '\1'; + if (FName.startswith(StringRef(&One, 1))) + FName = FName.substr(1); + fixupObjcLikeName(FName, Name); + return M.getNamedMetadata(Name.str()); +} + +/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable +/// to hold function specific information. +NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, DISubprogram Fn) { + SmallString<32> Name = StringRef("llvm.dbg.lv."); + StringRef FName = "fn"; + if (Fn.getFunction()) + FName = Fn.getFunction()->getName(); + else + FName = Fn.getName(); + char One = '\1'; + if (FName.startswith(StringRef(&One, 1))) + FName = FName.substr(1); + fixupObjcLikeName(FName, Name); + + return M.getOrInsertNamedMetadata(Name.str()); +} + +/// createInlinedVariable - Create a new inlined variable based on current +/// variable. +/// @param DV Current Variable. +/// @param InlinedScope Location at current variable is inlined. +DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope, + LLVMContext &VMContext) { + SmallVector Elts; + // Insert inlined scope as 7th element. + for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i) + i == 7 ? Elts.push_back(InlinedScope) : + Elts.push_back(DV->getOperand(i)); + return DIVariable(MDNode::get(VMContext, Elts)); +} + +/// cleanseInlinedVariable - Remove inlined scope from the variable. +DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) { + SmallVector Elts; + // Insert inlined scope as 7th element. + for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i) + i == 7 ? + Elts.push_back(llvm::Constant::getNullValue(Type::getInt32Ty(VMContext))): + Elts.push_back(DV->getOperand(i)); + return DIVariable(MDNode::get(VMContext, Elts)); +} + +/// getDISubprogram - Find subprogram that is enclosing this scope. +DISubprogram llvm::getDISubprogram(const MDNode *Scope) { + DIDescriptor D(Scope); + if (D.isSubprogram()) + return DISubprogram(Scope); + + if (D.isLexicalBlockFile()) + return getDISubprogram(DILexicalBlockFile(Scope).getContext()); + + if (D.isLexicalBlock()) + return getDISubprogram(DILexicalBlock(Scope).getContext()); + + return DISubprogram(); +} + +/// getDICompositeType - Find underlying composite type. +DICompositeType llvm::getDICompositeType(DIType T) { + if (T.isCompositeType()) + return DICompositeType(T); + + if (T.isDerivedType()) + return getDICompositeType(DIDerivedType(T).getTypeDerivedFrom()); + + return DICompositeType(); +} + +/// isSubprogramContext - Return true if Context is either a subprogram +/// or another context nested inside a subprogram. +bool llvm::isSubprogramContext(const MDNode *Context) { + if (!Context) + return false; + DIDescriptor D(Context); + if (D.isSubprogram()) + return true; + if (D.isType()) + return isSubprogramContext(DIType(Context).getContext()); + return false; +} + +//===----------------------------------------------------------------------===// +// DebugInfoFinder implementations. +//===----------------------------------------------------------------------===// + +/// processModule - Process entire module and collect debug info. +void DebugInfoFinder::processModule(Module &M) { + if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) { + for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { + DICompileUnit CU(CU_Nodes->getOperand(i)); + addCompileUnit(CU); + if (CU.getVersion() > LLVMDebugVersion10) { + DIArray GVs = CU.getGlobalVariables(); + for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) { + DIGlobalVariable DIG(GVs.getElement(i)); + if (addGlobalVariable(DIG)) + processType(DIG.getType()); + } + DIArray SPs = CU.getSubprograms(); + for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) + processSubprogram(DISubprogram(SPs.getElement(i))); + DIArray EnumTypes = CU.getEnumTypes(); + for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) + processType(DIType(EnumTypes.getElement(i))); + DIArray RetainedTypes = CU.getRetainedTypes(); + for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) + processType(DIType(RetainedTypes.getElement(i))); + return; + } + } + } + + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI) + for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end(); BI != BE; + ++BI) { + if (DbgDeclareInst *DDI = dyn_cast(BI)) + processDeclare(DDI); + + DebugLoc Loc = BI->getDebugLoc(); + if (Loc.isUnknown()) + continue; + + LLVMContext &Ctx = BI->getContext(); + DIDescriptor Scope(Loc.getScope(Ctx)); + + if (Scope.isCompileUnit()) + addCompileUnit(DICompileUnit(Scope)); + else if (Scope.isSubprogram()) + processSubprogram(DISubprogram(Scope)); + else if (Scope.isLexicalBlockFile()) { + DILexicalBlockFile DBF = DILexicalBlockFile(Scope); + processLexicalBlock(DILexicalBlock(DBF.getScope())); + } + else if (Scope.isLexicalBlock()) + processLexicalBlock(DILexicalBlock(Scope)); + + if (MDNode *IA = Loc.getInlinedAt(Ctx)) + processLocation(DILocation(IA)); + } + + if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv")) { + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + DIGlobalVariable DIG(cast(NMD->getOperand(i))); + if (addGlobalVariable(DIG)) { + if (DIG.getVersion() <= LLVMDebugVersion10) + addCompileUnit(DIG.getCompileUnit()); + processType(DIG.getType()); + } + } + } + + if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) + processSubprogram(DISubprogram(NMD->getOperand(i))); +} + +/// processLocation - Process DILocation. +void DebugInfoFinder::processLocation(DILocation Loc) { + if (!Loc.Verify()) return; + DIDescriptor S(Loc.getScope()); + if (S.isCompileUnit()) + addCompileUnit(DICompileUnit(S)); + else if (S.isSubprogram()) + processSubprogram(DISubprogram(S)); + else if (S.isLexicalBlock()) + processLexicalBlock(DILexicalBlock(S)); + else if (S.isLexicalBlockFile()) { + DILexicalBlockFile DBF = DILexicalBlockFile(S); + processLexicalBlock(DILexicalBlock(DBF.getScope())); + } + processLocation(Loc.getOrigLocation()); +} + +/// processType - Process DIType. +void DebugInfoFinder::processType(DIType DT) { + if (!addType(DT)) + return; + if (DT.getVersion() <= LLVMDebugVersion10) + addCompileUnit(DT.getCompileUnit()); + if (DT.isCompositeType()) { + DICompositeType DCT(DT); + processType(DCT.getTypeDerivedFrom()); + DIArray DA = DCT.getTypeArray(); + for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) { + DIDescriptor D = DA.getElement(i); + if (D.isType()) + processType(DIType(D)); + else if (D.isSubprogram()) + processSubprogram(DISubprogram(D)); + } + } else if (DT.isDerivedType()) { + DIDerivedType DDT(DT); + processType(DDT.getTypeDerivedFrom()); + } +} + +/// processLexicalBlock +void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { + DIScope Context = LB.getContext(); + if (Context.isLexicalBlock()) + return processLexicalBlock(DILexicalBlock(Context)); + else if (Context.isLexicalBlockFile()) { + DILexicalBlockFile DBF = DILexicalBlockFile(Context); + return processLexicalBlock(DILexicalBlock(DBF.getScope())); + } + else + return processSubprogram(DISubprogram(Context)); +} + +/// processSubprogram - Process DISubprogram. +void DebugInfoFinder::processSubprogram(DISubprogram SP) { + if (!addSubprogram(SP)) + return; + if (SP.getVersion() <= LLVMDebugVersion10) + addCompileUnit(SP.getCompileUnit()); + processType(SP.getType()); +} + +/// processDeclare - Process DbgDeclareInst. +void DebugInfoFinder::processDeclare(DbgDeclareInst *DDI) { + MDNode *N = dyn_cast(DDI->getVariable()); + if (!N) return; + + DIDescriptor DV(N); + if (!DV.isVariable()) + return; + + if (!NodesSeen.insert(DV)) + return; + if (DIVariable(N).getVersion() <= LLVMDebugVersion10) + addCompileUnit(DIVariable(N).getCompileUnit()); + processType(DIVariable(N).getType()); +} + +/// addType - Add type into Tys. +bool DebugInfoFinder::addType(DIType DT) { + if (!DT.isValid()) + return false; + + if (!NodesSeen.insert(DT)) + return false; + + TYs.push_back(DT); + return true; +} + +/// addCompileUnit - Add compile unit into CUs. +bool DebugInfoFinder::addCompileUnit(DICompileUnit CU) { + if (!CU.Verify()) + return false; + + if (!NodesSeen.insert(CU)) + return false; + + CUs.push_back(CU); + return true; +} + +/// addGlobalVariable - Add global variable into GVs. +bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable DIG) { + if (!DIDescriptor(DIG).isGlobalVariable()) + return false; + + if (!NodesSeen.insert(DIG)) + return false; + + GVs.push_back(DIG); + return true; +} + +// addSubprogram - Add subprgoram into SPs. +bool DebugInfoFinder::addSubprogram(DISubprogram SP) { + if (!DIDescriptor(SP).isSubprogram()) + return false; + + if (!NodesSeen.insert(SP)) + return false; + + SPs.push_back(SP); + return true; +} + +//===----------------------------------------------------------------------===// +// DIDescriptor: dump routines for all descriptors. +//===----------------------------------------------------------------------===// + +/// dump - Print descriptor to dbgs() with a newline. +void DIDescriptor::dump() const { + print(dbgs()); dbgs() << '\n'; +} + +/// print - Print descriptor. +void DIDescriptor::print(raw_ostream &OS) const { + if (!DbgNode) return; + + OS << "[" << dwarf::TagString(getTag()) << ']'; + + if (this->isSubrange()) { + DISubrange(DbgNode).printInternal(OS); + } else if (this->isScope()) { + DIScope(DbgNode).printInternal(OS); + } else if (this->isCompileUnit()) { + DICompileUnit(DbgNode).printInternal(OS); + } else if (this->isFile()) { + DIFile(DbgNode).printInternal(OS); + } else if (this->isEnumerator()) { + DIEnumerator(DbgNode).printInternal(OS); + } else if (this->isBasicType()) { + DIType(DbgNode).printInternal(OS); + } else if (this->isDerivedType()) { + DIDerivedType(DbgNode).printInternal(OS); + } else if (this->isCompositeType()) { + DICompositeType(DbgNode).printInternal(OS); + } else if (this->isSubprogram()) { + DISubprogram(DbgNode).printInternal(OS); + } else if (this->isGlobalVariable()) { + DIGlobalVariable(DbgNode).printInternal(OS); + } else if (this->isVariable()) { + DIVariable(DbgNode).printInternal(OS); + } +} + +void DISubrange::printInternal(raw_ostream &OS) const { + OS << " [" << getLo() << ", " << getHi() << ']'; +} + +void DIScope::printInternal(raw_ostream &OS) const { + OS << " [" << getDirectory() << "/" << getFilename() << ']'; +} + +void DICompileUnit::printInternal(raw_ostream &OS) const { + DIScope::printInternal(OS); + if (unsigned Lang = getLanguage()) + OS << " [" << dwarf::LanguageString(Lang) << ']'; +} + +void DIEnumerator::printInternal(raw_ostream &OS) const { + OS << " [" << getName() << " :: " << getEnumValue() << ']'; +} + +void DIType::printInternal(raw_ostream &OS) const { + if (!DbgNode) return; + + StringRef Res = getName(); + if (!Res.empty()) + OS << " [" << Res << "]"; + + // TODO: Print context? + + OS << " [line " << getLineNumber() + << ", size " << getSizeInBits() + << ", align " << getAlignInBits() + << ", offset " << getOffsetInBits(); + if (isBasicType()) + OS << ", enc " + << dwarf::AttributeEncodingString(DIBasicType(DbgNode).getEncoding()); + OS << "]"; + + if (isPrivate()) + OS << " [private]"; + else if (isProtected()) + OS << " [protected]"; + + if (isForwardDecl()) + OS << " [fwd]"; +} + +void DIDerivedType::printInternal(raw_ostream &OS) const { + DIType::printInternal(OS); + OS << " [from " << getTypeDerivedFrom().getName() << ']'; +} + +void DICompositeType::printInternal(raw_ostream &OS) const { + DIType::printInternal(OS); + DIArray A = getTypeArray(); + OS << " [" << A.getNumElements() << " elements]"; +} + +void DISubprogram::printInternal(raw_ostream &OS) const { + StringRef Res = getName(); + if (!Res.empty()) + OS << " [" << Res << ']'; + + // TODO : Print context + + OS << " [line " << getLineNumber() << ']'; + + if (isLocalToUnit()) + OS << " [local]"; + + if (isDefinition()) + OS << " [def]"; + + if (getScopeLineNumber() != getLineNumber()) + OS << " [scope " << getScopeLineNumber() << "]"; +} + +void DIGlobalVariable::printInternal(raw_ostream &OS) const { + StringRef Res = getName(); + if (!Res.empty()) + OS << " [" << Res << ']'; + + OS << " [line " << getLineNumber() << ']'; + + // TODO : Print context + + if (isLocalToUnit()) + OS << " [local]"; + + if (isDefinition()) + OS << " [def]"; +} + +void DIVariable::printInternal(raw_ostream &OS) const { + StringRef Res = getName(); + if (!Res.empty()) + OS << " [" << Res << ']'; + + OS << " [line " << getLineNumber() << ']'; +} + +static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS, + const LLVMContext &Ctx) { + if (!DL.isUnknown()) { // Print source line info. + DIScope Scope(DL.getScope(Ctx)); + // Omit the directory, because it's likely to be long and uninteresting. + if (Scope.Verify()) + CommentOS << Scope.getFilename(); + else + CommentOS << ""; + CommentOS << ':' << DL.getLine(); + if (DL.getCol() != 0) + CommentOS << ':' << DL.getCol(); + DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx)); + if (!InlinedAtDL.isUnknown()) { + CommentOS << " @[ "; + printDebugLoc(InlinedAtDL, CommentOS, Ctx); + CommentOS << " ]"; + } + } +} + +void DIVariable::printExtendedName(raw_ostream &OS) const { + const LLVMContext &Ctx = DbgNode->getContext(); + StringRef Res = getName(); + if (!Res.empty()) + OS << Res << "," << getLineNumber(); + if (MDNode *InlinedAt = getInlinedAt()) { + DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt); + if (!InlinedAtDL.isUnknown()) { + OS << " @["; + printDebugLoc(InlinedAtDL, OS, Ctx); + OS << "]"; + } + } +} + +//===----------------------------------------------------------------------===// +// DIDescriptor: vtable anchors for all descriptors. +//===----------------------------------------------------------------------===// + +void DIScope::anchor() { } + +void DICompileUnit::anchor() { } + +void DIFile::anchor() { } + +void DIType::anchor() { } + +void DIBasicType::anchor() { } + +void DIDerivedType::anchor() { } + +void DICompositeType::anchor() { } + +void DISubprogram::anchor() { } + +void DILexicalBlock::anchor() { } + +void DINameSpace::anchor() { } + +void DILexicalBlockFile::anchor() { } diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp index 29af7515ae8..41f023d4c43 100644 --- a/tools/llvm-dis/llvm-dis.cpp +++ b/tools/llvm-dis/llvm-dis.cpp @@ -17,11 +17,11 @@ //===----------------------------------------------------------------------===// #include "llvm/LLVMContext.h" +#include "llvm/DebugInfo.h" #include "llvm/Module.h" #include "llvm/Type.h" #include "llvm/IntrinsicInst.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Assembly/AssemblyAnnotationWriter.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/DataStream.h" diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index d9758b35ff9..4ada7d1e76d 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -13,12 +13,12 @@ //===----------------------------------------------------------------------===// #include "llvm/LLVMContext.h" +#include "llvm/DebugInfo.h" #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/CallGraphSCCPass.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Assembly/PrintModulePass.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/RegionPass.h" diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h index 53608cbfce3..41b09260e56 100644 --- a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h +++ b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h @@ -10,14 +10,14 @@ #ifndef JIT_EVENT_LISTENER_TEST_COMMON_H #define JIT_EVENT_LISTENER_TEST_COMMON_H +#include "llvm/DebugInfo.h" +#include "llvm/Instructions.h" +#include "llvm/Module.h" #include "llvm/Analysis/DIBuilder.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/CodeGen/MachineCodeInfo.h" #include "llvm/Config/config.h" #include "llvm/ExecutionEngine/JIT.h" #include "llvm/ExecutionEngine/JITEventListener.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" #include "llvm/Support/IRBuilder.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/TypeBuilder.h"