aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2010-11-04 15:01:38 +0000
committerDevang Patel <dpatel@apple.com>2010-11-04 15:01:38 +0000
commit35fcd6557f53aab69c2990b80fed4653fbaa3473 (patch)
tree9ff71fdf207bbbeb36a2d18431121baf17852a85
parentab70ed41f344c04dabaf180c40f04827bc9c56b5 (diff)
downloadexternal_llvm-35fcd6557f53aab69c2990b80fed4653fbaa3473.zip
external_llvm-35fcd6557f53aab69c2990b80fed4653fbaa3473.tar.gz
external_llvm-35fcd6557f53aab69c2990b80fed4653fbaa3473.tar.bz2
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
-rw-r--r--include/llvm/Analysis/DIBuilder.h94
-rw-r--r--lib/Analysis/CMakeLists.txt1
-rw-r--r--lib/Analysis/DIBuilder.cpp249
3 files changed, 344 insertions, 0 deletions
diff --git a/include/llvm/Analysis/DIBuilder.h b/include/llvm/Analysis/DIBuilder.h
new file mode 100644
index 0000000..3cdc1aa
--- /dev/null
+++ b/include/llvm/Analysis/DIBuilder.h
@@ -0,0 +1,94 @@
+//===--- llvm/Analysis/DIBuilder.h - Debug Information Builder --*- 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 DIBuilder that is useful for creating debugging
+// information entries in LLVM IR form.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DIBUILDER_H
+#define LLVM_ANALYSIS_DIBUILDER_H
+
+#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+ class Module;
+ class LLVMContext;
+ class MDNode;
+ class StringRef;
+ class DIDescriptor;
+ class DIFile;
+ class DIEnumerator;
+ class DIType;
+
+ class DIBuilder {
+ private:
+ Module &M;
+ LLVMContext & VMContext;
+ MDNode *TheCU;
+
+ DIBuilder(const DIBuilder &); // DO NOT IMPLEMENT
+ void operator=(const DIBuilder &); // DO NOT IMPLEMENT
+
+ public:
+ explicit DIBuilder(Module &M);
+ const MDNode *getCU() { return TheCU; }
+
+ /// CreateCompileUnit - A CompileUnit provides an anchor for all debugging
+ /// information generated during this instance of compilation.
+ void CreateCompileUnit(unsigned Lang, StringRef F, StringRef D, StringRef P,
+ bool isOptimized, StringRef Flags, unsigned RV);
+
+ /// CreateFile - Create a file descriptor to hold debugging information
+ /// for a file.
+ DIFile CreateFile(StringRef Filename, StringRef Directory);
+
+ /// CreateEnumerator - Create a single enumerator value.
+ DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val);
+
+ /// CreateBasicType - Create debugging information entry for a basic
+ /// type, e.g 'char'.
+ DIType CreateBasicType(StringRef Name, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Encoding);
+
+ /// CreateQaulifiedType - Create debugging information entry for a qualified
+ /// type, e.g. 'const int'.
+ DIType CreateQualifiedType(unsigned Tag, DIType FromTy);
+
+ /// CreatePointerType - Create debugging information entry for a pointer.
+ DIType CreatePointerType(DIType PointeeTy, uint64_t SizeInBits,
+ uint64_t AlignInBits = 0, StringRef Name = StringRef());
+
+ /// CreateReferenceType - Create debugging information entry for a reference.
+ DIType CreateReferenceType(DIType RTy);
+
+ /// CreateTypedef - Create debugging information entry for a typedef.
+ DIType CreateTypedef(DIType Ty, StringRef Name, DIFile F, unsigned LineNo);
+
+ /// CreateFriend - Create debugging information entry for a 'friend'.
+ DIType CreateFriend(DIType Ty, DIType FriendTy);
+
+ /// CreateInheritance - Create debugging information entry to establish
+ /// inheritnace relationship between two types.
+ DIType CreateInheritance(DIType Ty, DIType BaseTy, uint64_t BaseOffset,
+ unsigned Flags);
+
+ /// CreateMemberType - Create debugging information entry for a member.
+ DIType CreateMemberType(DIDescriptor Context, StringRef Name, DIFile F,
+ unsigned LineNumber, uint64_t SizeInBits,
+ uint64_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Flags, DIType Ty);
+
+ /// CreateArtificialType - Create a new DIType with "artificial" flag set.
+ DIType CreateArtificialType(DIType Ty);
+ };
+} // end namespace llvm
+
+#endif
diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt
index d69ab59..0c59582 100644
--- a/lib/Analysis/CMakeLists.txt
+++ b/lib/Analysis/CMakeLists.txt
@@ -11,6 +11,7 @@ add_llvm_library(LLVMAnalysis
ConstantFolding.cpp
DbgInfoPrinter.cpp
DebugInfo.cpp
+ DIBuilder.cpp
DomPrinter.cpp
IVUsers.cpp
InlineCost.cpp
diff --git a/lib/Analysis/DIBuilder.cpp b/lib/Analysis/DIBuilder.cpp
new file mode 100644
index 0000000..b6464e1
--- /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()));
+}