From 3dd697c9bd58ecf3ccd5003fb6952d807972f1b8 Mon Sep 17 00:00:00 2001 From: Alex Chandel Date: Fri, 4 Jul 2014 22:00:44 -0500 Subject: Build libbindgen and bindgen with Cargo --- .gitignore | 5 +- Cargo.toml | 11 + bindgen.rs | 192 -------- clang.rs | 698 ----------------------------- clangll.rs | 1357 -------------------------------------------------------- gen.rs | 920 -------------------------------------- lib.rs | 110 ----- macro.rs | 319 ------------- parser.rs | 480 -------------------- src/bindgen.rs | 192 ++++++++ src/clang.rs | 698 +++++++++++++++++++++++++++++ src/clangll.rs | 1357 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/gen.rs | 920 ++++++++++++++++++++++++++++++++++++++ src/lib.rs | 110 +++++ src/macro.rs | 319 +++++++++++++ src/parser.rs | 480 ++++++++++++++++++++ src/types.rs | 269 +++++++++++ types.rs | 269 ----------- 18 files changed, 4360 insertions(+), 4346 deletions(-) create mode 100644 Cargo.toml delete mode 100644 bindgen.rs delete mode 100644 clang.rs delete mode 100644 clangll.rs delete mode 100644 gen.rs delete mode 100644 lib.rs delete mode 100644 macro.rs delete mode 100644 parser.rs create mode 100644 src/bindgen.rs create mode 100644 src/clang.rs create mode 100644 src/clangll.rs create mode 100644 src/gen.rs create mode 100644 src/lib.rs create mode 100644 src/macro.rs create mode 100644 src/parser.rs create mode 100644 src/types.rs delete mode 100644 types.rs diff --git a/.gitignore b/.gitignore index d767cda6..9ab3f496 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ bindgen -libbindgen* \ No newline at end of file +libbindgen* + +# Cargo +target/ diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..e2d5cd03 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "rust-bindgen" +version = "0.0.0" +authors = [ "crabtw" ] + +[[lib]] +name = "bindgen" +path = "src/lib.rs" + +[[bin]] +name = "bindgen" diff --git a/bindgen.rs b/bindgen.rs deleted file mode 100644 index 8e46057b..00000000 --- a/bindgen.rs +++ /dev/null @@ -1,192 +0,0 @@ -#![crate_id = "bindgen"] -#![crate_type = "bin"] -#![feature(phase)] - -extern crate bindgen; -#[phase(plugin, link)] extern crate log; -extern crate syntax; - -use bindgen::{Logger, generate_bindings, BindgenOptions}; -use std::{io, os, path}; -use std::default::Default; -use std::io::{fs, IoResult}; -use syntax::ast; -use syntax::codemap::DUMMY_SP; -use syntax::print::pprust; -use syntax::print::pp::eof; - -struct StdLogger; - -impl Logger for StdLogger { - fn error(&self, msg: &str) { - error!("{}", msg); - } - - fn warn(&self, msg: &str) { - warn!("{}", msg); - } -} - -enum ParseResult { - CmdUsage, - ParseOk(BindgenOptions, Box), - ParseErr(String) -} - -fn parse_args(args: &[String]) -> ParseResult { - let args_len = args.len(); - - let mut options: BindgenOptions = Default::default(); - let mut out = box io::BufferedWriter::new(io::stdout()) as Box; - - if args_len == 0u { - return CmdUsage; - } - - let mut ix = 0u; - while ix < args_len { - if args[ix].len() > 2 && args[ix].as_slice().slice_to(2) == "-l" { - options.links.push((args[ix].as_slice().slice_from(2).to_string(), None)); - ix += 1u; - } else { - match args[ix].as_slice() { - "--help" | "-h" => { - return CmdUsage; - } - "-emit-clang-ast" => { - options.emit_ast = true; - ix += 1u; - } - "-o" => { - if ix + 1u >= args_len { - return ParseErr("Missing output filename".to_string()); - } - let path = path::Path::new(args[ix + 1].clone()); - match fs::File::create(&path) { - Ok(f) => { out = box io::BufferedWriter::new(f) as Box; } - Err(_) => { return ParseErr(format!("Open {} failed", args[ix + 1])); } - } - ix += 2u; - } - "-l" => { - if ix + 1u >= args_len { - return ParseErr("Missing link name".to_string()); - } - options.links.push((args[ix + 1u].clone(), None)); - ix += 2u; - } - "-static-link" => { - if ix + 1u >= args_len { - return ParseErr("Missing link name".to_string()); - } - options.links.push((args[ix + 1u].clone(), Some("static".to_string()))); - ix += 2u; - } - "-framework-link" => { - if ix + 1u >= args_len { - return ParseErr("Missing link name".to_string()); - } - options.links.push((args[ix + 1u].clone(), Some("framework".to_string()))); - ix += 2u; - } - "-match" => { - if ix + 1u >= args_len { - return ParseErr("Missing match pattern".to_string()); - } - options.match_pat.push(args[ix + 1u].clone()); - ix += 2u; - } - "-builtins" => { - options.builtins = true; - ix += 1u; - } - "-abi" => { - options.abi = args[ix + 1u].clone(); - ix += 2u; - } - "-allow-bitfields" => { - options.fail_on_bitfield = false; - ix += 1u; - } - "-allow-unknown-types" => { - options.fail_on_unknown_type = false; - ix += 1u; - } - _ => { - options.clang_args.push(args[ix].clone()); - ix += 1u; - } - } - } - } - - return ParseOk(options, out); -} - -fn print_usage(bin: String) { - io::stdio::print(format!("Usage: {} [options] input.h", bin.as_slice()).append( -" -Options: - -h or --help Display help message - -l or -l Link to a dynamic library, can be proivded - multiple times - -static-link Link to a static library - -framework-link Link to a framework - -o Write bindings to (default stdout) - -match Only output bindings for definitions from files - whose name contains - If multiple -match options are provided, files - matching any rule are bound to. - -builtins Output bindings for builtin definitions - (for example __builtin_va_list) - -abi Indicate abi of extern functions (default C) - -allow-bitfields Don't fail if we encounter a bitfield - (note that bindgen does not support bitfields) - -allow-unknown-types Don't fail if we encounter types we do not support, - instead treat them as void - -emit-clang-ast Output the ast (for debugging purposes) - - Options other than stated above are passed to clang. -" - ).as_slice()); -} - -fn try_pprint(module: &ast::Mod, out: Box) -> IoResult<()> { - let mut ps = pprust::rust_printer(out); - try!(ps.s.out.write("/* automatically generated by rust-bindgen */\n\n".as_bytes())); - - try!(ps.print_mod(module, &[])); - try!(ps.print_remaining_comments()); - try!(eof(&mut ps.s)); - - ps.s.out.flush() -} - -#[main] -pub fn main() { - let mut bind_args = os::args(); - let bin = bind_args.shift().unwrap(); - - match parse_args(bind_args.as_slice()) { - ParseErr(e) => fail!(e), - CmdUsage => print_usage(bin), - ParseOk(options, out) => { - let logger = StdLogger; - match generate_bindings(options, Some(&logger as &Logger), DUMMY_SP) { - Ok(items) => { - let module = ast::Mod { - inner: DUMMY_SP, - view_items: Vec::new(), - items: items, - }; - - match try_pprint(&module, out) { - Err(e) => logger.error(format!("Unable to write bindings to file. {}", e).as_slice()), - _ => () - } - } - Err(_) => () - } - } - } -} diff --git a/clang.rs b/clang.rs deleted file mode 100644 index 16d090d0..00000000 --- a/clang.rs +++ /dev/null @@ -1,698 +0,0 @@ -#![allow(non_uppercase_pattern_statics)] - -use libc::{c_uint, c_char, c_int, c_ulong}; -use std::{mem, io, ptr, str}; -use std::fmt; -use std::hash::Hash; -use std::hash::sip::SipState; -use std::c_str::CString; - -pub use ll = clangll; -use clangll::*; - -// Cursor -pub struct Cursor { - x: CXCursor -} - -pub type CursorVisitor<'s> = |c: &Cursor, p: &Cursor|: 's -> Enum_CXChildVisitResult; - -impl Cursor { - // common - pub fn spelling(&self) -> String { - unsafe { - String_ { x: clang_getCursorSpelling(self.x) }.to_str() - } - } - - pub fn kind(&self) -> Enum_CXCursorKind { - unsafe { - clang_getCursorKind(self.x) - } - } - - pub fn location(&self) -> SourceLocation { - unsafe { - SourceLocation { x: clang_getCursorLocation(self.x) } - } - } - - pub fn cur_type(&self) -> Type { - unsafe { - Type { x: clang_getCursorType(self.x) } - } - } - - pub fn definition(&self) -> Cursor { - unsafe { - Cursor { x: clang_getCursorDefinition(self.x) } - } - } - - pub fn visit(&self, func: CursorVisitor) { - unsafe { - let data = mem::transmute::<&CursorVisitor, CXClientData>(&func); - clang_visitChildren(self.x, Some(visit_children), data); - }; - } - - // bitfield - pub fn bit_width(&self) -> Option { - unsafe { - let w = clang_getFieldDeclBitWidth(self.x); - if w == -1 { - None - } else { - Some(w as uint) - } - } - } - - // enum - pub fn enum_type(&self) -> Type { - unsafe { - Type { x: clang_getEnumDeclIntegerType(self.x) } - } - } - - pub fn enum_val(&self) -> i64 { - unsafe { - clang_getEnumConstantDeclValue(self.x) as i64 - } - } - - // typedef - pub fn typedef_type(&self) -> Type { - unsafe { - Type { x: clang_getTypedefDeclUnderlyingType(self.x) } - } - } - - // function, variable - pub fn linkage(&self) -> Enum_CXLinkageKind { - unsafe { - clang_getCursorLinkage(self.x) - } - } - - // function - pub fn args(&self) -> Vec { - unsafe { - let num = self.num_args() as uint; - let mut args = vec!(); - for i in range(0, num) { - args.push(Cursor { x: clang_Cursor_getArgument(self.x, i as c_uint) }); - } - return args; - } - } - - pub fn ret_type(&self) -> Type { - unsafe { - Type { x: clang_getCursorResultType(self.x) } - } - } - - pub fn num_args(&self) -> i32 { - unsafe { - clang_Cursor_getNumArguments(self.x) - } - } -} - -extern fn visit_children(cur: CXCursor, parent: ll::CXCursor, - data: CXClientData) -> ll::Enum_CXChildVisitResult { - unsafe { - let func = mem::transmute::(data); - return (*func)(&Cursor { x: cur }, &Cursor { x: parent }); - } -} - -impl PartialEq for Cursor { - fn eq(&self, other: &Cursor) -> bool { - unsafe { - clang_equalCursors(self.x, other.x) == 1 - } - } - - fn ne(&self, other: &Cursor) -> bool { - return !self.eq(other); - } -} - -impl Eq for Cursor {} - -impl Hash for Cursor { - fn hash(&self, state: &mut SipState) { - self.x.kind.hash(state); - self.x.xdata.hash(state); - self.x.data[0].hash(state); - self.x.data[1].hash(state); - self.x.data[2].hash(state); - } -} - -// type -pub struct Type { - x: CXType -} - -impl Type { - // common - pub fn kind(&self) -> Enum_CXTypeKind { - return self.x.kind; - } - - pub fn declaration(&self) -> Cursor { - unsafe { - Cursor { x: clang_getTypeDeclaration(self.x) } - } - } - - pub fn is_const(&self) -> bool { - unsafe { - clang_isConstQualifiedType(self.x) == 1 - } - } - - pub fn size(&self) -> uint { - unsafe { - let val = clang_Type_getSizeOf(self.x); - if val < 0 { 0 } else { val as uint } - } - } - - pub fn align(&self) -> uint { - unsafe { - let val = clang_Type_getAlignOf(self.x); - if val < 0 { 0 } else { val as uint } - } - } - - // pointer - pub fn pointee_type(&self) -> Type { - unsafe { - Type { x: clang_getPointeeType(self.x) } - } - } - - // array - pub fn elem_type(&self) -> Type { - unsafe { - Type { x: clang_getArrayElementType(self.x) } - } - } - - pub fn array_size(&self) -> uint { - unsafe { - clang_getArraySize(self.x) as uint - } - } - - // typedef - pub fn canonical_type(&self) -> Type { - unsafe { - Type { x: clang_getCanonicalType(self.x) } - } - } - - // function - pub fn is_variadic(&self) -> bool { - unsafe { - clang_isFunctionTypeVariadic(self.x) == 1 - } - } - - pub fn arg_types(&self) -> Vec { - unsafe { - let num = clang_getNumArgTypes(self.x) as uint; - let mut args = vec!(); - for i in range(0, num) { - args.push(Type { x: clang_getArgType(self.x, i as c_uint) }); - } - return args; - } - } - - pub fn ret_type(&self) -> Type { - unsafe { - Type { x: clang_getResultType(self.x) } - } - } -} - -// SourceLocation -pub struct SourceLocation { - x: CXSourceLocation -} - -impl SourceLocation { - pub fn location(&self) -> (File, uint, uint, uint) { - unsafe { - let mut file = ptr::mut_null(); - let mut line = 0; - let mut col = 0; - let mut off = 0; - clang_getSpellingLocation(self.x, &mut file, &mut line, &mut col, &mut off); - return (File { x: file }, line as uint, col as uint, off as uint); - } - } -} - -impl fmt::Show for SourceLocation { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let (file, line, col, _) = self.location(); - match file.is_null() { - false => { - try!(file.name().fmt(f)); - try!(":".fmt(f)); - try!(line.fmt(f)); - try!(":".fmt(f)); - col.fmt(f) - }, - true => "builtin definitions".fmt(f) - } - } -} - -// File -pub struct File { - x: CXFile -} - -impl File { - pub fn name(&self) -> String { - if self.is_null() { - return "".to_string(); - } - unsafe { - String_ { x: clang_getFileName(self.x) }.to_str() - } - } - - pub fn is_null(&self) -> bool { - self.x.is_null() - } -} - -// String -pub struct String_ { - x: CXString -} - -impl fmt::Show for String_ { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.x.data.is_null() { - return "".fmt(f); - } - unsafe { - let c_str = clang_getCString(self.x) as *const c_char; - str::raw::from_c_str(c_str).fmt(f) - } - } -} - -// Index -pub struct Index { - x: CXIndex -} - -impl Index { - pub fn create(pch: bool, diag: bool) -> Index { - unsafe { - Index { x: clang_createIndex(pch as c_int, diag as c_int) } - } - } - - pub fn dispose(&self) { - unsafe { - clang_disposeIndex(self.x); - } - } - - pub fn is_null(&self) -> bool { - self.x.is_null() - } -} - -// TranslationUnit -pub struct TranslationUnit { - x: CXTranslationUnit -} - -impl TranslationUnit { - pub fn parse(ix: &Index, file: &str, cmd_args: &[String], - unsaved: &[UnsavedFile], opts: uint) -> TranslationUnit { - let _fname = file.to_c_str(); - let fname = _fname.as_ptr(); - let _c_args: Vec = cmd_args.iter().map(|s| s.to_c_str()).collect(); - let c_args: Vec<*const c_char> = _c_args.iter().map(|s| s.as_ptr()).collect(); - let mut c_unsaved: Vec = unsaved.iter().map(|f| f.x).collect(); - let tu = unsafe { - clang_parseTranslationUnit(ix.x, fname, - c_args.as_ptr(), - c_args.len() as c_int, - c_unsaved.as_mut_ptr(), - c_unsaved.len() as c_uint, - opts as c_uint) - }; - TranslationUnit { x: tu } - } - - pub fn reparse(&self, unsaved: &[UnsavedFile], opts: uint) -> bool { - let mut c_unsaved: Vec = unsaved.iter().map(|f| f.x).collect(); - - unsafe { - clang_reparseTranslationUnit(self.x, - c_unsaved.len() as c_uint, - c_unsaved.as_mut_ptr(), - opts as c_uint) == 0 - } - } - - pub fn diags(&self) -> Vec { - unsafe { - let num = clang_getNumDiagnostics(self.x) as uint; - let mut diags = vec!(); - for i in range(0, num) { - diags.push(Diagnostic { x: clang_getDiagnostic(self.x, i as c_uint) }); - } - return diags; - } - } - - pub fn cursor(&self) -> Cursor { - unsafe { - Cursor { x: clang_getTranslationUnitCursor(self.x) } - } - } - - pub fn dispose(&self) { - unsafe { - clang_disposeTranslationUnit(self.x); - } - } - - pub fn is_null(&self) -> bool { - self.x.is_null() - } -} - -// Diagnostic -pub struct Diagnostic { - x: CXDiagnostic -} - -impl Diagnostic { - pub fn default_opts() -> uint { - unsafe { - clang_defaultDiagnosticDisplayOptions() as uint - } - } - - pub fn format(&self, opts: uint) -> String { - unsafe { - String_ { x: clang_formatDiagnostic(self.x, opts as c_uint) }.to_str() - } - } - - pub fn severity(&self) -> Enum_CXDiagnosticSeverity { - unsafe { - clang_getDiagnosticSeverity(self.x) - } - } - - pub fn dispose(&self) { - unsafe { - clang_disposeDiagnostic(self.x); - } - } -} - -// UnsavedFile -pub struct UnsavedFile { - x: Struct_CXUnsavedFile, - name: CString, - contents: CString -} - -impl UnsavedFile { - pub fn new(name: &str, contents: &str) -> UnsavedFile { - let name = name.to_c_str(); - let contents = contents.to_c_str(); - let x = Struct_CXUnsavedFile { - Filename: name.as_ptr(), - Contents: contents.as_ptr(), - Length: contents.len() as c_ulong, - }; - UnsavedFile { - x: x, - name: name, - contents: contents - } - } -} - -pub fn kind_to_str(x: Enum_CXCursorKind) -> &str { - match x { - CXCursor_UnexposedDecl => "UnexposedDecl", - CXCursor_StructDecl => "StructDecl", - CXCursor_UnionDecl => "UnionDecl", - CXCursor_ClassDecl => "ClassDecl", - CXCursor_EnumDecl => "EnumDecl", - CXCursor_FieldDecl => "FieldDecl", - CXCursor_EnumConstantDecl => "EnumConstantDecl", - CXCursor_FunctionDecl => "FunctionDecl", - CXCursor_VarDecl => "VarDecl", - CXCursor_ParmDecl => "ParmDecl", - CXCursor_ObjCInterfaceDecl => "ObjCInterfaceDecl", - CXCursor_ObjCCategoryDecl => "ObjCCategoryDecl", - CXCursor_ObjCProtocolDecl => "ObjCProtocolDecl", - CXCursor_ObjCPropertyDecl => "ObjCPropertyDecl", - CXCursor_ObjCIvarDecl => "ObjCIvarDecl", - CXCursor_ObjCInstanceMethodDecl => "ObjCInstanceMethodDecl", - CXCursor_ObjCClassMethodDecl => "ObjCClassMethodDecl", - CXCursor_ObjCImplementationDecl => "ObjCImplementationDecl", - CXCursor_ObjCCategoryImplDecl => "ObjCCategoryImplDecl", - CXCursor_TypedefDecl => "TypedefDecl", - CXCursor_CXXMethod => "CXXMethod", - CXCursor_Namespace => "Namespace", - CXCursor_LinkageSpec => "LinkageSpec", - CXCursor_Constructor => "Constructor", - CXCursor_Destructor => "Destructor", - CXCursor_ConversionFunction => "ConversionFunction", - CXCursor_TemplateTypeParameter => "TemplateTypeParameter", - CXCursor_NonTypeTemplateParameter => "NonTypeTemplateParameter", - CXCursor_TemplateTemplateParameter => "TemplateTemplateParameter", - CXCursor_FunctionTemplate => "FunctionTemplate", - CXCursor_ClassTemplate => "ClassTemplate", - CXCursor_ClassTemplatePartialSpecialization => "ClassTemplatePartialSpecialization", - CXCursor_NamespaceAlias => "NamespaceAlias", - CXCursor_UsingDirective => "UsingDirective", - CXCursor_UsingDeclaration => "UsingDeclaration", - CXCursor_TypeAliasDecl => "TypeAliasDecl", - CXCursor_ObjCSynthesizeDecl => "ObjCSynthesizeDecl", - CXCursor_ObjCDynamicDecl => "ObjCDynamicDecl", - CXCursor_CXXAccessSpecifier => "CXXAccessSpecifier", - // CXCursor_FirstDecl => "FirstDecl", - // CXCursor_LastDecl => "LastDecl", - CXCursor_FirstRef => "FirstRef", - // CXCursor_ObjCSuperClassRef => "ObjCSuperClassRef", - CXCursor_ObjCProtocolRef => "ObjCProtocolRef", - CXCursor_ObjCClassRef => "ObjCClassRef", - CXCursor_TypeRef => "TypeRef", - CXCursor_CXXBaseSpecifier => "CXXBaseSpecifier", - CXCursor_TemplateRef => "TemplateRef", - CXCursor_NamespaceRef => "NamespaceRef", - CXCursor_MemberRef => "MemberRef", - // CXCursor_LabelRef => "LabelRef", - CXCursor_OverloadedDeclRef => "OverloadedDeclRef", - CXCursor_VariableRef => "VariableRef", - // CXCursor_LastRef => "LastRef", - CXCursor_FirstInvalid => "FirstInvalid", - // CXCursor_InvalidFile => "InvalidFile", - CXCursor_NoDeclFound => "NoDeclFound", - CXCursor_NotImplemented => "NotImplemented", - CXCursor_InvalidCode => "InvalidCode", - // CXCursor_LastInvalid => "LastInvalid", - CXCursor_FirstExpr => "FirstExpr", - // CXCursor_UnexposedExpr => "UnexposedExpr", - CXCursor_DeclRefExpr => "DeclRefExpr", - CXCursor_MemberRefExpr => "MemberRefExpr", - CXCursor_CallExpr => "CallExpr", - CXCursor_ObjCMessageExpr => "ObjCMessageExpr", - CXCursor_BlockExpr => "BlockExpr", - CXCursor_IntegerLiteral => "IntegerLiteral", - CXCursor_FloatingLiteral => "FloatingLiteral", - CXCursor_ImaginaryLiteral => "ImaginaryLiteral", - CXCursor_StringLiteral => "StringLiteral", - CXCursor_CharacterLiteral => "CharacterLiteral", - CXCursor_ParenExpr => "ParenExpr", - CXCursor_UnaryOperator => "UnaryOperator", - CXCursor_ArraySubscriptExpr => "ArraySubscriptExpr", - CXCursor_BinaryOperator => "BinaryOperator", - CXCursor_CompoundAssignOperator => "CompoundAssignOperator", - CXCursor_ConditionalOperator => "ConditionalOperator", - CXCursor_CStyleCastExpr => "CStyleCastExpr", - CXCursor_CompoundLiteralExpr => "CompoundLiteralExpr", - CXCursor_InitListExpr => "InitListExpr", - CXCursor_AddrLabelExpr => "AddrLabelExpr", - CXCursor_StmtExpr => "StmtExpr", - CXCursor_GenericSelectionExpr => "GenericSelectionExpr", - CXCursor_GNUNullExpr => "GNUNullExpr", - CXCursor_CXXStaticCastExpr => "CXXStaticCastExpr", - CXCursor_CXXDynamicCastExpr => "CXXDynamicCastExpr", - CXCursor_CXXReinterpretCastExpr => "CXXReinterpretCastExpr", - CXCursor_CXXConstCastExpr => "CXXConstCastExpr", - CXCursor_CXXFunctionalCastExpr => "CXXFunctionalCastExpr", - CXCursor_CXXTypeidExpr => "CXXTypeidExpr", - CXCursor_CXXBoolLiteralExpr => "CXXBoolLiteralExpr", - CXCursor_CXXNullPtrLiteralExpr => "CXXNullPtrLiteralExpr", - CXCursor_CXXThisExpr => "CXXThisExpr", - CXCursor_CXXThrowExpr => "CXXThrowExpr", - CXCursor_CXXNewExpr => "CXXNewExpr", - CXCursor_CXXDeleteExpr => "CXXDeleteExpr", - CXCursor_UnaryExpr => "UnaryExpr", - CXCursor_ObjCStringLiteral => "ObjCStringLiteral", - CXCursor_ObjCEncodeExpr => "ObjCEncodeExpr", - CXCursor_ObjCSelectorExpr => "ObjCSelectorExpr", - CXCursor_ObjCProtocolExpr => "ObjCProtocolExpr", - CXCursor_ObjCBridgedCastExpr => "ObjCBridgedCastExpr", - CXCursor_PackExpansionExpr => "PackExpansionExpr", - CXCursor_SizeOfPackExpr => "SizeOfPackExpr", - CXCursor_LambdaExpr => "LambdaExpr", - CXCursor_ObjCBoolLiteralExpr => "ObjCBoolLiteralExpr", - // CXCursor_LastExpr => "LastExpr", - CXCursor_FirstStmt => "FirstStmt", - // CXCursor_UnexposedStmt => "UnexposedStmt", - CXCursor_LabelStmt => "LabelStmt", - CXCursor_CompoundStmt => "CompoundStmt", - CXCursor_CaseStmt => "CaseStmt", - CXCursor_DefaultStmt => "DefaultStmt", - CXCursor_IfStmt => "IfStmt", - CXCursor_SwitchStmt => "SwitchStmt", - CXCursor_WhileStmt => "WhileStmt", - CXCursor_DoStmt => "DoStmt", - CXCursor_ForStmt => "ForStmt", - CXCursor_GotoStmt => "GotoStmt", - CXCursor_IndirectGotoStmt => "IndirectGotoStmt", - CXCursor_ContinueStmt => "ContinueStmt", - CXCursor_BreakStmt => "BreakStmt", - CXCursor_ReturnStmt => "ReturnStmt", - CXCursor_AsmStmt => "AsmStmt", - CXCursor_ObjCAtTryStmt => "ObjCAtTryStmt", - CXCursor_ObjCAtCatchStmt => "ObjCAtCatchStmt", - CXCursor_ObjCAtFinallyStmt => "ObjCAtFinallyStmt", - CXCursor_ObjCAtThrowStmt => "ObjCAtThrowStmt", - CXCursor_ObjCAtSynchronizedStmt => "ObjCAtSynchronizedStmt", - CXCursor_ObjCAutoreleasePoolStmt => "ObjCAutoreleasePoolStmt", - CXCursor_ObjCForCollectionStmt => "ObjCForCollectionStmt", - CXCursor_CXXCatchStmt => "CXXCatchStmt", - CXCursor_CXXTryStmt => "CXXTryStmt", - CXCursor_CXXForRangeStmt => "CXXForRangeStmt", - CXCursor_SEHTryStmt => "SEHTryStmt", - CXCursor_SEHExceptStmt => "SEHExceptStmt", - CXCursor_SEHFinallyStmt => "SEHFinallyStmt", - CXCursor_NullStmt => "NullStmt", - CXCursor_DeclStmt => "DeclStmt", - // CXCursor_LastStmt => "LastStmt", - CXCursor_TranslationUnit => "TranslationUnit", - CXCursor_FirstAttr => "FirstAttr", - // CXCursor_UnexposedAttr => "UnexposedAttr", - CXCursor_IBActionAttr => "IBActionAttr", - CXCursor_IBOutletAttr => "IBOutletAttr", - CXCursor_IBOutletCollectionAttr => "IBOutletCollectionAttr", - CXCursor_CXXFinalAttr => "CXXFinalAttr", - CXCursor_CXXOverrideAttr => "CXXOverrideAttr", - CXCursor_AnnotateAttr => "AnnotateAttr", - CXCursor_AsmLabelAttr => "AsmLabelAttr", - // CXCursor_LastAttr => "LastAttr", - CXCursor_PreprocessingDirective => "PreprocessingDirective", - CXCursor_MacroDefinition => "MacroDefinition", - CXCursor_MacroExpansion => "MacroExpansion", - // CXCursor_MacroInstantiation => "MacroInstantiation", - CXCursor_InclusionDirective => "InclusionDirective", - //CXCursor_FirstPreprocessing => "FirstPreprocessing", - //CXCursor_LastPreprocessing => "LastPreprocessing", - - _ => "?", - } -} - -pub fn type_to_str(x: Enum_CXTypeKind) -> &str { - match x { - CXType_Invalid => "Invalid", - CXType_Unexposed => "Unexposed", - CXType_Void => "Void", - CXType_Bool => "Bool", - CXType_Char_U => "Char_U", - CXType_UChar => "UChar", - CXType_Char16=> "Char16", - CXType_Char32=> "Char32", - CXType_UShort => "UShort", - CXType_UInt => "UInt", - CXType_ULong => "ULong", - CXType_ULongLong => "ULongLong", - CXType_UInt128=>"UInt128", - CXType_Char_S => "Char_S", - CXType_SChar => "SChar", - CXType_WChar => "WChar", - CXType_Short => "Short", - CXType_Int => "Int", - CXType_Long => "Long", - CXType_LongLong => "LongLong", - CXType_Int128=>"Int128", - CXType_Float => "Float", - CXType_Double => "Double", - CXType_LongDouble => "LongDouble", - CXType_NullPtr => "NullPtr", - CXType_Overload => "Overload", - CXType_Dependent => "Dependent", - CXType_ObjCId => "ObjCId", - CXType_ObjCClass => "ObjCClass", - CXType_ObjCSel => "ObjCSel", - // CXType_FirstBuiltin => "FirstBuiltin", - // CXType_LastBuiltin => "LastBuiltin", - CXType_Complex => "Complex", - CXType_Pointer => "Pointer", - CXType_BlockPointer => "BlockPointer", - CXType_LValueReference => "LValueReference", - CXType_RValueReference => "RValueReference", - CXType_Record => "Record", - CXType_Enum => "Enum", - CXType_Typedef => "Typedef", - CXType_ObjCInterface => "ObjCInterface", - CXType_ObjCObjectPointer => "ObjCObjectPointer", - CXType_FunctionNoProto => "FunctionNoProto", - CXType_FunctionProto => "FunctionProto", - CXType_ConstantArray => "ConstantArray", - CXType_Vector => "Vector", - CXType_IncompleteArray => "IncompleteArray", - CXType_VariableArray => "VariableArray", - CXType_DependentSizedArray => "DependentSizedArray", - _ => "?" - } -} - -// Debug -pub fn ast_dump(c: &Cursor, depth: int)-> Enum_CXVisitorResult { - fn print_indent(depth: int, s: &str) { - let mut i = 0; - while i < depth { - io::print("\t"); - i += 1; - } - io::println(s); - } - let ct = c.cur_type().kind(); - print_indent(depth, format!("({} {} {}", - kind_to_str(c.kind()).as_slice(), - c.spelling().as_slice(), - type_to_str(ct)).as_slice() - ); - c.visit(|s, _| { - ast_dump(s, depth + 1) - }); - print_indent(depth, ")"); - return CXChildVisit_Continue; -} diff --git a/clangll.rs b/clangll.rs deleted file mode 100644 index 27261f83..00000000 --- a/clangll.rs +++ /dev/null @@ -1,1357 +0,0 @@ -/* automatically generated by rust-bindgen */ - -#![allow(non_camel_case_types)] -#![allow(uppercase_variables)] -#![allow(dead_code)] -#![allow(unused_attribute)] - -pub type ptrdiff_t = ::libc::c_long; -pub type size_t = ::libc::c_ulong; -pub type wchar_t = ::libc::c_int; -#[repr(C)] -pub struct CXString { - pub data: *const ::libc::c_void, - pub private_flags: ::libc::c_uint, -} -pub type CXIndex = *mut ::libc::c_void; -pub enum Struct_CXTranslationUnitImpl { } -pub type CXTranslationUnit = *mut Struct_CXTranslationUnitImpl; -pub type CXClientData = *mut ::libc::c_void; -#[repr(C)] -pub struct Struct_CXUnsavedFile { - pub Filename: *const ::libc::c_char, - pub Contents: *const ::libc::c_char, - pub Length: ::libc::c_ulong, -} -pub type Enum_CXAvailabilityKind = ::libc::c_uint; -pub static CXAvailability_Available: ::libc::c_uint = 0; -pub static CXAvailability_Deprecated: ::libc::c_uint = 1; -pub static CXAvailability_NotAvailable: ::libc::c_uint = 2; -pub static CXAvailability_NotAccessible: ::libc::c_uint = 3; -#[repr(C)] -pub struct Struct_CXVersion { - pub Major: ::libc::c_int, - pub Minor: ::libc::c_int, - pub Subminor: ::libc::c_int, -} -pub type CXVersion = Struct_CXVersion; -pub type CXGlobalOptFlags = ::libc::c_uint; -pub static CXGlobalOpt_None: ::libc::c_uint = 0; -pub static CXGlobalOpt_ThreadBackgroundPriorityForIndexing: ::libc::c_uint = - 1; -pub static CXGlobalOpt_ThreadBackgroundPriorityForEditing: ::libc::c_uint = 2; -pub static CXGlobalOpt_ThreadBackgroundPriorityForAll: ::libc::c_uint = 3; -pub type CXFile = *mut ::libc::c_void; -#[repr(C)] -pub struct CXFileUniqueID { - pub data: [::libc::c_ulonglong, ..3u], -} -#[repr(C)] -pub struct CXSourceLocation { - pub ptr_data: [*const ::libc::c_void, ..2u], - pub int_data: ::libc::c_uint, -} -#[repr(C)] -pub struct CXSourceRange { - pub ptr_data: [*const ::libc::c_void, ..2u], - pub begin_int_data: ::libc::c_uint, - pub end_int_data: ::libc::c_uint, -} -pub type Enum_CXDiagnosticSeverity = ::libc::c_uint; -pub static CXDiagnostic_Ignored: ::libc::c_uint = 0; -pub static CXDiagnostic_Note: ::libc::c_uint = 1; -pub static CXDiagnostic_Warning: ::libc::c_uint = 2; -pub static CXDiagnostic_Error: ::libc::c_uint = 3; -pub static CXDiagnostic_Fatal: ::libc::c_uint = 4; -pub type CXDiagnostic = *mut ::libc::c_void; -pub type CXDiagnosticSet = *mut ::libc::c_void; -pub type Enum_CXLoadDiag_Error = ::libc::c_uint; -pub static CXLoadDiag_None: ::libc::c_uint = 0; -pub static CXLoadDiag_Unknown: ::libc::c_uint = 1; -pub static CXLoadDiag_CannotLoad: ::libc::c_uint = 2; -pub static CXLoadDiag_InvalidFile: ::libc::c_uint = 3; -pub type Enum_CXDiagnosticDisplayOptions = ::libc::c_uint; -pub static CXDiagnostic_DisplaySourceLocation: ::libc::c_uint = 1; -pub static CXDiagnostic_DisplayColumn: ::libc::c_uint = 2; -pub static CXDiagnostic_DisplaySourceRanges: ::libc::c_uint = 4; -pub static CXDiagnostic_DisplayOption: ::libc::c_uint = 8; -pub static CXDiagnostic_DisplayCategoryId: ::libc::c_uint = 16; -pub static CXDiagnostic_DisplayCategoryName: ::libc::c_uint = 32; -pub type Enum_CXTranslationUnit_Flags = ::libc::c_uint; -pub static CXTranslationUnit_None: ::libc::c_uint = 0; -pub static CXTranslationUnit_DetailedPreprocessingRecord: ::libc::c_uint = 1; -pub static CXTranslationUnit_Incomplete: ::libc::c_uint = 2; -pub static CXTranslationUnit_PrecompiledPreamble: ::libc::c_uint = 4; -pub static CXTranslationUnit_CacheCompletionResults: ::libc::c_uint = 8; -pub static CXTranslationUnit_ForSerialization: ::libc::c_uint = 16; -pub static CXTranslationUnit_CXXChainedPCH: ::libc::c_uint = 32; -pub static CXTranslationUnit_SkipFunctionBodies: ::libc::c_uint = 64; -pub static CXTranslationUnit_IncludeBriefCommentsInCodeCompletion: - ::libc::c_uint = - 128; -pub type Enum_CXSaveTranslationUnit_Flags = ::libc::c_uint; -pub static CXSaveTranslationUnit_None: ::libc::c_uint = 0; -pub type Enum_CXSaveError = ::libc::c_uint; -pub static CXSaveError_None: ::libc::c_uint = 0; -pub static CXSaveError_Unknown: ::libc::c_uint = 1; -pub static CXSaveError_TranslationErrors: ::libc::c_uint = 2; -pub static CXSaveError_InvalidTU: ::libc::c_uint = 3; -pub type Enum_CXReparse_Flags = ::libc::c_uint; -pub static CXReparse_None: ::libc::c_uint = 0; -pub type Enum_CXTUResourceUsageKind = ::libc::c_uint; -pub static CXTUResourceUsage_AST: ::libc::c_uint = 1; -pub static CXTUResourceUsage_Identifiers: ::libc::c_uint = 2; -pub static CXTUResourceUsage_Selectors: ::libc::c_uint = 3; -pub static CXTUResourceUsage_GlobalCompletionResults: ::libc::c_uint = 4; -pub static CXTUResourceUsage_SourceManagerContentCache: ::libc::c_uint = 5; -pub static CXTUResourceUsage_AST_SideTables: ::libc::c_uint = 6; -pub static CXTUResourceUsage_SourceManager_Membuffer_Malloc: ::libc::c_uint = - 7; -pub static CXTUResourceUsage_SourceManager_Membuffer_MMap: ::libc::c_uint = 8; -pub static CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc: - ::libc::c_uint = - 9; -pub static CXTUResourceUsage_ExternalASTSource_Membuffer_MMap: ::libc::c_uint - = - 10; -pub static CXTUResourceUsage_Preprocessor: ::libc::c_uint = 11; -pub static CXTUResourceUsage_PreprocessingRecord: ::libc::c_uint = 12; -pub static CXTUResourceUsage_SourceManager_DataStructures: ::libc::c_uint = - 13; -pub static CXTUResourceUsage_Preprocessor_HeaderSearch: ::libc::c_uint = 14; -pub static CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN: ::libc::c_uint = 1; -pub static CXTUResourceUsage_MEMORY_IN_BYTES_END: ::libc::c_uint = 14; -pub static CXTUResourceUsage_First: ::libc::c_uint = 1; -pub static CXTUResourceUsage_Last: ::libc::c_uint = 14; -#[repr(C)] -pub struct Struct_CXTUResourceUsageEntry { - pub kind: Enum_CXTUResourceUsageKind, - pub amount: ::libc::c_ulong, -} -pub type CXTUResourceUsageEntry = Struct_CXTUResourceUsageEntry; -#[repr(C)] -pub struct Struct_CXTUResourceUsage { - pub data: *mut ::libc::c_void, - pub numEntries: ::libc::c_uint, - pub entries: *mut CXTUResourceUsageEntry, -} -pub type CXTUResourceUsage = Struct_CXTUResourceUsage; -pub type Enum_CXCursorKind = ::libc::c_uint; -pub static CXCursor_UnexposedDecl: ::libc::c_uint = 1; -pub static CXCursor_StructDecl: ::libc::c_uint = 2; -pub static CXCursor_UnionDecl: ::libc::c_uint = 3; -pub static CXCursor_ClassDecl: ::libc::c_uint = 4; -pub static CXCursor_EnumDecl: ::libc::c_uint = 5; -pub static CXCursor_FieldDecl: ::libc::c_uint = 6; -pub static CXCursor_EnumConstantDecl: ::libc::c_uint = 7; -pub static CXCursor_FunctionDecl: ::libc::c_uint = 8; -pub static CXCursor_VarDecl: ::libc::c_uint = 9; -pub static CXCursor_ParmDecl: ::libc::c_uint = 10; -pub static CXCursor_ObjCInterfaceDecl: ::libc::c_uint = 11; -pub static CXCursor_ObjCCategoryDecl: ::libc::c_uint = 12; -pub static CXCursor_ObjCProtocolDecl: ::libc::c_uint = 13; -pub static CXCursor_ObjCPropertyDecl: ::libc::c_uint = 14; -pub static CXCursor_ObjCIvarDecl: ::libc::c_uint = 15; -pub static CXCursor_ObjCInstanceMethodDecl: ::libc::c_uint = 16; -pub static CXCursor_ObjCClassMethodDecl: ::libc::c_uint = 17; -pub static CXCursor_ObjCImplementationDecl: ::libc::c_uint = 18; -pub static CXCursor_ObjCCategoryImplDecl: ::libc::c_uint = 19; -pub static CXCursor_TypedefDecl: ::libc::c_uint = 20; -pub static CXCursor_CXXMethod: ::libc::c_uint = 21; -pub static CXCursor_Namespace: ::libc::c_uint = 22; -pub static CXCursor_LinkageSpec: ::libc::c_uint = 23; -pub static CXCursor_Constructor: ::libc::c_uint = 24; -pub static CXCursor_Destructor: ::libc::c_uint = 25; -pub static CXCursor_ConversionFunction: ::libc::c_uint = 26; -pub static CXCursor_TemplateTypeParameter: ::libc::c_uint = 27; -pub static CXCursor_NonTypeTemplateParameter: ::libc::c_uint = 28; -pub static CXCursor_TemplateTemplateParameter: ::libc::c_uint = 29; -pub static CXCursor_FunctionTemplate: ::libc::c_uint = 30; -pub static CXCursor_ClassTemplate: ::libc::c_uint = 31; -pub static CXCursor_ClassTemplatePartialSpecialization: ::libc::c_uint = 32; -pub static CXCursor_NamespaceAlias: ::libc::c_uint = 33; -pub static CXCursor_UsingDirective: ::libc::c_uint = 34; -pub static CXCursor_UsingDeclaration: ::libc::c_uint = 35; -pub static CXCursor_TypeAliasDecl: ::libc::c_uint = 36; -pub static CXCursor_ObjCSynthesizeDecl: ::libc::c_uint = 37; -pub static CXCursor_ObjCDynamicDecl: ::libc::c_uint = 38; -pub static CXCursor_CXXAccessSpecifier: ::libc::c_uint = 39; -pub static CXCursor_FirstDecl: ::libc::c_uint = 1; -pub static CXCursor_LastDecl: ::libc::c_uint = 39; -pub static CXCursor_FirstRef: ::libc::c_uint = 40; -pub static CXCursor_ObjCSuperClassRef: ::libc::c_uint = 40; -pub static CXCursor_ObjCProtocolRef: ::libc::c_uint = 41; -pub static CXCursor_ObjCClassRef: ::libc::c_uint = 42; -pub static CXCursor_TypeRef: ::libc::c_uint = 43; -pub static CXCursor_CXXBaseSpecifier: ::libc::c_uint = 44; -pub static CXCursor_TemplateRef: ::libc::c_uint = 45; -pub static CXCursor_NamespaceRef: ::libc::c_uint = 46; -pub static CXCursor_MemberRef: ::libc::c_uint = 47; -pub static CXCursor_LabelRef: ::libc::c_uint = 48; -pub static CXCursor_OverloadedDeclRef: ::libc::c_uint = 49; -pub static CXCursor_VariableRef: ::libc::c_uint = 50; -pub static CXCursor_LastRef: ::libc::c_uint = 50; -pub static CXCursor_FirstInvalid: ::libc::c_uint = 70; -pub static CXCursor_InvalidFile: ::libc::c_uint = 70; -pub static CXCursor_NoDeclFound: ::libc::c_uint = 71; -pub static CXCursor_NotImplemented: ::libc::c_uint = 72; -pub static CXCursor_InvalidCode: ::libc::c_uint = 73; -pub static CXCursor_LastInvalid: ::libc::c_uint = 73; -pub static CXCursor_FirstExpr: ::libc::c_uint = 100; -pub static CXCursor_UnexposedExpr: ::libc::c_uint = 100; -pub static CXCursor_DeclRefExpr: ::libc::c_uint = 101; -pub static CXCursor_MemberRefExpr: ::libc::c_uint = 102; -pub static CXCursor_CallExpr: ::libc::c_uint = 103; -pub static CXCursor_ObjCMessageExpr: ::libc::c_uint = 104; -pub static CXCursor_BlockExpr: ::libc::c_uint = 105; -pub static CXCursor_IntegerLiteral: ::libc::c_uint = 106; -pub static CXCursor_FloatingLiteral: ::libc::c_uint = 107; -pub static CXCursor_ImaginaryLiteral: ::libc::c_uint = 108; -pub static CXCursor_StringLiteral: ::libc::c_uint = 109; -pub static CXCursor_CharacterLiteral: ::libc::c_uint = 110; -pub static CXCursor_ParenExpr: ::libc::c_uint = 111; -pub static CXCursor_UnaryOperator: ::libc::c_uint = 112; -pub static CXCursor_ArraySubscriptExpr: ::libc::c_uint = 113; -pub static CXCursor_BinaryOperator: ::libc::c_uint = 114; -pub static CXCursor_CompoundAssignOperator: ::libc::c_uint = 115; -pub static CXCursor_ConditionalOperator: ::libc::c_uint = 116; -pub static CXCursor_CStyleCastExpr: ::libc::c_uint = 117; -pub static CXCursor_CompoundLiteralExpr: ::libc::c_uint = 118; -pub static CXCursor_InitListExpr: ::libc::c_uint = 119; -pub static CXCursor_AddrLabelExpr: ::libc::c_uint = 120; -pub static CXCursor_StmtExpr: ::libc::c_uint = 121; -pub static CXCursor_GenericSelectionExpr: ::libc::c_uint = 122; -pub static CXCursor_GNUNullExpr: ::libc::c_uint = 123; -pub static CXCursor_CXXStaticCastExpr: ::libc::c_uint = 124; -pub static CXCursor_CXXDynamicCastExpr: ::libc::c_uint = 125; -pub static CXCursor_CXXReinterpretCastExpr: ::libc::c_uint = 126; -pub static CXCursor_CXXConstCastExpr: ::libc::c_uint = 127; -pub static CXCursor_CXXFunctionalCastExpr: ::libc::c_uint = 128; -pub static CXCursor_CXXTypeidExpr: ::libc::c_uint = 129; -pub static CXCursor_CXXBoolLiteralExpr: ::libc::c_uint = 130; -pub static CXCursor_CXXNullPtrLiteralExpr: ::libc::c_uint = 131; -pub static CXCursor_CXXThisExpr: ::libc::c_uint = 132; -pub static CXCursor_CXXThrowExpr: ::libc::c_uint = 133; -pub static CXCursor_CXXNewExpr: ::libc::c_uint = 134; -pub static CXCursor_CXXDeleteExpr: ::libc::c_uint = 135; -pub static CXCursor_UnaryExpr: ::libc::c_uint = 136; -pub static CXCursor_ObjCStringLiteral: ::libc::c_uint = 137; -pub static CXCursor_ObjCEncodeExpr: ::libc::c_uint = 138; -pub static CXCursor_ObjCSelectorExpr: ::libc::c_uint = 139; -pub static CXCursor_ObjCProtocolExpr: ::libc::c_uint = 140; -pub static CXCursor_ObjCBridgedCastExpr: ::libc::c_uint = 141; -pub static CXCursor_PackExpansionExpr: ::libc::c_uint = 142; -pub static CXCursor_SizeOfPackExpr: ::libc::c_uint = 143; -pub static CXCursor_LambdaExpr: ::libc::c_uint = 144; -pub static CXCursor_ObjCBoolLiteralExpr: ::libc::c_uint = 145; -pub static CXCursor_ObjCSelfExpr: ::libc::c_uint = 146; -pub static CXCursor_LastExpr: ::libc::c_uint = 146; -pub static CXCursor_FirstStmt: ::libc::c_uint = 200; -pub static CXCursor_UnexposedStmt: ::libc::c_uint = 200; -pub static CXCursor_LabelStmt: ::libc::c_uint = 201; -pub static CXCursor_CompoundStmt: ::libc::c_uint = 202; -pub static CXCursor_CaseStmt: ::libc::c_uint = 203; -pub static CXCursor_DefaultStmt: ::libc::c_uint = 204; -pub static CXCursor_IfStmt: ::libc::c_uint = 205; -pub static CXCursor_SwitchStmt: ::libc::c_uint = 206; -pub static CXCursor_WhileStmt: ::libc::c_uint = 207; -pub static CXCursor_DoStmt: ::libc::c_uint = 208; -pub static CXCursor_ForStmt: ::libc::c_uint = 209; -pub static CXCursor_GotoStmt: ::libc::c_uint = 210; -pub static CXCursor_IndirectGotoStmt: ::libc::c_uint = 211; -pub static CXCursor_ContinueStmt: ::libc::c_uint = 212; -pub static CXCursor_BreakStmt: ::libc::c_uint = 213; -pub static CXCursor_ReturnStmt: ::libc::c_uint = 214; -pub static CXCursor_GCCAsmStmt: ::libc::c_uint = 215; -pub static CXCursor_AsmStmt: ::libc::c_uint = 215; -pub static CXCursor_ObjCAtTryStmt: ::libc::c_uint = 216; -pub static CXCursor_ObjCAtCatchStmt: ::libc::c_uint = 217; -pub static CXCursor_ObjCAtFinallyStmt: ::libc::c_uint = 218; -pub static CXCursor_ObjCAtThrowStmt: ::libc::c_uint = 219; -pub static CXCursor_ObjCAtSynchronizedStmt: ::libc::c_uint = 220; -pub static CXCursor_ObjCAutoreleasePoolStmt: ::libc::c_uint = 221; -pub static CXCursor_ObjCForCollectionStmt: ::libc::c_uint = 222; -pub static CXCursor_CXXCatchStmt: ::libc::c_uint = 223; -pub static CXCursor_CXXTryStmt: ::libc::c_uint = 224; -pub static CXCursor_CXXForRangeStmt: ::libc::c_uint = 225; -pub static CXCursor_SEHTryStmt: ::libc::c_uint = 226; -pub static CXCursor_SEHExceptStmt: ::libc::c_uint = 227; -pub static CXCursor_SEHFinallyStmt: ::libc::c_uint = 228; -pub static CXCursor_MSAsmStmt: ::libc::c_uint = 229; -pub static CXCursor_NullStmt: ::libc::c_uint = 230; -pub static CXCursor_DeclStmt: ::libc::c_uint = 231; -pub static CXCursor_OMPParallelDirective: ::libc::c_uint = 232; -pub static CXCursor_LastStmt: ::libc::c_uint = 232; -pub static CXCursor_TranslationUnit: ::libc::c_uint = 300; -pub static CXCursor_FirstAttr: ::libc::c_uint = 400; -pub static CXCursor_UnexposedAttr: ::libc::c_uint = 400; -pub static CXCursor_IBActionAttr: ::libc::c_uint = 401; -pub static CXCursor_IBOutletAttr: ::libc::c_uint = 402; -pub static CXCursor_IBOutletCollectionAttr: ::libc::c_uint = 403; -pub static CXCursor_CXXFinalAttr: ::libc::c_uint = 404; -pub static CXCursor_CXXOverrideAttr: ::libc::c_uint = 405; -pub static CXCursor_AnnotateAttr: ::libc::c_uint = 406; -pub static CXCursor_AsmLabelAttr: ::libc::c_uint = 407; -pub static CXCursor_PackedAttr: ::libc::c_uint = 408; -pub static CXCursor_LastAttr: ::libc::c_uint = 408; -pub static CXCursor_PreprocessingDirective: ::libc::c_uint = 500; -pub static CXCursor_MacroDefinition: ::libc::c_uint = 501; -pub static CXCursor_MacroExpansion: ::libc::c_uint = 502; -pub static CXCursor_MacroInstantiation: ::libc::c_uint = 502; -pub static CXCursor_InclusionDirective: ::libc::c_uint = 503; -pub static CXCursor_FirstPreprocessing: ::libc::c_uint = 500; -pub static CXCursor_LastPreprocessing: ::libc::c_uint = 503; -pub static CXCursor_ModuleImportDecl: ::libc::c_uint = 600; -pub static CXCursor_FirstExtraDecl: ::libc::c_uint = 600; -pub static CXCursor_LastExtraDecl: ::libc::c_uint = 600; -#[repr(C)] -pub struct CXCursor { - pub kind: Enum_CXCursorKind, - pub xdata: ::libc::c_int, - pub data: [*const ::libc::c_void, ..3u], -} -#[repr(C)] -pub struct CXComment { - pub ASTNode: *const ::libc::c_void, - pub TranslationUnit: CXTranslationUnit, -} -pub type Enum_CXLinkageKind = ::libc::c_uint; -pub static CXLinkage_Invalid: ::libc::c_uint = 0; -pub static CXLinkage_NoLinkage: ::libc::c_uint = 1; -pub static CXLinkage_Internal: ::libc::c_uint = 2; -pub static CXLinkage_UniqueExternal: ::libc::c_uint = 3; -pub static CXLinkage_External: ::libc::c_uint = 4; -#[repr(C)] -pub struct Struct_CXPlatformAvailability { - pub Platform: CXString, - pub Introduced: CXVersion, - pub Deprecated: CXVersion, - pub Obsoleted: CXVersion, - pub Unavailable: ::libc::c_int, - pub Message: CXString, -} -pub type CXPlatformAvailability = Struct_CXPlatformAvailability; -pub type Enum_CXLanguageKind = ::libc::c_uint; -pub static CXLanguage_Invalid: ::libc::c_uint = 0; -pub static CXLanguage_C: ::libc::c_uint = 1; -pub static CXLanguage_ObjC: ::libc::c_uint = 2; -pub static CXLanguage_CPlusPlus: ::libc::c_uint = 3; -pub enum Struct_CXCursorSetImpl { } -pub type CXCursorSet = *mut Struct_CXCursorSetImpl; -pub type Enum_CXTypeKind = ::libc::c_uint; -pub static CXType_Invalid: ::libc::c_uint = 0; -pub static CXType_Unexposed: ::libc::c_uint = 1; -pub static CXType_Void: ::libc::c_uint = 2; -pub static CXType_Bool: ::libc::c_uint = 3; -pub static CXType_Char_U: ::libc::c_uint = 4; -pub static CXType_UChar: ::libc::c_uint = 5; -pub static CXType_Char16: ::libc::c_uint = 6; -pub static CXType_Char32: ::libc::c_uint = 7; -pub static CXType_UShort: ::libc::c_uint = 8; -pub static CXType_UInt: ::libc::c_uint = 9; -pub static CXType_ULong: ::libc::c_uint = 10; -pub static CXType_ULongLong: ::libc::c_uint = 11; -pub static CXType_UInt128: ::libc::c_uint = 12; -pub static CXType_Char_S: ::libc::c_uint = 13; -pub static CXType_SChar: ::libc::c_uint = 14; -pub static CXType_WChar: ::libc::c_uint = 15; -pub static CXType_Short: ::libc::c_uint = 16; -pub static CXType_Int: ::libc::c_uint = 17; -pub static CXType_Long: ::libc::c_uint = 18; -pub static CXType_LongLong: ::libc::c_uint = 19; -pub static CXType_Int128: ::libc::c_uint = 20; -pub static CXType_Float: ::libc::c_uint = 21; -pub static CXType_Double: ::libc::c_uint = 22; -pub static CXType_LongDouble: ::libc::c_uint = 23; -pub static CXType_NullPtr: ::libc::c_uint = 24; -pub static CXType_Overload: ::libc::c_uint = 25; -pub static CXType_Dependent: ::libc::c_uint = 26; -pub static CXType_ObjCId: ::libc::c_uint = 27; -pub static CXType_ObjCClass: ::libc::c_uint = 28; -pub static CXType_ObjCSel: ::libc::c_uint = 29; -pub static CXType_FirstBuiltin: ::libc::c_uint = 2; -pub static CXType_LastBuiltin: ::libc::c_uint = 29; -pub static CXType_Complex: ::libc::c_uint = 100; -pub static CXType_Pointer: ::libc::c_uint = 101; -pub static CXType_BlockPointer: ::libc::c_uint = 102; -pub static CXType_LValueReference: ::libc::c_uint = 103; -pub static CXType_RValueReference: ::libc::c_uint = 104; -pub static CXType_Record: ::libc::c_uint = 105; -pub static CXType_Enum: ::libc::c_uint = 106; -pub static CXType_Typedef: ::libc::c_uint = 107; -pub static CXType_ObjCInterface: ::libc::c_uint = 108; -pub static CXType_ObjCObjectPointer: ::libc::c_uint = 109; -pub static CXType_FunctionNoProto: ::libc::c_uint = 110; -pub static CXType_FunctionProto: ::libc::c_uint = 111; -pub static CXType_ConstantArray: ::libc::c_uint = 112; -pub static CXType_Vector: ::libc::c_uint = 113; -pub static CXType_IncompleteArray: ::libc::c_uint = 114; -pub static CXType_VariableArray: ::libc::c_uint = 115; -pub static CXType_DependentSizedArray: ::libc::c_uint = 116; -pub static CXType_MemberPointer: ::libc::c_uint = 117; -pub type Enum_CXCallingConv = ::libc::c_uint; -pub static CXCallingConv_Default: ::libc::c_uint = 0; -pub static CXCallingConv_C: ::libc::c_uint = 1; -pub static CXCallingConv_X86StdCall: ::libc::c_uint = 2; -pub static CXCallingConv_X86FastCall: ::libc::c_uint = 3; -pub static CXCallingConv_X86ThisCall: ::libc::c_uint = 4; -pub static CXCallingConv_X86Pascal: ::libc::c_uint = 5; -pub static CXCallingConv_AAPCS: ::libc::c_uint = 6; -pub static CXCallingConv_AAPCS_VFP: ::libc::c_uint = 7; -pub static CXCallingConv_PnaclCall: ::libc::c_uint = 8; -pub static CXCallingConv_IntelOclBicc: ::libc::c_uint = 9; -pub static CXCallingConv_X86_64Win64: ::libc::c_uint = 10; -pub static CXCallingConv_X86_64SysV: ::libc::c_uint = 11; -pub static CXCallingConv_Invalid: ::libc::c_uint = 100; -pub static CXCallingConv_Unexposed: ::libc::c_uint = 200; -#[repr(C)] -pub struct CXType { - pub kind: Enum_CXTypeKind, - pub data: [*mut ::libc::c_void, ..2u], -} -pub type Enum_CXTypeLayoutError = ::libc::c_int; -pub static CXTypeLayoutError_Invalid: ::libc::c_int = -1; -pub static CXTypeLayoutError_Incomplete: ::libc::c_int = -2; -pub static CXTypeLayoutError_Dependent: ::libc::c_int = -3; -pub static CXTypeLayoutError_NotConstantSize: ::libc::c_int = -4; -pub static CXTypeLayoutError_InvalidFieldName: ::libc::c_int = -5; -pub type Enum_CXRefQualifierKind = ::libc::c_uint; -pub static CXRefQualifier_None: ::libc::c_uint = 0; -pub static CXRefQualifier_LValue: ::libc::c_uint = 1; -pub static CXRefQualifier_RValue: ::libc::c_uint = 2; -pub type Enum_CX_CXXAccessSpecifier = ::libc::c_uint; -pub static CX_CXXInvalidAccessSpecifier: ::libc::c_uint = 0; -pub static CX_CXXPublic: ::libc::c_uint = 1; -pub static CX_CXXProtected: ::libc::c_uint = 2; -pub static CX_CXXPrivate: ::libc::c_uint = 3; -pub type Enum_CXChildVisitResult = ::libc::c_uint; -pub static CXChildVisit_Break: ::libc::c_uint = 0; -pub static CXChildVisit_Continue: ::libc::c_uint = 1; -pub static CXChildVisit_Recurse: ::libc::c_uint = 2; -pub type CXCursorVisitor = - ::std::option::Option Enum_CXChildVisitResult>; -pub type CXObjCPropertyAttrKind = ::libc::c_uint; -pub static CXObjCPropertyAttr_noattr: ::libc::c_uint = 0; -pub static CXObjCPropertyAttr_readonly: ::libc::c_uint = 1; -pub static CXObjCPropertyAttr_getter: ::libc::c_uint = 2; -pub static CXObjCPropertyAttr_assign: ::libc::c_uint = 4; -pub static CXObjCPropertyAttr_readwrite: ::libc::c_uint = 8; -pub static CXObjCPropertyAttr_retain: ::libc::c_uint = 16; -pub static CXObjCPropertyAttr_copy: ::libc::c_uint = 32; -pub static CXObjCPropertyAttr_nonatomic: ::libc::c_uint = 64; -pub static CXObjCPropertyAttr_setter: ::libc::c_uint = 128; -pub static CXObjCPropertyAttr_atomic: ::libc::c_uint = 256; -pub static CXObjCPropertyAttr_weak: ::libc::c_uint = 512; -pub static CXObjCPropertyAttr_strong: ::libc::c_uint = 1024; -pub static CXObjCPropertyAttr_unsafe_unretained: ::libc::c_uint = 2048; -pub type CXObjCDeclQualifierKind = ::libc::c_uint; -pub static CXObjCDeclQualifier_None: ::libc::c_uint = 0; -pub static CXObjCDeclQualifier_In: ::libc::c_uint = 1; -pub static CXObjCDeclQualifier_Inout: ::libc::c_uint = 2; -pub static CXObjCDeclQualifier_Out: ::libc::c_uint = 4; -pub static CXObjCDeclQualifier_Bycopy: ::libc::c_uint = 8; -pub static CXObjCDeclQualifier_Byref: ::libc::c_uint = 16; -pub static CXObjCDeclQualifier_Oneway: ::libc::c_uint = 32; -pub type CXModule = *mut ::libc::c_void; -pub type Enum_CXCommentKind = ::libc::c_uint; -pub static CXComment_Null: ::libc::c_uint = 0; -pub static CXComment_Text: ::libc::c_uint = 1; -pub static CXComment_InlineCommand: ::libc::c_uint = 2; -pub static CXComment_HTMLStartTag: ::libc::c_uint = 3; -pub static CXComment_HTMLEndTag: ::libc::c_uint = 4; -pub static CXComment_Paragraph: ::libc::c_uint = 5; -pub static CXComment_BlockCommand: ::libc::c_uint = 6; -pub static CXComment_ParamCommand: ::libc::c_uint = 7; -pub static CXComment_TParamCommand: ::libc::c_uint = 8; -pub static CXComment_VerbatimBlockCommand: ::libc::c_uint = 9; -pub static CXComment_VerbatimBlockLine: ::libc::c_uint = 10; -pub static CXComment_VerbatimLine: ::libc::c_uint = 11; -pub static CXComment_FullComment: ::libc::c_uint = 12; -pub type Enum_CXCommentInlineCommandRenderKind = ::libc::c_uint; -pub static CXCommentInlineCommandRenderKind_Normal: ::libc::c_uint = 0; -pub static CXCommentInlineCommandRenderKind_Bold: ::libc::c_uint = 1; -pub static CXCommentInlineCommandRenderKind_Monospaced: ::libc::c_uint = 2; -pub static CXCommentInlineCommandRenderKind_Emphasized: ::libc::c_uint = 3; -pub type Enum_CXCommentParamPassDirection = ::libc::c_uint; -pub static CXCommentParamPassDirection_In: ::libc::c_uint = 0; -pub static CXCommentParamPassDirection_Out: ::libc::c_uint = 1; -pub static CXCommentParamPassDirection_InOut: ::libc::c_uint = 2; -pub type Enum_CXNameRefFlags = ::libc::c_uint; -pub static CXNameRange_WantQualifier: ::libc::c_uint = 1; -pub static CXNameRange_WantTemplateArgs: ::libc::c_uint = 2; -pub static CXNameRange_WantSinglePiece: ::libc::c_uint = 4; -pub type Enum_CXTokenKind = ::libc::c_uint; -pub static CXToken_Punctuation: ::libc::c_uint = 0; -pub static CXToken_Keyword: ::libc::c_uint = 1; -pub static CXToken_Identifier: ::libc::c_uint = 2; -pub static CXToken_Literal: ::libc::c_uint = 3; -pub static CXToken_Comment: ::libc::c_uint = 4; -pub type CXTokenKind = Enum_CXTokenKind; -#[repr(C)] -pub struct CXToken { - pub int_data: [::libc::c_uint, ..4u], - pub ptr_data: *mut ::libc::c_void, -} -pub type CXCompletionString = *mut ::libc::c_void; -#[repr(C)] -pub struct CXCompletionResult { - pub CursorKind: Enum_CXCursorKind, - pub CompletionString: CXCompletionString, -} -pub type Enum_CXCompletionChunkKind = ::libc::c_uint; -pub static CXCompletionChunk_Optional: ::libc::c_uint = 0; -pub static CXCompletionChunk_TypedText: ::libc::c_uint = 1; -pub static CXCompletionChunk_Text: ::libc::c_uint = 2; -pub static CXCompletionChunk_Placeholder: ::libc::c_uint = 3; -pub static CXCompletionChunk_Informative: ::libc::c_uint = 4; -pub static CXCompletionChunk_CurrentParameter: ::libc::c_uint = 5; -pub static CXCompletionChunk_LeftParen: ::libc::c_uint = 6; -pub static CXCompletionChunk_RightParen: ::libc::c_uint = 7; -pub static CXCompletionChunk_LeftBracket: ::libc::c_uint = 8; -pub static CXCompletionChunk_RightBracket: ::libc::c_uint = 9; -pub static CXCompletionChunk_LeftBrace: ::libc::c_uint = 10; -pub static CXCompletionChunk_RightBrace: ::libc::c_uint = 11; -pub static CXCompletionChunk_LeftAngle: ::libc::c_uint = 12; -pub static CXCompletionChunk_RightAngle: ::libc::c_uint = 13; -pub static CXCompletionChunk_Comma: ::libc::c_uint = 14; -pub static CXCompletionChunk_ResultType: ::libc::c_uint = 15; -pub static CXCompletionChunk_Colon: ::libc::c_uint = 16; -pub static CXCompletionChunk_SemiColon: ::libc::c_uint = 17; -pub static CXCompletionChunk_Equal: ::libc::c_uint = 18; -pub static CXCompletionChunk_HorizontalSpace: ::libc::c_uint = 19; -pub static CXCompletionChunk_VerticalSpace: ::libc::c_uint = 20; -#[repr(C)] -pub struct CXCodeCompleteResults { - pub Results: *mut CXCompletionResult, - pub NumResults: ::libc::c_uint, -} -pub type Enum_CXCodeComplete_Flags = ::libc::c_uint; -pub static CXCodeComplete_IncludeMacros: ::libc::c_uint = 1; -pub static CXCodeComplete_IncludeCodePatterns: ::libc::c_uint = 2; -pub static CXCodeComplete_IncludeBriefComments: ::libc::c_uint = 4; -pub type Enum_CXCompletionContext = ::libc::c_uint; -pub static CXCompletionContext_Unexposed: ::libc::c_uint = 0; -pub static CXCompletionContext_AnyType: ::libc::c_uint = 1; -pub static CXCompletionContext_AnyValue: ::libc::c_uint = 2; -pub static CXCompletionContext_ObjCObjectValue: ::libc::c_uint = 4; -pub static CXCompletionContext_ObjCSelectorValue: ::libc::c_uint = 8; -pub static CXCompletionContext_CXXClassTypeValue: ::libc::c_uint = 16; -pub static CXCompletionContext_DotMemberAccess: ::libc::c_uint = 32; -pub static CXCompletionContext_ArrowMemberAccess: ::libc::c_uint = 64; -pub static CXCompletionContext_ObjCPropertyAccess: ::libc::c_uint = 128; -pub static CXCompletionContext_EnumTag: ::libc::c_uint = 256; -pub static CXCompletionContext_UnionTag: ::libc::c_uint = 512; -pub static CXCompletionContext_StructTag: ::libc::c_uint = 1024; -pub static CXCompletionContext_ClassTag: ::libc::c_uint = 2048; -pub static CXCompletionContext_Namespace: ::libc::c_uint = 4096; -pub static CXCompletionContext_NestedNameSpecifier: ::libc::c_uint = 8192; -pub static CXCompletionContext_ObjCInterface: ::libc::c_uint = 16384; -pub static CXCompletionContext_ObjCProtocol: ::libc::c_uint = 32768; -pub static CXCompletionContext_ObjCCategory: ::libc::c_uint = 65536; -pub static CXCompletionContext_ObjCInstanceMessage: ::libc::c_uint = 131072; -pub static CXCompletionContext_ObjCClassMessage: ::libc::c_uint = 262144; -pub static CXCompletionContext_ObjCSelectorName: ::libc::c_uint = 524288; -pub static CXCompletionContext_MacroName: ::libc::c_uint = 1048576; -pub static CXCompletionContext_NaturalLanguage: ::libc::c_uint = 2097152; -pub static CXCompletionContext_Unknown: ::libc::c_uint = 4194303; -pub type CXInclusionVisitor = - ::std::option::Option; -pub type CXRemapping = *mut ::libc::c_void; -pub type Enum_CXVisitorResult = ::libc::c_uint; -pub static CXVisit_Break: ::libc::c_uint = 0; -pub static CXVisit_Continue: ::libc::c_uint = 1; -#[repr(C)] -pub struct CXCursorAndRangeVisitor { - pub context: *mut ::libc::c_void, - pub visit: ::std::option::Option Enum_CXVisitorResult>, -} -pub type CXResult = ::libc::c_uint; -pub static CXResult_Success: ::libc::c_uint = 0; -pub static CXResult_Invalid: ::libc::c_uint = 1; -pub static CXResult_VisitBreak: ::libc::c_uint = 2; -pub type CXIdxClientFile = *mut ::libc::c_void; -pub type CXIdxClientEntity = *mut ::libc::c_void; -pub type CXIdxClientContainer = *mut ::libc::c_void; -pub type CXIdxClientASTFile = *mut ::libc::c_void; -#[repr(C)] -pub struct CXIdxLoc { - pub ptr_data: [*mut ::libc::c_void, ..2u], - pub int_data: ::libc::c_uint, -} -#[repr(C)] -pub struct CXIdxIncludedFileInfo { - pub hashLoc: CXIdxLoc, - pub filename: *const ::libc::c_char, - pub file: CXFile, - pub isImport: ::libc::c_int, - pub isAngled: ::libc::c_int, - pub isModuleImport: ::libc::c_int, -} -#[repr(C)] -pub struct CXIdxImportedASTFileInfo { - pub file: CXFile, - pub module: CXModule, - pub loc: CXIdxLoc, - pub isImplicit: ::libc::c_int, -} -pub type CXIdxEntityKind = ::libc::c_uint; -pub static CXIdxEntity_Unexposed: ::libc::c_uint = 0; -pub static CXIdxEntity_Typedef: ::libc::c_uint = 1; -pub static CXIdxEntity_Function: ::libc::c_uint = 2; -pub static CXIdxEntity_Variable: ::libc::c_uint = 3; -pub static CXIdxEntity_Field: ::libc::c_uint = 4; -pub static CXIdxEntity_EnumConstant: ::libc::c_uint = 5; -pub static CXIdxEntity_ObjCClass: ::libc::c_uint = 6; -pub static CXIdxEntity_ObjCProtocol: ::libc::c_uint = 7; -pub static CXIdxEntity_ObjCCategory: ::libc::c_uint = 8; -pub static CXIdxEntity_ObjCInstanceMethod: ::libc::c_uint = 9; -pub static CXIdxEntity_ObjCClassMethod: ::libc::c_uint = 10; -pub static CXIdxEntity_ObjCProperty: ::libc::c_uint = 11; -pub static CXIdxEntity_ObjCIvar: ::libc::c_uint = 12; -pub static CXIdxEntity_Enum: ::libc::c_uint = 13; -pub static CXIdxEntity_Struct: ::libc::c_uint = 14; -pub static CXIdxEntity_Union: ::libc::c_uint = 15; -pub static CXIdxEntity_CXXClass: ::libc::c_uint = 16; -pub static CXIdxEntity_CXXNamespace: ::libc::c_uint = 17; -pub static CXIdxEntity_CXXNamespaceAlias: ::libc::c_uint = 18; -pub static CXIdxEntity_CXXStaticVariable: ::libc::c_uint = 19; -pub static CXIdxEntity_CXXStaticMethod: ::libc::c_uint = 20; -pub static CXIdxEntity_CXXInstanceMethod: ::libc::c_uint = 21; -pub static CXIdxEntity_CXXConstructor: ::libc::c_uint = 22; -pub static CXIdxEntity_CXXDestructor: ::libc::c_uint = 23; -pub static CXIdxEntity_CXXConversionFunction: ::libc::c_uint = 24; -pub static CXIdxEntity_CXXTypeAlias: ::libc::c_uint = 25; -pub static CXIdxEntity_CXXInterface: ::libc::c_uint = 26; -pub type CXIdxEntityLanguage = ::libc::c_uint; -pub static CXIdxEntityLang_None: ::libc::c_uint = 0; -pub static CXIdxEntityLang_C: ::libc::c_uint = 1; -pub static CXIdxEntityLang_ObjC: ::libc::c_uint = 2; -pub static CXIdxEntityLang_CXX: ::libc::c_uint = 3; -pub type CXIdxEntityCXXTemplateKind = ::libc::c_uint; -pub static CXIdxEntity_NonTemplate: ::libc::c_uint = 0; -pub static CXIdxEntity_Template: ::libc::c_uint = 1; -pub static CXIdxEntity_TemplatePartialSpecialization: ::libc::c_uint = 2; -pub static CXIdxEntity_TemplateSpecialization: ::libc::c_uint = 3; -pub type CXIdxAttrKind = ::libc::c_uint; -pub static CXIdxAttr_Unexposed: ::libc::c_uint = 0; -pub static CXIdxAttr_IBAction: ::libc::c_uint = 1; -pub static CXIdxAttr_IBOutlet: ::libc::c_uint = 2; -pub static CXIdxAttr_IBOutletCollection: ::libc::c_uint = 3; -#[repr(C)] -pub struct CXIdxAttrInfo { - pub kind: CXIdxAttrKind, - pub cursor: CXCursor, - pub loc: CXIdxLoc, -} -#[repr(C)] -pub struct CXIdxEntityInfo { - pub kind: CXIdxEntityKind, - pub templateKind: CXIdxEntityCXXTemplateKind, - pub lang: CXIdxEntityLanguage, - pub name: *const ::libc::c_char, - pub USR: *const ::libc::c_char, - pub cursor: CXCursor, - pub attributes: *const *const CXIdxAttrInfo, - pub numAttributes: ::libc::c_uint, -} -#[repr(C)] -pub struct CXIdxContainerInfo { - pub cursor: CXCursor, -} -#[repr(C)] -pub struct CXIdxIBOutletCollectionAttrInfo { - pub attrInfo: *const CXIdxAttrInfo, - pub objcClass: *const CXIdxEntityInfo, - pub classCursor: CXCursor, - pub classLoc: CXIdxLoc, -} -pub type CXIdxDeclInfoFlags = ::libc::c_uint; -pub static CXIdxDeclFlag_Skipped: ::libc::c_uint = 1; -#[repr(C)] -pub struct CXIdxDeclInfo { - pub entityInfo: *const CXIdxEntityInfo, - pub cursor: CXCursor, - pub loc: CXIdxLoc, - pub semanticContainer: *const CXIdxContainerInfo, - pub lexicalContainer: *const CXIdxContainerInfo, - pub isRedeclaration: ::libc::c_int, - pub isDefinition: ::libc::c_int, - pub isContainer: ::libc::c_int, - pub declAsContainer: *const CXIdxContainerInfo, - pub isImplicit: ::libc::c_int, - pub attributes: *const *const CXIdxAttrInfo, - pub numAttributes: ::libc::c_uint, - pub flags: ::libc::c_uint, -} -pub type CXIdxObjCContainerKind = ::libc::c_uint; -pub static CXIdxObjCContainer_ForwardRef: ::libc::c_uint = 0; -pub static CXIdxObjCContainer_Interface: ::libc::c_uint = 1; -pub static CXIdxObjCContainer_Implementation: ::libc::c_uint = 2; -#[repr(C)] -pub struct CXIdxObjCContainerDeclInfo { - pub declInfo: *const CXIdxDeclInfo, - pub kind: CXIdxObjCContainerKind, -} -#[repr(C)] -pub struct CXIdxBaseClassInfo { - pub base: *const CXIdxEntityInfo, - pub cursor: CXCursor, - pub loc: CXIdxLoc, -} -#[repr(C)] -pub struct CXIdxObjCProtocolRefInfo { - pub protocol: *const CXIdxEntityInfo, - pub cursor: CXCursor, - pub loc: CXIdxLoc, -} -#[repr(C)] -pub struct CXIdxObjCProtocolRefListInfo { - pub protocols: *const *const CXIdxObjCProtocolRefInfo, - pub numProtocols: ::libc::c_uint, -} -#[repr(C)] -pub struct CXIdxObjCInterfaceDeclInfo { - pub containerInfo: *const CXIdxObjCContainerDeclInfo, - pub superInfo: *const CXIdxBaseClassInfo, - pub protocols: *const CXIdxObjCProtocolRefListInfo, -} -#[repr(C)] -pub struct CXIdxObjCCategoryDeclInfo { - pub containerInfo: *const CXIdxObjCContainerDeclInfo, - pub objcClass: *const CXIdxEntityInfo, - pub classCursor: CXCursor, - pub classLoc: CXIdxLoc, - pub protocols: *const CXIdxObjCProtocolRefListInfo, -} -#[repr(C)] -pub struct CXIdxObjCPropertyDeclInfo { - pub declInfo: *const CXIdxDeclInfo, - pub getter: *const CXIdxEntityInfo, - pub setter: *const CXIdxEntityInfo, -} -#[repr(C)] -pub struct CXIdxCXXClassDeclInfo { - pub declInfo: *const CXIdxDeclInfo, - pub bases: *const *const CXIdxBaseClassInfo, - pub numBases: ::libc::c_uint, -} -pub type CXIdxEntityRefKind = ::libc::c_uint; -pub static CXIdxEntityRef_Direct: ::libc::c_uint = 1; -pub static CXIdxEntityRef_Implicit: ::libc::c_uint = 2; -#[repr(C)] -pub struct CXIdxEntityRefInfo { - pub kind: CXIdxEntityRefKind, - pub cursor: CXCursor, - pub loc: CXIdxLoc, - pub referencedEntity: *const CXIdxEntityInfo, - pub parentEntity: *const CXIdxEntityInfo, - pub container: *const CXIdxContainerInfo, -} -#[repr(C)] -pub struct IndexerCallbacks { - pub abortQuery: ::std::option::Option ::libc::c_int>, - pub diagnostic: ::std::option::Option, - pub enteredMainFile: ::std::option::Option CXIdxClientFile>, - pub ppIncludedFile: ::std::option::Option CXIdxClientFile>, - pub importedASTFile: ::std::option::Option CXIdxClientASTFile>, - pub startedTranslationUnit: ::std::option::Option - CXIdxClientContainer>, - pub indexDeclaration: ::std::option::Option, - pub indexEntityReference: ::std::option::Option, -} -pub type CXIndexAction = *mut ::libc::c_void; -pub type CXIndexOptFlags = ::libc::c_uint; -pub static CXIndexOpt_None: ::libc::c_uint = 0; -pub static CXIndexOpt_SuppressRedundantRefs: ::libc::c_uint = 1; -pub static CXIndexOpt_IndexFunctionLocalSymbols: ::libc::c_uint = 2; -pub static CXIndexOpt_IndexImplicitTemplateInstantiations: ::libc::c_uint = 4; -pub static CXIndexOpt_SuppressWarnings: ::libc::c_uint = 8; -pub static CXIndexOpt_SkipParsedBodiesInSession: ::libc::c_uint = 16; -#[link(name = "clang")] -extern "C" { - pub fn clang_getCString(string: CXString) -> *const ::libc::c_char; - pub fn clang_disposeString(string: CXString); - pub fn clang_createIndex(excludeDeclarationsFromPCH: ::libc::c_int, - displayDiagnostics: ::libc::c_int) -> CXIndex; - pub fn clang_disposeIndex(index: CXIndex); - pub fn clang_CXIndex_setGlobalOptions(arg1: CXIndex, - options: ::libc::c_uint); - pub fn clang_CXIndex_getGlobalOptions(arg1: CXIndex) -> ::libc::c_uint; - pub fn clang_getFileName(SFile: CXFile) -> CXString; - pub fn clang_getFileTime(SFile: CXFile) -> ::libc::time_t; - pub fn clang_getFileUniqueID(file: CXFile, outID: *mut CXFileUniqueID) -> - ::libc::c_int; - pub fn clang_isFileMultipleIncludeGuarded(tu: CXTranslationUnit, - file: CXFile) -> ::libc::c_uint; - pub fn clang_getFile(tu: CXTranslationUnit, - file_name: *const ::libc::c_char) -> CXFile; - pub fn clang_getNullLocation() -> CXSourceLocation; - pub fn clang_equalLocations(loc1: CXSourceLocation, - loc2: CXSourceLocation) -> ::libc::c_uint; - pub fn clang_getLocation(tu: CXTranslationUnit, file: CXFile, - line: ::libc::c_uint, column: ::libc::c_uint) -> - CXSourceLocation; - pub fn clang_getLocationForOffset(tu: CXTranslationUnit, file: CXFile, - offset: ::libc::c_uint) -> - CXSourceLocation; - pub fn clang_Location_isInSystemHeader(location: CXSourceLocation) -> - ::libc::c_int; - pub fn clang_Location_isFromMainFile(location: CXSourceLocation) -> - ::libc::c_int; - pub fn clang_getNullRange() -> CXSourceRange; - pub fn clang_getRange(begin: CXSourceLocation, end: CXSourceLocation) -> - CXSourceRange; - pub fn clang_equalRanges(range1: CXSourceRange, range2: CXSourceRange) -> - ::libc::c_uint; - pub fn clang_Range_isNull(range: CXSourceRange) -> ::libc::c_int; - pub fn clang_getExpansionLocation(location: CXSourceLocation, - file: *mut CXFile, - line: *mut ::libc::c_uint, - column: *mut ::libc::c_uint, - offset: *mut ::libc::c_uint); - pub fn clang_getPresumedLocation(location: CXSourceLocation, - filename: *mut CXString, - line: *mut ::libc::c_uint, - column: *mut ::libc::c_uint); - pub fn clang_getInstantiationLocation(location: CXSourceLocation, - file: *mut CXFile, - line: *mut ::libc::c_uint, - column: *mut ::libc::c_uint, - offset: *mut ::libc::c_uint); - pub fn clang_getSpellingLocation(location: CXSourceLocation, - file: *mut CXFile, - line: *mut ::libc::c_uint, - column: *mut ::libc::c_uint, - offset: *mut ::libc::c_uint); - pub fn clang_getFileLocation(location: CXSourceLocation, - file: *mut CXFile, line: *mut ::libc::c_uint, - column: *mut ::libc::c_uint, - offset: *mut ::libc::c_uint); - pub fn clang_getRangeStart(range: CXSourceRange) -> CXSourceLocation; - pub fn clang_getRangeEnd(range: CXSourceRange) -> CXSourceLocation; - pub fn clang_getNumDiagnosticsInSet(Diags: CXDiagnosticSet) -> - ::libc::c_uint; - pub fn clang_getDiagnosticInSet(Diags: CXDiagnosticSet, - Index: ::libc::c_uint) -> CXDiagnostic; - pub fn clang_loadDiagnostics(file: *const ::libc::c_char, - error: *mut Enum_CXLoadDiag_Error, - errorString: *mut CXString) -> - CXDiagnosticSet; - pub fn clang_disposeDiagnosticSet(Diags: CXDiagnosticSet); - pub fn clang_getChildDiagnostics(D: CXDiagnostic) -> CXDiagnosticSet; - pub fn clang_getNumDiagnostics(Unit: CXTranslationUnit) -> ::libc::c_uint; - pub fn clang_getDiagnostic(Unit: CXTranslationUnit, Index: ::libc::c_uint) - -> CXDiagnostic; - pub fn clang_getDiagnosticSetFromTU(Unit: CXTranslationUnit) -> - CXDiagnosticSet; - pub fn clang_disposeDiagnostic(Diagnostic: CXDiagnostic); - pub fn clang_formatDiagnostic(Diagnostic: CXDiagnostic, - Options: ::libc::c_uint) -> CXString; - pub fn clang_defaultDiagnosticDisplayOptions() -> ::libc::c_uint; - pub fn clang_getDiagnosticSeverity(arg1: CXDiagnostic) -> - Enum_CXDiagnosticSeverity; - pub fn clang_getDiagnosticLocation(arg1: CXDiagnostic) -> - CXSourceLocation; - pub fn clang_getDiagnosticSpelling(arg1: CXDiagnostic) -> CXString; - pub fn clang_getDiagnosticOption(Diag: CXDiagnostic, - Disable: *mut CXString) -> CXString; - pub fn clang_getDiagnosticCategory(arg1: CXDiagnostic) -> ::libc::c_uint; - pub fn clang_getDiagnosticCategoryName(Category: ::libc::c_uint) -> - CXString; - pub fn clang_getDiagnosticCategoryText(arg1: CXDiagnostic) -> CXString; - pub fn clang_getDiagnosticNumRanges(arg1: CXDiagnostic) -> ::libc::c_uint; - pub fn clang_getDiagnosticRange(Diagnostic: CXDiagnostic, - Range: ::libc::c_uint) -> CXSourceRange; - pub fn clang_getDiagnosticNumFixIts(Diagnostic: CXDiagnostic) -> - ::libc::c_uint; - pub fn clang_getDiagnosticFixIt(Diagnostic: CXDiagnostic, - FixIt: ::libc::c_uint, - ReplacementRange: *mut CXSourceRange) -> - CXString; - pub fn clang_getTranslationUnitSpelling(CTUnit: CXTranslationUnit) -> - CXString; - pub fn clang_createTranslationUnitFromSourceFile(CIdx: CXIndex, - source_filename: - *const ::libc::c_char, - num_clang_command_line_args: - ::libc::c_int, - clang_command_line_args: - *const *const ::libc::c_char, - num_unsaved_files: - ::libc::c_uint, - unsaved_files: - *mut Struct_CXUnsavedFile) - -> CXTranslationUnit; - pub fn clang_createTranslationUnit(arg1: CXIndex, - ast_filename: *const ::libc::c_char) -> - CXTranslationUnit; - pub fn clang_defaultEditingTranslationUnitOptions() -> ::libc::c_uint; - pub fn clang_parseTranslationUnit(CIdx: CXIndex, - source_filename: *const ::libc::c_char, - command_line_args: - *const *const ::libc::c_char, - num_command_line_args: ::libc::c_int, - unsaved_files: - *mut Struct_CXUnsavedFile, - num_unsaved_files: ::libc::c_uint, - options: ::libc::c_uint) -> - CXTranslationUnit; - pub fn clang_defaultSaveOptions(TU: CXTranslationUnit) -> ::libc::c_uint; - pub fn clang_saveTranslationUnit(TU: CXTranslationUnit, - FileName: *const ::libc::c_char, - options: ::libc::c_uint) -> - ::libc::c_int; - pub fn clang_disposeTranslationUnit(arg1: CXTranslationUnit); - pub fn clang_defaultReparseOptions(TU: CXTranslationUnit) -> - ::libc::c_uint; - pub fn clang_reparseTranslationUnit(TU: CXTranslationUnit, - num_unsaved_files: ::libc::c_uint, - unsaved_files: - *mut Struct_CXUnsavedFile, - options: ::libc::c_uint) -> - ::libc::c_int; - pub fn clang_getTUResourceUsageName(kind: Enum_CXTUResourceUsageKind) -> - *const ::libc::c_char; - pub fn clang_getCXTUResourceUsage(TU: CXTranslationUnit) -> - CXTUResourceUsage; - pub fn clang_disposeCXTUResourceUsage(usage: CXTUResourceUsage); - pub fn clang_getNullCursor() -> CXCursor; - pub fn clang_getTranslationUnitCursor(arg1: CXTranslationUnit) -> - CXCursor; - pub fn clang_equalCursors(arg1: CXCursor, arg2: CXCursor) -> - ::libc::c_uint; - pub fn clang_Cursor_isNull(cursor: CXCursor) -> ::libc::c_int; - pub fn clang_hashCursor(arg1: CXCursor) -> ::libc::c_uint; - pub fn clang_getCursorKind(arg1: CXCursor) -> Enum_CXCursorKind; - pub fn clang_isDeclaration(arg1: Enum_CXCursorKind) -> ::libc::c_uint; - pub fn clang_isReference(arg1: Enum_CXCursorKind) -> ::libc::c_uint; - pub fn clang_isExpression(arg1: Enum_CXCursorKind) -> ::libc::c_uint; - pub fn clang_isStatement(arg1: Enum_CXCursorKind) -> ::libc::c_uint; - pub fn clang_isAttribute(arg1: Enum_CXCursorKind) -> ::libc::c_uint; - pub fn clang_isInvalid(arg1: Enum_CXCursorKind) -> ::libc::c_uint; - pub fn clang_isTranslationUnit(arg1: Enum_CXCursorKind) -> ::libc::c_uint; - pub fn clang_isPreprocessing(arg1: Enum_CXCursorKind) -> ::libc::c_uint; - pub fn clang_isUnexposed(arg1: Enum_CXCursorKind) -> ::libc::c_uint; - pub fn clang_getCursorLinkage(cursor: CXCursor) -> Enum_CXLinkageKind; - pub fn clang_getCursorAvailability(cursor: CXCursor) -> - Enum_CXAvailabilityKind; - pub fn clang_getCursorPlatformAvailability(cursor: CXCursor, - always_deprecated: - *mut ::libc::c_int, - deprecated_message: - *mut CXString, - always_unavailable: - *mut ::libc::c_int, - unavailable_message: - *mut CXString, - availability: - *mut CXPlatformAvailability, - availability_size: - ::libc::c_int) -> - ::libc::c_int; - pub fn clang_disposeCXPlatformAvailability(availability: - *mut CXPlatformAvailability); - pub fn clang_getCursorLanguage(cursor: CXCursor) -> Enum_CXLanguageKind; - pub fn clang_Cursor_getTranslationUnit(arg1: CXCursor) -> - CXTranslationUnit; - pub fn clang_createCXCursorSet() -> CXCursorSet; - pub fn clang_disposeCXCursorSet(cset: CXCursorSet); - pub fn clang_CXCursorSet_contains(cset: CXCursorSet, cursor: CXCursor) -> - ::libc::c_uint; - pub fn clang_CXCursorSet_insert(cset: CXCursorSet, cursor: CXCursor) -> - ::libc::c_uint; - pub fn clang_getCursorSemanticParent(cursor: CXCursor) -> CXCursor; - pub fn clang_getCursorLexicalParent(cursor: CXCursor) -> CXCursor; - pub fn clang_getOverriddenCursors(cursor: CXCursor, - overridden: *mut *mut CXCursor, - num_overridden: *mut ::libc::c_uint); - pub fn clang_disposeOverriddenCursors(overridden: *mut CXCursor); - pub fn clang_getIncludedFile(cursor: CXCursor) -> CXFile; - pub fn clang_getCursor(arg1: CXTranslationUnit, arg2: CXSourceLocation) -> - CXCursor; - pub fn clang_getCursorLocation(arg1: CXCursor) -> CXSourceLocation; - pub fn clang_getCursorExtent(arg1: CXCursor) -> CXSourceRange; - pub fn clang_getCursorType(C: CXCursor) -> CXType; - pub fn clang_getTypeSpelling(CT: CXType) -> CXString; - pub fn clang_getTypedefDeclUnderlyingType(C: CXCursor) -> CXType; - pub fn clang_getEnumDeclIntegerType(C: CXCursor) -> CXType; - pub fn clang_getEnumConstantDeclValue(C: CXCursor) -> ::libc::c_longlong; - pub fn clang_getEnumConstantDeclUnsignedValue(C: CXCursor) -> - ::libc::c_ulonglong; - pub fn clang_getFieldDeclBitWidth(C: CXCursor) -> ::libc::c_int; - pub fn clang_Cursor_getNumArguments(C: CXCursor) -> ::libc::c_int; - pub fn clang_Cursor_getArgument(C: CXCursor, i: ::libc::c_uint) -> - CXCursor; - pub fn clang_equalTypes(A: CXType, B: CXType) -> ::libc::c_uint; - pub fn clang_getCanonicalType(T: CXType) -> CXType; - pub fn clang_isConstQualifiedType(T: CXType) -> ::libc::c_uint; - pub fn clang_isVolatileQualifiedType(T: CXType) -> ::libc::c_uint; - pub fn clang_isRestrictQualifiedType(T: CXType) -> ::libc::c_uint; - pub fn clang_getPointeeType(T: CXType) -> CXType; - pub fn clang_getTypeDeclaration(T: CXType) -> CXCursor; - pub fn clang_getDeclObjCTypeEncoding(C: CXCursor) -> CXString; - pub fn clang_getTypeKindSpelling(K: Enum_CXTypeKind) -> CXString; - pub fn clang_getFunctionTypeCallingConv(T: CXType) -> Enum_CXCallingConv; - pub fn clang_getResultType(T: CXType) -> CXType; - pub fn clang_getNumArgTypes(T: CXType) -> ::libc::c_int; - pub fn clang_getArgType(T: CXType, i: ::libc::c_uint) -> CXType; - pub fn clang_isFunctionTypeVariadic(T: CXType) -> ::libc::c_uint; - pub fn clang_getCursorResultType(C: CXCursor) -> CXType; - pub fn clang_isPODType(T: CXType) -> ::libc::c_uint; - pub fn clang_getElementType(T: CXType) -> CXType; - pub fn clang_getNumElements(T: CXType) -> ::libc::c_longlong; - pub fn clang_getArrayElementType(T: CXType) -> CXType; - pub fn clang_getArraySize(T: CXType) -> ::libc::c_longlong; - pub fn clang_Type_getAlignOf(T: CXType) -> ::libc::c_longlong; - pub fn clang_Type_getClassType(T: CXType) -> CXType; - pub fn clang_Type_getSizeOf(T: CXType) -> ::libc::c_longlong; - pub fn clang_Type_getOffsetOf(T: CXType, S: *const ::libc::c_char) -> - ::libc::c_longlong; - pub fn clang_Type_getCXXRefQualifier(T: CXType) -> - Enum_CXRefQualifierKind; - pub fn clang_Cursor_isBitField(C: CXCursor) -> ::libc::c_uint; - pub fn clang_isVirtualBase(arg1: CXCursor) -> ::libc::c_uint; - pub fn clang_getCXXAccessSpecifier(arg1: CXCursor) -> - Enum_CX_CXXAccessSpecifier; - pub fn clang_getNumOverloadedDecls(cursor: CXCursor) -> ::libc::c_uint; - pub fn clang_getOverloadedDecl(cursor: CXCursor, index: ::libc::c_uint) -> - CXCursor; - pub fn clang_getIBOutletCollectionType(arg1: CXCursor) -> CXType; - pub fn clang_visitChildren(parent: CXCursor, visitor: CXCursorVisitor, - client_data: CXClientData) -> ::libc::c_uint; - pub fn clang_getCursorUSR(arg1: CXCursor) -> CXString; - pub fn clang_constructUSR_ObjCClass(class_name: *const ::libc::c_char) -> - CXString; - pub fn clang_constructUSR_ObjCCategory(class_name: *const ::libc::c_char, - category_name: - *const ::libc::c_char) -> - CXString; - pub fn clang_constructUSR_ObjCProtocol(protocol_name: - *const ::libc::c_char) -> - CXString; - pub fn clang_constructUSR_ObjCIvar(name: *const ::libc::c_char, - classUSR: CXString) -> CXString; - pub fn clang_constructUSR_ObjCMethod(name: *const ::libc::c_char, - isInstanceMethod: ::libc::c_uint, - classUSR: CXString) -> CXString; - pub fn clang_constructUSR_ObjCProperty(property: *const ::libc::c_char, - classUSR: CXString) -> CXString; - pub fn clang_getCursorSpelling(arg1: CXCursor) -> CXString; - pub fn clang_Cursor_getSpellingNameRange(arg1: CXCursor, - pieceIndex: ::libc::c_uint, - options: ::libc::c_uint) -> - CXSourceRange; - pub fn clang_getCursorDisplayName(arg1: CXCursor) -> CXString; - pub fn clang_getCursorReferenced(arg1: CXCursor) -> CXCursor; - pub fn clang_getCursorDefinition(arg1: CXCursor) -> CXCursor; - pub fn clang_isCursorDefinition(arg1: CXCursor) -> ::libc::c_uint; - pub fn clang_getCanonicalCursor(arg1: CXCursor) -> CXCursor; - pub fn clang_Cursor_getObjCSelectorIndex(arg1: CXCursor) -> ::libc::c_int; - pub fn clang_Cursor_isDynamicCall(C: CXCursor) -> ::libc::c_int; - pub fn clang_Cursor_getReceiverType(C: CXCursor) -> CXType; - pub fn clang_Cursor_getObjCPropertyAttributes(C: CXCursor, - reserved: ::libc::c_uint) -> - ::libc::c_uint; - pub fn clang_Cursor_getObjCDeclQualifiers(C: CXCursor) -> ::libc::c_uint; - pub fn clang_Cursor_isObjCOptional(C: CXCursor) -> ::libc::c_uint; - pub fn clang_Cursor_isVariadic(C: CXCursor) -> ::libc::c_uint; - pub fn clang_Cursor_getCommentRange(C: CXCursor) -> CXSourceRange; - pub fn clang_Cursor_getRawCommentText(C: CXCursor) -> CXString; - pub fn clang_Cursor_getBriefCommentText(C: CXCursor) -> CXString; - pub fn clang_Cursor_getParsedComment(C: CXCursor) -> CXComment; - pub fn clang_Cursor_getModule(C: CXCursor) -> CXModule; - pub fn clang_Module_getASTFile(Module: CXModule) -> CXFile; - pub fn clang_Module_getParent(Module: CXModule) -> CXModule; - pub fn clang_Module_getName(Module: CXModule) -> CXString; - pub fn clang_Module_getFullName(Module: CXModule) -> CXString; - pub fn clang_Module_getNumTopLevelHeaders(arg1: CXTranslationUnit, - Module: CXModule) -> - ::libc::c_uint; - pub fn clang_Module_getTopLevelHeader(arg1: CXTranslationUnit, - Module: CXModule, - Index: ::libc::c_uint) -> CXFile; - pub fn clang_Comment_getKind(Comment: CXComment) -> Enum_CXCommentKind; - pub fn clang_Comment_getNumChildren(Comment: CXComment) -> ::libc::c_uint; - pub fn clang_Comment_getChild(Comment: CXComment, - ChildIdx: ::libc::c_uint) -> CXComment; - pub fn clang_Comment_isWhitespace(Comment: CXComment) -> ::libc::c_uint; - pub fn clang_InlineContentComment_hasTrailingNewline(Comment: CXComment) - -> ::libc::c_uint; - pub fn clang_TextComment_getText(Comment: CXComment) -> CXString; - pub fn clang_InlineCommandComment_getCommandName(Comment: CXComment) -> - CXString; - pub fn clang_InlineCommandComment_getRenderKind(Comment: CXComment) -> - Enum_CXCommentInlineCommandRenderKind; - pub fn clang_InlineCommandComment_getNumArgs(Comment: CXComment) -> - ::libc::c_uint; - pub fn clang_InlineCommandComment_getArgText(Comment: CXComment, - ArgIdx: ::libc::c_uint) -> - CXString; - pub fn clang_HTMLTagComment_getTagName(Comment: CXComment) -> CXString; - pub fn clang_HTMLStartTagComment_isSelfClosing(Comment: CXComment) -> - ::libc::c_uint; - pub fn clang_HTMLStartTag_getNumAttrs(Comment: CXComment) -> - ::libc::c_uint; - pub fn clang_HTMLStartTag_getAttrName(Comment: CXComment, - AttrIdx: ::libc::c_uint) -> - CXString; - pub fn clang_HTMLStartTag_getAttrValue(Comment: CXComment, - AttrIdx: ::libc::c_uint) -> - CXString; - pub fn clang_BlockCommandComment_getCommandName(Comment: CXComment) -> - CXString; - pub fn clang_BlockCommandComment_getNumArgs(Comment: CXComment) -> - ::libc::c_uint; - pub fn clang_BlockCommandComment_getArgText(Comment: CXComment, - ArgIdx: ::libc::c_uint) -> - CXString; - pub fn clang_BlockCommandComment_getParagraph(Comment: CXComment) -> - CXComment; - pub fn clang_ParamCommandComment_getParamName(Comment: CXComment) -> - CXString; - pub fn clang_ParamCommandComment_isParamIndexValid(Comment: CXComment) -> - ::libc::c_uint; - pub fn clang_ParamCommandComment_getParamIndex(Comment: CXComment) -> - ::libc::c_uint; - pub fn clang_ParamCommandComment_isDirectionExplicit(Comment: CXComment) - -> ::libc::c_uint; - pub fn clang_ParamCommandComment_getDirection(Comment: CXComment) -> - Enum_CXCommentParamPassDirection; - pub fn clang_TParamCommandComment_getParamName(Comment: CXComment) -> - CXString; - pub fn clang_TParamCommandComment_isParamPositionValid(Comment: CXComment) - -> ::libc::c_uint; - pub fn clang_TParamCommandComment_getDepth(Comment: CXComment) -> - ::libc::c_uint; - pub fn clang_TParamCommandComment_getIndex(Comment: CXComment, - Depth: ::libc::c_uint) -> - ::libc::c_uint; - pub fn clang_VerbatimBlockLineComment_getText(Comment: CXComment) -> - CXString; - pub fn clang_VerbatimLineComment_getText(Comment: CXComment) -> CXString; - pub fn clang_HTMLTagComment_getAsString(Comment: CXComment) -> CXString; - pub fn clang_FullComment_getAsHTML(Comment: CXComment) -> CXString; - pub fn clang_FullComment_getAsXML(Comment: CXComment) -> CXString; - pub fn clang_CXXMethod_isPureVirtual(C: CXCursor) -> ::libc::c_uint; - pub fn clang_CXXMethod_isStatic(C: CXCursor) -> ::libc::c_uint; - pub fn clang_CXXMethod_isVirtual(C: CXCursor) -> ::libc::c_uint; - pub fn clang_getTemplateCursorKind(C: CXCursor) -> Enum_CXCursorKind; - pub fn clang_getSpecializedCursorTemplate(C: CXCursor) -> CXCursor; - pub fn clang_getCursorReferenceNameRange(C: CXCursor, - NameFlags: ::libc::c_uint, - PieceIndex: ::libc::c_uint) -> - CXSourceRange; - pub fn clang_getTokenKind(arg1: CXToken) -> CXTokenKind; - pub fn clang_getTokenSpelling(arg1: CXTranslationUnit, arg2: CXToken) -> - CXString; - pub fn clang_getTokenLocation(arg1: CXTranslationUnit, arg2: CXToken) -> - CXSourceLocation; - pub fn clang_getTokenExtent(arg1: CXTranslationUnit, arg2: CXToken) -> - CXSourceRange; - pub fn clang_tokenize(TU: CXTranslationUnit, Range: CXSourceRange, - Tokens: *mut *mut CXToken, - NumTokens: *mut ::libc::c_uint); - pub fn clang_annotateTokens(TU: CXTranslationUnit, Tokens: *mut CXToken, - NumTokens: ::libc::c_uint, - Cursors: *mut CXCursor); - pub fn clang_disposeTokens(TU: CXTranslationUnit, Tokens: *mut CXToken, - NumTokens: ::libc::c_uint); - pub fn clang_getCursorKindSpelling(Kind: Enum_CXCursorKind) -> CXString; - pub fn clang_getDefinitionSpellingAndExtent(arg1: CXCursor, - startBuf: - *mut *const ::libc::c_char, - endBuf: - *mut *const ::libc::c_char, - startLine: - *mut ::libc::c_uint, - startColumn: - *mut ::libc::c_uint, - endLine: *mut ::libc::c_uint, - endColumn: - *mut ::libc::c_uint); - pub fn clang_enableStackTraces(); - pub fn clang_executeOnThread(_fn: - ::std::option::Option, - user_data: *mut ::libc::c_void, - stack_size: ::libc::c_uint); - pub fn clang_getCompletionChunkKind(completion_string: CXCompletionString, - chunk_number: ::libc::c_uint) -> - Enum_CXCompletionChunkKind; - pub fn clang_getCompletionChunkText(completion_string: CXCompletionString, - chunk_number: ::libc::c_uint) -> - CXString; - pub fn clang_getCompletionChunkCompletionString(completion_string: - CXCompletionString, - chunk_number: - ::libc::c_uint) -> - CXCompletionString; - pub fn clang_getNumCompletionChunks(completion_string: CXCompletionString) - -> ::libc::c_uint; - pub fn clang_getCompletionPriority(completion_string: CXCompletionString) - -> ::libc::c_uint; - pub fn clang_getCompletionAvailability(completion_string: - CXCompletionString) -> - Enum_CXAvailabilityKind; - pub fn clang_getCompletionNumAnnotations(completion_string: - CXCompletionString) -> - ::libc::c_uint; - pub fn clang_getCompletionAnnotation(completion_string: - CXCompletionString, - annotation_number: ::libc::c_uint) -> - CXString; - pub fn clang_getCompletionParent(completion_string: CXCompletionString, - kind: *mut Enum_CXCursorKind) -> - CXString; - pub fn clang_getCompletionBriefComment(completion_string: - CXCompletionString) -> - CXString; - pub fn clang_getCursorCompletionString(cursor: CXCursor) -> - CXCompletionString; - pub fn clang_defaultCodeCompleteOptions() -> ::libc::c_uint; - pub fn clang_codeCompleteAt(TU: CXTranslationUnit, - complete_filename: *const ::libc::c_char, - complete_line: ::libc::c_uint, - complete_column: ::libc::c_uint, - unsaved_files: *mut Struct_CXUnsavedFile, - num_unsaved_files: ::libc::c_uint, - options: ::libc::c_uint) -> - *mut CXCodeCompleteResults; - pub fn clang_sortCodeCompletionResults(Results: *mut CXCompletionResult, - NumResults: ::libc::c_uint); - pub fn clang_disposeCodeCompleteResults(Results: - *mut CXCodeCompleteResults); - pub fn clang_codeCompleteGetNumDiagnostics(Results: - *mut CXCodeCompleteResults) - -> ::libc::c_uint; - pub fn clang_codeCompleteGetDiagnostic(Results: - *mut CXCodeCompleteResults, - Index: ::libc::c_uint) -> - CXDiagnostic; - pub fn clang_codeCompleteGetContexts(Results: *mut CXCodeCompleteResults) - -> ::libc::c_ulonglong; - pub fn clang_codeCompleteGetContainerKind(Results: - *mut CXCodeCompleteResults, - IsIncomplete: - *mut ::libc::c_uint) -> - Enum_CXCursorKind; - pub fn clang_codeCompleteGetContainerUSR(Results: - *mut CXCodeCompleteResults) - -> CXString; - pub fn clang_codeCompleteGetObjCSelector(Results: - *mut CXCodeCompleteResults) - -> CXString; - pub fn clang_getClangVersion() -> CXString; - pub fn clang_toggleCrashRecovery(isEnabled: ::libc::c_uint); - pub fn clang_getInclusions(tu: CXTranslationUnit, - visitor: CXInclusionVisitor, - client_data: CXClientData); - pub fn clang_getRemappings(path: *const ::libc::c_char) -> CXRemapping; - pub fn clang_getRemappingsFromFileList(filePaths: - *mut *const ::libc::c_char, - numFiles: ::libc::c_uint) -> - CXRemapping; - pub fn clang_remap_getNumFiles(arg1: CXRemapping) -> ::libc::c_uint; - pub fn clang_remap_getFilenames(arg1: CXRemapping, index: ::libc::c_uint, - original: *mut CXString, - transformed: *mut CXString); - pub fn clang_remap_dispose(arg1: CXRemapping); - pub fn clang_findReferencesInFile(cursor: CXCursor, file: CXFile, - visitor: CXCursorAndRangeVisitor) -> - CXResult; - pub fn clang_findIncludesInFile(TU: CXTranslationUnit, file: CXFile, - visitor: CXCursorAndRangeVisitor) -> - CXResult; - pub fn clang_index_isEntityObjCContainerKind(arg1: CXIdxEntityKind) -> - ::libc::c_int; - pub fn clang_index_getObjCContainerDeclInfo(arg1: *const CXIdxDeclInfo) -> - *const CXIdxObjCContainerDeclInfo; - pub fn clang_index_getObjCInterfaceDeclInfo(arg1: *const CXIdxDeclInfo) -> - *const CXIdxObjCInterfaceDeclInfo; - pub fn clang_index_getObjCCategoryDeclInfo(arg1: *const CXIdxDeclInfo) -> - *const CXIdxObjCCategoryDeclInfo; - pub fn clang_index_getObjCProtocolRefListInfo(arg1: *const CXIdxDeclInfo) - -> *const CXIdxObjCProtocolRefListInfo; - pub fn clang_index_getObjCPropertyDeclInfo(arg1: *const CXIdxDeclInfo) -> - *const CXIdxObjCPropertyDeclInfo; - pub fn clang_index_getIBOutletCollectionAttrInfo(arg1: - *const CXIdxAttrInfo) - -> *const CXIdxIBOutletCollectionAttrInfo; - pub fn clang_index_getCXXClassDeclInfo(arg1: *const CXIdxDeclInfo) -> - *const CXIdxCXXClassDeclInfo; - pub fn clang_index_getClientContainer(arg1: *const CXIdxContainerInfo) -> - CXIdxClientContainer; - pub fn clang_index_setClientContainer(arg1: *const CXIdxContainerInfo, - arg2: CXIdxClientContainer); - pub fn clang_index_getClientEntity(arg1: *const CXIdxEntityInfo) -> - CXIdxClientEntity; - pub fn clang_index_setClientEntity(arg1: *const CXIdxEntityInfo, - arg2: CXIdxClientEntity); - pub fn clang_IndexAction_create(CIdx: CXIndex) -> CXIndexAction; - pub fn clang_IndexAction_dispose(arg1: CXIndexAction); - pub fn clang_indexSourceFile(arg1: CXIndexAction, - client_data: CXClientData, - index_callbacks: *mut IndexerCallbacks, - index_callbacks_size: ::libc::c_uint, - index_options: ::libc::c_uint, - source_filename: *const ::libc::c_char, - command_line_args: - *const *const ::libc::c_char, - num_command_line_args: ::libc::c_int, - unsaved_files: *mut Struct_CXUnsavedFile, - num_unsaved_files: ::libc::c_uint, - out_TU: *mut CXTranslationUnit, - TU_options: ::libc::c_uint) -> ::libc::c_int; - pub fn clang_indexTranslationUnit(arg1: CXIndexAction, - client_data: CXClientData, - index_callbacks: *mut IndexerCallbacks, - index_callbacks_size: ::libc::c_uint, - index_options: ::libc::c_uint, - arg2: CXTranslationUnit) -> - ::libc::c_int; - pub fn clang_indexLoc_getFileLocation(loc: CXIdxLoc, - indexFile: *mut CXIdxClientFile, - file: *mut CXFile, - line: *mut ::libc::c_uint, - column: *mut ::libc::c_uint, - offset: *mut ::libc::c_uint); - pub fn clang_indexLoc_getCXSourceLocation(loc: CXIdxLoc) -> - CXSourceLocation; -} diff --git a/gen.rs b/gen.rs deleted file mode 100644 index 87b37b47..00000000 --- a/gen.rs +++ /dev/null @@ -1,920 +0,0 @@ -#![allow(unused_must_use)] - -use std::cell::RefCell; -use std::option; -use std::iter; -use std::vec::Vec; -use std::gc::{Gc, GC}; - -use syntax::abi; -use syntax::ast; -use syntax::codemap::{Span, respan, ExpnInfo, NameAndSpan, MacroBang}; -use syntax::ext::base; -use syntax::ext::build::AstBuilder; -use syntax::ext::expand::ExpansionConfig; -use syntax::owned_slice::OwnedSlice; -use syntax::parse; -use syntax::attr::mk_attr_id; - -use types::*; - -struct GenCtx<'r> { - ext_cx: base::ExtCtxt<'r>, - unnamed_ty: uint, - abi: abi::Abi, - span: Span -} - -fn first((val, _): (A, B)) -> A { - return val; -} - -fn ref_eq<'a, 'b, T>(thing: &'a T, other: &'b T) -> bool { - (thing as *const T) == (other as *const T) -} - -fn to_intern_str(ctx: &mut GenCtx, s: String) -> parse::token::InternedString { - let id = ctx.ext_cx.ident_of(s.as_slice()); - parse::token::get_ident(id) -} - -fn empty_generics() -> ast::Generics { - ast::Generics { - lifetimes: Vec::new(), - ty_params: OwnedSlice::empty(), - } -} - -fn rust_id(ctx: &mut GenCtx, name: String) -> (String, bool) { - let token = parse::token::IDENT(ctx.ext_cx.ident_of(name.as_slice()), false); - if parse::token::is_any_keyword(&token) || "bool" == name.as_slice() { - ("_".to_string().append(name.as_slice()), true) - } else { - (name, false) - } - -} - -fn rust_type_id(ctx: &mut GenCtx, name: String) -> String { - if "bool" == name.as_slice() || - "uint" == name.as_slice() || - "u8" == name.as_slice() || - "u16" == name.as_slice() || - "u32" == name.as_slice() || - "f32" == name.as_slice() || - "f64" == name.as_slice() || - "i8" == name.as_slice() || - "i16" == name.as_slice() || - "i32" == name.as_slice() || - "i64" == name.as_slice() || - "Self" == name.as_slice() || - "str" == name.as_slice() { - "_".to_string().append(name.as_slice()) - } else { - let (n, _) = rust_id(ctx, name); - n - } -} - -fn unnamed_name(ctx: &mut GenCtx, name: String) -> String { - return if name.is_empty() { - ctx.unnamed_ty += 1; - format!("Unnamed{}", ctx.unnamed_ty) - } else { - name - }; -} - -fn struct_name(name: String) -> String { - format!("Struct_{}", name) -} - -fn union_name(name: String) -> String { - format!("Union_{}", name) -} - -fn enum_name(name: String) -> String { - format!("Enum_{}", name) -} - -pub fn gen_mod(abi: &str, links: &[(String, Option)], globs: Vec, span: Span) -> Vec> { - let abi = match abi { - "cdecl" => abi::Cdecl, - "stdcall" => abi::Stdcall, - "fastcall" => abi::Fastcall, - "aapcs" => abi::Aapcs, - "Rust" => abi::Rust, - "rust-intrinsic" => abi::RustIntrinsic, - _ => abi::C - }; - - // Create a dummy ExtCtxt. We only need this for string interning and that uses TLS. - let cfg = ExpansionConfig { - deriving_hash_type_parameter: false, - crate_id: from_str("xxx").unwrap(), - }; - let sess = &parse::new_parse_sess(); - let mut ctx = GenCtx { - ext_cx: base::ExtCtxt::new( - sess, - Vec::new(), - cfg, - ), - unnamed_ty: 0, - abi: abi, - span: span - }; - ctx.ext_cx.bt_push(ExpnInfo { - call_site: ctx.span, - callee: NameAndSpan { name: String::new(), format: MacroBang, span: None } - }); - let uniq_globs = tag_dup_decl(globs); - - let mut fs = vec!(); - let mut vs = vec!(); - let mut gs = vec!(); - for g in uniq_globs.move_iter() { - match g { - GOther => {} - GFunc(_) => fs.push(g), - GVar(_) => vs.push(g), - _ => gs.push(g) - } - } - - let mut defs = vec!(); - gs = remove_redundant_decl(gs); - - for g in gs.move_iter() { - match g { - GType(ti) => { - let t = ti.borrow().clone(); - defs.push_all_move(ctypedef_to_rs(&mut ctx, t.name.clone(), &t.ty)) - }, - GCompDecl(ci) => { - { - let mut c = ci.borrow_mut(); - c.name = unnamed_name(&mut ctx, c.name.clone()); - } - let c = ci.borrow().clone(); - if c.cstruct { - defs.push(opaque_to_rs(&mut ctx, struct_name(c.name))); - } else { - defs.push(opaque_to_rs(&mut ctx, union_name(c.name))); - } - }, - GComp(ci) => { - { - let mut c = ci.borrow_mut(); - c.name = unnamed_name(&mut ctx, c.name.clone()); - } - let c = ci.borrow().clone(); - if c.cstruct { - defs.push(cstruct_to_rs(&mut ctx, struct_name(c.name.clone()), - // this clone is necessary to prevent dynamic borrow - // check errors. - // FIXME: remove the @mut in types.rs to fix this - c.fields.clone())) - } else { - defs.push_all_move(cunion_to_rs(&mut ctx, union_name(c.name.clone()), - c.layout, c.fields)) - } - }, - GEnumDecl(ei) => { - { - let mut e = ei.borrow_mut(); - e.name = unnamed_name(&mut ctx, e.name.clone()); - } - let e = ei.borrow().clone(); - defs.push(opaque_to_rs(&mut ctx, enum_name(e.name))); - }, - GEnum(ei) => { - { - let mut e = ei.borrow_mut(); - e.name = unnamed_name(&mut ctx, e.name.clone()); - } - let e = ei.borrow().clone(); - defs.push_all_move(cenum_to_rs(&mut ctx, enum_name(e.name.clone()), e.kind, e.items)) - }, - _ => { } - } - } - - let vars = vs.move_iter().map(|v| { - match v { - GVar(vi) => { - let v = vi.borrow(); - cvar_to_rs(&mut ctx, v.name.clone(), &v.ty, v.is_const) - }, - _ => unreachable!() - } - }).collect(); - - let funcs = fs.move_iter().map(|f| { - match f { - GFunc(vi) => { - let v = vi.borrow(); - match v.ty { - TFunc(ref rty, ref aty, var) => - cfunc_to_rs(&mut ctx, v.name.clone(), - *rty, aty.as_slice(), var), - _ => unreachable!() - } - }, - _ => unreachable!() - } - }).collect(); - - defs.push(mk_extern(&mut ctx, links, vars, funcs)); - - //let attrs = vec!(mk_attr_list(&mut ctx, "allow", ["dead_code", "non_camel_case_types", "uppercase_variables"])); - - defs -} - -fn mk_extern(ctx: &mut GenCtx, links: &[(String, Option)], - vars: Vec>, - funcs: Vec>) -> Gc { - let attrs = if links.is_empty() { - Vec::new() - } else { - links.iter().map(|&(ref l, ref k)| { - let link_name = box(GC) respan(ctx.span, ast::MetaNameValue( - to_intern_str(ctx, "name".to_string()), - respan(ctx.span, ast::LitStr( - to_intern_str(ctx, l.to_string()), - ast::CookedStr - )) - )); - let link_args = match k { - &None => vec!(link_name), - &Some(ref k) => vec!(link_name, box(GC) respan(ctx.span, ast::MetaNameValue( - to_intern_str(ctx, "kind".to_string()), - respan(ctx.span, ast::LitStr( - to_intern_str(ctx, k.to_string()), - ast::CookedStr - )) - ))) - }; - respan(ctx.span, ast::Attribute_ { - id: mk_attr_id(), - style: ast::AttrOuter, - value: box(GC) respan(ctx.span, ast::MetaList( - to_intern_str(ctx, "link".to_string()), - link_args) - ), - is_sugared_doc: false - }) - }).collect() - }; - - let mut items = Vec::new(); - items.push_all_move(vars); - items.push_all_move(funcs); - let ext = ast::ItemForeignMod(ast::ForeignMod { - abi: ctx.abi, - view_items: Vec::new(), - items: items - }); - - return box(GC) ast::Item { - ident: ctx.ext_cx.ident_of(""), - attrs: attrs, - id: ast::DUMMY_NODE_ID, - node: ext, - vis: ast::Inherited, - span: ctx.span - }; -} - -fn remove_redundant_decl(gs: Vec) -> Vec { - fn check_decl(a: &Global, ty: &Type) -> bool { - match *a { - GComp(ci1) => match *ty { - TComp(ci2) => { - ref_eq(ci1, ci2) && ci1.borrow().name.is_empty() - }, - _ => false - }, - GEnum(ei1) => match *ty { - TEnum(ei2) => { - ref_eq(ei1, ei2) && ei1.borrow().name.is_empty() - }, - _ => false - }, - _ => false - } - } - - let typedefs: Vec = gs.iter().filter_map(|g| - match *g { - GType(ref ti) => Some(ti.borrow().ty.clone()), - _ => None - } - ).collect(); - - return gs.move_iter().filter(|g| - !typedefs.iter().any(|t| check_decl(g, t)) - ).collect(); -} - -fn tag_dup_decl(gs: Vec) -> Vec { - fn check(name1: &str, name2: &str) -> bool { - !name1.is_empty() && name1 == name2 - } - - fn check_dup(g1: &Global, g2: &Global) -> bool { - match (g1, g2) { - (>ype(ti1), >ype(ti2)) => { - let a = ti1.borrow(); - let b = ti2.borrow(); - check(a.name.as_slice(), b.name.as_slice()) - }, - (&GComp(ci1), &GComp(ci2)) => { - let a = ci1.borrow(); - let b = ci2.borrow(); - check(a.name.as_slice(), b.name.as_slice()) - }, - (&GCompDecl(ci1), &GCompDecl(ci2)) => { - let a = ci1.borrow(); - let b = ci2.borrow(); - check(a.name.as_slice(), b.name.as_slice()) - }, - (&GEnum(ei1), &GEnum(ei2)) => { - let a = ei1.borrow(); - let b = ei2.borrow(); - check(a.name.as_slice(), b.name.as_slice()) - }, - (&GEnumDecl(ei1), &GEnumDecl(ei2)) => { - let a = ei1.borrow(); - let b = ei2.borrow(); - check(a.name.as_slice(), b.name.as_slice()) - }, - (&GVar(vi1), &GVar(vi2)) => { - let a = vi1.borrow(); - let b = vi2.borrow(); - check(a.name.as_slice(), b.name.as_slice()) - }, - (&GFunc(vi1), &GFunc(vi2)) => { - let a = vi1.borrow(); - let b = vi2.borrow(); - check(a.name.as_slice(), b.name.as_slice()) - }, - _ => false - } - } - - if gs.is_empty() { - return gs; - } - - let len = gs.len(); - let mut res: Vec = vec!(); - res.push(*gs.get(0)); - - for i in iter::range(1, len) { - let mut dup = false; - for j in iter::range(0, i-1) { - if check_dup(gs.get(i), gs.get(j)) { - dup = true; - break; - } - } - if !dup { - res.push(*gs.get(i)); - } - } - - return res; -} - -fn ctypedef_to_rs(ctx: &mut GenCtx, name: String, ty: &Type) -> Vec> { - fn mk_item(ctx: &mut GenCtx, name: String, ty: &Type) -> Gc { - let rust_name = rust_type_id(ctx, name); - let rust_ty = cty_to_rs(ctx, ty); - let base = ast::ItemTy( - box(GC) ast::Ty { - id: ast::DUMMY_NODE_ID, - node: rust_ty.node, - span: ctx.span, - }, - empty_generics() - ); - - return box(GC) ast::Item { - ident: ctx.ext_cx.ident_of(rust_name.as_slice()), - attrs: Vec::new(), - id: ast::DUMMY_NODE_ID, - node: base, - vis: ast::Public, - span: ctx.span - }; - } - - return match *ty { - TComp(ci) => { - let is_empty = ci.borrow().name.is_empty(); - if is_empty { - ci.borrow_mut().name = name.clone(); - let c = ci.borrow().clone(); - if c.cstruct { - vec!(cstruct_to_rs(ctx, name, c.fields)) - } else { - cunion_to_rs(ctx, name, c.layout, c.fields) - } - } else { - vec!(mk_item(ctx, name, ty)) - } - }, - TEnum(ei) => { - let is_empty = ei.borrow().name.is_empty(); - if is_empty { - ei.borrow_mut().name = name.clone(); - let e = ei.borrow().clone(); - cenum_to_rs(ctx, name, e.kind, e.items) - } else { - vec!(mk_item(ctx, name, ty)) - } - }, - _ => vec!(mk_item(ctx, name, ty)) - } -} - -fn cstruct_to_rs(ctx: &mut GenCtx, name: String, fields: Vec) -> Gc { - let mut unnamed: uint = 0; - let fs = fields.iter().map(|f| { - let f_name = if f.name.is_empty() || "_" == f.name.as_slice() { - unnamed += 1; - format!("unnamed_field{}", unnamed) - } else { - rust_type_id(ctx, f.name.clone()) - }; - - let f_ty = box(GC) cty_to_rs(ctx, &f.ty); - - respan(ctx.span, ast::StructField_ { - kind: ast::NamedField( - ctx.ext_cx.ident_of(f_name.as_slice()), - ast::Public, - ), - id: ast::DUMMY_NODE_ID, - ty: f_ty, - attrs: Vec::new() - }) - }).collect(); - - let def = ast::ItemStruct( - box(GC) ast::StructDef { - fields: fs, - ctor_id: None, - super_struct: None, - is_virtual: false - }, - empty_generics() - ); - - let id = rust_type_id(ctx, name); - return box(GC) ast::Item { ident: ctx.ext_cx.ident_of(id.as_slice()), - attrs: vec!(mk_repr_attr(ctx)), - id: ast::DUMMY_NODE_ID, - node: def, - vis: ast::Public, - span: ctx.span - }; -} - -fn opaque_to_rs(ctx: &mut GenCtx, name: String) -> Gc { - let def = ast::ItemEnum( - ast::EnumDef { - variants: vec!() - }, - empty_generics() - ); - - let id = rust_type_id(ctx, name); - return box(GC) ast::Item { ident: ctx.ext_cx.ident_of(id.as_slice()), - attrs: Vec::new(), - id: ast::DUMMY_NODE_ID, - node: def, - vis: ast::Public, - span: ctx.span - }; -} - -fn cunion_to_rs(ctx: &mut GenCtx, name: String, layout: Layout, fields: Vec) -> Vec> { - fn mk_item(ctx: &mut GenCtx, name: String, item: ast::Item_, vis: - ast::Visibility, attrs: Vec) -> Gc { - return box(GC) ast::Item { - ident: ctx.ext_cx.ident_of(name.as_slice()), - attrs: attrs, - id: ast::DUMMY_NODE_ID, - node: item, - vis: vis, - span: ctx.span - }; - } - - let ci = box(GC) RefCell::new(CompInfo::new(name.clone(), false, fields.clone(), layout)); - let union = TNamed(box(GC) RefCell::new(TypeInfo::new(name.clone(), TComp(ci)))); - - let ty_name = match layout.align { - 1 => "u8", - 2 => "u16", - 4 => "u32", - 8 => "u64", - _ => "u8", - }; - let data_len = if ty_name == "u8" { layout.size } else { layout.size / layout.align }; - let base_ty = mk_ty(ctx, false, vec!(ty_name.to_string())); - let data_ty = box(GC) mk_arrty(ctx, &base_ty, data_len); - let data = respan(ctx.span, ast::StructField_ { - kind: ast::NamedField( - ctx.ext_cx.ident_of("data"), - ast::Public, - ), - id: ast::DUMMY_NODE_ID, - ty: data_ty, - attrs: Vec::new() - }); - - let def = ast::ItemStruct( - box(GC) ast::StructDef { - fields: Vec::from_elem(1, data), - ctor_id: None, - super_struct: None, - is_virtual: false - }, - empty_generics() - ); - let union_id = rust_type_id(ctx, name); - let union_attrs = vec!(mk_repr_attr(ctx)); - let union_def = mk_item(ctx, union_id, def, ast::Public, union_attrs); - - let expr = quote_expr!( - &ctx.ext_cx, - unsafe { ::std::mem::transmute(self) } - ); - let mut unnamed: uint = 0; - let fs = fields.iter().map(|f| { - let f_name = if f.name.is_empty() || "_" == f.name.as_slice() { - unnamed += 1; - format!("unnamed_field{}", unnamed) - } else { - first(rust_id(ctx, f.name.clone())) - }; - - let ret_ty = box(GC) cty_to_rs(ctx, &TPtr(box f.ty.clone(), false, Layout::zero())); - let body = box(GC) ast::Block { - view_items: Vec::new(), - stmts: Vec::new(), - expr: Some(expr), - id: ast::DUMMY_NODE_ID, - rules: ast::DefaultBlock, - span: ctx.span - }; - - box(GC) ast::Method { - ident: ctx.ext_cx.ident_of(f_name.as_slice()), - attrs: Vec::new(), - generics: empty_generics(), - explicit_self: respan(ctx.span, ast::SelfRegion(None, ast::MutMutable)), - fn_style: ast::NormalFn, - decl: box(GC) ast::FnDecl { - inputs: Vec::from_elem(1, ast::Arg::new_self(ctx.span, ast::MutImmutable)), - output: ret_ty, - cf: ast::Return, - variadic: false - }, - body: body, - id: ast::DUMMY_NODE_ID, - span: ctx.span, - vis: ast::Public - } - }).collect(); - - let methods = ast::ItemImpl( - empty_generics(), - None, - box(GC) cty_to_rs(ctx, &union), - fs - ); - - return vec!( - union_def, - mk_item(ctx, "".to_string(), methods, ast::Inherited, Vec::new()) - ); -} - -fn cenum_to_rs(ctx: &mut GenCtx, name: String, kind: IKind, items: Vec) -> Vec> { - let ty = TInt(kind, Layout::zero()); - let ty_id = rust_type_id(ctx, name); - let ty_def = ctypedef_to_rs(ctx, ty_id, &ty); - let val_ty = cty_to_rs(ctx, &ty); - let mut def = ty_def; - - for it in items.iter() { - let cst = ast::ItemStatic( - box(GC) val_ty.clone(), - ast::MutImmutable, - ctx.ext_cx.expr_lit(ctx.span, ast::LitIntUnsuffixed(it.val)) - ); - - let id = first(rust_id(ctx, it.name.clone())); - let val_def = box(GC) ast::Item { - ident: ctx.ext_cx.ident_of(id.as_slice()), - attrs: Vec::new(), - id: ast::DUMMY_NODE_ID, - node: cst, - vis: ast::Public, - span: ctx.span - }; - - def.push(val_def); - } - - return def; -} - -fn mk_link_name_attr(ctx: &mut GenCtx, name: String) -> ast::Attribute { - let lit = respan(ctx.span, ast::LitStr( - to_intern_str(ctx, name), - ast::CookedStr - )); - let attr_val = box(GC) respan(ctx.span, ast::MetaNameValue( - to_intern_str(ctx, "link_name".to_string()), lit - )); - let attr = ast::Attribute_ { - id: mk_attr_id(), - style: ast::AttrOuter, - value: attr_val, - is_sugared_doc: false - }; - respan(ctx.span, attr) -} - -fn mk_repr_attr(ctx: &mut GenCtx) -> ast::Attribute { - let attr_val = box(GC) respan(ctx.span, ast::MetaList( - to_intern_str(ctx, "repr".to_string()), - vec!(box(GC) respan(ctx.span, ast::MetaWord(to_intern_str(ctx, "C".to_string())))) - )); - - respan(ctx.span, ast::Attribute_ { - id: mk_attr_id(), - style: ast::AttrOuter, - value: attr_val, - is_sugared_doc: false - }) -} - -fn cvar_to_rs(ctx: &mut GenCtx, name: String, - ty: &Type, - is_const: bool) -> Gc { - let (rust_name, was_mangled) = rust_id(ctx, name.clone()); - - let mut attrs = Vec::new(); - if was_mangled { - attrs.push(mk_link_name_attr(ctx, name)); - } - - return box(GC) ast::ForeignItem { - ident: ctx.ext_cx.ident_of(rust_name.as_slice()), - attrs: attrs, - node: ast::ForeignItemStatic(box(GC) cty_to_rs(ctx, ty), !is_const), - id: ast::DUMMY_NODE_ID, - span: ctx.span, - vis: ast::Public, - }; -} - -fn cfuncty_to_rs(ctx: &mut GenCtx, - rty: &Type, - aty: &[(String, Type)], - var: bool) -> ast::FnDecl { - - let ret = box(GC) match *rty { - TVoid => ast::Ty { - id: ast::DUMMY_NODE_ID, - node: ast::TyNil, - span: ctx.span - }, - _ => cty_to_rs(ctx, rty) - }; - - let mut unnamed: uint = 0; - let args: Vec = aty.iter().map(|arg| { - let (ref n, ref t) = *arg; - - let arg_name = if n.is_empty() { - unnamed += 1; - format!("arg{}", unnamed) - } else { - first(rust_id(ctx, n.clone())) - }; - - let arg_ty = box(GC) cty_to_rs(ctx, t); - - ast::Arg { - ty: arg_ty, - pat: box(GC) ast::Pat { - id: ast::DUMMY_NODE_ID, - node: ast::PatIdent( - ast::BindByValue(ast::MutImmutable), - respan(ctx.span, ctx.ext_cx.ident_of(arg_name.as_slice())), - None - ), - span: ctx.span - }, - id: ast::DUMMY_NODE_ID, - } - }).collect(); - - let var = !args.is_empty() && var; - return ast::FnDecl { - inputs: args, - output: ret, - cf: ast::Return, - variadic: var - }; -} - -fn cfunc_to_rs(ctx: &mut GenCtx, name: String, rty: &Type, - aty: &[(String, Type)], - var: bool) -> Gc { - let var = !aty.is_empty() && var; - let decl = ast::ForeignItemFn( - box(GC) cfuncty_to_rs(ctx, rty, aty, var), - empty_generics() - ); - - let (rust_name, was_mangled) = rust_id(ctx, name.clone()); - - let mut attrs = Vec::new(); - if was_mangled { - attrs.push(mk_link_name_attr(ctx, name)); - } - - return box(GC) ast::ForeignItem { - ident: ctx.ext_cx.ident_of(rust_name.as_slice()), - attrs: attrs, - node: decl, - id: ast::DUMMY_NODE_ID, - span: ctx.span, - vis: ast::Public, - }; -} - -fn cty_to_rs(ctx: &mut GenCtx, ty: &Type) -> ast::Ty { - return match *ty { - TVoid => mk_ty(ctx, true, vec!("libc".to_string(), "c_void".to_string())), - TInt(i, _) => match i { - IBool => mk_ty(ctx, true, vec!("libc".to_string(), "c_int".to_string())), - ISChar => mk_ty(ctx, true, vec!("libc".to_string(), "c_char".to_string())), - IUChar => mk_ty(ctx, true, vec!("libc".to_string(), "c_uchar".to_string())), - IInt => mk_ty(ctx, true, vec!("libc".to_string(), "c_int".to_string())), - IUInt => mk_ty(ctx, true, vec!("libc".to_string(), "c_uint".to_string())), - IShort => mk_ty(ctx, true, vec!("libc".to_string(), "c_short".to_string())), - IUShort => mk_ty(ctx, true, vec!("libc".to_string(), "c_ushort".to_string())), - ILong => mk_ty(ctx, true, vec!("libc".to_string(), "c_long".to_string())), - IULong => mk_ty(ctx, true, vec!("libc".to_string(), "c_ulong".to_string())), - ILongLong => mk_ty(ctx, true, vec!("libc".to_string(), "c_longlong".to_string())), - IULongLong => mk_ty(ctx, true, vec!("libc".to_string(), "c_ulonglong".to_string())) - }, - TFloat(f, _) => match f { - FFloat => mk_ty(ctx, true, vec!("libc".to_string(), "c_float".to_string())), - FDouble => mk_ty(ctx, true, vec!("libc".to_string(), "c_double".to_string())) - }, - TPtr(ref t, is_const, _) => { - let id = cty_to_rs(ctx, *t); - mk_ptrty(ctx, &id, is_const) - }, - TArray(ref t, s, _) => { - let ty = cty_to_rs(ctx, *t); - mk_arrty(ctx, &ty, s) - }, - TFunc(ref rty, ref atys, var) => { - let decl = cfuncty_to_rs(ctx, *rty, atys.as_slice(), var); - mk_fnty(ctx, &decl) - }, - TNamed(ti) => { - let id = rust_type_id(ctx, ti.borrow().name.clone()); - mk_ty(ctx, false, vec!(id)) - }, - TComp(ci) => { - let mut c = ci.borrow_mut(); - c.name = unnamed_name(ctx, c.name.clone()); - if c.cstruct { - mk_ty(ctx, false, vec!(struct_name(c.name.clone()))) - } else { - mk_ty(ctx, false, vec!(union_name(c.name.clone()))) - } - }, - TEnum(ei) => { - let mut e = ei.borrow_mut(); - e.name = unnamed_name(ctx, e.name.clone()); - mk_ty(ctx, false, vec!(enum_name(e.name.clone()))) - } - }; -} - -fn mk_ty(ctx: &mut GenCtx, global: bool, segments: Vec) -> ast::Ty { - let ty = ast::TyPath( - ast::Path { - span: ctx.span, - global: global, - segments: segments.iter().map(|s| { - ast::PathSegment { - identifier: ctx.ext_cx.ident_of(s.as_slice()), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), - } - }).collect() - }, - option::None, - ast::DUMMY_NODE_ID - ); - - return ast::Ty { - id: ast::DUMMY_NODE_ID, - node: ty, - span: ctx.span - }; -} - -fn mk_ptrty(ctx: &mut GenCtx, base: &ast::Ty, is_const: bool) -> ast::Ty { - let ty = ast::TyPtr(ast::MutTy { - ty: box(GC) base.clone(), - mutbl: if is_const { ast::MutImmutable } else { ast::MutMutable } - }); - - return ast::Ty { - id: ast::DUMMY_NODE_ID, - node: ty, - span: ctx.span - }; -} - -fn mk_arrty(ctx: &mut GenCtx, base: &ast::Ty, n: uint) -> ast::Ty { - let sz = ast::ExprLit(box(GC) respan(ctx.span, ast::LitUint(n as u64, ast::TyU))); - let ty = ast::TyFixedLengthVec( - box(GC) base.clone(), - box(GC) ast::Expr { - id: ast::DUMMY_NODE_ID, - node: sz, - span: ctx.span - } - ); - - return ast::Ty { - id: ast::DUMMY_NODE_ID, - node: ty, - span: ctx.span - }; -} - -fn mk_fnty(ctx: &mut GenCtx, decl: &ast::FnDecl) -> ast::Ty { - let fnty = ast::TyBareFn(box(GC) ast::BareFnTy { - fn_style: ast::NormalFn, - abi: ctx.abi, - lifetimes: Vec::new(), - decl: box(GC) decl.clone() - }); - - let mut segs = Vec::new(); - segs.push_all([ - ast::PathSegment { - identifier: ctx.ext_cx.ident_of("std"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), - }, - ast::PathSegment { - identifier: ctx.ext_cx.ident_of("option"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), - }, - ast::PathSegment { - identifier: ctx.ext_cx.ident_of("Option"), - lifetimes: Vec::new(), - types: OwnedSlice::from_vec(Vec::from_elem(1, - box(GC) ast::Ty { - id: ast::DUMMY_NODE_ID, - node: fnty, - span: ctx.span - } - )) - } - ]); - - return ast::Ty { - id: ast::DUMMY_NODE_ID, - node: ast::TyPath( - ast::Path { - span: ctx.span, - global: true, - segments: segs - }, - None, - ast::DUMMY_NODE_ID - ), - span: ctx.span - }; -} diff --git a/lib.rs b/lib.rs deleted file mode 100644 index aeaa63f1..00000000 --- a/lib.rs +++ /dev/null @@ -1,110 +0,0 @@ -#![crate_id = "bindgen"] -#![crate_type = "dylib"] -#![feature(globs, managed_boxes, quote, phase, plugin_registrar)] - -extern crate syntax; -extern crate rustc; -extern crate libc; -#[phase(plugin, link)] extern crate log; - -use std::collections::HashSet; -use std::default::Default; -use std::gc::Gc; - -use syntax::ast; -use syntax::codemap::Span; -use rustc::plugin::Registry; - -use types::Global; - -mod types; -mod clangll; -mod clang; -mod gen; -mod parser; -mod macro; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_macro("bindgen", macro::bindgen_macro); -} - -pub struct BindgenOptions { - pub match_pat: Vec, - pub abi: String, - pub builtins: bool, - pub links: Vec<(String, Option)>, - pub emit_ast: bool, - pub fail_on_bitfield: bool, - pub fail_on_unknown_type: bool, - pub clang_args: Vec, -} - -impl Default for BindgenOptions { - fn default() -> BindgenOptions { - BindgenOptions { - match_pat: Vec::new(), - abi: "C".to_string(), - builtins: false, - links: Vec::new(), - emit_ast: false, - fail_on_bitfield: false, - fail_on_unknown_type: false, - clang_args: Vec::new() - } - } -} - -pub trait Logger { - fn error(&self, msg: &str); - fn warn(&self, msg: &str); -} - -pub fn generate_bindings(options: BindgenOptions, logger: Option<&Logger>, span: Span) -> Result>, ()> { - let l = DummyLogger; - let logger = match logger { - Some(l) => l, - None => { - &l as &Logger - } - }; - let globals = try!(parse_headers(&options, logger)); - Ok(gen::gen_mod(options.abi.as_slice(), options.links.as_slice(), globals, span)) -} - -struct DummyLogger; - -#[allow(unused_variable)] -impl Logger for DummyLogger { - fn error(&self, msg: &str) { } - fn warn(&self, msg: &str) { } -} - -fn parse_headers(options: &BindgenOptions, logger: &Logger) -> Result, ()> { - let clang_opts = parser::ClangParserOptions { - builtin_names: builtin_names(), - builtins: options.builtins, - match_pat: options.match_pat.clone(), - emit_ast: options.emit_ast, - fail_on_bitfield: options.fail_on_bitfield, - fail_on_unknown_type: options.fail_on_unknown_type, - clang_args: options.clang_args.clone(), - }; - - parser::parse(clang_opts, logger) -} - -fn builtin_names() -> HashSet { - let mut names = HashSet::new(); - let keys = [ - "__va_list_tag", - "__va_list", - ]; - - keys.iter().advance(|s| { - names.insert(s.to_string()); - true - }); - - return names; -} diff --git a/macro.rs b/macro.rs deleted file mode 100644 index 1aee481a..00000000 --- a/macro.rs +++ /dev/null @@ -1,319 +0,0 @@ -use std::cell::RefCell; -use std::default::Default; -use std::os; -use std::gc::Gc; - -use syntax::ast; -use syntax::codemap; -use syntax::ext::base; -use syntax::parse; -use syntax::parse::token; -use syntax::util::small_vector::SmallVector; - -use super::{generate_bindings, BindgenOptions, Logger}; - -pub fn bindgen_macro(cx: &mut base::ExtCtxt, sp: codemap::Span, tts: &[ast::TokenTree]) -> Box { - let mut visit = BindgenArgsVisitor { - options: Default::default(), - seen_named: false - }; - - visit.options.builtins = true; - if !parse_macro_opts(cx, tts, &mut visit) { - return base::DummyResult::any(sp); - } - - // Reparse clang_args as it is passed in string form - let clang_args = visit.options.clang_args.connect(" "); - visit.options.clang_args = parse_process_args(clang_args.as_slice()); - - // Set the working dir to the directory containing the invoking rs file so - // that clang searches for headers relative to it rather than the crate root - let mod_dir = Vec::from_slice(Path::new(cx.codemap().span_to_filename(sp)).dirname()); - let cwd = os::getcwd(); - os::change_dir(&Path::new(mod_dir)); - - // We want the span for errors to just match the bindgen! symbol - // instead of the whole invocation which can span multiple lines - let mut short_span = sp; - short_span.hi = short_span.lo + codemap::BytePos(8); - - let logger = MacroLogger { sp: short_span, cx: cx }; - - let ret = match generate_bindings(visit.options, Some(&logger as &Logger), short_span) { - Ok(items) => { - box BindgenResult { items: RefCell::new(Some(SmallVector::many(items))) } as Box - } - Err(_) => base::DummyResult::any(sp) - }; - - os::change_dir(&Path::new(cwd)); - - ret -} - -trait MacroArgsVisitor { - fn visit_str(&mut self, name: Option<&str>, val: &str) -> bool; - fn visit_int(&mut self, name: Option<&str>, val: i64) -> bool; - fn visit_bool(&mut self, name: Option<&str>, val: bool) -> bool; - fn visit_ident(&mut self, name: Option<&str>, ident: &str) -> bool; -} - -struct BindgenArgsVisitor { - pub options: BindgenOptions, - seen_named: bool -} - -impl MacroArgsVisitor for BindgenArgsVisitor { - fn visit_str(&mut self, mut name: Option<&str>, val: &str) -> bool { - if name.is_some() { self.seen_named = true; } - else if !self.seen_named { name = Some("clang_args") } - match name { - Some("link") => self.options.links.push((val.to_string(), None)), - Some("link_static") => self.options.links.push((val.to_string(), Some("static".to_string()))), - Some("link_framework") => self.options.links.push((val.to_string(), Some("framework".to_string()))), - Some("abi") => self.options.abi = val.to_string(), - Some("match") => self.options.match_pat.push(val.to_string()), - Some("clang_args") => self.options.clang_args.push(val.to_string()), - _ => return false - } - true - } - - #[allow(unused_variable)] - fn visit_int(&mut self, name: Option<&str>, val: i64) -> bool { - if name.is_some() { self.seen_named = true; } - false - } - - fn visit_bool(&mut self, name: Option<&str>, val: bool) -> bool { - if name.is_some() { self.seen_named = true; } - match name { - Some("allow_bitfields") => self.options.fail_on_bitfield = !val, - Some("allow_unknown_types") => self.options.fail_on_unknown_type = !val, - Some("emit_builtins") => self.options.builtins = val, - _ => return false - } - true - } - - #[allow(unused_variable)] - fn visit_ident(&mut self, name: Option<&str>, val: &str) -> bool { - if name.is_some() { self.seen_named = true; } - false - } -} - -// Parses macro invocations in the form [ident=|:]value where value is an ident or literal -// e.g. bindgen!(module_name, "header.h", emit_builtins=false, clang_args:"-I /usr/local/include") -fn parse_macro_opts(cx: &mut base::ExtCtxt, tts: &[ast::TokenTree], visit: &mut MacroArgsVisitor) -> bool { - let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), Vec::from_slice(tts)); - let mut args_good = true; - - loop { - let mut name: Option = None; - let mut span = parser.span; - - // Check for [ident=]value and if found save ident to name - if parser.look_ahead(1, |t| t == &token::EQ) { - match parser.bump_and_get() { - token::IDENT(ident, _) => { - let ident = parser.id_to_interned_str(ident); - name = Some(ident.get().to_string()); - parser.expect(&token::EQ); - }, - _ => { - cx.span_err(span, "invalid argument format"); - return false - } - } - } - - match parser.token { - // Match [ident] - token::IDENT(val, _) => { - let val = parser.id_to_interned_str(val); - span.hi = parser.span.hi; - parser.bump(); - - // Bools are simply encoded as idents - let ret = match val.get() { - "true" => visit.visit_bool(as_str(&name), true), - "false" => visit.visit_bool(as_str(&name), false), - val => visit.visit_ident(as_str(&name), val) - }; - if !ret { - cx.span_err(span, "invalid argument"); - args_good = false; - } - } - // Match [literal] and parse as an expression so we can expand macros - _ => { - let expr = cx.expand_expr(parser.parse_expr()); - span.hi = expr.span.hi; - match expr.node { - ast::ExprLit(lit) => { - let ret = match lit.node { - ast::LitStr(ref s, _) => visit.visit_str(as_str(&name), s.get()), - ast::LitBool(b) => visit.visit_bool(as_str(&name), b), - ast::LitIntUnsuffixed(i) | - ast::LitInt(i, _) => visit.visit_int(as_str(&name), i), - ast::LitUint(i, _) => visit.visit_int(as_str(&name), i as i64), - _ => { - cx.span_err(span, "invalid argument format"); - return false - } - }; - if !ret { - cx.span_err(span, "invalid argument"); - args_good = false; - } - }, - _ => { - cx.span_err(span, "invalid argument format"); - return false - } - } - } - } - - if parser.eat(&token::EOF) { - return args_good - } - - if !parser.eat(&token::COMMA) { - cx.span_err(parser.span, "invalid argument format"); - return false - } - } -} - -// I'm sure there's a nicer way of doing it -fn as_str<'a>(owned: &'a Option) -> Option<&'a str> { - match owned { - &Some(ref s) => Some(s.as_slice()), - &None => None - } -} - -#[deriving(PartialEq, Eq)] -enum QuoteState { - InNone, - InSingleQuotes, - InDoubleQuotes -} - -fn parse_process_args(s: &str) -> Vec { - let s = s.trim(); - let mut parts = Vec::new(); - let mut quote_state = InNone; - let mut positions = vec!(0); - let mut last = ' '; - for (i, c) in s.chars().chain(" ".chars()).enumerate() { - match (last, c) { - // Match \" set has_escaped and skip - ('\\', '\"') => (), - // Match \' - ('\\', '\'') => (), - // Match \ - // Check we don't escape the final added space - ('\\', ' ') if i < s.len() => (), - // Match \\ - ('\\', '\\') => (), - // Match " - (_, '\"') if quote_state == InNone => { - quote_state = InDoubleQuotes; - positions.push(i); - positions.push(i + 1); - }, - (_, '\"') if quote_state == InDoubleQuotes => { - quote_state = InNone; - positions.push(i); - positions.push(i + 1); - }, - // Match ' - (_, '\'') if quote_state == InNone => { - quote_state = InSingleQuotes; - positions.push(i); - positions.push(i + 1); - }, - (_, '\'') if quote_state == InSingleQuotes => { - quote_state = InNone; - positions.push(i); - positions.push(i + 1); - }, - // Match - // If we are at the end of the string close any open quotes - (_, ' ') if quote_state == InNone || i >= s.len() => { - { - positions.push(i); - - let starts = positions.iter().enumerate().filter(|&(i, _)| i % 2 == 0); - let ends = positions.iter().enumerate().filter(|&(i, _)| i % 2 == 1); - - let part: Vec = starts.zip(ends).map(|((_, start), (_, end))| s.slice(*start, *end).to_string()).collect(); - - let part = part.connect(""); - - if part.len() > 0 { - // Remove any extra whitespace outside the quotes - let part = part.as_slice().trim(); - // Replace quoted characters - let part = part.replace("\\\"", "\""); - let part = part.replace("\\\'", "\'"); - let part = part.replace("\\ ", " "); - let part = part.replace("\\\\", "\\"); - parts.push(part); - } - } - - positions.clear(); - positions.push(i + 1); - }, - (_, _) => () - } - last = c; - } - parts -} - -struct MacroLogger<'a, 'b> { - sp: codemap::Span, - cx: &'a base::ExtCtxt<'b> -} - -impl<'a, 'b> Logger for MacroLogger<'a, 'b> { - fn error(&self, msg: &str) { - self.cx.span_err(self.sp, msg) - } - - fn warn(&self, msg: &str) { - self.cx.span_warn(self.sp, msg) - } -} - -struct BindgenResult { - items: RefCell>>> -} - -impl base::MacResult for BindgenResult { - fn make_items(&self) -> Option>> { - self.items.borrow_mut().take() - } -} - -#[cfg(test)] -fn make_string_vec(parts: &[&str]) -> Vec { - parts.iter().map(|p| p.to_string()).collect() -} - -#[test] -fn test_parse_process_args() { - assert_eq!(parse_process_args("a b c"), make_string_vec(["a", "b", "c"])); - assert_eq!(parse_process_args("a \"b\" c"), make_string_vec(["a", "b", "c"])); - assert_eq!(parse_process_args("a \'b\' c"), make_string_vec(["a", "b", "c"])); - assert_eq!(parse_process_args("a \"b c\""), make_string_vec(["a", "b c"])); - assert_eq!(parse_process_args("a \'\"b\"\' c"), make_string_vec(["a", "\"b\"", "c"])); - assert_eq!(parse_process_args("a b\\ c"), make_string_vec(["a", "b c"])); - assert_eq!(parse_process_args("a b c\\"), make_string_vec(["a", "b", "c\\"])); -} diff --git a/parser.rs b/parser.rs deleted file mode 100644 index 4f9153ba..00000000 --- a/parser.rs +++ /dev/null @@ -1,480 +0,0 @@ -#![allow(non_uppercase_pattern_statics)] -#![allow(unused_must_use)] - -use std::collections::{HashMap, HashSet}; -use std::cell::RefCell; -use std::gc::GC; - -use il = types; -use types::*; -use cx = clang; -use clang::*; -use clang::ll::*; - -use super::Logger; - -pub struct ClangParserOptions { - pub builtin_names: HashSet, - pub builtins: bool, - pub match_pat: Vec, - pub emit_ast: bool, - pub fail_on_bitfield: bool, - pub fail_on_unknown_type: bool, - pub clang_args: Vec, -} - -struct ClangParserCtx<'a> { - options: ClangParserOptions, - name: HashMap, - globals: Vec, - builtin_defs: Vec, - logger: &'a Logger, - err_count: int -} - -fn match_pattern(ctx: &mut ClangParserCtx, cursor: &Cursor) -> bool { - let (file, _, _, _) = cursor.location().location(); - - if file.is_null() { - return ctx.options.builtins; - } - - if ctx.options.match_pat.is_empty() { - return true; - } - - let name = file.name(); - let mut found = false; - ctx.options.match_pat.iter().advance(|pat| { - if name.as_slice().contains((*pat).as_slice()) { - found = true; - } - true - }); - - return found; -} - -fn decl_name(ctx: &mut ClangParserCtx, cursor: &Cursor) -> Global { - let mut new_decl = false; - let decl = { - *ctx.name.find_or_insert_with(*cursor, |_| { - new_decl = true; - let spelling = cursor.spelling(); - let ty = cursor.cur_type(); - let layout = Layout::new(ty.size(), ty.align()); - - match cursor.kind() { - CXCursor_StructDecl => { - let ci = box(GC) RefCell::new(CompInfo::new(spelling, true, vec!(), layout)); - GCompDecl(ci) - } - CXCursor_UnionDecl => { - let ci = box(GC) RefCell::new(CompInfo::new(spelling, false, vec!(), layout)); - GCompDecl(ci) - } - CXCursor_EnumDecl => { - let kind = match cursor.enum_type().kind() { - CXType_SChar | CXType_Char_S => ISChar, - CXType_UChar | CXType_Char_U => IUChar, - CXType_UShort => IUShort, - CXType_UInt => IUInt, - CXType_ULong => IULong, - CXType_ULongLong => IULongLong, - CXType_Short => IShort, - CXType_Int => IInt, - CXType_Long => ILong, - CXType_LongLong => ILongLong, - _ => IInt, - }; - let ei = box(GC) RefCell::new(EnumInfo::new(spelling, kind, vec!(), layout)); - GEnumDecl(ei) - } - CXCursor_TypedefDecl => { - let ti = box(GC) RefCell::new(TypeInfo::new(spelling, TVoid)); - GType(ti) - } - CXCursor_VarDecl => { - let vi = box(GC) RefCell::new(VarInfo::new(spelling, TVoid)); - GVar(vi) - } - CXCursor_FunctionDecl => { - let vi = box(GC) RefCell::new(VarInfo::new(spelling, TVoid)); - GFunc(vi) - } - _ => GOther - } - }) - }; - - if new_decl { - if ctx.options.builtin_names.contains(&cursor.spelling()) { - ctx.builtin_defs.push(*cursor); - } - } - - return decl; -} - -fn opaque_decl(ctx: &mut ClangParserCtx, decl: &Cursor) { - let name = decl_name(ctx, decl); - ctx.globals.push(name); -} - -fn fwd_decl(ctx: &mut ClangParserCtx, cursor: &Cursor, f: |ctx: &mut ClangParserCtx|) { - let def = &cursor.definition(); - if cursor == def { - f(ctx); - } else if def.kind() == CXCursor_NoDeclFound || - def.kind() == CXCursor_InvalidFile { - opaque_decl(ctx, cursor); - } -} - -fn conv_ptr_ty(ctx: &mut ClangParserCtx, ty: &cx::Type, cursor: &Cursor, layout: Layout) -> il::Type { - let is_const = ty.is_const(); - match ty.kind() { - CXType_Void => { - return TPtr(box TVoid, is_const, layout) - } - CXType_Unexposed | - CXType_FunctionProto | - CXType_FunctionNoProto => { - let ret_ty = ty.ret_type(); - let decl = ty.declaration(); - return if ret_ty.kind() != CXType_Invalid { - let args_lst = ty.arg_types().iter().map(|arg| { - ("".to_string(), conv_ty(ctx, arg, cursor)) - }).collect(); - let ret_ty = box conv_ty(ctx, &ret_ty, cursor); - - TFunc(ret_ty, args_lst, ty.is_variadic()) - } else if decl.kind() != CXCursor_NoDeclFound { - TPtr(box conv_decl_ty(ctx, &decl), is_const, layout) - } else { - TPtr(box TVoid, is_const, layout) - }; - } - CXType_Typedef => { - let decl = ty.declaration(); - let def_ty = decl.typedef_type(); - if def_ty.kind() == CXType_FunctionProto || - def_ty.kind() == CXType_FunctionNoProto { - return TPtr(box conv_ptr_ty(ctx, &def_ty, cursor, layout), is_const, layout); - } else { - return TPtr(box conv_ty(ctx, ty, cursor), is_const, layout); - } - } - _ => return TPtr(box conv_ty(ctx, ty, cursor), is_const, layout), - } -} - -fn conv_decl_ty(ctx: &mut ClangParserCtx, cursor: &Cursor) -> il::Type { - return match cursor.kind() { - CXCursor_StructDecl => { - let decl = decl_name(ctx, cursor); - let ci = decl.compinfo(); - TComp(ci) - } - CXCursor_UnionDecl => { - let decl = decl_name(ctx, cursor); - let ci = decl.compinfo(); - TComp(ci) - } - CXCursor_EnumDecl => { - let decl = decl_name(ctx, cursor); - let ei = decl.enuminfo(); - TEnum(ei) - } - CXCursor_TypedefDecl => { - let decl = decl_name(ctx, cursor); - let ti = decl.typeinfo(); - TNamed(ti) - } - _ => TVoid - }; -} - -fn conv_ty(ctx: &mut ClangParserCtx, ty: &cx::Type, cursor: &Cursor) -> il::Type { - debug!("conv_ty: ty=`{}`", type_to_str(ty.kind())); - let layout = Layout::new(ty.size(), ty.align()); - return match ty.kind() { - CXType_Void | CXType_Invalid => TVoid, - CXType_Bool => TInt(IBool, layout), - CXType_SChar | - CXType_Char_S => TInt(ISChar, layout), - CXType_UChar | - CXType_Char_U => TInt(IUChar, layout), - CXType_UShort => TInt(IUShort, layout), - CXType_UInt => TInt(IUInt, layout), - CXType_ULong => TInt(IULong, layout), - CXType_ULongLong => TInt(IULongLong, layout), - CXType_Short => TInt(IShort, layout), - CXType_Int => TInt(IInt, layout), - CXType_Long => TInt(ILong, layout), - CXType_LongLong => TInt(ILongLong, layout), - CXType_Float => TFloat(FFloat, layout), - CXType_Double => TFloat(FDouble, layout), - CXType_LongDouble => TFloat(FDouble, layout), - CXType_Pointer => conv_ptr_ty(ctx, &ty.pointee_type(), cursor, layout), - CXType_VariableArray | CXType_DependentSizedArray | CXType_IncompleteArray => { - conv_ptr_ty(ctx, &ty.elem_type(), cursor, layout) - } - CXType_Record | - CXType_Typedef | - CXType_Unexposed | - CXType_Enum => conv_decl_ty(ctx, &ty.declaration()), - CXType_ConstantArray => TArray(box conv_ty(ctx, &ty.elem_type(), cursor), ty.array_size(), layout), - _ => { - let fail = ctx.options.fail_on_unknown_type; - log_err_warn(ctx, - format!("unsupported type `{}` ({})", - type_to_str(ty.kind()), cursor.location() - ).as_slice(), - fail - ); - TVoid - }, - }; -} - -fn opaque_ty(ctx: &mut ClangParserCtx, ty: &cx::Type) { - if ty.kind() == CXType_Record || ty.kind() == CXType_Enum { - let decl = ty.declaration(); - let def = decl.definition(); - if def.kind() == CXCursor_NoDeclFound || - def.kind() == CXCursor_InvalidFile { - opaque_decl(ctx, &decl); - } - } -} - -fn visit_struct(cursor: &Cursor, - parent: &Cursor, - ctx: &mut ClangParserCtx, - fields: &mut Vec) -> Enum_CXVisitorResult { - if cursor.kind() == CXCursor_FieldDecl { - let ty = conv_ty(ctx, &cursor.cur_type(), cursor); - let name = cursor.spelling(); - let bit = cursor.bit_width(); - // If we encounter a bitfield, and fail_on_bitfield is set, throw an - // error and exit entirely. - if bit != None { - let fail = ctx.options.fail_on_bitfield; - log_err_warn(ctx, - format!("unsupported bitfield `{}` in struct `{}` ({})", - name.as_slice(), parent.spelling().as_slice(), cursor.location() - ).as_slice(), - fail - ); - } - let field = FieldInfo::new(name, ty, bit); - fields.push(field); - } - return CXChildVisit_Continue; -} - -fn visit_union(cursor: &Cursor, - ctx: &mut ClangParserCtx, - fields: &mut Vec) -> Enum_CXVisitorResult { - if cursor.kind() == CXCursor_FieldDecl { - let ty = conv_ty(ctx, &cursor.cur_type(), cursor); - let name = cursor.spelling(); - let field = FieldInfo::new(name, ty, None); - fields.push(field); - } - return CXChildVisit_Continue; -} - -fn visit_enum(cursor: &Cursor, - items: &mut Vec) -> Enum_CXVisitorResult { - if cursor.kind() == CXCursor_EnumConstantDecl { - let name = cursor.spelling(); - let val = cursor.enum_val(); - let item = EnumItem::new(name, val); - items.push(item); - } - return CXChildVisit_Continue; -} - -fn visit_top<'r>(cur: &'r Cursor, - parent: &'r Cursor, - ctx: &mut ClangParserCtx) -> Enum_CXVisitorResult { - let cursor = if ctx.options.builtin_names.contains(&parent.spelling()) { - parent - } else { - cur - }; - - if !match_pattern(ctx, cursor) { - return CXChildVisit_Continue; - } - - match cursor.kind() { - CXCursor_StructDecl => { - fwd_decl(ctx, cursor, |ctx_| { - let decl = decl_name(ctx_, cursor); - let ci = decl.compinfo(); - cursor.visit(|c, p| { - let mut ci_ = ci.borrow_mut(); - visit_struct(c, p, ctx_, &mut ci_.fields) - }); - ctx_.globals.push(GComp(ci)); - }); - return if cur.kind() == CXCursor_FieldDecl { - CXChildVisit_Break - } else { - CXChildVisit_Recurse - }; - } - CXCursor_UnionDecl => { - fwd_decl(ctx, cursor, |ctx_| { - let decl = decl_name(ctx_, cursor); - let ci = decl.compinfo(); - cursor.visit(|c, _| { - let mut ci_ = ci.borrow_mut(); - visit_union(c, ctx_, &mut ci_.fields) - }); - ctx_.globals.push(GComp(ci)); - }); - return CXChildVisit_Recurse; - } - CXCursor_EnumDecl => { - fwd_decl(ctx, cursor, |ctx_| { - let decl = decl_name(ctx_, cursor); - let ei = decl.enuminfo(); - cursor.visit(|c, _| { - let mut ei_ = ei.borrow_mut(); - visit_enum(c, &mut ei_.items) - }); - ctx_.globals.push(GEnum(ei)); - }); - return CXChildVisit_Continue; - } - CXCursor_FunctionDecl => { - let linkage = cursor.linkage(); - if linkage != CXLinkage_External && linkage != CXLinkage_UniqueExternal { - return CXChildVisit_Continue; - } - - let args_lst: Vec<(String, il::Type)> = cursor.args().iter().map(|arg| { - let arg_name = arg.spelling(); - (arg_name, conv_ty(ctx, &arg.cur_type(), cursor)) - }).collect(); - - let ty = cursor.cur_type(); - let ret_ty = box conv_ty(ctx, &cursor.ret_type(), cursor); - - let func = decl_name(ctx, cursor); - let vi = func.varinfo(); - let mut vi = vi.borrow_mut(); - vi.ty = TFunc(ret_ty.clone(), args_lst.clone(), ty.is_variadic()); - ctx.globals.push(func); - - return CXChildVisit_Continue; - } - CXCursor_VarDecl => { - let linkage = cursor.linkage(); - if linkage != CXLinkage_External && linkage != CXLinkage_UniqueExternal { - 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(); - ctx.globals.push(var); - - return CXChildVisit_Continue; - } - CXCursor_TypedefDecl => { - let mut under_ty = cursor.typedef_type(); - if under_ty.kind() == CXType_Unexposed { - under_ty = under_ty.canonical_type(); - } - - let ty = conv_ty(ctx, &under_ty, cursor); - let typedef = decl_name(ctx, cursor); - let ti = typedef.typeinfo(); - let mut ti = ti.borrow_mut(); - ti.ty = ty.clone(); - ctx.globals.push(typedef); - - opaque_ty(ctx, &under_ty); - - return CXChildVisit_Continue; - } - CXCursor_FieldDecl => { - return CXChildVisit_Continue; - } - _ => return CXChildVisit_Recurse, - } -} - -fn log_err_warn(ctx: &mut ClangParserCtx, msg: &str, is_err: bool) { - match is_err { - true => { - ctx.err_count += 1; - ctx.logger.error(msg) - }, - false => ctx.logger.warn(msg) - } -} - -pub fn parse(options: ClangParserOptions, logger: &Logger) -> Result, ()> { - let mut ctx = ClangParserCtx { - options: options, - name: HashMap::new(), - builtin_defs: vec!(), - globals: vec!(), - logger: logger, - err_count: 0 - }; - - 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.as_slice(), [], 0); - if unit.is_null() { - ctx.logger.error("No input files given"); - return Err(()) - } - - let diags = unit.diags(); - for d in diags.iter() { - let msg = d.format(Diagnostic::default_opts()); - let is_err = d.severity() >= CXDiagnostic_Error; - log_err_warn(&mut ctx, msg.as_slice(), is_err); - } - - if ctx.err_count > 0 { - return Err(()) - } - - let cursor = unit.cursor(); - - if ctx.options.emit_ast { - cursor.visit(|cur, _| ast_dump(cur, 0)); - } - - cursor.visit(|cur, parent| visit_top(cur, parent, &mut ctx)); - - while !ctx.builtin_defs.is_empty() { - let c = ctx.builtin_defs.shift().unwrap(); - c.visit(|cur, parent| visit_top(cur, parent, &mut ctx)); - } - - unit.dispose(); - ix.dispose(); - - if ctx.err_count > 0 { - return Err(()) - } - - Ok(ctx.globals) -} diff --git a/src/bindgen.rs b/src/bindgen.rs new file mode 100644 index 00000000..8e46057b --- /dev/null +++ b/src/bindgen.rs @@ -0,0 +1,192 @@ +#![crate_id = "bindgen"] +#![crate_type = "bin"] +#![feature(phase)] + +extern crate bindgen; +#[phase(plugin, link)] extern crate log; +extern crate syntax; + +use bindgen::{Logger, generate_bindings, BindgenOptions}; +use std::{io, os, path}; +use std::default::Default; +use std::io::{fs, IoResult}; +use syntax::ast; +use syntax::codemap::DUMMY_SP; +use syntax::print::pprust; +use syntax::print::pp::eof; + +struct StdLogger; + +impl Logger for StdLogger { + fn error(&self, msg: &str) { + error!("{}", msg); + } + + fn warn(&self, msg: &str) { + warn!("{}", msg); + } +} + +enum ParseResult { + CmdUsage, + ParseOk(BindgenOptions, Box), + ParseErr(String) +} + +fn parse_args(args: &[String]) -> ParseResult { + let args_len = args.len(); + + let mut options: BindgenOptions = Default::default(); + let mut out = box io::BufferedWriter::new(io::stdout()) as Box; + + if args_len == 0u { + return CmdUsage; + } + + let mut ix = 0u; + while ix < args_len { + if args[ix].len() > 2 && args[ix].as_slice().slice_to(2) == "-l" { + options.links.push((args[ix].as_slice().slice_from(2).to_string(), None)); + ix += 1u; + } else { + match args[ix].as_slice() { + "--help" | "-h" => { + return CmdUsage; + } + "-emit-clang-ast" => { + options.emit_ast = true; + ix += 1u; + } + "-o" => { + if ix + 1u >= args_len { + return ParseErr("Missing output filename".to_string()); + } + let path = path::Path::new(args[ix + 1].clone()); + match fs::File::create(&path) { + Ok(f) => { out = box io::BufferedWriter::new(f) as Box; } + Err(_) => { return ParseErr(format!("Open {} failed", args[ix + 1])); } + } + ix += 2u; + } + "-l" => { + if ix + 1u >= args_len { + return ParseErr("Missing link name".to_string()); + } + options.links.push((args[ix + 1u].clone(), None)); + ix += 2u; + } + "-static-link" => { + if ix + 1u >= args_len { + return ParseErr("Missing link name".to_string()); + } + options.links.push((args[ix + 1u].clone(), Some("static".to_string()))); + ix += 2u; + } + "-framework-link" => { + if ix + 1u >= args_len { + return ParseErr("Missing link name".to_string()); + } + options.links.push((args[ix + 1u].clone(), Some("framework".to_string()))); + ix += 2u; + } + "-match" => { + if ix + 1u >= args_len { + return ParseErr("Missing match pattern".to_string()); + } + options.match_pat.push(args[ix + 1u].clone()); + ix += 2u; + } + "-builtins" => { + options.builtins = true; + ix += 1u; + } + "-abi" => { + options.abi = args[ix + 1u].clone(); + ix += 2u; + } + "-allow-bitfields" => { + options.fail_on_bitfield = false; + ix += 1u; + } + "-allow-unknown-types" => { + options.fail_on_unknown_type = false; + ix += 1u; + } + _ => { + options.clang_args.push(args[ix].clone()); + ix += 1u; + } + } + } + } + + return ParseOk(options, out); +} + +fn print_usage(bin: String) { + io::stdio::print(format!("Usage: {} [options] input.h", bin.as_slice()).append( +" +Options: + -h or --help Display help message + -l or -l Link to a dynamic library, can be proivded + multiple times + -static-link Link to a static library + -framework-link Link to a framework + -o Write bindings to (default stdout) + -match Only output bindings for definitions from files + whose name contains + If multiple -match options are provided, files + matching any rule are bound to. + -builtins Output bindings for builtin definitions + (for example __builtin_va_list) + -abi Indicate abi of extern functions (default C) + -allow-bitfields Don't fail if we encounter a bitfield + (note that bindgen does not support bitfields) + -allow-unknown-types Don't fail if we encounter types we do not support, + instead treat them as void + -emit-clang-ast Output the ast (for debugging purposes) + + Options other than stated above are passed to clang. +" + ).as_slice()); +} + +fn try_pprint(module: &ast::Mod, out: Box) -> IoResult<()> { + let mut ps = pprust::rust_printer(out); + try!(ps.s.out.write("/* automatically generated by rust-bindgen */\n\n".as_bytes())); + + try!(ps.print_mod(module, &[])); + try!(ps.print_remaining_comments()); + try!(eof(&mut ps.s)); + + ps.s.out.flush() +} + +#[main] +pub fn main() { + let mut bind_args = os::args(); + let bin = bind_args.shift().unwrap(); + + match parse_args(bind_args.as_slice()) { + ParseErr(e) => fail!(e), + CmdUsage => print_usage(bin), + ParseOk(options, out) => { + let logger = StdLogger; + match generate_bindings(options, Some(&logger as &Logger), DUMMY_SP) { + Ok(items) => { + let module = ast::Mod { + inner: DUMMY_SP, + view_items: Vec::new(), + items: items, + }; + + match try_pprint(&module, out) { + Err(e) => logger.error(format!("Unable to write bindings to file. {}", e).as_slice()), + _ => () + } + } + Err(_) => () + } + } + } +} diff --git a/src/clang.rs b/src/clang.rs new file mode 100644 index 00000000..16d090d0 --- /dev/null +++ b/src/clang.rs @@ -0,0 +1,698 @@ +#![allow(non_uppercase_pattern_statics)] + +use libc::{c_uint, c_char, c_int, c_ulong}; +use std::{mem, io, ptr, str}; +use std::fmt; +use std::hash::Hash; +use std::hash::sip::SipState; +use std::c_str::CString; + +pub use ll = clangll; +use clangll::*; + +// Cursor +pub struct Cursor { + x: CXCursor +} + +pub type CursorVisitor<'s> = |c: &Cursor, p: &Cursor|: 's -> Enum_CXChildVisitResult; + +impl Cursor { + // common + pub fn spelling(&self) -> String { + unsafe { + String_ { x: clang_getCursorSpelling(self.x) }.to_str() + } + } + + pub fn kind(&self) -> Enum_CXCursorKind { + unsafe { + clang_getCursorKind(self.x) + } + } + + pub fn location(&self) -> SourceLocation { + unsafe { + SourceLocation { x: clang_getCursorLocation(self.x) } + } + } + + pub fn cur_type(&self) -> Type { + unsafe { + Type { x: clang_getCursorType(self.x) } + } + } + + pub fn definition(&self) -> Cursor { + unsafe { + Cursor { x: clang_getCursorDefinition(self.x) } + } + } + + pub fn visit(&self, func: CursorVisitor) { + unsafe { + let data = mem::transmute::<&CursorVisitor, CXClientData>(&func); + clang_visitChildren(self.x, Some(visit_children), data); + }; + } + + // bitfield + pub fn bit_width(&self) -> Option { + unsafe { + let w = clang_getFieldDeclBitWidth(self.x); + if w == -1 { + None + } else { + Some(w as uint) + } + } + } + + // enum + pub fn enum_type(&self) -> Type { + unsafe { + Type { x: clang_getEnumDeclIntegerType(self.x) } + } + } + + pub fn enum_val(&self) -> i64 { + unsafe { + clang_getEnumConstantDeclValue(self.x) as i64 + } + } + + // typedef + pub fn typedef_type(&self) -> Type { + unsafe { + Type { x: clang_getTypedefDeclUnderlyingType(self.x) } + } + } + + // function, variable + pub fn linkage(&self) -> Enum_CXLinkageKind { + unsafe { + clang_getCursorLinkage(self.x) + } + } + + // function + pub fn args(&self) -> Vec { + unsafe { + let num = self.num_args() as uint; + let mut args = vec!(); + for i in range(0, num) { + args.push(Cursor { x: clang_Cursor_getArgument(self.x, i as c_uint) }); + } + return args; + } + } + + pub fn ret_type(&self) -> Type { + unsafe { + Type { x: clang_getCursorResultType(self.x) } + } + } + + pub fn num_args(&self) -> i32 { + unsafe { + clang_Cursor_getNumArguments(self.x) + } + } +} + +extern fn visit_children(cur: CXCursor, parent: ll::CXCursor, + data: CXClientData) -> ll::Enum_CXChildVisitResult { + unsafe { + let func = mem::transmute::(data); + return (*func)(&Cursor { x: cur }, &Cursor { x: parent }); + } +} + +impl PartialEq for Cursor { + fn eq(&self, other: &Cursor) -> bool { + unsafe { + clang_equalCursors(self.x, other.x) == 1 + } + } + + fn ne(&self, other: &Cursor) -> bool { + return !self.eq(other); + } +} + +impl Eq for Cursor {} + +impl Hash for Cursor { + fn hash(&self, state: &mut SipState) { + self.x.kind.hash(state); + self.x.xdata.hash(state); + self.x.data[0].hash(state); + self.x.data[1].hash(state); + self.x.data[2].hash(state); + } +} + +// type +pub struct Type { + x: CXType +} + +impl Type { + // common + pub fn kind(&self) -> Enum_CXTypeKind { + return self.x.kind; + } + + pub fn declaration(&self) -> Cursor { + unsafe { + Cursor { x: clang_getTypeDeclaration(self.x) } + } + } + + pub fn is_const(&self) -> bool { + unsafe { + clang_isConstQualifiedType(self.x) == 1 + } + } + + pub fn size(&self) -> uint { + unsafe { + let val = clang_Type_getSizeOf(self.x); + if val < 0 { 0 } else { val as uint } + } + } + + pub fn align(&self) -> uint { + unsafe { + let val = clang_Type_getAlignOf(self.x); + if val < 0 { 0 } else { val as uint } + } + } + + // pointer + pub fn pointee_type(&self) -> Type { + unsafe { + Type { x: clang_getPointeeType(self.x) } + } + } + + // array + pub fn elem_type(&self) -> Type { + unsafe { + Type { x: clang_getArrayElementType(self.x) } + } + } + + pub fn array_size(&self) -> uint { + unsafe { + clang_getArraySize(self.x) as uint + } + } + + // typedef + pub fn canonical_type(&self) -> Type { + unsafe { + Type { x: clang_getCanonicalType(self.x) } + } + } + + // function + pub fn is_variadic(&self) -> bool { + unsafe { + clang_isFunctionTypeVariadic(self.x) == 1 + } + } + + pub fn arg_types(&self) -> Vec { + unsafe { + let num = clang_getNumArgTypes(self.x) as uint; + let mut args = vec!(); + for i in range(0, num) { + args.push(Type { x: clang_getArgType(self.x, i as c_uint) }); + } + return args; + } + } + + pub fn ret_type(&self) -> Type { + unsafe { + Type { x: clang_getResultType(self.x) } + } + } +} + +// SourceLocation +pub struct SourceLocation { + x: CXSourceLocation +} + +impl SourceLocation { + pub fn location(&self) -> (File, uint, uint, uint) { + unsafe { + let mut file = ptr::mut_null(); + let mut line = 0; + let mut col = 0; + let mut off = 0; + clang_getSpellingLocation(self.x, &mut file, &mut line, &mut col, &mut off); + return (File { x: file }, line as uint, col as uint, off as uint); + } + } +} + +impl fmt::Show for SourceLocation { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let (file, line, col, _) = self.location(); + match file.is_null() { + false => { + try!(file.name().fmt(f)); + try!(":".fmt(f)); + try!(line.fmt(f)); + try!(":".fmt(f)); + col.fmt(f) + }, + true => "builtin definitions".fmt(f) + } + } +} + +// File +pub struct File { + x: CXFile +} + +impl File { + pub fn name(&self) -> String { + if self.is_null() { + return "".to_string(); + } + unsafe { + String_ { x: clang_getFileName(self.x) }.to_str() + } + } + + pub fn is_null(&self) -> bool { + self.x.is_null() + } +} + +// String +pub struct String_ { + x: CXString +} + +impl fmt::Show for String_ { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.x.data.is_null() { + return "".fmt(f); + } + unsafe { + let c_str = clang_getCString(self.x) as *const c_char; + str::raw::from_c_str(c_str).fmt(f) + } + } +} + +// Index +pub struct Index { + x: CXIndex +} + +impl Index { + pub fn create(pch: bool, diag: bool) -> Index { + unsafe { + Index { x: clang_createIndex(pch as c_int, diag as c_int) } + } + } + + pub fn dispose(&self) { + unsafe { + clang_disposeIndex(self.x); + } + } + + pub fn is_null(&self) -> bool { + self.x.is_null() + } +} + +// TranslationUnit +pub struct TranslationUnit { + x: CXTranslationUnit +} + +impl TranslationUnit { + pub fn parse(ix: &Index, file: &str, cmd_args: &[String], + unsaved: &[UnsavedFile], opts: uint) -> TranslationUnit { + let _fname = file.to_c_str(); + let fname = _fname.as_ptr(); + let _c_args: Vec = cmd_args.iter().map(|s| s.to_c_str()).collect(); + let c_args: Vec<*const c_char> = _c_args.iter().map(|s| s.as_ptr()).collect(); + let mut c_unsaved: Vec = unsaved.iter().map(|f| f.x).collect(); + let tu = unsafe { + clang_parseTranslationUnit(ix.x, fname, + c_args.as_ptr(), + c_args.len() as c_int, + c_unsaved.as_mut_ptr(), + c_unsaved.len() as c_uint, + opts as c_uint) + }; + TranslationUnit { x: tu } + } + + pub fn reparse(&self, unsaved: &[UnsavedFile], opts: uint) -> bool { + let mut c_unsaved: Vec = unsaved.iter().map(|f| f.x).collect(); + + unsafe { + clang_reparseTranslationUnit(self.x, + c_unsaved.len() as c_uint, + c_unsaved.as_mut_ptr(), + opts as c_uint) == 0 + } + } + + pub fn diags(&self) -> Vec { + unsafe { + let num = clang_getNumDiagnostics(self.x) as uint; + let mut diags = vec!(); + for i in range(0, num) { + diags.push(Diagnostic { x: clang_getDiagnostic(self.x, i as c_uint) }); + } + return diags; + } + } + + pub fn cursor(&self) -> Cursor { + unsafe { + Cursor { x: clang_getTranslationUnitCursor(self.x) } + } + } + + pub fn dispose(&self) { + unsafe { + clang_disposeTranslationUnit(self.x); + } + } + + pub fn is_null(&self) -> bool { + self.x.is_null() + } +} + +// Diagnostic +pub struct Diagnostic { + x: CXDiagnostic +} + +impl Diagnostic { + pub fn default_opts() -> uint { + unsafe { + clang_defaultDiagnosticDisplayOptions() as uint + } + } + + pub fn format(&self, opts: uint) -> String { + unsafe { + String_ { x: clang_formatDiagnostic(self.x, opts as c_uint) }.to_str() + } + } + + pub fn severity(&self) -> Enum_CXDiagnosticSeverity { + unsafe { + clang_getDiagnosticSeverity(self.x) + } + } + + pub fn dispose(&self) { + unsafe { + clang_disposeDiagnostic(self.x); + } + } +} + +// UnsavedFile +pub struct UnsavedFile { + x: Struct_CXUnsavedFile, + name: CString, + contents: CString +} + +impl UnsavedFile { + pub fn new(name: &str, contents: &str) -> UnsavedFile { + let name = name.to_c_str(); + let contents = contents.to_c_str(); + let x = Struct_CXUnsavedFile { + Filename: name.as_ptr(), + Contents: contents.as_ptr(), + Length: contents.len() as c_ulong, + }; + UnsavedFile { + x: x, + name: name, + contents: contents + } + } +} + +pub fn kind_to_str(x: Enum_CXCursorKind) -> &str { + match x { + CXCursor_UnexposedDecl => "UnexposedDecl", + CXCursor_StructDecl => "StructDecl", + CXCursor_UnionDecl => "UnionDecl", + CXCursor_ClassDecl => "ClassDecl", + CXCursor_EnumDecl => "EnumDecl", + CXCursor_FieldDecl => "FieldDecl", + CXCursor_EnumConstantDecl => "EnumConstantDecl", + CXCursor_FunctionDecl => "FunctionDecl", + CXCursor_VarDecl => "VarDecl", + CXCursor_ParmDecl => "ParmDecl", + CXCursor_ObjCInterfaceDecl => "ObjCInterfaceDecl", + CXCursor_ObjCCategoryDecl => "ObjCCategoryDecl", + CXCursor_ObjCProtocolDecl => "ObjCProtocolDecl", + CXCursor_ObjCPropertyDecl => "ObjCPropertyDecl", + CXCursor_ObjCIvarDecl => "ObjCIvarDecl", + CXCursor_ObjCInstanceMethodDecl => "ObjCInstanceMethodDecl", + CXCursor_ObjCClassMethodDecl => "ObjCClassMethodDecl", + CXCursor_ObjCImplementationDecl => "ObjCImplementationDecl", + CXCursor_ObjCCategoryImplDecl => "ObjCCategoryImplDecl", + CXCursor_TypedefDecl => "TypedefDecl", + CXCursor_CXXMethod => "CXXMethod", + CXCursor_Namespace => "Namespace", + CXCursor_LinkageSpec => "LinkageSpec", + CXCursor_Constructor => "Constructor", + CXCursor_Destructor => "Destructor", + CXCursor_ConversionFunction => "ConversionFunction", + CXCursor_TemplateTypeParameter => "TemplateTypeParameter", + CXCursor_NonTypeTemplateParameter => "NonTypeTemplateParameter", + CXCursor_TemplateTemplateParameter => "TemplateTemplateParameter", + CXCursor_FunctionTemplate => "FunctionTemplate", + CXCursor_ClassTemplate => "ClassTemplate", + CXCursor_ClassTemplatePartialSpecialization => "ClassTemplatePartialSpecialization", + CXCursor_NamespaceAlias => "NamespaceAlias", + CXCursor_UsingDirective => "UsingDirective", + CXCursor_UsingDeclaration => "UsingDeclaration", + CXCursor_TypeAliasDecl => "TypeAliasDecl", + CXCursor_ObjCSynthesizeDecl => "ObjCSynthesizeDecl", + CXCursor_ObjCDynamicDecl => "ObjCDynamicDecl", + CXCursor_CXXAccessSpecifier => "CXXAccessSpecifier", + // CXCursor_FirstDecl => "FirstDecl", + // CXCursor_LastDecl => "LastDecl", + CXCursor_FirstRef => "FirstRef", + // CXCursor_ObjCSuperClassRef => "ObjCSuperClassRef", + CXCursor_ObjCProtocolRef => "ObjCProtocolRef", + CXCursor_ObjCClassRef => "ObjCClassRef", + CXCursor_TypeRef => "TypeRef", + CXCursor_CXXBaseSpecifier => "CXXBaseSpecifier", + CXCursor_TemplateRef => "TemplateRef", + CXCursor_NamespaceRef => "NamespaceRef", + CXCursor_MemberRef => "MemberRef", + // CXCursor_LabelRef => "LabelRef", + CXCursor_OverloadedDeclRef => "OverloadedDeclRef", + CXCursor_VariableRef => "VariableRef", + // CXCursor_LastRef => "LastRef", + CXCursor_FirstInvalid => "FirstInvalid", + // CXCursor_InvalidFile => "InvalidFile", + CXCursor_NoDeclFound => "NoDeclFound", + CXCursor_NotImplemented => "NotImplemented", + CXCursor_InvalidCode => "InvalidCode", + // CXCursor_LastInvalid => "LastInvalid", + CXCursor_FirstExpr => "FirstExpr", + // CXCursor_UnexposedExpr => "UnexposedExpr", + CXCursor_DeclRefExpr => "DeclRefExpr", + CXCursor_MemberRefExpr => "MemberRefExpr", + CXCursor_CallExpr => "CallExpr", + CXCursor_ObjCMessageExpr => "ObjCMessageExpr", + CXCursor_BlockExpr => "BlockExpr", + CXCursor_IntegerLiteral => "IntegerLiteral", + CXCursor_FloatingLiteral => "FloatingLiteral", + CXCursor_ImaginaryLiteral => "ImaginaryLiteral", + CXCursor_StringLiteral => "StringLiteral", + CXCursor_CharacterLiteral => "CharacterLiteral", + CXCursor_ParenExpr => "ParenExpr", + CXCursor_UnaryOperator => "UnaryOperator", + CXCursor_ArraySubscriptExpr => "ArraySubscriptExpr", + CXCursor_BinaryOperator => "BinaryOperator", + CXCursor_CompoundAssignOperator => "CompoundAssignOperator", + CXCursor_ConditionalOperator => "ConditionalOperator", + CXCursor_CStyleCastExpr => "CStyleCastExpr", + CXCursor_CompoundLiteralExpr => "CompoundLiteralExpr", + CXCursor_InitListExpr => "InitListExpr", + CXCursor_AddrLabelExpr => "AddrLabelExpr", + CXCursor_StmtExpr => "StmtExpr", + CXCursor_GenericSelectionExpr => "GenericSelectionExpr", + CXCursor_GNUNullExpr => "GNUNullExpr", + CXCursor_CXXStaticCastExpr => "CXXStaticCastExpr", + CXCursor_CXXDynamicCastExpr => "CXXDynamicCastExpr", + CXCursor_CXXReinterpretCastExpr => "CXXReinterpretCastExpr", + CXCursor_CXXConstCastExpr => "CXXConstCastExpr", + CXCursor_CXXFunctionalCastExpr => "CXXFunctionalCastExpr", + CXCursor_CXXTypeidExpr => "CXXTypeidExpr", + CXCursor_CXXBoolLiteralExpr => "CXXBoolLiteralExpr", + CXCursor_CXXNullPtrLiteralExpr => "CXXNullPtrLiteralExpr", + CXCursor_CXXThisExpr => "CXXThisExpr", + CXCursor_CXXThrowExpr => "CXXThrowExpr", + CXCursor_CXXNewExpr => "CXXNewExpr", + CXCursor_CXXDeleteExpr => "CXXDeleteExpr", + CXCursor_UnaryExpr => "UnaryExpr", + CXCursor_ObjCStringLiteral => "ObjCStringLiteral", + CXCursor_ObjCEncodeExpr => "ObjCEncodeExpr", + CXCursor_ObjCSelectorExpr => "ObjCSelectorExpr", + CXCursor_ObjCProtocolExpr => "ObjCProtocolExpr", + CXCursor_ObjCBridgedCastExpr => "ObjCBridgedCastExpr", + CXCursor_PackExpansionExpr => "PackExpansionExpr", + CXCursor_SizeOfPackExpr => "SizeOfPackExpr", + CXCursor_LambdaExpr => "LambdaExpr", + CXCursor_ObjCBoolLiteralExpr => "ObjCBoolLiteralExpr", + // CXCursor_LastExpr => "LastExpr", + CXCursor_FirstStmt => "FirstStmt", + // CXCursor_UnexposedStmt => "UnexposedStmt", + CXCursor_LabelStmt => "LabelStmt", + CXCursor_CompoundStmt => "CompoundStmt", + CXCursor_CaseStmt => "CaseStmt", + CXCursor_DefaultStmt => "DefaultStmt", + CXCursor_IfStmt => "IfStmt", + CXCursor_SwitchStmt => "SwitchStmt", + CXCursor_WhileStmt => "WhileStmt", + CXCursor_DoStmt => "DoStmt", + CXCursor_ForStmt => "ForStmt", + CXCursor_GotoStmt => "GotoStmt", + CXCursor_IndirectGotoStmt => "IndirectGotoStmt", + CXCursor_ContinueStmt => "ContinueStmt", + CXCursor_BreakStmt => "BreakStmt", + CXCursor_ReturnStmt => "ReturnStmt", + CXCursor_AsmStmt => "AsmStmt", + CXCursor_ObjCAtTryStmt => "ObjCAtTryStmt", + CXCursor_ObjCAtCatchStmt => "ObjCAtCatchStmt", + CXCursor_ObjCAtFinallyStmt => "ObjCAtFinallyStmt", + CXCursor_ObjCAtThrowStmt => "ObjCAtThrowStmt", + CXCursor_ObjCAtSynchronizedStmt => "ObjCAtSynchronizedStmt", + CXCursor_ObjCAutoreleasePoolStmt => "ObjCAutoreleasePoolStmt", + CXCursor_ObjCForCollectionStmt => "ObjCForCollectionStmt", + CXCursor_CXXCatchStmt => "CXXCatchStmt", + CXCursor_CXXTryStmt => "CXXTryStmt", + CXCursor_CXXForRangeStmt => "CXXForRangeStmt", + CXCursor_SEHTryStmt => "SEHTryStmt", + CXCursor_SEHExceptStmt => "SEHExceptStmt", + CXCursor_SEHFinallyStmt => "SEHFinallyStmt", + CXCursor_NullStmt => "NullStmt", + CXCursor_DeclStmt => "DeclStmt", + // CXCursor_LastStmt => "LastStmt", + CXCursor_TranslationUnit => "TranslationUnit", + CXCursor_FirstAttr => "FirstAttr", + // CXCursor_UnexposedAttr => "UnexposedAttr", + CXCursor_IBActionAttr => "IBActionAttr", + CXCursor_IBOutletAttr => "IBOutletAttr", + CXCursor_IBOutletCollectionAttr => "IBOutletCollectionAttr", + CXCursor_CXXFinalAttr => "CXXFinalAttr", + CXCursor_CXXOverrideAttr => "CXXOverrideAttr", + CXCursor_AnnotateAttr => "AnnotateAttr", + CXCursor_AsmLabelAttr => "AsmLabelAttr", + // CXCursor_LastAttr => "LastAttr", + CXCursor_PreprocessingDirective => "PreprocessingDirective", + CXCursor_MacroDefinition => "MacroDefinition", + CXCursor_MacroExpansion => "MacroExpansion", + // CXCursor_MacroInstantiation => "MacroInstantiation", + CXCursor_InclusionDirective => "InclusionDirective", + //CXCursor_FirstPreprocessing => "FirstPreprocessing", + //CXCursor_LastPreprocessing => "LastPreprocessing", + + _ => "?", + } +} + +pub fn type_to_str(x: Enum_CXTypeKind) -> &str { + match x { + CXType_Invalid => "Invalid", + CXType_Unexposed => "Unexposed", + CXType_Void => "Void", + CXType_Bool => "Bool", + CXType_Char_U => "Char_U", + CXType_UChar => "UChar", + CXType_Char16=> "Char16", + CXType_Char32=> "Char32", + CXType_UShort => "UShort", + CXType_UInt => "UInt", + CXType_ULong => "ULong", + CXType_ULongLong => "ULongLong", + CXType_UInt128=>"UInt128", + CXType_Char_S => "Char_S", + CXType_SChar => "SChar", + CXType_WChar => "WChar", + CXType_Short => "Short", + CXType_Int => "Int", + CXType_Long => "Long", + CXType_LongLong => "LongLong", + CXType_Int128=>"Int128", + CXType_Float => "Float", + CXType_Double => "Double", + CXType_LongDouble => "LongDouble", + CXType_NullPtr => "NullPtr", + CXType_Overload => "Overload", + CXType_Dependent => "Dependent", + CXType_ObjCId => "ObjCId", + CXType_ObjCClass => "ObjCClass", + CXType_ObjCSel => "ObjCSel", + // CXType_FirstBuiltin => "FirstBuiltin", + // CXType_LastBuiltin => "LastBuiltin", + CXType_Complex => "Complex", + CXType_Pointer => "Pointer", + CXType_BlockPointer => "BlockPointer", + CXType_LValueReference => "LValueReference", + CXType_RValueReference => "RValueReference", + CXType_Record => "Record", + CXType_Enum => "Enum", + CXType_Typedef => "Typedef", + CXType_ObjCInterface => "ObjCInterface", + CXType_ObjCObjectPointer => "ObjCObjectPointer", + CXType_FunctionNoProto => "FunctionNoProto", + CXType_FunctionProto => "FunctionProto", + CXType_ConstantArray => "ConstantArray", + CXType_Vector => "Vector", + CXType_IncompleteArray => "IncompleteArray", + CXType_VariableArray => "VariableArray", + CXType_DependentSizedArray => "DependentSizedArray", + _ => "?" + } +} + +// Debug +pub fn ast_dump(c: &Cursor, depth: int)-> Enum_CXVisitorResult { + fn print_indent(depth: int, s: &str) { + let mut i = 0; + while i < depth { + io::print("\t"); + i += 1; + } + io::println(s); + } + let ct = c.cur_type().kind(); + print_indent(depth, format!("({} {} {}", + kind_to_str(c.kind()).as_slice(), + c.spelling().as_slice(), + type_to_str(ct)).as_slice() + ); + c.visit(|s, _| { + ast_dump(s, depth + 1) + }); + print_indent(depth, ")"); + return CXChildVisit_Continue; +} diff --git a/src/clangll.rs b/src/clangll.rs new file mode 100644 index 00000000..27261f83 --- /dev/null +++ b/src/clangll.rs @@ -0,0 +1,1357 @@ +/* automatically generated by rust-bindgen */ + +#![allow(non_camel_case_types)] +#![allow(uppercase_variables)] +#![allow(dead_code)] +#![allow(unused_attribute)] + +pub type ptrdiff_t = ::libc::c_long; +pub type size_t = ::libc::c_ulong; +pub type wchar_t = ::libc::c_int; +#[repr(C)] +pub struct CXString { + pub data: *const ::libc::c_void, + pub private_flags: ::libc::c_uint, +} +pub type CXIndex = *mut ::libc::c_void; +pub enum Struct_CXTranslationUnitImpl { } +pub type CXTranslationUnit = *mut Struct_CXTranslationUnitImpl; +pub type CXClientData = *mut ::libc::c_void; +#[repr(C)] +pub struct Struct_CXUnsavedFile { + pub Filename: *const ::libc::c_char, + pub Contents: *const ::libc::c_char, + pub Length: ::libc::c_ulong, +} +pub type Enum_CXAvailabilityKind = ::libc::c_uint; +pub static CXAvailability_Available: ::libc::c_uint = 0; +pub static CXAvailability_Deprecated: ::libc::c_uint = 1; +pub static CXAvailability_NotAvailable: ::libc::c_uint = 2; +pub static CXAvailability_NotAccessible: ::libc::c_uint = 3; +#[repr(C)] +pub struct Struct_CXVersion { + pub Major: ::libc::c_int, + pub Minor: ::libc::c_int, + pub Subminor: ::libc::c_int, +} +pub type CXVersion = Struct_CXVersion; +pub type CXGlobalOptFlags = ::libc::c_uint; +pub static CXGlobalOpt_None: ::libc::c_uint = 0; +pub static CXGlobalOpt_ThreadBackgroundPriorityForIndexing: ::libc::c_uint = + 1; +pub static CXGlobalOpt_ThreadBackgroundPriorityForEditing: ::libc::c_uint = 2; +pub static CXGlobalOpt_ThreadBackgroundPriorityForAll: ::libc::c_uint = 3; +pub type CXFile = *mut ::libc::c_void; +#[repr(C)] +pub struct CXFileUniqueID { + pub data: [::libc::c_ulonglong, ..3u], +} +#[repr(C)] +pub struct CXSourceLocation { + pub ptr_data: [*const ::libc::c_void, ..2u], + pub int_data: ::libc::c_uint, +} +#[repr(C)] +pub struct CXSourceRange { + pub ptr_data: [*const ::libc::c_void, ..2u], + pub begin_int_data: ::libc::c_uint, + pub end_int_data: ::libc::c_uint, +} +pub type Enum_CXDiagnosticSeverity = ::libc::c_uint; +pub static CXDiagnostic_Ignored: ::libc::c_uint = 0; +pub static CXDiagnostic_Note: ::libc::c_uint = 1; +pub static CXDiagnostic_Warning: ::libc::c_uint = 2; +pub static CXDiagnostic_Error: ::libc::c_uint = 3; +pub static CXDiagnostic_Fatal: ::libc::c_uint = 4; +pub type CXDiagnostic = *mut ::libc::c_void; +pub type CXDiagnosticSet = *mut ::libc::c_void; +pub type Enum_CXLoadDiag_Error = ::libc::c_uint; +pub static CXLoadDiag_None: ::libc::c_uint = 0; +pub static CXLoadDiag_Unknown: ::libc::c_uint = 1; +pub static CXLoadDiag_CannotLoad: ::libc::c_uint = 2; +pub static CXLoadDiag_InvalidFile: ::libc::c_uint = 3; +pub type Enum_CXDiagnosticDisplayOptions = ::libc::c_uint; +pub static CXDiagnostic_DisplaySourceLocation: ::libc::c_uint = 1; +pub static CXDiagnostic_DisplayColumn: ::libc::c_uint = 2; +pub static CXDiagnostic_DisplaySourceRanges: ::libc::c_uint = 4; +pub static CXDiagnostic_DisplayOption: ::libc::c_uint = 8; +pub static CXDiagnostic_DisplayCategoryId: ::libc::c_uint = 16; +pub static CXDiagnostic_DisplayCategoryName: ::libc::c_uint = 32; +pub type Enum_CXTranslationUnit_Flags = ::libc::c_uint; +pub static CXTranslationUnit_None: ::libc::c_uint = 0; +pub static CXTranslationUnit_DetailedPreprocessingRecord: ::libc::c_uint = 1; +pub static CXTranslationUnit_Incomplete: ::libc::c_uint = 2; +pub static CXTranslationUnit_PrecompiledPreamble: ::libc::c_uint = 4; +pub static CXTranslationUnit_CacheCompletionResults: ::libc::c_uint = 8; +pub static CXTranslationUnit_ForSerialization: ::libc::c_uint = 16; +pub static CXTranslationUnit_CXXChainedPCH: ::libc::c_uint = 32; +pub static CXTranslationUnit_SkipFunctionBodies: ::libc::c_uint = 64; +pub static CXTranslationUnit_IncludeBriefCommentsInCodeCompletion: + ::libc::c_uint = + 128; +pub type Enum_CXSaveTranslationUnit_Flags = ::libc::c_uint; +pub static CXSaveTranslationUnit_None: ::libc::c_uint = 0; +pub type Enum_CXSaveError = ::libc::c_uint; +pub static CXSaveError_None: ::libc::c_uint = 0; +pub static CXSaveError_Unknown: ::libc::c_uint = 1; +pub static CXSaveError_TranslationErrors: ::libc::c_uint = 2; +pub static CXSaveError_InvalidTU: ::libc::c_uint = 3; +pub type Enum_CXReparse_Flags = ::libc::c_uint; +pub static CXReparse_None: ::libc::c_uint = 0; +pub type Enum_CXTUResourceUsageKind = ::libc::c_uint; +pub static CXTUResourceUsage_AST: ::libc::c_uint = 1; +pub static CXTUResourceUsage_Identifiers: ::libc::c_uint = 2; +pub static CXTUResourceUsage_Selectors: ::libc::c_uint = 3; +pub static CXTUResourceUsage_GlobalCompletionResults: ::libc::c_uint = 4; +pub static CXTUResourceUsage_SourceManagerContentCache: ::libc::c_uint = 5; +pub static CXTUResourceUsage_AST_SideTables: ::libc::c_uint = 6; +pub static CXTUResourceUsage_SourceManager_Membuffer_Malloc: ::libc::c_uint = + 7; +pub static CXTUResourceUsage_SourceManager_Membuffer_MMap: ::libc::c_uint = 8; +pub static CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc: + ::libc::c_uint = + 9; +pub static CXTUResourceUsage_ExternalASTSource_Membuffer_MMap: ::libc::c_uint + = + 10; +pub static CXTUResourceUsage_Preprocessor: ::libc::c_uint = 11; +pub static CXTUResourceUsage_PreprocessingRecord: ::libc::c_uint = 12; +pub static CXTUResourceUsage_SourceManager_DataStructures: ::libc::c_uint = + 13; +pub static CXTUResourceUsage_Preprocessor_HeaderSearch: ::libc::c_uint = 14; +pub static CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN: ::libc::c_uint = 1; +pub static CXTUResourceUsage_MEMORY_IN_BYTES_END: ::libc::c_uint = 14; +pub static CXTUResourceUsage_First: ::libc::c_uint = 1; +pub static CXTUResourceUsage_Last: ::libc::c_uint = 14; +#[repr(C)] +pub struct Struct_CXTUResourceUsageEntry { + pub kind: Enum_CXTUResourceUsageKind, + pub amount: ::libc::c_ulong, +} +pub type CXTUResourceUsageEntry = Struct_CXTUResourceUsageEntry; +#[repr(C)] +pub struct Struct_CXTUResourceUsage { + pub data: *mut ::libc::c_void, + pub numEntries: ::libc::c_uint, + pub entries: *mut CXTUResourceUsageEntry, +} +pub type CXTUResourceUsage = Struct_CXTUResourceUsage; +pub type Enum_CXCursorKind = ::libc::c_uint; +pub static CXCursor_UnexposedDecl: ::libc::c_uint = 1; +pub static CXCursor_StructDecl: ::libc::c_uint = 2; +pub static CXCursor_UnionDecl: ::libc::c_uint = 3; +pub static CXCursor_ClassDecl: ::libc::c_uint = 4; +pub static CXCursor_EnumDecl: ::libc::c_uint = 5; +pub static CXCursor_FieldDecl: ::libc::c_uint = 6; +pub static CXCursor_EnumConstantDecl: ::libc::c_uint = 7; +pub static CXCursor_FunctionDecl: ::libc::c_uint = 8; +pub static CXCursor_VarDecl: ::libc::c_uint = 9; +pub static CXCursor_ParmDecl: ::libc::c_uint = 10; +pub static CXCursor_ObjCInterfaceDecl: ::libc::c_uint = 11; +pub static CXCursor_ObjCCategoryDecl: ::libc::c_uint = 12; +pub static CXCursor_ObjCProtocolDecl: ::libc::c_uint = 13; +pub static CXCursor_ObjCPropertyDecl: ::libc::c_uint = 14; +pub static CXCursor_ObjCIvarDecl: ::libc::c_uint = 15; +pub static CXCursor_ObjCInstanceMethodDecl: ::libc::c_uint = 16; +pub static CXCursor_ObjCClassMethodDecl: ::libc::c_uint = 17; +pub static CXCursor_ObjCImplementationDecl: ::libc::c_uint = 18; +pub static CXCursor_ObjCCategoryImplDecl: ::libc::c_uint = 19; +pub static CXCursor_TypedefDecl: ::libc::c_uint = 20; +pub static CXCursor_CXXMethod: ::libc::c_uint = 21; +pub static CXCursor_Namespace: ::libc::c_uint = 22; +pub static CXCursor_LinkageSpec: ::libc::c_uint = 23; +pub static CXCursor_Constructor: ::libc::c_uint = 24; +pub static CXCursor_Destructor: ::libc::c_uint = 25; +pub static CXCursor_ConversionFunction: ::libc::c_uint = 26; +pub static CXCursor_TemplateTypeParameter: ::libc::c_uint = 27; +pub static CXCursor_NonTypeTemplateParameter: ::libc::c_uint = 28; +pub static CXCursor_TemplateTemplateParameter: ::libc::c_uint = 29; +pub static CXCursor_FunctionTemplate: ::libc::c_uint = 30; +pub static CXCursor_ClassTemplate: ::libc::c_uint = 31; +pub static CXCursor_ClassTemplatePartialSpecialization: ::libc::c_uint = 32; +pub static CXCursor_NamespaceAlias: ::libc::c_uint = 33; +pub static CXCursor_UsingDirective: ::libc::c_uint = 34; +pub static CXCursor_UsingDeclaration: ::libc::c_uint = 35; +pub static CXCursor_TypeAliasDecl: ::libc::c_uint = 36; +pub static CXCursor_ObjCSynthesizeDecl: ::libc::c_uint = 37; +pub static CXCursor_ObjCDynamicDecl: ::libc::c_uint = 38; +pub static CXCursor_CXXAccessSpecifier: ::libc::c_uint = 39; +pub static CXCursor_FirstDecl: ::libc::c_uint = 1; +pub static CXCursor_LastDecl: ::libc::c_uint = 39; +pub static CXCursor_FirstRef: ::libc::c_uint = 40; +pub static CXCursor_ObjCSuperClassRef: ::libc::c_uint = 40; +pub static CXCursor_ObjCProtocolRef: ::libc::c_uint = 41; +pub static CXCursor_ObjCClassRef: ::libc::c_uint = 42; +pub static CXCursor_TypeRef: ::libc::c_uint = 43; +pub static CXCursor_CXXBaseSpecifier: ::libc::c_uint = 44; +pub static CXCursor_TemplateRef: ::libc::c_uint = 45; +pub static CXCursor_NamespaceRef: ::libc::c_uint = 46; +pub static CXCursor_MemberRef: ::libc::c_uint = 47; +pub static CXCursor_LabelRef: ::libc::c_uint = 48; +pub static CXCursor_OverloadedDeclRef: ::libc::c_uint = 49; +pub static CXCursor_VariableRef: ::libc::c_uint = 50; +pub static CXCursor_LastRef: ::libc::c_uint = 50; +pub static CXCursor_FirstInvalid: ::libc::c_uint = 70; +pub static CXCursor_InvalidFile: ::libc::c_uint = 70; +pub static CXCursor_NoDeclFound: ::libc::c_uint = 71; +pub static CXCursor_NotImplemented: ::libc::c_uint = 72; +pub static CXCursor_InvalidCode: ::libc::c_uint = 73; +pub static CXCursor_LastInvalid: ::libc::c_uint = 73; +pub static CXCursor_FirstExpr: ::libc::c_uint = 100; +pub static CXCursor_UnexposedExpr: ::libc::c_uint = 100; +pub static CXCursor_DeclRefExpr: ::libc::c_uint = 101; +pub static CXCursor_MemberRefExpr: ::libc::c_uint = 102; +pub static CXCursor_CallExpr: ::libc::c_uint = 103; +pub static CXCursor_ObjCMessageExpr: ::libc::c_uint = 104; +pub static CXCursor_BlockExpr: ::libc::c_uint = 105; +pub static CXCursor_IntegerLiteral: ::libc::c_uint = 106; +pub static CXCursor_FloatingLiteral: ::libc::c_uint = 107; +pub static CXCursor_ImaginaryLiteral: ::libc::c_uint = 108; +pub static CXCursor_StringLiteral: ::libc::c_uint = 109; +pub static CXCursor_CharacterLiteral: ::libc::c_uint = 110; +pub static CXCursor_ParenExpr: ::libc::c_uint = 111; +pub static CXCursor_UnaryOperator: ::libc::c_uint = 112; +pub static CXCursor_ArraySubscriptExpr: ::libc::c_uint = 113; +pub static CXCursor_BinaryOperator: ::libc::c_uint = 114; +pub static CXCursor_CompoundAssignOperator: ::libc::c_uint = 115; +pub static CXCursor_ConditionalOperator: ::libc::c_uint = 116; +pub static CXCursor_CStyleCastExpr: ::libc::c_uint = 117; +pub static CXCursor_CompoundLiteralExpr: ::libc::c_uint = 118; +pub static CXCursor_InitListExpr: ::libc::c_uint = 119; +pub static CXCursor_AddrLabelExpr: ::libc::c_uint = 120; +pub static CXCursor_StmtExpr: ::libc::c_uint = 121; +pub static CXCursor_GenericSelectionExpr: ::libc::c_uint = 122; +pub static CXCursor_GNUNullExpr: ::libc::c_uint = 123; +pub static CXCursor_CXXStaticCastExpr: ::libc::c_uint = 124; +pub static CXCursor_CXXDynamicCastExpr: ::libc::c_uint = 125; +pub static CXCursor_CXXReinterpretCastExpr: ::libc::c_uint = 126; +pub static CXCursor_CXXConstCastExpr: ::libc::c_uint = 127; +pub static CXCursor_CXXFunctionalCastExpr: ::libc::c_uint = 128; +pub static CXCursor_CXXTypeidExpr: ::libc::c_uint = 129; +pub static CXCursor_CXXBoolLiteralExpr: ::libc::c_uint = 130; +pub static CXCursor_CXXNullPtrLiteralExpr: ::libc::c_uint = 131; +pub static CXCursor_CXXThisExpr: ::libc::c_uint = 132; +pub static CXCursor_CXXThrowExpr: ::libc::c_uint = 133; +pub static CXCursor_CXXNewExpr: ::libc::c_uint = 134; +pub static CXCursor_CXXDeleteExpr: ::libc::c_uint = 135; +pub static CXCursor_UnaryExpr: ::libc::c_uint = 136; +pub static CXCursor_ObjCStringLiteral: ::libc::c_uint = 137; +pub static CXCursor_ObjCEncodeExpr: ::libc::c_uint = 138; +pub static CXCursor_ObjCSelectorExpr: ::libc::c_uint = 139; +pub static CXCursor_ObjCProtocolExpr: ::libc::c_uint = 140; +pub static CXCursor_ObjCBridgedCastExpr: ::libc::c_uint = 141; +pub static CXCursor_PackExpansionExpr: ::libc::c_uint = 142; +pub static CXCursor_SizeOfPackExpr: ::libc::c_uint = 143; +pub static CXCursor_LambdaExpr: ::libc::c_uint = 144; +pub static CXCursor_ObjCBoolLiteralExpr: ::libc::c_uint = 145; +pub static CXCursor_ObjCSelfExpr: ::libc::c_uint = 146; +pub static CXCursor_LastExpr: ::libc::c_uint = 146; +pub static CXCursor_FirstStmt: ::libc::c_uint = 200; +pub static CXCursor_UnexposedStmt: ::libc::c_uint = 200; +pub static CXCursor_LabelStmt: ::libc::c_uint = 201; +pub static CXCursor_CompoundStmt: ::libc::c_uint = 202; +pub static CXCursor_CaseStmt: ::libc::c_uint = 203; +pub static CXCursor_DefaultStmt: ::libc::c_uint = 204; +pub static CXCursor_IfStmt: ::libc::c_uint = 205; +pub static CXCursor_SwitchStmt: ::libc::c_uint = 206; +pub static CXCursor_WhileStmt: ::libc::c_uint = 207; +pub static CXCursor_DoStmt: ::libc::c_uint = 208; +pub static CXCursor_ForStmt: ::libc::c_uint = 209; +pub static CXCursor_GotoStmt: ::libc::c_uint = 210; +pub static CXCursor_IndirectGotoStmt: ::libc::c_uint = 211; +pub static CXCursor_ContinueStmt: ::libc::c_uint = 212; +pub static CXCursor_BreakStmt: ::libc::c_uint = 213; +pub static CXCursor_ReturnStmt: ::libc::c_uint = 214; +pub static CXCursor_GCCAsmStmt: ::libc::c_uint = 215; +pub static CXCursor_AsmStmt: ::libc::c_uint = 215; +pub static CXCursor_ObjCAtTryStmt: ::libc::c_uint = 216; +pub static CXCursor_ObjCAtCatchStmt: ::libc::c_uint = 217; +pub static CXCursor_ObjCAtFinallyStmt: ::libc::c_uint = 218; +pub static CXCursor_ObjCAtThrowStmt: ::libc::c_uint = 219; +pub static CXCursor_ObjCAtSynchronizedStmt: ::libc::c_uint = 220; +pub static CXCursor_ObjCAutoreleasePoolStmt: ::libc::c_uint = 221; +pub static CXCursor_ObjCForCollectionStmt: ::libc::c_uint = 222; +pub static CXCursor_CXXCatchStmt: ::libc::c_uint = 223; +pub static CXCursor_CXXTryStmt: ::libc::c_uint = 224; +pub static CXCursor_CXXForRangeStmt: ::libc::c_uint = 225; +pub static CXCursor_SEHTryStmt: ::libc::c_uint = 226; +pub static CXCursor_SEHExceptStmt: ::libc::c_uint = 227; +pub static CXCursor_SEHFinallyStmt: ::libc::c_uint = 228; +pub static CXCursor_MSAsmStmt: ::libc::c_uint = 229; +pub static CXCursor_NullStmt: ::libc::c_uint = 230; +pub static CXCursor_DeclStmt: ::libc::c_uint = 231; +pub static CXCursor_OMPParallelDirective: ::libc::c_uint = 232; +pub static CXCursor_LastStmt: ::libc::c_uint = 232; +pub static CXCursor_TranslationUnit: ::libc::c_uint = 300; +pub static CXCursor_FirstAttr: ::libc::c_uint = 400; +pub static CXCursor_UnexposedAttr: ::libc::c_uint = 400; +pub static CXCursor_IBActionAttr: ::libc::c_uint = 401; +pub static CXCursor_IBOutletAttr: ::libc::c_uint = 402; +pub static CXCursor_IBOutletCollectionAttr: ::libc::c_uint = 403; +pub static CXCursor_CXXFinalAttr: ::libc::c_uint = 404; +pub static CXCursor_CXXOverrideAttr: ::libc::c_uint = 405; +pub static CXCursor_AnnotateAttr: ::libc::c_uint = 406; +pub static CXCursor_AsmLabelAttr: ::libc::c_uint = 407; +pub static CXCursor_PackedAttr: ::libc::c_uint = 408; +pub static CXCursor_LastAttr: ::libc::c_uint = 408; +pub static CXCursor_PreprocessingDirective: ::libc::c_uint = 500; +pub static CXCursor_MacroDefinition: ::libc::c_uint = 501; +pub static CXCursor_MacroExpansion: ::libc::c_uint = 502; +pub static CXCursor_MacroInstantiation: ::libc::c_uint = 502; +pub static CXCursor_InclusionDirective: ::libc::c_uint = 503; +pub static CXCursor_FirstPreprocessing: ::libc::c_uint = 500; +pub static CXCursor_LastPreprocessing: ::libc::c_uint = 503; +pub static CXCursor_ModuleImportDecl: ::libc::c_uint = 600; +pub static CXCursor_FirstExtraDecl: ::libc::c_uint = 600; +pub static CXCursor_LastExtraDecl: ::libc::c_uint = 600; +#[repr(C)] +pub struct CXCursor { + pub kind: Enum_CXCursorKind, + pub xdata: ::libc::c_int, + pub data: [*const ::libc::c_void, ..3u], +} +#[repr(C)] +pub struct CXComment { + pub ASTNode: *const ::libc::c_void, + pub TranslationUnit: CXTranslationUnit, +} +pub type Enum_CXLinkageKind = ::libc::c_uint; +pub static CXLinkage_Invalid: ::libc::c_uint = 0; +pub static CXLinkage_NoLinkage: ::libc::c_uint = 1; +pub static CXLinkage_Internal: ::libc::c_uint = 2; +pub static CXLinkage_UniqueExternal: ::libc::c_uint = 3; +pub static CXLinkage_External: ::libc::c_uint = 4; +#[repr(C)] +pub struct Struct_CXPlatformAvailability { + pub Platform: CXString, + pub Introduced: CXVersion, + pub Deprecated: CXVersion, + pub Obsoleted: CXVersion, + pub Unavailable: ::libc::c_int, + pub Message: CXString, +} +pub type CXPlatformAvailability = Struct_CXPlatformAvailability; +pub type Enum_CXLanguageKind = ::libc::c_uint; +pub static CXLanguage_Invalid: ::libc::c_uint = 0; +pub static CXLanguage_C: ::libc::c_uint = 1; +pub static CXLanguage_ObjC: ::libc::c_uint = 2; +pub static CXLanguage_CPlusPlus: ::libc::c_uint = 3; +pub enum Struct_CXCursorSetImpl { } +pub type CXCursorSet = *mut Struct_CXCursorSetImpl; +pub type Enum_CXTypeKind = ::libc::c_uint; +pub static CXType_Invalid: ::libc::c_uint = 0; +pub static CXType_Unexposed: ::libc::c_uint = 1; +pub static CXType_Void: ::libc::c_uint = 2; +pub static CXType_Bool: ::libc::c_uint = 3; +pub static CXType_Char_U: ::libc::c_uint = 4; +pub static CXType_UChar: ::libc::c_uint = 5; +pub static CXType_Char16: ::libc::c_uint = 6; +pub static CXType_Char32: ::libc::c_uint = 7; +pub static CXType_UShort: ::libc::c_uint = 8; +pub static CXType_UInt: ::libc::c_uint = 9; +pub static CXType_ULong: ::libc::c_uint = 10; +pub static CXType_ULongLong: ::libc::c_uint = 11; +pub static CXType_UInt128: ::libc::c_uint = 12; +pub static CXType_Char_S: ::libc::c_uint = 13; +pub static CXType_SChar: ::libc::c_uint = 14; +pub static CXType_WChar: ::libc::c_uint = 15; +pub static CXType_Short: ::libc::c_uint = 16; +pub static CXType_Int: ::libc::c_uint = 17; +pub static CXType_Long: ::libc::c_uint = 18; +pub static CXType_LongLong: ::libc::c_uint = 19; +pub static CXType_Int128: ::libc::c_uint = 20; +pub static CXType_Float: ::libc::c_uint = 21; +pub static CXType_Double: ::libc::c_uint = 22; +pub static CXType_LongDouble: ::libc::c_uint = 23; +pub static CXType_NullPtr: ::libc::c_uint = 24; +pub static CXType_Overload: ::libc::c_uint = 25; +pub static CXType_Dependent: ::libc::c_uint = 26; +pub static CXType_ObjCId: ::libc::c_uint = 27; +pub static CXType_ObjCClass: ::libc::c_uint = 28; +pub static CXType_ObjCSel: ::libc::c_uint = 29; +pub static CXType_FirstBuiltin: ::libc::c_uint = 2; +pub static CXType_LastBuiltin: ::libc::c_uint = 29; +pub static CXType_Complex: ::libc::c_uint = 100; +pub static CXType_Pointer: ::libc::c_uint = 101; +pub static CXType_BlockPointer: ::libc::c_uint = 102; +pub static CXType_LValueReference: ::libc::c_uint = 103; +pub static CXType_RValueReference: ::libc::c_uint = 104; +pub static CXType_Record: ::libc::c_uint = 105; +pub static CXType_Enum: ::libc::c_uint = 106; +pub static CXType_Typedef: ::libc::c_uint = 107; +pub static CXType_ObjCInterface: ::libc::c_uint = 108; +pub static CXType_ObjCObjectPointer: ::libc::c_uint = 109; +pub static CXType_FunctionNoProto: ::libc::c_uint = 110; +pub static CXType_FunctionProto: ::libc::c_uint = 111; +pub static CXType_ConstantArray: ::libc::c_uint = 112; +pub static CXType_Vector: ::libc::c_uint = 113; +pub static CXType_IncompleteArray: ::libc::c_uint = 114; +pub static CXType_VariableArray: ::libc::c_uint = 115; +pub static CXType_DependentSizedArray: ::libc::c_uint = 116; +pub static CXType_MemberPointer: ::libc::c_uint = 117; +pub type Enum_CXCallingConv = ::libc::c_uint; +pub static CXCallingConv_Default: ::libc::c_uint = 0; +pub static CXCallingConv_C: ::libc::c_uint = 1; +pub static CXCallingConv_X86StdCall: ::libc::c_uint = 2; +pub static CXCallingConv_X86FastCall: ::libc::c_uint = 3; +pub static CXCallingConv_X86ThisCall: ::libc::c_uint = 4; +pub static CXCallingConv_X86Pascal: ::libc::c_uint = 5; +pub static CXCallingConv_AAPCS: ::libc::c_uint = 6; +pub static CXCallingConv_AAPCS_VFP: ::libc::c_uint = 7; +pub static CXCallingConv_PnaclCall: ::libc::c_uint = 8; +pub static CXCallingConv_IntelOclBicc: ::libc::c_uint = 9; +pub static CXCallingConv_X86_64Win64: ::libc::c_uint = 10; +pub static CXCallingConv_X86_64SysV: ::libc::c_uint = 11; +pub static CXCallingConv_Invalid: ::libc::c_uint = 100; +pub static CXCallingConv_Unexposed: ::libc::c_uint = 200; +#[repr(C)] +pub struct CXType { + pub kind: Enum_CXTypeKind, + pub data: [*mut ::libc::c_void, ..2u], +} +pub type Enum_CXTypeLayoutError = ::libc::c_int; +pub static CXTypeLayoutError_Invalid: ::libc::c_int = -1; +pub static CXTypeLayoutError_Incomplete: ::libc::c_int = -2; +pub static CXTypeLayoutError_Dependent: ::libc::c_int = -3; +pub static CXTypeLayoutError_NotConstantSize: ::libc::c_int = -4; +pub static CXTypeLayoutError_InvalidFieldName: ::libc::c_int = -5; +pub type Enum_CXRefQualifierKind = ::libc::c_uint; +pub static CXRefQualifier_None: ::libc::c_uint = 0; +pub static CXRefQualifier_LValue: ::libc::c_uint = 1; +pub static CXRefQualifier_RValue: ::libc::c_uint = 2; +pub type Enum_CX_CXXAccessSpecifier = ::libc::c_uint; +pub static CX_CXXInvalidAccessSpecifier: ::libc::c_uint = 0; +pub static CX_CXXPublic: ::libc::c_uint = 1; +pub static CX_CXXProtected: ::libc::c_uint = 2; +pub static CX_CXXPrivate: ::libc::c_uint = 3; +pub type Enum_CXChildVisitResult = ::libc::c_uint; +pub static CXChildVisit_Break: ::libc::c_uint = 0; +pub static CXChildVisit_Continue: ::libc::c_uint = 1; +pub static CXChildVisit_Recurse: ::libc::c_uint = 2; +pub type CXCursorVisitor = + ::std::option::Option Enum_CXChildVisitResult>; +pub type CXObjCPropertyAttrKind = ::libc::c_uint; +pub static CXObjCPropertyAttr_noattr: ::libc::c_uint = 0; +pub static CXObjCPropertyAttr_readonly: ::libc::c_uint = 1; +pub static CXObjCPropertyAttr_getter: ::libc::c_uint = 2; +pub static CXObjCPropertyAttr_assign: ::libc::c_uint = 4; +pub static CXObjCPropertyAttr_readwrite: ::libc::c_uint = 8; +pub static CXObjCPropertyAttr_retain: ::libc::c_uint = 16; +pub static CXObjCPropertyAttr_copy: ::libc::c_uint = 32; +pub static CXObjCPropertyAttr_nonatomic: ::libc::c_uint = 64; +pub static CXObjCPropertyAttr_setter: ::libc::c_uint = 128; +pub static CXObjCPropertyAttr_atomic: ::libc::c_uint = 256; +pub static CXObjCPropertyAttr_weak: ::libc::c_uint = 512; +pub static CXObjCPropertyAttr_strong: ::libc::c_uint = 1024; +pub static CXObjCPropertyAttr_unsafe_unretained: ::libc::c_uint = 2048; +pub type CXObjCDeclQualifierKind = ::libc::c_uint; +pub static CXObjCDeclQualifier_None: ::libc::c_uint = 0; +pub static CXObjCDeclQualifier_In: ::libc::c_uint = 1; +pub static CXObjCDeclQualifier_Inout: ::libc::c_uint = 2; +pub static CXObjCDeclQualifier_Out: ::libc::c_uint = 4; +pub static CXObjCDeclQualifier_Bycopy: ::libc::c_uint = 8; +pub static CXObjCDeclQualifier_Byref: ::libc::c_uint = 16; +pub static CXObjCDeclQualifier_Oneway: ::libc::c_uint = 32; +pub type CXModule = *mut ::libc::c_void; +pub type Enum_CXCommentKind = ::libc::c_uint; +pub static CXComment_Null: ::libc::c_uint = 0; +pub static CXComment_Text: ::libc::c_uint = 1; +pub static CXComment_InlineCommand: ::libc::c_uint = 2; +pub static CXComment_HTMLStartTag: ::libc::c_uint = 3; +pub static CXComment_HTMLEndTag: ::libc::c_uint = 4; +pub static CXComment_Paragraph: ::libc::c_uint = 5; +pub static CXComment_BlockCommand: ::libc::c_uint = 6; +pub static CXComment_ParamCommand: ::libc::c_uint = 7; +pub static CXComment_TParamCommand: ::libc::c_uint = 8; +pub static CXComment_VerbatimBlockCommand: ::libc::c_uint = 9; +pub static CXComment_VerbatimBlockLine: ::libc::c_uint = 10; +pub static CXComment_VerbatimLine: ::libc::c_uint = 11; +pub static CXComment_FullComment: ::libc::c_uint = 12; +pub type Enum_CXCommentInlineCommandRenderKind = ::libc::c_uint; +pub static CXCommentInlineCommandRenderKind_Normal: ::libc::c_uint = 0; +pub static CXCommentInlineCommandRenderKind_Bold: ::libc::c_uint = 1; +pub static CXCommentInlineCommandRenderKind_Monospaced: ::libc::c_uint = 2; +pub static CXCommentInlineCommandRenderKind_Emphasized: ::libc::c_uint = 3; +pub type Enum_CXCommentParamPassDirection = ::libc::c_uint; +pub static CXCommentParamPassDirection_In: ::libc::c_uint = 0; +pub static CXCommentParamPassDirection_Out: ::libc::c_uint = 1; +pub static CXCommentParamPassDirection_InOut: ::libc::c_uint = 2; +pub type Enum_CXNameRefFlags = ::libc::c_uint; +pub static CXNameRange_WantQualifier: ::libc::c_uint = 1; +pub static CXNameRange_WantTemplateArgs: ::libc::c_uint = 2; +pub static CXNameRange_WantSinglePiece: ::libc::c_uint = 4; +pub type Enum_CXTokenKind = ::libc::c_uint; +pub static CXToken_Punctuation: ::libc::c_uint = 0; +pub static CXToken_Keyword: ::libc::c_uint = 1; +pub static CXToken_Identifier: ::libc::c_uint = 2; +pub static CXToken_Literal: ::libc::c_uint = 3; +pub static CXToken_Comment: ::libc::c_uint = 4; +pub type CXTokenKind = Enum_CXTokenKind; +#[repr(C)] +pub struct CXToken { + pub int_data: [::libc::c_uint, ..4u], + pub ptr_data: *mut ::libc::c_void, +} +pub type CXCompletionString = *mut ::libc::c_void; +#[repr(C)] +pub struct CXCompletionResult { + pub CursorKind: Enum_CXCursorKind, + pub CompletionString: CXCompletionString, +} +pub type Enum_CXCompletionChunkKind = ::libc::c_uint; +pub static CXCompletionChunk_Optional: ::libc::c_uint = 0; +pub static CXCompletionChunk_TypedText: ::libc::c_uint = 1; +pub static CXCompletionChunk_Text: ::libc::c_uint = 2; +pub static CXCompletionChunk_Placeholder: ::libc::c_uint = 3; +pub static CXCompletionChunk_Informative: ::libc::c_uint = 4; +pub static CXCompletionChunk_CurrentParameter: ::libc::c_uint = 5; +pub static CXCompletionChunk_LeftParen: ::libc::c_uint = 6; +pub static CXCompletionChunk_RightParen: ::libc::c_uint = 7; +pub static CXCompletionChunk_LeftBracket: ::libc::c_uint = 8; +pub static CXCompletionChunk_RightBracket: ::libc::c_uint = 9; +pub static CXCompletionChunk_LeftBrace: ::libc::c_uint = 10; +pub static CXCompletionChunk_RightBrace: ::libc::c_uint = 11; +pub static CXCompletionChunk_LeftAngle: ::libc::c_uint = 12; +pub static CXCompletionChunk_RightAngle: ::libc::c_uint = 13; +pub static CXCompletionChunk_Comma: ::libc::c_uint = 14; +pub static CXCompletionChunk_ResultType: ::libc::c_uint = 15; +pub static CXCompletionChunk_Colon: ::libc::c_uint = 16; +pub static CXCompletionChunk_SemiColon: ::libc::c_uint = 17; +pub static CXCompletionChunk_Equal: ::libc::c_uint = 18; +pub static CXCompletionChunk_HorizontalSpace: ::libc::c_uint = 19; +pub static CXCompletionChunk_VerticalSpace: ::libc::c_uint = 20; +#[repr(C)] +pub struct CXCodeCompleteResults { + pub Results: *mut CXCompletionResult, + pub NumResults: ::libc::c_uint, +} +pub type Enum_CXCodeComplete_Flags = ::libc::c_uint; +pub static CXCodeComplete_IncludeMacros: ::libc::c_uint = 1; +pub static CXCodeComplete_IncludeCodePatterns: ::libc::c_uint = 2; +pub static CXCodeComplete_IncludeBriefComments: ::libc::c_uint = 4; +pub type Enum_CXCompletionContext = ::libc::c_uint; +pub static CXCompletionContext_Unexposed: ::libc::c_uint = 0; +pub static CXCompletionContext_AnyType: ::libc::c_uint = 1; +pub static CXCompletionContext_AnyValue: ::libc::c_uint = 2; +pub static CXCompletionContext_ObjCObjectValue: ::libc::c_uint = 4; +pub static CXCompletionContext_ObjCSelectorValue: ::libc::c_uint = 8; +pub static CXCompletionContext_CXXClassTypeValue: ::libc::c_uint = 16; +pub static CXCompletionContext_DotMemberAccess: ::libc::c_uint = 32; +pub static CXCompletionContext_ArrowMemberAccess: ::libc::c_uint = 64; +pub static CXCompletionContext_ObjCPropertyAccess: ::libc::c_uint = 128; +pub static CXCompletionContext_EnumTag: ::libc::c_uint = 256; +pub static CXCompletionContext_UnionTag: ::libc::c_uint = 512; +pub static CXCompletionContext_StructTag: ::libc::c_uint = 1024; +pub static CXCompletionContext_ClassTag: ::libc::c_uint = 2048; +pub static CXCompletionContext_Namespace: ::libc::c_uint = 4096; +pub static CXCompletionContext_NestedNameSpecifier: ::libc::c_uint = 8192; +pub static CXCompletionContext_ObjCInterface: ::libc::c_uint = 16384; +pub static CXCompletionContext_ObjCProtocol: ::libc::c_uint = 32768; +pub static CXCompletionContext_ObjCCategory: ::libc::c_uint = 65536; +pub static CXCompletionContext_ObjCInstanceMessage: ::libc::c_uint = 131072; +pub static CXCompletionContext_ObjCClassMessage: ::libc::c_uint = 262144; +pub static CXCompletionContext_ObjCSelectorName: ::libc::c_uint = 524288; +pub static CXCompletionContext_MacroName: ::libc::c_uint = 1048576; +pub static CXCompletionContext_NaturalLanguage: ::libc::c_uint = 2097152; +pub static CXCompletionContext_Unknown: ::libc::c_uint = 4194303; +pub type CXInclusionVisitor = + ::std::option::Option; +pub type CXRemapping = *mut ::libc::c_void; +pub type Enum_CXVisitorResult = ::libc::c_uint; +pub static CXVisit_Break: ::libc::c_uint = 0; +pub static CXVisit_Continue: ::libc::c_uint = 1; +#[repr(C)] +pub struct CXCursorAndRangeVisitor { + pub context: *mut ::libc::c_void, + pub visit: ::std::option::Option Enum_CXVisitorResult>, +} +pub type CXResult = ::libc::c_uint; +pub static CXResult_Success: ::libc::c_uint = 0; +pub static CXResult_Invalid: ::libc::c_uint = 1; +pub static CXResult_VisitBreak: ::libc::c_uint = 2; +pub type CXIdxClientFile = *mut ::libc::c_void; +pub type CXIdxClientEntity = *mut ::libc::c_void; +pub type CXIdxClientContainer = *mut ::libc::c_void; +pub type CXIdxClientASTFile = *mut ::libc::c_void; +#[repr(C)] +pub struct CXIdxLoc { + pub ptr_data: [*mut ::libc::c_void, ..2u], + pub int_data: ::libc::c_uint, +} +#[repr(C)] +pub struct CXIdxIncludedFileInfo { + pub hashLoc: CXIdxLoc, + pub filename: *const ::libc::c_char, + pub file: CXFile, + pub isImport: ::libc::c_int, + pub isAngled: ::libc::c_int, + pub isModuleImport: ::libc::c_int, +} +#[repr(C)] +pub struct CXIdxImportedASTFileInfo { + pub file: CXFile, + pub module: CXModule, + pub loc: CXIdxLoc, + pub isImplicit: ::libc::c_int, +} +pub type CXIdxEntityKind = ::libc::c_uint; +pub static CXIdxEntity_Unexposed: ::libc::c_uint = 0; +pub static CXIdxEntity_Typedef: ::libc::c_uint = 1; +pub static CXIdxEntity_Function: ::libc::c_uint = 2; +pub static CXIdxEntity_Variable: ::libc::c_uint = 3; +pub static CXIdxEntity_Field: ::libc::c_uint = 4; +pub static CXIdxEntity_EnumConstant: ::libc::c_uint = 5; +pub static CXIdxEntity_ObjCClass: ::libc::c_uint = 6; +pub static CXIdxEntity_ObjCProtocol: ::libc::c_uint = 7; +pub static CXIdxEntity_ObjCCategory: ::libc::c_uint = 8; +pub static CXIdxEntity_ObjCInstanceMethod: ::libc::c_uint = 9; +pub static CXIdxEntity_ObjCClassMethod: ::libc::c_uint = 10; +pub static CXIdxEntity_ObjCProperty: ::libc::c_uint = 11; +pub static CXIdxEntity_ObjCIvar: ::libc::c_uint = 12; +pub static CXIdxEntity_Enum: ::libc::c_uint = 13; +pub static CXIdxEntity_Struct: ::libc::c_uint = 14; +pub static CXIdxEntity_Union: ::libc::c_uint = 15; +pub static CXIdxEntity_CXXClass: ::libc::c_uint = 16; +pub static CXIdxEntity_CXXNamespace: ::libc::c_uint = 17; +pub static CXIdxEntity_CXXNamespaceAlias: ::libc::c_uint = 18; +pub static CXIdxEntity_CXXStaticVariable: ::libc::c_uint = 19; +pub static CXIdxEntity_CXXStaticMethod: ::libc::c_uint = 20; +pub static CXIdxEntity_CXXInstanceMethod: ::libc::c_uint = 21; +pub static CXIdxEntity_CXXConstructor: ::libc::c_uint = 22; +pub static CXIdxEntity_CXXDestructor: ::libc::c_uint = 23; +pub static CXIdxEntity_CXXConversionFunction: ::libc::c_uint = 24; +pub static CXIdxEntity_CXXTypeAlias: ::libc::c_uint = 25; +pub static CXIdxEntity_CXXInterface: ::libc::c_uint = 26; +pub type CXIdxEntityLanguage = ::libc::c_uint; +pub static CXIdxEntityLang_None: ::libc::c_uint = 0; +pub static CXIdxEntityLang_C: ::libc::c_uint = 1; +pub static CXIdxEntityLang_ObjC: ::libc::c_uint = 2; +pub static CXIdxEntityLang_CXX: ::libc::c_uint = 3; +pub type CXIdxEntityCXXTemplateKind = ::libc::c_uint; +pub static CXIdxEntity_NonTemplate: ::libc::c_uint = 0; +pub static CXIdxEntity_Template: ::libc::c_uint = 1; +pub static CXIdxEntity_TemplatePartialSpecialization: ::libc::c_uint = 2; +pub static CXIdxEntity_TemplateSpecialization: ::libc::c_uint = 3; +pub type CXIdxAttrKind = ::libc::c_uint; +pub static CXIdxAttr_Unexposed: ::libc::c_uint = 0; +pub static CXIdxAttr_IBAction: ::libc::c_uint = 1; +pub static CXIdxAttr_IBOutlet: ::libc::c_uint = 2; +pub static CXIdxAttr_IBOutletCollection: ::libc::c_uint = 3; +#[repr(C)] +pub struct CXIdxAttrInfo { + pub kind: CXIdxAttrKind, + pub cursor: CXCursor, + pub loc: CXIdxLoc, +} +#[repr(C)] +pub struct CXIdxEntityInfo { + pub kind: CXIdxEntityKind, + pub templateKind: CXIdxEntityCXXTemplateKind, + pub lang: CXIdxEntityLanguage, + pub name: *const ::libc::c_char, + pub USR: *const ::libc::c_char, + pub cursor: CXCursor, + pub attributes: *const *const CXIdxAttrInfo, + pub numAttributes: ::libc::c_uint, +} +#[repr(C)] +pub struct CXIdxContainerInfo { + pub cursor: CXCursor, +} +#[repr(C)] +pub struct CXIdxIBOutletCollectionAttrInfo { + pub attrInfo: *const CXIdxAttrInfo, + pub objcClass: *const CXIdxEntityInfo, + pub classCursor: CXCursor, + pub classLoc: CXIdxLoc, +} +pub type CXIdxDeclInfoFlags = ::libc::c_uint; +pub static CXIdxDeclFlag_Skipped: ::libc::c_uint = 1; +#[repr(C)] +pub struct CXIdxDeclInfo { + pub entityInfo: *const CXIdxEntityInfo, + pub cursor: CXCursor, + pub loc: CXIdxLoc, + pub semanticContainer: *const CXIdxContainerInfo, + pub lexicalContainer: *const CXIdxContainerInfo, + pub isRedeclaration: ::libc::c_int, + pub isDefinition: ::libc::c_int, + pub isContainer: ::libc::c_int, + pub declAsContainer: *const CXIdxContainerInfo, + pub isImplicit: ::libc::c_int, + pub attributes: *const *const CXIdxAttrInfo, + pub numAttributes: ::libc::c_uint, + pub flags: ::libc::c_uint, +} +pub type CXIdxObjCContainerKind = ::libc::c_uint; +pub static CXIdxObjCContainer_ForwardRef: ::libc::c_uint = 0; +pub static CXIdxObjCContainer_Interface: ::libc::c_uint = 1; +pub static CXIdxObjCContainer_Implementation: ::libc::c_uint = 2; +#[repr(C)] +pub struct CXIdxObjCContainerDeclInfo { + pub declInfo: *const CXIdxDeclInfo, + pub kind: CXIdxObjCContainerKind, +} +#[repr(C)] +pub struct CXIdxBaseClassInfo { + pub base: *const CXIdxEntityInfo, + pub cursor: CXCursor, + pub loc: CXIdxLoc, +} +#[repr(C)] +pub struct CXIdxObjCProtocolRefInfo { + pub protocol: *const CXIdxEntityInfo, + pub cursor: CXCursor, + pub loc: CXIdxLoc, +} +#[repr(C)] +pub struct CXIdxObjCProtocolRefListInfo { + pub protocols: *const *const CXIdxObjCProtocolRefInfo, + pub numProtocols: ::libc::c_uint, +} +#[repr(C)] +pub struct CXIdxObjCInterfaceDeclInfo { + pub containerInfo: *const CXIdxObjCContainerDeclInfo, + pub superInfo: *const CXIdxBaseClassInfo, + pub protocols: *const CXIdxObjCProtocolRefListInfo, +} +#[repr(C)] +pub struct CXIdxObjCCategoryDeclInfo { + pub containerInfo: *const CXIdxObjCContainerDeclInfo, + pub objcClass: *const CXIdxEntityInfo, + pub classCursor: CXCursor, + pub classLoc: CXIdxLoc, + pub protocols: *const CXIdxObjCProtocolRefListInfo, +} +#[repr(C)] +pub struct CXIdxObjCPropertyDeclInfo { + pub declInfo: *const CXIdxDeclInfo, + pub getter: *const CXIdxEntityInfo, + pub setter: *const CXIdxEntityInfo, +} +#[repr(C)] +pub struct CXIdxCXXClassDeclInfo { + pub declInfo: *const CXIdxDeclInfo, + pub bases: *const *const CXIdxBaseClassInfo, + pub numBases: ::libc::c_uint, +} +pub type CXIdxEntityRefKind = ::libc::c_uint; +pub static CXIdxEntityRef_Direct: ::libc::c_uint = 1; +pub static CXIdxEntityRef_Implicit: ::libc::c_uint = 2; +#[repr(C)] +pub struct CXIdxEntityRefInfo { + pub kind: CXIdxEntityRefKind, + pub cursor: CXCursor, + pub loc: CXIdxLoc, + pub referencedEntity: *const CXIdxEntityInfo, + pub parentEntity: *const CXIdxEntityInfo, + pub container: *const CXIdxContainerInfo, +} +#[repr(C)] +pub struct IndexerCallbacks { + pub abortQuery: ::std::option::Option ::libc::c_int>, + pub diagnostic: ::std::option::Option, + pub enteredMainFile: ::std::option::Option CXIdxClientFile>, + pub ppIncludedFile: ::std::option::Option CXIdxClientFile>, + pub importedASTFile: ::std::option::Option CXIdxClientASTFile>, + pub startedTranslationUnit: ::std::option::Option + CXIdxClientContainer>, + pub indexDeclaration: ::std::option::Option, + pub indexEntityReference: ::std::option::Option, +} +pub type CXIndexAction = *mut ::libc::c_void; +pub type CXIndexOptFlags = ::libc::c_uint; +pub static CXIndexOpt_None: ::libc::c_uint = 0; +pub static CXIndexOpt_SuppressRedundantRefs: ::libc::c_uint = 1; +pub static CXIndexOpt_IndexFunctionLocalSymbols: ::libc::c_uint = 2; +pub static CXIndexOpt_IndexImplicitTemplateInstantiations: ::libc::c_uint = 4; +pub static CXIndexOpt_SuppressWarnings: ::libc::c_uint = 8; +pub static CXIndexOpt_SkipParsedBodiesInSession: ::libc::c_uint = 16; +#[link(name = "clang")] +extern "C" { + pub fn clang_getCString(string: CXString) -> *const ::libc::c_char; + pub fn clang_disposeString(string: CXString); + pub fn clang_createIndex(excludeDeclarationsFromPCH: ::libc::c_int, + displayDiagnostics: ::libc::c_int) -> CXIndex; + pub fn clang_disposeIndex(index: CXIndex); + pub fn clang_CXIndex_setGlobalOptions(arg1: CXIndex, + options: ::libc::c_uint); + pub fn clang_CXIndex_getGlobalOptions(arg1: CXIndex) -> ::libc::c_uint; + pub fn clang_getFileName(SFile: CXFile) -> CXString; + pub fn clang_getFileTime(SFile: CXFile) -> ::libc::time_t; + pub fn clang_getFileUniqueID(file: CXFile, outID: *mut CXFileUniqueID) -> + ::libc::c_int; + pub fn clang_isFileMultipleIncludeGuarded(tu: CXTranslationUnit, + file: CXFile) -> ::libc::c_uint; + pub fn clang_getFile(tu: CXTranslationUnit, + file_name: *const ::libc::c_char) -> CXFile; + pub fn clang_getNullLocation() -> CXSourceLocation; + pub fn clang_equalLocations(loc1: CXSourceLocation, + loc2: CXSourceLocation) -> ::libc::c_uint; + pub fn clang_getLocation(tu: CXTranslationUnit, file: CXFile, + line: ::libc::c_uint, column: ::libc::c_uint) -> + CXSourceLocation; + pub fn clang_getLocationForOffset(tu: CXTranslationUnit, file: CXFile, + offset: ::libc::c_uint) -> + CXSourceLocation; + pub fn clang_Location_isInSystemHeader(location: CXSourceLocation) -> + ::libc::c_int; + pub fn clang_Location_isFromMainFile(location: CXSourceLocation) -> + ::libc::c_int; + pub fn clang_getNullRange() -> CXSourceRange; + pub fn clang_getRange(begin: CXSourceLocation, end: CXSourceLocation) -> + CXSourceRange; + pub fn clang_equalRanges(range1: CXSourceRange, range2: CXSourceRange) -> + ::libc::c_uint; + pub fn clang_Range_isNull(range: CXSourceRange) -> ::libc::c_int; + pub fn clang_getExpansionLocation(location: CXSourceLocation, + file: *mut CXFile, + line: *mut ::libc::c_uint, + column: *mut ::libc::c_uint, + offset: *mut ::libc::c_uint); + pub fn clang_getPresumedLocation(location: CXSourceLocation, + filename: *mut CXString, + line: *mut ::libc::c_uint, + column: *mut ::libc::c_uint); + pub fn clang_getInstantiationLocation(location: CXSourceLocation, + file: *mut CXFile, + line: *mut ::libc::c_uint, + column: *mut ::libc::c_uint, + offset: *mut ::libc::c_uint); + pub fn clang_getSpellingLocation(location: CXSourceLocation, + file: *mut CXFile, + line: *mut ::libc::c_uint, + column: *mut ::libc::c_uint, + offset: *mut ::libc::c_uint); + pub fn clang_getFileLocation(location: CXSourceLocation, + file: *mut CXFile, line: *mut ::libc::c_uint, + column: *mut ::libc::c_uint, + offset: *mut ::libc::c_uint); + pub fn clang_getRangeStart(range: CXSourceRange) -> CXSourceLocation; + pub fn clang_getRangeEnd(range: CXSourceRange) -> CXSourceLocation; + pub fn clang_getNumDiagnosticsInSet(Diags: CXDiagnosticSet) -> + ::libc::c_uint; + pub fn clang_getDiagnosticInSet(Diags: CXDiagnosticSet, + Index: ::libc::c_uint) -> CXDiagnostic; + pub fn clang_loadDiagnostics(file: *const ::libc::c_char, + error: *mut Enum_CXLoadDiag_Error, + errorString: *mut CXString) -> + CXDiagnosticSet; + pub fn clang_disposeDiagnosticSet(Diags: CXDiagnosticSet); + pub fn clang_getChildDiagnostics(D: CXDiagnostic) -> CXDiagnosticSet; + pub fn clang_getNumDiagnostics(Unit: CXTranslationUnit) -> ::libc::c_uint; + pub fn clang_getDiagnostic(Unit: CXTranslationUnit, Index: ::libc::c_uint) + -> CXDiagnostic; + pub fn clang_getDiagnosticSetFromTU(Unit: CXTranslationUnit) -> + CXDiagnosticSet; + pub fn clang_disposeDiagnostic(Diagnostic: CXDiagnostic); + pub fn clang_formatDiagnostic(Diagnostic: CXDiagnostic, + Options: ::libc::c_uint) -> CXString; + pub fn clang_defaultDiagnosticDisplayOptions() -> ::libc::c_uint; + pub fn clang_getDiagnosticSeverity(arg1: CXDiagnostic) -> + Enum_CXDiagnosticSeverity; + pub fn clang_getDiagnosticLocation(arg1: CXDiagnostic) -> + CXSourceLocation; + pub fn clang_getDiagnosticSpelling(arg1: CXDiagnostic) -> CXString; + pub fn clang_getDiagnosticOption(Diag: CXDiagnostic, + Disable: *mut CXString) -> CXString; + pub fn clang_getDiagnosticCategory(arg1: CXDiagnostic) -> ::libc::c_uint; + pub fn clang_getDiagnosticCategoryName(Category: ::libc::c_uint) -> + CXString; + pub fn clang_getDiagnosticCategoryText(arg1: CXDiagnostic) -> CXString; + pub fn clang_getDiagnosticNumRanges(arg1: CXDiagnostic) -> ::libc::c_uint; + pub fn clang_getDiagnosticRange(Diagnostic: CXDiagnostic, + Range: ::libc::c_uint) -> CXSourceRange; + pub fn clang_getDiagnosticNumFixIts(Diagnostic: CXDiagnostic) -> + ::libc::c_uint; + pub fn clang_getDiagnosticFixIt(Diagnostic: CXDiagnostic, + FixIt: ::libc::c_uint, + ReplacementRange: *mut CXSourceRange) -> + CXString; + pub fn clang_getTranslationUnitSpelling(CTUnit: CXTranslationUnit) -> + CXString; + pub fn clang_createTranslationUnitFromSourceFile(CIdx: CXIndex, + source_filename: + *const ::libc::c_char, + num_clang_command_line_args: + ::libc::c_int, + clang_command_line_args: + *const *const ::libc::c_char, + num_unsaved_files: + ::libc::c_uint, + unsaved_files: + *mut Struct_CXUnsavedFile) + -> CXTranslationUnit; + pub fn clang_createTranslationUnit(arg1: CXIndex, + ast_filename: *const ::libc::c_char) -> + CXTranslationUnit; + pub fn clang_defaultEditingTranslationUnitOptions() -> ::libc::c_uint; + pub fn clang_parseTranslationUnit(CIdx: CXIndex, + source_filename: *const ::libc::c_char, + command_line_args: + *const *const ::libc::c_char, + num_command_line_args: ::libc::c_int, + unsaved_files: + *mut Struct_CXUnsavedFile, + num_unsaved_files: ::libc::c_uint, + options: ::libc::c_uint) -> + CXTranslationUnit; + pub fn clang_defaultSaveOptions(TU: CXTranslationUnit) -> ::libc::c_uint; + pub fn clang_saveTranslationUnit(TU: CXTranslationUnit, + FileName: *const ::libc::c_char, + options: ::libc::c_uint) -> + ::libc::c_int; + pub fn clang_disposeTranslationUnit(arg1: CXTranslationUnit); + pub fn clang_defaultReparseOptions(TU: CXTranslationUnit) -> + ::libc::c_uint; + pub fn clang_reparseTranslationUnit(TU: CXTranslationUnit, + num_unsaved_files: ::libc::c_uint, + unsaved_files: + *mut Struct_CXUnsavedFile, + options: ::libc::c_uint) -> + ::libc::c_int; + pub fn clang_getTUResourceUsageName(kind: Enum_CXTUResourceUsageKind) -> + *const ::libc::c_char; + pub fn clang_getCXTUResourceUsage(TU: CXTranslationUnit) -> + CXTUResourceUsage; + pub fn clang_disposeCXTUResourceUsage(usage: CXTUResourceUsage); + pub fn clang_getNullCursor() -> CXCursor; + pub fn clang_getTranslationUnitCursor(arg1: CXTranslationUnit) -> + CXCursor; + pub fn clang_equalCursors(arg1: CXCursor, arg2: CXCursor) -> + ::libc::c_uint; + pub fn clang_Cursor_isNull(cursor: CXCursor) -> ::libc::c_int; + pub fn clang_hashCursor(arg1: CXCursor) -> ::libc::c_uint; + pub fn clang_getCursorKind(arg1: CXCursor) -> Enum_CXCursorKind; + pub fn clang_isDeclaration(arg1: Enum_CXCursorKind) -> ::libc::c_uint; + pub fn clang_isReference(arg1: Enum_CXCursorKind) -> ::libc::c_uint; + pub fn clang_isExpression(arg1: Enum_CXCursorKind) -> ::libc::c_uint; + pub fn clang_isStatement(arg1: Enum_CXCursorKind) -> ::libc::c_uint; + pub fn clang_isAttribute(arg1: Enum_CXCursorKind) -> ::libc::c_uint; + pub fn clang_isInvalid(arg1: Enum_CXCursorKind) -> ::libc::c_uint; + pub fn clang_isTranslationUnit(arg1: Enum_CXCursorKind) -> ::libc::c_uint; + pub fn clang_isPreprocessing(arg1: Enum_CXCursorKind) -> ::libc::c_uint; + pub fn clang_isUnexposed(arg1: Enum_CXCursorKind) -> ::libc::c_uint; + pub fn clang_getCursorLinkage(cursor: CXCursor) -> Enum_CXLinkageKind; + pub fn clang_getCursorAvailability(cursor: CXCursor) -> + Enum_CXAvailabilityKind; + pub fn clang_getCursorPlatformAvailability(cursor: CXCursor, + always_deprecated: + *mut ::libc::c_int, + deprecated_message: + *mut CXString, + always_unavailable: + *mut ::libc::c_int, + unavailable_message: + *mut CXString, + availability: + *mut CXPlatformAvailability, + availability_size: + ::libc::c_int) -> + ::libc::c_int; + pub fn clang_disposeCXPlatformAvailability(availability: + *mut CXPlatformAvailability); + pub fn clang_getCursorLanguage(cursor: CXCursor) -> Enum_CXLanguageKind; + pub fn clang_Cursor_getTranslationUnit(arg1: CXCursor) -> + CXTranslationUnit; + pub fn clang_createCXCursorSet() -> CXCursorSet; + pub fn clang_disposeCXCursorSet(cset: CXCursorSet); + pub fn clang_CXCursorSet_contains(cset: CXCursorSet, cursor: CXCursor) -> + ::libc::c_uint; + pub fn clang_CXCursorSet_insert(cset: CXCursorSet, cursor: CXCursor) -> + ::libc::c_uint; + pub fn clang_getCursorSemanticParent(cursor: CXCursor) -> CXCursor; + pub fn clang_getCursorLexicalParent(cursor: CXCursor) -> CXCursor; + pub fn clang_getOverriddenCursors(cursor: CXCursor, + overridden: *mut *mut CXCursor, + num_overridden: *mut ::libc::c_uint); + pub fn clang_disposeOverriddenCursors(overridden: *mut CXCursor); + pub fn clang_getIncludedFile(cursor: CXCursor) -> CXFile; + pub fn clang_getCursor(arg1: CXTranslationUnit, arg2: CXSourceLocation) -> + CXCursor; + pub fn clang_getCursorLocation(arg1: CXCursor) -> CXSourceLocation; + pub fn clang_getCursorExtent(arg1: CXCursor) -> CXSourceRange; + pub fn clang_getCursorType(C: CXCursor) -> CXType; + pub fn clang_getTypeSpelling(CT: CXType) -> CXString; + pub fn clang_getTypedefDeclUnderlyingType(C: CXCursor) -> CXType; + pub fn clang_getEnumDeclIntegerType(C: CXCursor) -> CXType; + pub fn clang_getEnumConstantDeclValue(C: CXCursor) -> ::libc::c_longlong; + pub fn clang_getEnumConstantDeclUnsignedValue(C: CXCursor) -> + ::libc::c_ulonglong; + pub fn clang_getFieldDeclBitWidth(C: CXCursor) -> ::libc::c_int; + pub fn clang_Cursor_getNumArguments(C: CXCursor) -> ::libc::c_int; + pub fn clang_Cursor_getArgument(C: CXCursor, i: ::libc::c_uint) -> + CXCursor; + pub fn clang_equalTypes(A: CXType, B: CXType) -> ::libc::c_uint; + pub fn clang_getCanonicalType(T: CXType) -> CXType; + pub fn clang_isConstQualifiedType(T: CXType) -> ::libc::c_uint; + pub fn clang_isVolatileQualifiedType(T: CXType) -> ::libc::c_uint; + pub fn clang_isRestrictQualifiedType(T: CXType) -> ::libc::c_uint; + pub fn clang_getPointeeType(T: CXType) -> CXType; + pub fn clang_getTypeDeclaration(T: CXType) -> CXCursor; + pub fn clang_getDeclObjCTypeEncoding(C: CXCursor) -> CXString; + pub fn clang_getTypeKindSpelling(K: Enum_CXTypeKind) -> CXString; + pub fn clang_getFunctionTypeCallingConv(T: CXType) -> Enum_CXCallingConv; + pub fn clang_getResultType(T: CXType) -> CXType; + pub fn clang_getNumArgTypes(T: CXType) -> ::libc::c_int; + pub fn clang_getArgType(T: CXType, i: ::libc::c_uint) -> CXType; + pub fn clang_isFunctionTypeVariadic(T: CXType) -> ::libc::c_uint; + pub fn clang_getCursorResultType(C: CXCursor) -> CXType; + pub fn clang_isPODType(T: CXType) -> ::libc::c_uint; + pub fn clang_getElementType(T: CXType) -> CXType; + pub fn clang_getNumElements(T: CXType) -> ::libc::c_longlong; + pub fn clang_getArrayElementType(T: CXType) -> CXType; + pub fn clang_getArraySize(T: CXType) -> ::libc::c_longlong; + pub fn clang_Type_getAlignOf(T: CXType) -> ::libc::c_longlong; + pub fn clang_Type_getClassType(T: CXType) -> CXType; + pub fn clang_Type_getSizeOf(T: CXType) -> ::libc::c_longlong; + pub fn clang_Type_getOffsetOf(T: CXType, S: *const ::libc::c_char) -> + ::libc::c_longlong; + pub fn clang_Type_getCXXRefQualifier(T: CXType) -> + Enum_CXRefQualifierKind; + pub fn clang_Cursor_isBitField(C: CXCursor) -> ::libc::c_uint; + pub fn clang_isVirtualBase(arg1: CXCursor) -> ::libc::c_uint; + pub fn clang_getCXXAccessSpecifier(arg1: CXCursor) -> + Enum_CX_CXXAccessSpecifier; + pub fn clang_getNumOverloadedDecls(cursor: CXCursor) -> ::libc::c_uint; + pub fn clang_getOverloadedDecl(cursor: CXCursor, index: ::libc::c_uint) -> + CXCursor; + pub fn clang_getIBOutletCollectionType(arg1: CXCursor) -> CXType; + pub fn clang_visitChildren(parent: CXCursor, visitor: CXCursorVisitor, + client_data: CXClientData) -> ::libc::c_uint; + pub fn clang_getCursorUSR(arg1: CXCursor) -> CXString; + pub fn clang_constructUSR_ObjCClass(class_name: *const ::libc::c_char) -> + CXString; + pub fn clang_constructUSR_ObjCCategory(class_name: *const ::libc::c_char, + category_name: + *const ::libc::c_char) -> + CXString; + pub fn clang_constructUSR_ObjCProtocol(protocol_name: + *const ::libc::c_char) -> + CXString; + pub fn clang_constructUSR_ObjCIvar(name: *const ::libc::c_char, + classUSR: CXString) -> CXString; + pub fn clang_constructUSR_ObjCMethod(name: *const ::libc::c_char, + isInstanceMethod: ::libc::c_uint, + classUSR: CXString) -> CXString; + pub fn clang_constructUSR_ObjCProperty(property: *const ::libc::c_char, + classUSR: CXString) -> CXString; + pub fn clang_getCursorSpelling(arg1: CXCursor) -> CXString; + pub fn clang_Cursor_getSpellingNameRange(arg1: CXCursor, + pieceIndex: ::libc::c_uint, + options: ::libc::c_uint) -> + CXSourceRange; + pub fn clang_getCursorDisplayName(arg1: CXCursor) -> CXString; + pub fn clang_getCursorReferenced(arg1: CXCursor) -> CXCursor; + pub fn clang_getCursorDefinition(arg1: CXCursor) -> CXCursor; + pub fn clang_isCursorDefinition(arg1: CXCursor) -> ::libc::c_uint; + pub fn clang_getCanonicalCursor(arg1: CXCursor) -> CXCursor; + pub fn clang_Cursor_getObjCSelectorIndex(arg1: CXCursor) -> ::libc::c_int; + pub fn clang_Cursor_isDynamicCall(C: CXCursor) -> ::libc::c_int; + pub fn clang_Cursor_getReceiverType(C: CXCursor) -> CXType; + pub fn clang_Cursor_getObjCPropertyAttributes(C: CXCursor, + reserved: ::libc::c_uint) -> + ::libc::c_uint; + pub fn clang_Cursor_getObjCDeclQualifiers(C: CXCursor) -> ::libc::c_uint; + pub fn clang_Cursor_isObjCOptional(C: CXCursor) -> ::libc::c_uint; + pub fn clang_Cursor_isVariadic(C: CXCursor) -> ::libc::c_uint; + pub fn clang_Cursor_getCommentRange(C: CXCursor) -> CXSourceRange; + pub fn clang_Cursor_getRawCommentText(C: CXCursor) -> CXString; + pub fn clang_Cursor_getBriefCommentText(C: CXCursor) -> CXString; + pub fn clang_Cursor_getParsedComment(C: CXCursor) -> CXComment; + pub fn clang_Cursor_getModule(C: CXCursor) -> CXModule; + pub fn clang_Module_getASTFile(Module: CXModule) -> CXFile; + pub fn clang_Module_getParent(Module: CXModule) -> CXModule; + pub fn clang_Module_getName(Module: CXModule) -> CXString; + pub fn clang_Module_getFullName(Module: CXModule) -> CXString; + pub fn clang_Module_getNumTopLevelHeaders(arg1: CXTranslationUnit, + Module: CXModule) -> + ::libc::c_uint; + pub fn clang_Module_getTopLevelHeader(arg1: CXTranslationUnit, + Module: CXModule, + Index: ::libc::c_uint) -> CXFile; + pub fn clang_Comment_getKind(Comment: CXComment) -> Enum_CXCommentKind; + pub fn clang_Comment_getNumChildren(Comment: CXComment) -> ::libc::c_uint; + pub fn clang_Comment_getChild(Comment: CXComment, + ChildIdx: ::libc::c_uint) -> CXComment; + pub fn clang_Comment_isWhitespace(Comment: CXComment) -> ::libc::c_uint; + pub fn clang_InlineContentComment_hasTrailingNewline(Comment: CXComment) + -> ::libc::c_uint; + pub fn clang_TextComment_getText(Comment: CXComment) -> CXString; + pub fn clang_InlineCommandComment_getCommandName(Comment: CXComment) -> + CXString; + pub fn clang_InlineCommandComment_getRenderKind(Comment: CXComment) -> + Enum_CXCommentInlineCommandRenderKind; + pub fn clang_InlineCommandComment_getNumArgs(Comment: CXComment) -> + ::libc::c_uint; + pub fn clang_InlineCommandComment_getArgText(Comment: CXComment, + ArgIdx: ::libc::c_uint) -> + CXString; + pub fn clang_HTMLTagComment_getTagName(Comment: CXComment) -> CXString; + pub fn clang_HTMLStartTagComment_isSelfClosing(Comment: CXComment) -> + ::libc::c_uint; + pub fn clang_HTMLStartTag_getNumAttrs(Comment: CXComment) -> + ::libc::c_uint; + pub fn clang_HTMLStartTag_getAttrName(Comment: CXComment, + AttrIdx: ::libc::c_uint) -> + CXString; + pub fn clang_HTMLStartTag_getAttrValue(Comment: CXComment, + AttrIdx: ::libc::c_uint) -> + CXString; + pub fn clang_BlockCommandComment_getCommandName(Comment: CXComment) -> + CXString; + pub fn clang_BlockCommandComment_getNumArgs(Comment: CXComment) -> + ::libc::c_uint; + pub fn clang_BlockCommandComment_getArgText(Comment: CXComment, + ArgIdx: ::libc::c_uint) -> + CXString; + pub fn clang_BlockCommandComment_getParagraph(Comment: CXComment) -> + CXComment; + pub fn clang_ParamCommandComment_getParamName(Comment: CXComment) -> + CXString; + pub fn clang_ParamCommandComment_isParamIndexValid(Comment: CXComment) -> + ::libc::c_uint; + pub fn clang_ParamCommandComment_getParamIndex(Comment: CXComment) -> + ::libc::c_uint; + pub fn clang_ParamCommandComment_isDirectionExplicit(Comment: CXComment) + -> ::libc::c_uint; + pub fn clang_ParamCommandComment_getDirection(Comment: CXComment) -> + Enum_CXCommentParamPassDirection; + pub fn clang_TParamCommandComment_getParamName(Comment: CXComment) -> + CXString; + pub fn clang_TParamCommandComment_isParamPositionValid(Comment: CXComment) + -> ::libc::c_uint; + pub fn clang_TParamCommandComment_getDepth(Comment: CXComment) -> + ::libc::c_uint; + pub fn clang_TParamCommandComment_getIndex(Comment: CXComment, + Depth: ::libc::c_uint) -> + ::libc::c_uint; + pub fn clang_VerbatimBlockLineComment_getText(Comment: CXComment) -> + CXString; + pub fn clang_VerbatimLineComment_getText(Comment: CXComment) -> CXString; + pub fn clang_HTMLTagComment_getAsString(Comment: CXComment) -> CXString; + pub fn clang_FullComment_getAsHTML(Comment: CXComment) -> CXString; + pub fn clang_FullComment_getAsXML(Comment: CXComment) -> CXString; + pub fn clang_CXXMethod_isPureVirtual(C: CXCursor) -> ::libc::c_uint; + pub fn clang_CXXMethod_isStatic(C: CXCursor) -> ::libc::c_uint; + pub fn clang_CXXMethod_isVirtual(C: CXCursor) -> ::libc::c_uint; + pub fn clang_getTemplateCursorKind(C: CXCursor) -> Enum_CXCursorKind; + pub fn clang_getSpecializedCursorTemplate(C: CXCursor) -> CXCursor; + pub fn clang_getCursorReferenceNameRange(C: CXCursor, + NameFlags: ::libc::c_uint, + PieceIndex: ::libc::c_uint) -> + CXSourceRange; + pub fn clang_getTokenKind(arg1: CXToken) -> CXTokenKind; + pub fn clang_getTokenSpelling(arg1: CXTranslationUnit, arg2: CXToken) -> + CXString; + pub fn clang_getTokenLocation(arg1: CXTranslationUnit, arg2: CXToken) -> + CXSourceLocation; + pub fn clang_getTokenExtent(arg1: CXTranslationUnit, arg2: CXToken) -> + CXSourceRange; + pub fn clang_tokenize(TU: CXTranslationUnit, Range: CXSourceRange, + Tokens: *mut *mut CXToken, + NumTokens: *mut ::libc::c_uint); + pub fn clang_annotateTokens(TU: CXTranslationUnit, Tokens: *mut CXToken, + NumTokens: ::libc::c_uint, + Cursors: *mut CXCursor); + pub fn clang_disposeTokens(TU: CXTranslationUnit, Tokens: *mut CXToken, + NumTokens: ::libc::c_uint); + pub fn clang_getCursorKindSpelling(Kind: Enum_CXCursorKind) -> CXString; + pub fn clang_getDefinitionSpellingAndExtent(arg1: CXCursor, + startBuf: + *mut *const ::libc::c_char, + endBuf: + *mut *const ::libc::c_char, + startLine: + *mut ::libc::c_uint, + startColumn: + *mut ::libc::c_uint, + endLine: *mut ::libc::c_uint, + endColumn: + *mut ::libc::c_uint); + pub fn clang_enableStackTraces(); + pub fn clang_executeOnThread(_fn: + ::std::option::Option, + user_data: *mut ::libc::c_void, + stack_size: ::libc::c_uint); + pub fn clang_getCompletionChunkKind(completion_string: CXCompletionString, + chunk_number: ::libc::c_uint) -> + Enum_CXCompletionChunkKind; + pub fn clang_getCompletionChunkText(completion_string: CXCompletionString, + chunk_number: ::libc::c_uint) -> + CXString; + pub fn clang_getCompletionChunkCompletionString(completion_string: + CXCompletionString, + chunk_number: + ::libc::c_uint) -> + CXCompletionString; + pub fn clang_getNumCompletionChunks(completion_string: CXCompletionString) + -> ::libc::c_uint; + pub fn clang_getCompletionPriority(completion_string: CXCompletionString) + -> ::libc::c_uint; + pub fn clang_getCompletionAvailability(completion_string: + CXCompletionString) -> + Enum_CXAvailabilityKind; + pub fn clang_getCompletionNumAnnotations(completion_string: + CXCompletionString) -> + ::libc::c_uint; + pub fn clang_getCompletionAnnotation(completion_string: + CXCompletionString, + annotation_number: ::libc::c_uint) -> + CXString; + pub fn clang_getCompletionParent(completion_string: CXCompletionString, + kind: *mut Enum_CXCursorKind) -> + CXString; + pub fn clang_getCompletionBriefComment(completion_string: + CXCompletionString) -> + CXString; + pub fn clang_getCursorCompletionString(cursor: CXCursor) -> + CXCompletionString; + pub fn clang_defaultCodeCompleteOptions() -> ::libc::c_uint; + pub fn clang_codeCompleteAt(TU: CXTranslationUnit, + complete_filename: *const ::libc::c_char, + complete_line: ::libc::c_uint, + complete_column: ::libc::c_uint, + unsaved_files: *mut Struct_CXUnsavedFile, + num_unsaved_files: ::libc::c_uint, + options: ::libc::c_uint) -> + *mut CXCodeCompleteResults; + pub fn clang_sortCodeCompletionResults(Results: *mut CXCompletionResult, + NumResults: ::libc::c_uint); + pub fn clang_disposeCodeCompleteResults(Results: + *mut CXCodeCompleteResults); + pub fn clang_codeCompleteGetNumDiagnostics(Results: + *mut CXCodeCompleteResults) + -> ::libc::c_uint; + pub fn clang_codeCompleteGetDiagnostic(Results: + *mut CXCodeCompleteResults, + Index: ::libc::c_uint) -> + CXDiagnostic; + pub fn clang_codeCompleteGetContexts(Results: *mut CXCodeCompleteResults) + -> ::libc::c_ulonglong; + pub fn clang_codeCompleteGetContainerKind(Results: + *mut CXCodeCompleteResults, + IsIncomplete: + *mut ::libc::c_uint) -> + Enum_CXCursorKind; + pub fn clang_codeCompleteGetContainerUSR(Results: + *mut CXCodeCompleteResults) + -> CXString; + pub fn clang_codeCompleteGetObjCSelector(Results: + *mut CXCodeCompleteResults) + -> CXString; + pub fn clang_getClangVersion() -> CXString; + pub fn clang_toggleCrashRecovery(isEnabled: ::libc::c_uint); + pub fn clang_getInclusions(tu: CXTranslationUnit, + visitor: CXInclusionVisitor, + client_data: CXClientData); + pub fn clang_getRemappings(path: *const ::libc::c_char) -> CXRemapping; + pub fn clang_getRemappingsFromFileList(filePaths: + *mut *const ::libc::c_char, + numFiles: ::libc::c_uint) -> + CXRemapping; + pub fn clang_remap_getNumFiles(arg1: CXRemapping) -> ::libc::c_uint; + pub fn clang_remap_getFilenames(arg1: CXRemapping, index: ::libc::c_uint, + original: *mut CXString, + transformed: *mut CXString); + pub fn clang_remap_dispose(arg1: CXRemapping); + pub fn clang_findReferencesInFile(cursor: CXCursor, file: CXFile, + visitor: CXCursorAndRangeVisitor) -> + CXResult; + pub fn clang_findIncludesInFile(TU: CXTranslationUnit, file: CXFile, + visitor: CXCursorAndRangeVisitor) -> + CXResult; + pub fn clang_index_isEntityObjCContainerKind(arg1: CXIdxEntityKind) -> + ::libc::c_int; + pub fn clang_index_getObjCContainerDeclInfo(arg1: *const CXIdxDeclInfo) -> + *const CXIdxObjCContainerDeclInfo; + pub fn clang_index_getObjCInterfaceDeclInfo(arg1: *const CXIdxDeclInfo) -> + *const CXIdxObjCInterfaceDeclInfo; + pub fn clang_index_getObjCCategoryDeclInfo(arg1: *const CXIdxDeclInfo) -> + *const CXIdxObjCCategoryDeclInfo; + pub fn clang_index_getObjCProtocolRefListInfo(arg1: *const CXIdxDeclInfo) + -> *const CXIdxObjCProtocolRefListInfo; + pub fn clang_index_getObjCPropertyDeclInfo(arg1: *const CXIdxDeclInfo) -> + *const CXIdxObjCPropertyDeclInfo; + pub fn clang_index_getIBOutletCollectionAttrInfo(arg1: + *const CXIdxAttrInfo) + -> *const CXIdxIBOutletCollectionAttrInfo; + pub fn clang_index_getCXXClassDeclInfo(arg1: *const CXIdxDeclInfo) -> + *const CXIdxCXXClassDeclInfo; + pub fn clang_index_getClientContainer(arg1: *const CXIdxContainerInfo) -> + CXIdxClientContainer; + pub fn clang_index_setClientContainer(arg1: *const CXIdxContainerInfo, + arg2: CXIdxClientContainer); + pub fn clang_index_getClientEntity(arg1: *const CXIdxEntityInfo) -> + CXIdxClientEntity; + pub fn clang_index_setClientEntity(arg1: *const CXIdxEntityInfo, + arg2: CXIdxClientEntity); + pub fn clang_IndexAction_create(CIdx: CXIndex) -> CXIndexAction; + pub fn clang_IndexAction_dispose(arg1: CXIndexAction); + pub fn clang_indexSourceFile(arg1: CXIndexAction, + client_data: CXClientData, + index_callbacks: *mut IndexerCallbacks, + index_callbacks_size: ::libc::c_uint, + index_options: ::libc::c_uint, + source_filename: *const ::libc::c_char, + command_line_args: + *const *const ::libc::c_char, + num_command_line_args: ::libc::c_int, + unsaved_files: *mut Struct_CXUnsavedFile, + num_unsaved_files: ::libc::c_uint, + out_TU: *mut CXTranslationUnit, + TU_options: ::libc::c_uint) -> ::libc::c_int; + pub fn clang_indexTranslationUnit(arg1: CXIndexAction, + client_data: CXClientData, + index_callbacks: *mut IndexerCallbacks, + index_callbacks_size: ::libc::c_uint, + index_options: ::libc::c_uint, + arg2: CXTranslationUnit) -> + ::libc::c_int; + pub fn clang_indexLoc_getFileLocation(loc: CXIdxLoc, + indexFile: *mut CXIdxClientFile, + file: *mut CXFile, + line: *mut ::libc::c_uint, + column: *mut ::libc::c_uint, + offset: *mut ::libc::c_uint); + pub fn clang_indexLoc_getCXSourceLocation(loc: CXIdxLoc) -> + CXSourceLocation; +} diff --git a/src/gen.rs b/src/gen.rs new file mode 100644 index 00000000..87b37b47 --- /dev/null +++ b/src/gen.rs @@ -0,0 +1,920 @@ +#![allow(unused_must_use)] + +use std::cell::RefCell; +use std::option; +use std::iter; +use std::vec::Vec; +use std::gc::{Gc, GC}; + +use syntax::abi; +use syntax::ast; +use syntax::codemap::{Span, respan, ExpnInfo, NameAndSpan, MacroBang}; +use syntax::ext::base; +use syntax::ext::build::AstBuilder; +use syntax::ext::expand::ExpansionConfig; +use syntax::owned_slice::OwnedSlice; +use syntax::parse; +use syntax::attr::mk_attr_id; + +use types::*; + +struct GenCtx<'r> { + ext_cx: base::ExtCtxt<'r>, + unnamed_ty: uint, + abi: abi::Abi, + span: Span +} + +fn first((val, _): (A, B)) -> A { + return val; +} + +fn ref_eq<'a, 'b, T>(thing: &'a T, other: &'b T) -> bool { + (thing as *const T) == (other as *const T) +} + +fn to_intern_str(ctx: &mut GenCtx, s: String) -> parse::token::InternedString { + let id = ctx.ext_cx.ident_of(s.as_slice()); + parse::token::get_ident(id) +} + +fn empty_generics() -> ast::Generics { + ast::Generics { + lifetimes: Vec::new(), + ty_params: OwnedSlice::empty(), + } +} + +fn rust_id(ctx: &mut GenCtx, name: String) -> (String, bool) { + let token = parse::token::IDENT(ctx.ext_cx.ident_of(name.as_slice()), false); + if parse::token::is_any_keyword(&token) || "bool" == name.as_slice() { + ("_".to_string().append(name.as_slice()), true) + } else { + (name, false) + } + +} + +fn rust_type_id(ctx: &mut GenCtx, name: String) -> String { + if "bool" == name.as_slice() || + "uint" == name.as_slice() || + "u8" == name.as_slice() || + "u16" == name.as_slice() || + "u32" == name.as_slice() || + "f32" == name.as_slice() || + "f64" == name.as_slice() || + "i8" == name.as_slice() || + "i16" == name.as_slice() || + "i32" == name.as_slice() || + "i64" == name.as_slice() || + "Self" == name.as_slice() || + "str" == name.as_slice() { + "_".to_string().append(name.as_slice()) + } else { + let (n, _) = rust_id(ctx, name); + n + } +} + +fn unnamed_name(ctx: &mut GenCtx, name: String) -> String { + return if name.is_empty() { + ctx.unnamed_ty += 1; + format!("Unnamed{}", ctx.unnamed_ty) + } else { + name + }; +} + +fn struct_name(name: String) -> String { + format!("Struct_{}", name) +} + +fn union_name(name: String) -> String { + format!("Union_{}", name) +} + +fn enum_name(name: String) -> String { + format!("Enum_{}", name) +} + +pub fn gen_mod(abi: &str, links: &[(String, Option)], globs: Vec, span: Span) -> Vec> { + let abi = match abi { + "cdecl" => abi::Cdecl, + "stdcall" => abi::Stdcall, + "fastcall" => abi::Fastcall, + "aapcs" => abi::Aapcs, + "Rust" => abi::Rust, + "rust-intrinsic" => abi::RustIntrinsic, + _ => abi::C + }; + + // Create a dummy ExtCtxt. We only need this for string interning and that uses TLS. + let cfg = ExpansionConfig { + deriving_hash_type_parameter: false, + crate_id: from_str("xxx").unwrap(), + }; + let sess = &parse::new_parse_sess(); + let mut ctx = GenCtx { + ext_cx: base::ExtCtxt::new( + sess, + Vec::new(), + cfg, + ), + unnamed_ty: 0, + abi: abi, + span: span + }; + ctx.ext_cx.bt_push(ExpnInfo { + call_site: ctx.span, + callee: NameAndSpan { name: String::new(), format: MacroBang, span: None } + }); + let uniq_globs = tag_dup_decl(globs); + + let mut fs = vec!(); + let mut vs = vec!(); + let mut gs = vec!(); + for g in uniq_globs.move_iter() { + match g { + GOther => {} + GFunc(_) => fs.push(g), + GVar(_) => vs.push(g), + _ => gs.push(g) + } + } + + let mut defs = vec!(); + gs = remove_redundant_decl(gs); + + for g in gs.move_iter() { + match g { + GType(ti) => { + let t = ti.borrow().clone(); + defs.push_all_move(ctypedef_to_rs(&mut ctx, t.name.clone(), &t.ty)) + }, + GCompDecl(ci) => { + { + let mut c = ci.borrow_mut(); + c.name = unnamed_name(&mut ctx, c.name.clone()); + } + let c = ci.borrow().clone(); + if c.cstruct { + defs.push(opaque_to_rs(&mut ctx, struct_name(c.name))); + } else { + defs.push(opaque_to_rs(&mut ctx, union_name(c.name))); + } + }, + GComp(ci) => { + { + let mut c = ci.borrow_mut(); + c.name = unnamed_name(&mut ctx, c.name.clone()); + } + let c = ci.borrow().clone(); + if c.cstruct { + defs.push(cstruct_to_rs(&mut ctx, struct_name(c.name.clone()), + // this clone is necessary to prevent dynamic borrow + // check errors. + // FIXME: remove the @mut in types.rs to fix this + c.fields.clone())) + } else { + defs.push_all_move(cunion_to_rs(&mut ctx, union_name(c.name.clone()), + c.layout, c.fields)) + } + }, + GEnumDecl(ei) => { + { + let mut e = ei.borrow_mut(); + e.name = unnamed_name(&mut ctx, e.name.clone()); + } + let e = ei.borrow().clone(); + defs.push(opaque_to_rs(&mut ctx, enum_name(e.name))); + }, + GEnum(ei) => { + { + let mut e = ei.borrow_mut(); + e.name = unnamed_name(&mut ctx, e.name.clone()); + } + let e = ei.borrow().clone(); + defs.push_all_move(cenum_to_rs(&mut ctx, enum_name(e.name.clone()), e.kind, e.items)) + }, + _ => { } + } + } + + let vars = vs.move_iter().map(|v| { + match v { + GVar(vi) => { + let v = vi.borrow(); + cvar_to_rs(&mut ctx, v.name.clone(), &v.ty, v.is_const) + }, + _ => unreachable!() + } + }).collect(); + + let funcs = fs.move_iter().map(|f| { + match f { + GFunc(vi) => { + let v = vi.borrow(); + match v.ty { + TFunc(ref rty, ref aty, var) => + cfunc_to_rs(&mut ctx, v.name.clone(), + *rty, aty.as_slice(), var), + _ => unreachable!() + } + }, + _ => unreachable!() + } + }).collect(); + + defs.push(mk_extern(&mut ctx, links, vars, funcs)); + + //let attrs = vec!(mk_attr_list(&mut ctx, "allow", ["dead_code", "non_camel_case_types", "uppercase_variables"])); + + defs +} + +fn mk_extern(ctx: &mut GenCtx, links: &[(String, Option)], + vars: Vec>, + funcs: Vec>) -> Gc { + let attrs = if links.is_empty() { + Vec::new() + } else { + links.iter().map(|&(ref l, ref k)| { + let link_name = box(GC) respan(ctx.span, ast::MetaNameValue( + to_intern_str(ctx, "name".to_string()), + respan(ctx.span, ast::LitStr( + to_intern_str(ctx, l.to_string()), + ast::CookedStr + )) + )); + let link_args = match k { + &None => vec!(link_name), + &Some(ref k) => vec!(link_name, box(GC) respan(ctx.span, ast::MetaNameValue( + to_intern_str(ctx, "kind".to_string()), + respan(ctx.span, ast::LitStr( + to_intern_str(ctx, k.to_string()), + ast::CookedStr + )) + ))) + }; + respan(ctx.span, ast::Attribute_ { + id: mk_attr_id(), + style: ast::AttrOuter, + value: box(GC) respan(ctx.span, ast::MetaList( + to_intern_str(ctx, "link".to_string()), + link_args) + ), + is_sugared_doc: false + }) + }).collect() + }; + + let mut items = Vec::new(); + items.push_all_move(vars); + items.push_all_move(funcs); + let ext = ast::ItemForeignMod(ast::ForeignMod { + abi: ctx.abi, + view_items: Vec::new(), + items: items + }); + + return box(GC) ast::Item { + ident: ctx.ext_cx.ident_of(""), + attrs: attrs, + id: ast::DUMMY_NODE_ID, + node: ext, + vis: ast::Inherited, + span: ctx.span + }; +} + +fn remove_redundant_decl(gs: Vec) -> Vec { + fn check_decl(a: &Global, ty: &Type) -> bool { + match *a { + GComp(ci1) => match *ty { + TComp(ci2) => { + ref_eq(ci1, ci2) && ci1.borrow().name.is_empty() + }, + _ => false + }, + GEnum(ei1) => match *ty { + TEnum(ei2) => { + ref_eq(ei1, ei2) && ei1.borrow().name.is_empty() + }, + _ => false + }, + _ => false + } + } + + let typedefs: Vec = gs.iter().filter_map(|g| + match *g { + GType(ref ti) => Some(ti.borrow().ty.clone()), + _ => None + } + ).collect(); + + return gs.move_iter().filter(|g| + !typedefs.iter().any(|t| check_decl(g, t)) + ).collect(); +} + +fn tag_dup_decl(gs: Vec) -> Vec { + fn check(name1: &str, name2: &str) -> bool { + !name1.is_empty() && name1 == name2 + } + + fn check_dup(g1: &Global, g2: &Global) -> bool { + match (g1, g2) { + (>ype(ti1), >ype(ti2)) => { + let a = ti1.borrow(); + let b = ti2.borrow(); + check(a.name.as_slice(), b.name.as_slice()) + }, + (&GComp(ci1), &GComp(ci2)) => { + let a = ci1.borrow(); + let b = ci2.borrow(); + check(a.name.as_slice(), b.name.as_slice()) + }, + (&GCompDecl(ci1), &GCompDecl(ci2)) => { + let a = ci1.borrow(); + let b = ci2.borrow(); + check(a.name.as_slice(), b.name.as_slice()) + }, + (&GEnum(ei1), &GEnum(ei2)) => { + let a = ei1.borrow(); + let b = ei2.borrow(); + check(a.name.as_slice(), b.name.as_slice()) + }, + (&GEnumDecl(ei1), &GEnumDecl(ei2)) => { + let a = ei1.borrow(); + let b = ei2.borrow(); + check(a.name.as_slice(), b.name.as_slice()) + }, + (&GVar(vi1), &GVar(vi2)) => { + let a = vi1.borrow(); + let b = vi2.borrow(); + check(a.name.as_slice(), b.name.as_slice()) + }, + (&GFunc(vi1), &GFunc(vi2)) => { + let a = vi1.borrow(); + let b = vi2.borrow(); + check(a.name.as_slice(), b.name.as_slice()) + }, + _ => false + } + } + + if gs.is_empty() { + return gs; + } + + let len = gs.len(); + let mut res: Vec = vec!(); + res.push(*gs.get(0)); + + for i in iter::range(1, len) { + let mut dup = false; + for j in iter::range(0, i-1) { + if check_dup(gs.get(i), gs.get(j)) { + dup = true; + break; + } + } + if !dup { + res.push(*gs.get(i)); + } + } + + return res; +} + +fn ctypedef_to_rs(ctx: &mut GenCtx, name: String, ty: &Type) -> Vec> { + fn mk_item(ctx: &mut GenCtx, name: String, ty: &Type) -> Gc { + let rust_name = rust_type_id(ctx, name); + let rust_ty = cty_to_rs(ctx, ty); + let base = ast::ItemTy( + box(GC) ast::Ty { + id: ast::DUMMY_NODE_ID, + node: rust_ty.node, + span: ctx.span, + }, + empty_generics() + ); + + return box(GC) ast::Item { + ident: ctx.ext_cx.ident_of(rust_name.as_slice()), + attrs: Vec::new(), + id: ast::DUMMY_NODE_ID, + node: base, + vis: ast::Public, + span: ctx.span + }; + } + + return match *ty { + TComp(ci) => { + let is_empty = ci.borrow().name.is_empty(); + if is_empty { + ci.borrow_mut().name = name.clone(); + let c = ci.borrow().clone(); + if c.cstruct { + vec!(cstruct_to_rs(ctx, name, c.fields)) + } else { + cunion_to_rs(ctx, name, c.layout, c.fields) + } + } else { + vec!(mk_item(ctx, name, ty)) + } + }, + TEnum(ei) => { + let is_empty = ei.borrow().name.is_empty(); + if is_empty { + ei.borrow_mut().name = name.clone(); + let e = ei.borrow().clone(); + cenum_to_rs(ctx, name, e.kind, e.items) + } else { + vec!(mk_item(ctx, name, ty)) + } + }, + _ => vec!(mk_item(ctx, name, ty)) + } +} + +fn cstruct_to_rs(ctx: &mut GenCtx, name: String, fields: Vec) -> Gc { + let mut unnamed: uint = 0; + let fs = fields.iter().map(|f| { + let f_name = if f.name.is_empty() || "_" == f.name.as_slice() { + unnamed += 1; + format!("unnamed_field{}", unnamed) + } else { + rust_type_id(ctx, f.name.clone()) + }; + + let f_ty = box(GC) cty_to_rs(ctx, &f.ty); + + respan(ctx.span, ast::StructField_ { + kind: ast::NamedField( + ctx.ext_cx.ident_of(f_name.as_slice()), + ast::Public, + ), + id: ast::DUMMY_NODE_ID, + ty: f_ty, + attrs: Vec::new() + }) + }).collect(); + + let def = ast::ItemStruct( + box(GC) ast::StructDef { + fields: fs, + ctor_id: None, + super_struct: None, + is_virtual: false + }, + empty_generics() + ); + + let id = rust_type_id(ctx, name); + return box(GC) ast::Item { ident: ctx.ext_cx.ident_of(id.as_slice()), + attrs: vec!(mk_repr_attr(ctx)), + id: ast::DUMMY_NODE_ID, + node: def, + vis: ast::Public, + span: ctx.span + }; +} + +fn opaque_to_rs(ctx: &mut GenCtx, name: String) -> Gc { + let def = ast::ItemEnum( + ast::EnumDef { + variants: vec!() + }, + empty_generics() + ); + + let id = rust_type_id(ctx, name); + return box(GC) ast::Item { ident: ctx.ext_cx.ident_of(id.as_slice()), + attrs: Vec::new(), + id: ast::DUMMY_NODE_ID, + node: def, + vis: ast::Public, + span: ctx.span + }; +} + +fn cunion_to_rs(ctx: &mut GenCtx, name: String, layout: Layout, fields: Vec) -> Vec> { + fn mk_item(ctx: &mut GenCtx, name: String, item: ast::Item_, vis: + ast::Visibility, attrs: Vec) -> Gc { + return box(GC) ast::Item { + ident: ctx.ext_cx.ident_of(name.as_slice()), + attrs: attrs, + id: ast::DUMMY_NODE_ID, + node: item, + vis: vis, + span: ctx.span + }; + } + + let ci = box(GC) RefCell::new(CompInfo::new(name.clone(), false, fields.clone(), layout)); + let union = TNamed(box(GC) RefCell::new(TypeInfo::new(name.clone(), TComp(ci)))); + + let ty_name = match layout.align { + 1 => "u8", + 2 => "u16", + 4 => "u32", + 8 => "u64", + _ => "u8", + }; + let data_len = if ty_name == "u8" { layout.size } else { layout.size / layout.align }; + let base_ty = mk_ty(ctx, false, vec!(ty_name.to_string())); + let data_ty = box(GC) mk_arrty(ctx, &base_ty, data_len); + let data = respan(ctx.span, ast::StructField_ { + kind: ast::NamedField( + ctx.ext_cx.ident_of("data"), + ast::Public, + ), + id: ast::DUMMY_NODE_ID, + ty: data_ty, + attrs: Vec::new() + }); + + let def = ast::ItemStruct( + box(GC) ast::StructDef { + fields: Vec::from_elem(1, data), + ctor_id: None, + super_struct: None, + is_virtual: false + }, + empty_generics() + ); + let union_id = rust_type_id(ctx, name); + let union_attrs = vec!(mk_repr_attr(ctx)); + let union_def = mk_item(ctx, union_id, def, ast::Public, union_attrs); + + let expr = quote_expr!( + &ctx.ext_cx, + unsafe { ::std::mem::transmute(self) } + ); + let mut unnamed: uint = 0; + let fs = fields.iter().map(|f| { + let f_name = if f.name.is_empty() || "_" == f.name.as_slice() { + unnamed += 1; + format!("unnamed_field{}", unnamed) + } else { + first(rust_id(ctx, f.name.clone())) + }; + + let ret_ty = box(GC) cty_to_rs(ctx, &TPtr(box f.ty.clone(), false, Layout::zero())); + let body = box(GC) ast::Block { + view_items: Vec::new(), + stmts: Vec::new(), + expr: Some(expr), + id: ast::DUMMY_NODE_ID, + rules: ast::DefaultBlock, + span: ctx.span + }; + + box(GC) ast::Method { + ident: ctx.ext_cx.ident_of(f_name.as_slice()), + attrs: Vec::new(), + generics: empty_generics(), + explicit_self: respan(ctx.span, ast::SelfRegion(None, ast::MutMutable)), + fn_style: ast::NormalFn, + decl: box(GC) ast::FnDecl { + inputs: Vec::from_elem(1, ast::Arg::new_self(ctx.span, ast::MutImmutable)), + output: ret_ty, + cf: ast::Return, + variadic: false + }, + body: body, + id: ast::DUMMY_NODE_ID, + span: ctx.span, + vis: ast::Public + } + }).collect(); + + let methods = ast::ItemImpl( + empty_generics(), + None, + box(GC) cty_to_rs(ctx, &union), + fs + ); + + return vec!( + union_def, + mk_item(ctx, "".to_string(), methods, ast::Inherited, Vec::new()) + ); +} + +fn cenum_to_rs(ctx: &mut GenCtx, name: String, kind: IKind, items: Vec) -> Vec> { + let ty = TInt(kind, Layout::zero()); + let ty_id = rust_type_id(ctx, name); + let ty_def = ctypedef_to_rs(ctx, ty_id, &ty); + let val_ty = cty_to_rs(ctx, &ty); + let mut def = ty_def; + + for it in items.iter() { + let cst = ast::ItemStatic( + box(GC) val_ty.clone(), + ast::MutImmutable, + ctx.ext_cx.expr_lit(ctx.span, ast::LitIntUnsuffixed(it.val)) + ); + + let id = first(rust_id(ctx, it.name.clone())); + let val_def = box(GC) ast::Item { + ident: ctx.ext_cx.ident_of(id.as_slice()), + attrs: Vec::new(), + id: ast::DUMMY_NODE_ID, + node: cst, + vis: ast::Public, + span: ctx.span + }; + + def.push(val_def); + } + + return def; +} + +fn mk_link_name_attr(ctx: &mut GenCtx, name: String) -> ast::Attribute { + let lit = respan(ctx.span, ast::LitStr( + to_intern_str(ctx, name), + ast::CookedStr + )); + let attr_val = box(GC) respan(ctx.span, ast::MetaNameValue( + to_intern_str(ctx, "link_name".to_string()), lit + )); + let attr = ast::Attribute_ { + id: mk_attr_id(), + style: ast::AttrOuter, + value: attr_val, + is_sugared_doc: false + }; + respan(ctx.span, attr) +} + +fn mk_repr_attr(ctx: &mut GenCtx) -> ast::Attribute { + let attr_val = box(GC) respan(ctx.span, ast::MetaList( + to_intern_str(ctx, "repr".to_string()), + vec!(box(GC) respan(ctx.span, ast::MetaWord(to_intern_str(ctx, "C".to_string())))) + )); + + respan(ctx.span, ast::Attribute_ { + id: mk_attr_id(), + style: ast::AttrOuter, + value: attr_val, + is_sugared_doc: false + }) +} + +fn cvar_to_rs(ctx: &mut GenCtx, name: String, + ty: &Type, + is_const: bool) -> Gc { + let (rust_name, was_mangled) = rust_id(ctx, name.clone()); + + let mut attrs = Vec::new(); + if was_mangled { + attrs.push(mk_link_name_attr(ctx, name)); + } + + return box(GC) ast::ForeignItem { + ident: ctx.ext_cx.ident_of(rust_name.as_slice()), + attrs: attrs, + node: ast::ForeignItemStatic(box(GC) cty_to_rs(ctx, ty), !is_const), + id: ast::DUMMY_NODE_ID, + span: ctx.span, + vis: ast::Public, + }; +} + +fn cfuncty_to_rs(ctx: &mut GenCtx, + rty: &Type, + aty: &[(String, Type)], + var: bool) -> ast::FnDecl { + + let ret = box(GC) match *rty { + TVoid => ast::Ty { + id: ast::DUMMY_NODE_ID, + node: ast::TyNil, + span: ctx.span + }, + _ => cty_to_rs(ctx, rty) + }; + + let mut unnamed: uint = 0; + let args: Vec = aty.iter().map(|arg| { + let (ref n, ref t) = *arg; + + let arg_name = if n.is_empty() { + unnamed += 1; + format!("arg{}", unnamed) + } else { + first(rust_id(ctx, n.clone())) + }; + + let arg_ty = box(GC) cty_to_rs(ctx, t); + + ast::Arg { + ty: arg_ty, + pat: box(GC) ast::Pat { + id: ast::DUMMY_NODE_ID, + node: ast::PatIdent( + ast::BindByValue(ast::MutImmutable), + respan(ctx.span, ctx.ext_cx.ident_of(arg_name.as_slice())), + None + ), + span: ctx.span + }, + id: ast::DUMMY_NODE_ID, + } + }).collect(); + + let var = !args.is_empty() && var; + return ast::FnDecl { + inputs: args, + output: ret, + cf: ast::Return, + variadic: var + }; +} + +fn cfunc_to_rs(ctx: &mut GenCtx, name: String, rty: &Type, + aty: &[(String, Type)], + var: bool) -> Gc { + let var = !aty.is_empty() && var; + let decl = ast::ForeignItemFn( + box(GC) cfuncty_to_rs(ctx, rty, aty, var), + empty_generics() + ); + + let (rust_name, was_mangled) = rust_id(ctx, name.clone()); + + let mut attrs = Vec::new(); + if was_mangled { + attrs.push(mk_link_name_attr(ctx, name)); + } + + return box(GC) ast::ForeignItem { + ident: ctx.ext_cx.ident_of(rust_name.as_slice()), + attrs: attrs, + node: decl, + id: ast::DUMMY_NODE_ID, + span: ctx.span, + vis: ast::Public, + }; +} + +fn cty_to_rs(ctx: &mut GenCtx, ty: &Type) -> ast::Ty { + return match *ty { + TVoid => mk_ty(ctx, true, vec!("libc".to_string(), "c_void".to_string())), + TInt(i, _) => match i { + IBool => mk_ty(ctx, true, vec!("libc".to_string(), "c_int".to_string())), + ISChar => mk_ty(ctx, true, vec!("libc".to_string(), "c_char".to_string())), + IUChar => mk_ty(ctx, true, vec!("libc".to_string(), "c_uchar".to_string())), + IInt => mk_ty(ctx, true, vec!("libc".to_string(), "c_int".to_string())), + IUInt => mk_ty(ctx, true, vec!("libc".to_string(), "c_uint".to_string())), + IShort => mk_ty(ctx, true, vec!("libc".to_string(), "c_short".to_string())), + IUShort => mk_ty(ctx, true, vec!("libc".to_string(), "c_ushort".to_string())), + ILong => mk_ty(ctx, true, vec!("libc".to_string(), "c_long".to_string())), + IULong => mk_ty(ctx, true, vec!("libc".to_string(), "c_ulong".to_string())), + ILongLong => mk_ty(ctx, true, vec!("libc".to_string(), "c_longlong".to_string())), + IULongLong => mk_ty(ctx, true, vec!("libc".to_string(), "c_ulonglong".to_string())) + }, + TFloat(f, _) => match f { + FFloat => mk_ty(ctx, true, vec!("libc".to_string(), "c_float".to_string())), + FDouble => mk_ty(ctx, true, vec!("libc".to_string(), "c_double".to_string())) + }, + TPtr(ref t, is_const, _) => { + let id = cty_to_rs(ctx, *t); + mk_ptrty(ctx, &id, is_const) + }, + TArray(ref t, s, _) => { + let ty = cty_to_rs(ctx, *t); + mk_arrty(ctx, &ty, s) + }, + TFunc(ref rty, ref atys, var) => { + let decl = cfuncty_to_rs(ctx, *rty, atys.as_slice(), var); + mk_fnty(ctx, &decl) + }, + TNamed(ti) => { + let id = rust_type_id(ctx, ti.borrow().name.clone()); + mk_ty(ctx, false, vec!(id)) + }, + TComp(ci) => { + let mut c = ci.borrow_mut(); + c.name = unnamed_name(ctx, c.name.clone()); + if c.cstruct { + mk_ty(ctx, false, vec!(struct_name(c.name.clone()))) + } else { + mk_ty(ctx, false, vec!(union_name(c.name.clone()))) + } + }, + TEnum(ei) => { + let mut e = ei.borrow_mut(); + e.name = unnamed_name(ctx, e.name.clone()); + mk_ty(ctx, false, vec!(enum_name(e.name.clone()))) + } + }; +} + +fn mk_ty(ctx: &mut GenCtx, global: bool, segments: Vec) -> ast::Ty { + let ty = ast::TyPath( + ast::Path { + span: ctx.span, + global: global, + segments: segments.iter().map(|s| { + ast::PathSegment { + identifier: ctx.ext_cx.ident_of(s.as_slice()), + lifetimes: Vec::new(), + types: OwnedSlice::empty(), + } + }).collect() + }, + option::None, + ast::DUMMY_NODE_ID + ); + + return ast::Ty { + id: ast::DUMMY_NODE_ID, + node: ty, + span: ctx.span + }; +} + +fn mk_ptrty(ctx: &mut GenCtx, base: &ast::Ty, is_const: bool) -> ast::Ty { + let ty = ast::TyPtr(ast::MutTy { + ty: box(GC) base.clone(), + mutbl: if is_const { ast::MutImmutable } else { ast::MutMutable } + }); + + return ast::Ty { + id: ast::DUMMY_NODE_ID, + node: ty, + span: ctx.span + }; +} + +fn mk_arrty(ctx: &mut GenCtx, base: &ast::Ty, n: uint) -> ast::Ty { + let sz = ast::ExprLit(box(GC) respan(ctx.span, ast::LitUint(n as u64, ast::TyU))); + let ty = ast::TyFixedLengthVec( + box(GC) base.clone(), + box(GC) ast::Expr { + id: ast::DUMMY_NODE_ID, + node: sz, + span: ctx.span + } + ); + + return ast::Ty { + id: ast::DUMMY_NODE_ID, + node: ty, + span: ctx.span + }; +} + +fn mk_fnty(ctx: &mut GenCtx, decl: &ast::FnDecl) -> ast::Ty { + let fnty = ast::TyBareFn(box(GC) ast::BareFnTy { + fn_style: ast::NormalFn, + abi: ctx.abi, + lifetimes: Vec::new(), + decl: box(GC) decl.clone() + }); + + let mut segs = Vec::new(); + segs.push_all([ + ast::PathSegment { + identifier: ctx.ext_cx.ident_of("std"), + lifetimes: Vec::new(), + types: OwnedSlice::empty(), + }, + ast::PathSegment { + identifier: ctx.ext_cx.ident_of("option"), + lifetimes: Vec::new(), + types: OwnedSlice::empty(), + }, + ast::PathSegment { + identifier: ctx.ext_cx.ident_of("Option"), + lifetimes: Vec::new(), + types: OwnedSlice::from_vec(Vec::from_elem(1, + box(GC) ast::Ty { + id: ast::DUMMY_NODE_ID, + node: fnty, + span: ctx.span + } + )) + } + ]); + + return ast::Ty { + id: ast::DUMMY_NODE_ID, + node: ast::TyPath( + ast::Path { + span: ctx.span, + global: true, + segments: segs + }, + None, + ast::DUMMY_NODE_ID + ), + span: ctx.span + }; +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 00000000..aeaa63f1 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,110 @@ +#![crate_id = "bindgen"] +#![crate_type = "dylib"] +#![feature(globs, managed_boxes, quote, phase, plugin_registrar)] + +extern crate syntax; +extern crate rustc; +extern crate libc; +#[phase(plugin, link)] extern crate log; + +use std::collections::HashSet; +use std::default::Default; +use std::gc::Gc; + +use syntax::ast; +use syntax::codemap::Span; +use rustc::plugin::Registry; + +use types::Global; + +mod types; +mod clangll; +mod clang; +mod gen; +mod parser; +mod macro; + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_macro("bindgen", macro::bindgen_macro); +} + +pub struct BindgenOptions { + pub match_pat: Vec, + pub abi: String, + pub builtins: bool, + pub links: Vec<(String, Option)>, + pub emit_ast: bool, + pub fail_on_bitfield: bool, + pub fail_on_unknown_type: bool, + pub clang_args: Vec, +} + +impl Default for BindgenOptions { + fn default() -> BindgenOptions { + BindgenOptions { + match_pat: Vec::new(), + abi: "C".to_string(), + builtins: false, + links: Vec::new(), + emit_ast: false, + fail_on_bitfield: false, + fail_on_unknown_type: false, + clang_args: Vec::new() + } + } +} + +pub trait Logger { + fn error(&self, msg: &str); + fn warn(&self, msg: &str); +} + +pub fn generate_bindings(options: BindgenOptions, logger: Option<&Logger>, span: Span) -> Result>, ()> { + let l = DummyLogger; + let logger = match logger { + Some(l) => l, + None => { + &l as &Logger + } + }; + let globals = try!(parse_headers(&options, logger)); + Ok(gen::gen_mod(options.abi.as_slice(), options.links.as_slice(), globals, span)) +} + +struct DummyLogger; + +#[allow(unused_variable)] +impl Logger for DummyLogger { + fn error(&self, msg: &str) { } + fn warn(&self, msg: &str) { } +} + +fn parse_headers(options: &BindgenOptions, logger: &Logger) -> Result, ()> { + let clang_opts = parser::ClangParserOptions { + builtin_names: builtin_names(), + builtins: options.builtins, + match_pat: options.match_pat.clone(), + emit_ast: options.emit_ast, + fail_on_bitfield: options.fail_on_bitfield, + fail_on_unknown_type: options.fail_on_unknown_type, + clang_args: options.clang_args.clone(), + }; + + parser::parse(clang_opts, logger) +} + +fn builtin_names() -> HashSet { + let mut names = HashSet::new(); + let keys = [ + "__va_list_tag", + "__va_list", + ]; + + keys.iter().advance(|s| { + names.insert(s.to_string()); + true + }); + + return names; +} diff --git a/src/macro.rs b/src/macro.rs new file mode 100644 index 00000000..1aee481a --- /dev/null +++ b/src/macro.rs @@ -0,0 +1,319 @@ +use std::cell::RefCell; +use std::default::Default; +use std::os; +use std::gc::Gc; + +use syntax::ast; +use syntax::codemap; +use syntax::ext::base; +use syntax::parse; +use syntax::parse::token; +use syntax::util::small_vector::SmallVector; + +use super::{generate_bindings, BindgenOptions, Logger}; + +pub fn bindgen_macro(cx: &mut base::ExtCtxt, sp: codemap::Span, tts: &[ast::TokenTree]) -> Box { + let mut visit = BindgenArgsVisitor { + options: Default::default(), + seen_named: false + }; + + visit.options.builtins = true; + if !parse_macro_opts(cx, tts, &mut visit) { + return base::DummyResult::any(sp); + } + + // Reparse clang_args as it is passed in string form + let clang_args = visit.options.clang_args.connect(" "); + visit.options.clang_args = parse_process_args(clang_args.as_slice()); + + // Set the working dir to the directory containing the invoking rs file so + // that clang searches for headers relative to it rather than the crate root + let mod_dir = Vec::from_slice(Path::new(cx.codemap().span_to_filename(sp)).dirname()); + let cwd = os::getcwd(); + os::change_dir(&Path::new(mod_dir)); + + // We want the span for errors to just match the bindgen! symbol + // instead of the whole invocation which can span multiple lines + let mut short_span = sp; + short_span.hi = short_span.lo + codemap::BytePos(8); + + let logger = MacroLogger { sp: short_span, cx: cx }; + + let ret = match generate_bindings(visit.options, Some(&logger as &Logger), short_span) { + Ok(items) => { + box BindgenResult { items: RefCell::new(Some(SmallVector::many(items))) } as Box + } + Err(_) => base::DummyResult::any(sp) + }; + + os::change_dir(&Path::new(cwd)); + + ret +} + +trait MacroArgsVisitor { + fn visit_str(&mut self, name: Option<&str>, val: &str) -> bool; + fn visit_int(&mut self, name: Option<&str>, val: i64) -> bool; + fn visit_bool(&mut self, name: Option<&str>, val: bool) -> bool; + fn visit_ident(&mut self, name: Option<&str>, ident: &str) -> bool; +} + +struct BindgenArgsVisitor { + pub options: BindgenOptions, + seen_named: bool +} + +impl MacroArgsVisitor for BindgenArgsVisitor { + fn visit_str(&mut self, mut name: Option<&str>, val: &str) -> bool { + if name.is_some() { self.seen_named = true; } + else if !self.seen_named { name = Some("clang_args") } + match name { + Some("link") => self.options.links.push((val.to_string(), None)), + Some("link_static") => self.options.links.push((val.to_string(), Some("static".to_string()))), + Some("link_framework") => self.options.links.push((val.to_string(), Some("framework".to_string()))), + Some("abi") => self.options.abi = val.to_string(), + Some("match") => self.options.match_pat.push(val.to_string()), + Some("clang_args") => self.options.clang_args.push(val.to_string()), + _ => return false + } + true + } + + #[allow(unused_variable)] + fn visit_int(&mut self, name: Option<&str>, val: i64) -> bool { + if name.is_some() { self.seen_named = true; } + false + } + + fn visit_bool(&mut self, name: Option<&str>, val: bool) -> bool { + if name.is_some() { self.seen_named = true; } + match name { + Some("allow_bitfields") => self.options.fail_on_bitfield = !val, + Some("allow_unknown_types") => self.options.fail_on_unknown_type = !val, + Some("emit_builtins") => self.options.builtins = val, + _ => return false + } + true + } + + #[allow(unused_variable)] + fn visit_ident(&mut self, name: Option<&str>, val: &str) -> bool { + if name.is_some() { self.seen_named = true; } + false + } +} + +// Parses macro invocations in the form [ident=|:]value where value is an ident or literal +// e.g. bindgen!(module_name, "header.h", emit_builtins=false, clang_args:"-I /usr/local/include") +fn parse_macro_opts(cx: &mut base::ExtCtxt, tts: &[ast::TokenTree], visit: &mut MacroArgsVisitor) -> bool { + let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), Vec::from_slice(tts)); + let mut args_good = true; + + loop { + let mut name: Option = None; + let mut span = parser.span; + + // Check for [ident=]value and if found save ident to name + if parser.look_ahead(1, |t| t == &token::EQ) { + match parser.bump_and_get() { + token::IDENT(ident, _) => { + let ident = parser.id_to_interned_str(ident); + name = Some(ident.get().to_string()); + parser.expect(&token::EQ); + }, + _ => { + cx.span_err(span, "invalid argument format"); + return false + } + } + } + + match parser.token { + // Match [ident] + token::IDENT(val, _) => { + let val = parser.id_to_interned_str(val); + span.hi = parser.span.hi; + parser.bump(); + + // Bools are simply encoded as idents + let ret = match val.get() { + "true" => visit.visit_bool(as_str(&name), true), + "false" => visit.visit_bool(as_str(&name), false), + val => visit.visit_ident(as_str(&name), val) + }; + if !ret { + cx.span_err(span, "invalid argument"); + args_good = false; + } + } + // Match [literal] and parse as an expression so we can expand macros + _ => { + let expr = cx.expand_expr(parser.parse_expr()); + span.hi = expr.span.hi; + match expr.node { + ast::ExprLit(lit) => { + let ret = match lit.node { + ast::LitStr(ref s, _) => visit.visit_str(as_str(&name), s.get()), + ast::LitBool(b) => visit.visit_bool(as_str(&name), b), + ast::LitIntUnsuffixed(i) | + ast::LitInt(i, _) => visit.visit_int(as_str(&name), i), + ast::LitUint(i, _) => visit.visit_int(as_str(&name), i as i64), + _ => { + cx.span_err(span, "invalid argument format"); + return false + } + }; + if !ret { + cx.span_err(span, "invalid argument"); + args_good = false; + } + }, + _ => { + cx.span_err(span, "invalid argument format"); + return false + } + } + } + } + + if parser.eat(&token::EOF) { + return args_good + } + + if !parser.eat(&token::COMMA) { + cx.span_err(parser.span, "invalid argument format"); + return false + } + } +} + +// I'm sure there's a nicer way of doing it +fn as_str<'a>(owned: &'a Option) -> Option<&'a str> { + match owned { + &Some(ref s) => Some(s.as_slice()), + &None => None + } +} + +#[deriving(PartialEq, Eq)] +enum QuoteState { + InNone, + InSingleQuotes, + InDoubleQuotes +} + +fn parse_process_args(s: &str) -> Vec { + let s = s.trim(); + let mut parts = Vec::new(); + let mut quote_state = InNone; + let mut positions = vec!(0); + let mut last = ' '; + for (i, c) in s.chars().chain(" ".chars()).enumerate() { + match (last, c) { + // Match \" set has_escaped and skip + ('\\', '\"') => (), + // Match \' + ('\\', '\'') => (), + // Match \ + // Check we don't escape the final added space + ('\\', ' ') if i < s.len() => (), + // Match \\ + ('\\', '\\') => (), + // Match " + (_, '\"') if quote_state == InNone => { + quote_state = InDoubleQuotes; + positions.push(i); + positions.push(i + 1); + }, + (_, '\"') if quote_state == InDoubleQuotes => { + quote_state = InNone; + positions.push(i); + positions.push(i + 1); + }, + // Match ' + (_, '\'') if quote_state == InNone => { + quote_state = InSingleQuotes; + positions.push(i); + positions.push(i + 1); + }, + (_, '\'') if quote_state == InSingleQuotes => { + quote_state = InNone; + positions.push(i); + positions.push(i + 1); + }, + // Match + // If we are at the end of the string close any open quotes + (_, ' ') if quote_state == InNone || i >= s.len() => { + { + positions.push(i); + + let starts = positions.iter().enumerate().filter(|&(i, _)| i % 2 == 0); + let ends = positions.iter().enumerate().filter(|&(i, _)| i % 2 == 1); + + let part: Vec = starts.zip(ends).map(|((_, start), (_, end))| s.slice(*start, *end).to_string()).collect(); + + let part = part.connect(""); + + if part.len() > 0 { + // Remove any extra whitespace outside the quotes + let part = part.as_slice().trim(); + // Replace quoted characters + let part = part.replace("\\\"", "\""); + let part = part.replace("\\\'", "\'"); + let part = part.replace("\\ ", " "); + let part = part.replace("\\\\", "\\"); + parts.push(part); + } + } + + positions.clear(); + positions.push(i + 1); + }, + (_, _) => () + } + last = c; + } + parts +} + +struct MacroLogger<'a, 'b> { + sp: codemap::Span, + cx: &'a base::ExtCtxt<'b> +} + +impl<'a, 'b> Logger for MacroLogger<'a, 'b> { + fn error(&self, msg: &str) { + self.cx.span_err(self.sp, msg) + } + + fn warn(&self, msg: &str) { + self.cx.span_warn(self.sp, msg) + } +} + +struct BindgenResult { + items: RefCell>>> +} + +impl base::MacResult for BindgenResult { + fn make_items(&self) -> Option>> { + self.items.borrow_mut().take() + } +} + +#[cfg(test)] +fn make_string_vec(parts: &[&str]) -> Vec { + parts.iter().map(|p| p.to_string()).collect() +} + +#[test] +fn test_parse_process_args() { + assert_eq!(parse_process_args("a b c"), make_string_vec(["a", "b", "c"])); + assert_eq!(parse_process_args("a \"b\" c"), make_string_vec(["a", "b", "c"])); + assert_eq!(parse_process_args("a \'b\' c"), make_string_vec(["a", "b", "c"])); + assert_eq!(parse_process_args("a \"b c\""), make_string_vec(["a", "b c"])); + assert_eq!(parse_process_args("a \'\"b\"\' c"), make_string_vec(["a", "\"b\"", "c"])); + assert_eq!(parse_process_args("a b\\ c"), make_string_vec(["a", "b c"])); + assert_eq!(parse_process_args("a b c\\"), make_string_vec(["a", "b", "c\\"])); +} diff --git a/src/parser.rs b/src/parser.rs new file mode 100644 index 00000000..4f9153ba --- /dev/null +++ b/src/parser.rs @@ -0,0 +1,480 @@ +#![allow(non_uppercase_pattern_statics)] +#![allow(unused_must_use)] + +use std::collections::{HashMap, HashSet}; +use std::cell::RefCell; +use std::gc::GC; + +use il = types; +use types::*; +use cx = clang; +use clang::*; +use clang::ll::*; + +use super::Logger; + +pub struct ClangParserOptions { + pub builtin_names: HashSet, + pub builtins: bool, + pub match_pat: Vec, + pub emit_ast: bool, + pub fail_on_bitfield: bool, + pub fail_on_unknown_type: bool, + pub clang_args: Vec, +} + +struct ClangParserCtx<'a> { + options: ClangParserOptions, + name: HashMap, + globals: Vec, + builtin_defs: Vec, + logger: &'a Logger, + err_count: int +} + +fn match_pattern(ctx: &mut ClangParserCtx, cursor: &Cursor) -> bool { + let (file, _, _, _) = cursor.location().location(); + + if file.is_null() { + return ctx.options.builtins; + } + + if ctx.options.match_pat.is_empty() { + return true; + } + + let name = file.name(); + let mut found = false; + ctx.options.match_pat.iter().advance(|pat| { + if name.as_slice().contains((*pat).as_slice()) { + found = true; + } + true + }); + + return found; +} + +fn decl_name(ctx: &mut ClangParserCtx, cursor: &Cursor) -> Global { + let mut new_decl = false; + let decl = { + *ctx.name.find_or_insert_with(*cursor, |_| { + new_decl = true; + let spelling = cursor.spelling(); + let ty = cursor.cur_type(); + let layout = Layout::new(ty.size(), ty.align()); + + match cursor.kind() { + CXCursor_StructDecl => { + let ci = box(GC) RefCell::new(CompInfo::new(spelling, true, vec!(), layout)); + GCompDecl(ci) + } + CXCursor_UnionDecl => { + let ci = box(GC) RefCell::new(CompInfo::new(spelling, false, vec!(), layout)); + GCompDecl(ci) + } + CXCursor_EnumDecl => { + let kind = match cursor.enum_type().kind() { + CXType_SChar | CXType_Char_S => ISChar, + CXType_UChar | CXType_Char_U => IUChar, + CXType_UShort => IUShort, + CXType_UInt => IUInt, + CXType_ULong => IULong, + CXType_ULongLong => IULongLong, + CXType_Short => IShort, + CXType_Int => IInt, + CXType_Long => ILong, + CXType_LongLong => ILongLong, + _ => IInt, + }; + let ei = box(GC) RefCell::new(EnumInfo::new(spelling, kind, vec!(), layout)); + GEnumDecl(ei) + } + CXCursor_TypedefDecl => { + let ti = box(GC) RefCell::new(TypeInfo::new(spelling, TVoid)); + GType(ti) + } + CXCursor_VarDecl => { + let vi = box(GC) RefCell::new(VarInfo::new(spelling, TVoid)); + GVar(vi) + } + CXCursor_FunctionDecl => { + let vi = box(GC) RefCell::new(VarInfo::new(spelling, TVoid)); + GFunc(vi) + } + _ => GOther + } + }) + }; + + if new_decl { + if ctx.options.builtin_names.contains(&cursor.spelling()) { + ctx.builtin_defs.push(*cursor); + } + } + + return decl; +} + +fn opaque_decl(ctx: &mut ClangParserCtx, decl: &Cursor) { + let name = decl_name(ctx, decl); + ctx.globals.push(name); +} + +fn fwd_decl(ctx: &mut ClangParserCtx, cursor: &Cursor, f: |ctx: &mut ClangParserCtx|) { + let def = &cursor.definition(); + if cursor == def { + f(ctx); + } else if def.kind() == CXCursor_NoDeclFound || + def.kind() == CXCursor_InvalidFile { + opaque_decl(ctx, cursor); + } +} + +fn conv_ptr_ty(ctx: &mut ClangParserCtx, ty: &cx::Type, cursor: &Cursor, layout: Layout) -> il::Type { + let is_const = ty.is_const(); + match ty.kind() { + CXType_Void => { + return TPtr(box TVoid, is_const, layout) + } + CXType_Unexposed | + CXType_FunctionProto | + CXType_FunctionNoProto => { + let ret_ty = ty.ret_type(); + let decl = ty.declaration(); + return if ret_ty.kind() != CXType_Invalid { + let args_lst = ty.arg_types().iter().map(|arg| { + ("".to_string(), conv_ty(ctx, arg, cursor)) + }).collect(); + let ret_ty = box conv_ty(ctx, &ret_ty, cursor); + + TFunc(ret_ty, args_lst, ty.is_variadic()) + } else if decl.kind() != CXCursor_NoDeclFound { + TPtr(box conv_decl_ty(ctx, &decl), is_const, layout) + } else { + TPtr(box TVoid, is_const, layout) + }; + } + CXType_Typedef => { + let decl = ty.declaration(); + let def_ty = decl.typedef_type(); + if def_ty.kind() == CXType_FunctionProto || + def_ty.kind() == CXType_FunctionNoProto { + return TPtr(box conv_ptr_ty(ctx, &def_ty, cursor, layout), is_const, layout); + } else { + return TPtr(box conv_ty(ctx, ty, cursor), is_const, layout); + } + } + _ => return TPtr(box conv_ty(ctx, ty, cursor), is_const, layout), + } +} + +fn conv_decl_ty(ctx: &mut ClangParserCtx, cursor: &Cursor) -> il::Type { + return match cursor.kind() { + CXCursor_StructDecl => { + let decl = decl_name(ctx, cursor); + let ci = decl.compinfo(); + TComp(ci) + } + CXCursor_UnionDecl => { + let decl = decl_name(ctx, cursor); + let ci = decl.compinfo(); + TComp(ci) + } + CXCursor_EnumDecl => { + let decl = decl_name(ctx, cursor); + let ei = decl.enuminfo(); + TEnum(ei) + } + CXCursor_TypedefDecl => { + let decl = decl_name(ctx, cursor); + let ti = decl.typeinfo(); + TNamed(ti) + } + _ => TVoid + }; +} + +fn conv_ty(ctx: &mut ClangParserCtx, ty: &cx::Type, cursor: &Cursor) -> il::Type { + debug!("conv_ty: ty=`{}`", type_to_str(ty.kind())); + let layout = Layout::new(ty.size(), ty.align()); + return match ty.kind() { + CXType_Void | CXType_Invalid => TVoid, + CXType_Bool => TInt(IBool, layout), + CXType_SChar | + CXType_Char_S => TInt(ISChar, layout), + CXType_UChar | + CXType_Char_U => TInt(IUChar, layout), + CXType_UShort => TInt(IUShort, layout), + CXType_UInt => TInt(IUInt, layout), + CXType_ULong => TInt(IULong, layout), + CXType_ULongLong => TInt(IULongLong, layout), + CXType_Short => TInt(IShort, layout), + CXType_Int => TInt(IInt, layout), + CXType_Long => TInt(ILong, layout), + CXType_LongLong => TInt(ILongLong, layout), + CXType_Float => TFloat(FFloat, layout), + CXType_Double => TFloat(FDouble, layout), + CXType_LongDouble => TFloat(FDouble, layout), + CXType_Pointer => conv_ptr_ty(ctx, &ty.pointee_type(), cursor, layout), + CXType_VariableArray | CXType_DependentSizedArray | CXType_IncompleteArray => { + conv_ptr_ty(ctx, &ty.elem_type(), cursor, layout) + } + CXType_Record | + CXType_Typedef | + CXType_Unexposed | + CXType_Enum => conv_decl_ty(ctx, &ty.declaration()), + CXType_ConstantArray => TArray(box conv_ty(ctx, &ty.elem_type(), cursor), ty.array_size(), layout), + _ => { + let fail = ctx.options.fail_on_unknown_type; + log_err_warn(ctx, + format!("unsupported type `{}` ({})", + type_to_str(ty.kind()), cursor.location() + ).as_slice(), + fail + ); + TVoid + }, + }; +} + +fn opaque_ty(ctx: &mut ClangParserCtx, ty: &cx::Type) { + if ty.kind() == CXType_Record || ty.kind() == CXType_Enum { + let decl = ty.declaration(); + let def = decl.definition(); + if def.kind() == CXCursor_NoDeclFound || + def.kind() == CXCursor_InvalidFile { + opaque_decl(ctx, &decl); + } + } +} + +fn visit_struct(cursor: &Cursor, + parent: &Cursor, + ctx: &mut ClangParserCtx, + fields: &mut Vec) -> Enum_CXVisitorResult { + if cursor.kind() == CXCursor_FieldDecl { + let ty = conv_ty(ctx, &cursor.cur_type(), cursor); + let name = cursor.spelling(); + let bit = cursor.bit_width(); + // If we encounter a bitfield, and fail_on_bitfield is set, throw an + // error and exit entirely. + if bit != None { + let fail = ctx.options.fail_on_bitfield; + log_err_warn(ctx, + format!("unsupported bitfield `{}` in struct `{}` ({})", + name.as_slice(), parent.spelling().as_slice(), cursor.location() + ).as_slice(), + fail + ); + } + let field = FieldInfo::new(name, ty, bit); + fields.push(field); + } + return CXChildVisit_Continue; +} + +fn visit_union(cursor: &Cursor, + ctx: &mut ClangParserCtx, + fields: &mut Vec) -> Enum_CXVisitorResult { + if cursor.kind() == CXCursor_FieldDecl { + let ty = conv_ty(ctx, &cursor.cur_type(), cursor); + let name = cursor.spelling(); + let field = FieldInfo::new(name, ty, None); + fields.push(field); + } + return CXChildVisit_Continue; +} + +fn visit_enum(cursor: &Cursor, + items: &mut Vec) -> Enum_CXVisitorResult { + if cursor.kind() == CXCursor_EnumConstantDecl { + let name = cursor.spelling(); + let val = cursor.enum_val(); + let item = EnumItem::new(name, val); + items.push(item); + } + return CXChildVisit_Continue; +} + +fn visit_top<'r>(cur: &'r Cursor, + parent: &'r Cursor, + ctx: &mut ClangParserCtx) -> Enum_CXVisitorResult { + let cursor = if ctx.options.builtin_names.contains(&parent.spelling()) { + parent + } else { + cur + }; + + if !match_pattern(ctx, cursor) { + return CXChildVisit_Continue; + } + + match cursor.kind() { + CXCursor_StructDecl => { + fwd_decl(ctx, cursor, |ctx_| { + let decl = decl_name(ctx_, cursor); + let ci = decl.compinfo(); + cursor.visit(|c, p| { + let mut ci_ = ci.borrow_mut(); + visit_struct(c, p, ctx_, &mut ci_.fields) + }); + ctx_.globals.push(GComp(ci)); + }); + return if cur.kind() == CXCursor_FieldDecl { + CXChildVisit_Break + } else { + CXChildVisit_Recurse + }; + } + CXCursor_UnionDecl => { + fwd_decl(ctx, cursor, |ctx_| { + let decl = decl_name(ctx_, cursor); + let ci = decl.compinfo(); + cursor.visit(|c, _| { + let mut ci_ = ci.borrow_mut(); + visit_union(c, ctx_, &mut ci_.fields) + }); + ctx_.globals.push(GComp(ci)); + }); + return CXChildVisit_Recurse; + } + CXCursor_EnumDecl => { + fwd_decl(ctx, cursor, |ctx_| { + let decl = decl_name(ctx_, cursor); + let ei = decl.enuminfo(); + cursor.visit(|c, _| { + let mut ei_ = ei.borrow_mut(); + visit_enum(c, &mut ei_.items) + }); + ctx_.globals.push(GEnum(ei)); + }); + return CXChildVisit_Continue; + } + CXCursor_FunctionDecl => { + let linkage = cursor.linkage(); + if linkage != CXLinkage_External && linkage != CXLinkage_UniqueExternal { + return CXChildVisit_Continue; + } + + let args_lst: Vec<(String, il::Type)> = cursor.args().iter().map(|arg| { + let arg_name = arg.spelling(); + (arg_name, conv_ty(ctx, &arg.cur_type(), cursor)) + }).collect(); + + let ty = cursor.cur_type(); + let ret_ty = box conv_ty(ctx, &cursor.ret_type(), cursor); + + let func = decl_name(ctx, cursor); + let vi = func.varinfo(); + let mut vi = vi.borrow_mut(); + vi.ty = TFunc(ret_ty.clone(), args_lst.clone(), ty.is_variadic()); + ctx.globals.push(func); + + return CXChildVisit_Continue; + } + CXCursor_VarDecl => { + let linkage = cursor.linkage(); + if linkage != CXLinkage_External && linkage != CXLinkage_UniqueExternal { + 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(); + ctx.globals.push(var); + + return CXChildVisit_Continue; + } + CXCursor_TypedefDecl => { + let mut under_ty = cursor.typedef_type(); + if under_ty.kind() == CXType_Unexposed { + under_ty = under_ty.canonical_type(); + } + + let ty = conv_ty(ctx, &under_ty, cursor); + let typedef = decl_name(ctx, cursor); + let ti = typedef.typeinfo(); + let mut ti = ti.borrow_mut(); + ti.ty = ty.clone(); + ctx.globals.push(typedef); + + opaque_ty(ctx, &under_ty); + + return CXChildVisit_Continue; + } + CXCursor_FieldDecl => { + return CXChildVisit_Continue; + } + _ => return CXChildVisit_Recurse, + } +} + +fn log_err_warn(ctx: &mut ClangParserCtx, msg: &str, is_err: bool) { + match is_err { + true => { + ctx.err_count += 1; + ctx.logger.error(msg) + }, + false => ctx.logger.warn(msg) + } +} + +pub fn parse(options: ClangParserOptions, logger: &Logger) -> Result, ()> { + let mut ctx = ClangParserCtx { + options: options, + name: HashMap::new(), + builtin_defs: vec!(), + globals: vec!(), + logger: logger, + err_count: 0 + }; + + 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.as_slice(), [], 0); + if unit.is_null() { + ctx.logger.error("No input files given"); + return Err(()) + } + + let diags = unit.diags(); + for d in diags.iter() { + let msg = d.format(Diagnostic::default_opts()); + let is_err = d.severity() >= CXDiagnostic_Error; + log_err_warn(&mut ctx, msg.as_slice(), is_err); + } + + if ctx.err_count > 0 { + return Err(()) + } + + let cursor = unit.cursor(); + + if ctx.options.emit_ast { + cursor.visit(|cur, _| ast_dump(cur, 0)); + } + + cursor.visit(|cur, parent| visit_top(cur, parent, &mut ctx)); + + while !ctx.builtin_defs.is_empty() { + let c = ctx.builtin_defs.shift().unwrap(); + c.visit(|cur, parent| visit_top(cur, parent, &mut ctx)); + } + + unit.dispose(); + ix.dispose(); + + if ctx.err_count > 0 { + return Err(()) + } + + Ok(ctx.globals) +} diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 00000000..2b84bbca --- /dev/null +++ b/src/types.rs @@ -0,0 +1,269 @@ +use std::cell::RefCell; +use std::fmt; +use std::gc::Gc; + +#[deriving(Clone)] +pub enum Global { + GType(Gc>), + GComp(Gc>), + GCompDecl(Gc>), + GEnum(Gc>), + GEnumDecl(Gc>), + GVar(Gc>), + GFunc(Gc>), + GOther +} + +impl Global { + pub fn compinfo(&self) -> Gc> { + match *self { + GComp(i) => return i, + GCompDecl(i) => return i, + _ => fail!("global_compinfo".to_string()) + } + } + + pub fn enuminfo(&self) -> Gc> { + match *self { + GEnum(i) => return i, + GEnumDecl(i) => return i, + _ => fail!("global_enuminfo".to_string()) + } + } + + pub fn typeinfo(&self) -> Gc> { + match *self { + GType(i) => return i, + _ => fail!("global_typeinfo".to_string()) + } + } + + pub fn varinfo(&self) -> Gc> { + match *self { + GVar(i) => i, + GFunc(i) => i, + _ => fail!("global_varinfo".to_string()) + } + } +} + +impl fmt::Show for Global { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + GType(ti) => ti.borrow().fmt(f), + GComp(ci) => ci.borrow().fmt(f), + GCompDecl(ci) => ci.borrow().fmt(f), + GEnum(ei) => ei.borrow().fmt(f), + GEnumDecl(ei) => ei.borrow().fmt(f), + GVar(vi) => vi.borrow().fmt(f), + GFunc(vi) => vi.borrow().fmt(f), + GOther => "*".fmt(f), + } + } +} + +#[deriving(Clone, PartialEq)] +pub enum Type { + TVoid, + TInt(IKind, Layout), + TFloat(FKind, Layout), + TPtr(Box, bool, Layout), + TArray(Box, uint, Layout), + TFunc(Box, Vec<(String, Type)>, bool), + TNamed(Gc>), + TComp(Gc>), + TEnum(Gc>) +} + +impl Type { + pub fn size(&self) -> uint { + match *self { + TInt(_, l) => l.size, + TFloat(_, l) => l.size, + TPtr(_, _, l) => l.size, + TArray(_, _, l) => l.size, + TNamed(ref ti) => ti.borrow().ty.size(), + TComp(ref ci) => ci.borrow().layout.size, + TEnum(ref ei) => ei.borrow().layout.size, + TVoid => 0, + TFunc(..) => 0, + } + } + + pub fn align(&self) -> uint { + match *self { + TInt(_, l) => l.align, + TFloat(_, l) => l.align, + TPtr(_, _, l) => l.align, + TArray(_, _, l) => l.align, + TNamed(ref ti) => ti.borrow().ty.align(), + TComp(ref ci) => ci.borrow().layout.align, + TEnum(ref ei) => ei.borrow().layout.align, + TVoid => 0, + TFunc(..) => 0, + } + } +} + +#[deriving(Clone, PartialEq)] +pub struct Layout { + pub size: uint, + pub align: uint, +} + +impl Layout { + pub fn new(size: uint, align: uint) -> Layout { + Layout { size: size, align: align } + } + + pub fn zero() -> Layout { + Layout { size: 0, align: 0 } + } +} + +#[deriving(Clone, PartialEq)] +pub enum IKind { + IBool, + ISChar, + IUChar, + IShort, + IUShort, + IInt, + IUInt, + ILong, + IULong, + ILongLong, + IULongLong +} + +#[deriving(Clone, PartialEq)] +pub enum FKind { + FFloat, + FDouble +} + +#[deriving(Clone, PartialEq)] +pub struct CompInfo { + pub cstruct: bool, + pub name: String, + pub fields: Vec, + pub layout: Layout, +} + +impl CompInfo { + pub fn new(name: String, cstruct: bool, fields: Vec, layout: Layout) -> CompInfo { + CompInfo { + cstruct: cstruct, + name: name, + fields: fields, + layout: layout, + } + } +} + +impl fmt::Show for CompInfo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.name.fmt(f) + } +} + +#[deriving(Clone, PartialEq)] +pub struct FieldInfo { + pub name: String, + pub ty: Type, + pub bit: Option, +} + +impl FieldInfo { + pub fn new(name: String, ty: Type, bit: Option) -> FieldInfo { + FieldInfo { + name: name, + ty: ty, + bit: bit, + } + } +} + +#[deriving(Clone, PartialEq)] +pub struct EnumInfo { + pub name: String, + pub items: Vec, + pub kind: IKind, + pub layout: Layout, +} + +impl EnumInfo { + pub fn new(name: String, kind: IKind, items: Vec, layout: Layout) -> EnumInfo { + EnumInfo { + name: name, + items: items, + kind: kind, + layout: layout, + } + } +} + +impl fmt::Show for EnumInfo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.name.fmt(f) + } +} + +#[deriving(Clone, PartialEq)] +pub struct EnumItem { + pub name: String, + pub val: i64 +} + +impl EnumItem { + pub fn new(name: String, val: i64) -> EnumItem { + EnumItem { + name: name, + val: val + } + } +} + +#[deriving(Clone, PartialEq)] +pub struct TypeInfo { + pub name: String, + pub ty: Type +} + +impl TypeInfo { + pub fn new(name: String, ty: Type) -> TypeInfo { + TypeInfo { + name: name, + ty: ty + } + } +} + +impl fmt::Show for TypeInfo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.name.fmt(f) + } +} + +#[deriving(Clone)] +pub struct VarInfo { + pub name: String, + pub ty: Type, + pub is_const: bool +} + +impl VarInfo { + pub fn new(name: String, ty: Type) -> VarInfo { + VarInfo { + name: name, + ty: ty, + is_const: false + } + } +} + +impl fmt::Show for VarInfo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.name.fmt(f) + } +} diff --git a/types.rs b/types.rs deleted file mode 100644 index 2b84bbca..00000000 --- a/types.rs +++ /dev/null @@ -1,269 +0,0 @@ -use std::cell::RefCell; -use std::fmt; -use std::gc::Gc; - -#[deriving(Clone)] -pub enum Global { - GType(Gc>), - GComp(Gc>), - GCompDecl(Gc>), - GEnum(Gc>), - GEnumDecl(Gc>), - GVar(Gc>), - GFunc(Gc>), - GOther -} - -impl Global { - pub fn compinfo(&self) -> Gc> { - match *self { - GComp(i) => return i, - GCompDecl(i) => return i, - _ => fail!("global_compinfo".to_string()) - } - } - - pub fn enuminfo(&self) -> Gc> { - match *self { - GEnum(i) => return i, - GEnumDecl(i) => return i, - _ => fail!("global_enuminfo".to_string()) - } - } - - pub fn typeinfo(&self) -> Gc> { - match *self { - GType(i) => return i, - _ => fail!("global_typeinfo".to_string()) - } - } - - pub fn varinfo(&self) -> Gc> { - match *self { - GVar(i) => i, - GFunc(i) => i, - _ => fail!("global_varinfo".to_string()) - } - } -} - -impl fmt::Show for Global { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - GType(ti) => ti.borrow().fmt(f), - GComp(ci) => ci.borrow().fmt(f), - GCompDecl(ci) => ci.borrow().fmt(f), - GEnum(ei) => ei.borrow().fmt(f), - GEnumDecl(ei) => ei.borrow().fmt(f), - GVar(vi) => vi.borrow().fmt(f), - GFunc(vi) => vi.borrow().fmt(f), - GOther => "*".fmt(f), - } - } -} - -#[deriving(Clone, PartialEq)] -pub enum Type { - TVoid, - TInt(IKind, Layout), - TFloat(FKind, Layout), - TPtr(Box, bool, Layout), - TArray(Box, uint, Layout), - TFunc(Box, Vec<(String, Type)>, bool), - TNamed(Gc>), - TComp(Gc>), - TEnum(Gc>) -} - -impl Type { - pub fn size(&self) -> uint { - match *self { - TInt(_, l) => l.size, - TFloat(_, l) => l.size, - TPtr(_, _, l) => l.size, - TArray(_, _, l) => l.size, - TNamed(ref ti) => ti.borrow().ty.size(), - TComp(ref ci) => ci.borrow().layout.size, - TEnum(ref ei) => ei.borrow().layout.size, - TVoid => 0, - TFunc(..) => 0, - } - } - - pub fn align(&self) -> uint { - match *self { - TInt(_, l) => l.align, - TFloat(_, l) => l.align, - TPtr(_, _, l) => l.align, - TArray(_, _, l) => l.align, - TNamed(ref ti) => ti.borrow().ty.align(), - TComp(ref ci) => ci.borrow().layout.align, - TEnum(ref ei) => ei.borrow().layout.align, - TVoid => 0, - TFunc(..) => 0, - } - } -} - -#[deriving(Clone, PartialEq)] -pub struct Layout { - pub size: uint, - pub align: uint, -} - -impl Layout { - pub fn new(size: uint, align: uint) -> Layout { - Layout { size: size, align: align } - } - - pub fn zero() -> Layout { - Layout { size: 0, align: 0 } - } -} - -#[deriving(Clone, PartialEq)] -pub enum IKind { - IBool, - ISChar, - IUChar, - IShort, - IUShort, - IInt, - IUInt, - ILong, - IULong, - ILongLong, - IULongLong -} - -#[deriving(Clone, PartialEq)] -pub enum FKind { - FFloat, - FDouble -} - -#[deriving(Clone, PartialEq)] -pub struct CompInfo { - pub cstruct: bool, - pub name: String, - pub fields: Vec, - pub layout: Layout, -} - -impl CompInfo { - pub fn new(name: String, cstruct: bool, fields: Vec, layout: Layout) -> CompInfo { - CompInfo { - cstruct: cstruct, - name: name, - fields: fields, - layout: layout, - } - } -} - -impl fmt::Show for CompInfo { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.name.fmt(f) - } -} - -#[deriving(Clone, PartialEq)] -pub struct FieldInfo { - pub name: String, - pub ty: Type, - pub bit: Option, -} - -impl FieldInfo { - pub fn new(name: String, ty: Type, bit: Option) -> FieldInfo { - FieldInfo { - name: name, - ty: ty, - bit: bit, - } - } -} - -#[deriving(Clone, PartialEq)] -pub struct EnumInfo { - pub name: String, - pub items: Vec, - pub kind: IKind, - pub layout: Layout, -} - -impl EnumInfo { - pub fn new(name: String, kind: IKind, items: Vec, layout: Layout) -> EnumInfo { - EnumInfo { - name: name, - items: items, - kind: kind, - layout: layout, - } - } -} - -impl fmt::Show for EnumInfo { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.name.fmt(f) - } -} - -#[deriving(Clone, PartialEq)] -pub struct EnumItem { - pub name: String, - pub val: i64 -} - -impl EnumItem { - pub fn new(name: String, val: i64) -> EnumItem { - EnumItem { - name: name, - val: val - } - } -} - -#[deriving(Clone, PartialEq)] -pub struct TypeInfo { - pub name: String, - pub ty: Type -} - -impl TypeInfo { - pub fn new(name: String, ty: Type) -> TypeInfo { - TypeInfo { - name: name, - ty: ty - } - } -} - -impl fmt::Show for TypeInfo { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.name.fmt(f) - } -} - -#[deriving(Clone)] -pub struct VarInfo { - pub name: String, - pub ty: Type, - pub is_const: bool -} - -impl VarInfo { - pub fn new(name: String, ty: Type) -> VarInfo { - VarInfo { - name: name, - ty: ty, - is_const: false - } - } -} - -impl fmt::Show for VarInfo { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.name.fmt(f) - } -} -- cgit v1.2.3 From be87da264583de39344d5e53565c11969ee5b520 Mon Sep 17 00:00:00 2001 From: Alex Chandel Date: Sat, 5 Jul 2014 00:02:57 -0500 Subject: Set Travis CI to use Cargo --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 42df1e15..dff4eb1d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,9 +2,9 @@ before_install: - yes | sudo add-apt-repository "deb http://llvm.org/apt/precise/ llvm-toolchain-precise-3.4 main" - yes | sudo add-apt-repository "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu precise main" - yes | sudo add-apt-repository ppa:hansjorg/rust + - yes | sudo add-apt-repository ppa:cmrx64/cargo - sudo apt-get update install: - - sudo apt-get install --force-yes libclang-3.4-dev rust-nightly + - sudo apt-get install --force-yes libclang-3.4-dev rust-nightly cargo script: - - rustc lib.rs -L /usr/lib/llvm-3.4/lib - - rustc bindgen.rs -L /usr/lib/llvm-3.4/lib -L . + - cargo build -- cgit v1.2.3 From b36bdbbc6ab806c46822c9486a859fa8dead91d2 Mon Sep 17 00:00:00 2001 From: Alex Chandel Date: Sat, 5 Jul 2014 00:08:44 -0500 Subject: Fix binary src location for cargo build --- src/bin/bindgen.rs | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/bindgen.rs | 192 ----------------------------------------------------- 2 files changed, 192 insertions(+), 192 deletions(-) create mode 100644 src/bin/bindgen.rs delete mode 100644 src/bindgen.rs diff --git a/src/bin/bindgen.rs b/src/bin/bindgen.rs new file mode 100644 index 00000000..8e46057b --- /dev/null +++ b/src/bin/bindgen.rs @@ -0,0 +1,192 @@ +#![crate_id = "bindgen"] +#![crate_type = "bin"] +#![feature(phase)] + +extern crate bindgen; +#[phase(plugin, link)] extern crate log; +extern crate syntax; + +use bindgen::{Logger, generate_bindings, BindgenOptions}; +use std::{io, os, path}; +use std::default::Default; +use std::io::{fs, IoResult}; +use syntax::ast; +use syntax::codemap::DUMMY_SP; +use syntax::print::pprust; +use syntax::print::pp::eof; + +struct StdLogger; + +impl Logger for StdLogger { + fn error(&self, msg: &str) { + error!("{}", msg); + } + + fn warn(&self, msg: &str) { + warn!("{}", msg); + } +} + +enum ParseResult { + CmdUsage, + ParseOk(BindgenOptions, Box), + ParseErr(String) +} + +fn parse_args(args: &[String]) -> ParseResult { + let args_len = args.len(); + + let mut options: BindgenOptions = Default::default(); + let mut out = box io::BufferedWriter::new(io::stdout()) as Box; + + if args_len == 0u { + return CmdUsage; + } + + let mut ix = 0u; + while ix < args_len { + if args[ix].len() > 2 && args[ix].as_slice().slice_to(2) == "-l" { + options.links.push((args[ix].as_slice().slice_from(2).to_string(), None)); + ix += 1u; + } else { + match args[ix].as_slice() { + "--help" | "-h" => { + return CmdUsage; + } + "-emit-clang-ast" => { + options.emit_ast = true; + ix += 1u; + } + "-o" => { + if ix + 1u >= args_len { + return ParseErr("Missing output filename".to_string()); + } + let path = path::Path::new(args[ix + 1].clone()); + match fs::File::create(&path) { + Ok(f) => { out = box io::BufferedWriter::new(f) as Box; } + Err(_) => { return ParseErr(format!("Open {} failed", args[ix + 1])); } + } + ix += 2u; + } + "-l" => { + if ix + 1u >= args_len { + return ParseErr("Missing link name".to_string()); + } + options.links.push((args[ix + 1u].clone(), None)); + ix += 2u; + } + "-static-link" => { + if ix + 1u >= args_len { + return ParseErr("Missing link name".to_string()); + } + options.links.push((args[ix + 1u].clone(), Some("static".to_string()))); + ix += 2u; + } + "-framework-link" => { + if ix + 1u >= args_len { + return ParseErr("Missing link name".to_string()); + } + options.links.push((args[ix + 1u].clone(), Some("framework".to_string()))); + ix += 2u; + } + "-match" => { + if ix + 1u >= args_len { + return ParseErr("Missing match pattern".to_string()); + } + options.match_pat.push(args[ix + 1u].clone()); + ix += 2u; + } + "-builtins" => { + options.builtins = true; + ix += 1u; + } + "-abi" => { + options.abi = args[ix + 1u].clone(); + ix += 2u; + } + "-allow-bitfields" => { + options.fail_on_bitfield = false; + ix += 1u; + } + "-allow-unknown-types" => { + options.fail_on_unknown_type = false; + ix += 1u; + } + _ => { + options.clang_args.push(args[ix].clone()); + ix += 1u; + } + } + } + } + + return ParseOk(options, out); +} + +fn print_usage(bin: String) { + io::stdio::print(format!("Usage: {} [options] input.h", bin.as_slice()).append( +" +Options: + -h or --help Display help message + -l or -l Link to a dynamic library, can be proivded + multiple times + -static-link Link to a static library + -framework-link Link to a framework + -o Write bindings to (default stdout) + -match Only output bindings for definitions from files + whose name contains + If multiple -match options are provided, files + matching any rule are bound to. + -builtins Output bindings for builtin definitions + (for example __builtin_va_list) + -abi Indicate abi of extern functions (default C) + -allow-bitfields Don't fail if we encounter a bitfield + (note that bindgen does not support bitfields) + -allow-unknown-types Don't fail if we encounter types we do not support, + instead treat them as void + -emit-clang-ast Output the ast (for debugging purposes) + + Options other than stated above are passed to clang. +" + ).as_slice()); +} + +fn try_pprint(module: &ast::Mod, out: Box) -> IoResult<()> { + let mut ps = pprust::rust_printer(out); + try!(ps.s.out.write("/* automatically generated by rust-bindgen */\n\n".as_bytes())); + + try!(ps.print_mod(module, &[])); + try!(ps.print_remaining_comments()); + try!(eof(&mut ps.s)); + + ps.s.out.flush() +} + +#[main] +pub fn main() { + let mut bind_args = os::args(); + let bin = bind_args.shift().unwrap(); + + match parse_args(bind_args.as_slice()) { + ParseErr(e) => fail!(e), + CmdUsage => print_usage(bin), + ParseOk(options, out) => { + let logger = StdLogger; + match generate_bindings(options, Some(&logger as &Logger), DUMMY_SP) { + Ok(items) => { + let module = ast::Mod { + inner: DUMMY_SP, + view_items: Vec::new(), + items: items, + }; + + match try_pprint(&module, out) { + Err(e) => logger.error(format!("Unable to write bindings to file. {}", e).as_slice()), + _ => () + } + } + Err(_) => () + } + } + } +} diff --git a/src/bindgen.rs b/src/bindgen.rs deleted file mode 100644 index 8e46057b..00000000 --- a/src/bindgen.rs +++ /dev/null @@ -1,192 +0,0 @@ -#![crate_id = "bindgen"] -#![crate_type = "bin"] -#![feature(phase)] - -extern crate bindgen; -#[phase(plugin, link)] extern crate log; -extern crate syntax; - -use bindgen::{Logger, generate_bindings, BindgenOptions}; -use std::{io, os, path}; -use std::default::Default; -use std::io::{fs, IoResult}; -use syntax::ast; -use syntax::codemap::DUMMY_SP; -use syntax::print::pprust; -use syntax::print::pp::eof; - -struct StdLogger; - -impl Logger for StdLogger { - fn error(&self, msg: &str) { - error!("{}", msg); - } - - fn warn(&self, msg: &str) { - warn!("{}", msg); - } -} - -enum ParseResult { - CmdUsage, - ParseOk(BindgenOptions, Box), - ParseErr(String) -} - -fn parse_args(args: &[String]) -> ParseResult { - let args_len = args.len(); - - let mut options: BindgenOptions = Default::default(); - let mut out = box io::BufferedWriter::new(io::stdout()) as Box; - - if args_len == 0u { - return CmdUsage; - } - - let mut ix = 0u; - while ix < args_len { - if args[ix].len() > 2 && args[ix].as_slice().slice_to(2) == "-l" { - options.links.push((args[ix].as_slice().slice_from(2).to_string(), None)); - ix += 1u; - } else { - match args[ix].as_slice() { - "--help" | "-h" => { - return CmdUsage; - } - "-emit-clang-ast" => { - options.emit_ast = true; - ix += 1u; - } - "-o" => { - if ix + 1u >= args_len { - return ParseErr("Missing output filename".to_string()); - } - let path = path::Path::new(args[ix + 1].clone()); - match fs::File::create(&path) { - Ok(f) => { out = box io::BufferedWriter::new(f) as Box; } - Err(_) => { return ParseErr(format!("Open {} failed", args[ix + 1])); } - } - ix += 2u; - } - "-l" => { - if ix + 1u >= args_len { - return ParseErr("Missing link name".to_string()); - } - options.links.push((args[ix + 1u].clone(), None)); - ix += 2u; - } - "-static-link" => { - if ix + 1u >= args_len { - return ParseErr("Missing link name".to_string()); - } - options.links.push((args[ix + 1u].clone(), Some("static".to_string()))); - ix += 2u; - } - "-framework-link" => { - if ix + 1u >= args_len { - return ParseErr("Missing link name".to_string()); - } - options.links.push((args[ix + 1u].clone(), Some("framework".to_string()))); - ix += 2u; - } - "-match" => { - if ix + 1u >= args_len { - return ParseErr("Missing match pattern".to_string()); - } - options.match_pat.push(args[ix + 1u].clone()); - ix += 2u; - } - "-builtins" => { - options.builtins = true; - ix += 1u; - } - "-abi" => { - options.abi = args[ix + 1u].clone(); - ix += 2u; - } - "-allow-bitfields" => { - options.fail_on_bitfield = false; - ix += 1u; - } - "-allow-unknown-types" => { - options.fail_on_unknown_type = false; - ix += 1u; - } - _ => { - options.clang_args.push(args[ix].clone()); - ix += 1u; - } - } - } - } - - return ParseOk(options, out); -} - -fn print_usage(bin: String) { - io::stdio::print(format!("Usage: {} [options] input.h", bin.as_slice()).append( -" -Options: - -h or --help Display help message - -l or -l Link to a dynamic library, can be proivded - multiple times - -static-link Link to a static library - -framework-link Link to a framework - -o Write bindings to (default stdout) - -match Only output bindings for definitions from files - whose name contains - If multiple -match options are provided, files - matching any rule are bound to. - -builtins Output bindings for builtin definitions - (for example __builtin_va_list) - -abi Indicate abi of extern functions (default C) - -allow-bitfields Don't fail if we encounter a bitfield - (note that bindgen does not support bitfields) - -allow-unknown-types Don't fail if we encounter types we do not support, - instead treat them as void - -emit-clang-ast Output the ast (for debugging purposes) - - Options other than stated above are passed to clang. -" - ).as_slice()); -} - -fn try_pprint(module: &ast::Mod, out: Box) -> IoResult<()> { - let mut ps = pprust::rust_printer(out); - try!(ps.s.out.write("/* automatically generated by rust-bindgen */\n\n".as_bytes())); - - try!(ps.print_mod(module, &[])); - try!(ps.print_remaining_comments()); - try!(eof(&mut ps.s)); - - ps.s.out.flush() -} - -#[main] -pub fn main() { - let mut bind_args = os::args(); - let bin = bind_args.shift().unwrap(); - - match parse_args(bind_args.as_slice()) { - ParseErr(e) => fail!(e), - CmdUsage => print_usage(bin), - ParseOk(options, out) => { - let logger = StdLogger; - match generate_bindings(options, Some(&logger as &Logger), DUMMY_SP) { - Ok(items) => { - let module = ast::Mod { - inner: DUMMY_SP, - view_items: Vec::new(), - items: items, - }; - - match try_pprint(&module, out) { - Err(e) => logger.error(format!("Unable to write bindings to file. {}", e).as_slice()), - _ => () - } - } - Err(_) => () - } - } - } -} -- cgit v1.2.3