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