@@ -615,38 +615,78 @@ 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 );
620- if (EnumTypeInfo .Kind != SWIFT_NO_PAYLOAD_ENUM
621- && EnumTypeInfo .Kind != SWIFT_SINGLE_PAYLOAD_ENUM
622- && EnumTypeInfo .Kind != SWIFT_MULTI_PAYLOAD_ENUM ) {
621+ switch (EnumTypeInfo .Kind ) {
622+ case SWIFT_NO_PAYLOAD_ENUM :
623+ case SWIFT_SINGLE_PAYLOAD_ENUM :
624+ case SWIFT_MULTI_PAYLOAD_ENUM :
625+ {
626+ int CaseIndex ;
627+ if (!swift_reflection_projectEnumValue (RC , EnumInstance , EnumTypeRef , & CaseIndex )) {
628+ printf ("swift_reflection_projectEnumValue failed.\n\n" );
629+ PipeMemoryReader_sendDoneMessage (& Pipe );
630+ return 1 ; // <<< Test cases rely on detecting this, so must "succeed"
631+ }
632+ if ((unsigned )CaseIndex > EnumTypeInfo .NumFields ) {
633+ printf ("swift_reflection_projectEnumValue returned invalid case.\n\n" );
634+ PipeMemoryReader_sendDoneMessage (& Pipe );
635+ return 0 ;
636+ }
637+ swift_childinfo_t CaseInfo
638+ = swift_reflection_childOfTypeRef (RC , EnumTypeRef , CaseIndex );
639+ printf (".%s" , CaseInfo .Name );
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!
646+ printf ("(" );
647+ parens += 1 ;
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+ }
676+ }
677+ }
678+ break ;
679+ }
680+ default :
681+ {
682+ EnumTypeRef = 0 ;
623683 if (parens == 0 ) {
624684 printf (".??" ); // Enum was optimized away, print "something"
625685 } else {
626686 printf ("_" );
627687 }
628688 break ;
629689 }
630-
631- int CaseIndex ;
632- if (!swift_reflection_projectEnumValue (RC , EnumInstance , EnumTypeRef , & CaseIndex )) {
633- printf ("swift_reflection_projectEnumValue failed.\n\n" );
634- PipeMemoryReader_sendDoneMessage (& Pipe );
635- return 1 ; // <<< Test cases rely on detecting this, so must "succeed"
636- }
637- if ((unsigned )CaseIndex > EnumTypeInfo .NumFields ) {
638- printf ("swift_reflection_projectEnumValue returned invalid case.\n\n" );
639- PipeMemoryReader_sendDoneMessage (& Pipe );
640- return 0 ;
641- }
642-
643- swift_childinfo_t CaseInfo
644- = swift_reflection_childOfTypeRef (RC , EnumTypeRef , CaseIndex );
645- printf (".%s" , CaseInfo .Name );
646- EnumTypeRef = CaseInfo .TR ;
647- if (EnumTypeRef != 0 ) {
648- printf ("(" );
649- parens += 1 ;
650690 }
651691 }
652692 for (int i = 0 ; i < parens ; ++ i ) {
@@ -724,6 +764,10 @@ int doDumpHeapInstance(const char *BinaryFilename) {
724764 exit (status );
725765 }
726766 default : { // Parent
767+ for (int i = 5 ; i > 1 ; i -- ) {
768+ fprintf (stderr , "%d\n" , i );
769+ sleep (1 );
770+ }
727771 close (PipeMemoryReader_getChildReadFD (& Pipe ));
728772 close (PipeMemoryReader_getChildWriteFD (& Pipe ));
729773 SwiftReflectionContextRef RC =
0 commit comments