@@ -615,6 +615,7 @@ int reflectEnumValue(SwiftReflectionContextRef RC,
615615
616616 printf ("Value: " );
617617 int parens = 0 ;
618+ // Walk into successively nested enum types...
618619 while (EnumTypeRef != 0 ) {
619620 swift_typeinfo_t EnumTypeInfo = swift_reflection_infoForTypeRef (RC , EnumTypeRef );
620621 switch (EnumTypeInfo .Kind ) {
@@ -633,42 +634,48 @@ int reflectEnumValue(SwiftReflectionContextRef RC,
633634 PipeMemoryReader_sendDoneMessage (& Pipe );
634635 return 0 ;
635636 }
636-
637637 swift_childinfo_t CaseInfo
638638 = swift_reflection_childOfTypeRef (RC , EnumTypeRef , CaseIndex );
639639 printf (".%s" , CaseInfo .Name );
640- EnumTypeRef = CaseInfo .TR ;
641- if (EnumTypeRef != 0 ) {
640+
641+ if (EnumTypeInfo .Kind == SWIFT_NO_PAYLOAD_ENUM || CaseInfo .TR == 0 ) {
642+ // No payload here, so end the walk
643+ EnumTypeRef = 0 ;
644+ } else {
645+ // There's a payload!
642646 printf ("(" );
643647 parens += 1 ;
644- }
645- break ;
646- }
647- case SWIFT_STRONG_REFERENCE : // Might be an indirect enum...
648- {
649- // Get the pointer value from the target
650- void * outFreeContext = NULL ;
651- const void * rawPtr
652- = PipeMemoryReader_readBytes ((void * )& Pipe , EnumInstance , 8 , & outFreeContext );
653- uintptr_t instance = * (uintptr_t * )rawPtr ;
654- PipeMemoryReader_freeBytes ((void * )& Pipe , rawPtr , outFreeContext );
655-
656- // Indirect enum is stored as the first field of a closure context...
657- swift_typeinfo_t TI = swift_reflection_infoForInstance (RC , instance );
658- if (TI .Kind == SWIFT_CLOSURE_CONTEXT ) {
659- swift_childinfo_t CaseInfo
660- = swift_reflection_childOfInstance (RC , instance , 0 );
661- if (CaseInfo .Kind == SWIFT_NO_PAYLOAD_ENUM
662- || CaseInfo .Kind == SWIFT_SINGLE_PAYLOAD_ENUM
663- || CaseInfo .Kind == SWIFT_MULTI_PAYLOAD_ENUM ) {
664- // Found the indirect enum storage, loop to print it out.
665- EnumTypeRef = CaseInfo .TR ;
666- EnumInstance = instance + CaseInfo .Offset ;
667- break ;
648+ EnumTypeRef = CaseInfo .TR ; // Walk into payload to see if it's an enum
649+
650+ if (CaseInfo .Kind == SWIFT_STRONG_REFERENCE ) { // Maybe an indirect enum?
651+ // Get the pointer value from the target
652+ void * outFreeContext = NULL ;
653+ // !!! FIXME !!! obtain the pointer by properly projecting the enum value
654+ // Next lines are a hack to prove the concept.
655+ const void * rawPtr
656+ = PipeMemoryReader_readBytes ((void * )& Pipe , EnumInstance , 8 , & outFreeContext );
657+ uintptr_t instance = * (uintptr_t * )rawPtr & 0xffffffffffffff8ULL ;
658+ PipeMemoryReader_freeBytes ((void * )& Pipe , rawPtr , outFreeContext );
659+
660+ // Indirect enum stores the payload as the first field of a closure context
661+ swift_typeinfo_t TI = swift_reflection_infoForInstance (RC , instance );
662+ if (TI .Kind == SWIFT_CLOSURE_CONTEXT ) {
663+ // Yep, it's an indirect enum. Let's follow the pointer...
664+ // TODO: Could we get here if we have an enum whose payload is a closure?
665+ swift_childinfo_t CaseInfo
666+ = swift_reflection_childOfInstance (RC , instance , 0 );
667+ if (CaseInfo .Kind == SWIFT_NO_PAYLOAD_ENUM
668+ || CaseInfo .Kind == SWIFT_SINGLE_PAYLOAD_ENUM
669+ || CaseInfo .Kind == SWIFT_MULTI_PAYLOAD_ENUM ) {
670+ // Found the indirect enum storage, loop to print it out.
671+ EnumTypeRef = CaseInfo .TR ;
672+ EnumInstance = instance + CaseInfo .Offset ;
673+ break ;
674+ }
675+ }
668676 }
669677 }
670- // Not an indirect enum, fall through...
671- __attribute__((fallthrough ));
678+ break ;
672679 }
673680 default :
674681 {
0 commit comments