@@ -213,13 +213,38 @@ where
213213
214214impl < M : FunctionMutability > LowLevelILFunction < M , NonSSA > {
215215 /// Retrieve the SSA form of the function.
216+ ///
217+ /// If the function has not had the SSA form generated you may call `generate_ssa_form`.
216218 pub fn ssa_form ( & self ) -> Option < Ref < LowLevelILFunction < M , SSA > > > {
217219 let handle = unsafe { BNGetLowLevelILSSAForm ( self . handle ) } ;
218220 if handle. is_null ( ) {
219221 return None ;
220222 }
221223 Some ( unsafe { LowLevelILFunction :: ref_from_raw ( handle) } )
222224 }
225+
226+ /// Generates the SSA form of the function. Typically called **after** `finalize`.
227+ ///
228+ /// If you created a freestanding [`LowLevelILFunction`] with no [`LowLevelILFunction::function`]
229+ /// than this function will **not** generate the SSA form, as it is currently impossible.
230+ ///
231+ /// # Example
232+ ///
233+ /// ```no_run
234+ /// use binaryninja::low_level_il::LowLevelILMutableFunction;
235+ /// use binaryninja::rc::Ref;
236+ /// # let mutable_llil: Ref<LowLevelILMutableFunction> = unimplemented!();
237+ /// // ... modify the IL
238+ /// let finalized_llil = mutable_llil.finalized();
239+ /// finalized_llil.generate_ssa_form();
240+ /// ```
241+ pub fn generate_ssa_form ( & self ) {
242+ use binaryninjacore_sys:: BNGenerateLowLevelILSSAForm ;
243+ // SSA form may only be generated if there is an owning function, otherwise it will crash.
244+ if self . function ( ) . is_some ( ) {
245+ unsafe { BNGenerateLowLevelILSSAForm ( self . handle ) } ;
246+ }
247+ }
223248}
224249
225250// Allow instantiating Lifted IL functions for querying Lifted IL from Architectures
@@ -242,14 +267,24 @@ impl LowLevelILFunction<Mutable, NonSSA> {
242267
243268 unsafe { Self :: ref_from_raw_with_arch ( handle, Some ( arch) ) }
244269 }
245-
246- pub fn generate_ssa_form ( & self ) {
247- use binaryninjacore_sys:: BNGenerateLowLevelILSSAForm ;
248- unsafe { BNGenerateLowLevelILSSAForm ( self . handle ) } ;
249- }
250270}
251271
252272impl Ref < LowLevelILFunction < Mutable , NonSSA > > {
273+ /// Finalize the mutated [`LowLevelILFunction`], returning a [`LowLevelILRegularFunction`].
274+ ///
275+ /// This function **will not** correct the SSA related dataflow, to do that you must call
276+ /// the function [`LowLevelILMutableFunction::generate_ssa_form`].
277+ ///
278+ /// # Example
279+ ///
280+ /// ```no_run
281+ /// use binaryninja::low_level_il::LowLevelILMutableFunction;
282+ /// use binaryninja::rc::Ref;
283+ /// # let mutable_llil: Ref<LowLevelILMutableFunction> = unimplemented!();
284+ /// // ... modify the IL
285+ /// let finalized_llil = mutable_llil.finalized();
286+ /// finalized_llil.generate_ssa_form();
287+ /// ```
253288 pub fn finalized ( self ) -> Ref < LowLevelILFunction < Finalized , NonSSA > > {
254289 unsafe {
255290 BNFinalizeLowLevelILFunction ( self . handle ) ;
0 commit comments