[cfe-commits] r58971 - in /cfe/trunk/lib/CodeGen: CGDebugInfo.cpp CGDebugInfo.h CGDecl.cpp

Chris Lattner sabre at nondot.org
Sun Nov 9 22:08:35 PST 2008


Author: lattner
Date: Mon Nov 10 00:08:34 2008
New Revision: 58971

URL: http://llvm.org/viewvc/llvm-project?rev=58971&view=rev
Log:
reimplement debug info generation in terms of DebugInfo.h instead of
using MachineModuleInfo.  This runs at about the same speed as the old
code, but fixes a bunch of bugs and is simpler and shorter.

Modified:
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.h
    cfe/trunk/lib/CodeGen/CGDecl.cpp

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=58971&r1=58970&r2=58971&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Nov 10 00:08:34 2008
@@ -25,622 +25,415 @@
 #include "llvm/Module.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Target/TargetMachine.h"
 using namespace clang;
 using namespace clang::CodeGen;
 
 CGDebugInfo::CGDebugInfo(CodeGenModule *m)
-: M(m)
-, CurLoc()
-, PrevLoc()
-, CompileUnitCache()
-, TypeCache()
-, StopPointFn(NULL)
-, FuncStartFn(NULL)
-, DeclareFn(NULL)
-, RegionStartFn(NULL)
-, RegionEndFn(NULL)
-, CompileUnitAnchor(NULL)
-, SubprogramAnchor(NULL)
-, GlobalVariableAnchor(NULL)
-, RegionStack()
-, VariableDescList()
-, GlobalVarDescList()
-, EnumDescList()
-, SubrangeDescList()
-, Subprogram(NULL)
-{
-  SR = new llvm::DISerializer();
-  SR->setModule (&M->getModule());
+  : M(m), DebugFactory(M->getModule()) {
 }
 
-CGDebugInfo::~CGDebugInfo()
-{
+CGDebugInfo::~CGDebugInfo() {
   assert(RegionStack.empty() && "Region stack mismatch, stack not empty!");
-
-  delete SR;
-
-  // Free CompileUnitCache.
-  for (std::map<const FileEntry*, llvm::CompileUnitDesc *>::iterator I 
-       = CompileUnitCache.begin(); I != CompileUnitCache.end(); ++I) {
-    delete I->second;
-  }
-  CompileUnitCache.clear();
-
-  // Free TypeCache.
-  for (std::map<void *, llvm::TypeDesc *>::iterator I 
-       = TypeCache.begin(); I != TypeCache.end(); ++I) {
-    delete I->second;
-  }
-  TypeCache.clear();
-
-  // Free region descriptors.
-  for (std::vector<llvm::DebugInfoDesc *>::iterator I 
-       = RegionStack.begin(); I != RegionStack.end(); ++I) {
-    delete *I;
-  }
-
-  // Free local var descriptors.
-  for (std::vector<llvm::VariableDesc *>::iterator I 
-       = VariableDescList.begin(); I != VariableDescList.end(); ++I) {
-    delete *I;
-  }
-
-  // Free global var descriptors.
-  for (std::vector<llvm::GlobalVariableDesc *>::iterator I 
-       = GlobalVarDescList.begin(); I != GlobalVarDescList.end(); ++I) {
-    delete *I;
-  }
-
-  // Free enum constants descriptors.
-  for (std::vector<llvm::EnumeratorDesc *>::iterator I 
-       = EnumDescList.begin(); I != EnumDescList.end(); ++I) {
-    delete *I;
-  }
-
-  // Free subrange descriptors.
-  for (std::vector<llvm::SubrangeDesc *>::iterator I
-       = SubrangeDescList.begin(); I != SubrangeDescList.end(); ++I) {
-    delete *I;
-  }
-
-  delete CompileUnitAnchor;
-  delete SubprogramAnchor;
-  delete GlobalVariableAnchor;
 }
 
-void CGDebugInfo::setLocation(SourceLocation loc) {
-  if (loc.isValid())
-    CurLoc = M->getContext().getSourceManager().getLogicalLoc(loc);
-}
-
-/// getCastValueFor - Return a llvm representation for a given debug information
-/// descriptor cast to an empty struct pointer.
-llvm::Value *CGDebugInfo::getCastValueFor(llvm::DebugInfoDesc *DD) {
-  return llvm::ConstantExpr::getBitCast(SR->Serialize(DD), 
-                                        SR->getEmptyStructPtrType());
-}
-
-/// getValueFor - Return a llvm representation for a given debug information
-/// descriptor.
-llvm::Value *CGDebugInfo::getValueFor(llvm::DebugInfoDesc *DD) {
-  return SR->Serialize(DD);
+void CGDebugInfo::setLocation(SourceLocation Loc) {
+  if (Loc.isValid())
+    CurLoc = M->getContext().getSourceManager().getLogicalLoc(Loc);
 }
 
 /// getOrCreateCompileUnit - Get the compile unit from the cache or create a new
 /// one if necessary. This returns null for invalid source locations.
-llvm::CompileUnitDesc*
-CGDebugInfo::getOrCreateCompileUnit(const SourceLocation Loc) {
+llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) {
   if (Loc.isInvalid())
-    return NULL;
+    return llvm::DICompileUnit();
 
   SourceManager &SM = M->getContext().getSourceManager();
   const FileEntry *FE = SM.getFileEntryForLoc(Loc);
-
+  if (FE == 0) return llvm::DICompileUnit();
+    
   // See if this compile unit has been used before.
-  llvm::CompileUnitDesc *&Unit = CompileUnitCache[FE];
-  if (Unit) return Unit;
+  llvm::DICompileUnit &Unit = CompileUnitCache[FE];
+  if (!Unit.isNull()) return Unit;
   
-  // Create new compile unit.
-  // FIXME: Where to free these?
-  // One way is to iterate over the CompileUnitCache in ~CGDebugInfo.
-  Unit = new llvm::CompileUnitDesc();
-
-  // Make sure we have an anchor.
-  if (!CompileUnitAnchor) {
-    CompileUnitAnchor = new llvm::AnchorDesc(Unit);
-  }
-
   // Get source file information.
-  const char *FileName, *DirName;
-  if (FE) {
-    FileName = FE->getName();
-    DirName = FE->getDir()->getName();
-  } else {
-    FileName = SM.getSourceName(Loc);
-    DirName = "";
-  }
-
-  Unit->setAnchor(CompileUnitAnchor);
-  Unit->setFileName(FileName);
-  Unit->setDirectory(DirName);
-
-  // Set up producer name.
+  const char *FileName = FE->getName();
+  const char *DirName = FE->getDir()->getName();
+  
+  // Create new compile unit.
+  // FIXME: Handle other language IDs as well.
   // FIXME: Do not know how to get clang version yet.
-  Unit->setProducer("clang");
-
-  // Set up Language number.
-  // FIXME: Handle other languages as well.
-  Unit->setLanguage(llvm::dwarf::DW_LANG_C89);
-
-  return Unit;
+  return Unit = DebugFactory.CreateCompileUnit(llvm::dwarf::DW_LANG_C89,
+                                               FileName, DirName, "clang");
 }
 
-
-/// getOrCreateCVRType - Get the CVR qualified type from the cache or create 
-/// a new one if necessary.
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateCVRType(QualType type, llvm::CompileUnitDesc *Unit)
-{
-  // We will create a Derived type.
-  llvm::DerivedTypeDesc *DTy = NULL;
-  llvm::TypeDesc *FromTy = NULL;
-
-  if (type.isConstQualified()) {
-    DTy = new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_const_type);
-    type.removeConst(); 
-    FromTy = getOrCreateType(type, Unit);
-  } else if (type.isVolatileQualified()) {
-    DTy = new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_volatile_type);
-    type.removeVolatile(); 
-    FromTy = getOrCreateType(type, Unit);
-  } else if (type.isRestrictQualified()) {
-    DTy = new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_restrict_type);
-    type.removeRestrict(); 
-    FromTy = getOrCreateType(type, Unit);
-  }
-
-  // No need to fill in the Name, Line, Size, Alignment, Offset in case of
-  // CVR derived types.
-  DTy->setContext(Unit);
-  DTy->setFromType(FromTy);
-
-  return DTy;
-}
-
-   
 /// getOrCreateBuiltinType - Get the Basic type from the cache or create a new
 /// one if necessary.
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateBuiltinType(const BuiltinType *type, 
-                                    llvm::CompileUnitDesc *Unit) {
+llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT,
+                                     llvm::DICompileUnit Unit){
   unsigned Encoding = 0;
-  switch (type->getKind())
-  {
-    case BuiltinType::Void:
-      return NULL;
-    case BuiltinType::UChar:
-    case BuiltinType::Char_U:
-      Encoding = llvm::dwarf::DW_ATE_unsigned_char;
-      break;
-    case BuiltinType::Char_S:
-    case BuiltinType::SChar:
-      Encoding = llvm::dwarf::DW_ATE_signed_char;
-      break;
-    case BuiltinType::UShort:
-    case BuiltinType::UInt:
-    case BuiltinType::ULong:
-    case BuiltinType::ULongLong:
-      Encoding = llvm::dwarf::DW_ATE_unsigned;
-      break;
-    case BuiltinType::Short:
-    case BuiltinType::Int:
-    case BuiltinType::Long:
-    case BuiltinType::LongLong:
-      Encoding = llvm::dwarf::DW_ATE_signed;
-      break;
-    case BuiltinType::Bool:
-      Encoding = llvm::dwarf::DW_ATE_boolean;
-      break;
-    case BuiltinType::Float:
-    case BuiltinType::Double:
-      Encoding = llvm::dwarf::DW_ATE_float;
-      break;
-    default:
-      Encoding = llvm::dwarf::DW_ATE_signed;
-      break;
+  switch (BT->getKind()) {
+  default:
+  case BuiltinType::Void:
+    return llvm::DIType();
+  case BuiltinType::UChar:
+  case BuiltinType::Char_U: Encoding = llvm::dwarf::DW_ATE_unsigned_char; break;
+  case BuiltinType::Char_S:
+  case BuiltinType::SChar: Encoding = llvm::dwarf::DW_ATE_signed_char; break;
+  case BuiltinType::UShort:
+  case BuiltinType::UInt:
+  case BuiltinType::ULong:
+  case BuiltinType::ULongLong: Encoding = llvm::dwarf::DW_ATE_unsigned; break;
+  case BuiltinType::Short:
+  case BuiltinType::Int:
+  case BuiltinType::Long:
+  case BuiltinType::LongLong:  Encoding = llvm::dwarf::DW_ATE_signed; break;
+  case BuiltinType::Bool:      Encoding = llvm::dwarf::DW_ATE_boolean; break;
+  case BuiltinType::Float:
+  case BuiltinType::Double:    Encoding = llvm::dwarf::DW_ATE_float; break;
   } 
-
-  // Ty will have contain the resulting type.
-  llvm::BasicTypeDesc *BTy = new llvm::BasicTypeDesc();
-
-  // Get the name and location early to assist debugging.
-  const char *TyName = type->getName();
-
   // Bit size, align and offset of the type.
-  uint64_t Size = M->getContext().getTypeSize(type);
-  uint64_t Align = M->getContext().getTypeAlign(type);
+  uint64_t Size = M->getContext().getTypeSize(BT);
+  uint64_t Align = M->getContext().getTypeAlign(BT);
   uint64_t Offset = 0;
-                                                  
-  // If the type is defined, fill in the details.
-  if (BTy) {
-    BTy->setContext(Unit);
-    BTy->setName(TyName);
-    BTy->setSize(Size);
-    BTy->setAlign(Align);
-    BTy->setOffset(Offset);
-    BTy->setEncoding(Encoding);
-  }
-                                                                                
-  return BTy;
+  
+  return DebugFactory.CreateBasicType(Unit, BT->getName(), Unit, 0, Size, Align,
+                                      Offset, /*flags*/ 0, Encoding);
 }
 
-llvm::TypeDesc *
-CGDebugInfo::getOrCreatePointerType(const PointerType *type, 
-                                    llvm::CompileUnitDesc *Unit) {
-  // type*
-  llvm::DerivedTypeDesc *DTy =
-    new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_pointer_type);
+/// getOrCreateCVRType - Get the CVR qualified type from the cache or create 
+/// a new one if necessary.
+llvm::DIType CGDebugInfo::CreateCVRType(QualType Ty, llvm::DICompileUnit Unit) {
+  // We will create one Derived type for one qualifier and recurse to handle any
+  // additional ones.
+  llvm::DIType FromTy;
+  unsigned Tag;
+  if (Ty.isConstQualified()) {
+    Tag = llvm::dwarf::DW_TAG_const_type;
+    Ty.removeConst(); 
+    FromTy = getOrCreateType(Ty, Unit);
+  } else if (Ty.isVolatileQualified()) {
+    Tag = llvm::dwarf::DW_TAG_volatile_type;
+    Ty.removeVolatile(); 
+    FromTy = getOrCreateType(Ty, Unit);
+  } else {
+    assert(Ty.isRestrictQualified() && "Unknown type qualifier for debug info");
+    Tag = llvm::dwarf::DW_TAG_restrict_type;
+    Ty.removeRestrict(); 
+    FromTy = getOrCreateType(Ty, Unit);
+  }
+  
+  // No need to fill in the Name, Line, Size, Alignment, Offset in case of
+  // CVR derived types.
+  return DebugFactory.CreateDerivedType(Tag, Unit, "", llvm::DICompileUnit(),
+                                        0, 0, 0, 0, 0, FromTy);
+}
 
-  // Handle the derived type.
-  llvm::TypeDesc *FromTy = getOrCreateType(type->getPointeeType(), Unit);
+llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty,
+                                     llvm::DICompileUnit Unit) {
+  llvm::DIType EltTy = getOrCreateType(Ty->getPointeeType(), Unit);
  
-  // Get the name and location early to assist debugging.
-  SourceManager &SM = M->getContext().getSourceManager();
-  uint64_t Line = SM.getLogicalLineNumber(CurLoc);
-                                                                               
   // Bit size, align and offset of the type.
-  uint64_t Size = M->getContext().getTypeSize(type);
-  uint64_t Align = M->getContext().getTypeAlign(type);
-  uint64_t Offset = 0;
+  uint64_t Size = M->getContext().getTypeSize(Ty);
+  uint64_t Align = M->getContext().getTypeAlign(Ty);
                                                                                
-  // If the type is defined, fill in the details.
-  if (DTy) {
-    DTy->setContext(Unit);
-    DTy->setLine(Line);
-    DTy->setSize(Size);
-    DTy->setAlign(Align);
-    DTy->setOffset(Offset);
-    DTy->setFromType(FromTy);
-  }
-
-  return DTy;
+  return DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit,
+                                        "", llvm::DICompileUnit(),
+                                        0, Size, Align, 0, 0, EltTy);
 }
 
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateTypedefType(const TypedefType *TDT, 
-                                    llvm::CompileUnitDesc *Unit) {
-  // typedefs are derived from some other type.
-  llvm::DerivedTypeDesc *DTy =
-    new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_typedef);
-
-  // Handle derived type.
-  llvm::TypeDesc *FromTy = getOrCreateType(TDT->LookThroughTypedefs(),
-                                           Unit);
+llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty,
+                                     llvm::DICompileUnit Unit) {
+  // Typedefs are derived from some other type.  If we have a typedef of a
+  // typedef, make sure to emit the whole chain.
+  llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit);
+  
+  // We don't set size information, but do specify where the typedef was
+  // declared.
+  const char *TyName = Ty->getDecl()->getName();
+  SourceLocation DefLoc = Ty->getDecl()->getLocation();
+  llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(DefLoc);
 
