#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Dwarf.h" // FIXME: Should not need this.
+#include "llvm/Support/Dwarf.h"
namespace llvm {
class BasicBlock;
class Module;
class Type;
class Value;
- struct DbgStopPointInst;
- struct DbgDeclareInst;
- struct DbgFuncStartInst;
- struct DbgRegionStartInst;
- struct DbgRegionEndInst;
- class DebugLoc;
- struct DebugLocTracker;
+ class DbgDeclareInst;
class Instruction;
class MDNode;
class LLVMContext;
protected:
MDNode *DbgNode;
- /// DIDescriptor constructor. If the specified node is non-null, check
- /// to make sure that the tag in the descriptor matches 'RequiredTag'. If
- /// not, the debug info is corrupt and we ignore it.
- DIDescriptor(MDNode *N, unsigned RequiredTag);
-
StringRef getStringField(unsigned Elt) const;
unsigned getUnsignedField(unsigned Elt) const {
return (unsigned)getUInt64Field(Elt);
explicit DIDescriptor() : DbgNode(0) {}
explicit DIDescriptor(MDNode *N) : DbgNode(N) {}
- bool isNull() const { return DbgNode == 0; }
+ bool Verify() const { return DbgNode != 0; }
MDNode *getNode() const { return DbgNode; }
bool isSubprogram() const;
bool isGlobalVariable() const;
bool isScope() const;
+ bool isFile() const;
bool isCompileUnit() const;
bool isNameSpace() const;
bool isLexicalBlock() const;
/// DISubrange - This is used to represent ranges, for array bounds.
class DISubrange : public DIDescriptor {
public:
- explicit DISubrange(MDNode *N = 0)
- : DIDescriptor(N, dwarf::DW_TAG_subrange_type) {}
+ explicit DISubrange(MDNode *N = 0) : DIDescriptor(N) {}
int64_t getLo() const { return (int64_t)getUInt64Field(1); }
int64_t getHi() const { return (int64_t)getUInt64Field(2); }
/// DIScope - A base class for various scopes.
class DIScope : public DIDescriptor {
public:
- explicit DIScope(MDNode *N = 0) : DIDescriptor (N) {
- if (DbgNode && !isScope())
- DbgNode = 0;
- }
+ explicit DIScope(MDNode *N = 0) : DIDescriptor (N) {}
virtual ~DIScope() {}
StringRef getFilename() const;
/// DICompileUnit - A wrapper for a compile unit.
class DICompileUnit : public DIScope {
public:
- explicit DICompileUnit(MDNode *N = 0) : DIScope(N) {
- if (DbgNode && !isCompileUnit())
- DbgNode = 0;
- }
+ explicit DICompileUnit(MDNode *N = 0) : DIScope(N) {}
unsigned getLanguage() const { return getUnsignedField(2); }
StringRef getFilename() const { return getStringField(3); }
void dump() const;
};
+ /// DIFile - This is a wrapper for a file.
+ class DIFile : public DIScope {
+ public:
+ explicit DIFile(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{ return getFieldAs<DICompileUnit>(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 {
public:
- explicit DIEnumerator(MDNode *N = 0)
- : DIDescriptor(N, dwarf::DW_TAG_enumerator) {}
+ explicit DIEnumerator(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 DIDescriptor {
+ class DIType : public DIScope {
public:
enum {
FlagPrivate = 1 << 0,
FlagFwdDecl = 1 << 2,
FlagAppleBlock = 1 << 3,
FlagBlockByrefStruct = 1 << 4,
- FlagVirtual = 1 << 5
+ FlagVirtual = 1 << 5,
+ FlagArtificial = 1 << 6 // To identify artificial arguments in
+ // a subroutine type. e.g. "this" in c++.
};
protected:
- DIType(MDNode *N, unsigned Tag)
- : DIDescriptor(N, Tag) {}
// This ctor is used when the Tag has already been validated by a derived
// ctor.
- DIType(MDNode *N, bool, bool) : DIDescriptor(N) {}
+ DIType(MDNode *N, bool, bool) : DIScope(N) {}
public:
explicit DIType() {}
virtual ~DIType() {}
- DIDescriptor getContext() const { return getDescriptorField(1); }
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
- DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
+ DICompileUnit getCompileUnit() const{
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs<DICompileUnit>(3);
+
+ DIFile F = getFieldAs<DIFile>(3);
+ return F.getCompileUnit();
+ }
unsigned getLineNumber() const { return getUnsignedField(4); }
uint64_t getSizeInBits() const { return getUInt64Field(5); }
uint64_t getAlignInBits() const { return getUInt64Field(6); }
bool isVirtual() const {
return (getFlags() & FlagVirtual) != 0;
}
-
+ bool isArtificial() const {
+ return (getFlags() & FlagArtificial) != 0;
+ }
+ bool isValid() const {
+ return DbgNode && (isBasicType() || isDerivedType() || isCompositeType());
+ }
+ StringRef getFilename() const { return getCompileUnit().getFilename();}
+ StringRef getDirectory() const { return getCompileUnit().getDirectory();}
/// dump - print type.
void dump() const;
};
/// DIBasicType - A basic type, like 'int' or 'float'.
class DIBasicType : public DIType {
public:
- explicit DIBasicType(MDNode *N = 0)
- : DIType(N, dwarf::DW_TAG_base_type) {}
+ explicit DIBasicType(MDNode *N = 0) : DIType(N) {}
unsigned getEncoding() const { return getUnsignedField(9); }
: DIType(N, true, true) {}
public:
explicit DIDerivedType(MDNode *N = 0)
- : DIType(N, true, true) {
- if (DbgNode && !isDerivedType())
- DbgNode = 0;
- }
+ : DIType(N, true, true) {}
DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
unsigned getRunTimeLang() const { return getUnsignedField(11); }
+ DICompositeType getContainingType() const {
+ return getFieldAs<DICompositeType>(12);
+ }
/// Verify - Verify that a composite type descriptor is well formed.
bool Verify() const;
/// DIGlobal - This is a common class for global variables and subprograms.
class DIGlobal : public DIDescriptor {
protected:
- explicit DIGlobal(MDNode *N, unsigned RequiredTag)
- : DIDescriptor(N, RequiredTag) {}
+ explicit DIGlobal(MDNode *N) : DIDescriptor(N) {}
public:
virtual ~DIGlobal() {}
- DIDescriptor getContext() const { return getDescriptorField(2); }
+ DIScope getContext() const { return getFieldAs<DIScope>(2); }
StringRef getName() const { return getStringField(3); }
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
- DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(6); }
+ DICompileUnit getCompileUnit() const{
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs<DICompileUnit>(6);
+
+ DIFile F = getFieldAs<DIFile>(6);
+ return F.getCompileUnit();
+ }
+
unsigned getLineNumber() const { return getUnsignedField(7); }
DIType getType() const { return getFieldAs<DIType>(8); }
/// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
class DISubprogram : public DIScope {
public:
- explicit DISubprogram(MDNode *N = 0) : DIScope(N) {
- if (DbgNode && !isSubprogram())
- DbgNode = 0;
- }
+ explicit DISubprogram(MDNode *N = 0) : DIScope(N) {}
- DIDescriptor getContext() const { return getDescriptorField(2); }
+ DIScope getContext() const { return getFieldAs<DIScope>(2); }
StringRef getName() const { return getStringField(3); }
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
- DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(6); }
+ DICompileUnit getCompileUnit() const{
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs<DICompileUnit>(6);
+
+ DIFile F = getFieldAs<DIFile>(6);
+ return F.getCompileUnit();
+ }
unsigned getLineNumber() const { return getUnsignedField(7); }
DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
/// DIType or as DICompositeType.
StringRef getReturnTypeName() const {
DICompositeType DCT(getFieldAs<DICompositeType>(8));
- if (!DCT.isNull()) {
+ if (DCT.Verify()) {
DIArray A = DCT.getTypeArray();
DIType T(A.getElement(0).getNode());
return T.getName();
DICompositeType getContainingType() const {
return getFieldAs<DICompositeType>(13);
}
+ unsigned isArtificial() const { return getUnsignedField(14); }
- StringRef getFilename() const { return getCompileUnit().getFilename();}
- StringRef getDirectory() const { return getCompileUnit().getDirectory();}
+ StringRef getFilename() const {
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getCompileUnit().getFilename();
+
+ DIFile F = getFieldAs<DIFile>(6);
+ return F.getFilename();
+ }
+
+ StringRef getDirectory() const {
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getCompileUnit().getFilename();
+
+ DIFile F = getFieldAs<DIFile>(6);
+ return F.getDirectory();
+ }
/// Verify - Verify that a subprogram descriptor is well formed.
bool Verify() const;
/// DIGlobalVariable - This is a wrapper for a global variable.
class DIGlobalVariable : public DIGlobal {
public:
- explicit DIGlobalVariable(MDNode *N = 0)
- : DIGlobal(N, dwarf::DW_TAG_variable) {}
+ explicit DIGlobalVariable(MDNode *N = 0) : DIGlobal(N) {}
GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
class DIVariable : public DIDescriptor {
public:
explicit DIVariable(MDNode *N = 0)
- : DIDescriptor(N) {
- if (DbgNode && !isVariable())
- DbgNode = 0;
- }
+ : DIDescriptor(N) {}
- DIDescriptor getContext() const { return getDescriptorField(1); }
- StringRef getName() const { return getStringField(2); }
- DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ StringRef getName() const { return getStringField(2); }
+ DICompileUnit getCompileUnit() const{
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs<DICompileUnit>(3);
+
+ DIFile F = getFieldAs<DIFile>(3);
+ return F.getCompileUnit();
+ }
unsigned getLineNumber() const { return getUnsignedField(4); }
DIType getType() const { return getFieldAs<DIType>(5); }
/// DILexicalBlock - This is a wrapper for a lexical block.
class DILexicalBlock : public DIScope {
public:
- explicit DILexicalBlock(MDNode *N = 0) : DIScope(N) {
- if (DbgNode && !isLexicalBlock())
- DbgNode = 0;
- }
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- StringRef getDirectory() const { return getContext().getDirectory(); }
- StringRef getFilename() const { return getContext().getFilename(); }
+ explicit DILexicalBlock(MDNode *N = 0) : DIScope(N) {}
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ StringRef getDirectory() const { return getContext().getDirectory(); }
+ StringRef getFilename() const { return getContext().getFilename(); }
+ unsigned getLineNumber() const { return getUnsignedField(2); }
+ unsigned getColumnNumber() const { return getUnsignedField(3); }
};
/// DINameSpace - A wrapper for a C++ style name space.
class DINameSpace : public DIScope {
public:
- explicit DINameSpace(MDNode *N = 0) : DIScope(N) {
- if (DbgNode && !isNameSpace())
- DbgNode = 0;
- }
-
+ explicit DINameSpace(MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
StringRef getDirectory() const { return getContext().getDirectory(); }
StringRef getFilename() const { return getContext().getFilename(); }
- DICompileUnit getCompileUnit() const { return getFieldAs<DICompileUnit>(3);}
+ DICompileUnit getCompileUnit() const{
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs<DICompileUnit>(3);
+
+ DIFile F = getFieldAs<DIFile>(3);
+ return F.getCompileUnit();
+ }
unsigned getLineNumber() const { return getUnsignedField(4); }
};
/// is not associated with any DWARF tag.
class DILocation : public DIDescriptor {
public:
- explicit DILocation(MDNode *N) : DIDescriptor(N) { ; }
+ explicit DILocation(MDNode *N) : DIDescriptor(N) { }
unsigned getLineNumber() const { return getUnsignedField(0); }
unsigned getColumnNumber() const { return getUnsignedField(1); }
DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); }
StringRef getFilename() const { return getScope().getFilename(); }
StringRef getDirectory() const { return getScope().getDirectory(); }
+ bool Verify() const;
};
/// DIFactory - This object assists with the construction of the various
Module &M;
LLVMContext& VMContext;
- const Type *EmptyStructPtr; // "{}*".
Function *DeclareFn; // llvm.dbg.declare
Function *ValueFn; // llvm.dbg.value
StringRef Flags = "",
unsigned RunTimeVer = 0);
+ /// CreateFile - Create a new descriptor for the specified file.
+ DIFile CreateFile(StringRef Filename, StringRef Directory, DICompileUnit CU);
+
/// CreateEnumerator - Create a single enumerator value.
DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val);
/// CreateBasicType - Create a basic type like int, float, etc.
DIBasicType CreateBasicType(DIDescriptor Context, StringRef Name,
- DICompileUnit CompileUnit, unsigned LineNumber,
+ DIFile F, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
unsigned Encoding);
/// CreateBasicType - Create a basic type like int, float, etc.
DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name,
- DICompileUnit CompileUnit, unsigned LineNumber,
+ DIFile F, unsigned LineNumber,
Constant *SizeInBits, Constant *AlignInBits,
Constant *OffsetInBits, unsigned Flags,
unsigned Encoding);
/// pointer, typedef, etc.
DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
/// CreateDerivedType - Create a derived type like const qualified type,
/// pointer, typedef, etc.
DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DICompileUnit CompileUnit,
- unsigned LineNumber,
- Constant *SizeInBits, Constant *AlignInBits,
- Constant *OffsetInBits, unsigned Flags,
- DIType DerivedFrom);
+ StringRef Name,
+ DIFile F,
+ unsigned LineNumber,
+ Constant *SizeInBits,
+ Constant *AlignInBits,
+ Constant *OffsetInBits, unsigned Flags,
+ DIType DerivedFrom);
/// CreateCompositeType - Create a composite type like array, struct, etc.
DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit,
+ DIFile F,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
DIType DerivedFrom,
DIArray Elements,
- unsigned RunTimeLang = 0);
+ unsigned RunTimeLang = 0,
+ MDNode *ContainingType = 0);
+
+ /// CreateArtificialType - Create a new DIType with "artificial" flag set.
+ DIType CreateArtificialType(DIType Ty);
/// CreateCompositeType - Create a composite type like array, struct, etc.
DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DICompileUnit CompileUnit,
- unsigned LineNumber,
- Constant *SizeInBits,
- Constant *AlignInBits,
- Constant *OffsetInBits, unsigned Flags,
- DIType DerivedFrom,
- DIArray Elements,
- unsigned RunTimeLang = 0);
+ StringRef Name,
+ DIFile F,
+ unsigned LineNumber,
+ Constant *SizeInBits,
+ Constant *AlignInBits,
+ Constant *OffsetInBits,
+ unsigned Flags,
+ DIType DerivedFrom,
+ DIArray Elements,
+ unsigned RunTimeLang = 0);
/// CreateSubprogram - Create a new descriptor for the specified subprogram.
/// See comments in DISubprogram for descriptions of these fields.
DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
- DICompileUnit CompileUnit, unsigned LineNo,
- DIType Type, bool isLocalToUnit,
+ DIFile F, unsigned LineNo,
+ DIType Ty, bool isLocalToUnit,
bool isDefinition,
unsigned VK = 0,
unsigned VIndex = 0,
- DIType = DIType());
+ DIType = DIType(),
+ bool isArtificial = 0);
/// CreateSubprogramDefinition - Create new subprogram descriptor for the
/// given declaration.
CreateGlobalVariable(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
- DICompileUnit CompileUnit,
- unsigned LineNo, DIType Type, bool isLocalToUnit,
+ DIFile F,
+ unsigned LineNo, DIType Ty, bool isLocalToUnit,
bool isDefinition, llvm::GlobalVariable *GV);
/// CreateVariable - Create a new descriptor for the specified variable.
DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
StringRef Name,
- DICompileUnit CompileUnit, unsigned LineNo,
- DIType Type);
+ DIFile F, unsigned LineNo,
+ DIType Ty);
/// CreateComplexVariable - Create a new descriptor for the specified
/// variable which has a complex address expression for its address.
DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context,
const std::string &Name,
- DICompileUnit CompileUnit, unsigned LineNo,
- DIType Type,
+ DIFile F, unsigned LineNo,
+ DIType Ty,
SmallVector<Value *, 9> &addr);
/// CreateLexicalBlock - This creates a descriptor for a lexical block
/// with the specified parent context.
- DILexicalBlock CreateLexicalBlock(DIDescriptor Context);
+ DILexicalBlock CreateLexicalBlock(DIDescriptor Context, unsigned Line = 0,
+ unsigned Col = 0);
/// CreateNameSpace - This creates new descriptor for a namespace
/// with the specified parent context.
DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name,
- DICompileUnit CU, unsigned LineNo);
+ DIFile F, unsigned LineNo);
/// CreateLocation - Creates a debug info location.
DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
Instruction *InsertBefore);
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
- Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset,
+ Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
DIVariable D, BasicBlock *InsertAtEnd);
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
- Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset,
+ Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
DIVariable D, Instruction *InsertBefore);
private:
Constant *GetTagConstant(unsigned TAG);
};
- /// Finds the stoppoint coressponding to this instruction, that is the
- /// stoppoint that dominates this instruction
- const DbgStopPointInst *findStopPoint(const Instruction *Inst);
-
- /// Finds the stoppoint corresponding to first real (non-debug intrinsic)
- /// instruction in this Basic Block, and returns the stoppoint for it.
- const DbgStopPointInst *findBBStopPoint(const BasicBlock *BB);
-
- /// Finds the dbg.declare intrinsic corresponding to this value if any.
- /// It looks through pointer casts too.
- const DbgDeclareInst *findDbgDeclare(const Value *V, bool stripCasts = true);
-
- /// Find the debug info descriptor corresponding to this global variable.
- Value *findDbgGlobalDeclare(GlobalVariable *V);
-
bool getLocationInfo(const Value *V, std::string &DisplayName,
std::string &Type, unsigned &LineNo, std::string &File,
std::string &Dir);
- /// ExtractDebugLocation - Extract debug location information
- /// from llvm.dbg.stoppoint intrinsic.
- DebugLoc ExtractDebugLocation(DbgStopPointInst &SPI,
- DebugLocTracker &DebugLocInfo);
-
- /// ExtractDebugLocation - Extract debug location information
- /// from DILocation.
- DebugLoc ExtractDebugLocation(DILocation &Loc,
- DebugLocTracker &DebugLocInfo);
-
- /// ExtractDebugLocation - Extract debug location information
- /// from llvm.dbg.func_start intrinsic.
- DebugLoc ExtractDebugLocation(DbgFuncStartInst &FSI,
- DebugLocTracker &DebugLocInfo);
-
/// getDISubprogram - Find subprogram that is enclosing this scope.
DISubprogram getDISubprogram(MDNode *Scope);