Introduce DIBuilder. It is intended to be a front-end friendly interface to emit...
authorDevang Patel <dpatel@apple.com>
Thu, 4 Nov 2010 15:01:38 +0000 (15:01 +0000)
committerDevang Patel <dpatel@apple.com>
Thu, 4 Nov 2010 15:01:38 +0000 (15:01 +0000)
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

include/llvm/Analysis/DIBuilder.h [new file with mode: 0644]
lib/Analysis/CMakeLists.txt
lib/Analysis/DIBuilder.cpp [new file with mode: 0644]

diff --git a/include/llvm/Analysis/DIBuilder.h b/include/llvm/Analysis/DIBuilder.h
new file mode 100644 (file)
index 0000000..3cdc1aa
--- /dev/null
@@ -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
index d69ab5990767bce886ada262668f8ec3fb1f5101..0c595827bd7549c2f186dc26aaf638518eb89607 100644 (file)
@@ -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 (file)
index 0000000..b6464e1
--- /dev/null
@@ -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()));
+}