Function Outliner::Preprocess::transformPreprocIfs

Function Outliner::Preprocess::transformPreprocIfs#

Function Documentation#

SgBasicBlock *Outliner::Preprocess::transformPreprocIfs(SgBasicBlock *b)#

Transform ‘#if’ directive structure. It is possible that certain preprocessor directives may straddle the boundaries of a basic block. This routine attempts to detect and transform these instances so that the block may be safely outlined.

In particular, consider the following SgBasicBlock, which has 2 ‘#if’ directives straddling it (labeled ‘B’ and ‘D’) and one surrounding it (‘A’).

#if [A1] S0;

if [B1] <==+#

S1; |

elif [B2] <==+#

S2; | { | S3; +&#8212; Straddles opening brace.

elif [B3] <==+#

S4; |

endif [B] <==+#

S5;

if [C] <==+#

S6; +&#8212; Fully within the block

endif [C] <==+#

S7;

if [D1] <==+#

S8; |

elif [D2] <==+#

S9; +-&#8212; Straddles ending brace. } | S10; |

elif [D3] <==+#

S11; |

endif [D] <==+#

S12; #endif [A]

This routine will transform this block into (new statements and directives marked with a ‘**’):

#if [A1] S0;

if [B1]#

S1;

elif [B2]#

S2;

endif // [B] ** <==+ CLOSE ([B]);#

#endif // [A] ** <==+ { { ** <==============+ #if 1 // [A1] ** | OPEN ([B]);

if 1 // [B1, B2] ** <==+#

S3;

elif [B3]#

S4;

endif [B]#

S5;

if [C]#

S6;

endif [C]#

S7;

if [D1]#

S8;

elif [D2]#

S9;

endif [D] ** <==+ CLOSE ([D]);#

#endif [A] ** <==+ } ** #if 1 //[A1] ** <=========+ OPEN ([D2]);

if 1 // [D1, D2] ** <==+#

} S10;

elif [D3]#

S11;

endif [D]#

S12; #endif [A]

Note that the block to-be-outlined is now fully self-contained. Logically, the transformation consists of “closing” and “opening” the ‘#if’ directive contexts at the boundaries to the outlined block as shown above.