-  // Get the name and location early to assist debugging.
-  const char *TyName = TDT->getDecl()->getName();
   SourceManager &SM = M->getContext().getSourceManager();
-  uint64_t Line = SM.getLogicalLineNumber(TDT->getDecl()->getLocation());
-                                                                                
-  // If the type is defined, fill in the details.
-  if (DTy) {
-    DTy->setContext(Unit);
-    DTy->setFile(getOrCreateCompileUnit(TDT->getDecl()->getLocation()));
-    DTy->setLine(Line);
-    DTy->setName(TyName);
-    DTy->setFromType(FromTy);
-  }
+  uint64_t Line = SM.getLogicalLineNumber(DefLoc);
 
-  return DTy;
+  return DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_typedef, Unit,
+                                        TyName, DefUnit, Line, 0, 0, 0, 0, Src);
 }
 
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateFunctionType(QualType type, llvm::CompileUnitDesc *Unit)
-{
-  llvm::CompositeTypeDesc *SubrTy =
-    new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_subroutine_type);
-
-  // Prepare to add the arguments for the subroutine.
-  std::vector<llvm::DebugInfoDesc *> &Elements = SubrTy->getElements();
-
-  // Get result type.
-  const FunctionType *FT = type->getAsFunctionType();
-  llvm::TypeDesc *ArgTy = getOrCreateType(FT->getResultType(), Unit);
-  Elements.push_back(ArgTy);
-
-  // Set up remainder of arguments.
-  if (type->getTypeClass() == Type::FunctionProto) {
-    const FunctionTypeProto *FTPro = dyn_cast<FunctionTypeProto>(type);
-    for (unsigned int i =0; i < FTPro->getNumArgs(); i++) {
-      QualType ParamType = FTPro->getArgType(i);
-      ArgTy = getOrCreateType(ParamType, Unit);
-      // FIXME: Remove once we support all types.
-      if (ArgTy) Elements.push_back(ArgTy);
-    }
-  }
+llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
+                                     llvm::DICompileUnit Unit) {
+  llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
 
-  // FIXME: set other fields file, line here.
-  SubrTy->setContext(Unit);
+  // Add the result type at least.
+  EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit));
+  
+  // Set up remainder of arguments if there is a prototype.
+  // FIXME: IF NOT, HOW IS THIS REPRESENTED?  llvm-gcc doesn't represent '...'!
+  if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(Ty)) {
+    for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
+      EltTys.push_back(getOrCreateType(FTP->getArgType(i), Unit));
+  } else {
+    // FIXME: Handle () case in C.  llvm-gcc doesn't do it either.
+  }
 
