summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp43
1 files changed, 31 insertions, 12 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 91a771e7cfe..bd4df879d5f 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<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);
OpenPOWER on IntegriCloud