forked from OSchip/llvm-project
Revert "DebugInfo: Remove explicit declaration-emissiong handling now that we have a more principled approach (the 'requires complete type' callback)"
This reverts commit r189013. This is causing a segfault crash in a test case I have. Reverting while I investigate the issue. llvm-svn: 189906
This commit is contained in:
parent
8270dcac33
commit
ab415a4b35
clang/lib/CodeGen
|
@ -543,7 +543,8 @@ llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty) {
|
|||
|
||||
/// CreateCVRType - Get the qualified type from the cache or create
|
||||
/// a new one if necessary.
|
||||
llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) {
|
||||
llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit,
|
||||
bool Declaration) {
|
||||
QualifierCollector Qc;
|
||||
const Type *T = Qc.strip(Ty);
|
||||
|
||||
|
@ -569,7 +570,8 @@ llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) {
|
|||
return getOrCreateType(QualType(T, 0), Unit);
|
||||
}
|
||||
|
||||
llvm::DIType FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit);
|
||||
llvm::DIType FromTy =
|
||||
getOrCreateType(Qc.apply(CGM.getContext(), T), Unit, Declaration);
|
||||
|
||||
// No need to fill in the Name, Line, Size, Alignment, Offset in case of
|
||||
// CVR derived types.
|
||||
|
@ -682,7 +684,8 @@ llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,
|
|||
llvm::DIFile Unit) {
|
||||
if (Tag == llvm::dwarf::DW_TAG_reference_type ||
|
||||
Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
|
||||
return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit));
|
||||
return DBuilder.createReferenceType(
|
||||
Tag, getOrCreateType(PointeeTy, Unit, true));
|
||||
|
||||
// Bit size, align and offset of the type.
|
||||
// Size is always the size of a pointer. We can't use getTypeSize here
|
||||
|
@ -691,8 +694,8 @@ llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,
|
|||
uint64_t Size = CGM.getTarget().getPointerWidth(AS);
|
||||
uint64_t Align = CGM.getContext().getTypeAlign(Ty);
|
||||
|
||||
return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
|
||||
Align);
|
||||
return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit, true),
|
||||
Size, Align);
|
||||
}
|
||||
|
||||
llvm::DIType CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
|
||||
|
@ -768,10 +771,12 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
|
|||
return BlockLiteralGeneric;
|
||||
}
|
||||
|
||||
llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit) {
|
||||
llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit,
|
||||
bool Declaration) {
|
||||
// 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);
|
||||
llvm::DIType Src =
|
||||
getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit, Declaration);
|
||||
if (!Src)
|
||||
return llvm::DIType();
|
||||
// We don't set size information, but do specify where the typedef was
|
||||
|
@ -791,7 +796,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
|
|||
SmallVector<llvm::Value *, 16> EltTys;
|
||||
|
||||
// Add the result type at least.
|
||||
EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit));
|
||||
EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit, true));
|
||||
|
||||
// Set up remainder of arguments if there is a prototype.
|
||||
// FIXME: IF NOT, HOW IS THIS REPRESENTED? llvm-gcc doesn't represent '...'!
|
||||
|
@ -799,7 +804,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
|
|||
EltTys.push_back(DBuilder.createUnspecifiedParameter());
|
||||
else if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(Ty)) {
|
||||
for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i)
|
||||
EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit));
|
||||
EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit, true));
|
||||
}
|
||||
|
||||
llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys);
|
||||
|
@ -1196,7 +1201,7 @@ CollectCXXFriends(const CXXRecordDecl *RD, llvm::DIFile Unit,
|
|||
continue;
|
||||
if (TypeSourceInfo *TInfo = (*BI)->getFriendType())
|
||||
EltTys.push_back(DBuilder.createFriend(
|
||||
RecordTy, getOrCreateType(TInfo->getType(), Unit)));
|
||||
RecordTy, getOrCreateType(TInfo->getType(), Unit, true)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1498,16 +1503,12 @@ void CGDebugInfo::completeClassData(const RecordDecl *RD) {
|
|||
}
|
||||
|
||||
/// CreateType - get structure or union type.
|
||||
llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {
|
||||
llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, bool Declaration) {
|
||||
RecordDecl *RD = Ty->getDecl();
|
||||
const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
|
||||
// Always emit declarations for types that aren't required to be complete when
|
||||
// in limit-debug-info mode. If the type is later found to be required to be
|
||||
// complete this declaration will be upgraded to a definition by
|
||||
// `completeRequiredType`.
|
||||
// If the type is dynamic, only emit the definition in TUs that require class
|
||||
// data. This is handled by `completeClassData`.
|
||||
if ((DebugKind <= CodeGenOptions::LimitedDebugInfo &&
|
||||
// Limited debug info should only remove struct definitions that can
|
||||
// safely be replaced by a forward declaration in the source code.
|
||||
if ((DebugKind <= CodeGenOptions::LimitedDebugInfo && Declaration &&
|
||||
!RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) ||
|
||||
(CXXDecl && CXXDecl->hasDefinition() && CXXDecl->isDynamicClass())) {
|
||||
llvm::DIDescriptor FDContext =
|
||||
|
@ -1885,7 +1886,7 @@ llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty,
|
|||
llvm::DIType ClassType = getOrCreateType(QualType(Ty->getClass(), 0), U);
|
||||
if (!Ty->getPointeeType()->isFunctionType())
|
||||
return DBuilder.createMemberPointerType(
|
||||
getOrCreateType(Ty->getPointeeType(), U), ClassType);
|
||||
getOrCreateType(Ty->getPointeeType(), U, true), ClassType);
|
||||
return DBuilder.createMemberPointerType(getOrCreateInstanceMethodType(
|
||||
CGM.getContext().getPointerType(
|
||||
QualType(Ty->getClass(), Ty->getPointeeType().getCVRQualifiers())),
|
||||
|
@ -2065,18 +2066,26 @@ llvm::Value *CGDebugInfo::getCachedInterfaceTypeOrNull(QualType Ty) {
|
|||
|
||||
/// getOrCreateType - Get the type from the cache or create a new
|
||||
/// one if necessary.
|
||||
llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
|
||||
llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit,
|
||||
bool Declaration) {
|
||||
if (Ty.isNull())
|
||||
return llvm::DIType();
|
||||
|
||||
// Unwrap the type as needed for debug information.
|
||||
Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());
|
||||
|
||||
if (llvm::DIType T = getCompletedTypeOrNull(Ty))
|
||||
if (llvm::DIType T = getCompletedTypeOrNull(Ty)) {
|
||||
// If we're looking for a definition, make sure we have definitions of any
|
||||
// underlying types.
|
||||
if (const TypedefType* TTy = dyn_cast<TypedefType>(Ty))
|
||||
getOrCreateType(TTy->getDecl()->getUnderlyingType(), Unit, Declaration);
|
||||
if (Ty.hasLocalQualifiers())
|
||||
getOrCreateType(QualType(Ty.getTypePtr(), 0), Unit, Declaration);
|
||||
return T;
|
||||
}
|
||||
|
||||
// Otherwise create the type.
|
||||
llvm::DIType Res = CreateTypeNode(Ty, Unit);
|
||||
llvm::DIType Res = CreateTypeNode(Ty, Unit, Declaration);
|
||||
void* TyPtr = Ty.getAsOpaquePtr();
|
||||
|
||||
// And update the type cache.
|
||||
|
@ -2145,10 +2154,11 @@ ObjCInterfaceDecl *CGDebugInfo::getObjCInterfaceDecl(QualType Ty) {
|
|||
}
|
||||
|
||||
/// CreateTypeNode - Create a new debug type node.
|
||||
llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {
|
||||
llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit,
|
||||
bool Declaration) {
|
||||
// Handle qualifiers, which recursively handles what they refer to.
|
||||
if (Ty.hasLocalQualifiers())
|
||||
return CreateQualifiedType(Ty, Unit);
|
||||
return CreateQualifiedType(Ty, Unit, Declaration);
|
||||
|
||||
const char *Diag = 0;
|
||||
|
||||
|
@ -2183,9 +2193,9 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {
|
|||
case Type::BlockPointer:
|
||||
return CreateType(cast<BlockPointerType>(Ty), Unit);
|
||||
case Type::Typedef:
|
||||
return CreateType(cast<TypedefType>(Ty), Unit);
|
||||
return CreateType(cast<TypedefType>(Ty), Unit, Declaration);
|
||||
case Type::Record:
|
||||
return CreateType(cast<RecordType>(Ty));
|
||||
return CreateType(cast<RecordType>(Ty), Declaration);
|
||||
case Type::Enum:
|
||||
return CreateEnumType(cast<EnumType>(Ty));
|
||||
case Type::FunctionProto:
|
||||
|
@ -2371,7 +2381,7 @@ llvm::DIDescriptor CGDebugInfo::getDeclarationOrDefinition(const Decl *D) {
|
|||
// in unlimited debug info)
|
||||
if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
|
||||
return getOrCreateType(CGM.getContext().getTypeDeclType(TD),
|
||||
getOrCreateFile(TD->getLocation()));
|
||||
getOrCreateFile(TD->getLocation()), true);
|
||||
// Otherwise fall back to a fairly rudimentary cache of existing declarations.
|
||||
// This doesn't handle providing declarations (for functions or variables) for
|
||||
// entities without definitions in this TU, nor when the definition proceeds
|
||||
|
|
|
@ -107,14 +107,14 @@ class CGDebugInfo {
|
|||
unsigned Checksum(const ObjCInterfaceDecl *InterfaceDecl);
|
||||
llvm::DIType CreateType(const BuiltinType *Ty);
|
||||
llvm::DIType CreateType(const ComplexType *Ty);
|
||||
llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile Fg);
|
||||
llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile Fg);
|
||||
llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile F, bool Declaration);
|
||||
llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile F, bool Declaration);
|
||||
llvm::DIType CreateType(const ObjCObjectPointerType *Ty,
|
||||
llvm::DIFile F);
|
||||
llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F);
|
||||
llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F);
|
||||
llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F);
|
||||
llvm::DIType CreateType(const RecordType *Tyg);
|
||||
llvm::DIType CreateType(const RecordType *Ty, bool Declaration);
|
||||
llvm::DIType CreateTypeDefinition(const RecordType *Ty);
|
||||
llvm::DICompositeType CreateLimitedType(const RecordType *Ty);
|
||||
void CollectContainingType(const CXXRecordDecl *RD, llvm::DICompositeType CT);
|
||||
|
@ -330,14 +330,14 @@ private:
|
|||
|
||||
/// getOrCreateType - Get the type from the cache or create a new type if
|
||||
/// necessary.
|
||||
llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile Fg);
|
||||
llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F, bool Declaration = false);
|
||||
|
||||
/// getOrCreateLimitedType - Get the type from the cache or create a new
|
||||
/// partial type if necessary.
|
||||
llvm::DIType getOrCreateLimitedType(const RecordType *Ty, llvm::DIFile F);
|
||||
|
||||
/// CreateTypeNode - Create type metadata for a source language type.
|
||||
llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile Fg);
|
||||
llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F, bool Declaration);
|
||||
|
||||
/// getObjCInterfaceDecl - return the underlying ObjCInterfaceDecl
|
||||
/// if Ty is an ObjCInterface or a pointer to one.
|
||||
|
|
Loading…
Reference in New Issue