-  return SubrTy;
+  llvm::DIArray EltTypeArray =
+    DebugFactory.GetOrCreateArray(&EltTys[0], EltTys.size());
+  
+  return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
+                                          Unit, "", llvm::DICompileUnit(),
+                                          0, 0, 0, 0, 0,
+                                          llvm::DIType(), EltTypeArray);
 }
 
 /// getOrCreateRecordType - get structure or union type.
-void CGDebugInfo::getOrCreateRecordType(const RecordType *type,
-                                        llvm::CompileUnitDesc *Unit,
-                                        llvm::TypeDesc *&Slot)
-{
-  // Prevent recursing in type generation by initializing the slot
-  // here.
-  llvm::CompositeTypeDesc *RecType;
-  if (type->isStructureType())
-    Slot = RecType = 
-      new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_structure_type);
-  else if (type->isUnionType())
-    Slot = RecType = 
-      new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_union_type);
-  else
-    return;
-
-  RecordDecl *RecDecl = type->getDecl();
-  // We can not get the type for forward declarations. 
-  // FIXME: What *should* we be doing here?
-  if (!RecDecl->getDefinition(M->getContext()))
-    return;
-  const ASTRecordLayout &RL = M->getContext().getASTRecordLayout(RecDecl);
+llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
+                                     llvm::DICompileUnit Unit) {
+  const RecordDecl *Decl = Ty->getDecl();
+  
+  if (!Decl->getDefinition(M->getContext()))
+    return llvm::DIType();
+  
+  unsigned Tag;
+  if (Decl->isStruct())
+    Tag = llvm::dwarf::DW_TAG_structure_type;
+  else if (Decl->isUnion())
+    Tag = llvm::dwarf::DW_TAG_union_type;
+  else {
+    assert(Decl->isClass() && "Unknown RecordType!");
+    Tag = llvm::dwarf::DW_TAG_class_type;
+  }
 
   SourceManager &SM = M->getContext().getSourceManager();
-  uint64_t Line = SM.getLogicalLineNumber(RecDecl->getLocation());
 
-  std::vector<llvm::DebugInfoDesc *> &Elements = RecType->getElements();
+  // Get overall information about the record type for the debug info.
+  const char *Name = Decl->getName();
+  if (Name == 0) Name = "";
 
-  // Add the members.
-  int NumMembers = RecDecl->getNumMembers();
-  for (int i = 0; i < NumMembers; i++) {
-    FieldDecl *Member = RecDecl->getMember(i);
-    llvm::TypeDesc *MemberTy = getOrCreateType(Member->getType(), Unit);
-    // FIXME: Remove once we support all types.
-    if (MemberTy) {
-      MemberTy->setOffset(RL.getFieldOffset(i));
-      Elements.push_back(MemberTy);
-    }
+  llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(Decl->getLocation());
+  uint64_t Line = SM.getLogicalLineNumber(Decl->getLocation());
+  
+  
+  // Records and classes and unions can all be recursive.  To handle them, we
+  // first generate a debug descriptor for the struct as a forward declaration.
+  // Then (if it is a definition) we go through and get debug info for all of
+  // its members.  Finally, we create a descriptor for the complete type (which
+  // may refer to the forward decl if the struct is recursive) and replace all
+  // uses of the forward declaration with the final definition.
+  llvm::DIType FwdDecl =
+    DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, 0, 0, 0, 0,
+                                     llvm::DIType(), llvm::DIArray());
+  
+  // If this is just a forward declaration, return it.
+  if (!Decl->getDefinition(M->getContext()))
+    return FwdDecl;
+
+  // Otherwise, insert it into the TypeCache so that recursive uses will find
+  // it.
+  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
+
+  // Convert all the elements.
+  llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
+
+  const ASTRecordLayout &RL = M->getContext().getASTRecordLayout(Decl);
+
+  unsigned FieldNo = 0;
+  for (RecordDecl::field_const_iterator I = Decl->field_begin(),
+       E = Decl->field_end(); I != E; ++I, ++FieldNo) {
+    FieldDecl *Field = *I;
+    llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
+    
+#if 0
+    const char *FieldName = Field->getName();
+    if (FieldName == 0) FieldName = "";
+
+    // Get the location for the field.
+    SourceLocation FieldDefLoc = Field->getLocation();
+    llvm::DICompileUnit FieldDefUnit = getOrCreateCompileUnit(FieldDefLoc);
+    uint64_t FieldLine = SM.getLogicalLineNumber(FieldDefLoc);
+    
+    // Bit size, align and offset of the type.
+    uint64_t FieldSize = M->getContext().getTypeSize(Ty);
+    uint64_t FieldAlign = M->getContext().getTypeAlign(Ty);
+    uint64_t FieldOffset = RL.getFieldOffset(FieldNo);    
+    
+    // Create a DW_TAG_member node to remember the offset of this field in the
+    // struct.  FIXME: This is an absolutely insane way to capture this
+    // information.  When we gut debug info, this should be fixed.
+    FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+                                             FieldName, FieldDefUnit,
+                                             FieldLine, FieldSize, FieldAlign,
+                                             FieldOffset, 0, FieldTy);
+#endif
+    EltTys.push_back(FieldTy);
   }
