@@ -505,8 +505,19 @@ void Pointer::activate() const {
505505 auto activate = [](Pointer &P) -> void {
506506 P.getInlineDesc ()->IsActive = true ;
507507 };
508- auto deactivate = [](Pointer &P) -> void {
508+
509+ std::function<void (Pointer &)> deactivate;
510+ deactivate = [&deactivate](Pointer &P) -> void {
509511 P.getInlineDesc ()->IsActive = false ;
512+
513+ if (const Record *R = P.getRecord ()) {
514+ for (const Record::Field &F : R->fields ()) {
515+ Pointer FieldPtr = P.atField (F.Offset );
516+ if (FieldPtr.getInlineDesc ()->IsActive )
517+ deactivate (FieldPtr);
518+ }
519+ // FIXME: Bases?
520+ }
510521 };
511522
512523 // Unions might be nested etc., so find the topmost Pointer that's
@@ -516,21 +527,31 @@ void Pointer::activate() const {
516527 UnionPtr = UnionPtr.getBase ();
517528
518529 assert (UnionPtr.getFieldDesc ()->isUnion ());
519-
520530 const Record *UnionRecord = UnionPtr.getRecord ();
531+
532+ // The direct child pointer of the union that's on the path from
533+ // this pointer to the union.
534+ Pointer ChildPtr = *this ;
535+ assert (ChildPtr != UnionPtr);
536+ while (true ) {
537+ if (ChildPtr.getBase () == UnionPtr)
538+ break ;
539+ ChildPtr = ChildPtr.getBase ();
540+ }
541+ assert (ChildPtr.getBase () == UnionPtr);
542+
521543 for (const Record::Field &F : UnionRecord->fields ()) {
522544 Pointer FieldPtr = UnionPtr.atField (F.Offset );
523- if (FieldPtr == *this ) {
545+ if (FieldPtr == ChildPtr) {
546+ // No need to deactivate, will be activated in the next loop.
524547 } else {
525548 deactivate (FieldPtr);
526- // FIXME: Recurse.
527549 }
528550 }
529551
530552 Pointer B = *this ;
531553 while (B != UnionPtr) {
532554 activate (B);
533- // FIXME: Need to de-activate other fields of parent records.
534555 B = B.getBase ();
535556 }
536557}
0 commit comments