File tree 3 files changed +28
-4
lines changed
3 files changed +28
-4
lines changed Original file line number Diff line number Diff line change 2
2
_Noreturn void f (void );
3
3
__attribute__ ((noreturn)) void g(void );
4
4
[[noreturn]] void h (void );
5
+ void i (__attribute__((noreturn)) void (*arg)(void ));
6
+ __attribute__ ((noreturn)) void j(__attribute__((noreturn)) void (*arg)(void ));
Original file line number Diff line number Diff line change @@ -505,10 +505,24 @@ impl FunctionSig {
505
505
Default :: default ( )
506
506
} ;
507
507
508
- // This looks easy to break but the clang parser keeps the type spelling clean even if
509
- // other attributes are added.
510
- is_divergent =
511
- is_divergent || ty. spelling ( ) . contains ( "__attribute__((noreturn))" ) ;
508
+ // Check if the type contains __attribute__((noreturn)) outside of parentheses. This is
509
+ // somewhat fragile, but it seems to be the only way to get at this information as of
510
+ // libclang 9.
511
+ let ty_spelling = ty. spelling ( ) ;
512
+ let has_attribute_noreturn = ty_spelling
513
+ . match_indices ( "__attribute__((noreturn))" )
514
+ . any ( |( i, _) | {
515
+ let depth = ty_spelling[ ..i]
516
+ . bytes ( )
517
+ . filter_map ( |ch| match ch {
518
+ b'(' => Some ( 1 ) ,
519
+ b')' => Some ( -1 ) ,
520
+ _ => None ,
521
+ } )
522
+ . sum :: < isize > ( ) ;
523
+ depth == 0
524
+ } ) ;
525
+ is_divergent = is_divergent || has_attribute_noreturn;
512
526
513
527
let is_method = kind == CXCursor_CXXMethod ;
514
528
let is_constructor = kind == CXCursor_Constructor ;
You can’t perform that action at this time.
0 commit comments