+  
+  llvm::DIArray Elements =
+    DebugFactory.GetOrCreateArray(&EltTys[0], EltTys.size());
 
-  // Fill in the blanks.
-  if (RecType) {
-    RecType->setContext(Unit);
-    RecType->setName(RecDecl->getName());
-    RecType->setFile(getOrCreateCompileUnit(RecDecl->getLocation()));
-    RecType->setLine(Line);
-    RecType->setSize(RL.getSize());
-    RecType->setAlign(RL.getAlignment());
-    RecType->setOffset(0);
-  }
+  // Bit size, align and offset of the type.
+  uint64_t Size = M->getContext().getTypeSize(Ty);
+  uint64_t Align = M->getContext().getTypeAlign(Ty);
+  
+  llvm::DIType RealDecl =
+    DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, Size,
+                                     Align, 0, 0, llvm::DIType(), Elements);
+
+  // Now that we have a real decl for the struct, replace anything using the
+  // old decl with the new one.  This will recursively update the debug info.
+  FwdDecl.getGV()->replaceAllUsesWith(RealDecl.getGV());
+  FwdDecl.getGV()->eraseFromParent();
+  
+  return RealDecl;
 }
 
-/// getOrCreateEnumType - get Enum type.
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateEnumType(const EnumType *type, 
-                                 llvm::CompileUnitDesc *Unit) {
-  llvm::CompositeTypeDesc *EnumTy 
-    = new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_enumeration_type);
+llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
+                                     llvm::DICompileUnit Unit) {
+  EnumDecl *Decl = Ty->getDecl();
 
-  EnumDecl *EDecl = type->getDecl();
-  SourceManager &SM = M->getContext().getSourceManager();
-  uint64_t Line = SM.getLogicalLineNumber(EDecl->getLocation());
+  llvm::SmallVector<llvm::DIDescriptor, 32> Enumerators;
 
-  // Size, align and offset of the type.
-  uint64_t Size = M->getContext().getTypeSize(type);
-  uint64_t Align = M->getContext().getTypeAlign(type);
-  
-  // Create descriptors for enum members.
-  std::vector<llvm::DebugInfoDesc *> &Elements = EnumTy->getElements();
-  EnumConstantDecl *ElementList = EDecl->getEnumConstantList();
-  while (ElementList) {
-    llvm::EnumeratorDesc *EnumDesc = new llvm::EnumeratorDesc();
-    // push it to the enum desc list so that we can free it later.
-    EnumDescList.push_back(EnumDesc);
-
-    const char *ElementName = ElementList->getName();
-    uint64_t Value = ElementList->getInitVal().getZExtValue();
-
-    EnumDesc->setName(ElementName);
-    EnumDesc->setValue(Value);
-    Elements.push_back(EnumDesc);
-    if (ElementList->getNextDeclarator())
-      ElementList 
-        = dyn_cast<EnumConstantDecl>(ElementList->getNextDeclarator());
-    else
-      break;
+  // Create DIEnumerator elements for each enumerator.
+  for (EnumConstantDecl *Elt = Decl->getEnumConstantList(); Elt;
+       Elt = dyn_cast_or_null<EnumConstantDecl>(Elt->getNextDeclarator())) {
+    Enumerators.push_back(DebugFactory.CreateEnumerator(Elt->getName(),
+                                            Elt->getInitVal().getZExtValue()));
   }
-
-  // Fill in the blanks.
-  if (EnumTy) {
-    EnumTy->setContext(Unit);
-    EnumTy->setName(EDecl->getName());
-    EnumTy->setSize(Size);
-    EnumTy->setAlign(Align);    
-    EnumTy->setOffset(0);
-    EnumTy->setFile(getOrCreateCompileUnit(EDecl->getLocation()));
-    EnumTy->setLine(Line);
-  }
-  return EnumTy;
-}
-
-/// getOrCreateArrayType - get or create array types.
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateArrayType(QualType type, 
-                                  llvm::CompileUnitDesc *Unit) {
-  llvm::CompositeTypeDesc *ArrayTy 
-    = new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_array_type);
-
-  // Size, align and offset of the type.
-  uint64_t Size = M->getContext().getTypeSize(type);
-  uint64_t Align = M->getContext().getTypeAlign(type);
-
+  
+  // Return a CompositeType for the enum itself.
+  llvm::DIArray EltArray =
+    DebugFactory.GetOrCreateArray(&Enumerators[0], Enumerators.size());
+
+  const char *EnumName = Decl->getName() ? Decl->getName() : "";
+  SourceLocation DefLoc = Decl->getLocation();
+  llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(DefLoc);
   SourceManager &SM = M->getContext().getSourceManager();
-  uint64_t Line = SM.getLogicalLineNumber(CurLoc);
-
-  // Add the dimensions of the array.
-  std::vector<llvm::DebugInfoDesc *> &Elements = ArrayTy->getElements();
-  do {
-    const ArrayType *AT = M->getContext().getAsArrayType(type);
-    llvm::SubrangeDesc *Subrange = new llvm::SubrangeDesc();
+  uint64_t Line = SM.getLogicalLineNumber(DefLoc);
+  
+  // Size and align of the type.
+  uint64_t Size = M->getContext().getTypeSize(Ty);
+  uint64_t Align = M->getContext().getTypeAlign(Ty);
+  
+  return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_enumeration_type,
+                                          Unit, EnumName, DefUnit, Line,
+                                          Size, Align, 0, 0,
+                                          llvm::DIType(), EltArray);
+}
 
