Skip to content

[DebugInfo] No longer assign non-fixed-size types the size of a pointer#87569

Merged
Teemperor merged 1 commit intoswiftlang:mainfrom
Teemperor:StorageType
Mar 20, 2026
Merged

[DebugInfo] No longer assign non-fixed-size types the size of a pointer#87569
Teemperor merged 1 commit intoswiftlang:mainfrom
Teemperor:StorageType

Conversation

@Teemperor
Copy link
Contributor

@Teemperor Teemperor commented Feb 27, 2026

CompletedDebugTypeInfo::getFromTypeInfo currently uses the storage type as
the preferred source of size information.
For address-only types (and any other type that has no fixed size at compile
time), the storage type is always changed to a pointer.

This currently causes that some non-fixed-size types (e.g., generics)
are assigned the size of a pointer as their actual size in the generated
debug information.

For example:

protocol P {
associatedtype S
}

func foo<B: P>(_ b: B) {
let x: (aaa: Int, bbb: B.S?) = (aaa: 0, bbb: nil)
_ = x
let y: (Fx: Int, Fy: Int) = (Fx: 0, Fy: 0)
_ = y
}

results in the following DWARF output where the first struct
is given size 8 (= the size of a pointer).

0x000000d4:   DW_TAG_structure_type
                DW_AT_name	("$sSi3aaa_1S4main1PPQzSg3bbbtD")
                DW_AT_linkage_name	("$sSi3aaa_1S4main1PPQzSg3bbbtD")
                DW_AT_byte_size	(0x08)
                DW_AT_APPLE_runtime_class	(DW_LANG_Swift)

0x000000f3:   DW_TAG_structure_type
                DW_AT_name	("$sSi2Fx_Si2FytD")
                DW_AT_linkage_name	("$sSi2Fx_Si2FytD")
                DW_AT_byte_size	(0x10)
                DW_AT_APPLE_runtime_class	(DW_LANG_Swift)

This change modifies CompletedDebugTypeInfo::getFromTypeInfo to ignore the
storage size for types that do not have fixed size. Generics now have no
specified size or 0 in DWARF. FixedArray<A, B> without substituted type/size
is now also emitted using the dedicated FixedArray code.

@Teemperor
Copy link
Contributor Author

@swift-ci please test


extension Slab: Copyable where Element: Copyable {}

// CHECK-DAG: !DICompositeType({{.*}}name: "$sxq_BVD"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this change is an improvement or not, but the fact that we emit the new name is actually because we his the code path for the specific type here:

    case TypeKind::BuiltinFixedArray: {
      if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
        // DISABLED IN THE TEST
      }
      unsigned FwdDeclLine = 0;
      return createOpaqueStruct(Scope, "Builtin.FixedArray", MainFile, // << HERE
                                FwdDeclLine, SizeInBits, AlignInBits, Flags,
                                MangledName);
    }

