summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGDebugInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp686
1 files changed, 550 insertions, 136 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 2bf8a222a2531..4c624205b4cac 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "CGDebugInfo.h"
+#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
@@ -19,6 +20,7 @@
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/Version.h"
#include "clang/Frontend/CompileOptions.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
@@ -47,6 +49,22 @@ void CGDebugInfo::setLocation(SourceLocation Loc) {
CurLoc = M->getContext().getSourceManager().getInstantiationLoc(Loc);
}
+/// getContext - Get context info for the decl.
+llvm::DIDescriptor CGDebugInfo::getContext(const VarDecl *Decl,
+ llvm::DIDescriptor &CompileUnit) {
+ if (Decl->isFileVarDecl())
+ return CompileUnit;
+ if (Decl->getDeclContext()->isFunctionOrMethod()) {
+ // Find the last subprogram in region stack.
+ for (unsigned RI = RegionStack.size(), RE = 0; RI != RE; --RI) {
+ llvm::DIDescriptor R = RegionStack[RI - 1];
+ if (R.isSubprogram())
+ return R;
+ }
+ }
+ return CompileUnit;
+}
+
/// getOrCreateCompileUnit - Get the compile unit from the cache or create a new
/// one if necessary. This returns null for invalid source locations.
llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) {
@@ -59,7 +77,7 @@ llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) {
FileName = PLoc.getFilename();
FID = PLoc.getIncludeLoc().getRawEncoding();
}
-
+
// See if this compile unit has been used before.
llvm::DICompileUnit &Unit = CompileUnitCache[FID];
if (!Unit.isNull()) return Unit;
@@ -104,7 +122,11 @@ llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) {
LangTag = llvm::dwarf::DW_LANG_C89;
}
- std::string Producer = "clang 1.0";// FIXME: clang version.
+ std::string Producer =
+#ifdef CLANG_VENDOR
+ CLANG_VENDOR
+#endif
+ "clang " CLANG_VERSION_STRING;
bool isOptimized = LO.Optimize;
const char *Flags = ""; // FIXME: Encode command line options.
@@ -112,10 +134,10 @@ llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) {
unsigned RuntimeVers = 0;
if (LO.ObjC1)
RuntimeVers = LO.ObjCNonFragileABI ? 2 : 1;
-
+
// Create new compile unit.
return Unit = DebugFactory.CreateCompileUnit(LangTag, AbsFileName.getLast(),
- AbsFileName.getDirname(),
+ AbsFileName.getDirname(),
Producer, isMain, isOptimized,
Flags, RuntimeVers);
}
@@ -143,14 +165,15 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT,
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::LongDouble:
case BuiltinType::Double: Encoding = llvm::dwarf::DW_ATE_float; break;
- }
+ }
// Bit size, align and offset of the type.
uint64_t Size = M->getContext().getTypeSize(BT);
uint64_t Align = M->getContext().getTypeAlign(BT);
uint64_t Offset = 0;
-
- return DebugFactory.CreateBasicType(Unit,
+
+ return DebugFactory.CreateBasicType(Unit,
BT->getName(M->getContext().getLangOptions()),
Unit, 0, Size, Align,
Offset, /*flags*/ 0, Encoding);
@@ -162,52 +185,72 @@ llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty,
unsigned Encoding = llvm::dwarf::DW_ATE_complex_float;
if (Ty->isComplexIntegerType())
Encoding = llvm::dwarf::DW_ATE_lo_user;
-
+
uint64_t Size = M->getContext().getTypeSize(Ty);
uint64_t Align = M->getContext().getTypeAlign(Ty);
uint64_t Offset = 0;
-
+
return DebugFactory.CreateBasicType(Unit, "complex",
Unit, 0, Size, Align,
Offset, /*flags*/ 0, Encoding);
}
-/// getOrCreateCVRType - Get the CVR qualified type from the cache or create
+/// CreateCVRType - Get the qualified type from the cache or create
/// a new one if necessary.
-llvm::DIType CGDebugInfo::CreateCVRType(QualType Ty, llvm::DICompileUnit Unit) {
+llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DICompileUnit Unit) {
+ QualifierCollector Qc;
+ const Type *T = Qc.strip(Ty);
+
+ // Ignore these qualifiers for now.
+ Qc.removeObjCGCAttr();
+ Qc.removeAddressSpace();
+
// We will create one Derived type for one qualifier and recurse to handle any
// additional ones.
- llvm::DIType FromTy;
unsigned Tag;
- if (Ty.isConstQualified()) {
+ if (Qc.hasConst()) {
Tag = llvm::dwarf::DW_TAG_const_type;
- Ty.removeConst();
- FromTy = getOrCreateType(Ty, Unit);
- } else if (Ty.isVolatileQualified()) {
+ Qc.removeConst();
+ } else if (Qc.hasVolatile()) {
Tag = llvm::dwarf::DW_TAG_volatile_type;
- Ty.removeVolatile();
- FromTy = getOrCreateType(Ty, Unit);
- } else {
- assert(Ty.isRestrictQualified() && "Unknown type qualifier for debug info");
+ Qc.removeVolatile();
+ } else if (Qc.hasRestrict()) {
Tag = llvm::dwarf::DW_TAG_restrict_type;
- Ty.removeRestrict();
- FromTy = getOrCreateType(Ty, Unit);
+ Qc.removeRestrict();
+ } else {
+ assert(Qc.empty() && "Unknown type qualifier for debug info");
+ return getOrCreateType(QualType(T, 0), Unit);
}
-
+
+ llvm::DIType FromTy = getOrCreateType(Qc.apply(T), 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);
}
+llvm::DIType CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty,
+ llvm::DICompileUnit Unit) {
+ llvm::DIType EltTy = getOrCreateType(Ty->getPointeeType(), Unit);
+
+ // Bit size, align and offset of the type.
+ uint64_t Size = M->getContext().getTypeSize(Ty);
+ uint64_t Align = M->getContext().getTypeAlign(Ty);
+
+ return DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit,
+ "", llvm::DICompileUnit(),
+ 0, Size, Align, 0, 0, EltTy);
+}
+
llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty,
llvm::DICompileUnit Unit) {
llvm::DIType EltTy = getOrCreateType(Ty->getPointeeType(), Unit);
-
+
// Bit size, align and offset of the type.
uint64_t Size = M->getContext().getTypeSize(Ty);
uint64_t Align = M->getContext().getTypeAlign(Ty);
-
+
return DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit,
"", llvm::DICompileUnit(),
0, Size, Align, 0, 0, EltTy);
@@ -258,14 +301,16 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
EltTys.clear();
+ unsigned Flags = llvm::DIType::FlagAppleBlock;
+
EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_descriptor",
- DefUnit, 0, FieldOffset, 0, 0, 0,
+ DefUnit, 0, FieldOffset, 0, 0, Flags,
llvm::DIType(), Elements);
-
+
// Bit size, align and offset of the type.
uint64_t Size = M->getContext().getTypeSize(Ty);
uint64_t Align = M->getContext().getTypeAlign(Ty);
-
+
DescTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
Unit, "", llvm::DICompileUnit(),
0, Size, Align, 0, 0, EltTy);
@@ -329,9 +374,9 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_literal_generic",
- DefUnit, 0, FieldOffset, 0, 0, 0,
+ DefUnit, 0, FieldOffset, 0, 0, Flags,
llvm::DIType(), Elements);
-
+
BlockLiteralGenericSet = true;
BlockLiteralGeneric
= DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit,
@@ -345,7 +390,7 @@ llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty,
// 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.
std::string TyName = Ty->getDecl()->getNameAsString();
@@ -366,7 +411,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
// 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 FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(Ty)) {
@@ -378,7 +423,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
llvm::DIArray EltTypeArray =
DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
-
+
return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
Unit, "", llvm::DICompileUnit(),
0, 0, 0, 0, 0,
@@ -389,7 +434,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
llvm::DICompileUnit Unit) {
RecordDecl *Decl = Ty->getDecl();
-
+
unsigned Tag;
if (Decl->isStruct())
Tag = llvm::dwarf::DW_TAG_structure_type;
@@ -412,24 +457,24 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
DefUnit = getOrCreateCompileUnit(Decl->getLocation());
Line = PLoc.getLine();
}
-
+
// 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 =
+ llvm::DICompositeType 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;
+ TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl.getNode();
// Convert all the elements.
llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
@@ -438,7 +483,7 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
unsigned FieldNo = 0;
for (RecordDecl::field_iterator I = Decl->field_begin(),
- E = Decl->field_end();
+ E = Decl->field_end();
I != E; ++I, ++FieldNo) {
FieldDecl *Field = *I;
llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
@@ -454,7 +499,7 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
PresumedLoc PLoc = SM.getPresumedLoc(FieldDefLoc);
llvm::DICompileUnit FieldDefUnit;
unsigned FieldLine = 0;
-
+
if (!PLoc.isInvalid()) {
FieldDefUnit = getOrCreateCompileUnit(FieldDefLoc);
FieldLine = PLoc.getLine();
@@ -464,18 +509,18 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
uint64_t FieldSize = 0;
unsigned FieldAlign = 0;
if (!FType->isIncompleteArrayType()) {
-
+
// Bit size, align and offset of the type.
FieldSize = M->getContext().getTypeSize(FType);
Expr *BitWidth = Field->getBitWidth();
if (BitWidth)
FieldSize = BitWidth->EvaluateAsInt(M->getContext()).getZExtValue();
-
+
FieldAlign = M->getContext().getTypeAlign(FType);
}
- uint64_t FieldOffset = RL.getFieldOffset(FieldNo);
-
+ 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.
@@ -485,23 +530,25 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
}
-
+
llvm::DIArray Elements =
DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
// 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 =
+
+ llvm::DICompositeType RealDecl =
DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, Size,
Align, 0, 0, llvm::DIType(), Elements);
+ // Update TypeCache.
+ TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RealDecl.getNode();
+
// 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();
-
+ FwdDecl.replaceAllUsesWith(RealDecl);
+
return RealDecl;
}
@@ -509,7 +556,7 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
llvm::DICompileUnit Unit) {
ObjCInterfaceDecl *Decl = Ty->getDecl();
-
+
unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
SourceManager &SM = M->getContext().getSourceManager();
@@ -520,7 +567,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
PresumedLoc PLoc = SM.getPresumedLoc(Decl->getLocation());
unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine();
-
+
unsigned RuntimeLang = DefUnit.getLanguage();
// To handle recursive interface, we
@@ -529,27 +576,27 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
// 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 =
+ llvm::DICompositeType FwdDecl =
DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, 0, 0, 0, 0,
llvm::DIType(), llvm::DIArray(),
RuntimeLang);
-
+
// If this is just a forward declaration, return it.
if (Decl->isForwardDecl())
return FwdDecl;
// Otherwise, insert it into the TypeCache so that recursive uses will find
// it.
- TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
+ TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl.getNode();
// Convert all the elements.
llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
ObjCInterfaceDecl *SClass = Decl->getSuperClass();
if (SClass) {
- llvm::DIType SClassTy =
+ llvm::DIType SClassTy =
getOrCreateType(M->getContext().getObjCInterfaceType(SClass), Unit);
- llvm::DIType InhTag =
+ llvm::DIType InhTag =
DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_inheritance,
Unit, "", llvm::DICompileUnit(), 0, 0, 0,
0 /* offset */, 0, SClassTy);
@@ -576,13 +623,13 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
PresumedLoc PLoc = SM.getPresumedLoc(FieldDefLoc);
unsigned FieldLine = PLoc.isInvalid() ? 0 : PLoc.getLine();
-
+
QualType FType = Field->getType();
uint64_t FieldSize = 0;
unsigned FieldAlign = 0;
if (!FType->isIncompleteArrayType()) {
-
+
// Bit size, align and offset of the type.
FieldSize = M->getContext().getTypeSize(FType);
Expr *BitWidth = Field->getBitWidth();
@@ -592,14 +639,14 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
FieldAlign = M->getContext().getTypeAlign(FType);
}
- uint64_t FieldOffset = RL.getFieldOffset(FieldNo);
-
+ uint64_t FieldOffset = RL.getFieldOffset(FieldNo);
+
unsigned Flags = 0;
if (Field->getAccessControl() == ObjCIvarDecl::Protected)
Flags = llvm::DIType::FlagProtected;
else if (Field->getAccessControl() == ObjCIvarDecl::Private)
Flags = llvm::DIType::FlagPrivate;
-
+
// 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.
@@ -609,24 +656,26 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
FieldOffset, Flags, FieldTy);
EltTys.push_back(FieldTy);
}
-
+
llvm::DIArray Elements =
DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
// 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 =
+
+ llvm::DICompositeType RealDecl =
DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, Size,
Align, 0, 0, llvm::DIType(), Elements,
RuntimeLang);
+ // Update TypeCache.
+ TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RealDecl.getNode();
+
// 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();
-
+ FwdDecl.replaceAllUsesWith(RealDecl);
+
return RealDecl;
}
@@ -637,13 +686,13 @@ llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
llvm::SmallVector<llvm::DIDescriptor, 32> Enumerators;
// Create DIEnumerator elements for each enumerator.
- for (EnumDecl::enumerator_iterator
+ for (EnumDecl::enumerator_iterator
Enum = Decl->enumerator_begin(), EnumEnd = Decl->enumerator_end();
Enum != EnumEnd; ++Enum) {
Enumerators.push_back(DebugFactory.CreateEnumerator(Enum->getNameAsString(),
Enum->getInitVal().getZExtValue()));
}
-
+
// Return a CompositeType for the enum itself.
llvm::DIArray EltArray =
DebugFactory.GetOrCreateArray(Enumerators.data(), Enumerators.size());
@@ -655,7 +704,7 @@ llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
PresumedLoc PLoc = SM.getPresumedLoc(DefLoc);
unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine();
-
+
// Size and align of the type.
uint64_t Size = 0;
unsigned Align = 0;
@@ -663,7 +712,7 @@ llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
Size = M->getContext().getTypeSize(Ty);
Align = M->getContext().getTypeAlign(Ty);
}
-
+
return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_enumeration_type,
Unit, EnumName, DefUnit, Line,
Size, Align, 0, 0,
@@ -676,7 +725,7 @@ llvm::DIType CGDebugInfo::CreateType(const TagType *Ty,
return CreateType(RT, Unit);
else if (const EnumType *ET = dyn_cast<EnumType>(Ty))
return CreateType(ET, Unit);
-
+
return llvm::DIType();
}
@@ -684,8 +733,8 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
llvm::DICompileUnit Unit) {
uint64_t Size;
uint64_t Align;
-
-
+
+
// FIXME: make getTypeAlign() aware of VLAs and incomplete array types
if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(Ty)) {
Size = 0;
@@ -699,7 +748,7 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
Size = M->getContext().getTypeSize(Ty);
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?
@@ -708,12 +757,13 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
while ((Ty = dyn_cast<ArrayType>(EltTy))) {
uint64_t Upper = 0;
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty))
- Upper = CAT->getSize().getZExtValue() - 1;
+ if (CAT->getSize().getZExtValue())
+ Upper = CAT->getSize().getZExtValue() - 1;
// FIXME: Verify this is right for VLAs.
Subscripts.push_back(DebugFactory.GetOrCreateSubrange(0, Upper));
EltTy = Ty->getElementType();
}
-
+
llvm::DIArray SubscriptArray =
DebugFactory.GetOrCreateArray(Subscripts.data(), Subscripts.size());
@@ -731,14 +781,29 @@ 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::DIType &Slot = TypeCache[Ty.getAsOpaquePtr()];
- if (!Slot.isNull()) return Slot;
- // Handle CVR qualifiers, which recursively handles what they refer to.
- if (Ty.getCVRQualifiers())
- return Slot = CreateCVRType(Ty, Unit);
+ // Check for existing entry.
+ std::map<void *, llvm::WeakVH>::iterator it =
+ TypeCache.find(Ty.getAsOpaquePtr());
+ if (it != TypeCache.end()) {
+ // Verify that the debug info still exists.
+ if (&*it->second)
+ return llvm::DIType(cast<llvm::MDNode>(it->second));
+ }
+
+ // Otherwise create the type.
+ llvm::DIType Res = CreateTypeNode(Ty, Unit);
+ TypeCache.insert(std::make_pair(Ty.getAsOpaquePtr(), Res.getNode()));
+ return Res;
+}
+
+/// getOrCreateTypeNode - Get the type metadata node from the cache or create a
+/// new one if necessary.
+llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty,
+ llvm::DICompileUnit Unit) {
+ // Handle qualifiers, which recursively handles what they refer to.
+ if (Ty.hasQualifiers())
+ return CreateQualifiedType(Ty, Unit);
// Work out details of type.
switch (Ty->getTypeClass()) {
@@ -748,53 +813,52 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
#define DEPENDENT_TYPE(Class, Base) case Type::Class:
#include "clang/AST/TypeNodes.def"
assert(false && "Dependent types cannot show up in debug information");
-
+
+ default:
case Type::LValueReference:
case Type::RValueReference:
case Type::Vector:
case Type::ExtVector:
- case Type::ExtQual:
case Type::FixedWidthInt:
case Type::MemberPointer:
case Type::TemplateSpecialization:
case Type::QualifiedName:
// Unsupported types
return llvm::DIType();
- case Type::ObjCObjectPointer: // Encode id<p> in debug info just like id.
- return Slot = getOrCreateType(M->getContext().getObjCIdType(), Unit);
-
- case Type::ObjCQualifiedInterface: // Drop protocols from interface.
- case Type::ObjCInterface:
- return Slot = CreateType(cast<ObjCInterfaceType>(Ty), Unit);
- case Type::Builtin: return Slot = CreateType(cast<BuiltinType>(Ty), Unit);
- case Type::Complex: return Slot = CreateType(cast<ComplexType>(Ty), Unit);
- case Type::Pointer: return Slot = CreateType(cast<PointerType>(Ty), Unit);
+ case Type::ObjCObjectPointer:
+ return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
+ case Type::ObjCInterface:
+ return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
+ case Type::Builtin: return CreateType(cast<BuiltinType>(Ty), Unit);
+ case Type::Complex: return CreateType(cast<ComplexType>(Ty), Unit);
+ case Type::Pointer: return CreateType(cast<PointerType>(Ty), Unit);
case Type::BlockPointer:
- return Slot = CreateType(cast<BlockPointerType>(Ty), Unit);
- case Type::Typedef: return Slot = CreateType(cast<TypedefType>(Ty), Unit);
+ return CreateType(cast<BlockPointerType>(Ty), Unit);
+ case Type::Typedef: return CreateType(cast<TypedefType>(Ty), Unit);
case Type::Record:
case Type::Enum:
- return Slot = CreateType(cast<TagType>(Ty), Unit);
+ return CreateType(cast<TagType>(Ty), Unit);
case Type::FunctionProto:
case Type::FunctionNoProto:
- return Slot = CreateType(cast<FunctionType>(Ty), Unit);
-
+ return CreateType(cast<FunctionType>(Ty), Unit);
+ case Type::Elaborated:
+ return getOrCreateType(cast<ElaboratedType>(Ty)->getUnderlyingType(),
+ Unit);
+
case Type::ConstantArray:
+ case Type::ConstantArrayWithExpr:
+ case Type::ConstantArrayWithoutExpr:
case Type::VariableArray:
case Type::IncompleteArray:
- return Slot = CreateType(cast<ArrayType>(Ty), Unit);
+ return CreateType(cast<ArrayType>(Ty), Unit);
case Type::TypeOfExpr:
- return Slot = getOrCreateType(cast<TypeOfExprType>(Ty)->getUnderlyingExpr()
- ->getType(), Unit);
+ return getOrCreateType(cast<TypeOfExprType>(Ty)->getUnderlyingExpr()
+ ->getType(), Unit);
case Type::TypeOf:
- return Slot = getOrCreateType(cast<TypeOfType>(Ty)->getUnderlyingType(),
- Unit);
+ return getOrCreateType(cast<TypeOfType>(Ty)->getUnderlyingType(), Unit);
case Type::Decltype:
- return Slot = getOrCreateType(cast<DecltypeType>(Ty)->getUnderlyingExpr()
- ->getType(), Unit);
+ return getOrCreateType(cast<DecltypeType>(Ty)->getUnderlyingType(), Unit);
}
-
- return Slot;
}
/// EmitFunctionStart - Constructs the debug code for entering a function -
@@ -803,25 +867,27 @@ void CGDebugInfo::EmitFunctionStart(const char *Name, QualType ReturnType,
llvm::Function *Fn,
CGBuilderTy &Builder) {
const char *LinkageName = Name;
-
+
// Skip the asm prefix if it exists.
//
// FIXME: This should probably be the unmangled name?
if (Name[0] == '\01')
++Name;
-
+
// FIXME: Why is this using CurLoc???
llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc);
SourceManager &SM = M->getContext().getSourceManager();
unsigned LineNo = SM.getPresumedLoc(CurLoc).getLine();
-
+
llvm::DISubprogram SP =
DebugFactory.CreateSubprogram(Unit, Name, Name, LinkageName, Unit, LineNo,
getOrCreateType(ReturnType, Unit),
Fn->hasInternalLinkage(), true/*definition*/);
-
+
+#ifndef ATTACH_DEBUG_INFO_TO_AN_INSN
DebugFactory.InsertSubprogramStart(SP, Builder.GetInsertBlock());
-
+#endif
+
// Push function on region stack.
RegionStack.push_back(SP);
}
@@ -829,10 +895,10 @@ void CGDebugInfo::EmitFunctionStart(const char *Name, QualType ReturnType,
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.
SourceManager &SM = M->getContext().getSourceManager();
- if (CurLoc == PrevLoc
+ if (CurLoc == PrevLoc
|| (SM.getInstantiationLineNumber(CurLoc) ==
SM.getInstantiationLineNumber(PrevLoc)
&& SM.isFromSameFile(CurLoc, PrevLoc)))
@@ -844,8 +910,19 @@ void CGDebugInfo::EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder) {
// Get the appropriate compile unit.
llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc);
PresumedLoc PLoc = SM.getPresumedLoc(CurLoc);
+
+#ifdef ATTACH_DEBUG_INFO_TO_AN_INSN
+ llvm::DIDescriptor DR = RegionStack.back();
+ llvm::DIScope DS = llvm::DIScope(DR.getNode());
+ llvm::DILocation DO(NULL);
+ llvm::DILocation DL =
+ DebugFactory.CreateLocation(PLoc.getLine(), PLoc.getColumn(),
+ DS, DO);
+ Builder.SetCurrentDebugLocation(DL.getNode());
+#else
DebugFactory.InsertStopPoint(Unit, PLoc.getLine(), PLoc.getColumn(),
- Builder.GetInsertBlock());
+ Builder.GetInsertBlock());
+#endif
}
/// EmitRegionStart- Constructs the debug code for entering a declarative
@@ -854,9 +931,11 @@ void CGDebugInfo::EmitRegionStart(llvm::Function *Fn, CGBuilderTy &Builder) {
llvm::DIDescriptor D;
if (!RegionStack.empty())
D = RegionStack.back();
- D = DebugFactory.CreateBlock(D);
+ D = DebugFactory.CreateLexicalBlock(D);
RegionStack.push_back(D);
+#ifndef ATTACH_DEBUG_INFO_TO_AN_INSN
DebugFactory.InsertRegionStart(D, Builder.GetInsertBlock());
+#endif
}
/// EmitRegionEnd - Constructs the debug code for exiting a declarative
@@ -866,8 +945,10 @@ void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, CGBuilderTy &Builder) {
// Provide an region stop point.
EmitStopPoint(Fn, Builder);
-
+
+#ifndef ATTACH_DEBUG_INFO_TO_AN_INSN
DebugFactory.InsertRegionEnd(RegionStack.back(), Builder.GetInsertBlock());
+#endif
RegionStack.pop_back();
}
@@ -884,7 +965,139 @@ void CGDebugInfo::EmitDeclare(const VarDecl *Decl, unsigned Tag,
return;
llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation());
- llvm::DIType Ty = getOrCreateType(Decl->getType(), Unit);
+ QualType Type = Decl->getType();
+ llvm::DIType Ty = getOrCreateType(Type, Unit);
+ if (Decl->hasAttr<BlocksAttr>()) {
+ llvm::DICompileUnit DefUnit;
+ unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
+
+ llvm::SmallVector<llvm::DIDescriptor, 5> EltTys;
+
+ llvm::DIType FieldTy;
+
+ QualType FType;
+ uint64_t FieldSize, FieldOffset;
+ unsigned FieldAlign;
+
+ llvm::DIArray Elements;
+ llvm::DIType EltTy;
+
+ // Build up structure for the byref. See BuildByRefType.
+ FieldOffset = 0;
+ FType = M->getContext().getPointerType(M->getContext().VoidTy);
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ "__isa", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+
+ FType = M->getContext().getPointerType(M->getContext().VoidTy);
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ "__forwarding", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+
+ FType = M->getContext().getFixedWidthIntType(32, true); // Int32Ty;
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ "__flags", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+
+ FType = M->getContext().getFixedWidthIntType(32, true); // Int32Ty;
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ "__size", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+
+ bool HasCopyAndDispose = M->BlockRequiresCopying(Type);
+ if (HasCopyAndDispose) {
+ FType = M->getContext().getPointerType(M->getContext().VoidTy);
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ "__copy_helper", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+
+ FType = M->getContext().getPointerType(M->getContext().VoidTy);
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ "__destroy_helper", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+ }
+
+ unsigned Align = M->getContext().getDeclAlignInBytes(Decl);
+ if (Align > M->getContext().Target.getPointerAlign(0) / 8) {
+ unsigned AlignedOffsetInBytes
+ = llvm::RoundUpToAlignment(FieldOffset/8, Align);
+ unsigned NumPaddingBytes
+ = AlignedOffsetInBytes - FieldOffset/8;
+
+ if (NumPaddingBytes > 0) {
+ llvm::APInt pad(32, NumPaddingBytes);
+ FType = M->getContext().getConstantArrayType(M->getContext().CharTy,
+ pad, ArrayType::Normal, 0);
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member,
+ Unit, "", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+ }
+ }
+
+ FType = Type;
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = Align*8;
+ std::string Name = Decl->getNameAsString();
+
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ Name, DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+
+ Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
+
+ unsigned Flags = llvm::DIType::FlagBlockByrefStruct;
+
+ Ty = DebugFactory.CreateCompositeType(Tag, Unit, "",
+ llvm::DICompileUnit(),
+ 0, FieldOffset, 0, 0, Flags,
+ llvm::DIType(), Elements);
+ }
// Get location information.
SourceManager &SM = M->getContext().getSourceManager();
@@ -895,21 +1108,222 @@ void CGDebugInfo::EmitDeclare(const VarDecl *Decl, unsigned Tag,
else
Unit = llvm::DICompileUnit();
-
+
// Create the descriptor for the variable.
- llvm::DIVariable D =
+ llvm::DIVariable D =
DebugFactory.CreateVariable(Tag, RegionStack.back(),Decl->getNameAsString(),
Unit, Line, Ty);
// Insert an llvm.dbg.declare into the current block.
DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock());
}
+/// EmitDeclare - Emit local variable declaration debug info.
+void CGDebugInfo::EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag,
+ llvm::Value *Storage, CGBuilderTy &Builder,
+ CodeGenFunction *CGF) {
+ const ValueDecl *Decl = BDRE->getDecl();
+ assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
+
+ // Do not emit variable debug information while generating optimized code.
+ // The llvm optimizer and code generator are not yet ready to support
+ // optimized code debugging.
+ const CompileOptions &CO = M->getCompileOpts();
+ if (CO.OptimizationLevel || Builder.GetInsertBlock() == 0)
+ return;
+
+ uint64_t XOffset = 0;
+ llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation());
+ QualType Type = Decl->getType();
+ llvm::DIType Ty = getOrCreateType(Type, Unit);
+ if (Decl->hasAttr<BlocksAttr>()) {
+ llvm::DICompileUnit DefUnit;
+ unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
+
+ llvm::SmallVector<llvm::DIDescriptor, 5> EltTys;
+
+ llvm::DIType FieldTy;
+
+ QualType FType;
+ uint64_t FieldSize, FieldOffset;
+ unsigned FieldAlign;
+
+ llvm::DIArray Elements;
+ llvm::DIType EltTy;
+
+ // Build up structure for the byref. See BuildByRefType.
+ FieldOffset = 0;
+ FType = M->getContext().getPointerType(M->getContext().VoidTy);
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ "__isa", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+
+ FType = M->getContext().getPointerType(M->getContext().VoidTy);
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ "__forwarding", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+
+ FType = M->getContext().getFixedWidthIntType(32, true); // Int32Ty;
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ "__flags", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+
+ FType = M->getContext().getFixedWidthIntType(32, true); // Int32Ty;
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ "__size", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+
+ bool HasCopyAndDispose = M->BlockRequiresCopying(Type);
+ if (HasCopyAndDispose) {
+ FType = M->getContext().getPointerType(M->getContext().VoidTy);
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ "__copy_helper", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+
+ FType = M->getContext().getPointerType(M->getContext().VoidTy);
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ "__destroy_helper", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+ }
+
+ unsigned Align = M->getContext().getDeclAlignInBytes(Decl);
+ if (Align > M->getContext().Target.getPointerAlign(0) / 8) {
+ unsigned AlignedOffsetInBytes
+ = llvm::RoundUpToAlignment(FieldOffset/8, Align);
+ unsigned NumPaddingBytes
+ = AlignedOffsetInBytes - FieldOffset/8;
+
+ if (NumPaddingBytes > 0) {
+ llvm::APInt pad(32, NumPaddingBytes);
+ FType = M->getContext().getConstantArrayType(M->getContext().CharTy,
+ pad, ArrayType::Normal, 0);
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = M->getContext().getTypeAlign(FType);
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member,
+ Unit, "", DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+ }
+ }
+
+ FType = Type;
+ FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ FieldSize = M->getContext().getTypeSize(FType);
+ FieldAlign = Align*8;
+ std::string Name = Decl->getNameAsString();
+
+ XOffset = FieldOffset;
+ FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+ Name, DefUnit,
+ 0, FieldSize, FieldAlign,
+ FieldOffset, 0, FieldTy);
+ EltTys.push_back(FieldTy);
+ FieldOffset += FieldSize;
+
+ Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
+
+ unsigned Flags = llvm::DIType::FlagBlockByrefStruct;
+
+ Ty = DebugFactory.CreateCompositeType(Tag, Unit, "",
+ llvm::DICompileUnit(),
+ 0, FieldOffset, 0, 0, Flags,
+ llvm::DIType(), Elements);
+ }
+
+ // Get location information.
+ SourceManager &SM = M->getContext().getSourceManager();
+ PresumedLoc PLoc = SM.getPresumedLoc(Decl->getLocation());
+ unsigned Line = 0;
+ if (!PLoc.isInvalid())
+ Line = PLoc.getLine();
+ else
+ Unit = llvm::DICompileUnit();
+
+ uint64_t offset = CGF->BlockDecls[Decl];
+ llvm::SmallVector<llvm::Value *, 9> addr;
+ llvm::LLVMContext &VMContext = M->getLLVMContext();
+ addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+ llvm::DIFactory::OpDeref));
+ addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+ llvm::DIFactory::OpPlus));
+ addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+ offset));
+ if (BDRE->isByRef()) {
+ addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+ llvm::DIFactory::OpDeref));
+ addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+ llvm::DIFactory::OpPlus));
+ offset = CGF->LLVMPointerWidth/8; // offset of __forwarding field
+ addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+ offset));
+ addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+ llvm::DIFactory::OpDeref));
+ addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+ llvm::DIFactory::OpPlus));
+ offset = XOffset/8; // offset of x field
+ addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+ offset));
+ }
+
+ // Create the descriptor for the variable.
+ llvm::DIVariable D =
+ DebugFactory.CreateComplexVariable(Tag, RegionStack.back(),
+ Decl->getNameAsString(), Unit, Line, Ty,
+ addr);
+ // Insert an llvm.dbg.declare into the current block.
+ DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertPoint());
+}
+
void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *Decl,
llvm::Value *Storage,
CGBuilderTy &Builder) {
EmitDeclare(Decl, llvm::dwarf::DW_TAG_auto_variable, Storage, Builder);
}
+void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
+ const BlockDeclRefExpr *BDRE, llvm::Value *Storage, CGBuilderTy &Builder,
+ CodeGenFunction *CGF) {
+ EmitDeclare(BDRE, llvm::dwarf::DW_TAG_auto_variable, Storage, Builder, CGF);
+}
+
/// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument
/// variable declaration.
void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,
@@ -920,7 +1334,7 @@ void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,
/// EmitGlobalVariable - Emit information about a global variable.
-void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
+void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
const VarDecl *Decl) {
// Do not emit variable debug information while generating optimized code.
@@ -936,29 +1350,30 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
PresumedLoc PLoc = SM.getPresumedLoc(Decl->getLocation());
unsigned LineNo = PLoc.isInvalid() ? 0 : PLoc.getLine();
- std::string Name = Decl->getNameAsString();
+ std::string Name = Var->getName();
QualType T = Decl->getType();
if (T->isIncompleteArrayType()) {
-
+
// CodeGen turns int[] into int[1] so we'll do the same here.
llvm::APSInt ConstVal(32);
-
+
ConstVal = 1;
QualType ET = M->getContext().getAsArrayType(T)->getElementType();
-
- T = M->getContext().getConstantArrayType(ET, ConstVal,
+
+ T = M->getContext().getConstantArrayType(ET, ConstVal,
ArrayType::Normal, 0);
}
- DebugFactory.CreateGlobalVariable(Unit, Name, Name, "", Unit, LineNo,
+ DebugFactory.CreateGlobalVariable(getContext(Decl, Unit),
+ Name, Name, "", Unit, LineNo,
getOrCreateType(T, Unit),
Var->hasInternalLinkage(),
true/*definition*/, Var);
}
/// EmitGlobalVariable - Emit information about an objective-c interface.
-void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
+void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
ObjCInterfaceDecl *Decl) {
// Create global variable debug descriptor.
llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation());
@@ -970,14 +1385,14 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
QualType T = M->getContext().getObjCInterfaceType(Decl);
if (T->isIncompleteArrayType()) {
-
+
// CodeGen turns int[] into int[1] so we'll do the same here.
llvm::APSInt ConstVal(32);
-
+
ConstVal = 1;
QualType ET = M->getContext().getAsArrayType(T)->getElementType();
-
- T = M->getContext().getConstantArrayType(ET, ConstVal,
+
+ T = M->getContext().getConstantArrayType(ET, ConstVal,
ArrayType::Normal, 0);
}
@@ -986,4 +1401,3 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
Var->hasInternalLinkage(),
true/*definition*/, Var);
}
-