From: Duncan P. N. Exon Smith Date: Thu, 18 Dec 2014 00:48:56 +0000 (+0000) Subject: CGDebugInfo: Use DIBuilder API for self-referencing DICompositeTypes X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8422f691261bc6e04a4e15ea3b4589e79154a08f;p=clang CGDebugInfo: Use DIBuilder API for self-referencing DICompositeTypes Use new `DIBuilder` API from LLVM r224482 to mutate `DICompositeType`s, rather than changing them directly. This allows `DIBuilder` to track otherwise orphaned cycles when `CollectContainingType()` creates a self-reference. Fixes PR21941. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@224483 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 5bf460f2b8..dc4084613c 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -422,9 +422,10 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) { DBuilder.createStructType(TheCU, "objc_object", getOrCreateMainFile(), 0, 0, 0, 0, llvm::DIType(), llvm::DIArray()); - ObjTy.setArrays(DBuilder.getOrCreateArray( - &*DBuilder.createMemberType(ObjTy, "isa", getOrCreateMainFile(), 0, - Size, 0, 0, 0, ISATy))); + DBuilder.replaceArrays( + ObjTy, + DBuilder.getOrCreateArray(&*DBuilder.createMemberType( + ObjTy, "isa", getOrCreateMainFile(), 0, Size, 0, 0, 0, ISATy))); return ObjTy; } case BuiltinType::ObjCSel: { @@ -1593,7 +1594,7 @@ llvm::DIType CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { RegionMap.erase(Ty->getDecl()); llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys); - FwdDecl.setArrays(Elements); + DBuilder.replaceArrays(FwdDecl, Elements); RegionMap[Ty->getDecl()].reset(FwdDecl); return FwdDecl; @@ -1795,7 +1796,7 @@ llvm::DIType CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty, } llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys); - RealDecl.setArrays(Elements); + DBuilder.replaceArrays(RealDecl, Elements); LexicalBlockStack.pop_back(); return RealDecl; @@ -2204,7 +2205,7 @@ llvm::DIType CGDebugInfo::getOrCreateLimitedType(const RecordType *Ty, // Propagate members from the declaration to the definition // CreateType(const RecordType*) will overwrite this with the members in the // correct order if the full type is needed. - Res.setArrays(T.getElements()); + DBuilder.replaceArrays(Res, T.getElements()); // And update the type cache. TypeCache[QTy.getAsOpaquePtr()].reset(Res); @@ -2260,8 +2261,8 @@ llvm::DICompositeType CGDebugInfo::CreateLimitedType(const RecordType *Ty) { if (const ClassTemplateSpecializationDecl *TSpecial = dyn_cast(RD)) - RealDecl.setArrays(llvm::DIArray(), - CollectCXXTemplateParams(TSpecial, DefUnit)); + DBuilder.replaceArrays(RealDecl, llvm::DIArray(), + CollectCXXTemplateParams(TSpecial, DefUnit)); return RealDecl; } @@ -2286,7 +2287,7 @@ void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD, } else if (RD->isDynamicClass()) ContainingType = RealDecl; - RealDecl.setContainingType(ContainingType); + DBuilder.replaceVTableHolder(RealDecl, ContainingType); } /// CreateMemberType - Create new member and increase Offset by FType's size. diff --git a/test/CodeGenCXX/vtable-holder-self-reference.cpp b/test/CodeGenCXX/vtable-holder-self-reference.cpp new file mode 100644 index 0000000000..d311ea6594 --- /dev/null +++ b/test/CodeGenCXX/vtable-holder-self-reference.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-llvm -gdwarf-2 -x c++ -o - %s | FileCheck %s +// +// PR21941: crasher for self-referencing DW_TAG_structure_type node. If we get +// rid of self-referenceing structure_types (PR21902), then it should be safe +// to just kill this test. +// +// CHECK: ![[SELF:[0-9]+]] = !{!"0x13\00B\00{{[^"]*}}", {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, ![[SELF]], {{[^}]+}}} ; [ DW_TAG_structure_type ] [B] + +void foo() { + struct V { + int vi; + }; + struct B : virtual V {}; + B b; +}