Skip to content

Document the parse module #156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ir/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ impl ClangItemParser for Item {
}

/// Parse a C++ type. If we find a reference to a type that has not been
/// defined yet, use UnresolvedTypeRef as a placeholder.
/// defined yet, use `UnresolvedTypeRef` as a placeholder.
///
/// This logic is needed to avoid parsing items with the incorrect parent
/// and it's sort of complex to explain, so I'll just point to
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ macro_rules! doc_mod {
mod clangll;
doc_mod!(clang);
doc_mod!(ir);
mod parse;
doc_mod!(parse);
mod regex_set;

mod codegen {
Expand Down
55 changes: 46 additions & 9 deletions src/parse.rs
Original file line number Diff line number Diff line change
@@ -1,53 +1,90 @@
//! Common traits and types related to parsing our IR from Clang cursors.

use clang;
use ir::ty::TypeKind;
use ir::item::ItemId;
use ir::context::BindgenContext;

/// Not so much an error in the traditional sense, but a control flow message
/// when walking over Clang's AST with a cursor.
#[derive(Debug)]
pub enum ParseError {
/// Recurse down the current AST node's children.
Recurse,
/// Continue on to the next sibling AST node, or back up to the parent's
/// siblings if we've exhausted all of this node's siblings (and so on).
Continue,
}

/// The result of parsing a Clang AST node.
#[derive(Debug)]
pub enum ParseResult<T> {
/// We've already resolved this item before, here is the extant `ItemId` for
/// it.
AlreadyResolved(ItemId),

/// This is a newly parsed item. If the cursor is `Some`, it points to the
/// AST node where the new `T` was declared.
New(T, Option<clang::Cursor>),
}

/// An intermediate representation "sub-item" (i.e. one of the types contained
/// inside an `ItemKind` variant) that can be parsed from a Clang cursor.
pub trait ClangSubItemParser : Sized {
/// Attempt to parse this type from the given cursor.
///
/// The fact that is a reference guarantees it's held by the context, and
/// allow returning already existing types.
fn parse(cursor: clang::Cursor, context: &mut BindgenContext) -> Result<ParseResult<Self>, ParseError>;
}

/// An intermediate representation item that can be parsed from a Clang cursor.
pub trait ClangItemParser: Sized {
/// Parse this item from the given Clang cursor.
fn parse(cursor: clang::Cursor,
parent: Option<ItemId>,
context: &mut BindgenContext) -> Result<ItemId, ParseError>;

/// Parse this item from the given Clang type.
fn from_ty(ty: &clang::Type,
location: Option<clang::Cursor>,
parent: Option<ItemId>,
ctx: &mut BindgenContext) -> Result<ItemId, ParseError>;

/// Identical to `from_ty`, but use the given `id` as the `ItemId` for the
/// newly parsed item.
fn from_ty_with_id(id: ItemId,
ty: &clang::Type,
location: Option<clang::Cursor>,
parent: Option<ItemId>,
ctx: &mut BindgenContext) -> Result<ItemId, ParseError>;

/// Parse this item from the given Clang type, or if we haven't resolved all
/// the other items this one depends on, an unresolved reference.
fn from_ty_or_ref(ty: clang::Type,
location: Option<clang::Cursor>,
parent_id: Option<ItemId>,
context: &mut BindgenContext) -> ItemId;

/// Identical to `from_ty_or_ref`, but use the given `potential_id` as the
/// `ItemId` for the newly parsed item.
fn from_ty_or_ref_with_id(potential_id: ItemId,
ty: clang::Type,
location: Option<clang::Cursor>,
parent_id: Option<ItemId>,
context: &mut BindgenContext) -> ItemId;
fn from_ty_with_id(id: ItemId,
ty: &clang::Type,
location: Option<clang::Cursor>,
parent: Option<ItemId>,
ctx: &mut BindgenContext) -> Result<ItemId, ParseError>;
fn from_ty(ty: &clang::Type,
location: Option<clang::Cursor>,
parent: Option<ItemId>,
ctx: &mut BindgenContext) -> Result<ItemId, ParseError>;

/// Create a named template type.
fn named_type<S>(name: S, default: Option<ItemId>, parent: ItemId,
context: &mut BindgenContext) -> ItemId
where S: Into<String>;

/// Identical to `named_type`, but use `id` as the resulting item's
/// `ItemId`.
fn named_type_with_id<S>(id: ItemId, name: S, default: Option<ItemId>,
parent: ItemId, context: &mut BindgenContext) -> ItemId
where S: Into<String>;

/// Create a builtin type.
fn builtin_type(kind: TypeKind, is_const: bool, context: &mut BindgenContext) -> ItemId;
}