Partition the reflection metadata to Runtime and Debug categories

During the review of the Opt-In Reflection Metadata proposal, @Adrian_Prantl raised a concern regarding the preservation of debugging capabilities while implementing the support of Opt-in reflection metadata.

I would like to discuss the possible solution and corner cases that might appear during the addressing of it.

The current state of affairs:

  • The reflection feature can be fully enabled or disabled. (No options in between)
  • When disabled using the -disable-reflection-metadata flag, LLDB will not be able to consume reflection metadata, resulting in a significant reduction in debugging capabilities.
  • When enabled, dsymutil copies the reflection information from TEXT to the DWARF segment of a dSYM which allows lldb to discover it later.
  • By using the -enable-reflection-for-debugger-only flag, reflection can be made available to LLDB, however, it will not be linked to the NTD, which will allow the linker to eliminate it through dead-stripping.

From the review:

The presence of debugging options is not supposed to affect code generation

A proper design for this feature would partition the reflection metadata into a metadata that goes into the binary and metadata that should go into the debug info. The dsymutil utility currently implements an all-or-nothing variant of this that allows all reflection metadata to be copied in the .dSYM bundle together with the debug info, thus allowing for the binary to be linked without the reflection metadata, while still preserving 100% debugability.

Design:

SWIFT COMPILER:

  • Extend FieldTypeMetadataBuilder(and possibly other builders too) and make it configurable from outside.

  • In emitFieldDescriptor instantiate two FieldTypeMetadataBuilder, one will emit full reflection directly in _DWARF, and another will emit reflection as usual to the _TEXT segment. The former one will be controlled by the -g family of flags, while the latter will be controlled by the reflection flags.

DSYMUTIL:

  • Change dsymutil and instead of copying reflection from TEXT, copy it to the DWRAF segment.

LLDB:

  • The change in LLDB might be required, to teach it to discover reflection in the DWARF segment in case of debugging without provided DSYMs.

Any other obvious issue I might have missed?
Thanks!