summaryrefslogtreecommitdiff
path: root/src/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.rs')
-rw-r--r--src/parser.rs86
1 files changed, 49 insertions, 37 deletions
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 {