1 //! Common traits and types related to parsing our IR from Clang cursors. 2 3 use crate::clang; 4 use crate::ir::context::{BindgenContext, ItemId, TypeId}; 5 use crate::ir::ty::TypeKind; 6 7 /// Not so much an error in the traditional sense, but a control flow message 8 /// when walking over Clang's AST with a cursor. 9 #[derive(Debug)] 10 pub enum ParseError { 11 /// Recurse down the current AST node's children. 12 Recurse, 13 /// Continue on to the next sibling AST node, or back up to the parent's 14 /// siblings if we've exhausted all of this node's siblings (and so on). 15 Continue, 16 } 17 18 /// The result of parsing a Clang AST node. 19 #[derive(Debug)] 20 pub enum ParseResult<T> { 21 /// We've already resolved this item before, here is the extant `ItemId` for 22 /// it. 23 AlreadyResolved(ItemId), 24 25 /// This is a newly parsed item. If the cursor is `Some`, it points to the 26 /// AST node where the new `T` was declared. 27 New(T, Option<clang::Cursor>), 28 } 29 30 /// An intermediate representation "sub-item" (i.e. one of the types contained 31 /// inside an `ItemKind` variant) that can be parsed from a Clang cursor. 32 pub trait ClangSubItemParser: Sized { 33 /// Attempt to parse this type from the given cursor. 34 /// 35 /// The fact that is a reference guarantees it's held by the context, and 36 /// allow returning already existing types. parse( cursor: clang::Cursor, context: &mut BindgenContext, ) -> Result<ParseResult<Self>, ParseError>37 fn parse( 38 cursor: clang::Cursor, 39 context: &mut BindgenContext, 40 ) -> Result<ParseResult<Self>, ParseError>; 41 } 42 43 /// An intermediate representation item that can be parsed from a Clang cursor. 44 pub trait ClangItemParser: Sized { 45 /// Parse this item from the given Clang cursor. parse( cursor: clang::Cursor, parent: Option<ItemId>, context: &mut BindgenContext, ) -> Result<ItemId, ParseError>46 fn parse( 47 cursor: clang::Cursor, 48 parent: Option<ItemId>, 49 context: &mut BindgenContext, 50 ) -> Result<ItemId, ParseError>; 51 52 /// Parse this item from the given Clang type. from_ty( ty: &clang::Type, location: clang::Cursor, parent: Option<ItemId>, ctx: &mut BindgenContext, ) -> Result<TypeId, ParseError>53 fn from_ty( 54 ty: &clang::Type, 55 location: clang::Cursor, 56 parent: Option<ItemId>, 57 ctx: &mut BindgenContext, 58 ) -> Result<TypeId, ParseError>; 59 60 /// Identical to `from_ty`, but use the given `id` as the `ItemId` for the 61 /// newly parsed item. from_ty_with_id( id: ItemId, ty: &clang::Type, location: clang::Cursor, parent: Option<ItemId>, ctx: &mut BindgenContext, ) -> Result<TypeId, ParseError>62 fn from_ty_with_id( 63 id: ItemId, 64 ty: &clang::Type, 65 location: clang::Cursor, 66 parent: Option<ItemId>, 67 ctx: &mut BindgenContext, 68 ) -> Result<TypeId, ParseError>; 69 70 /// Parse this item from the given Clang type, or if we haven't resolved all 71 /// the other items this one depends on, an unresolved reference. from_ty_or_ref( ty: clang::Type, location: clang::Cursor, parent_id: Option<ItemId>, context: &mut BindgenContext, ) -> TypeId72 fn from_ty_or_ref( 73 ty: clang::Type, 74 location: clang::Cursor, 75 parent_id: Option<ItemId>, 76 context: &mut BindgenContext, 77 ) -> TypeId; 78 79 /// Identical to `from_ty_or_ref`, but use the given `potential_id` as the 80 /// `ItemId` for the newly parsed item. from_ty_or_ref_with_id( potential_id: ItemId, ty: clang::Type, location: clang::Cursor, parent_id: Option<ItemId>, context: &mut BindgenContext, ) -> TypeId81 fn from_ty_or_ref_with_id( 82 potential_id: ItemId, 83 ty: clang::Type, 84 location: clang::Cursor, 85 parent_id: Option<ItemId>, 86 context: &mut BindgenContext, 87 ) -> TypeId; 88 89 /// Create a named template type. type_param( with_id: Option<ItemId>, location: clang::Cursor, ctx: &mut BindgenContext, ) -> Option<TypeId>90 fn type_param( 91 with_id: Option<ItemId>, 92 location: clang::Cursor, 93 ctx: &mut BindgenContext, 94 ) -> Option<TypeId>; 95 96 /// Create a builtin type. builtin_type( kind: TypeKind, is_const: bool, context: &mut BindgenContext, ) -> TypeId97 fn builtin_type( 98 kind: TypeKind, 99 is_const: bool, 100 context: &mut BindgenContext, 101 ) -> TypeId; 102 } 103