// If we do not know the size of this type, pass a size of 0.
// FIXME: createEnumType should not require a sized debug info type.
if (!CompletedDbgTy)
CompletedDbgTy = CompletedDebugTypeInfo::get(DbgTy, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess your FIXME makes that clear already, but this defeats the purpose of CompletedDebugTypeInfo. Why can't we call createOpaqueStructWithSizedContainer() here any more?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tbh, I just want to keep this change as uninvasive as possible just so we can unblock main. Maybe we could call this, but then even more stuff breaks.

const bool RequiresSize =
!isa<PrimaryArchetypeType>(DbgTy.getType()) &&
!DbgTy.getType()->hasArchetype() &&
!isa<TypeAliasType>(DbgTy.getType());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

extension Slab: Copyable where Element: Copyable {}

// CHECK-DAG: !DICompositeType({{.*}}name: "$sxq_BVD"
// CHECK-DAG: !DICompositeType({{.*}}name: "Builtin.FixedArray"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that is fine, but can you CHECK for the mangled name instead (or in addition)? The mangled names are more important for LLDB's functionality than the human-readable ones.

Teemperor added a commit to Teemperor/llvm-project that referenced this pull request Mar 12, 2026
…entation

Swift commit fcbebc5 added support for emitting Builtin.FixedArray
as a DW_TAG_array_type. With swiftlang/swift#87569
this code path is now also taken for `Builtin.FixedArray<A, B>` which is
the non-substituted `FixedArray` class. Before PR llvm#87569 the DWARF emitted for
`FixedArray<A, B>` looked like this:

    DW_TAG_structure_type
        DW_AT_name ("$exq_BVD")
        DW_AT_linkage_name ("$exq_BVD")
        DW_AT_declaration (true)
        DW_AT_APPLE_runtime_class (DW_LANG_Swift)

and the new DWARF that is emitted now takes the FixedArray code path which
produces this DWARF:

    DW_TAG_array_type
        DW_AT_type	(0x00006c70 "$eq_D")

    DW_TAG_structure_type
        DW_AT_name	("$eq_D")
        DW_AT_byte_size	(0x00)
        DW_AT_APPLE_runtime_class	(DW_LANG_Swift)

The patch adds support for parsing this specific pattern. We curiously don't
need to ever parse the substituted array types for embedded Swift, so this
patch just adds enough support for the unsubstituted type.
// then only emit a forward declaration.
// TODO: This check can probably be simplified and generalized.
const bool RequiresSize = !isa<PrimaryArchetypeType>(DbgTy.getType()) &&
!DbgTy.getType()->hasArchetype() &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the archetype is constrained to AnyObject (a class) the size is known.

struct W<T: AnyObject> {
  let t: T
}

I'm not sure if there are other cases, I think not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess constraining T to a class directly, a protocol that is itself constrained to any object. and maybe @objc protocols too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this check (i.e., does this type have a fixed size) should already exist somewhere in the compiler and we should reuse it, but I don't know what is the right function here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TypeInfo::IsFixedSize should do it, unless you don't have access to a TypeInfo here?

Copy link
Contributor

@augusto2112 augusto2112 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice change.

Like I mentioned on swiftlang/llvm-project#12571 though I think that you should figure out why FixedArrays are being emitted as $eq_D first.

Copy link
Contributor

@augusto2112 augusto2112 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I think this change is correct. I commented on swiftlang/llvm-project#12571 what I think needs to be done to fix the FixedArray change.

Teemperor added a commit to Teemperor/llvm-project that referenced this pull request Mar 13, 2026
…entation

Swift commit fcbebc5 added support for emitting Builtin.FixedArray
as a DW_TAG_array_type. With swiftlang/swift#87569
this code path is now also taken for `Builtin.FixedArray<A, B>` which is
the non-substituted `FixedArray` class. Before PR llvm#87569 the DWARF emitted for
`FixedArray<A, B>` looked like this:

    DW_TAG_structure_type
        DW_AT_name ("$exq_BVD")
        DW_AT_linkage_name ("$exq_BVD")
        DW_AT_declaration (true)
        DW_AT_APPLE_runtime_class (DW_LANG_Swift)

and the new DWARF that is emitted now takes the FixedArray code path which
produces this DWARF:

    DW_TAG_array_type
        DW_AT_type	(0x00006c70 "$eq_D")

    DW_TAG_structure_type
        DW_AT_name	("$eq_D")
        DW_AT_byte_size	(0x00)
        DW_AT_APPLE_runtime_class	(DW_LANG_Swift)

The patch adds support for parsing this specific pattern. We curiously don't
need to ever parse the substituted array types for embedded Swift, so this
patch just adds enough support for the unsubstituted type.
@Teemperor Teemperor changed the title [WIP][DebugInfo] No longer assign non-fixed-size types the size of a … [DebugInfo] No longer assign non-fixed-size types the size of a … Mar 13, 2026
@Teemperor Teemperor changed the title [DebugInfo] No longer assign non-fixed-size types the size of a … [DebugInfo] No longer assign non-fixed-size types the size of a pointer Mar 13, 2026
`CompletedDebugTypeInfo::getFromTypeInfo` currently uses the storage type as
the preferred source of size information.
For address-only types (and any other type that has no fixed size at compile
time), the storage type is always changed to a pointer.

This currently causes that some non-fixed-size types (e.g., generics)
are assigned the size of a pointer as their actual size in the generated
debug information.

For example:

```
protocol P {
associatedtype S
}

func foo<B: P>(_ b: B) {
let x: (aaa: Int, bbb: B.S?) = (aaa: 0, bbb: nil)
_ = x
let y: (Fx: Int, Fy: Int) = (Fx: 0, Fy: 0)
_ = y
}
```

results in the following DWARF output where the first struct
is given size 8 (= the size of a pointer).

```
0x000000d4:   DW_TAG_structure_type
                DW_AT_name	("$sSi3aaa_1S4main1PPQzSg3bbbtD")
                DW_AT_linkage_name	("$sSi3aaa_1S4main1PPQzSg3bbbtD")
                DW_AT_byte_size	(0x08)
                DW_AT_APPLE_runtime_class	(DW_LANG_Swift)

0x000000f3:   DW_TAG_structure_type
                DW_AT_name	("$sSi2Fx_Si2FytD")
                DW_AT_linkage_name	("$sSi2Fx_Si2FytD")
                DW_AT_byte_size	(0x10)
                DW_AT_APPLE_runtime_class	(DW_LANG_Swift)
```

This change modifies `CompletedDebugTypeInfo::getFromTypeInfo` to ignore the
storage size for types that do not have fixed size. Generics now have no
specified size or 0 in DWARF. FixedArray<A, B> without substituted type/size
is now also emitted using the dedicated FixedArray code.
@Teemperor
Copy link
Contributor Author

@swift-ci please test and merge

@Teemperor
Copy link
Contributor Author

@swift-ci please test

@Teemperor Teemperor enabled auto-merge March 18, 2026 15:08
Teemperor added a commit to swiftlang/llvm-project that referenced this pull request Mar 18, 2026
…entation

Swift commit fcbebc5 added support for emitting Builtin.FixedArray
as a DW_TAG_array_type. With swiftlang/swift#87569
this code path is now also taken for `Builtin.FixedArray<A, B>` which is
the non-substituted `FixedArray` class. Before PR llvm#87569 the DWARF emitted for
`FixedArray<A, B>` looked like this:

    DW_TAG_structure_type
        DW_AT_name ("$exq_BVD")
        DW_AT_linkage_name ("$exq_BVD")
        DW_AT_declaration (true)
        DW_AT_APPLE_runtime_class (DW_LANG_Swift)

and the new DWARF that is emitted now takes the FixedArray code path which
produces this DWARF:

    DW_TAG_array_type
        DW_AT_type	(0x00006c70 "$eq_D")

    DW_TAG_structure_type
        DW_AT_name	("$eq_D")
        DW_AT_byte_size	(0x00)
        DW_AT_APPLE_runtime_class	(DW_LANG_Swift)

The patch adds support for parsing this specific pattern. We curiously don't
need to ever parse the substituted array types for embedded Swift, so this
patch just adds enough support for the unsubstituted type.

(cherry picked from commit 1e1af53)
@Teemperor
Copy link
Contributor Author

@swift-ci please test

@Teemperor Teemperor disabled auto-merge March 19, 2026 08:49
@Teemperor Teemperor enabled auto-merge March 19, 2026 08:49
@Teemperor Teemperor disabled auto-merge March 20, 2026 11:38
@Teemperor
Copy link
Contributor Author

@swift-ci smoke test macOS

@Teemperor Teemperor enabled auto-merge March 20, 2026 15:10
@Teemperor Teemperor merged commit 345bda9 into swiftlang:main Mar 20, 2026
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants