diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index 46b9edc830452..fb1757974fc1e 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "IRGenDebugInfo.h" +#include "GenEnum.h" #include "GenOpaque.h" #include "GenStruct.h" #include "GenType.h" @@ -1078,8 +1079,6 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { llvm::dwarf::DW_TAG_structure_type, UniqueID, Scope, File, Line, llvm::dwarf::DW_LANG_Swift, SizeInBits, 0); } - if (OffsetInBits > SizeInBits) - SizeInBits = OffsetInBits; auto DITy = DBuilder.createStructType( Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, DerivedFrom, @@ -1525,7 +1524,8 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { ? 0 : DbgTy.getAlignment().getValue() * SizeOfByte; unsigned Encoding = 0; - uint32_t NumExtraInhabitants = 0; + uint32_t NumExtraInhabitants = DbgTy.getNumExtraInhabitants().value_or(0); + llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; TypeBase *BaseTy = DbgTy.getType(); @@ -1549,8 +1549,6 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { Encoding = llvm::dwarf::DW_ATE_unsigned; if (auto CompletedDbgTy = CompletedDebugTypeInfo::get(DbgTy)) SizeInBits = getSizeOfBasicType(*CompletedDbgTy); - if (auto DbgTyNumExtraInhabitants = DbgTy.getNumExtraInhabitants()) - NumExtraInhabitants = *DbgTyNumExtraInhabitants; break; } @@ -1558,8 +1556,6 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { Encoding = llvm::dwarf::DW_ATE_unsigned; // ? if (auto CompletedDbgTy = CompletedDebugTypeInfo::get(DbgTy)) SizeInBits = getSizeOfBasicType(*CompletedDbgTy); - if (auto DbgTyNumExtraInhabitants = DbgTy.getNumExtraInhabitants()) - NumExtraInhabitants = *DbgTyNumExtraInhabitants; break; } @@ -1568,48 +1564,30 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { // Assuming that the bitwidth and FloatTy->getFPKind() are identical. SizeInBits = FloatTy->getBitWidth(); Encoding = llvm::dwarf::DW_ATE_float; - if (auto DbgTyNumExtraInhabitants = DbgTy.getNumExtraInhabitants()) - NumExtraInhabitants = *DbgTyNumExtraInhabitants; break; } - case TypeKind::BuiltinNativeObject: { - unsigned PtrSize = CI.getTargetInfo().getPointerWidth(clang::LangAS::Default); - auto PTy = DBuilder.createPointerType(nullptr, PtrSize, 0, - /* DWARFAddressSpace */ llvm::None, - MangledName); - return DBuilder.createObjectPointerType(PTy); - } - - case TypeKind::BuiltinBridgeObject: { - unsigned PtrSize = CI.getTargetInfo().getPointerWidth(clang::LangAS::Default); - auto PTy = DBuilder.createPointerType(nullptr, PtrSize, 0, - /* DWARFAddressSpace */ llvm::None, - MangledName); - return DBuilder.createObjectPointerType(PTy); - } - - case TypeKind::BuiltinRawPointer: { - unsigned PtrSize = CI.getTargetInfo().getPointerWidth(clang::LangAS::Default); - return DBuilder.createPointerType(nullptr, PtrSize, 0, - /* DWARFAddressSpace */ llvm::None, - MangledName); - } + case TypeKind::BuiltinNativeObject: + case TypeKind::BuiltinBridgeObject: + case TypeKind::BuiltinRawPointer: + case TypeKind::BuiltinRawUnsafeContinuation: + case TypeKind::BuiltinJob: { + unsigned PtrSize = + CI.getTargetInfo().getPointerWidth(clang::LangAS::Default); + if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) { + Flags |= llvm::DINode::FlagArtificial; + llvm::DICompositeType *PTy = DBuilder.createStructType( + Scope, MangledName, File, 0, PtrSize, 0, Flags, nullptr, nullptr, + llvm::dwarf::DW_LANG_Swift, nullptr, {}, NumExtraInhabitants); + return PTy; - case TypeKind::BuiltinRawUnsafeContinuation: { - unsigned PtrSize = CI.getTargetInfo().getPointerWidth(clang::LangAS::Default); - return DBuilder.createPointerType(nullptr, PtrSize, 0, - /* DWARFAddressSpace */ llvm::None, - MangledName); - } + } + llvm::DIDerivedType *PTy = DBuilder.createPointerType( + nullptr, PtrSize, 0, + /* DWARFAddressSpace */ llvm::None, MangledName); - case TypeKind::BuiltinJob: { - unsigned PtrSize = CI.getTargetInfo().getPointerWidth(clang::LangAS::Default); - return DBuilder.createPointerType(nullptr, PtrSize, 0, - /* DWARFAddressSpace */ llvm::None, - MangledName); + return DBuilder.createObjectPointerType(PTy); } - case TypeKind::BuiltinExecutor: { return createDoublePointerSizedStruct( Scope, "Builtin.Executor", nullptr, MainFile, 0, @@ -1663,6 +1641,25 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { unsigned FwdDeclLine = 0; assert(SizeInBits == CI.getTargetInfo().getPointerWidth(clang::LangAS::Default)); + if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) { + auto *DIType = createStructType( + DbgTy, Decl, ClassTy, Scope, File, L.Line, SizeInBits, AlignInBits, + Flags, nullptr, llvm::dwarf::DW_LANG_Swift, MangledName); + assert(DIType && "Unexpected null DIType!"); + assert(DIType && "createStructType should never return null!"); + auto SuperClassTy = ClassTy->getSuperclass(); + if (SuperClassTy) { + auto SuperClassDbgTy = DebugTypeInfo::getFromTypeInfo( + SuperClassTy, IGM.getTypeInfoForUnlowered(SuperClassTy), IGM, + false); + + llvm::DIType *SuperClassDITy = getOrCreateType(SuperClassDbgTy); + assert(SuperClassDITy && "getOrCreateType should never return null!"); + DBuilder.retainType(DBuilder.createInheritance( + DIType, SuperClassDITy, 0, 0, llvm::DINode::FlagZero)); + } + return DIType; + } return createPointerSizedStruct(Scope, Decl->getNameStr(), L.File, FwdDeclLine, Flags, MangledName); } @@ -2033,6 +2030,20 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { } #endif + /// Emits the special builtin types into the debug info. These types are the + /// ones that are unconditionally emitted into the stdlib's metadata and are + /// needed to correctly calculate the layout of more complex types built on + /// top of them. + void createSpecialStlibBuiltinTypes() { + if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::ASTTypes) + return; + for (auto BuiltinType: IGM.getOrCreateSpecialStlibBuiltinTypes()) { + auto DbgTy = DebugTypeInfo::getFromTypeInfo( + BuiltinType, IGM.getTypeInfoForUnlowered(BuiltinType), IGM, false); + DBuilder.retainType(getOrCreateType(DbgTy)); + } + } + llvm::DIType *getOrCreateType(DebugTypeInfo DbgTy) { // Is this an empty type? if (DbgTy.isNull()) @@ -2079,6 +2090,8 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { TypeDecl = ND; Context = ND->getParent(); ClangDecl = ND->getClangDecl(); + } else if (auto BNO = dyn_cast(DbgTy.getType())) { + Context = BNO->getASTContext().TheBuiltinModule; } if (ClangDecl) { clang::ASTReader &Reader = *CI.getClangInstance().getASTReader(); @@ -2255,6 +2268,7 @@ IRGenDebugInfoImpl::IRGenDebugInfoImpl(const IRGenOptions &Opts, } OS << '"'; } + createSpecialStlibBuiltinTypes(); } void IRGenDebugInfoImpl::finalize() { diff --git a/test/DebugInfo/BuiltinStdlibTypes.swift b/test/DebugInfo/BuiltinStdlibTypes.swift new file mode 100644 index 0000000000000..dc3c7eed81948 --- /dev/null +++ b/test/DebugInfo/BuiltinStdlibTypes.swift @@ -0,0 +1,28 @@ +// RUN: %target-swift-frontend %s -Onone -emit-ir -gdwarf-types -o - | %FileCheck %s + +// File is empty as this test check for the builtin stdlib types that should +// always be emitted. + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "$sBoD", +// CHECK-SAME: size: 64, num_extra_inhabitants: {{2147483647|4096}}, flags: DIFlagArtificial, +// CHECK-SAME: runtimeLang: DW_LANG_Swift) + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "$syXlD", +// CHECK-SAME: size: 64, + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "$sBbD", +// CHECK-SAME: size: 64, num_extra_inhabitants: {{2147483647|4096}}, flags: DIFlagArtificial, +// CHECK-SAME: runtimeLang: DW_LANG_Swift) + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "$sBpD", +// CHECK-SAME: size: 64, num_extra_inhabitants: 1, flags: DIFlagArtificial, +// CHECK-SAME: runtimeLang: DW_LANG_Swift) + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "$syyXfD", +// CHECK-SAME: size: 64, +// CHECK-SAME: runtimeLang: DW_LANG_Swift + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "$sypXpD", size: 64, +// CHECK-SAME: flags: DIFlagArtificial, runtimeLang: DW_LANG_Swift, identifier: "$sypXpD") + + diff --git a/test/DebugInfo/EagerTypeMetadata.swift b/test/DebugInfo/EagerTypeMetadata.swift index e216d788fc7de..1f53cb5cae90e 100644 --- a/test/DebugInfo/EagerTypeMetadata.swift +++ b/test/DebugInfo/EagerTypeMetadata.swift @@ -13,6 +13,6 @@ public class C } // CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "T", // CHECK-SAME: baseType: ![[PTRTY:[0-9]+]] -// CHECK: ![[PTRTY]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "$sBpD", baseType: null, size: {{64|32}}) +// CHECK: ![[PTRTY]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "$sBpD", baseType: null, size: {{64|32}}, flags: DIFlagArtificial | DIFlagObjectPointer) // CHECK: ![[LOC]] = !DILocation(line: 0, diff --git a/test/DebugInfo/classes.swift b/test/DebugInfo/classes.swift new file mode 100644 index 0000000000000..4f38d59f5eb08 --- /dev/null +++ b/test/DebugInfo/classes.swift @@ -0,0 +1,15 @@ +// RUN: %target-swift-frontend -primary-file %s -emit-ir -gdwarf-types -o - | %FileCheck %s + +class SomeClass { + let first = 4 + let second = "Hello" +} + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "SomeClass", +// CHECK-SAME: size: 64, elements: +// CHECK-SAME: runtimeLang: DW_LANG_Swift, identifier: "$s7classes9SomeClassCD") + +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "first", +// CHECK-SAME: size: 64) +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "second", +// CHECK-SAME: size: 128, offset: 64)