Index: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -224,6 +224,7 @@ codeview::TypeIndex lowerTypeMemberPointer(const DIDerivedType *Ty); codeview::TypeIndex lowerTypeModifier(const DIDerivedType *Ty); codeview::TypeIndex lowerTypeFunction(const DISubroutineType *Ty); + codeview::TypeIndex lowerTypeEnum(const DICompositeType *Ty); codeview::TypeIndex lowerTypeClass(const DICompositeType *Ty); codeview::TypeIndex lowerTypeUnion(const DICompositeType *Ty); Index: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -756,6 +756,8 @@ return lowerTypeModifier(cast(Ty)); case dwarf::DW_TAG_subroutine_type: return lowerTypeFunction(cast(Ty)); + case dwarf::DW_TAG_enumeration_type: + return lowerTypeEnum(cast(Ty)); case dwarf::DW_TAG_class_type: case dwarf::DW_TAG_structure_type: return lowerTypeClass(cast(Ty)); @@ -1081,6 +1083,21 @@ : ClassOptions::None; } +TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) { + ClassOptions CO = ClassOptions::None | getRecordUniqueNameOption(Ty); + TypeIndex FTI; + unsigned FieldCount = 0; + + if (Ty->isForwardDecl()) + CO |= ClassOptions::ForwardReference; + else + std::tie(FTI, FieldCount) = lowerRecordFieldList(Ty); + + return TypeTable.writeEnum(EnumRecord(FieldCount, CO, FTI, Ty->getName(), + Ty->getIdentifier(), + getTypeIndex(Ty->getBaseType()))); +} + TypeIndex CodeViewDebug::lowerTypeClass(const DICompositeType *Ty) { // First, construct the forward decl. Don't look into Ty to compute the // forward decl options, since it might not be available in all TUs. @@ -1172,6 +1189,10 @@ } // FIXME: Get clang to emit nested types here and do something with // them. + } else if (auto *Enumerator = dyn_cast(Element)) { + Fields.writeEnumerator(EnumeratorRecord( + MemberAccess::Public, APSInt::getUnsigned(Enumerator->getValue()), + Enumerator->getName())); } // Skip other unrecognized kinds of elements. } Index: llvm/trunk/test/DebugInfo/COFF/enum.ll =================================================================== --- llvm/trunk/test/DebugInfo/COFF/enum.ll +++ llvm/trunk/test/DebugInfo/COFF/enum.ll @@ -0,0 +1,47 @@ +; RUN: llc < %s -filetype=obj | llvm-readobj - -codeview | FileCheck %s + +; Generated from the following C++ source: +; enum E : int { BLAH }; +; E e; + +; CHECK: CodeViewTypes [ +; CHECK: UnknownLeaf (0x1000) { +; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203) +; CHECK-NEXT: Enumerator { +; CHECK-NEXT: AccessSpecifier: Public (0x3) +; CHECK-NEXT: EnumValue: 0 +; CHECK-NEXT: Name: BLAH +; CHECK-NEXT: } +; CHECK-NEXT: } +; CHECK-NEXT: Enum (0x1001) { +; CHECK-NEXT: TypeLeafKind: LF_ENUM (0x1507) +; CHECK-NEXT: NumEnumerators: 0 +; CHECK-NEXT: Properties [ (0x0) +; CHECK-NEXT: ] +; CHECK-NEXT: UnderlyingType: int (0x74) +; CHECK-NEXT: FieldListType: BLAH (0x1000) +; CHECK-NEXT: Name: E +; CHECK-NEXT: } + +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" +target triple = "i686-pc-windows-msvc18.0.0" + +@"\01?e@@3W4E@@A" = global i32 0, align 4 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.9.0 (trunk 272790) (llvm/trunk 272813)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !8) +!1 = !DIFile(filename: "-", directory: "/") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E", file: !4, line: 1, baseType: !5, size: 32, align: 32, elements: !6) +!4 = !DIFile(filename: "", directory: "/") +!5 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!6 = !{!7} +!7 = !DIEnumerator(name: "BLAH", value: 0) +!8 = !{!9} +!9 = distinct !DIGlobalVariable(name: "e", linkageName: "\01?e@@3W4E@@A", scope: !0, file: !4, line: 2, type: !3, isLocal: false, isDefinition: true, variable: i32* @"\01?e@@3W4E@@A") +!10 = !{i32 2, !"CodeView", i32 1} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{!"clang version 3.9.0 (trunk 272790) (llvm/trunk 272813)"}