summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Poveda <christian.poveda@ferrous-systems.com>2022-08-31 14:38:26 -0500
committerEmilio Cobos Álvarez <emilio@crisal.io>2022-09-22 20:25:33 -1000
commit250150d0159ef02b35f65cd83d71d60f0439ee95 (patch)
treeb8d35855a58b4571fd0049e32c50235b674a1c31 /src
parent6a100c0b32fae6dca5148636bb00c1f8ecd234ca (diff)
check for noreturn attribute
Diffstat (limited to 'src')
-rw-r--r--src/clang.rs18
-rw-r--r--src/codegen/mod.rs4
-rw-r--r--src/ir/function.rs14
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 {