-    // push it back on the subrange desc list so that we can free it later.
-    SubrangeDescList.push_back(Subrange);
+llvm::DIType CGDebugInfo::CreateType(const TagType *Ty,
+                                     llvm::DICompileUnit Unit) {
+  if (const RecordType *RT = dyn_cast<RecordType>(Ty))
+    return CreateType(RT, Unit);
+  else if (const EnumType *ET = dyn_cast<EnumType>(Ty))
+    return CreateType(ET, Unit);
+  
+  return llvm::DIType();
+}
 
+llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
+                                     llvm::DICompileUnit Unit) {
+  // Size and align of the whole array, not the element type.
+  uint64_t Size = M->getContext().getTypeSize(Ty);
+  uint64_t Align = M->getContext().getTypeAlign(Ty);
+  
+  // Add the dimensions of the array.  FIXME: This loses CV qualifiers from
+  // interior arrays, do we care?  Why aren't nested arrays represented the
+  // obvious/recursive way?
+  llvm::SmallVector<llvm::DIDescriptor, 8> Subscripts;
+  QualType EltTy(Ty, 0);
+  while ((Ty = dyn_cast<ArrayType>(EltTy))) {
     uint64_t Upper = 0;
-    if (const ConstantArrayType *ConstArrTy = dyn_cast<ConstantArrayType>(AT)) {
-      Upper = ConstArrTy->getSize().getZExtValue() - 1;
-    }
-    Subrange->setLo(0);
-    Subrange->setHi(Upper);
-    Elements.push_back(Subrange);
-    type = AT->getElementType();
-  } while (type->isArrayType());
-
-  ArrayTy->setFromType(getOrCreateType(type, Unit));
-
-  if (ArrayTy) {
-    ArrayTy->setContext(Unit);
-    ArrayTy->setSize(Size);
-    ArrayTy->setAlign(Align);
-    ArrayTy->setOffset(0);
-    ArrayTy->setFile(getOrCreateCompileUnit(CurLoc));
-    ArrayTy->setLine(Line);
+    if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty))
+      Upper = CAT->getSize().getZExtValue() - 1;
+    // FIXME: Verify this is right for VLAs.
+    Subscripts.push_back(DebugFactory.GetOrCreateSubrange(0, Upper));
+    EltTy = Ty->getElementType();
   }
-  return ArrayTy;
+  
+  llvm::DIArray SubscriptArray =
+    DebugFactory.GetOrCreateArray(&Subscripts[0], Subscripts.size());
+
+  return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_array_type,
+                                          Unit, "", llvm::DICompileUnit(),
+                                          0, Size, Align, 0, 0,
+                                          getOrCreateType(EltTy, Unit),
+                                          SubscriptArray);
 }
 
 
