diff options
author | Devang Patel <dpatel@apple.com> | 2010-11-04 15:01:38 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2010-11-04 15:01:38 +0000 |
commit | 35fcd6557f53aab69c2990b80fed4653fbaa3473 (patch) | |
tree | 9ff71fdf207bbbeb36a2d18431121baf17852a85 /lib/Analysis/DIBuilder.cpp | |
parent | ab70ed41f344c04dabaf180c40f04827bc9c56b5 (diff) |
Introduce DIBuilder. It is intended to be a front-end friendly interface to emit debuggging information entries in LLVM IR.
To create debugging information for a pointer, using DIBUilder front-end just needs
DBuilder.CreatePointerType(Ty, Size);
instead of
DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
TheCU, "", getOrCreateMainFile(),
0, Size, 0, 0, 0, OCTy);
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118248 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/DIBuilder.cpp')
-rw-r--r-- | lib/Analysis/DIBuilder.cpp | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/lib/Analysis/DIBuilder.cpp b/lib/Analysis/DIBuilder.cpp new file mode 100644 index 0000000000..b6464e1eb2 --- /dev/null +++ b/lib/Analysis/DIBuilder.cpp @@ -0,0 +1,249 @@ +//===--- DIBuilder.cpp - Debug Information Builder ------------------------===// +// +// 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 DIBuilder. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/DIBuilder.h" +#include "llvm/Analysis/DebugInfo.h" +#include "llvm/Constants.h" +#include "llvm/IntrinsicInst.h" +#include "llvm/Module.h" +#include "llvm/Support/Dwarf.h" + +using namespace llvm; +using namespace llvm::dwarf; + +static Constant *GetTagConstant(LLVMContext &VMContext, unsigned Tag) { + assert((Tag & LLVMDebugVersionMask) == 0 && + "Tag too large for debug encoding!"); + return ConstantInt::get(Type::getInt32Ty(VMContext), Tag | LLVMDebugVersion); +} +DIBuilder::DIBuilder(Module &m) + : M(m), VMContext(M.getContext()), TheCU(0) {} + +/// CreateCompileUnit - A CompileUnit provides an anchor for all debugging +/// information generated during this instance of compilation. +void DIBuilder::CreateCompileUnit(unsigned Lang, StringRef Filename, + StringRef Directory, StringRef Producer, + bool isOptimized, StringRef Flags, + unsigned RunTimeVer) { + SmallVector<Value *, 16> Elts; + Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_compile_unit)); + Elts.push_back(llvm::Constant::getNullValue(Type::getInt32Ty(VMContext))); + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), Lang)); + Elts.push_back(MDString::get(VMContext, Filename)); + Elts.push_back(MDString::get(VMContext, Directory)); + Elts.push_back(MDString::get(VMContext, Producer)); + // Deprecate isMain field. + Elts.push_back(ConstantInt::get(Type::getInt1Ty(VMContext), true)); // isMain + Elts.push_back(ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized)); + Elts.push_back(MDString::get(VMContext, Flags)); + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeVer)); + + TheCU = DICompileUnit(MDNode::get(VMContext, Elts.data(), Elts.size())); +} + +/// CreateFile - Create a file descriptor to hold debugging information +/// for a file. +DIFile DIBuilder::CreateFile(StringRef Filename, StringRef Directory) { + assert (TheCU && "Unable to create DW_TAG_file_type without CompileUnit"); + SmallVector<Value *, 4> Elts; + Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_file_type)); + Elts.push_back(MDString::get(VMContext, Filename)); + Elts.push_back(MDString::get(VMContext, Directory)); + Elts.push_back(TheCU); + return DIFile(MDNode::get(VMContext, Elts.data(), Elts.size())); +} + +/// CreateEnumerator - Create a single enumerator value. +DIEnumerator DIBuilder::CreateEnumerator(StringRef Name, uint64_t Val) { + SmallVector<Value *, 4> Elts; + Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_enumerator)); + Elts.push_back(MDString::get(VMContext, Name)); + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), Val)); + return DIEnumerator(MDNode::get(VMContext, Elts.data(), Elts.size())); +} + +/// CreateBasicType - Create debugging information entry for a basic +/// type, e.g 'char'. +DIType DIBuilder::CreateBasicType(StringRef Name, uint64_t SizeInBits, + uint64_t AlignInBits, + unsigned Encoding) { + // Basic types are encoded in DIBasicType format. Line number, filename, + // offset and flags are always empty here. + SmallVector<Value *, 12> Elts; + Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_base_type)); + Elts.push_back(TheCU); + Elts.push_back(MDString::get(VMContext, Name)); + Elts.push_back(NULL); // Filename + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Line + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits)); + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits)); + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Offset + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Flags; + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), Encoding)); + return DIType(MDNode::get(VMContext, Elts.data(), Elts.size())); +} + +/// CreateQaulifiedType - Create debugging information entry for a qualified +/// type, e.g. 'const int'. +DIType DIBuilder::CreateQualifiedType(unsigned Tag, DIType FromTy) { + /// Qualified types are encoded in DIDerivedType format. + SmallVector<Value *, 12> Elts; + Elts.push_back(GetTagConstant(VMContext, Tag)); + Elts.push_back(TheCU); + Elts.push_back(MDString::get(VMContext, StringRef())); // Empty name. + Elts.push_back(NULL); // Filename + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Line + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Size + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Align + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Offset + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Flags + Elts.push_back(FromTy); + return DIType(MDNode::get(VMContext, Elts.data(), Elts.size())); +} + +/// CreatePointerType - Create debugging information entry for a pointer. +DIType DIBuilder::CreatePointerType(DIType PointeeTy, uint64_t SizeInBits, + uint64_t AlignInBits, StringRef Name) { + /// pointer types are encoded in DIDerivedType format. + SmallVector<Value *, 12> Elts; + Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_pointer_type)); + Elts.push_back(TheCU); + Elts.push_back(MDString::get(VMContext, Name)); + Elts.push_back(NULL); // Filename + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Line + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits)); + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits)); + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Offset + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Flags + Elts.push_back(PointeeTy); + return DIType(MDNode::get(VMContext, Elts.data(), Elts.size())); +} + +/// CreateReferenceType - Create debugging information entry for a reference. +DIType DIBuilder::CreateReferenceType(DIType RTy) { + /// references are encoded in DIDerivedType format. + SmallVector<Value *, 12> Elts; + Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_reference_type)); + Elts.push_back(TheCU); + Elts.push_back(NULL); // Name + Elts.push_back(NULL); // Filename + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Line + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Size + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Align + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Offset + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Flags + Elts.push_back(RTy); + return DIType(MDNode::get(VMContext, Elts.data(), Elts.size())); +} + +/// CreateTypedef - Create debugging information entry for a typedef. +DIType DIBuilder::CreateTypedef(DIType Ty, StringRef Name, DIFile File, + unsigned LineNo) { + /// typedefs are encoded in DIDerivedType format. + assert (Ty.Verify() && "Invalid typedef type!"); + SmallVector<Value *, 12> Elts; + Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_typedef)); + Elts.push_back(Ty.getContext()); + Elts.push_back(MDString::get(VMContext, Name)); + Elts.push_back(File); + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), LineNo)); + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Size + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Align + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Offset + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Flags + Elts.push_back(Ty); + return DIType(MDNode::get(VMContext, Elts.data(), Elts.size())); +} + +/// CreateFriend - Create debugging information entry for a 'friend'. +DIType DIBuilder::CreateFriend(DIType Ty, DIType FriendTy) { + /// typedefs are encoded in DIDerivedType format. + assert (Ty.Verify() && "Invalid type!"); + assert (FriendTy.Verify() && "Invalid friend type!"); + SmallVector<Value *, 12> Elts; + Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_friend)); + Elts.push_back(Ty); + Elts.push_back(NULL); // Name + Elts.push_back(Ty.getFile()); + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Line + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Size + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Align + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Offset + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Flags + Elts.push_back(FriendTy); + return DIType(MDNode::get(VMContext, Elts.data(), Elts.size())); +} + +/// CreateInheritance - Create debugging information entry to establish +/// inheritnace relationship between two types. +DIType DIBuilder::CreateInheritance(DIType Ty, DIType BaseTy, + uint64_t BaseOffset, unsigned Flags) { + /// TAG_inheritance is encoded in DIDerivedType format. + SmallVector<Value *, 12> Elts; + Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_inheritance)); + Elts.push_back(Ty); + Elts.push_back(NULL); // Name + Elts.push_back(NULL); // File + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), 0)); // Line + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Size + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), 0)); // Align + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), BaseOffset)); + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), Flags)); + Elts.push_back(BaseTy); + return DIType(MDNode::get(VMContext, Elts.data(), Elts.size())); +} + +/// CreateMemberType - Create debugging information entry for a member. +DIType DIBuilder::CreateMemberType(DIDescriptor Context, StringRef Name, + DIFile F, unsigned LineNumber, + uint64_t SizeInBits, uint64_t AlignInBits, + uint64_t OffsetInBits, unsigned Flags, + DIType Ty) { + /// TAG_member is encoded in DIDerivedType format. + SmallVector<Value *, 12> Elts; + Elts.push_back(GetTagConstant(VMContext, dwarf::DW_TAG_member)); + Elts.push_back(Context); + Elts.push_back(MDString::get(VMContext, Name)); + Elts.push_back(F); + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber)); + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits)); + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits)); + Elts.push_back(ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits)); + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), Flags)); + Elts.push_back(Ty); + return DIType(MDNode::get(VMContext, Elts.data(), Elts.size())); +} + +/// CreateArtificialType - Create a new DIType with "artificial" flag set. +DIType DIBuilder::CreateArtificialType(DIType Ty) { + if (Ty.isArtificial()) + return Ty; + + SmallVector<Value *, 9> Elts; + MDNode *N = Ty; + assert (N && "Unexpected input DIType!"); + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + if (Value *V = N->getOperand(i)) + Elts.push_back(V); + else + Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))); + } + + unsigned CurFlags = Ty.getFlags(); + CurFlags = CurFlags | DIType::FlagArtificial; + + // Flags are stored at this slot. + Elts[8] = ConstantInt::get(Type::getInt32Ty(VMContext), CurFlags); + + return DIType(MDNode::get(VMContext, Elts.data(), Elts.size())); +} |