mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Debug Info: Improve the accuracy of enum elements' sizes within the
limitations of LLVM.
This commit is contained in:
@@ -1227,37 +1227,43 @@ llvm::DICompositeType *IRGenDebugInfo::createStructType(
|
||||
|
||||
/// Return an array with the DITypes for each of an enum's elements.
|
||||
llvm::DINodeArray IRGenDebugInfo::getEnumElements(DebugTypeInfo DbgTy,
|
||||
EnumDecl *D,
|
||||
EnumDecl *ED,
|
||||
llvm::DIScope *Scope,
|
||||
llvm::DIFile *File,
|
||||
unsigned Flags) {
|
||||
SmallVector<llvm::Metadata *, 16> Elements;
|
||||
|
||||
for (auto *ElemDecl : D->getAllElements()) {
|
||||
for (auto *ElemDecl : ED->getAllElements()) {
|
||||
// FIXME <rdar://problem/14845818> Support enums.
|
||||
// Swift Enums can be both like DWARF enums and DWARF unions.
|
||||
// They should probably be emitted as DW_TAG_variant_type.
|
||||
// Swift Enums can be both like DWARF enums and discriminated unions.
|
||||
if (ElemDecl->hasType()) {
|
||||
// Use Decl as DeclContext.
|
||||
DebugTypeInfo ElemDbgTy;
|
||||
if (ElemDecl->hasArgumentType())
|
||||
ElemDbgTy = DebugTypeInfo(ElemDecl->getArgumentType(),
|
||||
DbgTy.StorageType,
|
||||
DbgTy.size, DbgTy.align, D);
|
||||
else
|
||||
if (D->hasRawType())
|
||||
ElemDbgTy = DebugTypeInfo(D->getRawType(), DbgTy.StorageType,
|
||||
DbgTy.size, DbgTy.align, D);
|
||||
else
|
||||
// Fallback to Int as the element type.
|
||||
ElemDbgTy = DebugTypeInfo(IGM.Context.getIntDecl()->getDeclaredType(),
|
||||
DbgTy.StorageType,
|
||||
DbgTy.size, DbgTy.align, D);
|
||||
if (ED->hasRawType())
|
||||
// An enum with a raw type (enum E : Int {}), similar to a
|
||||
// DWARF enum.
|
||||
//
|
||||
// The storage occupied by the enum may be smaller than the
|
||||
// one of the raw type as long as it is large enough to hold
|
||||
// all enum values. Use the raw type for the debug type, but
|
||||
// the storage size from the enum.
|
||||
ElemDbgTy = DebugTypeInfo(ED->getRawType(), DbgTy.StorageType,
|
||||
DbgTy.size, DbgTy.align, ED);
|
||||
else if (ElemDecl->hasArgumentType()) {
|
||||
// A discriminated union. This should really be described as a
|
||||
// DW_TAG_variant_type. For now only describing the data.
|
||||
auto &TI = IGM.getTypeInfoForUnlowered(ElemDecl->getArgumentType());
|
||||
ElemDbgTy = DebugTypeInfo(ElemDecl->getArgumentType(), TI, ED);
|
||||
} else {
|
||||
// Discriminated union case without argument. Fallback to Int
|
||||
// as the element type; there is no storage here.
|
||||
Type IntTy = IGM.Context.getIntDecl()->getDeclaredType();
|
||||
ElemDbgTy = DebugTypeInfo(IntTy, DbgTy.StorageType, 0, 1, ED);
|
||||
}
|
||||
unsigned Offset = 0;
|
||||
auto MTy = createMemberType(ElemDbgTy, ElemDecl->getName().str(), Offset,
|
||||
Scope, File, Flags);
|
||||
Elements.push_back(MTy);
|
||||
if (D->isIndirect() || ElemDecl->isIndirect())
|
||||
if (ED->isIndirect() || ElemDecl->isIndirect())
|
||||
IndirectEnumCases.insert(MTy);
|
||||
}
|
||||
}
|
||||
|
||||
18
test/DebugInfo/NestedTypes.swift
Normal file
18
test/DebugInfo/NestedTypes.swift
Normal file
@@ -0,0 +1,18 @@
|
||||
// RUN: %target-swift-frontend -primary-file %s -emit-ir -g -o - | FileCheck %s
|
||||
|
||||
// Verify that the size of a class that has not been created before
|
||||
// its outer type is emitted is emitted correctly.
|
||||
public struct S { var x : Int64; var y : Int64}
|
||||
public enum Enum {
|
||||
case WithClass(C)
|
||||
case WithStruct(S)
|
||||
}
|
||||
public class C { }
|
||||
|
||||
public let e : Enum = .WithClass(C())
|
||||
|
||||
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "WithClass",
|
||||
// CHECK-SAME: size: 64,
|
||||
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "WithStruct",
|
||||
// CHECK-SAME: size: 128,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
// CHECK-SAME: size: 8, align: 8,
|
||||
// CHECK-SAME: identifier: "_TtO4enum5Color"
|
||||
enum Color : UInt64 {
|
||||
// This is effectively a 2-bit bitfield:
|
||||
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "Red"
|
||||
// CHECK-SAME: baseType: !"_TtVs6UInt64"
|
||||
// CHECK-SAME: size: 8, align: 8{{[,)]}}
|
||||
@@ -18,12 +19,11 @@ enum Color : UInt64 {
|
||||
// CHECK-SAME: identifier: "_TtO4enum12MaybeIntPair"
|
||||
enum MaybeIntPair {
|
||||
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "none"
|
||||
// CHECK-SAME: baseType: !"_TtSi"
|
||||
// CHECK-SAME: size: 136, align: 64{{[,)]}}
|
||||
// CHECK-SAME: baseType: !"_TtSi", align: 8{{[,)]}}
|
||||
case none
|
||||
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "just"
|
||||
// CHECK-SAME: baseType: !"_TtTVs5Int64S__"
|
||||
// CHECK-SAME: size: 136, align: 64{{[,)]}}
|
||||
// CHECK-SAME: size: 128, align: 64{{[,)]}}
|
||||
case just(Int64, Int64)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user