-/// getOrCreateTaggedType - get or create structure/union/Enum type.
-void CGDebugInfo::getOrCreateTagType(const TagType *type, 
-                                        llvm::CompileUnitDesc *Unit,
-                                        llvm::TypeDesc *&Slot) {
-  if (const RecordType *RT = dyn_cast<RecordType>(type))
-    getOrCreateRecordType(RT, Unit, Slot);
-  else if (const EnumType *ET = dyn_cast<EnumType>(type))
-    Slot = getOrCreateEnumType(ET, Unit);
-}
-  
 /// getOrCreateType - Get the type from the cache or create a new
 /// one if necessary.
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateType(QualType type, llvm::CompileUnitDesc *Unit) {
-  if (type.isNull())
-    return NULL;
-
+llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
+                                          llvm::DICompileUnit Unit) {
+  if (Ty.isNull())
+    return llvm::DIType();
+  
   // Check to see if the compile unit already has created this type.
-  llvm::TypeDesc *&Slot = TypeCache[type.getAsOpaquePtr()];
-  if (Slot) return Slot;
+  llvm::DIType &Slot = TypeCache[Ty.getAsOpaquePtr()];
+  if (!Slot.isNull()) return Slot;
 
-  // We need to check for the CVR qualifiers as the first thing.
-  if (type.getCVRQualifiers()) {
-    Slot = getOrCreateCVRType(type, Unit);
-    return Slot;
-  }
+  // Handle CVR qualifiers, which recursively handles what they refer to.
+  if (Ty.getCVRQualifiers())
+    return Slot = CreateCVRType(Ty, Unit);
 
   // Work out details of type.
-  switch (type->getTypeClass()) {
-    case Type::Complex:
-    case Type::Reference:
-    case Type::Vector:
-    case Type::ExtVector:
-    case Type::ASQual:
-    case Type::ObjCInterface:
-    case Type::ObjCQualifiedInterface:
-    case Type::ObjCQualifiedId:
-    case Type::TypeOfExp:
-    case Type::TypeOfTyp:
-    default:
-      return NULL;
-
-    case Type::TypeName:
-      Slot = getOrCreateTypedefType(cast<TypedefType>(type), Unit);
-      break;
-
-    case Type::FunctionProto:
-    case Type::FunctionNoProto:
-      Slot = getOrCreateFunctionType(type, Unit);
-      break;
-
-    case Type::Builtin:
-      Slot = getOrCreateBuiltinType(cast<BuiltinType>(type), Unit);
-      break;
-
-    case Type::Pointer:
-      Slot = getOrCreatePointerType(cast<PointerType>(type), Unit);
-      break;
-
-    case Type::Tagged:
-      getOrCreateTagType(cast<TagType>(type), Unit, Slot);
-      break;
-
-    case Type::ConstantArray:
-    case Type::VariableArray:
-    case Type::IncompleteArray:
-      Slot = getOrCreateArrayType(type, Unit);
-      break;
+  switch (Ty->getTypeClass()) {
+  case Type::Complex:
+  case Type::Reference:
+  case Type::Vector:
+  case Type::ExtVector:
+  case Type::ASQual:
+  case Type::ObjCInterface:
+  case Type::ObjCQualifiedInterface:
+  case Type::ObjCQualifiedId:
+  case Type::TypeOfExp:
+  case Type::TypeOfTyp:
+  default:
+    return llvm::DIType();
+
+  case Type::Builtin: Slot = CreateType(cast<BuiltinType>(Ty), Unit); break;
+  case Type::Pointer: Slot = CreateType(cast<PointerType>(Ty), Unit); break;
+  case Type::TypeName: Slot = CreateType(cast<TypedefType>(Ty), Unit); break;
+  case Type::Tagged: Slot = CreateType(cast<TagType>(Ty), Unit); break;
+  case Type::FunctionProto:
+  case Type::FunctionNoProto:
+    Slot = CreateType(cast<FunctionType>(Ty), Unit);
+    break;
+    
+  case Type::ConstantArray:
+  case Type::VariableArray:
+  case Type::IncompleteArray:
+    Slot = CreateType(cast<ArrayType>(Ty), Unit);
+    break;
   }
-
+  
   return Slot;
 }
 
 /// EmitFunctionStart - Constructs the debug code for entering a function -
 /// "llvm.dbg.func.start.".
-void CGDebugInfo::EmitFunctionStart(const char *Name,
-                                    QualType ReturnType,
+void CGDebugInfo::EmitFunctionStart(const char *Name, QualType ReturnType,
                                     llvm::Function *Fn,
-                                    CGBuilderTy &Builder)
-{
-  // Create subprogram descriptor.
-  Subprogram = new llvm::SubprogramDesc();
-
-  // Make sure we have an anchor.
-  if (!SubprogramAnchor) {
-    SubprogramAnchor = new llvm::AnchorDesc(Subprogram);
-  }
-
-  // Get name information.
-  Subprogram->setName(Name);
-  Subprogram->setFullName(Name);
-
-  // Gather location information.
-  llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
+                                    CGBuilderTy &Builder) {
+  // FIXME: Why is this using CurLoc???
+  llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc);
   SourceManager &SM = M->getContext().getSourceManager();
-  uint64_t Loc = SM.getLogicalLineNumber(CurLoc);
-
-  // Get Function Type.
-  llvm::TypeDesc *SPTy = getOrCreateType(ReturnType, Unit);
-
-  Subprogram->setAnchor(SubprogramAnchor);
-  Subprogram->setContext(Unit);
-  Subprogram->setFile(Unit);
-  Subprogram->setLine(Loc);
-  Subprogram->setType(SPTy);
-  Subprogram->setIsStatic(Fn->hasInternalLinkage());
-  Subprogram->setIsDefinition(true);
-
-  // Lazily construct llvm.dbg.func.start.
-  if (!FuncStartFn)
-    FuncStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(),
-                    llvm::Intrinsic::dbg_func_start);
-
-  // Call llvm.dbg.func.start which also implicitly calls llvm.dbg.stoppoint.
-  Builder.CreateCall(FuncStartFn, getCastValueFor(Subprogram), "");
-
+  uint64_t LineNo = SM.getLogicalLineNumber(CurLoc);
+  
+  llvm::DISubprogram SP =
+    DebugFactory.CreateSubprogram(Unit, Name, Name, "", Unit, LineNo,
+                                  getOrCreateType(ReturnType, Unit),
+                                  Fn->hasInternalLinkage(), true/*definition*/);
+  
+  DebugFactory.InsertSubprogramStart(SP, Builder.GetInsertBlock());
+                                                        
   // Push function on region stack.
-  RegionStack.push_back(Subprogram);
+  RegionStack.push_back(SP);
 }
 
 
-void 
-CGDebugInfo::EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder) 
-{
+void CGDebugInfo::EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder) {
   if (CurLoc.isInvalid() || CurLoc.isMacroID()) return;
   
   // Don't bother if things are the same as last time.
@@ -654,141 +447,81 @@
   PrevLoc = CurLoc;
 
   // Get the appropriate compile unit.
-  llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
-
-  // Lazily construct llvm.dbg.stoppoint function.
-  if (!StopPointFn)
-    StopPointFn = llvm::Intrinsic::getDeclaration(&M->getModule(), 
-                                        llvm::Intrinsic::dbg_stoppoint);
-
-  uint64_t CurLineNo = SM.getLogicalLineNumber(CurLoc);
-  uint64_t ColumnNo = SM.getLogicalColumnNumber(CurLoc);
-
-  // Invoke llvm.dbg.stoppoint
-  Builder.CreateCall3(StopPointFn, 
-                      llvm::ConstantInt::get(llvm::Type::Int32Ty, CurLineNo),
-                      llvm::ConstantInt::get(llvm::Type::Int32Ty, ColumnNo),
-                      getCastValueFor(Unit), "");
+  llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc);
+  DebugFactory.InsertStopPoint(Unit, SM.getLogicalLineNumber(CurLoc),
+                               SM.getLogicalColumnNumber(CurLoc),
+                               Builder.GetInsertBlock()); 
 }
 
 /// EmitRegionStart- Constructs the debug code for entering a declarative
 /// region - "llvm.dbg.region.start.".
-void CGDebugInfo::EmitRegionStart(llvm::Function *Fn,
-                                  CGBuilderTy &Builder) 
-{
-  llvm::BlockDesc *Block = new llvm::BlockDesc();
+void CGDebugInfo::EmitRegionStart(llvm::Function *Fn, CGBuilderTy &Builder) {
+  llvm::DIDescriptor D;
   if (!RegionStack.empty())
-    Block->setContext(RegionStack.back());
-  RegionStack.push_back(Block);
-
-  // Lazily construct llvm.dbg.region.start function.
-  if (!RegionStartFn)
-    RegionStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(), 
-                                llvm::Intrinsic::dbg_region_start);
-
-  // Call llvm.dbg.func.start.
-  Builder.CreateCall(RegionStartFn, getCastValueFor(Block), "");
+    D = RegionStack.back();
+  D = DebugFactory.CreateBlock(D);
+  RegionStack.push_back(D);
+  DebugFactory.InsertRegionStart(D, Builder.GetInsertBlock());
 }
 
 /// EmitRegionEnd - Constructs the debug code for exiting a declarative
 /// region - "llvm.dbg.region.end."
