From e092dad72cca55fb1c96ddbcc9cbddcc4657b7bb Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Sat, 2 Jul 2016 00:11:07 +0000 Subject: [PATCH] [codeview] Set the Nested and Scoped ClassOptions based on the scope chain These are set on both the declaration record and the definition record. llvm-svn: 274410 --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 43 +++++++++++++------ llvm/test/DebugInfo/COFF/bitfields.ll | 6 ++- llvm/test/DebugInfo/COFF/scopes.ll | 6 ++- .../test/DebugInfo/COFF/types-data-members.ll | 6 ++- 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 91a771e7cfe6..bd4df879d5f3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -1332,18 +1332,38 @@ static TypeRecordKind getRecordKind(const DICompositeType *Ty) { llvm_unreachable("unexpected tag"); } -/// Return the HasUniqueName option if it should be present in ClassOptions, or -/// None otherwise. -static ClassOptions getRecordUniqueNameOption(const DICompositeType *Ty) { - // MSVC always sets this flag now, even for local types. Clang doesn't always +/// Return ClassOptions that should be present on both the forward declaration +/// and the defintion of a tag type. +static ClassOptions getCommonClassOptions(const DICompositeType *Ty) { + ClassOptions CO = ClassOptions::None; + + // MSVC always sets this flag, even for local types. Clang doesn't always // appear to give every type a linkage name, which may be problematic for us. // FIXME: Investigate the consequences of not following them here. - return !Ty->getIdentifier().empty() ? ClassOptions::HasUniqueName - : ClassOptions::None; + if (!Ty->getIdentifier().empty()) + CO |= ClassOptions::HasUniqueName; + + // Put the Nested flag on a type if it appears immediately inside a tag type. + // Do not walk the scope chain. Do not attempt to compute ContainsNestedClass + // here. That flag is only set on definitions, and not forward declarations. + const DIScope *ImmediateScope = Ty->getScope().resolve(); + if (ImmediateScope && isa(ImmediateScope)) + CO |= ClassOptions::Nested; + + // Put the Scoped flag on function-local types. + for (const DIScope *Scope = ImmediateScope; Scope != nullptr; + Scope = Scope->getScope().resolve()) { + if (isa(Scope)) { + CO |= ClassOptions::Scoped; + break; + } + } + + return CO; } TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) { - ClassOptions CO = ClassOptions::None | getRecordUniqueNameOption(Ty); + ClassOptions CO = getCommonClassOptions(Ty); TypeIndex FTI; unsigned EnumeratorCount = 0; @@ -1459,7 +1479,7 @@ TypeIndex CodeViewDebug::lowerTypeClass(const DICompositeType *Ty) { // forward decl options, since it might not be available in all TUs. TypeRecordKind Kind = getRecordKind(Ty); ClassOptions CO = - ClassOptions::ForwardReference | getRecordUniqueNameOption(Ty); + ClassOptions::ForwardReference | getCommonClassOptions(Ty); std::string FullName = getFullyQualifiedName(Ty); TypeIndex FwdDeclTI = TypeTable.writeClass(ClassRecord( Kind, 0, CO, HfaKind::None, WindowsRTClassKind::None, TypeIndex(), @@ -1472,8 +1492,7 @@ TypeIndex CodeViewDebug::lowerTypeClass(const DICompositeType *Ty) { TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) { // Construct the field list and complete type record. TypeRecordKind Kind = getRecordKind(Ty); - // FIXME: Other ClassOptions, like ContainsNestedClass and NestedClass. - ClassOptions CO = ClassOptions::None | getRecordUniqueNameOption(Ty); + ClassOptions CO = getCommonClassOptions(Ty); TypeIndex FieldTI; TypeIndex VShapeTI; unsigned FieldCount; @@ -1499,7 +1518,7 @@ TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) { TypeIndex CodeViewDebug::lowerTypeUnion(const DICompositeType *Ty) { ClassOptions CO = - ClassOptions::ForwardReference | getRecordUniqueNameOption(Ty); + ClassOptions::ForwardReference | getCommonClassOptions(Ty); std::string FullName = getFullyQualifiedName(Ty); TypeIndex FwdDeclTI = TypeTable.writeUnion(UnionRecord(0, CO, HfaKind::None, TypeIndex(), 0, @@ -1510,7 +1529,7 @@ TypeIndex CodeViewDebug::lowerTypeUnion(const DICompositeType *Ty) { } TypeIndex CodeViewDebug::lowerCompleteTypeUnion(const DICompositeType *Ty) { - ClassOptions CO = ClassOptions::None | getRecordUniqueNameOption(Ty); + ClassOptions CO = getCommonClassOptions(Ty); TypeIndex FieldTI; unsigned FieldCount; std::tie(FieldTI, std::ignore, FieldCount) = lowerRecordFieldList(Ty); diff --git a/llvm/test/DebugInfo/COFF/bitfields.ll b/llvm/test/DebugInfo/COFF/bitfields.ll index 46f006674acd..817bb88837d1 100644 --- a/llvm/test/DebugInfo/COFF/bitfields.ll +++ b/llvm/test/DebugInfo/COFF/bitfields.ll @@ -66,8 +66,9 @@ ; CHECK: Struct ([[anon_ty:.*]]) { ; CHECK: TypeLeafKind: LF_STRUCTURE (0x1505) ; CHECK: MemberCount: 0 -; CHECK: Properties [ (0x80) +; CHECK: Properties [ (0x88) ; CHECK: ForwardReference (0x80) +; CHECK: Nested (0x8) ; CHECK: ] ; CHECK: FieldList: 0x0 ; CHECK: SizeOf: 0 @@ -141,7 +142,8 @@ ; CHECK: Struct ({{.*}}) { ; CHECK: TypeLeafKind: LF_STRUCTURE (0x1505) ; CHECK: MemberCount: 2 -; CHECK: Properties [ (0x0) +; CHECK: Properties [ (0x8) +; CHECK: Nested (0x8) ; CHECK: ] ; CHECK: FieldList: ([[anon_fl]]) ; CHECK: SizeOf: 3 diff --git a/llvm/test/DebugInfo/COFF/scopes.ll b/llvm/test/DebugInfo/COFF/scopes.ll index e07e92ddb7d8..d7b4962945da 100644 --- a/llvm/test/DebugInfo/COFF/scopes.ll +++ b/llvm/test/DebugInfo/COFF/scopes.ll @@ -29,8 +29,9 @@ ; CHECK: Struct ({{.*}}) { ; CHECK: TypeLeafKind: LF_STRUCTURE (0x1505) ; CHECK: MemberCount: 0 -; CHECK: Properties [ (0x80) +; CHECK: Properties [ (0x180) ; CHECK: ForwardReference (0x80) +; CHECK: Scoped (0x100) ; CHECK: ] ; CHECK: FieldList: 0x0 ; CHECK: DerivedFrom: 0x0 @@ -42,7 +43,8 @@ ; CHECK: Struct ({{.*}}) { ; CHECK: TypeLeafKind: LF_STRUCTURE (0x1505) ; CHECK: MemberCount: 1 -; CHECK: Properties [ (0x0) +; CHECK: Properties [ (0x100) +; CHECK: Scoped (0x100) ; CHECK: ] ; CHECK: Name: foo::bar::baz::LocalRecord ; CHECK: } diff --git a/llvm/test/DebugInfo/COFF/types-data-members.ll b/llvm/test/DebugInfo/COFF/types-data-members.ll index 79c40b7363ed..70a509714b69 100644 --- a/llvm/test/DebugInfo/COFF/types-data-members.ll +++ b/llvm/test/DebugInfo/COFF/types-data-members.ll @@ -337,9 +337,10 @@ ; CHECK: Struct (0x1019) { ; CHECK: TypeLeafKind: LF_STRUCTURE (0x1505) ; CHECK: MemberCount: 0 -; CHECK: Properties [ (0x280) +; CHECK: Properties [ (0x288) ; CHECK: ForwardReference (0x80) ; CHECK: HasUniqueName (0x200) +; CHECK: Nested (0x8) ; CHECK: ] ; CHECK: FieldList: 0x0 ; CHECK: DerivedFrom: 0x0 @@ -360,8 +361,9 @@ ; CHECK: Struct (0x101B) { ; CHECK: TypeLeafKind: LF_STRUCTURE (0x1505) ; CHECK: MemberCount: 1 -; CHECK: Properties [ (0x200) +; CHECK: Properties [ (0x208) ; CHECK: HasUniqueName (0x200) +; CHECK: Nested (0x8) ; CHECK: ] ; CHECK: FieldList: (0x101A) ; CHECK: DerivedFrom: 0x0