[llvm-commits] [llvm] r118248 - in /llvm/trunk: include/llvm/Analysis/DIBuilder.h lib/Analysis/CMakeLists.txt lib/Analysis/DIBuilder.cpp

Devang Patel dpatel at apple.com
Thu Nov 4 08:01:39 PDT 2010


Author: dpatel
Date: Thu Nov  4 10:01:38 2010
New Revision: 118248

URL: http://llvm.org/viewvc/llvm-project?rev=118248&view=rev
Log:
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);


Added:
    llvm/trunk/include/llvm/Analysis/DIBuilder.h
    llvm/trunk/lib/Analysis/DIBuilder.cpp
Modified:
    llvm/trunk/lib/Analysis/CMakeLists.txt

Added: llvm/trunk/include/llvm/Analysis/DIBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DIBuilder.h?rev=118248&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Analysis/DIBuilder.h (added)
+++ llvm/trunk/include/llvm/Analysis/DIBuilder.h Thu Nov  4 10:01:38 2010
@@ -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

Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=118248&r1=118247&r2=118248&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
+++ llvm/trunk/lib/Analysis/CMakeLists.txt Thu Nov  4 10:01:38 2010
@@ -11,6 +11,7 @@
   ConstantFolding.cpp
   DbgInfoPrinter.cpp
   DebugInfo.cpp
+  DIBuilder.cpp
   DomPrinter.cpp
   IVUsers.cpp
   InlineCost.cpp

Added: llvm/trunk/lib/Analysis/DIBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DIBuilder.cpp?rev=118248&view=auto
==============================================================================
--- llvm/trunk/lib/Analysis/DIBuilder.cpp (added)
+++ llvm/trunk/lib/Analysis/DIBuilder.cpp Thu Nov  4 10:01:38 2010
@@ -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()));
+}





More information about the llvm-commits mailing list