-void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, CGBuilderTy &Builder) 
-{
+void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, CGBuilderTy &Builder) {
   assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
 
-  // Lazily construct llvm.dbg.region.end function.
-  if (!RegionEndFn)
-    RegionEndFn =llvm::Intrinsic::getDeclaration(&M->getModule(), 
-                                llvm::Intrinsic::dbg_region_end);
-
   // Provide an region stop point.
   EmitStopPoint(Fn, Builder);
   
-  // Call llvm.dbg.func.end.
-  llvm::DebugInfoDesc *DID = RegionStack.back();
-  Builder.CreateCall(RegionEndFn, getCastValueFor(DID), "");
+  DebugFactory.InsertRegionEnd(RegionStack.back(), Builder.GetInsertBlock());
   RegionStack.pop_back();
-  // FIXME: Should be freeing here?
 }
 
 /// EmitDeclare - Emit local variable declaration debug info.
-void CGDebugInfo::EmitDeclare(const VarDecl *decl, unsigned Tag,
-                              llvm::Value *AI,
-                              CGBuilderTy &Builder)
-{
+void CGDebugInfo::EmitDeclare(const VarDecl *Decl, unsigned Tag,
+                              llvm::Value *Storage, CGBuilderTy &Builder) {
   assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
 
-  // FIXME: If it is a compiler generated temporary then return.
-
-  // Construct llvm.dbg.declare function.
-  if (!DeclareFn)
-    DeclareFn = llvm::Intrinsic::getDeclaration(&M->getModule(), 
-                        llvm::Intrinsic::dbg_declare);
-
-  // Get type information.
-  llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
-  llvm::TypeDesc *TyDesc = getOrCreateType(decl->getType(), Unit);
-
+  // Get location information.
   SourceManager &SM = M->getContext().getSourceManager();
-  uint64_t Loc = SM.getLogicalLineNumber(CurLoc);
+  uint64_t Line = SM.getLogicalLineNumber(Decl->getLocation());
+  llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation());
+  
+  // Create the descriptor for the variable.
+  llvm::DIVariable D = 
+    DebugFactory.CreateVariable(Tag, RegionStack.back(), Decl->getName(),
+                                Unit, Line,
+                                getOrCreateType(Decl->getType(), Unit));
+  // Insert an llvm.dbg.declare into the current block.
+  DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock());
+}
+
+void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *Decl,
+                                            llvm::Value *Storage,
+                                            CGBuilderTy &Builder) {
+  EmitDeclare(Decl, llvm::dwarf::DW_TAG_auto_variable, Storage, Builder);
+}
+
+/// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument
+/// variable declaration.
+void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,
+                                           CGBuilderTy &Builder) {
+  EmitDeclare(Decl, llvm::dwarf::DW_TAG_arg_variable, AI, Builder);
+}
 
-  // Construct variable.
-  llvm::VariableDesc *Variable = new llvm::VariableDesc(Tag);
-  Variable->setContext(RegionStack.back());
-  Variable->setName(decl->getName());
-  Variable->setFile(Unit);
-  Variable->setLine(Loc);
-  Variable->setType(TyDesc);
-
-  // Push it onto the list so that we can free it.
-  VariableDescList.push_back(Variable);
-
-  // Cast the AllocA result to a {}* for the call to llvm.dbg.declare.
-  // These bit cast instructions will get freed when the basic block is
-  // deleted. So do not need to free them explicity.
-  const llvm::PointerType *EmpPtr = SR->getEmptyStructPtrType();
-  llvm::Value *AllocACast =  new llvm::BitCastInst(AI, EmpPtr, decl->getName(),
-                               Builder.GetInsertBlock());
 
-  // Call llvm.dbg.declare.
-  Builder.CreateCall2(DeclareFn, AllocACast, getCastValueFor(Variable), "");
-}
 
 /// EmitGlobalVariable - Emit information about a global variable.
-void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *GV, 
-                                     const VarDecl *decl)
-{
+void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, 
+                                     const VarDecl *Decl) {
   // Create global variable debug descriptor.
-  llvm::GlobalVariableDesc *Global = new llvm::GlobalVariableDesc();
-
-  // Push it onto the list so that we can free it.
-  GlobalVarDescList.push_back(Global);
-
-  // Make sure we have an anchor.
-  if (!GlobalVariableAnchor)
-    GlobalVariableAnchor = new llvm::AnchorDesc(Global);
-
-  // Get name information.
-  Global->setName(decl->getName());
-  Global->setFullName(decl->getName());
-
-  llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
+  llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation());
   SourceManager &SM = M->getContext().getSourceManager();
-  uint64_t Loc = SM.getLogicalLineNumber(CurLoc);
-
-  llvm::TypeDesc *TyD = getOrCreateType(decl->getType(), Unit);
-
-  // Fill in the Global information.
-  Global->setAnchor(GlobalVariableAnchor);
-  Global->setContext(Unit);
-  Global->setFile(Unit);
-  Global->setLine(Loc);
-  Global->setType(TyD);
-  Global->setIsDefinition(true);
-  Global->setIsStatic(GV->hasInternalLinkage());
-  Global->setGlobalVariable(GV);
-
-  // Make sure global is created if needed.
-  getValueFor(Global);
+  uint64_t LineNo = SM.getLogicalLineNumber(Decl->getLocation());
+  const char *Name = Decl->getName();
+  
+  DebugFactory.CreateGlobalVariable(Unit, Name, Name, "", Unit, LineNo,
+                                    getOrCreateType(Decl->getType(), Unit),
+                                    Var->hasInternalLinkage(),
+                                    true/*definition*/, Var);
 }
 

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=58971&r1=58970&r2=58971&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Mon Nov 10 00:08:34 2008
@@ -16,30 +16,13 @@
 
 #include "clang/AST/Type.h"
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Analysis/DebugInfo.h"
 #include <map>
-#include <vector>
 
 #include "CGBuilder.h"
 
