Use the new forward declaration scheme for records. Also add more
caching of results after we create them. Fixes rdar://10809898 llvm-svn: 150025
This commit is contained in:
parent
ae56eecf5f
commit
75b90c4a86
|
@ -486,23 +486,22 @@ llvm::DIType CGDebugInfo::createRecordFwdDecl(const RecordDecl *RD,
|
|||
|
||||
llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
|
||||
unsigned Line = getLineNumber(RD->getLocation());
|
||||
|
||||
// Get the tag.
|
||||
const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
|
||||
|
||||
unsigned Tag = 0;
|
||||
if (CXXDecl)
|
||||
return DBuilder.createClassType(Ctx, RD->getName(), DefUnit,
|
||||
Line, 0, 0, 0,
|
||||
llvm::DIType::FlagFwdDecl,
|
||||
llvm::DIType(), llvm::DIArray());
|
||||
Tag = llvm::dwarf::DW_TAG_class_type;
|
||||
else if (RD->isStruct())
|
||||
return DBuilder.createStructType(Ctx, RD->getName(), DefUnit,
|
||||
Line, 0, 0, llvm::DIType::FlagFwdDecl,
|
||||
llvm::DIArray());
|
||||
Tag = llvm::dwarf::DW_TAG_structure_type;
|
||||
else if (RD->isUnion())
|
||||
return DBuilder.createUnionType(Ctx, RD->getName(), DefUnit,
|
||||
Line, 0, 0, llvm::DIType::FlagFwdDecl,
|
||||
llvm::DIArray());
|
||||
Tag = llvm::dwarf::DW_TAG_union_type;
|
||||
else
|
||||
llvm_unreachable("Unknown RecordDecl type!");
|
||||
|
||||
// Create the type.
|
||||
return DBuilder.createForwardDecl(Tag, RD->getName(), DefUnit,
|
||||
Line);
|
||||
}
|
||||
|
||||
// Walk up the context chain and create forward decls for record decls,
|
||||
|
@ -526,7 +525,7 @@ llvm::DIDescriptor CGDebugInfo::createContextChain(const Decl *Context) {
|
|||
llvm::DIDescriptor FDContext =
|
||||
createContextChain(cast<Decl>(RD->getDeclContext()));
|
||||
llvm::DIType Ty = createRecordFwdDecl(RD, FDContext);
|
||||
|
||||
TypeCache[QualType(RD->getTypeForDecl(),0).getAsOpaquePtr()] = Ty;
|
||||
RegionMap[Context] = llvm::WeakVH(Ty);
|
||||
return llvm::DIDescriptor(Ty);
|
||||
}
|
||||
|
@ -556,10 +555,10 @@ llvm::DIType CGDebugInfo::CreatePointeeType(QualType PointeeTy,
|
|||
RecordDecl *RD = RTy->getDecl();
|
||||
llvm::DIDescriptor FDContext =
|
||||
getContextDescriptor(cast<Decl>(RD->getDeclContext()));
|
||||
return createRecordFwdDecl(RD, FDContext);
|
||||
llvm::DIType DTy = createRecordFwdDecl(RD, FDContext);
|
||||
TypeCache[PointeeTy.getAsOpaquePtr()] = DTy;
|
||||
}
|
||||
return getOrCreateType(PointeeTy, Unit);
|
||||
|
||||
}
|
||||
|
||||
llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,
|
||||
|
@ -1151,9 +1150,14 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {
|
|||
|
||||
// If this is just a forward declaration, construct an appropriately
|
||||
// marked node and just return it.
|
||||
if (!RD->getDefinition())
|
||||
return createRecordFwdDecl(RD, RDContext);
|
||||
if (!RD->getDefinition()) {
|
||||
llvm::DIType FwdTy = createRecordFwdDecl(RD, RDContext);
|
||||
TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdTy;
|
||||
return FwdTy;
|
||||
}
|
||||
|
||||
// Create a temporary type here - different than normal forward declared
|
||||
// types.
|
||||
llvm::DIType FwdDecl = DBuilder.createTemporaryType(DefUnit);
|
||||
|
||||
llvm::MDNode *MN = FwdDecl;
|
||||
|
@ -1624,7 +1628,7 @@ llvm::DIType CGDebugInfo::getTypeOrNull(QualType Ty) {
|
|||
|
||||
// Unwrap the type as needed for debug information.
|
||||
Ty = UnwrapTypeForDebugInfo(Ty);
|
||||
|
||||
|
||||
// Check for existing entry.
|
||||
llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
|
||||
TypeCache.find(Ty.getAsOpaquePtr());
|
||||
|
@ -1656,7 +1660,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
|
|||
llvm::DIType Res = CreateTypeNode(Ty, Unit);
|
||||
|
||||
// And update the type cache.
|
||||
TypeCache[Ty.getAsOpaquePtr()] = Res;
|
||||
TypeCache[Ty.getAsOpaquePtr()] = Res;
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s
|
||||
class Test
|
||||
{
|
||||
public:
|
||||
Test () : reserved (new data()) {}
|
||||
|
||||
unsigned
|
||||
getID() const
|
||||
{
|
||||
return reserved->objectID;
|
||||
}
|
||||
protected:
|
||||
struct data {
|
||||
unsigned objectID;
|
||||
};
|
||||
data* reserved;
|
||||
};
|
||||
|
||||
Test t;
|
||||
|
||||
// CHECK: metadata !"data", metadata !7, i32 13, i64 32, i64 32, i32 0, i32 0
|
||||
// CHECK: metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !5} ; [ DW_TAG_pointer_type ]
|
||||
// CHECK-NOT: metadata !"data", metadata !7, i32 13, i64 0, i64 0, i32 0, i32 4,
|
|
@ -19,5 +19,5 @@ void bar() {
|
|||
A a;
|
||||
}
|
||||
|
||||
// B should only be emitted as a forward reference.
|
||||
// CHECK: metadata !"B", metadata !6, i32 3, i64 0, i64 0, i32 0, i32 4, null, null, i32 0, null, null} ; [ DW_TAG_class_type
|
||||
// B should only be emitted as a forward reference (i32 4).
|
||||
// CHECK: metadata !"B", metadata !6, i32 3, i32 0, i32 0, i32 0, i32 4} ; [ DW_TAG_class_type ]
|
||||
|
|
Loading…
Reference in New Issue