#ifndef LLVM_ANALYSIS_DEBUGINFO_H
#define LLVM_ANALYSIS_DEBUGINFO_H
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Dwarf.h"
namespace llvm {
class BasicBlock;
class Constant;
class Function;
class GlobalVariable;
class Module;
class Type;
class Value;
struct DbgStopPointInst;
struct DbgDeclareInst;
class Instruction;
class DIDescriptor {
protected:
GlobalVariable *GV;
DIDescriptor(GlobalVariable *GV, unsigned RequiredTag);
const std::string &getStringField(unsigned Elt, std::string &Result) const;
unsigned getUnsignedField(unsigned Elt) const {
return (unsigned)getUInt64Field(Elt);
}
uint64_t getUInt64Field(unsigned Elt) const;
DIDescriptor getDescriptorField(unsigned Elt) const;
template <typename DescTy>
DescTy getFieldAs(unsigned Elt) const {
return DescTy(getDescriptorField(Elt).getGV());
}
GlobalVariable *getGlobalVariableField(unsigned Elt) const;
public:
explicit DIDescriptor() : GV(0) {}
explicit DIDescriptor(GlobalVariable *gv) : GV(gv) {}
bool isNull() const { return GV == 0; }
GlobalVariable *getGV() const { return GV; }
unsigned getVersion() const {
return getUnsignedField(0) & LLVMDebugVersionMask;
}
unsigned getTag() const {
return getUnsignedField(0) & ~LLVMDebugVersionMask;
}
static bool ValidDebugInfo(Value *V, CodeGenOpt::Level OptLevel);
void dump() const;
};
class DIAnchor : public DIDescriptor {
public:
explicit DIAnchor(GlobalVariable *GV = 0);
unsigned getAnchorTag() const { return getUnsignedField(1); }
};
class DISubrange : public DIDescriptor {
public:
explicit DISubrange(GlobalVariable *GV = 0);
int64_t getLo() const { return (int64_t)getUInt64Field(1); }
int64_t getHi() const { return (int64_t)getUInt64Field(2); }
};
class DIArray : public DIDescriptor {
public:
explicit DIArray(GlobalVariable *GV = 0) : DIDescriptor(GV) {}
unsigned getNumElements() const;
DIDescriptor getElement(unsigned Idx) const {
return getDescriptorField(Idx);
}
};
class DICompileUnit : public DIDescriptor {
public:
explicit DICompileUnit(GlobalVariable *GV = 0);
unsigned getLanguage() const { return getUnsignedField(2); }
const std::string &getFilename(std::string &F) const {
return getStringField(3, F);
}
const std::string &getDirectory(std::string &F) const {
return getStringField(4, F);
}
const std::string &getProducer(std::string &F) const {
return getStringField(5, F);
}
bool isMain() const { return getUnsignedField(6); }
bool isOptimized() const { return getUnsignedField(7); }
const std::string &getFlags(std::string &F) const {
return getStringField(8, F);
}
unsigned getRunTimeVersion() const { return getUnsignedField(9); }
bool Verify() const;
void dump() const;
};
class DIEnumerator : public DIDescriptor {
public:
explicit DIEnumerator(GlobalVariable *GV = 0);
const std::string &getName(std::string &F) const {
return getStringField(1, F);
}
uint64_t getEnumValue() const { return getUInt64Field(2); }
};
class DIType : public DIDescriptor {
public:
enum {
FlagPrivate = 1 << 0,
FlagProtected = 1 << 1,
FlagFwdDecl = 1 << 2
};
protected:
DIType(GlobalVariable *GV, unsigned Tag) : DIDescriptor(GV, Tag) {}
DIType(GlobalVariable *GV, bool, bool) : DIDescriptor(GV) {}
public:
static bool isDerivedType(unsigned TAG);
static bool isCompositeType(unsigned TAG);
static bool isBasicType(unsigned TAG) {
return TAG == dwarf::DW_TAG_base_type;
}
bool Verify() const;
public:
explicit DIType(GlobalVariable *GV);
explicit DIType() {}
virtual ~DIType() {}
DIDescriptor getContext() const { return getDescriptorField(1); }
const std::string &getName(std::string &F) const {
return getStringField(2, F);
}
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
unsigned getLineNumber() const { return getUnsignedField(4); }
uint64_t getSizeInBits() const { return getUInt64Field(5); }
uint64_t getAlignInBits() const { return getUInt64Field(6); }
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; }
void dump() const;
};
class DIBasicType : public DIType {
public:
explicit DIBasicType(GlobalVariable *GV);
unsigned getEncoding() const { return getUnsignedField(9); }
void dump() const;
};
class DIDerivedType : public DIType {
protected:
explicit DIDerivedType(GlobalVariable *GV, bool, bool)
: DIType(GV, true, true) {}
public:
explicit DIDerivedType(GlobalVariable *GV);
DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
uint64_t getOriginalTypeSize() const;
void dump() const;
};
class DICompositeType : public DIDerivedType {
public:
explicit DICompositeType(GlobalVariable *GV);
DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
unsigned getRunTimeLang() const { return getUnsignedField(11); }
bool Verify() const;
void dump() const;
};
class DIGlobal : public DIDescriptor {
protected:
explicit DIGlobal(GlobalVariable *GV, unsigned RequiredTag)
: DIDescriptor(GV, RequiredTag) {}
static bool isSubprogram(unsigned TAG) {
return TAG == dwarf::DW_TAG_subprogram;
}
static bool isGlobalVariable(unsigned TAG) {
return TAG == dwarf::DW_TAG_variable;
}
public:
virtual ~DIGlobal() {}
DIDescriptor getContext() const { return getDescriptorField(2); }
const std::string &getName(std::string &F) const {
return getStringField(3, F);
}
const std::string &getDisplayName(std::string &F) const {
return getStringField(4, F);
}
const std::string &getLinkageName(std::string &F) const {
return getStringField(5, F);
}
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(6); }
unsigned getLineNumber() const { return getUnsignedField(7); }
DIType getType() const { return getFieldAs<DIType>(8); }
unsigned isLocalToUnit() const { return getUnsignedField(9); }
unsigned isDefinition() const { return getUnsignedField(10); }
void dump() const;
};
class DISubprogram : public DIGlobal {
public:
explicit DISubprogram(GlobalVariable *GV = 0);
DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
bool Verify() const;
void dump() const;
bool describes(const Function *F);
};
class DIGlobalVariable : public DIGlobal {
public:
explicit DIGlobalVariable(GlobalVariable *GV = 0);
GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
bool Verify() const;
void dump() const;
};
class DIVariable : public DIDescriptor {
public:
explicit DIVariable(GlobalVariable *GV = 0);
DIDescriptor getContext() const { return getDescriptorField(1); }
const std::string &getName(std::string &F) const {
return getStringField(2, F);
}
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
unsigned getLineNumber() const { return getUnsignedField(4); }
DIType getType() const { return getFieldAs<DIType>(5); }
static bool isVariable(unsigned Tag);
bool Verify() const;
void dump() const;
};
class DIBlock : public DIDescriptor {
public:
explicit DIBlock(GlobalVariable *GV = 0);
DIDescriptor getContext() const { return getDescriptorField(1); }
};
class DIFactory {
Module &M;
DIAnchor CompileUnitAnchor, SubProgramAnchor, GlobalVariableAnchor;
const Type *EmptyStructPtr; Function *StopPointFn; Function *FuncStartFn; Function *RegionStartFn; Function *RegionEndFn; Function *DeclareFn; StringMap<Constant*> StringCache;
DenseMap<Constant*, DIDescriptor> SimpleConstantCache;
DIFactory(const DIFactory &); void operator=(const DIFactory&); public:
explicit DIFactory(Module &m);
DIAnchor GetOrCreateCompileUnitAnchor();
DIAnchor GetOrCreateSubprogramAnchor();
DIAnchor GetOrCreateGlobalVariableAnchor();
DIArray GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys);
DISubrange GetOrCreateSubrange(int64_t Lo, int64_t Hi);
DICompileUnit CreateCompileUnit(unsigned LangID,
const std::string &Filename,
const std::string &Directory,
const std::string &Producer,
bool isMain = false,
bool isOptimized = false,
const char *Flags = "",
unsigned RunTimeVer = 0);
DIEnumerator CreateEnumerator(const std::string &Name, uint64_t Val);
DIBasicType CreateBasicType(DIDescriptor Context, const std::string &Name,
DICompileUnit CompileUnit, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
unsigned Encoding);
DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context,
const std::string &Name,
DICompileUnit CompileUnit,
unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
DIType DerivedFrom);
DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
const std::string &Name,
DICompileUnit CompileUnit,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
DIType DerivedFrom,
DIArray Elements,
unsigned RunTimeLang = 0);
DISubprogram CreateSubprogram(DIDescriptor Context, const std::string &Name,
const std::string &DisplayName,
const std::string &LinkageName,
DICompileUnit CompileUnit, unsigned LineNo,
DIType Type, bool isLocalToUnit,
bool isDefinition);
DIGlobalVariable
CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
const std::string &DisplayName,
const std::string &LinkageName,
DICompileUnit CompileUnit,
unsigned LineNo, DIType Type, bool isLocalToUnit,
bool isDefinition, llvm::GlobalVariable *GV);
DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
const std::string &Name,
DICompileUnit CompileUnit, unsigned LineNo,
DIType Type);
DIBlock CreateBlock(DIDescriptor Context);
void InsertStopPoint(DICompileUnit CU, unsigned LineNo, unsigned ColNo,
BasicBlock *BB);
void InsertSubprogramStart(DISubprogram SP, BasicBlock *BB);
void InsertRegionStart(DIDescriptor D, BasicBlock *BB);
void InsertRegionEnd(DIDescriptor D, BasicBlock *BB);
void InsertDeclare(llvm::Value *Storage, DIVariable D, BasicBlock *BB);
private:
Constant *GetTagConstant(unsigned TAG);
Constant *GetStringConstant(const std::string &String);
DIAnchor GetOrCreateAnchor(unsigned TAG, const char *Name);
Constant *getCastToEmpty(DIDescriptor D);
};
const DbgStopPointInst *findStopPoint(const Instruction *Inst);
const DbgStopPointInst *findBBStopPoint(const BasicBlock *BB);
const DbgDeclareInst *findDbgDeclare(const Value *V, bool stripCasts = true);
Value *findDbgGlobalDeclare(GlobalVariable *V);
bool getLocationInfo(const Value *V, std::string &DisplayName, std::string &Type,
unsigned &LineNo, std::string &File, std::string &Dir);
}
#endif