From 9018ef709e798ad49957fc808744aee4ecf52b5f Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Fri, 5 Oct 2012 01:49:33 +0000 Subject: [PATCH] Make sure to generate the right kind of MDNode for enum forward declarations. PR14029, clang part. llvm-svn: 165289 --- clang/lib/CodeGen/CGDebugInfo.cpp | 31 ++++++++++++++++++------- clang/test/CodeGenCXX/debug-info-enum-class.cpp | 16 ++++++++++++- clang/test/CodeGenObjC/debug-info-fwddecl.m | 2 +- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 9a0bcd5..16115c1 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1598,9 +1598,29 @@ llvm::DIType CGDebugInfo::CreateType(const AtomicType *Ty, /// CreateEnumType - get enumeration type. llvm::DIType CGDebugInfo::CreateEnumType(const EnumDecl *ED) { - SmallVector Enumerators; + uint64_t Size = 0; + uint64_t Align = 0; + if (!ED->getTypeForDecl()->isIncompleteType()) { + Size = CGM.getContext().getTypeSize(ED->getTypeForDecl()); + Align = CGM.getContext().getTypeAlign(ED->getTypeForDecl()); + } + + // If this is just a forward declaration, construct an appropriately + // marked node and just return it. + if (!ED->getDefinition()) { + llvm::DIDescriptor EDContext; + EDContext = getContextDescriptor(cast(ED->getDeclContext())); + llvm::DIFile DefUnit = getOrCreateFile(ED->getLocation()); + unsigned Line = getLineNumber(ED->getLocation()); + StringRef EDName = ED->getName(); + return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_enumeration_type, + EDName, EDContext, DefUnit, Line, 0, + Size, Align); + } // Create DIEnumerator elements for each enumerator. + SmallVector Enumerators; + ED = ED->getDefinition(); for (EnumDecl::enumerator_iterator Enum = ED->enumerator_begin(), EnumEnd = ED->enumerator_end(); Enum != EnumEnd; ++Enum) { @@ -1614,21 +1634,14 @@ llvm::DIType CGDebugInfo::CreateEnumType(const EnumDecl *ED) { llvm::DIFile DefUnit = getOrCreateFile(ED->getLocation()); unsigned Line = getLineNumber(ED->getLocation()); - uint64_t Size = 0; - uint64_t Align = 0; - if (!ED->getTypeForDecl()->isIncompleteType()) { - Size = CGM.getContext().getTypeSize(ED->getTypeForDecl()); - Align = CGM.getContext().getTypeAlign(ED->getTypeForDecl()); - } llvm::DIDescriptor EnumContext = getContextDescriptor(cast(ED->getDeclContext())); llvm::DIType ClassTy = ED->isScopedUsingClassTag() ? getOrCreateType(ED->getIntegerType(), DefUnit) : llvm::DIType(); - unsigned Flags = !ED->isCompleteDefinition() ? llvm::DIDescriptor::FlagFwdDecl : 0; llvm::DIType DbgTy = DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, Line, Size, Align, EltArray, - ClassTy, Flags); + ClassTy); return DbgTy; } diff --git a/clang/test/CodeGenCXX/debug-info-enum-class.cpp b/clang/test/CodeGenCXX/debug-info-enum-class.cpp index 6f88439..fd243ab 100644 --- a/clang/test/CodeGenCXX/debug-info-enum-class.cpp +++ b/clang/test/CodeGenCXX/debug-info-enum-class.cpp @@ -12,4 +12,18 @@ D d; // CHECK: metadata !{i32 {{.*}}, null, metadata !"A", metadata !4, i32 3, i64 32, i64 32, i32 0, i32 0, metadata !5, metadata !6, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] // CHECK: metadata !{i32 {{.*}}, null, metadata !"B", metadata !4, i32 4, i64 64, i64 64, i32 0, i32 0, metadata !9, metadata !10, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] // CHECK: metadata !{i32 {{.*}}, null, metadata !"C", metadata !4, i32 5, i64 32, i64 32, i32 0, i32 0, null, metadata !13, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] -// CHECK: metadata !{i32 {{.*}}, null, metadata !"D", metadata !4, i32 6, i64 16, i64 16, i32 0, i32 4, null, metadata !16, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] +// CHECK: metadata !{i32 {{.*}}, null, metadata !"D", metadata !4, i32 6, i64 16, i64 16, i32 0, i32 4, null, null, i32 0} ; [ DW_TAG_enumeration_type ] + +namespace PR14029 { + // Make sure this doesn't crash/assert. + template struct Test { + enum class Tag { + test = 0 + }; + Test() { + auto t = Tag::test; + } + Tag tag() const { return static_cast(1); } + }; + Test t; +} diff --git a/clang/test/CodeGenObjC/debug-info-fwddecl.m b/clang/test/CodeGenObjC/debug-info-fwddecl.m index ebdc5f2..8f2860c 100644 --- a/clang/test/CodeGenObjC/debug-info-fwddecl.m +++ b/clang/test/CodeGenObjC/debug-info-fwddecl.m @@ -2,4 +2,4 @@ @class ForwardObjcClass; ForwardObjcClass *ptr = 0; -// CHECK: metadata !{i32 {{.*}}, null, metadata !"ForwardObjcClass", metadata !{{.*}}, i32 2, i32 0, i32 0, i32 0, i32 4, null, null, i32 16} ; [ DW_TAG_structure_type ] +// CHECK: metadata !{i32 {{.*}}, null, metadata !"ForwardObjcClass", metadata !{{.*}}, i32 2, i64 0, i64 0, i32 0, i32 4, null, null, i32 16} ; [ DW_TAG_structure_type ] -- 2.7.4