-namespace llvm {
-  class Function;
-  class DISerializer;
-  class CompileUnitDesc;
-  class BasicBlock;
-  class AnchorDesc;
-  class DebugInfoDesc;
-  class Value;
-  class TypeDesc;
-  class VariableDesc;
-  class SubprogramDesc;
-  class GlobalVariable;
-  class GlobalVariableDesc;
-  class EnumeratorDesc;
-  class SubrangeDesc;
-}
-
 namespace clang {
-  class FunctionDecl;
   class VarDecl;
 
 namespace CodeGen {
@@ -49,54 +32,30 @@
 /// and is responsible for emitting to llvm globals or pass directly to 
 /// the backend.
 class CGDebugInfo {
-private:
   CodeGenModule *M;
-  llvm::DISerializer *SR;
-  SourceLocation CurLoc;
-  SourceLocation PrevLoc;
+  llvm::DIFactory DebugFactory;
+  
+  SourceLocation CurLoc, PrevLoc;
 
   /// CompileUnitCache - Cache of previously constructed CompileUnits.
-  std::map<const FileEntry*, llvm::CompileUnitDesc *> CompileUnitCache;
+  llvm::DenseMap<const FileEntry*, llvm::DICompileUnit> CompileUnitCache;
 
   /// TypeCache - Cache of previously constructed Types.
-  std::map<void *, llvm::TypeDesc *> TypeCache;
+  // FIXME: Eliminate this map.  Be careful of iterator invalidation.
+  std::map<void *, llvm::DIType> TypeCache;
   
-  llvm::Function *StopPointFn;
-  llvm::Function *FuncStartFn;
-  llvm::Function *DeclareFn;
-  llvm::Function *RegionStartFn;
-  llvm::Function *RegionEndFn;
-  llvm::AnchorDesc *CompileUnitAnchor;
-  llvm::AnchorDesc *SubprogramAnchor;
-  llvm::AnchorDesc *GlobalVariableAnchor;
-  std::vector<llvm::DebugInfoDesc *> RegionStack;
-  std::vector<llvm::VariableDesc *> VariableDescList;
-  std::vector<llvm::GlobalVariableDesc *> GlobalVarDescList;
-  std::vector<llvm::EnumeratorDesc *> EnumDescList;
-  std::vector<llvm::SubrangeDesc *> SubrangeDescList;
-  llvm::SubprogramDesc *Subprogram;
+  std::vector<llvm::DIDescriptor> RegionStack;
 
   /// Helper functions for getOrCreateType.
-  llvm::TypeDesc *getOrCreateCVRType(QualType type, 
-                                     llvm::CompileUnitDesc *unit);
-  llvm::TypeDesc *getOrCreateBuiltinType(const BuiltinType *type, 
-                                         llvm::CompileUnitDesc *unit);
-  llvm::TypeDesc *getOrCreateTypedefType(const TypedefType *type, 
-                                         llvm::CompileUnitDesc *unit);
-  llvm::TypeDesc *getOrCreatePointerType(const PointerType *type, 
-                                         llvm::CompileUnitDesc *unit);
-  llvm::TypeDesc *getOrCreateFunctionType(QualType type, 
-                                          llvm::CompileUnitDesc *unit);
-  void getOrCreateRecordType(const RecordType *type,
-                             llvm::CompileUnitDesc *unit,
-                             llvm::TypeDesc *&Slot);
-  llvm::TypeDesc *getOrCreateEnumType(const EnumType *type,
-                                      llvm::CompileUnitDesc *unit);
-  void getOrCreateTagType(const TagType *type,
-                             llvm::CompileUnitDesc *unit,
-                             llvm::TypeDesc *&Slot);
-  llvm::TypeDesc *getOrCreateArrayType(QualType type,
-                                       llvm::CompileUnitDesc *unit);
+  llvm::DIType CreateType(const BuiltinType *Ty, llvm::DICompileUnit U);
+  llvm::DIType CreateCVRType(QualType Ty, llvm::DICompileUnit U);
+  llvm::DIType CreateType(const TypedefType *Ty, llvm::DICompileUnit U);
+  llvm::DIType CreateType(const PointerType *Ty, llvm::DICompileUnit U);
+  llvm::DIType CreateType(const FunctionType *Ty, llvm::DICompileUnit U);
+  llvm::DIType CreateType(const TagType *Ty, llvm::DICompileUnit U);
+  llvm::DIType CreateType(const RecordType *Ty, llvm::DICompileUnit U);
+  llvm::DIType CreateType(const EnumType *Ty, llvm::DICompileUnit U);
+  llvm::DIType CreateType(const ArrayType *Ty, llvm::DICompileUnit U);
 
 public:
   CGDebugInfo(CodeGenModule *m);
@@ -104,7 +63,7 @@
 
   /// setLocation - Update the current source location. If \arg loc is
   /// invalid it is ignored.
-  void setLocation(SourceLocation loc);
+  void setLocation(SourceLocation Loc);
 
   /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of
   /// source line.
@@ -123,31 +82,33 @@
   /// block.
   void EmitRegionEnd(llvm::Function *Fn, CGBuilderTy &Builder);
 
-  /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
-  void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,
-                   CGBuilderTy &Builder);
-
+  /// EmitDeclareOfAutoVariable - Emit call to llvm.dbg.declare for an automatic
+  /// variable declaration.
+  void EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI,
+                                 CGBuilderTy &Builder);
+
+  /// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument
+  /// variable declaration.
+  void EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,
+                                CGBuilderTy &Builder);
+  
   /// EmitGlobalVariable - Emit information about a global variable.
-  void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *decl);
+  void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
  
   
 private:
+  /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
+  void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,
+                   CGBuilderTy &Builder);
+  
   
   /// getOrCreateCompileUnit - Get the compile unit from the cache or create a
   /// new one if necessary.
-  llvm::CompileUnitDesc *getOrCreateCompileUnit(SourceLocation loc);
+  llvm::DICompileUnit getOrCreateCompileUnit(SourceLocation Loc);
 
   /// getOrCreateType - Get the type from the cache or create a new type if
   /// necessary.
-  llvm::TypeDesc *getOrCreateType(QualType type, llvm::CompileUnitDesc *unit);
-
-  /// getCastValueFor - Return a llvm representation for a given debug
-  /// information descriptor cast to an empty struct pointer.
-  llvm::Value *getCastValueFor(llvm::DebugInfoDesc *DD);
-
-  /// getValueFor - Return a llvm representation for a given debug information
-  /// descriptor.
-  llvm::Value *getValueFor(llvm::DebugInfoDesc *DD);
+  llvm::DIType getOrCreateType(QualType Ty, llvm::DICompileUnit Unit);
 };
 } // namespace CodeGen
 } // namespace clang

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=58971&r1=58970&r2=58971&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon Nov 10 00:08:34 2008
@@ -21,7 +21,6 @@
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/Type.h"
-#include "llvm/Support/Dwarf.h"
 using namespace clang;
 using namespace CodeGen;
 
@@ -174,11 +173,9 @@
   DMEntry = DeclPtr;
 
   // Emit debug info for local var declaration.
-  CGDebugInfo *DI = CGM.getDebugInfo();
-  if(DI) {
+  if (CGDebugInfo *DI = CGM.getDebugInfo()) {
     DI->setLocation(D.getLocation());
-    DI->EmitDeclare(&D, llvm::dwarf::DW_TAG_auto_variable,
-                    DeclPtr, Builder);
+    DI->EmitDeclareOfAutoVariable(&D, DeclPtr, Builder);
   }
 
   // If this local has an initializer, emit it now.
@@ -231,12 +228,9 @@
   DMEntry = DeclPtr;
 
   // Emit debug info for param declaration.
-  CGDebugInfo *DI = CGM.getDebugInfo();
-  if(DI) {
+  if (CGDebugInfo *DI = CGM.getDebugInfo()) {
     DI->setLocation(D.getLocation());
-    DI->EmitDeclare(&D, llvm::dwarf::DW_TAG_arg_variable,
-                    DeclPtr, Builder);
+    DI->EmitDeclareOfArgVariable(&D, DeclPtr, Builder);
   }
-
 }
 





More information about the cfe-commits mailing list