[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
This commit is contained in:
Reid Kleckner 2016-07-02 00:11:07 +00:00
parent 54a213d280
commit e092dad72c
4 changed files with 43 additions and 18 deletions

View File

@ -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<DICompositeType>(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<DISubprogram>(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);

View File

@ -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: <field list> ([[anon_fl]])
; CHECK: SizeOf: 3

View File

@ -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: }

View File

@ -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: <field list> (0x101A)
; CHECK: DerivedFrom: 0x0