summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
authorBrock Wyma <brock.wyma@intel.com>2018-03-13 14:14:16 +0000
committerBrock Wyma <brock.wyma@intel.com>2018-03-13 14:14:16 +0000
commit4fb918455800c40cd1b40f8b0a7df4b3790b0465 (patch)
tree9711ef605a2e3276cefd37d8c75c3f5be31f2fc6 /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
parente1a1da11262a906235648087008de43986ac2463 (diff)
downloadbcm5719-llvm-4fb918455800c40cd1b40f8b0a7df4b3790b0465.tar.gz
bcm5719-llvm-4fb918455800c40cd1b40f8b0a7df4b3790b0465.zip
[CodeView] Omit forward references for unnamed structs and unions
Codeview references to unnamed structs and unions are expected to refer to the complete type definition instead of a forward reference so Visual Studio can resolve the type properly. Differential Revision: https://reviews.llvm.org/D32498 llvm-svn: 327397
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp50
1 files changed, 40 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 0e8a83cbe18..e397e30b098 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1936,7 +1936,28 @@ ClassInfo CodeViewDebug::collectClassInfo(const DICompositeType *Ty) {
return Info;
}
+static bool shouldAlwaysEmitCompleteClassType(const DICompositeType *Ty) {
+ // This routine is used by lowerTypeClass and lowerTypeUnion to determine
+ // if a complete type should be emitted instead of a forward reference.
+ return Ty->getName().empty() && Ty->getIdentifier().empty() &&
+ !Ty->isForwardDecl();
+}
+
TypeIndex CodeViewDebug::lowerTypeClass(const DICompositeType *Ty) {
+ // Emit the complete type for unnamed structs. C++ classes with methods
+ // which have a circular reference back to the class type are expected to
+ // be named by the front-end and should not be "unnamed". C unnamed
+ // structs should not have circular references.
+ if (shouldAlwaysEmitCompleteClassType(Ty)) {
+ // If this unnamed complete type is already in the process of being defined
+ // then the description of the type is malformed and cannot be emitted
+ // into CodeView correctly so report a fatal error.
+ auto I = CompleteTypeIndices.find(Ty);
+ if (I != CompleteTypeIndices.end() && I->second == TypeIndex())
+ report_fatal_error("cannot debug circular reference to unnamed type");
+ return getCompleteTypeIndex(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.
TypeRecordKind Kind = getRecordKind(Ty);
@@ -1981,6 +2002,10 @@ TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) {
}
TypeIndex CodeViewDebug::lowerTypeUnion(const DICompositeType *Ty) {
+ // Emit the complete type for unnamed unions.
+ if (shouldAlwaysEmitCompleteClassType(Ty))
+ return getCompleteTypeIndex(Ty);
+
ClassOptions CO =
ClassOptions::ForwardReference | getCommonClassOptions(Ty);
std::string FullName = getFullyQualifiedName(Ty);
@@ -2211,9 +2236,7 @@ TypeIndex CodeViewDebug::getCompleteTypeIndex(DITypeRef TypeRef) {
return getTypeIndex(Ty);
}
- // Check if we've already translated the complete record type. Lowering a
- // complete type should never trigger lowering another complete type, so we
- // can reuse the hash table lookup result.
+ // Check if we've already translated the complete record type.
const auto *CTy = cast<DICompositeType>(Ty);
auto InsertResult = CompleteTypeIndices.insert({CTy, TypeIndex()});
if (!InsertResult.second)
@@ -2224,13 +2247,16 @@ TypeIndex CodeViewDebug::getCompleteTypeIndex(DITypeRef TypeRef) {
// Make sure the forward declaration is emitted first. It's unclear if this
// is necessary, but MSVC does it, and we should follow suit until we can show
// otherwise.
- TypeIndex FwdDeclTI = getTypeIndex(CTy);
+ // We only emit a forward declaration for named types.
+ if (!CTy->getName().empty() || !CTy->getIdentifier().empty()) {
+ TypeIndex FwdDeclTI = getTypeIndex(CTy);
- // Just use the forward decl if we don't have complete type info. This might
- // happen if the frontend is using modules and expects the complete definition
- // to be emitted elsewhere.
- if (CTy->isForwardDecl())
- return FwdDeclTI;
+ // Just use the forward decl if we don't have complete type info. This
+ // might happen if the frontend is using modules and expects the complete
+ // definition to be emitted elsewhere.
+ if (CTy->isForwardDecl())
+ return FwdDeclTI;
+ }
TypeIndex TI;
switch (CTy->getTag()) {
@@ -2245,7 +2271,11 @@ TypeIndex CodeViewDebug::getCompleteTypeIndex(DITypeRef TypeRef) {
llvm_unreachable("not a record");
}
- InsertResult.first->second = TI;
+ // Update the type index associated with this CompositeType. This cannot
+ // use the 'InsertResult' iterator above because it is potentially
+ // invalidated by map insertions which can occur while lowering the class
+ // type above.
+ CompleteTypeIndices[CTy] = TI;
return TI;
}
OpenPOWER on IntegriCloud