@@ -163,14 +163,19 @@ impl<'ctx> Builder<'ctx> {
163
163
}
164
164
}
165
165
166
- /// Builds an invoke instruction. An invoke is similar to a normal function call, but used to
166
+ /// An invoke is similar to a normal function call, but used to
167
167
/// call functions that may throw an exception, and then respond to the exception.
168
168
///
169
169
/// When the called function returns normally, the `then` block is evaluated next. If instead
170
- /// the function threw an exception, the `catch` block is intered . The first non-phi
170
+ /// the function threw an exception, the `catch` block is entered . The first non-phi
171
171
/// instruction of the catch block must be a `landingpad` instruction. See also
172
172
/// [`Builder::build_landing_pad`].
173
173
///
174
+ /// The [`add_prune_eh_pass`] turns an invoke into a call when the called function is
175
+ /// guaranteed to never throw an exception.
176
+ ///
177
+ /// [`add_prune_eh_pass`]: crate::passes::PassManager::add_prune_eh_pass
178
+ ///
174
179
/// This example catches C++ exceptions of type `int`, and returns `0` if an exceptions is thrown.
175
180
/// For usage of a cleanup landing pad and the `resume` instruction, see [`Builder::build_resume`]
176
181
/// ```no_run
@@ -219,8 +224,9 @@ impl<'ctx> Builder<'ctx> {
219
224
/// // the personality function used by C++
220
225
/// let personality_function = {
221
226
/// let name = "__gxx_personality_v0";
227
+ /// let linkage = Some(Linkage::External);
222
228
///
223
- /// module.add_function(name, context.i64_type().fn_type(&[], false), None )
229
+ /// module.add_function(name, context.i64_type().fn_type(&[], false), linkage )
224
230
/// };
225
231
///
226
232
/// // type of an exception in C++
@@ -276,15 +282,17 @@ impl<'ctx> Builder<'ctx> {
276
282
}
277
283
278
284
/// Landing pads are places where control flow jumps to if a [`Builder::build_invoke`] triggered an exception.
279
- /// The landing pad will inspect the exception, and either handle the exception, or after some optional cleanup,
280
- /// will resume the exception handling, causing the exception to bubble up.
285
+ /// The landing pad will match the exception against its *clauses*. Depending on the clause
286
+ /// that is matched, the exception can then be handled, or resumed after some optional cleanup,
287
+ /// causing the exception to bubble up.
281
288
///
282
289
/// Exceptions in LLVM are designed based on the needs of a C++ compiler, but can be used more generally.
283
- /// Here are some specific examples of landing pads. For a full example, see [`Builder::build_invoke`].
290
+ /// Here are some specific examples of landing pads. For a full example of handling an exception , see [`Builder::build_invoke`].
284
291
///
285
292
/// * **cleanup**: a cleanup landing pad is always visited when unwinding the stack.
286
293
/// A cleanup is extra code that needs to be run when unwinding a scope. C++ destructors are a typical example.
287
294
/// In a language with reference counting, the cleanup block can decrement the refcount of values in scope.
295
+ /// The [`Builder::build_resume`] function has a full example using a cleanup lading pad.
288
296
///
289
297
/// ```no_run
290
298
/// use inkwell::context::Context;
@@ -302,13 +310,13 @@ impl<'ctx> Builder<'ctx> {
302
310
/// // the personality function used by C++
303
311
/// let personality_function = {
304
312
/// let name = "__gxx_personality_v0";
305
- ///
306
- /// module.add_function(name, context.i64_type().fn_type(&[], false), None)
313
+ /// let linkage = Some(Linkage::External);
314
+ ///
315
+ /// module.add_function(name, context.i64_type().fn_type(&[], false), linkage)
307
316
/// };
308
317
///
309
318
/// // make the cleanup landing pad
310
- /// let clauses: &[inkwell::values::PointerValue] = &[];
311
- /// let res = builder.build_landing_pad( exception_type, personality_function, clauses, true, "res");
319
+ /// let res = builder.build_landing_pad( exception_type, personality_function, &[], true, "res");
312
320
/// ```
313
321
///
314
322
/// * **catch all**: An implementation of the C++ `catch(...)`, which catches all exceptions.
@@ -330,8 +338,9 @@ impl<'ctx> Builder<'ctx> {
330
338
/// // the personality function used by C++
331
339
/// let personality_function = {
332
340
/// let name = "__gxx_personality_v0";
333
- ///
334
- /// module.add_function(name, context.i64_type().fn_type(&[], false), None)
341
+ /// let linkage = Some(Linkage::External);
342
+ ///
343
+ /// module.add_function(name, context.i64_type().fn_type(&[], false), linkage)
335
344
/// };
336
345
///
337
346
/// // make a null pointer of type i8
@@ -341,7 +350,7 @@ impl<'ctx> Builder<'ctx> {
341
350
/// let res = builder.build_landing_pad(exception_type, personality_function, &[null], false, "res");
342
351
/// ```
343
352
///
344
- /// * **catch a typeinfo **: Catch a specific type of exception. The example uses C++'s type info.
353
+ /// * **catch a type of exception **: Catch a specific type of exception. The example uses C++'s type info.
345
354
///
346
355
/// ```no_run
347
356
/// use inkwell::context::Context;
@@ -360,8 +369,9 @@ impl<'ctx> Builder<'ctx> {
360
369
/// // the personality function used by C++
361
370
/// let personality_function = {
362
371
/// let name = "__gxx_personality_v0";
363
- ///
364
- /// module.add_function(name, context.i64_type().fn_type(&[], false), None)
372
+ /// let linkage = Some(Linkage::External);
373
+ ///
374
+ /// module.add_function(name, context.i64_type().fn_type(&[], false), linkage)
365
375
/// };
366
376
///
367
377
/// // link in the C++ type info for the `int` type
@@ -393,8 +403,9 @@ impl<'ctx> Builder<'ctx> {
393
403
/// // the personality function used by C++
394
404
/// let personality_function = {
395
405
/// let name = "__gxx_personality_v0";
396
- ///
397
- /// module.add_function(name, context.i64_type().fn_type(&[], false), None)
406
+ /// let linkage = Some(Linkage::External);
407
+ ///
408
+ /// module.add_function(name, context.i64_type().fn_type(&[], false), linkage)
398
409
/// };
399
410
///
400
411
/// // link in the C++ type info for the `int` type
@@ -405,17 +416,16 @@ impl<'ctx> Builder<'ctx> {
405
416
/// let filter_pattern = i8_ptr_type.const_array(&[type_info_int.as_any_value_enum().into_pointer_value()]);
406
417
/// let res = builder.build_landing_pad(exception_type, personality_function, &[filter_pattern], false, "res");
407
418
/// ```
408
- pub fn build_landing_pad < T , V > (
419
+ pub fn build_landing_pad < T > (
409
420
& self ,
410
421
exception_type : T ,
411
422
personality_function : FunctionValue < ' ctx > ,
412
- clauses : & [ V ] ,
423
+ clauses : & [ BasicValueEnum < ' ctx > ] ,
413
424
is_cleanup : bool ,
414
425
name : & str
415
426
) -> BasicValueEnum < ' ctx >
416
427
where
417
428
T : BasicType < ' ctx > ,
418
- V : BasicValue < ' ctx > ,
419
429
{
420
430
let c_string = to_c_str ( name) ;
421
431
let num_clauses = clauses. len ( ) as u32 ;
@@ -498,8 +508,9 @@ impl<'ctx> Builder<'ctx> {
498
508
/// // the personality function used by C++
499
509
/// let personality_function = {
500
510
/// let name = "__gxx_personality_v0";
511
+ /// let linkage = Some(Linkage::External);
501
512
///
502
- /// module.add_function(name, context.i64_type().fn_type(&[], false), None )
513
+ /// module.add_function(name, context.i64_type().fn_type(&[], false), linkage )
503
514
/// };
504
515
///
505
516
/// // type of an exception in C++
@@ -508,8 +519,7 @@ impl<'ctx> Builder<'ctx> {
508
519
/// let exception_type = context.struct_type(&[i8_ptr_type.into(), i32_type.into()], false);
509
520
///
510
521
/// // make the landing pad; must give a concrete type to the slice
511
- /// let clauses: &[inkwell::values::PointerValue] = &[];
512
- /// let res = builder.build_landing_pad( exception_type, personality_function, clauses, true, "res");
522
+ /// let res = builder.build_landing_pad( exception_type, personality_function, &[], true, "res");
513
523
///
514
524
/// // do cleanup ...
515
525
///
0 commit comments