1 //! Intermediate representation for C/C++ functions and methods.
2 
3 use super::comp::MethodKind;
4 use super::context::{BindgenContext, TypeId};
5 use super::dot::DotAttributes;
6 use super::item::Item;
7 use super::traversal::{EdgeKind, Trace, Tracer};
8 use super::ty::TypeKind;
9 use crate::callbacks::{ItemInfo, ItemKind};
10 use crate::clang::{self, ABIKind, Attribute};
11 use crate::parse::{ClangSubItemParser, ParseError, ParseResult};
12 use clang_sys::{self, CXCallingConv};
13 
14 use quote::TokenStreamExt;
15 use std::io;
16 use std::str::FromStr;
17 
18 const RUST_DERIVE_FUNPTR_LIMIT: usize = 12;
19 
20 /// What kind of a function are we looking at?
21 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
22 pub(crate) enum FunctionKind {
23     /// A plain, free function.
24     Function,
25     /// A method of some kind.
26     Method(MethodKind),
27 }
28 
29 impl FunctionKind {
30     /// Given a clang cursor, return the kind of function it represents, or
31     /// `None` otherwise.
from_cursor(cursor: &clang::Cursor) -> Option<FunctionKind>32     pub(crate) fn from_cursor(cursor: &clang::Cursor) -> Option<FunctionKind> {
33         // FIXME(emilio): Deduplicate logic with `ir::comp`.
34         Some(match cursor.kind() {
35             clang_sys::CXCursor_FunctionDecl => FunctionKind::Function,
36             clang_sys::CXCursor_Constructor => {
37                 FunctionKind::Method(MethodKind::Constructor)
38             }
39             clang_sys::CXCursor_Destructor => {
40                 FunctionKind::Method(if cursor.method_is_virtual() {
41                     MethodKind::VirtualDestructor {
42                         pure_virtual: cursor.method_is_pure_virtual(),
43                     }
44                 } else {
45                     MethodKind::Destructor
46                 })
47             }
48             clang_sys::CXCursor_CXXMethod => {
49                 if cursor.method_is_virtual() {
50                     FunctionKind::Method(MethodKind::Virtual {
51                         pure_virtual: cursor.method_is_pure_virtual(),
52                     })
53                 } else if cursor.method_is_static() {
54                     FunctionKind::Method(MethodKind::Static)
55                 } else {
56                     FunctionKind::Method(MethodKind::Normal)
57                 }
58             }
59             _ => return None,
60         })
61     }
62 }
63 
64 /// The style of linkage
65 #[derive(Debug, Clone, Copy)]
66 pub(crate) enum Linkage {
67     /// Externally visible and can be linked against
68     External,
69     /// Not exposed externally. 'static inline' functions will have this kind of linkage
70     Internal,
71 }
72 
73 /// A function declaration, with a signature, arguments, and argument names.
74 ///
75 /// The argument names vector must be the same length as the ones in the
76 /// signature.
77 #[derive(Debug)]
78 pub(crate) struct Function {
79     /// The name of this function.
80     name: String,
81 
82     /// The mangled name, that is, the symbol.
83     mangled_name: Option<String>,
84 
85     /// The link name. If specified, overwrite mangled_name.
86     link_name: Option<String>,
87 
88     /// The ID pointing to the current function signature.
89     signature: TypeId,
90 
91     /// The kind of function this is.
92     kind: FunctionKind,
93 
94     /// The linkage of the function.
95     linkage: Linkage,
96 }
97 
98 impl Function {
99     /// Construct a new function.
new( name: String, mangled_name: Option<String>, link_name: Option<String>, signature: TypeId, kind: FunctionKind, linkage: Linkage, ) -> Self100     pub(crate) fn new(
101         name: String,
102         mangled_name: Option<String>,
103         link_name: Option<String>,
104         signature: TypeId,
105         kind: FunctionKind,
106         linkage: Linkage,
107     ) -> Self {
108         Function {
109             name,
110             mangled_name,
111             link_name,
112             signature,
113             kind,
114             linkage,
115         }
116     }
117 
118     /// Get this function's name.
name(&self) -> &str119     pub(crate) fn name(&self) -> &str {
120         &self.name
121     }
122 
123     /// Get this function's name.
mangled_name(&self) -> Option<&str>124     pub(crate) fn mangled_name(&self) -> Option<&str> {
125         self.mangled_name.as_deref()
126     }
127 
128     /// Get this function's link name.
link_name(&self) -> Option<&str>129     pub fn link_name(&self) -> Option<&str> {
130         self.link_name.as_deref()
131     }
132 
133     /// Get this function's signature type.
signature(&self) -> TypeId134     pub(crate) fn signature(&self) -> TypeId {
135         self.signature
136     }
137 
138     /// Get this function's kind.
kind(&self) -> FunctionKind139     pub(crate) fn kind(&self) -> FunctionKind {
140         self.kind
141     }
142 
143     /// Get this function's linkage.
linkage(&self) -> Linkage144     pub(crate) fn linkage(&self) -> Linkage {
145         self.linkage
146     }
147 }
148 
149 impl DotAttributes for Function {
dot_attributes<W>( &self, _ctx: &BindgenContext, out: &mut W, ) -> io::Result<()> where W: io::Write,150     fn dot_attributes<W>(
151         &self,
152         _ctx: &BindgenContext,
153         out: &mut W,
154     ) -> io::Result<()>
155     where
156         W: io::Write,
157     {
158         if let Some(ref mangled) = self.mangled_name {
159             let mangled: String =
160                 mangled.chars().flat_map(|c| c.escape_default()).collect();
161             writeln!(
162                 out,
163                 "<tr><td>mangled name</td><td>{}</td></tr>",
164                 mangled
165             )?;
166         }
167 
168         Ok(())
169     }
170 }
171 
172 /// A valid rust ABI.
173 #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
174 pub enum Abi {
175     /// The default C ABI.
176     C,
177     /// The "stdcall" ABI.
178     Stdcall,
179     /// The "efiapi" ABI.
180     EfiApi,
181     /// The "fastcall" ABI.
182     Fastcall,
183     /// The "thiscall" ABI.
184     ThisCall,
185     /// The "vectorcall" ABI.
186     Vectorcall,
187     /// The "aapcs" ABI.
188     Aapcs,
189     /// The "win64" ABI.
190     Win64,
191     /// The "C-unwind" ABI.
192     CUnwind,
193     /// The "system" ABI.
194     System,
195 }
196 
197 impl FromStr for Abi {
198     type Err = String;
199 
from_str(s: &str) -> Result<Self, Self::Err>200     fn from_str(s: &str) -> Result<Self, Self::Err> {
201         match s {
202             "C" => Ok(Self::C),
203             "stdcall" => Ok(Self::Stdcall),
204             "efiapi" => Ok(Self::EfiApi),
205             "fastcall" => Ok(Self::Fastcall),
206             "thiscall" => Ok(Self::ThisCall),
207             "vectorcall" => Ok(Self::Vectorcall),
208             "aapcs" => Ok(Self::Aapcs),
209             "win64" => Ok(Self::Win64),
210             "C-unwind" => Ok(Self::CUnwind),
211             "system" => Ok(Self::System),
212             _ => Err(format!("Invalid or unknown ABI {:?}", s)),
213         }
214     }
215 }
216 
217 impl std::fmt::Display for Abi {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result218     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
219         let s = match *self {
220             Self::C => "C",
221             Self::Stdcall => "stdcall",
222             Self::EfiApi => "efiapi",
223             Self::Fastcall => "fastcall",
224             Self::ThisCall => "thiscall",
225             Self::Vectorcall => "vectorcall",
226             Self::Aapcs => "aapcs",
227             Self::Win64 => "win64",
228             Self::CUnwind => "C-unwind",
229             Abi::System => "system",
230         };
231 
232         s.fmt(f)
233     }
234 }
235 
236 impl quote::ToTokens for Abi {
to_tokens(&self, tokens: &mut proc_macro2::TokenStream)237     fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
238         let abi = self.to_string();
239         tokens.append_all(quote! { #abi });
240     }
241 }
242 
243 /// An ABI extracted from a clang cursor.
244 #[derive(Debug, Copy, Clone)]
245 pub(crate) enum ClangAbi {
246     /// An ABI known by Rust.
247     Known(Abi),
248     /// An unknown or invalid ABI.
249     Unknown(CXCallingConv),
250 }
251 
252 impl ClangAbi {
253     /// Returns whether this Abi is known or not.
is_unknown(&self) -> bool254     fn is_unknown(&self) -> bool {
255         matches!(*self, ClangAbi::Unknown(..))
256     }
257 }
258 
259 impl quote::ToTokens for ClangAbi {
to_tokens(&self, tokens: &mut proc_macro2::TokenStream)260     fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
261         match *self {
262             Self::Known(abi) => abi.to_tokens(tokens),
263             Self::Unknown(cc) => panic!(
264                 "Cannot turn unknown calling convention to tokens: {:?}",
265                 cc
266             ),
267         }
268     }
269 }
270 
271 /// A function signature.
272 #[derive(Debug)]
273 pub(crate) struct FunctionSig {
274     /// The name of this function signature.
275     name: String,
276 
277     /// The return type of the function.
278     return_type: TypeId,
279 
280     /// The type of the arguments, optionally with the name of the argument when
281     /// declared.
282     argument_types: Vec<(Option<String>, TypeId)>,
283 
284     /// Whether this function is variadic.
285     is_variadic: bool,
286     is_divergent: bool,
287 
288     /// Whether this function's return value must be used.
289     must_use: bool,
290 
291     /// The ABI of this function.
292     abi: ClangAbi,
293 }
294 
get_abi(cc: CXCallingConv) -> ClangAbi295 fn get_abi(cc: CXCallingConv) -> ClangAbi {
296     use clang_sys::*;
297     match cc {
298         CXCallingConv_Default => ClangAbi::Known(Abi::C),
299         CXCallingConv_C => ClangAbi::Known(Abi::C),
300         CXCallingConv_X86StdCall => ClangAbi::Known(Abi::Stdcall),
301         CXCallingConv_X86FastCall => ClangAbi::Known(Abi::Fastcall),
302         CXCallingConv_X86ThisCall => ClangAbi::Known(Abi::ThisCall),
303         CXCallingConv_X86VectorCall => ClangAbi::Known(Abi::Vectorcall),
304         CXCallingConv_AAPCS => ClangAbi::Known(Abi::Aapcs),
305         CXCallingConv_X86_64Win64 => ClangAbi::Known(Abi::Win64),
306         CXCallingConv_AArch64VectorCall => ClangAbi::Known(Abi::Vectorcall),
307         other => ClangAbi::Unknown(other),
308     }
309 }
310 
311 /// Get the mangled name for the cursor's referent.
cursor_mangling( ctx: &BindgenContext, cursor: &clang::Cursor, ) -> Option<String>312 pub(crate) fn cursor_mangling(
313     ctx: &BindgenContext,
314     cursor: &clang::Cursor,
315 ) -> Option<String> {
316     if !ctx.options().enable_mangling {
317         return None;
318     }
319 
320     // We early return here because libclang may crash in some case
321     // if we pass in a variable inside a partial specialized template.
322     // See rust-lang/rust-bindgen#67, and rust-lang/rust-bindgen#462.
323     if cursor.is_in_non_fully_specialized_template() {
324         return None;
325     }
326 
327     let is_itanium_abi = ctx.abi_kind() == ABIKind::GenericItanium;
328     let is_destructor = cursor.kind() == clang_sys::CXCursor_Destructor;
329     if let Ok(mut manglings) = cursor.cxx_manglings() {
330         while let Some(m) = manglings.pop() {
331             // Only generate the destructor group 1, see below.
332             if is_itanium_abi && is_destructor && !m.ends_with("D1Ev") {
333                 continue;
334             }
335 
336             return Some(m);
337         }
338     }
339 
340     let mut mangling = cursor.mangling();
341     if mangling.is_empty() {
342         return None;
343     }
344 
345     if is_itanium_abi && is_destructor {
346         // With old (3.8-) libclang versions, and the Itanium ABI, clang returns
347         // the "destructor group 0" symbol, which means that it'll try to free
348         // memory, which definitely isn't what we want.
349         //
350         // Explicitly force the destructor group 1 symbol.
351         //
352         // See http://refspecs.linuxbase.org/cxxabi-1.83.html#mangling-special
353         // for the reference, and http://stackoverflow.com/a/6614369/1091587 for
354         // a more friendly explanation.
355         //
356         // We don't need to do this for constructors since clang seems to always
357         // have returned the C1 constructor.
358         //
359         // FIXME(emilio): Can a legit symbol in other ABIs end with this string?
360         // I don't think so, but if it can this would become a linker error
361         // anyway, not an invalid free at runtime.
362         //
363         // TODO(emilio, #611): Use cpp_demangle if this becomes nastier with
364         // time.
365         if mangling.ends_with("D0Ev") {
366             let new_len = mangling.len() - 4;
367             mangling.truncate(new_len);
368             mangling.push_str("D1Ev");
369         }
370     }
371 
372     Some(mangling)
373 }
374 
args_from_ty_and_cursor( ty: &clang::Type, cursor: &clang::Cursor, ctx: &mut BindgenContext, ) -> Vec<(Option<String>, TypeId)>375 fn args_from_ty_and_cursor(
376     ty: &clang::Type,
377     cursor: &clang::Cursor,
378     ctx: &mut BindgenContext,
379 ) -> Vec<(Option<String>, TypeId)> {
380     let cursor_args = cursor.args().unwrap_or_default().into_iter();
381     let type_args = ty.args().unwrap_or_default().into_iter();
382 
383     // Argument types can be found in either the cursor or the type, but argument names may only be
384     // found on the cursor. We often have access to both a type and a cursor for each argument, but
385     // in some cases we may only have one.
386     //
387     // Prefer using the type as the source of truth for the argument's type, but fall back to
388     // inspecting the cursor (this happens for Objective C interfaces).
389     //
390     // Prefer using the cursor for the argument's type, but fall back to using the parent's cursor
391     // (this happens for function pointer return types).
392     cursor_args
393         .map(Some)
394         .chain(std::iter::repeat(None))
395         .zip(type_args.map(Some).chain(std::iter::repeat(None)))
396         .take_while(|(cur, ty)| cur.is_some() || ty.is_some())
397         .map(|(arg_cur, arg_ty)| {
398             let name = arg_cur.map(|a| a.spelling()).and_then(|name| {
399                 if name.is_empty() {
400                     None
401                 } else {
402                     Some(name)
403                 }
404             });
405 
406             let cursor = arg_cur.unwrap_or(*cursor);
407             let ty = arg_ty.unwrap_or_else(|| cursor.cur_type());
408             (name, Item::from_ty_or_ref(ty, cursor, None, ctx))
409         })
410         .collect()
411 }
412 
413 impl FunctionSig {
414     /// Get the function name.
name(&self) -> &str415     pub(crate) fn name(&self) -> &str {
416         &self.name
417     }
418 
419     /// Construct a new function signature from the given Clang type.
from_ty( ty: &clang::Type, cursor: &clang::Cursor, ctx: &mut BindgenContext, ) -> Result<Self, ParseError>420     pub(crate) fn from_ty(
421         ty: &clang::Type,
422         cursor: &clang::Cursor,
423         ctx: &mut BindgenContext,
424     ) -> Result<Self, ParseError> {
425         use clang_sys::*;
426         debug!("FunctionSig::from_ty {:?} {:?}", ty, cursor);
427 
428         // Skip function templates
429         let kind = cursor.kind();
430         if kind == CXCursor_FunctionTemplate {
431             return Err(ParseError::Continue);
432         }
433 
434         let spelling = cursor.spelling();
435 
436         // Don't parse operatorxx functions in C++
437         let is_operator = |spelling: &str| {
438             spelling.starts_with("operator") &&
439                 !clang::is_valid_identifier(spelling)
440         };
441         if is_operator(&spelling) {
442             return Err(ParseError::Continue);
443         }
444 
445         // Constructors of non-type template parameter classes for some reason
446         // include the template parameter in their name. Just skip them, since
447         // we don't handle well non-type template parameters anyway.
448         if (kind == CXCursor_Constructor || kind == CXCursor_Destructor) &&
449             spelling.contains('<')
450         {
451             return Err(ParseError::Continue);
452         }
453 
454         let cursor = if cursor.is_valid() {
455             *cursor
456         } else {
457             ty.declaration()
458         };
459 
460         let mut args = match kind {
461             CXCursor_FunctionDecl |
462             CXCursor_Constructor |
463             CXCursor_CXXMethod |
464             CXCursor_ObjCInstanceMethodDecl |
465             CXCursor_ObjCClassMethodDecl => {
466                 args_from_ty_and_cursor(ty, &cursor, ctx)
467             }
468             _ => {
469                 // For non-CXCursor_FunctionDecl, visiting the cursor's children
470                 // is the only reliable way to get parameter names.
471                 let mut args = vec![];
472                 cursor.visit(|c| {
473                     if c.kind() == CXCursor_ParmDecl {
474                         let ty =
475                             Item::from_ty_or_ref(c.cur_type(), c, None, ctx);
476                         let name = c.spelling();
477                         let name =
478                             if name.is_empty() { None } else { Some(name) };
479                         args.push((name, ty));
480                     }
481                     CXChildVisit_Continue
482                 });
483 
484                 if args.is_empty() {
485                     // FIXME(emilio): Sometimes libclang doesn't expose the
486                     // right AST for functions tagged as stdcall and such...
487                     //
488                     // https://bugs.llvm.org/show_bug.cgi?id=45919
489                     args_from_ty_and_cursor(ty, &cursor, ctx)
490                 } else {
491                     args
492                 }
493             }
494         };
495 
496         let (must_use, mut is_divergent) =
497             if ctx.options().enable_function_attribute_detection {
498                 let [must_use, no_return, no_return_cpp] = cursor.has_attrs(&[
499                     Attribute::MUST_USE,
500                     Attribute::NO_RETURN,
501                     Attribute::NO_RETURN_CPP,
502                 ]);
503                 (must_use, no_return || no_return_cpp)
504             } else {
505                 Default::default()
506             };
507 
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;
526 
527         let is_method = kind == CXCursor_CXXMethod;
528         let is_constructor = kind == CXCursor_Constructor;
529         let is_destructor = kind == CXCursor_Destructor;
530         if (is_constructor || is_destructor || is_method) &&
531             cursor.lexical_parent() != cursor.semantic_parent()
532         {
533             // Only parse constructors once.
534             return Err(ParseError::Continue);
535         }
536 
537         if is_method || is_constructor || is_destructor {
538             let is_const = is_method && cursor.method_is_const();
539             let is_virtual = is_method && cursor.method_is_virtual();
540             let is_static = is_method && cursor.method_is_static();
541             if !is_static && !is_virtual {
542                 let parent = cursor.semantic_parent();
543                 let class = Item::parse(parent, None, ctx)
544                     .expect("Expected to parse the class");
545                 // The `class` most likely is not finished parsing yet, so use
546                 // the unchecked variant.
547                 let class = class.as_type_id_unchecked();
548 
549                 let class = if is_const {
550                     let const_class_id = ctx.next_item_id();
551                     ctx.build_const_wrapper(
552                         const_class_id,
553                         class,
554                         None,
555                         &parent.cur_type(),
556                     )
557                 } else {
558                     class
559                 };
560 
561                 let ptr =
562                     Item::builtin_type(TypeKind::Pointer(class), false, ctx);
563                 args.insert(0, (Some("this".into()), ptr));
564             } else if is_virtual {
565                 let void = Item::builtin_type(TypeKind::Void, false, ctx);
566                 let ptr =
567                     Item::builtin_type(TypeKind::Pointer(void), false, ctx);
568                 args.insert(0, (Some("this".into()), ptr));
569             }
570         }
571 
572         let ty_ret_type = if kind == CXCursor_ObjCInstanceMethodDecl ||
573             kind == CXCursor_ObjCClassMethodDecl
574         {
575             ty.ret_type()
576                 .or_else(|| cursor.ret_type())
577                 .ok_or(ParseError::Continue)?
578         } else {
579             ty.ret_type().ok_or(ParseError::Continue)?
580         };
581 
582         let ret = if is_constructor && ctx.is_target_wasm32() {
583             // Constructors in Clang wasm32 target return a pointer to the object
584             // being constructed.
585             let void = Item::builtin_type(TypeKind::Void, false, ctx);
586             Item::builtin_type(TypeKind::Pointer(void), false, ctx)
587         } else {
588             Item::from_ty_or_ref(ty_ret_type, cursor, None, ctx)
589         };
590 
591         // Clang plays with us at "find the calling convention", see #549 and
592         // co. This seems to be a better fix than that commit.
593         let mut call_conv = ty.call_conv();
594         if let Some(ty) = cursor.cur_type().canonical_type().pointee_type() {
595             let cursor_call_conv = ty.call_conv();
596             if cursor_call_conv != CXCallingConv_Invalid {
597                 call_conv = cursor_call_conv;
598             }
599         }
600 
601         let abi = get_abi(call_conv);
602 
603         if abi.is_unknown() {
604             warn!("Unknown calling convention: {:?}", call_conv);
605         }
606 
607         Ok(Self {
608             name: spelling,
609             return_type: ret,
610             argument_types: args,
611             is_variadic: ty.is_variadic(),
612             is_divergent,
613             must_use,
614             abi,
615         })
616     }
617 
618     /// Get this function signature's return type.
return_type(&self) -> TypeId619     pub(crate) fn return_type(&self) -> TypeId {
620         self.return_type
621     }
622 
623     /// Get this function signature's argument (name, type) pairs.
argument_types(&self) -> &[(Option<String>, TypeId)]624     pub(crate) fn argument_types(&self) -> &[(Option<String>, TypeId)] {
625         &self.argument_types
626     }
627 
628     /// Get this function signature's ABI.
abi( &self, ctx: &BindgenContext, name: Option<&str>, ) -> crate::codegen::error::Result<ClangAbi>629     pub(crate) fn abi(
630         &self,
631         ctx: &BindgenContext,
632         name: Option<&str>,
633     ) -> crate::codegen::error::Result<ClangAbi> {
634         // FIXME (pvdrz): Try to do this check lazily instead. Maybe store the ABI inside `ctx`
635         // instead?.
636         let abi = if let Some(name) = name {
637             if let Some((abi, _)) = ctx
638                 .options()
639                 .abi_overrides
640                 .iter()
641                 .find(|(_, regex_set)| regex_set.matches(name))
642             {
643                 ClangAbi::Known(*abi)
644             } else {
645                 self.abi
646             }
647         } else if let Some((abi, _)) = ctx
648             .options()
649             .abi_overrides
650             .iter()
651             .find(|(_, regex_set)| regex_set.matches(&self.name))
652         {
653             ClangAbi::Known(*abi)
654         } else {
655             self.abi
656         };
657 
658         match abi {
659             ClangAbi::Known(Abi::ThisCall)
660                 if !ctx.options().rust_features().thiscall_abi =>
661             {
662                 Err(crate::codegen::error::Error::UnsupportedAbi("thiscall"))
663             }
664             ClangAbi::Known(Abi::Vectorcall)
665                 if !ctx.options().rust_features().vectorcall_abi =>
666             {
667                 Err(crate::codegen::error::Error::UnsupportedAbi("vectorcall"))
668             }
669             ClangAbi::Known(Abi::CUnwind)
670                 if !ctx.options().rust_features().c_unwind_abi =>
671             {
672                 Err(crate::codegen::error::Error::UnsupportedAbi("C-unwind"))
673             }
674             ClangAbi::Known(Abi::EfiApi)
675                 if !ctx.options().rust_features().abi_efiapi =>
676             {
677                 Err(crate::codegen::error::Error::UnsupportedAbi("efiapi"))
678             }
679             ClangAbi::Known(Abi::Win64) if self.is_variadic() => {
680                 Err(crate::codegen::error::Error::UnsupportedAbi("Win64"))
681             }
682             abi => Ok(abi),
683         }
684     }
685 
686     /// Is this function signature variadic?
is_variadic(&self) -> bool687     pub(crate) fn is_variadic(&self) -> bool {
688         // Clang reports some functions as variadic when they *might* be
689         // variadic. We do the argument check because rust doesn't codegen well
690         // variadic functions without an initial argument.
691         self.is_variadic && !self.argument_types.is_empty()
692     }
693 
694     /// Must this function's return value be used?
must_use(&self) -> bool695     pub(crate) fn must_use(&self) -> bool {
696         self.must_use
697     }
698 
699     /// Are function pointers with this signature able to derive Rust traits?
700     /// Rust only supports deriving traits for function pointers with a limited
701     /// number of parameters and a couple ABIs.
702     ///
703     /// For more details, see:
704     ///
705     /// * <https://github.com/rust-lang/rust-bindgen/issues/547>,
706     /// * <https://github.com/rust-lang/rust/issues/38848>,
707     /// * and <https://github.com/rust-lang/rust/issues/40158>
function_pointers_can_derive(&self) -> bool708     pub(crate) fn function_pointers_can_derive(&self) -> bool {
709         if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT {
710             return false;
711         }
712 
713         matches!(self.abi, ClangAbi::Known(Abi::C) | ClangAbi::Unknown(..))
714     }
715 
716     /// Whether this function has attributes marking it as divergent.
is_divergent(&self) -> bool717     pub(crate) fn is_divergent(&self) -> bool {
718         self.is_divergent
719     }
720 }
721 
722 impl ClangSubItemParser for Function {
parse( cursor: clang::Cursor, context: &mut BindgenContext, ) -> Result<ParseResult<Self>, ParseError>723     fn parse(
724         cursor: clang::Cursor,
725         context: &mut BindgenContext,
726     ) -> Result<ParseResult<Self>, ParseError> {
727         use clang_sys::*;
728 
729         let kind = match FunctionKind::from_cursor(&cursor) {
730             None => return Err(ParseError::Continue),
731             Some(k) => k,
732         };
733 
734         debug!("Function::parse({:?}, {:?})", cursor, cursor.cur_type());
735         let visibility = cursor.visibility();
736         if visibility != CXVisibility_Default {
737             return Err(ParseError::Continue);
738         }
739 
740         if cursor.access_specifier() == CX_CXXPrivate {
741             return Err(ParseError::Continue);
742         }
743 
744         let linkage = cursor.linkage();
745         let linkage = match linkage {
746             CXLinkage_External | CXLinkage_UniqueExternal => Linkage::External,
747             CXLinkage_Internal => Linkage::Internal,
748             _ => return Err(ParseError::Continue),
749         };
750 
751         if cursor.is_inlined_function() ||
752             cursor
753                 .definition()
754                 .map_or(false, |x| x.is_inlined_function())
755         {
756             if !context.options().generate_inline_functions &&
757                 !context.options().wrap_static_fns
758             {
759                 return Err(ParseError::Continue);
760             }
761 
762             if cursor.is_deleted_function() {
763                 return Err(ParseError::Continue);
764             }
765 
766             // We cannot handle `inline` functions that are not `static`.
767             if context.options().wrap_static_fns &&
768                 cursor.is_inlined_function() &&
769                 matches!(linkage, Linkage::External)
770             {
771                 return Err(ParseError::Continue);
772             }
773         }
774 
775         // Grab the signature using Item::from_ty.
776         let sig = Item::from_ty(&cursor.cur_type(), cursor, None, context)?;
777 
778         let mut name = cursor.spelling();
779         assert!(!name.is_empty(), "Empty function name?");
780 
781         if cursor.kind() == CXCursor_Destructor {
782             // Remove the leading `~`. The alternative to this is special-casing
783             // code-generation for destructor functions, which seems less than
784             // ideal.
785             if name.starts_with('~') {
786                 name.remove(0);
787             }
788 
789             // Add a suffix to avoid colliding with constructors. This would be
790             // technically fine (since we handle duplicated functions/methods),
791             // but seems easy enough to handle it here.
792             name.push_str("_destructor");
793         }
794         if let Some(nm) = context.options().last_callback(|callbacks| {
795             callbacks.generated_name_override(ItemInfo {
796                 name: name.as_str(),
797                 kind: ItemKind::Function,
798             })
799         }) {
800             name = nm;
801         }
802         assert!(!name.is_empty(), "Empty function name.");
803 
804         let mangled_name = cursor_mangling(context, &cursor);
805 
806         let link_name = context.options().last_callback(|callbacks| {
807             callbacks.generated_link_name_override(ItemInfo {
808                 name: name.as_str(),
809                 kind: ItemKind::Function,
810             })
811         });
812 
813         let function = Self::new(
814             name.clone(),
815             mangled_name,
816             link_name,
817             sig,
818             kind,
819             linkage,
820         );
821 
822         Ok(ParseResult::New(function, Some(cursor)))
823     }
824 }
825 
826 impl Trace for FunctionSig {
827     type Extra = ();
828 
trace<T>(&self, _: &BindgenContext, tracer: &mut T, _: &()) where T: Tracer,829     fn trace<T>(&self, _: &BindgenContext, tracer: &mut T, _: &())
830     where
831         T: Tracer,
832     {
833         tracer.visit_kind(self.return_type().into(), EdgeKind::FunctionReturn);
834 
835         for &(_, ty) in self.argument_types() {
836             tracer.visit_kind(ty.into(), EdgeKind::FunctionParameter);
837         }
838     }
839 }
840