This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rG711a64412749: [clang][DebugInfo] Emit DW_AT_type of preferred name if available (authored by Michael137).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D145803/new/ https://reviews.llvm.org/D145803 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/lib/CodeGen/CGDebugInfo.h clang/test/CodeGen/preferred_name-chain.cpp clang/test/CodeGen/preferred_name.cpp clang/test/Modules/Inputs/gmodules-preferred-name-alias.h clang/test/Modules/Inputs/gmodules-preferred-name-alias.modulemap clang/test/Modules/Inputs/gmodules-preferred-name-typedef.h clang/test/Modules/Inputs/gmodules-preferred-name-typedef.modulemap clang/test/Modules/gmodules-preferred-name-alias.cpp clang/test/Modules/gmodules-preferred-name-typedef.cpp lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py =================================================================== --- lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py +++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py @@ -22,7 +22,7 @@ def make_expected_basic_string_ptr(self) -> str: if self.expectedCompiler(["clang"]) and self.expectedCompilerVersion(['>', '16.0']): - return f'std::unique_ptr<std::basic_string<char> >' + return f'std::unique_ptr<std::string>' else: return 'std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, ' \ 'std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >' Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py =================================================================== --- lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py +++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py @@ -59,13 +59,13 @@ self.assertNotEqual(valobj.child[0].unsigned, 0) if self.expectedCompiler(["clang"]) and self.expectedCompilerVersion(['>', '16.0']): - string_type = "std::basic_string<char>" + string_type = "std::string" else: - string_type = "std::basic_string<char, std::char_traits<char>, std::allocator<char> >" + string_type = "std::basic_string<char, std::char_traits<char>, std::allocator<char> > " valobj = self.expect_var_path( "sp_str", - type="std::shared_ptr<" + string_type + " >", + type="std::shared_ptr<" + string_type + ">", children=[ValueCheck(name="__ptr_", summary='"hello"')], ) self.assertRegex(valobj.summary, r'^"hello"( strong=1)? weak=1$') Index: clang/test/Modules/gmodules-preferred-name-typedef.cpp =================================================================== --- /dev/null +++ clang/test/Modules/gmodules-preferred-name-typedef.cpp @@ -0,0 +1,12 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -std=c++11 -dwarf-ext-refs -fmodule-format=obj \ +// RUN: -fmodule-map-file=%S/Inputs/gmodules-preferred-name-typedef.modulemap \ +// RUN: -fmodules-cache-path=%t -debug-info-kind=standalone -debugger-tuning=lldb \ +// RUN: -fmodules -mllvm -debug-only=pchcontainer -x c++ \ +// RUN: -I %S/Inputs %s &> %t.ll +// RUN: cat %t.ll | FileCheck %s + +#include "gmodules-preferred-name-typedef.h" + +// CHECK: ![[#]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[PREF_BASE:[0-9]+]]) +// CHECK: ![[PREF_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<char>" Index: clang/test/Modules/gmodules-preferred-name-alias.cpp =================================================================== --- /dev/null +++ clang/test/Modules/gmodules-preferred-name-alias.cpp @@ -0,0 +1,12 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -std=c++11 -dwarf-ext-refs -fmodule-format=obj \ +// RUN: -fmodule-map-file=%S/Inputs/gmodules-preferred-name-alias.modulemap \ +// RUN: -fmodules-cache-path=%t -debug-info-kind=standalone -debugger-tuning=lldb \ +// RUN: -fmodules -mllvm -debug-only=pchcontainer -x c++ \ +// RUN: -I %S/Inputs %s &> %t.ll +// RUN: cat %t.ll | FileCheck %s + +#include "gmodules-preferred-name-alias.h" + +// CHECK: ![[#]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<char>", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[PREF_BASE:[0-9]+]]) +// CHECK: ![[PREF_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<char>" Index: clang/test/Modules/Inputs/gmodules-preferred-name-typedef.modulemap =================================================================== --- /dev/null +++ clang/test/Modules/Inputs/gmodules-preferred-name-typedef.modulemap @@ -0,0 +1,4 @@ +module PreferredNameModule { + header "gmodules-preferred-name-typedef.h" + export * +} Index: clang/test/Modules/Inputs/gmodules-preferred-name-typedef.h =================================================================== --- /dev/null +++ clang/test/Modules/Inputs/gmodules-preferred-name-typedef.h @@ -0,0 +1,7 @@ +template<typename T> struct Foo; + +typedef Foo<char> Bar; + +template<typename T> struct [[clang::preferred_name(Bar)]] Foo {}; + +template <typename T> struct Baz { Foo<char> member; }; Index: clang/test/Modules/Inputs/gmodules-preferred-name-alias.modulemap =================================================================== --- /dev/null +++ clang/test/Modules/Inputs/gmodules-preferred-name-alias.modulemap @@ -0,0 +1,4 @@ +module PreferredNameModule { + header "gmodules-preferred-name-alias.h" + export * +} Index: clang/test/Modules/Inputs/gmodules-preferred-name-alias.h =================================================================== --- /dev/null +++ clang/test/Modules/Inputs/gmodules-preferred-name-alias.h @@ -0,0 +1,8 @@ +template<typename T> struct Foo; + +template<typename T> +using Bar = Foo<T>; + +template<typename T> struct [[clang::preferred_name(Bar<T>)]] Foo {}; + +template <typename T> struct Baz { Foo<char> member; }; Index: clang/test/CodeGen/preferred_name.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/preferred_name.cpp @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=standalone -debugger-tuning=lldb %s | FileCheck %s --check-prefixes=COMMON,LLDB +// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=standalone -debugger-tuning=gdb %s | FileCheck %s --check-prefixes=COMMON,GDB + +template <typename T> +struct Foo; + +typedef Foo<int> BarInt; +typedef Foo<double> BarDouble; + +template <typename T> +using Bar = Foo<T>; + +template <typename T> +struct [[clang::preferred_name(BarInt), + clang::preferred_name(BarDouble), + clang::preferred_name(Bar<short>), + clang::preferred_name(Bar<char>)]] Foo{ + }; + +int main() { + Foo<int> varInt; + +// COMMON: !DILocalVariable(name: "varInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_INT_TY:[0-9]+]]) +// LLDB: ![[BAR_INT_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarInt", file: ![[#]], line: [[#]], baseType: ![[BAR_INT_BASE:[0-9]+]]) +// LLDB: ![[BAR_INT_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<int>", file: ![[#]], line: [[#]], size: [[#]] +// GDB: ![[BAR_INT_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<int>", file: ![[#]], line: [[#]], size: [[#]] + + Foo<double> varDouble; + +// COMMON: !DILocalVariable(name: "varDouble", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_DOUBLE_TY:[0-9]+]]) +// LLDB: ![[BAR_DOUBLE_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarDouble", file: ![[#]], line: [[#]], baseType: ![[BAR_DOUBLE_BASE:[0-9]+]]) +// LLDB: ![[BAR_DOUBLE_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<double>" +// GDB: ![[BAR_DOUBLE_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<double>" + + Foo<short> varShort; + +// COMMON: !DILocalVariable(name: "varShort", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_SHORT_TY:[0-9]+]]) +// LLDB: ![[BAR_SHORT_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<short>", file: ![[#]], line: [[#]], baseType: ![[BAR_SHORT_BASE:[0-9]+]]) +// LLDB: ![[BAR_SHORT_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<short>" +// GDB: ![[BAR_SHORT_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<short>" + + Foo<char> varChar; + +// COMMON: !DILocalVariable(name: "varChar", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_CHAR_TY:[0-9]+]]) +// LLDB: ![[BAR_CHAR_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<char>", file: ![[#]], line: [[#]], baseType: ![[BAR_CHAR_BASE:[0-9]+]]) +// LLDB: ![[BAR_CHAR_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<char>" +// GDB: ![[BAR_CHAR_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<char>" + + Foo<Foo<int>> varFooInt; + +// COMMON: !DILocalVariable(name: "varFooInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[FOO_BAR_INT_TY:[0-9]+]]) +// COMMON: ![[FOO_BAR_INT_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<Foo<int> >" +// COMMON-SAME: templateParams: ![[PARAM:[0-9]+]] +// COMMON: ![[PARAM]] = !{![[TEMPL_TYPE_PARAM:[0-9]+]]} +// GDB: ![[TEMPL_TYPE_PARAM]] = !DITemplateTypeParameter(name: "T", type: ![[BAR_INT_TY]]) +// LLDB: ![[TEMPL_TYPE_PARAM]] = !DITemplateTypeParameter(name: "T", type: ![[BAR_INT_TY]]) + + BarInt barInt; + +// LLDB: !DILocalVariable(name: "barInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_INT_TY]]) +// GDB: !DILocalVariable(name: "barInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_INT_TYPEDEF:[0-9]+]]) +// GDB: ![[BAR_INT_TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarInt" + + BarDouble barDouble; + +// LLDB: !DILocalVariable(name: "barDouble", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_DOUBLE_TY]]) +// GDB: !DILocalVariable(name: "barDouble", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_DOUBLE_TYPEDEF:[0-9]+]]) +// GDB: ![[BAR_DOUBLE_TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarDouble" + + Bar<short> barShort; + +// LLDB: !DILocalVariable(name: "barShort", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_SHORT_TY_2:[0-9]+]]) +// GDB: !DILocalVariable(name: "barShort", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_SHORT_TYPEDEF:[0-9]+]]) +// GDB: ![[BAR_SHORT_TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<short>" + + Bar<char> barChar; + +// LLDB: ![[BAR_SHORT_TY_2]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<short>", file: ![[#]], line: [[#]], baseType: ![[BAR_SHORT_TY]]) + +// LLDB: !DILocalVariable(name: "barChar", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_CHAR_TY_2:[0-9]+]]) +// GDB: !DILocalVariable(name: "barChar", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_CHAR_TYPEDEF:[0-9]+]]) +// GDB: ![[BAR_CHAR_TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<char>" + +// LLDB: ![[BAR_CHAR_TY_2]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<char>", file: ![[#]], line: [[#]], baseType: ![[BAR_CHAR_TY]]) + + return 0; +} + + Index: clang/test/CodeGen/preferred_name-chain.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/preferred_name-chain.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=standalone -debugger-tuning=lldb %s | FileCheck %s --check-prefixes=COMMON,LLDB +// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=standalone -debugger-tuning=gdb %s | FileCheck %s --check-prefixes=COMMON,GDB + +template <typename T> +struct Foo; + +typedef Foo<int> BarIntBase; +typedef BarIntBase BarIntTmp; +typedef BarIntTmp BarInt; + +template <typename T> +using BarBase = Foo<T>; + +template <typename T> +using BarTmp = BarBase<T>; + +template <typename T> +using Bar = BarTmp<T>; + +template <typename T> +struct [[clang::preferred_name(BarInt), + clang::preferred_name(Bar<char>)]] Foo{ + }; + +int main() { + Foo<int> varInt; + +// COMMON: !DILocalVariable(name: "varInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_INT_TY:[0-9]+]]) +// LLDB: ![[BAR_INT_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarInt", file: ![[#]], line: [[#]], baseType: ![[BAR_INT_TMP:[0-9]+]]) +// LLDB: ![[BAR_INT_TMP]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarIntTmp", file: ![[#]], line: [[#]], baseType: ![[BAR_INT_BASE:[0-9]+]]) +// LLDB: ![[BAR_INT_BASE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarIntBase", file: ![[#]], line: [[#]], baseType: ![[FOO_INT:[0-9]+]]) +// LLDB: ![[FOO_INT]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<int>", file: ![[#]], line: [[#]], size: [[#]] +// GDB: ![[BAR_INT_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<int>", file: ![[#]], line: [[#]], size: [[#]] + + Foo<char> varChar; + +// COMMON: !DILocalVariable(name: "varChar", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_CHAR_TY:[0-9]+]]) +// LLDB: ![[BAR_CHAR_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<char>", file: ![[#]], line: [[#]], baseType: ![[BAR_CHAR_TMP:[0-9]+]]) +// LLDB: ![[BAR_CHAR_TMP]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarTmp<char>", file: ![[#]], line: [[#]], baseType: ![[BAR_CHAR_BASE:[0-9]+]]) +// LLDB: ![[BAR_CHAR_BASE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarBase<char>", file: ![[#]], line: [[#]], baseType: ![[FOO_CHAR:[0-9]+]]) +// LLDB: ![[FOO_CHAR]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<char>" +// GDB: ![[BAR_CHAR_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<char>" + + Foo<Foo<int>> varFooInt; + +// COMMON: !DILocalVariable(name: "varFooInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[FOO_BAR_INT_TY:[0-9]+]]) +// COMMON: ![[FOO_BAR_INT_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<Foo<int> >" +// COMMON-SAME: templateParams: ![[PARAM:[0-9]+]] +// COMMON: ![[PARAM]] = !{![[TEMPL_TYPE_PARAM:[0-9]+]]} +// GDB: ![[TEMPL_TYPE_PARAM]] = !DITemplateTypeParameter(name: "T", type: ![[BAR_INT_TY]]) +// LLDB: ![[TEMPL_TYPE_PARAM]] = !DITemplateTypeParameter(name: "T", type: ![[BAR_INT_TY]]) + + Foo<Foo<char>> varFooChar; + +// COMMON: !DILocalVariable(name: "varFooChar", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[FOO_BAR_CHAR_TY:[0-9]+]]) +// COMMON: ![[FOO_BAR_CHAR_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<Foo<char> >" +// COMMON-SAME: templateParams: ![[CHAR_PARAM:[0-9]+]] +// COMMON: ![[CHAR_PARAM]] = !{![[CHAR_TEMPL_TYPE_PARAM:[0-9]+]]} +// GDB: ![[CHAR_TEMPL_TYPE_PARAM]] = !DITemplateTypeParameter(name: "T", type: ![[BAR_CHAR_TY]]) +// LLDB: ![[CHAR_TEMPL_TYPE_PARAM]] = !DITemplateTypeParameter(name: "T", type: ![[BAR_CHAR_TY]]) + + return 0; +} + + Index: clang/lib/CodeGen/CGDebugInfo.h =================================================================== --- clang/lib/CodeGen/CGDebugInfo.h +++ clang/lib/CodeGen/CGDebugInfo.h @@ -192,7 +192,15 @@ llvm::DIType *CreateType(const FunctionType *Ty, llvm::DIFile *F); /// Get structure or union type. llvm::DIType *CreateType(const RecordType *Tyg); - llvm::DIType *CreateTypeDefinition(const RecordType *Ty); + + /// Create definition for the specified 'Ty'. + /// + /// \returns A pair of 'llvm::DIType's. The first is the definition + /// of the 'Ty'. The second is the type specified by the preferred_name + /// attribute on 'Ty', which can be a nullptr if no such attribute + /// exists. + std::pair<llvm::DIType *, llvm::DIType *> + CreateTypeDefinition(const RecordType *Ty); llvm::DICompositeType *CreateLimitedType(const RecordType *Ty); void CollectContainingType(const CXXRecordDecl *RD, llvm::DICompositeType *CT); @@ -276,6 +284,12 @@ llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes, llvm::DINode::DIFlags StartingFlags); + /// Helper function that returns the llvm::DIType that the + /// PreferredNameAttr attribute on \ref RD refers to. If no such + /// attribute exists, returns nullptr. + llvm::DIType *GetPreferredNameType(const CXXRecordDecl *RD, + llvm::DIFile *Unit); + struct TemplateArgs { const TemplateParameterList *TList; llvm::ArrayRef<TemplateArgument> Args; Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -2556,7 +2556,11 @@ auto I = TypeCache.find(TyPtr); if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl()) return; - llvm::DIType *Res = CreateTypeDefinition(Ty->castAs<RecordType>()); + + // We want the canonical definition of the structure to not + // be the typedef. Since that would lead to circular typedef + // metadata. + auto [Res, PrefRes] = CreateTypeDefinition(Ty->castAs<RecordType>()); assert(!Res->isForwardDecl()); TypeCache[TyPtr].reset(Res); } @@ -2676,10 +2680,25 @@ return T; } - return CreateTypeDefinition(Ty); + auto [Def, Pref] = CreateTypeDefinition(Ty); + + return Pref ? Pref : Def; } -llvm::DIType *CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { +llvm::DIType *CGDebugInfo::GetPreferredNameType(const CXXRecordDecl *RD, + llvm::DIFile *Unit) { + if (!RD) + return nullptr; + + auto const *PNA = RD->getAttr<PreferredNameAttr>(); + if (!PNA) + return nullptr; + + return getOrCreateType(PNA->getTypedefType(), Unit); +} + +std::pair<llvm::DIType *, llvm::DIType *> +CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { RecordDecl *RD = Ty->getDecl(); // Get overall information about the record type for the debug info. @@ -2695,7 +2714,7 @@ const RecordDecl *D = RD->getDefinition(); if (!D || !D->isCompleteDefinition()) - return FwdDecl; + return {FwdDecl, nullptr}; if (const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) CollectContainingType(CXXDecl, FwdDecl); @@ -2734,7 +2753,12 @@ llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl)); RegionMap[Ty->getDecl()].reset(FwdDecl); - return FwdDecl; + + if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB) + if (auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit)) + return {FwdDecl, PrefDI}; + + return {FwdDecl, nullptr}; } llvm::DIType *CGDebugInfo::CreateType(const ObjCObjectType *Ty, @@ -3763,7 +3787,7 @@ void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD, llvm::DICompositeType *RealDecl) { // A class's primary base or the class itself contains the vtable. - llvm::DICompositeType *ContainingType = nullptr; + llvm::DIType *ContainingType = nullptr; const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) { // Seek non-virtual primary base root. @@ -3775,9 +3799,8 @@ else break; } - ContainingType = cast<llvm::DICompositeType>( - getOrCreateType(QualType(PBase->getTypeForDecl(), 0), - getOrCreateFile(RD->getLocation()))); + ContainingType = getOrCreateType(QualType(PBase->getTypeForDecl(), 0), + getOrCreateFile(RD->getLocation())); } else if (RD->isDynamicClass()) ContainingType = RealDecl;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits