@@ -615,6 +615,7 @@ int reflectEnumValue(SwiftReflectionContextRef RC,
615
615
616
616
printf ("Value: " );
617
617
int parens = 0 ;
618
+ // Walk into successively nested enum types...
618
619
while (EnumTypeRef != 0 ) {
619
620
swift_typeinfo_t EnumTypeInfo = swift_reflection_infoForTypeRef (RC , EnumTypeRef );
620
621
switch (EnumTypeInfo .Kind ) {
@@ -633,42 +634,48 @@ int reflectEnumValue(SwiftReflectionContextRef RC,
633
634
PipeMemoryReader_sendDoneMessage (& Pipe );
634
635
return 0 ;
635
636
}
636
-
637
637
swift_childinfo_t CaseInfo
638
638
= swift_reflection_childOfTypeRef (RC , EnumTypeRef , CaseIndex );
639
639
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!
642
646
printf ("(" );
643
647
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
+ }
668
676
}
669
677
}
670
- // Not an indirect enum, fall through...
671
- __attribute__((fallthrough ));
678
+ break ;
672
679
}
673
680
default :
674
681
{
0 commit comments