diff options
author | Christian Poveda <christian.poveda@ferrous-systems.com> | 2022-08-31 14:38:26 -0500 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2022-09-22 20:25:33 -1000 |
commit | 250150d0159ef02b35f65cd83d71d60f0439ee95 (patch) | |
tree | b8d35855a58b4571fd0049e32c50235b674a1c31 /src | |
parent | 6a100c0b32fae6dca5148636bb00c1f8ecd234ca (diff) |
check for noreturn attribute
Diffstat (limited to 'src')
-rw-r--r-- | src/clang.rs | 18 | ||||
-rw-r--r-- | src/codegen/mod.rs | 4 | ||||
-rw-r--r-- | src/ir/function.rs | 14 |
3 files changed, 35 insertions, 1 deletions
diff --git a/src/clang.rs b/src/clang.rs index 2aab9618..5579c42b 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -645,6 +645,24 @@ impl Cursor { self.has_attr("warn_unused_result", Some(CXCursor_WarnUnusedResultAttr)) } + pub fn has_no_return_attr(&self) -> bool { + let mut found_attr = false; + self.visit(|cur| { + found_attr = cur.kind() == CXCursor_UnexposedAttr && + cur.tokens().iter().any(|t| { + t.kind == CXToken_Keyword && t.spelling() == b"_Noreturn" + }); + + if found_attr { + CXChildVisit_Break + } else { + CXChildVisit_Continue + } + }); + + found_attr + } + /// Does this cursor have the given attribute? /// /// `name` is checked against unexposed attributes. diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index f523232e..f1422d6b 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -4729,6 +4729,10 @@ pub mod utils { ctx: &BindgenContext, sig: &FunctionSig, ) -> proc_macro2::TokenStream { + if sig.is_divergent() { + return quote! { -> ! }; + } + let return_item = ctx.resolve_item(sig.return_type()); if let TypeKind::Void = *return_item.kind().expect_type().kind() { quote! {} diff --git a/src/ir/function.rs b/src/ir/function.rs index afbb9024..6b59649c 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -381,6 +381,7 @@ impl FunctionSig { ) -> Result<Self, ParseError> { use clang_sys::*; debug!("FunctionSig::from_ty {:?} {:?}", ty, cursor); + let is_divergent = cursor.has_no_return_attr(); // Skip function templates let kind = cursor.kind(); @@ -531,7 +532,14 @@ impl FunctionSig { warn!("Unknown calling convention: {:?}", call_conv); } - Ok(Self::new(ret, args, ty.is_variadic(), false, must_use, abi)) + Ok(Self::new( + ret, + args, + ty.is_variadic(), + is_divergent, + must_use, + abi, + )) } /// Get this function signature's return type. @@ -578,6 +586,10 @@ impl FunctionSig { matches!(self.abi, Abi::C | Abi::Unknown(..)) } + + pub(crate) fn is_divergent(&self) -> bool { + self.is_divergent + } } impl ClangSubItemParser for Function { |