[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