Ich würde die Routine ohnehin anders aufbauen.

1. Einen der internen Timer als Zeitbasis aktivieren.

2. Je nach IR Code kann man den Interrupt bei jeder Flanke, oder nur bei steigender oder fallender Flanke des Signals auslösen.
( Interrupt Sensing in der Interrupt Routine umschalten, oder Pin Change Interrupts verwenden ).
( Auch der ICP des Timers könnte genutzt werden ! ).

3. Der Timer wird bei jedem Interrupt Ereignis ausgelesen und zurück gesetzt. Dadurch bekommt man eine Timing Information über das ankommende Signal, das man auswerten kann. Und in ensprechende Befehle, Bits oder sonstwas umsetzen kann.

4. Am Ende der Impulskette wird ein Flag gesetzt, das dem Hauptprogramm mitteilt, das eine komplette Impulskette empfangen wurde.

5. Bei dem Verwendeten Timer kann man einen Comparematch Interrupt mit CTC setzen um unvollständige Codes zu erkennen und diesen String dann zu verwerfen. ( Zählregister und Pointer für den Empfang zurück setzten ).

6. Die komplette Abarbeitung eines empfangenen Strings findet in der Hauptroutine statt. Nach der Verarbeitung wird dann das Flag für einen komplett Empfangenen IR Code gelöscht, damit das System für den nächsten String wieder "scharf" ist.

Es gibt sicher auch andere Methoden um so etwas zu lösen, allerdings ist es schon so wie oben Beschrieben wurde.
Bei einem aktiven Interrupt sind alle!!! anderen Interrupts gesperrt.
Die entsprechenden Flags werden aber dennoch gesetzt.
Das bedeutet, das dann alle freigegebenen und anstehenden Interrupts nach Beendigung einer Interruptroutine nach Ihrer Priorität nacheinander ausgeführt werden.
Es gilt also nach wie vor die Anweisung Interrupt Routinen so kurz wie möglich zu halten!
Komplette Abfragen in einen einzigen Interrupt zu packen erscheint zwar einfach, ist aber keine gute Idee.