diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gen.rs | 19 | ||||
-rw-r--r-- | src/parser.rs | 86 | ||||
-rw-r--r-- | src/types.rs | 13 |
3 files changed, 74 insertions, 44 deletions
@@ -1242,10 +1242,24 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item> _ => unreachable!() } } - if mangledlist.len() > 0 { - items.push(mk_extern(ctx, &vec![], mangledlist, Abi::C)); + if !mangledlist.is_empty() { + items.push(mk_extern(ctx, &[], mangledlist, Abi::C)); items.push(mk_impl(ctx, id_ty, unmangledlist)); } + + if !ci.vars.is_empty() { + let vars = ci.vars.into_iter().map(|v| { + let vi = v.varinfo(); + let v = vi.borrow_mut(); + let mut var_name = v.name.clone(); + if !v.mangled.is_empty() { + var_name = format!("{}_consts_{}", name, v.name); + } + cvar_to_rs(ctx, var_name, v.mangled.clone(), &v.ty, v.is_const) + }).collect(); + + items.push(mk_extern(ctx, &[], vars, Abi::C)); + } items } @@ -2301,6 +2315,7 @@ fn gen_union_field_definitions_if_necessary(ctx: &mut GenCtx, mut root_mod: &mut let union_fields_decl = quote_item!(&ctx.ext_cx, #[derive(Copy, Debug)] + #[repr(C)] pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>); ).unwrap(); diff --git a/src/parser.rs b/src/parser.rs index 0a40a13e..aa6fcbdb 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -37,6 +37,7 @@ struct ClangParserCtx<'a> { builtin_defs: Vec<Cursor>, module_map: ModuleMap, current_module_id: ModuleId, + current_translation_unit: TranslationUnit, logger: &'a (Logger+'a), err_count: i32, anonymous_modules_found: usize, @@ -185,8 +186,15 @@ fn decl_name(ctx: &mut ClangParserCtx, cursor: &Cursor) -> Global { } CXCursor_VarDecl => { let mangled = cursor.mangling(); - let vi = Rc::new(RefCell::new(VarInfo::new(spelling, mangled, comment, TVoid))); - GVar(vi) + let is_const = ty.is_const(); + let ty = conv_ty_resolving_typedefs(ctx, &ty, &cursor, true); + let mut vi = VarInfo::new(spelling, mangled, comment, ty); + vi.is_const = is_const; + cursor.visit(|c, _: &Cursor| { + vi.val = visit_literal(c, &ctx.current_translation_unit); + CXChildVisit_Continue + }); + GVar(Rc::new(RefCell::new(vi))) } CXCursor_MacroDefinition => { let vi = Rc::new(RefCell::new(VarInfo::new(spelling, String::new(), comment, TVoid))); @@ -972,13 +980,26 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor, cursor.location()), false); ci.has_non_type_template_params = true; } + CXCursor_VarDecl => { + let linkage = cursor.linkage(); + if linkage != CXLinkage_External && linkage != CXLinkage_UniqueExternal { + return CXChildVisit_Continue; + } + + let visibility = cursor.visibility(); + if visibility != CXVisibility_Default { + return CXChildVisit_Continue; + } + + let var = decl_name(ctx, cursor); + ci.vars.push(var); + } // Intentionally not handled CXCursor_CXXAccessSpecifier | CXCursor_CXXFinalAttr | CXCursor_Constructor | CXCursor_FunctionTemplate | - CXCursor_ConversionFunction | - CXCursor_VarDecl => {} + CXCursor_ConversionFunction => {} _ => { // XXX: Some kind of warning would be nice, but this produces far // too many. @@ -1035,8 +1056,7 @@ fn visit_literal(cursor: &Cursor, unit: &TranslationUnit) -> Option<i64> { } fn visit_top(cursor: &Cursor, - mut ctx: &mut ClangParserCtx, - unit: &TranslationUnit) -> Enum_CXVisitorResult { + mut ctx: &mut ClangParserCtx) -> Enum_CXVisitorResult { if !match_pattern(ctx, cursor) { return CXChildVisit_Continue; } @@ -1194,17 +1214,8 @@ fn visit_top(cursor: &Cursor, if visibility != CXVisibility_Default { return CXChildVisit_Continue; } - let ty = conv_ty(ctx, &cursor.cur_type(), cursor); - let var = decl_name(ctx, cursor); - let vi = var.varinfo(); - let mut vi = vi.borrow_mut(); - vi.ty = ty.clone(); - vi.is_const = cursor.cur_type().is_const(); - cursor.visit(|c, _: &Cursor| { - vi.val = visit_literal(c, unit); - CXChildVisit_Continue - }); - ctx.current_module_mut().globals.push(var); + let val = decl_name(ctx, cursor); + ctx.current_module_mut().globals.push(val); CXChildVisit_Continue } @@ -1255,7 +1266,7 @@ fn visit_top(cursor: &Cursor, return CXChildVisit_Recurse; } - let namespace_name = match unit.tokens(cursor) { + let namespace_name = match ctx.current_translation_unit.tokens(cursor) { None => None, Some(tokens) => { if tokens.len() <= 1 { @@ -1292,13 +1303,13 @@ fn visit_top(cursor: &Cursor, let previous_id = ctx.current_module_id; ctx.current_module_id = mod_id; - cursor.visit(|cur, _: &Cursor| visit_top(cur, &mut ctx, &unit)); + cursor.visit(|cur, _: &Cursor| visit_top(cur, &mut ctx)); ctx.current_module_id = previous_id; return CXChildVisit_Continue; } CXCursor_MacroDefinition => { - let val = parse_int_literal_tokens(cursor, unit, 1); + let val = parse_int_literal_tokens(cursor, &ctx.current_translation_unit, 1); if val.is_none() { // Not an integer literal. return CXChildVisit_Continue; @@ -1334,12 +1345,25 @@ fn log_err_warn(ctx: &mut ClangParserCtx, msg: &str, is_err: bool) { } pub fn parse(options: ClangParserOptions, logger: &Logger) -> Result<ModuleMap, ()> { + let ix = cx::Index::create(false, true); + if ix.is_null() { + logger.error("Clang failed to create index"); + return Err(()) + } + + let unit = TranslationUnit::parse(&ix, "", &options.clang_args, &[], CXTranslationUnit_DetailedPreprocessingRecord); + if unit.is_null() { + logger.error("No input files given"); + return Err(()) + } + let mut ctx = ClangParserCtx { options: options, name: HashMap::new(), builtin_defs: vec!(), module_map: ModuleMap::new(), current_module_id: ROOT_MODULE_ID, + current_translation_unit: unit, logger: logger, err_count: 0, anonymous_modules_found: 0, @@ -1347,19 +1371,7 @@ pub fn parse(options: ClangParserOptions, logger: &Logger) -> Result<ModuleMap, ctx.module_map.insert(ROOT_MODULE_ID, Module::new("root".to_owned(), None)); - let ix = cx::Index::create(false, true); - if ix.is_null() { - ctx.logger.error("Clang failed to create index"); - return Err(()) - } - - let unit = TranslationUnit::parse(&ix, "", &ctx.options.clang_args[..], &[], CXTranslationUnit_DetailedPreprocessingRecord); - if unit.is_null() { - ctx.logger.error("No input files given"); - return Err(()) - } - - let diags = unit.diags(); + let diags = ctx.current_translation_unit.diags(); for d in &diags { let msg = d.format(Diagnostic::default_opts()); let is_err = d.severity() >= CXDiagnostic_Error; @@ -1370,20 +1382,20 @@ pub fn parse(options: ClangParserOptions, logger: &Logger) -> Result<ModuleMap, return Err(()) } - let cursor = unit.cursor(); + let cursor = ctx.current_translation_unit.cursor(); if ctx.options.emit_ast { cursor.visit(|cur, _: &Cursor| ast_dump(cur, 0)); } - cursor.visit(|cur, _: &Cursor| visit_top(cur, &mut ctx, &unit)); + cursor.visit(|cur, _: &Cursor| visit_top(cur, &mut ctx)); while !ctx.builtin_defs.is_empty() { let c = ctx.builtin_defs.remove(0); - visit_top(&c.definition(), &mut ctx, &unit); + visit_top(&c.definition(), &mut ctx); } - unit.dispose(); + ctx.current_translation_unit.dispose(); ix.dispose(); if ctx.err_count > 0 { diff --git a/src/types.rs b/src/types.rs index 15849db9..7d65c7d0 100644 --- a/src/types.rs +++ b/src/types.rs @@ -55,7 +55,7 @@ impl Module { } } -#[derive(Clone)] +#[derive(Clone, PartialEq)] pub enum Global { GType(Rc<RefCell<TypeInfo>>), GComp(Rc<RefCell<CompInfo>>), @@ -435,6 +435,8 @@ pub struct CompInfo { pub has_non_type_template_params: bool, /// If this type was unnamed when parsed pub was_unnamed: bool, + /// Set of static vars declared inside this class. + pub vars: Vec<Global>, /// Used to detect if we've run in a can_derive_debug cycle while /// cycling around the template arguments. detect_derive_debug_cycle: Cell<bool>, @@ -467,9 +469,9 @@ impl CompInfo { filename: filename, comment: comment, members: members, - args: vec!(), - methods: vec!(), - vmethods: vec!(), + args: vec![], + methods: vec![], + vmethods: vec![], ref_template: None, has_vtable: false, has_destructor: false, @@ -479,7 +481,8 @@ impl CompInfo { opaque: false, base_members: 0, layout: layout, - typedefs: vec!(), + typedefs: vec![], + vars: vec![], has_non_type_template_params: false, was_unnamed: was_unnamed, detect_derive_debug_cycle: Cell::new(false), |