diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index e819c3d13697..13a0666ccdd3 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -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(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(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(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::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; } diff --git a/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp b/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp new file mode 100644 index 000000000000..766a613e7002 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp @@ -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, diff --git a/clang/test/CodeGenCXX/debug-info-limit-type.cpp b/clang/test/CodeGenCXX/debug-info-limit-type.cpp index f0138ef5865d..760e3ece39ef 100644 --- a/clang/test/CodeGenCXX/debug-info-limit-type.cpp +++ b/clang/test/CodeGenCXX/debug-info-limit-type.cpp @@ -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 ]