@@ -435,8 +435,8 @@ impl FunctionSig {
435
435
436
436
// Don't parse operatorxx functions in C++
437
437
let is_operator = |spelling : & str | {
438
- spelling. starts_with ( "operator" ) &&
439
- !clang:: is_valid_identifier ( spelling)
438
+ spelling. starts_with ( "operator" )
439
+ && !clang:: is_valid_identifier ( spelling)
440
440
} ;
441
441
if is_operator ( & spelling) {
442
442
return Err ( ParseError :: Continue ) ;
@@ -445,8 +445,8 @@ impl FunctionSig {
445
445
// Constructors of non-type template parameter classes for some reason
446
446
// include the template parameter in their name. Just skip them, since
447
447
// we don't handle well non-type template parameters anyway.
448
- if ( kind == CXCursor_Constructor || kind == CXCursor_Destructor ) &&
449
- spelling. contains ( '<' )
448
+ if ( kind == CXCursor_Constructor || kind == CXCursor_Destructor )
449
+ && spelling. contains ( '<' )
450
450
{
451
451
return Err ( ParseError :: Continue ) ;
452
452
}
@@ -458,11 +458,11 @@ impl FunctionSig {
458
458
} ;
459
459
460
460
let mut args = match kind {
461
- CXCursor_FunctionDecl |
462
- CXCursor_Constructor |
463
- CXCursor_CXXMethod |
464
- CXCursor_ObjCInstanceMethodDecl |
465
- CXCursor_ObjCClassMethodDecl => {
461
+ CXCursor_FunctionDecl
462
+ | CXCursor_Constructor
463
+ | CXCursor_CXXMethod
464
+ | CXCursor_ObjCInstanceMethodDecl
465
+ | CXCursor_ObjCClassMethodDecl => {
466
466
args_from_ty_and_cursor ( ty, & cursor, ctx)
467
467
}
468
468
_ => {
@@ -505,16 +505,31 @@ 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
+ . find ( "__attribute__((noreturn))" )
514
+ . filter ( |& 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_some ( ) ;
526
+ is_divergent = is_divergent || has_attribute_noreturn;
512
527
513
528
let is_method = kind == CXCursor_CXXMethod ;
514
529
let is_constructor = kind == CXCursor_Constructor ;
515
530
let is_destructor = kind == CXCursor_Destructor ;
516
- if ( is_constructor || is_destructor || is_method) &&
517
- cursor. lexical_parent ( ) != cursor. semantic_parent ( )
531
+ if ( is_constructor || is_destructor || is_method)
532
+ && cursor. lexical_parent ( ) != cursor. semantic_parent ( )
518
533
{
519
534
// Only parse constructors once.
520
535
return Err ( ParseError :: Continue ) ;
@@ -555,8 +570,8 @@ impl FunctionSig {
555
570
}
556
571
}
557
572
558
- let ty_ret_type = if kind == CXCursor_ObjCInstanceMethodDecl ||
559
- kind == CXCursor_ObjCClassMethodDecl
573
+ let ty_ret_type = if kind == CXCursor_ObjCInstanceMethodDecl
574
+ || kind == CXCursor_ObjCClassMethodDecl
560
575
{
561
576
ty. ret_type ( )
562
577
. or_else ( || cursor. ret_type ( ) )
@@ -734,13 +749,13 @@ impl ClangSubItemParser for Function {
734
749
_ => return Err ( ParseError :: Continue ) ,
735
750
} ;
736
751
737
- if cursor. is_inlined_function ( ) ||
738
- cursor
752
+ if cursor. is_inlined_function ( )
753
+ || cursor
739
754
. definition ( )
740
755
. map_or ( false , |x| x. is_inlined_function ( ) )
741
756
{
742
- if !context. options ( ) . generate_inline_functions &&
743
- !context. options ( ) . wrap_static_fns
757
+ if !context. options ( ) . generate_inline_functions
758
+ && !context. options ( ) . wrap_static_fns
744
759
{
745
760
return Err ( ParseError :: Continue ) ;
746
761
}
@@ -750,9 +765,9 @@ impl ClangSubItemParser for Function {
750
765
}
751
766
752
767
// We cannot handle `inline` functions that are not `static`.
753
- if context. options ( ) . wrap_static_fns &&
754
- cursor. is_inlined_function ( ) &&
755
- matches ! ( linkage, Linkage :: External )
768
+ if context. options ( ) . wrap_static_fns
769
+ && cursor. is_inlined_function ( )
770
+ && matches ! ( linkage, Linkage :: External )
756
771
{
757
772
return Err ( ParseError :: Continue ) ;
758
773
}
0 commit comments