From bd73c086c16d3501d3ae93e59d102035a739c110 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Sat, 15 Feb 2020 00:52:22 -0800 Subject: [PATCH 01/88] Initial implementation of clang tooling API Bindgen builds and runs now, but does not produce any bindings yet. --- Cargo.lock | 10 + Cargo.toml | 3 + build.rs | 269 ++ src/clang.rs | 1081 +++--- src/clang/CMakeLists.txt | 64 + src/clang/ClangAST.cpp | 2593 ++++++++++++++ src/clang/ClangAST.hpp | 253 ++ src/clang/clangtool.rs | 7160 ++++++++++++++++++++++++++++++++++++++ src/ir/annotations.rs | 2 +- src/ir/comp.rs | 4 +- src/ir/context.rs | 106 +- src/ir/enum_ty.rs | 2 +- src/ir/function.rs | 21 +- src/ir/item.rs | 29 +- src/ir/module.rs | 2 +- src/ir/objc.rs | 16 +- src/ir/template.rs | 2 +- src/ir/ty.rs | 85 +- src/ir/var.rs | 4 +- src/lib.rs | 12 +- 20 files changed, 11149 insertions(+), 569 deletions(-) create mode 100644 src/clang/CMakeLists.txt create mode 100644 src/clang/ClangAST.cpp create mode 100644 src/clang/ClangAST.hpp create mode 100644 src/clang/clangtool.rs diff --git a/Cargo.lock b/Cargo.lock index 2898ae21de..4f2bb08f80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,6 +34,7 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -100,6 +101,14 @@ dependencies = [ "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cmake" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "diff" version = "0.1.11" @@ -335,6 +344,7 @@ dependencies = [ "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" "checksum env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39ecdb7dd54465526f0a56d666e3b2dd5f3a218665a030b6e4ad9e70fa95d8fa" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" diff --git a/Cargo.toml b/Cargo.toml index 5bdb3e8826..6051dca1d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,9 @@ diff = "0.1" clap = "2" shlex = "0.1" +[build-dependencies] +cmake = "0.1" + [dependencies] bitflags = "1.0.3" cexpr = "0.3.6" diff --git a/build.rs b/build.rs index acae6d6722..bdfa777120 100644 --- a/build.rs +++ b/build.rs @@ -1,3 +1,5 @@ +extern crate cmake; + mod target { use std::env; use std::fs::File; @@ -68,7 +70,274 @@ mod testgen { } } +mod clang_ast { + use std::env; + use std::ffi::OsStr; + use std::path::{Path, PathBuf}; + use std::process::{Command, Stdio}; + + pub fn main() { + let llvm_info = LLVMInfo::new(); + build_native(&llvm_info); + } + + /// Call out to CMake, build the clang ast library, and tell cargo where to look + /// for it. Note that `CMAKE_BUILD_TYPE` gets implicitly determined by the + /// cmake crate according to the following: + /// + /// - if `opt-level=0` then `CMAKE_BUILD_TYPE=Debug` + /// - if `opt-level={1,2,3}` and not `debug=false`, then `CMAKE_BUILD_TYPE=RelWithDebInfo` + fn build_native(llvm_info: &LLVMInfo) { + // Find where the (already built) LLVM lib dir is + let llvm_lib_dir = &llvm_info.lib_dir; + + println!("cargo:rerun-if-changed=src/clang/ClangAST.cpp"); + println!("cargo:rerun-if-changed=src/clang/ClangAST.hpp"); + // Build libclangAst.a with cmake + let dst = cmake::Config::new("src/clang") + // Where to find LLVM/Clang CMake files + .define("LLVM_DIR", &format!("{}/cmake/llvm", llvm_lib_dir)) + .define("Clang_DIR", &format!("{}/cmake/clang", llvm_lib_dir)) + // What to build + .build_target("clangAst") + .build(); + + let out_dir = dst.display(); + + // Set up search path for newly built libclangAst.a + println!("cargo:rustc-link-search=native={}/build/lib", out_dir); + println!("cargo:rustc-link-search=native={}/build", out_dir); + + // Statically link against 'clangAst' + println!("cargo:rustc-link-lib=static=clangAst"); + + // Link against these Clang libs. The ordering here is important! Libraries + // must be listed before their dependencies when statically linking. + println!("cargo:rustc-link-search=native={}", llvm_lib_dir); + for lib in &[ + "clangIndex", + "clangTooling", + "clangFrontend", + "clangASTMatchers", + "clangParse", + "clangSerialization", + "clangSema", + "clangEdit", + "clangAnalysis", + "clangDriver", + "clangFormat", + "clangToolingCore", + "clangAST", + "clangRewrite", + "clangLex", + "clangBasic", + ] { + println!("cargo:rustc-link-lib={}", lib); + } + + for lib in &llvm_info.libs { + // IMPORTANT: We cannot specify static= or dylib= here because rustc + // will reorder those libs before the clang libs above which don't have + // static or dylib. + println!("cargo:rustc-link-lib={}", lib); + } + + // Link against the C++ std library. + if cfg!(target_os = "macos") { + println!("cargo:rustc-link-lib=c++"); + } else { + println!("cargo:rustc-link-lib=stdc++"); + } + } + + /// Holds information about LLVM paths we have found + struct LLVMInfo { + /// LLVM lib dir containing libclang* and libLLVM* libraries + pub lib_dir: String, + + /// List of libs we need to link against + pub libs: Vec, + } + + impl LLVMInfo { + fn new() -> Self { + fn find_llvm_config() -> Option { + // Explicitly provided path in LLVM_CONFIG_PATH + env::var("LLVM_CONFIG_PATH") + .ok() + // Relative to LLVM_LIB_DIR + .or(env::var("LLVM_LIB_DIR").ok().map(|d| { + String::from( + Path::new(&d) + .join("../bin/llvm-config") + .canonicalize() + .unwrap() + .to_string_lossy(), + ) + })) + // In PATH + .or([ + "llvm-config-7.0", + "llvm-config-6.1", + "llvm-config-6.0", + "llvm-config", + // Homebrew install location on MacOS + "/usr/local/opt/llvm/bin/llvm-config", + ] + .iter() + .find_map(|c| { + if Command::new(c) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn() + .is_ok() + { + Some(String::from(*c)) + } else { + None + } + })) + } + + /// Invoke given `command`, if any, with the specified arguments. + fn invoke_command(command: Option<&String>, args: I) -> Option + where + I: IntoIterator, + S: AsRef, + { + command.and_then(|c| { + Command::new(c).args(args).output().ok().and_then(|output| { + if output.status.success() { + Some(String::from_utf8_lossy(&output.stdout).trim().to_string()) + } else { + None + } + }) + }) + } + + let llvm_config = find_llvm_config(); + let lib_dir = { + let path_str = env::var("LLVM_LIB_DIR") + .ok() + .or(invoke_command(llvm_config.as_ref(), &["--libdir"])) + .expect( + " +Couldn't find LLVM lib dir. Try setting the `LLVM_LIB_DIR` environment +variable or make sure `llvm-config` is on $PATH then re-build. For example: + + $ export LLVM_LIB_DIR=/usr/local/opt/llvm/lib +", + ); + String::from( + Path::new(&path_str) + .canonicalize() + .unwrap() + .to_string_lossy(), + ) + }; + + let llvm_shared_libs = invoke_command(llvm_config.as_ref(), &["--libs", "--link-shared"]); + + // /lib/rustlib//lib/ contains a libLLVM DSO for the + // rust compiler. On MacOS, this lib is named libLLVM.dylib, which will + // always conflict with the dylib we are trying to link against. On + // Linux we generally will not hit this issue because the prebuilt lib + // includes the `svn` suffix. This would conflict with a source build + // from master, however. + // + // We check here if the lib we want to link against will conflict with + // the rustlib version. If so we can't dynamically link against libLLVM. + let conflicts_with_rustlib_llvm = { + if let Some(llvm_shared_libs) = llvm_shared_libs.as_ref() { + let dylib_suffix = { + if cfg!(target_os = "macos") { + ".dylib" + } else { + ".so" + } // Windows is not supported + }; + let mut dylib_file = String::from("lib"); + dylib_file.push_str(llvm_shared_libs.trim_start_matches("-l")); + dylib_file.push_str(dylib_suffix); + let sysroot = + invoke_command(env::var("RUSTC").ok().as_ref(), &["--print=sysroot"]).unwrap(); + + // Does /lib/rustlib//lib/ exist? + let mut libllvm_path = PathBuf::new(); + libllvm_path.push(sysroot); + libllvm_path.push("lib/rustlib"); + libllvm_path.push(env::var("TARGET").unwrap()); + libllvm_path.push("lib"); + libllvm_path.push(dylib_file); + + libllvm_path.as_path().exists() + } else { + false + } + }; + + let link_statically = cfg!(feature = "llvm-static") || { + let args = if conflicts_with_rustlib_llvm { + vec!["--shared-mode", "--ignore-libllvm"] + } else { + vec!["--shared-mode"] + }; + invoke_command(llvm_config.as_ref(), &args).map_or(false, |c| c == "static") + }; + + let link_mode = if link_statically { + "--link-static" + } else { + "--link-shared" + }; + + // Construct the list of libs we need to link against + let mut libs: Vec = invoke_command( + llvm_config.as_ref(), + &[ + "--libs", + link_mode, + "MC", + "MCParser", + "Support", + "Option", + "BitReader", + "ProfileData", + "BinaryFormat", + "Core", + ], + ) + .unwrap_or("-lLLVM".to_string()) + .split_whitespace() + .map(|lib| String::from(lib.trim_start_matches("-l"))) + .collect(); + + libs.extend( + env::var("LLVM_SYSTEM_LIBS") + .ok() + .or(invoke_command( + llvm_config.as_ref(), + &[ + "--system-libs", + link_mode, + ], + )) + .unwrap_or(String::new()) + .split_whitespace() + .map(|lib| String::from(lib.trim_start_matches("-l"))) + ); + + Self { + lib_dir, + libs, + } + } + } +} + fn main() { target::main(); testgen::main(); + clang_ast::main() } diff --git a/src/clang.rs b/src/clang.rs index 4bcc4b4ac4..064870b677 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -5,24 +5,122 @@ use cexpr; -use clang_sys::*; use ir::context::BindgenContext; use regex; use std::ffi::{CStr, CString}; use std::fmt; use std::hash::Hash; -use std::hash::Hasher; +// use std::hash::Hasher; use std::os::raw::{c_char, c_int, c_longlong, c_uint, c_ulong, c_ulonglong}; use std::{mem, ptr, slice}; +#[allow(non_camel_case_types, non_snake_case)] +mod clangtool; +pub use self::clangtool::CXDiagnosticSeverity::Type as CXDiagnosticSeverity; +pub use self::clangtool::CXCallingConv::Type as CXCallingConv; +pub use self::clangtool::CXLinkageKind::Type as CXLinkageKind; +pub use self::clangtool::CX_CXXAccessSpecifier::Type as CX_CXXAccessSpecifier; +pub use self::clangtool::CXEvalResultKind::Type as CXEvalResultKind; +pub use self::clangtool::CXTokenKind::Type as CXTokenKind; +pub use self::clangtool::CXVisibilityKind::Type as CXVisibilityKind; +pub use self::clangtool::CXChildVisitResult::Type as CXChildVisitResult; +pub use self::clangtool::CXCursorKind::Type as CXCursorKind; +pub use self::clangtool::CXTypeKind::Type as CXTypeKind; +pub use self::clangtool::CXCommentKind::*; +pub use self::clangtool::CXDiagnosticSeverity::*; +pub use self::clangtool::CXCallingConv::*; +pub use self::clangtool::CX_CXXAccessSpecifier::*; +pub use self::clangtool::CXChildVisitResult::*; +pub use self::clangtool::CXCursorKind::*; +pub use self::clangtool::CXEvalResultKind::*; +pub use self::clangtool::CXLinkageKind::*; +pub use self::clangtool::CXTypeKind::*; +pub use self::clangtool::CXTokenKind::*; +pub use self::clangtool::CXVisitorResult::*; +pub use self::clangtool::CXVisibilityKind::*; + +impl clangtool::BindgenSourceRange { + fn null() -> Self { + Self { B: ptr::null_mut(), E: ptr::null_mut() } + } +} + +trait ToCString { + fn to_cstring(&self) -> CString; +} + +impl ToCString for clangtool::BindgenStringRef { + fn to_cstring(&self) -> CString { + if !self.s.is_null() { + unsafe { CString::from_raw(clangtool::cString(*self)) } + } else { + return CString::new("").unwrap(); + } + } +} + +impl fmt::Display for clangtool::BindgenStringRef { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let str = self.to_cstring(); + write!(f, "{}", str.to_str().unwrap()) + } +} + /// A cursor into the Clang AST, pointing to an AST node. /// /// We call the AST node pointed to by the cursor the cursor's "referent". -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Cursor { - x: CXCursor, + node: ASTNode, + unit: *mut clangtool::clang_ASTUnit, } +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub enum ASTNode { + Invalid, + Decl(*const clangtool::clang_Decl), + Expr(*const clangtool::clang_Expr), + CXXBaseSpecifier(*const clangtool::clang_CXXBaseSpecifier), +} + +impl ASTNode { + /// Is this node valid? + fn is_valid(&self) -> bool { + unsafe { !clangtool::CursorKind_isInvalid(self.kind()) } + } + + fn kind(&self) -> CXCursorKind { + unsafe { + match *self { + ASTNode::Decl(d) => clangtool::Decl_getCXCursorKind(d), + ASTNode::Expr(e) => clangtool::Expr_getCXCursorKind(e), + ASTNode::Invalid => CXCursor_InvalidFile, + ASTNode::CXXBaseSpecifier(_) => CXCursor_CXXBaseSpecifier, + } + } + } + +} + +// impl PartialEq for clangtool::BindgenNode { +// fn eq(&self, other: &Self) -> bool { +// ptr::eq(self.node, other.node) +// && ptr::eq(self.context, other.context) +// } +// } + +// impl Eq for clangtool::BindgenNode { +// } + +// impl Hash for clangtool::BindgenNode { +// fn hash(&self, state: &mut H) +// where H: Hasher +// { +// self.node.hash(state); +// self.context.hash(state); +// } +// } + impl fmt::Debug for Cursor { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!( @@ -37,13 +135,23 @@ impl fmt::Debug for Cursor { } impl Cursor { + fn context(&self) -> *mut clangtool::clang_ASTContext { + unsafe { clangtool::ASTUnit_getContext(self.unit) } + } + /// Get the Unified Symbol Resolution for this cursor's referent, if /// available. /// /// The USR can be used to compare entities across translation units. pub fn usr(&self) -> Option { - let s = unsafe { cxstring_into_string(clang_getCursorUSR(self.x)) }; - if s.is_empty() { + let s = unsafe { + match self.node { + ASTNode::Decl(d) => clangtool::Decl_getUSR(d), + _ => return None, + } + }; + let s = s.to_string(); + if s.len() == 0 { None } else { Some(s) @@ -52,51 +160,63 @@ impl Cursor { /// Is this cursor's referent a declaration? pub fn is_declaration(&self) -> bool { - unsafe { clang_isDeclaration(self.kind()) != 0 } + match self.node { + ASTNode::Decl(_) => true, + _ => false, + } } /// Get this cursor's referent's spelling. pub fn spelling(&self) -> String { - unsafe { cxstring_into_string(clang_getCursorSpelling(self.x)) } + unsafe { + match self.node { + ASTNode::Decl(d) => clangtool::Decl_getSpelling(d).to_string(), + ASTNode::Expr(e) => clangtool::Expr_getSpelling(e).to_string(), + _ => String::new(), + } + } } - /// Get this cursor's referent's display name. - /// - /// This is not necessarily a valid identifier. It includes extra - /// information, such as parameters for a function, etc. - pub fn display_name(&self) -> String { - unsafe { cxstring_into_string(clang_getCursorDisplayName(self.x)) } - } + // /// Get this cursor's referent's display name. + // /// + // /// This is not necessarily a valid identifier. It includes extra + // /// information, such as parameters for a function, etc. + // pub fn display_name(&self) -> String { + // unsafe { + // match self.node { + // ASTNode::Decl(d) => clangtool::Decl_getDisplayName(d).to_string(), + // ASTNode::Expr(e) => clangtool::Expr_getDisplayName(e).to_string(), + // _ => String::new(), + // } + // } + // } /// Get the mangled name of this cursor's referent. pub fn mangling(&self) -> String { - if clang_Cursor_getMangling::is_loaded() { - unsafe { cxstring_into_string(clang_Cursor_getMangling(self.x)) } - } else { - self.spelling() + unsafe { + match self.node { + ASTNode::Decl(d) => clangtool::Decl_getMangling(d, self.context()).to_string(), + _ => String::new(), + } } } /// Gets the C++ manglings for this cursor, or an error if the function is /// not loaded or the manglings are not available. pub fn cxx_manglings(&self) -> Result, ()> { - use clang_sys::*; - if !clang_Cursor_getCXXManglings::is_loaded() { - return Err(()); - } unsafe { - let manglings = clang_Cursor_getCXXManglings(self.x); - if manglings.is_null() { - return Err(()); - } - let count = (*manglings).Count as usize; + let manglings = match self.node { + ASTNode::Decl(d) => clangtool::Decl_getCXXManglings(d, self.context()), + _ => return Err(()), + }; + let count = manglings.len as usize; let mut result = Vec::with_capacity(count); for i in 0..count { - let string_ptr = (*manglings).Strings.offset(i as isize); - result.push(cxstring_to_string_leaky(*string_ptr)); + let string_ptr = manglings.strings.offset(i as isize); + result.push((*string_ptr).to_string()); } - clang_disposeStringSet(manglings); + // clang_disposeStringSet(manglings); Ok(result) } } @@ -125,10 +245,15 @@ impl Cursor { /// void Foo::method() { /* ... */ } /// ``` pub fn lexical_parent(&self) -> Cursor { - unsafe { - Cursor { - x: clang_getCursorLexicalParent(self.x), - } + let node = match self.node { + ASTNode::Decl(d) => unsafe { + ASTNode::Decl(clangtool::Decl_getLexicalParent(d)) + }, + _ => ASTNode::Invalid, + }; + Cursor { + node, + unit: self.unit, } } @@ -137,15 +262,20 @@ impl Cursor { /// See documentation for `lexical_parent` for details on semantic vs /// lexical parents. pub fn fallible_semantic_parent(&self) -> Option { - let sp = unsafe { - Cursor { - x: clang_getCursorSemanticParent(self.x), - } + let node = match self.node { + ASTNode::Decl(d) => unsafe { + ASTNode::Decl(clangtool::Decl_getSemanticParent(d)) + }, + ASTNode::Expr(e) => panic!("Unimplemented for Expr"), + _ => return None, }; - if sp == *self || !sp.is_valid() { + if node == self.node || !node.is_valid() { return None; } - Some(sp) + Some(Cursor { + node, + unit: self.unit, + }) } /// Get the referent's semantic parent. @@ -167,11 +297,16 @@ impl Cursor { // `clang_Cursor_getNumTemplateArguments` is totally unreliable. // Therefore, try former first, and only fallback to the latter if we // have to. + let decl = if let ASTNode::Decl(decl) = self.node { + decl + } else { + return None; + }; self.cur_type() .num_template_args() .or_else(|| { - let n: c_int = - unsafe { clang_Cursor_getNumTemplateArguments(self.x) }; + let n: c_int = + unsafe { clangtool::Decl_getNumTemplateArguments(decl) }; if n >= 0 { Some(n as u32) @@ -196,16 +331,8 @@ impl Cursor { /// bindgen assumes there will only be one of them alive at a time, and /// disposes it on drop. That can change if this would be required, but I /// think we can survive fine without it. - pub fn translation_unit(&self) -> Cursor { - assert!(self.is_valid()); - unsafe { - let tu = clang_Cursor_getTranslationUnit(self.x); - let cursor = Cursor { - x: clang_getTranslationUnitCursor(tu), - }; - assert!(cursor.is_valid()); - cursor - } + pub fn translation_unit(&self) -> *mut clangtool::clang_ASTUnit { + self.unit } /// Is the referent a top level construct? @@ -214,15 +341,20 @@ impl Cursor { while semantic_parent.is_some() && (semantic_parent.unwrap().kind() == CXCursor_Namespace || - semantic_parent.unwrap().kind() == - CXCursor_NamespaceAlias || + semantic_parent.unwrap().kind() == + CXCursor_NamespaceAlias || semantic_parent.unwrap().kind() == CXCursor_NamespaceRef) { semantic_parent = semantic_parent.unwrap().fallible_semantic_parent(); } - let tu = self.translation_unit(); + let tu = Cursor { + node: ASTNode::Decl(unsafe { + clangtool::getTranslationUnitDecl(self.unit) + }), + unit: self.unit, + }; // Yes, this can happen with, e.g., macro definitions. semantic_parent == tu.fallible_semantic_parent() } @@ -241,12 +373,17 @@ impl Cursor { /// Get the kind of referent this cursor is pointing to. pub fn kind(&self) -> CXCursorKind { - self.x.kind + self.node.kind() } /// Returns true is the cursor is a definition pub fn is_definition(&self) -> bool { - unsafe { clang_isCursorDefinition(self.x) != 0 } + match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::Decl_isDefinition(d) + }, + _ => false, + } } /// Is the referent a template specialization? @@ -283,27 +420,39 @@ impl Cursor { /// Is this cursor pointing a valid referent? pub fn is_valid(&self) -> bool { - unsafe { clang_isInvalid(self.kind()) == 0 } + self.node.is_valid() } /// Get the source location for the referent. pub fn location(&self) -> SourceLocation { unsafe { - SourceLocation { - x: clang_getCursorLocation(self.x), - } + let x = match self.node { + ASTNode::Decl(d) => clangtool::Decl_getLocation(d), + ASTNode::Expr(e) => clangtool::Expr_getLocation(e), + _ => ptr::null(), + }; + SourceLocation { x, unit: self.unit } } } /// Get the source location range for the referent. - pub fn extent(&self) -> CXSourceRange { - unsafe { clang_getCursorExtent(self.x) } + pub fn extent(&self) -> clangtool::BindgenSourceRange { + unsafe { + match self.node { + ASTNode::Decl(d) => clangtool::Decl_getSourceRange(d), + ASTNode::Expr(e) => clangtool::Expr_getSourceRange(e), + _ => clangtool::BindgenSourceRange::null(), + } + } } /// Get the raw declaration comment for this referent, if one exists. pub fn raw_comment(&self) -> Option { - let s = unsafe { - cxstring_into_string(clang_Cursor_getRawCommentText(self.x)) + let s = match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::Decl_getRawCommentText(d, self.context()).to_string() + }, + _ => return None, }; if s.is_empty() { None @@ -314,19 +463,24 @@ impl Cursor { /// Get the referent's parsed comment. pub fn comment(&self) -> Comment { - unsafe { - Comment { - x: clang_Cursor_getParsedComment(self.x), - } - } + let x = match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::Decl_getParsedComment(d, self.context()) + }, + _ => ptr::null(), + }; + Comment { x } } /// Get the referent's type. pub fn cur_type(&self) -> Type { unsafe { - Type { - x: clang_getCursorType(self.x), - } + let x = match self.node { + ASTNode::Decl(d) => clangtool::Decl_getType(d, self.context()), + ASTNode::Expr(e) => clangtool::Expr_getType(e), + _ => mem::zeroed(), + }; + Type { x, unit: self.unit } } } @@ -334,32 +488,38 @@ impl Cursor { /// a declaration, get the cursor pointing to the referenced type or type of /// the declared thing. pub fn definition(&self) -> Option { - unsafe { - let ret = Cursor { - x: clang_getCursorDefinition(self.x), - }; - - if ret.is_valid() && ret.kind() != CXCursor_NoDeclFound { - Some(ret) - } else { - None - } + let def = match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::Decl_getDefinition(d) + }, + _ => return None, + }; + if def.is_null() { + None + } else { + Some(Cursor { + node: ASTNode::Decl(def), + unit: self.unit, + }) } } /// Given that this cursor's referent is reference type, get the cursor /// pointing to the referenced type. pub fn referenced(&self) -> Option { - unsafe { - let ret = Cursor { - x: clang_getCursorReferenced(self.x), - }; - - if ret.is_valid() { - Some(ret) - } else { - None - } + match self.node { + ASTNode::Decl(d) => unsafe { + let ptr = clangtool::Decl_getReferenced(d); + if ptr.is_null() { + None + } else { + Some(Cursor { + node: ASTNode::Decl(ptr), + unit: self.unit, + }) + } + }, + _ => return None, } } @@ -369,10 +529,15 @@ impl Cursor { /// defined. This method allows us to get the canonical cursor for the /// referent type. pub fn canonical(&self) -> Cursor { - unsafe { - Cursor { - x: clang_getCanonicalCursor(self.x), - } + let node = match self.node { + ASTNode::Decl(d) => unsafe { + ASTNode::Decl(clangtool::Decl_getCanonical(d)) + }, + _ => ASTNode::Invalid, + }; + Cursor { + node, + unit: self.unit, } } @@ -380,22 +545,31 @@ impl Cursor { /// template instantiation, get a cursor pointing to the template definition /// that is being specialized. pub fn specialized(&self) -> Option { - unsafe { - let ret = Cursor { - x: clang_getSpecializedCursorTemplate(self.x), - }; - if ret.is_valid() { - Some(ret) - } else { - None - } + match self.node { + ASTNode::Decl(d) => unsafe { + let ptr = clangtool::Decl_getSpecializedTemplate(d); + if ptr.is_null() { + None + } else { + Some(Cursor { + node: ASTNode::Decl(ptr), + unit: self.unit, + }) + } + }, + _ => None, } } /// Assuming that this cursor's referent is a template declaration, get the /// kind of cursor that would be generated for its specializations. pub fn template_kind(&self) -> CXCursorKind { - unsafe { clang_getTemplateCursorKind(self.x) } + match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::Decl_getTemplateCursorKind(d) + }, + _ => CXCursor_NoDeclFound, + } } /// Traverse this cursor's referent and its children. @@ -405,12 +579,24 @@ impl Cursor { where Visitor: FnMut(Cursor) -> CXChildVisitResult, { - unsafe { - clang_visitChildren( - self.x, - visit_children::, - mem::transmute(&mut visitor), - ); + match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::Decl_visitChildren( + d, + Some(visit_children::), + self.unit, + mem::transmute(&mut visitor), + ); + } + ASTNode::Expr(e) => unsafe { + clangtool::Expr_visitChildren( + e, + Some(visit_children::), + self.unit, + mem::transmute(&mut visitor), + ); + } + _ => {} } } @@ -469,35 +655,43 @@ impl Cursor { /// Is the referent an inlined function? pub fn is_inlined_function(&self) -> bool { - clang_Cursor_isFunctionInlined::is_loaded() && - unsafe { clang_Cursor_isFunctionInlined(self.x) != 0 } + match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::Decl_isFunctionInlined(d) + }, + _ => false, + } } /// Get the width of this cursor's referent bit field, or `None` if the /// referent is not a bit field. pub fn bit_width(&self) -> Option { - unsafe { - let w = clang_getFieldDeclBitWidth(self.x); - if w == -1 { - None - } else { - Some(w as u32) - } + let w = match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::Decl_getFieldDeclBitWidth(d, self.context()) + }, + _ => -1, + }; + if w == -1 { + None + } else { + Some(w as u32) } } /// Get the integer representation type used to hold this cursor's referent /// enum type. pub fn enum_type(&self) -> Option { - unsafe { - let t = Type { - x: clang_getEnumDeclIntegerType(self.x), - }; - if t.is_valid() { - Some(t) - } else { - None + let x = unsafe { + match self.node { + ASTNode::Decl(d) => clangtool::Decl_getEnumDeclIntegerType(d), + _ => mem::zeroed(), } + }; + if x.ptr.is_null() { + None + } else { + Some(Type { x, unit: self.unit }) } } @@ -505,12 +699,11 @@ impl Cursor { /// /// Returns None if the cursor's referent is not an enum variant. pub fn enum_val_signed(&self) -> Option { - unsafe { - if self.kind() == CXCursor_EnumConstantDecl { - Some(clang_getEnumConstantDeclValue(self.x) as i64) - } else { - None + match self.node { + ASTNode::Decl(d) => unsafe { + Some(clangtool::Decl_getEnumConstantValue(d)) } + _ => None, } } @@ -518,12 +711,11 @@ impl Cursor { /// /// Returns None if the cursor's referent is not an enum variant. pub fn enum_val_unsigned(&self) -> Option { - unsafe { - if self.kind() == CXCursor_EnumConstantDecl { - Some(clang_getEnumConstantDeclUnsignedValue(self.x) as u64) - } else { - None + match self.node { + ASTNode::Decl(d) => unsafe { + Some(clangtool::Decl_getEnumConstantUnsignedValue(d)) } + _ => None, } } @@ -561,14 +753,12 @@ impl Cursor { /// Given that this cursor's referent is a `typedef`, get the `Type` that is /// being aliased. pub fn typedef_type(&self) -> Option { - let inner = Type { - x: unsafe { clang_getTypedefDeclUnderlyingType(self.x) }, - }; - - if inner.is_valid() { - Some(inner) - } else { - None + match self.node { + ASTNode::Decl(d) => Some(Type { + x: unsafe { clangtool::Decl_getTypedefDeclUnderlyingType(d) }, + unit: self.unit, + }), + _ => None, } } @@ -576,15 +766,17 @@ impl Cursor { /// /// This only applies to functions and variables. pub fn linkage(&self) -> CXLinkageKind { - unsafe { clang_getCursorLinkage(self.x) } + match self.node { + ASTNode::Decl(d) => unsafe { clangtool::Decl_getLinkage(d) }, + _ => CXLinkage_Invalid, + } } /// Get the visibility of this cursor's referent. pub fn visibility(&self) -> CXVisibilityKind { - if clang_getCursorVisibility::is_loaded() { - unsafe { clang_getCursorVisibility(self.x) } - } else { - CXVisibility_Default + match self.node { + ASTNode::Decl(d) => unsafe { clangtool::Decl_getVisibility(d) }, + _ => CXVisibility_Invalid, } } @@ -599,8 +791,20 @@ impl Cursor { // CXCursor_CXXMethod => { self.num_args().ok().map(|num| { (0..num) - .map(|i| Cursor { - x: unsafe { clang_Cursor_getArgument(self.x, i as c_uint) }, + .map(|i| { + let node = match self.node { + ASTNode::Decl(d) => unsafe { + ASTNode::Decl(clangtool::Decl_getArgument(d, i as c_uint)) + }, + ASTNode::Expr(e) => unsafe { + ASTNode::Expr(clangtool::Expr_getArgument(e, i as c_uint)) + }, + _ => ASTNode::Invalid, + }; + Cursor { + node, + unit: self.unit, + } }) .collect() }) @@ -612,36 +816,52 @@ impl Cursor { /// Returns Err if the cursor's referent is not a function/method call or /// declaration. pub fn num_args(&self) -> Result { - unsafe { - let w = clang_Cursor_getNumArguments(self.x); - if w == -1 { - Err(()) - } else { - Ok(w as u32) - } + let w = match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::Decl_getNumArguments(d) + }, + ASTNode::Expr(e) => unsafe { + clangtool::Expr_getNumArguments(e) + }, + _ => -1, + }; + if w == -1 { + Err(()) + } else { + Ok(w as u32) } } /// Get the access specifier for this cursor's referent. pub fn access_specifier(&self) -> CX_CXXAccessSpecifier { - unsafe { clang_getCXXAccessSpecifier(self.x) } + match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::Decl_getAccess(d) + }, + // TODO(sjc): handle CXXBaseSpecifier cursors + _ => CX_CXXInvalidAccessSpecifier, + } } /// Is this cursor's referent a field declaration that is marked as /// `mutable`? pub fn is_mutable_field(&self) -> bool { - clang_CXXField_isMutable::is_loaded() && - unsafe { clang_CXXField_isMutable(self.x) != 0 } + match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::CXXField_isMutable(d) + }, + _ => false, + } } /// Get the offset of the field represented by the Cursor. pub fn offset_of_field(&self) -> Result { - if !clang_Cursor_getOffsetOfField::is_loaded() { - return Err(LayoutError::from(-1)); - } - - let offset = unsafe { clang_Cursor_getOffsetOfField(self.x) }; - + let offset = match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::Decl_getOffsetOfField(d, self.context()) + }, + _ => -1, + }; if offset < 0 { Err(LayoutError::from(offset as i32)) } else { @@ -651,43 +871,94 @@ impl Cursor { /// Is this cursor's referent a member function that is declared `static`? pub fn method_is_static(&self) -> bool { - unsafe { clang_CXXMethod_isStatic(self.x) != 0 } + match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::CXXMethod_isStatic(d) + }, + _ => false, + } } /// Is this cursor's referent a member function that is declared `const`? pub fn method_is_const(&self) -> bool { - unsafe { clang_CXXMethod_isConst(self.x) != 0 } + match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::CXXMethod_isConst(d) + }, + _ => false, + } } /// Is this cursor's referent a member function that is virtual? pub fn method_is_virtual(&self) -> bool { - unsafe { clang_CXXMethod_isVirtual(self.x) != 0 } + match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::CXXMethod_isVirtual(d) + }, + _ => false, + } } /// Is this cursor's referent a member function that is pure virtual? pub fn method_is_pure_virtual(&self) -> bool { - unsafe { clang_CXXMethod_isPureVirtual(self.x) != 0 } + match self.node { + ASTNode::Decl(d) => unsafe { + clangtool::CXXMethod_isPureVirtual(d) + }, + _ => false, + } } /// Is this cursor's referent a struct or class with virtual members? pub fn is_virtual_base(&self) -> bool { - unsafe { clang_isVirtualBase(self.x) != 0 } + match self.node { + ASTNode::CXXBaseSpecifier(b) => unsafe { + clangtool::CXXBaseSpecifier_isVirtualBase(b) + }, + _ => false, + } } /// Try to evaluate this cursor. pub fn evaluate(&self) -> Option { - EvalResult::new(*self) + // Work around https://bugs.llvm.org/show_bug.cgi?id=42532, see: + // * https://github.com/rust-lang/rust-bindgen/issues/283 + // * https://github.com/rust-lang/rust-bindgen/issues/1590 + { + let mut found_cant_eval = false; + self.visit(|c| { + if c.kind() == CXCursor_TypeRef && + c.cur_type().canonical_type().kind() == CXType_Unexposed + { + found_cant_eval = true; + return CXChildVisit_Break; + } + + CXChildVisit_Recurse + }); + + if found_cant_eval { + return None; + } + } + unsafe { + let x = match self.node { + ASTNode::Decl(d) => clangtool::Decl_Evaluate(d, self.context()), + ASTNode::Expr(e) => clangtool::Expr_Evaluate(e, self.context()), + _ => return None, + }; + Some(EvalResult { x }) + } } /// Return the result type for this cursor pub fn ret_type(&self) -> Option { - let rt = Type { - x: unsafe { clang_getCursorResultType(self.x) }, - }; - if rt.is_valid() { - Some(rt) - } else { - None + match self.node { + ASTNode::Decl(d) => Some(Type { + x: unsafe { clangtool::Decl_getResultType(d, self.context()) }, + unit: self.unit, + }), + _ => None, } } @@ -729,22 +1000,24 @@ impl Cursor { /// /// Returns None if the cursor does not include a file, otherwise the file's full name pub fn get_included_file_name(&self) -> Option { - let file = unsafe { clang_sys::clang_getIncludedFile(self.x) }; - if file.is_null() { - None - } else { - Some(unsafe { - cxstring_into_string(clang_sys::clang_getFileName(file)) - }) - } + // TODO(sjc): implement + None + // let file = unsafe { clang_sys::clang_getIncludedFile(self.x) }; + // if file.is_null() { + // None + // } else { + // Some(unsafe { + // cxstring_into_string(clang_sys::clang_getFileName(file)) + // }) + // } } } /// A struct that owns the tokenizer result from a given cursor. pub struct RawTokens<'a> { cursor: &'a Cursor, - tu: CXTranslationUnit, - tokens: *mut CXToken, + tu: *mut clangtool::clang_ASTUnit, + tokens: *mut clangtool::CXToken, token_count: c_uint, } @@ -753,8 +1026,8 @@ impl<'a> RawTokens<'a> { let mut tokens = ptr::null_mut(); let mut token_count = 0; let range = cursor.extent(); - let tu = unsafe { clang_Cursor_getTranslationUnit(cursor.x) }; - unsafe { clang_tokenize(tu, range, &mut tokens, &mut token_count) }; + let tu = cursor.translation_unit(); + unsafe { clangtool::tokenize(tu, range, &mut tokens, &mut token_count) }; Self { cursor, tu, @@ -763,7 +1036,7 @@ impl<'a> RawTokens<'a> { } } - fn as_slice(&self) -> &[CXToken] { + fn as_slice(&self) -> &[clangtool::CXToken] { if self.tokens.is_null() { return &[]; } @@ -783,7 +1056,7 @@ impl<'a> Drop for RawTokens<'a> { fn drop(&mut self) { if !self.tokens.is_null() { unsafe { - clang_disposeTokens( + clangtool::disposeTokens( self.tu, self.tokens, self.token_count as c_uint, @@ -798,7 +1071,7 @@ impl<'a> Drop for RawTokens<'a> { /// string. #[derive(Debug)] pub struct ClangToken { - spelling: CXString, + spelling: CString, /// The kind of token, this is the same as the relevant member from /// `CXToken`. pub kind: CXTokenKind, @@ -807,23 +1080,14 @@ pub struct ClangToken { impl ClangToken { /// Get the token spelling, without being converted to utf-8. pub fn spelling(&self) -> &[u8] { - let c_str = unsafe { - CStr::from_ptr(clang_getCString(self.spelling) as *const _) - }; - c_str.to_bytes() - } -} - -impl Drop for ClangToken { - fn drop(&mut self) { - unsafe { clang_disposeString(self.spelling) } + self.spelling.to_bytes() } } /// An iterator over a set of Tokens. pub struct ClangTokenIterator<'a> { - tu: CXTranslationUnit, - raw: slice::Iter<'a, CXToken>, + tu: *mut clangtool::clang_ASTUnit, + raw: slice::Iter<'a, clangtool::CXToken>, } impl<'a> Iterator for ClangTokenIterator<'a> { @@ -832,8 +1096,8 @@ impl<'a> Iterator for ClangTokenIterator<'a> { fn next(&mut self) -> Option { let raw = self.raw.next()?; unsafe { - let kind = clang_getTokenKind(*raw); - let spelling = clang_getTokenSpelling(self.tu, *raw); + let kind = clangtool::getTokenKind(*raw); + let spelling = clangtool::getTokenSpelling(self.tu, *raw).to_cstring(); Some(ClangToken { kind, spelling }) } } @@ -851,47 +1115,56 @@ pub fn is_valid_identifier(name: &str) -> bool { first_valid && chars.all(|c| c.is_alphanumeric() || c == '_') } -extern "C" fn visit_children( - cur: CXCursor, - _parent: CXCursor, - data: CXClientData, +unsafe extern "C" fn visit_children( + node: clangtool::Node, + _parent: clangtool::Node, + unit: *mut clangtool::clang_ASTUnit, + data: clangtool::CXClientData, ) -> CXChildVisitResult where Visitor: FnMut(Cursor) -> CXChildVisitResult, { - let func: &mut Visitor = unsafe { mem::transmute(data) }; - let child = Cursor { x: cur }; + let func: &mut Visitor = mem::transmute(data); + let node = match node.kind { + CXCursor_StructDecl => ASTNode::Decl(node.ptr.decl), + _ => ASTNode::Invalid, + }; + let child = Cursor { + node, + unit, + }; (*func)(child) } -impl PartialEq for Cursor { - fn eq(&self, other: &Cursor) -> bool { - unsafe { clang_equalCursors(self.x, other.x) == 1 } - } -} +// impl PartialEq for Cursor { +// fn eq(&self, other: &Cursor) -> bool { +// unsafe { clang_equalCursors(self.x, other.x) == 1 } +// } +// } -impl Eq for Cursor {} +// impl Eq for Cursor {} -impl Hash for Cursor { - fn hash(&self, state: &mut H) { - unsafe { clang_hashCursor(self.x) }.hash(state) - } -} +// impl Hash for Cursor { +// fn hash(&self, state: &mut H) { +// unsafe { clang_hashCursor(self.x) }.hash(state) +// } +// } /// The type of a node in clang's AST. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct Type { - x: CXType, + x: clangtool::clang_QualType, + unit: *mut clangtool::clang_ASTUnit, } -impl PartialEq for Type { +impl PartialEq for clangtool::clang_QualType { fn eq(&self, other: &Self) -> bool { - unsafe { clang_equalTypes(self.x, other.x) != 0 } + ptr::eq(self.ptr, other.ptr) } } -impl Eq for Type {} +impl Eq for clangtool::clang_QualType {} impl fmt::Debug for Type { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { @@ -928,6 +1201,7 @@ pub enum LayoutError { impl ::std::convert::From for LayoutError { fn from(val: i32) -> Self { use self::LayoutError::*; + use self::clangtool::CXTypeLayoutError::*; match val { CXTypeLayoutError_Invalid => Invalid, @@ -941,16 +1215,21 @@ impl ::std::convert::From for LayoutError { } impl Type { + fn context(&self) -> *mut clangtool::clang_ASTContext { + unsafe { clangtool::ASTUnit_getContext(self.unit) } + } + /// Get this type's kind. pub fn kind(&self) -> CXTypeKind { - self.x.kind + unsafe { clangtool::Type_kind(self.x) } } /// Get a cursor pointing to this type's declaration. pub fn declaration(&self) -> Cursor { unsafe { Cursor { - x: clang_getTypeDeclaration(self.x), + node: ASTNode::Decl(clangtool::Type_getDeclaration(self.x)), + unit: self.unit, } } } @@ -983,7 +1262,7 @@ impl Type { /// Get a raw display name for this type. pub fn spelling(&self) -> String { - let s = unsafe { cxstring_into_string(clang_getTypeSpelling(self.x)) }; + let s = unsafe { clangtool::Type_getTypeSpelling(self.x, self.context()).to_string() }; // Clang 5.0 introduced changes in the spelling API so it returned the // full qualified name. Let's undo that here. if s.split("::").all(|s| is_valid_identifier(s)) { @@ -997,7 +1276,7 @@ impl Type { /// Is this type const qualified? pub fn is_const(&self) -> bool { - unsafe { clang_isConstQualifiedType(self.x) != 0 } + unsafe { clangtool::Type_isConstQualifiedType(self.x) } } #[inline] @@ -1015,7 +1294,7 @@ impl Type { } // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 CXType_Auto if self.is_non_deductible_auto_type() => return -6, - _ => unsafe { clang_Type_getSizeOf(self.x) }, + _ => unsafe { clangtool::Type_getSizeOf(self.x, self.context()) }, } } @@ -1028,7 +1307,7 @@ impl Type { } // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 CXType_Auto if self.is_non_deductible_auto_type() => return -6, - _ => unsafe { clang_Type_getAlignOf(self.x) }, + _ => unsafe { clangtool::Type_getAlignOf(self.x, self.context()) }, } } @@ -1098,11 +1377,11 @@ impl Type { // If an old libclang is loaded, we have no hope of answering this // question correctly. However, that's no reason to panic when // generating bindings for simple C headers with an old libclang. - if !clang_Type_getNumTemplateArguments::is_loaded() { - return None; - } + // if !clangtool::Type_getNumTemplateArguments::is_loaded() { + // return None; + // } - let n = unsafe { clang_Type_getNumTemplateArguments(self.x) }; + let n = unsafe { clangtool::Type_getNumTemplateArguments(self.x) }; if n >= 0 { Some(n as u32) } else { @@ -1116,6 +1395,7 @@ impl Type { pub fn template_args(&self) -> Option { self.num_template_args().map(|n| TypeTemplateArgIterator { x: self.x, + unit: self.unit, length: n, index: 0, }) @@ -1128,7 +1408,8 @@ impl Type { self.num_args().ok().map(|num| { (0..num) .map(|i| Type { - x: unsafe { clang_getArgType(self.x, i as c_uint) }, + x: unsafe { clangtool::Type_getArgType(self.x, i as c_uint) }, + unit: self.unit, }) .collect() }) @@ -1139,7 +1420,7 @@ impl Type { /// Returns Err if the type is not a function prototype. pub fn num_args(&self) -> Result { unsafe { - let w = clang_getNumArgTypes(self.x); + let w = clangtool::Type_getNumArgTypes(self.x); if w == -1 { Err(()) } else { @@ -1159,7 +1440,8 @@ impl Type { CXType_BlockPointer | CXType_ObjCObjectPointer => { let ret = Type { - x: unsafe { clang_getPointeeType(self.x) }, + x: unsafe { clangtool::Type_getPointeeType(self.x) }, + unit: self.unit, }; debug_assert!(ret.is_valid()); Some(ret) @@ -1172,7 +1454,8 @@ impl Type { /// type of its elements. pub fn elem_type(&self) -> Option { let current_type = Type { - x: unsafe { clang_getElementType(self.x) }, + x: unsafe { clangtool::Type_getElementType(self.x) }, + unit: self.unit, }; if current_type.is_valid() { Some(current_type) @@ -1184,7 +1467,7 @@ impl Type { /// Given that this type is an array or vector type, return its number of /// elements. pub fn num_elements(&self) -> Option { - let num_elements_returned = unsafe { clang_getNumElements(self.x) }; + let num_elements_returned = unsafe { clangtool::Type_getNumElements(self.x) }; if num_elements_returned != -1 { Some(num_elements_returned as usize) } else { @@ -1197,21 +1480,23 @@ impl Type { pub fn canonical_type(&self) -> Type { unsafe { Type { - x: clang_getCanonicalType(self.x), + x: clangtool::Type_getCanonicalType(self.x, self.context()), + unit: self.unit, } } } /// Is this type a variadic function type? pub fn is_variadic(&self) -> bool { - unsafe { clang_isFunctionTypeVariadic(self.x) != 0 } + unsafe { clangtool::Type_isFunctionTypeVariadic(self.x) } } /// Given that this type is a function type, get the type of its return /// value. pub fn ret_type(&self) -> Option { let rt = Type { - x: unsafe { clang_getResultType(self.x) }, + x: unsafe { clangtool::Type_getResultType(self.x) }, + unit: self.unit, }; if rt.is_valid() { Some(rt) @@ -1222,8 +1507,8 @@ impl Type { /// Given that this type is a function type, get its calling convention. If /// this is not a function type, `CXCallingConv_Invalid` is returned. - pub fn call_conv(&self) -> CXCallingConv { - unsafe { clang_getFunctionTypeCallingConv(self.x) } + pub fn call_conv(&self) -> clangtool::CXCallingConv::Type { + unsafe { clangtool::Type_getFunctionTypeCallingConv(self.x) } } /// For elaborated types (types which use `class`, `struct`, or `union` to @@ -1231,11 +1516,8 @@ impl Type { pub fn named(&self) -> Type { unsafe { Type { - x: if clang_Type_getNamedType::is_loaded() { - clang_Type_getNamedType(self.x) - } else { - self.x - }, + x: clangtool::Type_getNamedType(self.x), + unit: self.unit, } } } @@ -1315,7 +1597,8 @@ impl CanonicalTypeDeclaration { /// An iterator for a type's template arguments. pub struct TypeTemplateArgIterator { - x: CXType, + x: clangtool::clang_QualType, + unit: *mut clangtool::clang_ASTUnit, length: u32, index: u32, } @@ -1327,7 +1610,8 @@ impl Iterator for TypeTemplateArgIterator { let idx = self.index as c_uint; self.index += 1; Some(Type { - x: unsafe { clang_Type_getTemplateArgumentAsType(self.x, idx) }, + x: unsafe { clangtool::Type_getTemplateArgumentAsType(self.x, idx) }, + unit: self.unit, }) } else { None @@ -1345,7 +1629,8 @@ impl ExactSizeIterator for TypeTemplateArgIterator { /// A `SourceLocation` is a file, line, column, and byte offset location for /// some source text. pub struct SourceLocation { - x: CXSourceLocation, + x: *const clangtool::clang_SourceLocation, + unit: *mut clangtool::clang_ASTUnit, } impl SourceLocation { @@ -1357,8 +1642,8 @@ impl SourceLocation { let mut line = 0; let mut col = 0; let mut off = 0; - clang_getSpellingLocation( - self.x, &mut file, &mut line, &mut col, &mut off, + clangtool::getSpellingLocation( + self.unit, self.x, &mut file, &mut line, &mut col, &mut off, ); (File { x: file }, line as usize, col as usize, off as usize) } @@ -1380,20 +1665,20 @@ impl fmt::Display for SourceLocation { /// /// Comments are sort of parsed by Clang, and have a tree structure. pub struct Comment { - x: CXComment, + x: *const clangtool::clang_comments_Comment, } impl Comment { /// What kind of comment is this? - pub fn kind(&self) -> CXCommentKind { - unsafe { clang_Comment_getKind(self.x) } + pub fn kind(&self) -> clangtool::CXCommentKind::Type { + unsafe { clangtool::Comment_getKind(self.x) } } /// Get this comment's children comment pub fn get_children(&self) -> CommentChildrenIterator { CommentChildrenIterator { parent: self.x, - length: unsafe { clang_Comment_getNumChildren(self.x) }, + length: unsafe { clangtool::Comment_getNumChildren(self.x) }, index: 0, } } @@ -1401,14 +1686,14 @@ impl Comment { /// Given that this comment is the start or end of an HTML tag, get its tag /// name. pub fn get_tag_name(&self) -> String { - unsafe { cxstring_into_string(clang_HTMLTagComment_getTagName(self.x)) } + unsafe { clangtool::HTMLTagComment_getTagName(self.x).to_string() } } /// Given that this comment is an HTML start tag, get its attributes. pub fn get_tag_attrs(&self) -> CommentAttributesIterator { CommentAttributesIterator { x: self.x, - length: unsafe { clang_HTMLStartTag_getNumAttrs(self.x) }, + length: unsafe { clangtool::HTMLStartTag_getNumAttrs(self.x) }, index: 0, } } @@ -1416,7 +1701,7 @@ impl Comment { /// An iterator for a comment's children pub struct CommentChildrenIterator { - parent: CXComment, + parent: *const clangtool::clang_comments_Comment, length: c_uint, index: c_uint, } @@ -1428,7 +1713,7 @@ impl Iterator for CommentChildrenIterator { let idx = self.index; self.index += 1; Some(Comment { - x: unsafe { clang_Comment_getChild(self.parent, idx) }, + x: unsafe { clangtool::Comment_getChild(self.parent, idx) }, }) } else { None @@ -1446,7 +1731,7 @@ pub struct CommentAttribute { /// An iterator for a comment's attributes pub struct CommentAttributesIterator { - x: CXComment, + x: *const clangtool::clang_comments_Comment, length: c_uint, index: c_uint, } @@ -1459,14 +1744,14 @@ impl Iterator for CommentAttributesIterator { self.index += 1; Some(CommentAttribute { name: unsafe { - cxstring_into_string(clang_HTMLStartTag_getAttrName( + clangtool::HTMLStartTag_getAttrName( self.x, idx, - )) + ).to_string() }, value: unsafe { - cxstring_into_string(clang_HTMLStartTag_getAttrValue( + clangtool::HTMLStartTag_getAttrValue( self.x, idx, - )) + ).to_string() }, }) } else { @@ -1477,7 +1762,7 @@ impl Iterator for CommentAttributesIterator { /// A source file. pub struct File { - x: CXFile, + x: *mut clangtool::clang_FileEntry, } impl File { @@ -1486,59 +1771,59 @@ impl File { if self.x.is_null() { return None; } - Some(unsafe { cxstring_into_string(clang_getFileName(self.x)) }) - } -} - -fn cxstring_to_string_leaky(s: CXString) -> String { - if s.data.is_null() { - return "".to_owned(); + Some(unsafe { clangtool::FileEntry_getName(self.x).to_string() }) } - let c_str = unsafe { CStr::from_ptr(clang_getCString(s) as *const _) }; - c_str.to_string_lossy().into_owned() } -fn cxstring_into_string(s: CXString) -> String { - let ret = cxstring_to_string_leaky(s); - unsafe { clang_disposeString(s) }; - ret -} - -/// An `Index` is an environment for a set of translation units that will -/// typically end up linked together in one final binary. -pub struct Index { - x: CXIndex, -} - -impl Index { - /// Construct a new `Index`. - /// - /// The `pch` parameter controls whether declarations in pre-compiled - /// headers are included when enumerating a translation unit's "locals". - /// - /// The `diag` parameter controls whether debugging diagnostics are enabled. - pub fn new(pch: bool, diag: bool) -> Index { - unsafe { - Index { - x: clang_createIndex(pch as c_int, diag as c_int), - } - } - } -} - -impl fmt::Debug for Index { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "Index {{ }}") - } -} - -impl Drop for Index { - fn drop(&mut self) { - unsafe { - clang_disposeIndex(self.x); - } - } -} +// fn cxstring_to_string_leaky(s: CXString) -> String { +// if s.data.is_null() { +// return "".to_owned(); +// } +// let c_str = unsafe { CStr::from_ptr(clang_getCString(s) as *const _) }; +// c_str.to_string_lossy().into_owned() +// } + +// fn cxstring_into_string(s: CXString) -> String { +// let ret = cxstring_to_string_leaky(s); +// unsafe { clang_disposeString(s) }; +// ret +// } + +// /// An `Index` is an environment for a set of translation units that will +// /// typically end up linked together in one final binary. +// pub struct Index { +// x: CXIndex, +// } + +// impl Index { +// /// Construct a new `Index`. +// /// +// /// The `pch` parameter controls whether declarations in pre-compiled +// /// headers are included when enumerating a translation unit's "locals". +// /// +// /// The `diag` parameter controls whether debugging diagnostics are enabled. +// pub fn new(pch: bool, diag: bool) -> Index { +// unsafe { +// Index { +// x: clang_createIndex(pch as c_int, diag as c_int), +// } +// } +// } +// } + +// impl fmt::Debug for Index { +// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { +// write!(fmt, "Index {{ }}") +// } +// } + +// impl Drop for Index { +// fn drop(&mut self) { +// unsafe { +// clang_disposeIndex(self.x); +// } +// } +// } /// A token emitted by clang's lexer. #[derive(Debug)] @@ -1551,7 +1836,7 @@ pub struct Token { /// A translation unit (or "compilation unit"). pub struct TranslationUnit { - x: CXTranslationUnit, + x: *mut clangtool::clang_ASTUnit, } impl fmt::Debug for TranslationUnit { @@ -1563,11 +1848,11 @@ impl fmt::Debug for TranslationUnit { impl TranslationUnit { /// Parse a source file into a translation unit. pub fn parse( - ix: &Index, + // ix: &Index, file: &str, cmd_args: &[String], unsaved: &[UnsavedFile], - opts: CXTranslationUnit_Flags, + opts: clang_sys::CXTranslationUnit_Flags, ) -> Option { let fname = CString::new(file).unwrap(); let _c_args: Vec = cmd_args @@ -1576,16 +1861,14 @@ impl TranslationUnit { .collect(); let c_args: Vec<*const c_char> = _c_args.iter().map(|s| s.as_ptr()).collect(); - let mut c_unsaved: Vec = + let mut c_unsaved: Vec = unsaved.iter().map(|f| f.x).collect(); let tu = unsafe { - clang_parseTranslationUnit( - ix.x, + // TODO(sjc): add back in unsaved files and opts + clangtool::parseTranslationUnit( fname.as_ptr(), c_args.as_ptr(), c_args.len() as c_int, - c_unsaved.as_mut_ptr(), - c_unsaved.len() as c_uint, opts, ) }; @@ -1600,11 +1883,11 @@ impl TranslationUnit { /// unit. pub fn diags(&self) -> Vec { unsafe { - let num = clang_getNumDiagnostics(self.x) as usize; + let num = clangtool::ASTUnit_getNumDiagnostics(self.x) as usize; let mut diags = vec![]; for i in 0..num { diags.push(Diagnostic { - x: clang_getDiagnostic(self.x, i as c_uint), + x: clangtool::ASTUnit_getDiagnostic(self.x, i as c_uint), }); } diags @@ -1615,7 +1898,8 @@ impl TranslationUnit { pub fn cursor(&self) -> Cursor { unsafe { Cursor { - x: clang_getTranslationUnitCursor(self.x), + node: ASTNode::Decl(clangtool::getTranslationUnitDecl(self.x)), + unit: self.x, } } } @@ -1629,14 +1913,14 @@ impl TranslationUnit { impl Drop for TranslationUnit { fn drop(&mut self) { unsafe { - clang_disposeTranslationUnit(self.x); + clangtool::disposeASTUnit(self.x); } } } /// A diagnostic message generated while parsing a translation unit. pub struct Diagnostic { - x: CXDiagnostic, + x: *const clangtool::clang_StoredDiagnostic, } impl Diagnostic { @@ -1644,29 +1928,28 @@ impl Diagnostic { /// flags. pub fn format(&self) -> String { unsafe { - let opts = clang_defaultDiagnosticDisplayOptions(); - cxstring_into_string(clang_formatDiagnostic(self.x, opts)) + clangtool::Diagnostic_format(self.x).to_string() } } /// What is the severity of this diagnostic message? - pub fn severity(&self) -> CXDiagnosticSeverity { - unsafe { clang_getDiagnosticSeverity(self.x) } + pub fn severity(&self) -> clangtool::CXDiagnosticSeverity::Type { + unsafe { clangtool::Diagnostic_getSeverity(self.x) } } } -impl Drop for Diagnostic { - /// Destroy this diagnostic message. - fn drop(&mut self) { - unsafe { - clang_disposeDiagnostic(self.x); - } - } -} +// impl Drop for Diagnostic { +// /// Destroy this diagnostic message. +// fn drop(&mut self) { +// unsafe { +// clangtool::Diagnostic_dispose(self.x); +// } +// } +// } /// A file which has not been saved to disk. pub struct UnsavedFile { - x: CXUnsavedFile, + x: clangtool::CXUnsavedFile, /// The name of the unsaved file. Kept here to avoid leaving dangling pointers in /// `CXUnsavedFile`. pub name: CString, @@ -1678,7 +1961,7 @@ impl UnsavedFile { pub fn new(name: &str, contents: &str) -> UnsavedFile { let name = CString::new(name).unwrap(); let contents = CString::new(contents).unwrap(); - let x = CXUnsavedFile { + let x = clangtool::CXUnsavedFile { Filename: name.as_ptr(), Contents: contents.as_ptr(), Length: contents.as_bytes().len() as c_ulong, @@ -1703,12 +1986,12 @@ impl fmt::Debug for UnsavedFile { /// Convert a cursor kind into a static string. pub fn kind_to_str(x: CXCursorKind) -> String { - unsafe { cxstring_into_string(clang_getCursorKindSpelling(x)) } + unsafe { clangtool::CursorKind_getSpelling(x).to_string() } } /// Convert a type kind to a static string. pub fn type_to_str(x: CXTypeKind) -> String { - unsafe { cxstring_into_string(clang_getTypeKindSpelling(x)) } + unsafe { clangtool::TypeKind_getSpelling(x).to_string() } } /// Dump the Clang AST to stdout for debugging purposes. @@ -1854,11 +2137,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { format!(" {}spelling = \"{}\"", prefix, ty.spelling()), ); let num_template_args = - if clang_Type_getNumTemplateArguments::is_loaded() { - unsafe { clang_Type_getNumTemplateArguments(ty.x) } - } else { - -1 - }; + unsafe { clangtool::Type_getNumTemplateArguments(ty.x) }; if num_template_args >= 0 { print_indent( depth, @@ -1943,56 +2222,26 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { /// Try to extract the clang version to a string pub fn extract_clang_version() -> String { - unsafe { cxstring_into_string(clang_getClangVersion()) } + let version = unsafe { clangtool::getClangVersion() }; + version.to_string() } /// A wrapper for the result of evaluating an expression. #[derive(Debug)] pub struct EvalResult { - x: CXEvalResult, + x: *mut clangtool::EvalResult, } impl EvalResult { - /// Evaluate `cursor` and return the result. - pub fn new(cursor: Cursor) -> Option { - if !clang_Cursor_Evaluate::is_loaded() { - return None; - } - - // Work around https://bugs.llvm.org/show_bug.cgi?id=42532, see: - // * https://github.com/rust-lang/rust-bindgen/issues/283 - // * https://github.com/rust-lang/rust-bindgen/issues/1590 - { - let mut found_cant_eval = false; - cursor.visit(|c| { - if c.kind() == CXCursor_TypeRef && - c.cur_type().canonical_type().kind() == CXType_Unexposed - { - found_cant_eval = true; - return CXChildVisit_Break; - } - - CXChildVisit_Recurse - }); - - if found_cant_eval { - return None; - } - } - Some(EvalResult { - x: unsafe { clang_Cursor_Evaluate(cursor.x) }, - }) - } - fn kind(&self) -> CXEvalResultKind { - unsafe { clang_EvalResult_getKind(self.x) } + unsafe { clangtool::EvalResult_getKind(self.x) } } /// Try to get back the result as a double. pub fn as_double(&self) -> Option { match self.kind() { CXEval_Float => { - Some(unsafe { clang_EvalResult_getAsDouble(self.x) } as f64) + Some(unsafe { clangtool::EvalResult_getAsDouble(self.x) } as f64) } _ => None, } @@ -2004,14 +2253,8 @@ impl EvalResult { return None; } - if !clang_EvalResult_isUnsignedInt::is_loaded() { - // FIXME(emilio): There's no way to detect underflow here, and clang - // will just happily give us a value. - return Some(unsafe { clang_EvalResult_getAsInt(self.x) } as i64); - } - - if unsafe { clang_EvalResult_isUnsignedInt(self.x) } != 0 { - let value = unsafe { clang_EvalResult_getAsUnsigned(self.x) }; + if unsafe { clangtool::EvalResult_isUnsignedInt(self.x) } { + let value = unsafe { clangtool::EvalResult_getAsUnsigned(self.x) }; if value > i64::max_value() as c_ulonglong { return None; } @@ -2019,7 +2262,7 @@ impl EvalResult { return Some(value as i64); } - let value = unsafe { clang_EvalResult_getAsLongLong(self.x) }; + let value = unsafe { clangtool::EvalResult_getAsLongLong(self.x) }; if value > i64::max_value() as c_longlong { return None; } @@ -2035,7 +2278,7 @@ impl EvalResult { match self.kind() { CXEval_StrLiteral => { let ret = unsafe { - CStr::from_ptr(clang_EvalResult_getAsStr(self.x)) + CStr::from_ptr(clangtool::cString(clangtool::EvalResult_getAsStr(self.x))) }; Some(ret.to_bytes().to_vec()) } @@ -2044,11 +2287,11 @@ impl EvalResult { } } -impl Drop for EvalResult { - fn drop(&mut self) { - unsafe { clang_EvalResult_dispose(self.x) }; - } -} +// impl Drop for EvalResult { +// fn drop(&mut self) { +// unsafe { clangtool::EvalResult_dispose(self.x) }; +// } +// } /// Target information obtained from libclang. #[derive(Debug)] @@ -2062,16 +2305,12 @@ pub struct TargetInfo { impl TargetInfo { /// Tries to obtain target information from libclang. pub fn new(tu: &TranslationUnit) -> Option { - if !clang_getTranslationUnitTargetInfo::is_loaded() { - return None; - } let triple; let pointer_width; unsafe { - let ti = clang_getTranslationUnitTargetInfo(tu.x); - triple = cxstring_into_string(clang_TargetInfo_getTriple(ti)); - pointer_width = clang_TargetInfo_getPointerWidth(ti); - clang_TargetInfo_dispose(ti); + let ti = clangtool::ASTUnit_getTargetInfo(tu.x); + triple = clangtool::TargetInfo_getTriple(ti).to_string(); + pointer_width = clangtool::TargetInfo_getPointerWidth(ti); } assert!(pointer_width > 0); assert_eq!(pointer_width % 8, 0); diff --git a/src/clang/CMakeLists.txt b/src/clang/CMakeLists.txt new file mode 100644 index 0000000000..3b36cba192 --- /dev/null +++ b/src/clang/CMakeLists.txt @@ -0,0 +1,64 @@ +cmake_minimum_required(VERSION 3.4.3) +project(BindgenClangAST) + +set(SRCS + ClangAST.cpp + ) + +if( PROJECT_NAME STREQUAL "LLVM" ) + # We are building in-tree, we can use LLVM cmake functions + + add_definitions(-DCLANG_BIN_PATH="${CMAKE_INSTALL_PREFIX}/bin") + add_definitions(-DCLANG_VERSION_STRING="${PACKAGE_VERSION}") + + add_clang_library(clangAst ${SRCS} DEPENDS clang-headers) + + set(LLVM_LINK_COMPONENTS support) +else() + find_package(LLVM REQUIRED CONFIG) + + # Debian and Ubuntu's clang cmake files are broken, so we can't require the + # package here. We already have to manually order the link against the clang + # libs in build.rs, so that's not so bad. + find_package(Clang CONFIG) + + include_directories(${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS}) + add_definitions(${LLVM_DEFINITIONS} ${CLANG_DEFINITIONS}) + + if (DEFINED CLANG_INSTALL_PREFIX) + add_definitions(-DCLANG_BIN_PATH="${CLANG_INSTALL_PREFIX}/bin") + elseif(DEFINED LLVM_INSTALL_PREFIX) + add_definitions(-DCLANG_BIN_PATH="${LLVM_INSTALL_PREFIX}/bin") + elseif(DEFINED LLVM_TOOLS_BINARY_DIR) + add_definitions(-DCLANG_BIN_PATH="${LLVM_TOOLS_BINARY_DIR}") + else() + message(FATAL_ERROR "Cannot find path to clang binary") + endif() + add_definitions(-DCLANG_VERSION_STRING="${LLVM_PACKAGE_VERSION}") + + set(LLVM_LINK_COMPONENTS support) + + # LLVM is not always built with RTTI, we don't need it either. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") + + # The library + add_library(clangAst STATIC ${SRCS}) +endif() + +add_definitions(-DCLANG_LIBDIR_SUFFIX="${LLVM_LIBDIR_SUFFIX}") + +set_target_properties(clangAst PROPERTIES + CXX_STANDARD 11 + CXX_EXTENSIONS OFF + ) + +# PRIVATE was added to make clangAst build with LLVM 6.0. Keyword +# description: https://cmake.org/pipermail/cmake/2016-May/063400.html +target_link_libraries(clangAst PRIVATE + clangAST + clangFrontend + clangIndex + clangTooling + clangBasic + clangASTMatchers + ) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp new file mode 100644 index 0000000000..07674eccaa --- /dev/null +++ b/src/clang/ClangAST.cpp @@ -0,0 +1,2593 @@ +#include + +#include "clang/AST/Comment.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclFriend.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprObjC.h" +#include "clang/AST/Mangle.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Version.h" +#include "clang/Frontend/ASTUnit.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Index/USRGeneration.h" +#include "clang-c/Documentation.h" +#include "clang-c/Index.h" + +#define BINDGEN_IMPLEMENTATION +#include "ClangAST.hpp" + +using namespace clang; + +BindgenStringRef stringref() { + BindgenStringRef ref; + ref.s = nullptr; + ref.len = 0; + return ref; +} + +BindgenStringRef stringref(const char *newStr) { + BindgenStringRef ref; + ref.len = strlen(newStr); + ref.s = new char[ref.len + 1]; + strncpy(ref.s, newStr, ref.len); + ref.s[ref.len] = '\0'; + return ref; +} + +BindgenStringRef stringref(const std::string &s) { + return stringref(s.c_str()); +} + +// From libclang/CIndex.cpp +static const Decl *getDeclFromExpr(const Stmt *E) { + if (const ImplicitCastExpr *CE = dyn_cast(E)) + return getDeclFromExpr(CE->getSubExpr()); + + if (const DeclRefExpr *RefExpr = dyn_cast(E)) + return RefExpr->getDecl(); + if (const MemberExpr *ME = dyn_cast(E)) + return ME->getMemberDecl(); + if (const ObjCIvarRefExpr *RE = dyn_cast(E)) + return RE->getDecl(); + if (const ObjCPropertyRefExpr *PRE = dyn_cast(E)) { + if (PRE->isExplicitProperty()) + return PRE->getExplicitProperty(); + // It could be messaging both getter and setter as in: + // ++myobj.myprop; + // in which case prefer to associate the setter since it is less obvious + // from inspecting the source that the setter is going to get called. + if (PRE->isMessagingSetter()) + return PRE->getImplicitPropertySetter(); + return PRE->getImplicitPropertyGetter(); + } + if (const PseudoObjectExpr *POE = dyn_cast(E)) + return getDeclFromExpr(POE->getSyntacticForm()); + if (const OpaqueValueExpr *OVE = dyn_cast(E)) + if (Expr *Src = OVE->getSourceExpr()) + return getDeclFromExpr(Src); + + if (const CallExpr *CE = dyn_cast(E)) + return getDeclFromExpr(CE->getCallee()); + if (const CXXConstructExpr *CE = dyn_cast(E)) + if (!CE->isElidable()) + return CE->getConstructor(); + if (const CXXInheritedCtorInitExpr *CE = + dyn_cast(E)) + return CE->getConstructor(); + if (const ObjCMessageExpr *OME = dyn_cast(E)) + return OME->getMethodDecl(); + + if (const ObjCProtocolExpr *PE = dyn_cast(E)) + return PE->getProtocol(); + if (const SubstNonTypeTemplateParmPackExpr *NTTP + = dyn_cast(E)) + return NTTP->getParameterPack(); + if (const SizeOfPackExpr *SizeOfPack = dyn_cast(E)) + if (isa(SizeOfPack->getPack()) || + isa(SizeOfPack->getPack())) + return SizeOfPack->getPack(); + + return nullptr; +} + +BindgenSourceRange::BindgenSourceRange(const SourceRange &range) { + B = new SourceLocation(range.getBegin()); + E = new SourceLocation(range.getEnd()); +} + +BindgenStringRefSet make_stringrefset(std::vector &string_vec) { + BindgenStringRefSet set; + set.len = string_vec.size(); + set.strings = new BindgenStringRef[set.len]; + for (size_t i = 0; i < set.len; ++i) + set.strings[i] = stringref(string_vec[i]); + return set; +} + + +void freeString(BindgenStringRef s) { + delete[] s.s; +} + +char *cString(BindgenStringRef s) { return s.s; } + +ASTContext *ASTUnit_getContext(ASTUnit *Unit) { + return &Unit->getASTContext(); +} + +ASTUnit *parseTranslationUnit(const char *source_filename, + const char *const *command_line_args, + int num_command_line_args, + int options) { + + ArrayRef Args(command_line_args, num_command_line_args); + + // Configure the diagnostics. + IntrusiveRefCntPtr + Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); + + if (options & CXTranslationUnit_KeepGoing) + Diags->setFatalsAsError(true); + + CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All; + if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles) + CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes; + + auto Invoc = createInvocationFromCommandLine(Args, Diags); + if (!Invoc) + return nullptr; + + return ASTUnit::LoadFromCompilerInvocationAction( + std::move(Invoc), std::make_shared(), Diags); +} + +void disposeASTUnit(ASTUnit *AU) { + delete AU; +} + +unsigned ASTUnit_getNumDiagnostics(const ASTUnit *AU) { + return AU->stored_diag_size(); +} + +const StoredDiagnostic *ASTUnit_getDiagnostic(const ASTUnit *AU, unsigned i) { + return (AU->stored_diag_begin()+i); +} + +const TargetInfo *ASTUnit_getTargetInfo(ASTUnit *Unit) { + return &Unit->getASTContext().getTargetInfo(); +} + +int TargetInfo_getPointerWidth(const TargetInfo *TI) { + if (!TI) + return -1; + return TI->getMaxPointerWidth(); +} + +BindgenStringRef TargetInfo_getTriple(const TargetInfo *TI) { + if (!TI) + return stringref(); + + std::string Triple = TI->getTriple().normalize(); + return stringref(Triple); +} + +struct EvalResult { + CXEvalResultKind EvalType; + APValue Val; + std::string stringVal; + + EvalResult() : EvalType(CXEval_UnExposed) {} + EvalResult(APValue Val) : EvalType(CXEval_UnExposed), Val(Val) { + if (Val.isInt()) + EvalType = CXEval_Int; + else if (Val.isFloat()) + EvalType = CXEval_Float; + } + EvalResult(std::string str) : EvalType(CXEval_StrLiteral), stringVal(str) {} +}; + +EvalResult *Expr_Evaluate(const Expr *E, ASTContext *Ctx) { + if (!E) + return nullptr; + + Expr::EvalResult res; + if (E->EvaluateAsRValue(res, *Ctx)) { + if (E->getStmtClass() == Stmt::ImplicitCastExprClass) { + const ImplicitCastExpr *I = dyn_cast(&*E); + auto *subExpr = I->getSubExprAsWritten(); + if (subExpr->getStmtClass() == Stmt::StringLiteralClass) { + auto StrE = cast(I->getSubExprAsWritten()); + return new EvalResult(StrE->getString().str()); + } + } else if (E->getStmtClass() == Stmt::StringLiteralClass) { + auto StrE = cast(&*E); + return new EvalResult(StrE->getString().str()); + } else { + return new EvalResult(res.Val); + } + } + + return nullptr; +} + +EvalResult *Decl_Evaluate(const Decl *D, ASTContext *Ctx) { + if (!D) + return nullptr; + + const Expr *E; + if (auto *Var = dyn_cast(&*D)) + E = Var->getInit(); + else if (auto *Field = dyn_cast(&*D)) + E = Field->getInClassInitializer(); + else + return nullptr; + + return Expr_Evaluate(E, Ctx); +} + +CXEvalResultKind EvalResult_getKind(EvalResult *ER) { + return ER->EvalType; +} + +double EvalResult_getAsDouble(EvalResult *ER) { + if (!ER) + return 0; + auto apFloat = ER->Val.getFloat(); + bool ignored; + apFloat.convert(llvm::APFloat::IEEEdouble(), + llvm::APFloat::rmNearestTiesToEven, &ignored); + return apFloat.convertToDouble(); +} + +bool EvalResult_isUnsignedInt(EvalResult *ER) { + return ER && + ER->EvalType == CXEval_Int && + ER->Val.getInt().isUnsigned(); +} + +long long EvalResult_getAsLongLong(EvalResult *ER) { + if (!ER) + return 0; + + auto intVal = ER->Val.getInt(); + if (intVal.isUnsigned()) + return intVal.getZExtValue(); + else + return intVal.getExtValue(); +} + +unsigned long long EvalResult_getAsUnsigned(EvalResult *ER) { + return static_cast(EvalResult_getAsLongLong(ER)); +} + +BindgenStringRef EvalResult_getAsStr(EvalResult *ER) { + if (!ER) + return stringref(); + + return stringref(ER->stringVal); +} + +BindgenStringRef Diagnostic_format(const StoredDiagnostic *D) { + if (!D) + return stringref(); + + return stringref(D->getMessage()); +} + +CXDiagnosticSeverity Diagnostic_getSeverity(const StoredDiagnostic *D) { + switch (D->getLevel()) { + case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored; + case DiagnosticsEngine::Note: return CXDiagnostic_Note; + case DiagnosticsEngine::Remark: + // The 'Remark' level isn't represented in the stable API. + case DiagnosticsEngine::Warning: return CXDiagnostic_Warning; + case DiagnosticsEngine::Error: return CXDiagnostic_Error; + case DiagnosticsEngine::Fatal: return CXDiagnostic_Fatal; + } + + llvm_unreachable("Invalid diagnostic level"); +} + +const Decl *getTranslationUnitDecl(ASTUnit *Unit) { + return Unit->getASTContext().getTranslationUnitDecl(); +} + +bool CursorKind_isInvalid(CXCursorKind kind) { + return kind >= CXCursor_FirstInvalid && kind <= CXCursor_LastInvalid; +} + +const Decl *Decl_getLexicalParent(const Decl *D) { + if (!D) + return nullptr; + + const DeclContext *DC = D->getLexicalDeclContext(); + if (!DC) + return nullptr; + + return cast(DC); +} + +const Decl *Decl_getSemanticParent(const Decl *D) { + if (!D) + return nullptr; + + const DeclContext *DC = D->getDeclContext(); + if (!DC) + return nullptr; + + return cast(DC); +} + +// ASTUnit *Decl_getTranslationUnit(const Decl *D) { +// if (!D) +// return nullptr; + +// return D.unit; +// } + +const Decl *Decl_getDefinition(const Decl *D) { + if (!D) + return nullptr; + + switch (D->getKind()) { + // Declaration kinds that don't really separate the notions of + // declaration and definition. + case Decl::Namespace: + case Decl::Typedef: + case Decl::TypeAlias: + case Decl::TypeAliasTemplate: + case Decl::TemplateTypeParm: + case Decl::EnumConstant: + case Decl::Field: + case Decl::Binding: + case Decl::MSProperty: + case Decl::IndirectField: + case Decl::ObjCIvar: + case Decl::ObjCAtDefsField: + case Decl::ImplicitParam: + case Decl::ParmVar: + case Decl::NonTypeTemplateParm: + case Decl::TemplateTemplateParm: + case Decl::ObjCCategoryImpl: + case Decl::ObjCImplementation: + case Decl::AccessSpec: + case Decl::LinkageSpec: + case Decl::Export: + case Decl::ObjCPropertyImpl: + case Decl::FileScopeAsm: + case Decl::StaticAssert: + case Decl::Block: + case Decl::Captured: + case Decl::OMPCapturedExpr: + case Decl::Label: // FIXME: Is this right?? + case Decl::ClassScopeFunctionSpecialization: + case Decl::CXXDeductionGuide: + case Decl::Import: + case Decl::OMPThreadPrivate: + case Decl::OMPAllocate: + case Decl::OMPDeclareReduction: + case Decl::OMPDeclareMapper: + case Decl::OMPRequires: + case Decl::ObjCTypeParam: + case Decl::BuiltinTemplate: + case Decl::PragmaComment: + case Decl::PragmaDetectMismatch: + case Decl::UsingPack: + case Decl::Concept: + return D; + + // Declaration kinds that don't make any sense here, but are + // nonetheless harmless. + case Decl::Empty: + case Decl::TranslationUnit: + case Decl::ExternCContext: + break; + + // Declaration kinds for which the definition is not resolvable. + case Decl::UnresolvedUsingTypename: + case Decl::UnresolvedUsingValue: + break; + + case Decl::UsingDirective: + return cast(&*D)->getNominatedNamespace(); + + case Decl::NamespaceAlias: + return cast(&*D)->getNamespace(); + + case Decl::Enum: + case Decl::Record: + case Decl::CXXRecord: + case Decl::ClassTemplateSpecialization: + case Decl::ClassTemplatePartialSpecialization: + if (TagDecl *Def = cast(&*D)->getDefinition()) + return Def; + break; + + case Decl::Function: + case Decl::CXXMethod: + case Decl::CXXConstructor: + case Decl::CXXDestructor: + case Decl::CXXConversion: { + const FunctionDecl *Def = nullptr; + if (cast(&*D)->getBody(Def)) + return Def; + break; + } + + case Decl::Var: + case Decl::VarTemplateSpecialization: + case Decl::VarTemplatePartialSpecialization: + case Decl::Decomposition: { + // Ask the variable if it has a definition. + if (const VarDecl *Def = cast(&*D)->getDefinition()) + return Def; + break; + } + + case Decl::FunctionTemplate: { + const FunctionDecl *Def = nullptr; + if (cast(&*D)->getTemplatedDecl()->getBody(Def)) + return Def->getDescribedFunctionTemplate(); + break; + } + + case Decl::ClassTemplate: { + if (RecordDecl *Def = + cast(&*D)->getTemplatedDecl()->getDefinition()) + return cast(Def)->getDescribedClassTemplate(); + break; + } + + case Decl::VarTemplate: { + if (VarDecl *Def = + cast(&*D)->getTemplatedDecl()->getDefinition()) + return cast(Def)->getDescribedVarTemplate(); + break; + } + + case Decl::Using: + return cast(&*D); + + case Decl::UsingShadow: + case Decl::ConstructorUsingShadow: + return Decl_getDefinition( + cast(&*D)->getTargetDecl()); + + case Decl::ObjCMethod: + case Decl::ObjCCategory: + case Decl::ObjCProtocol: + case Decl::ObjCInterface: + case Decl::ObjCProperty: + case Decl::ObjCCompatibleAlias: + llvm_unreachable("Objective-C not implemented"); + break; + + case Decl::Friend: + if (NamedDecl *Friend = cast(&*D)->getFriendDecl()) + return Decl_getDefinition(Friend); + break; + + case Decl::FriendTemplate: + if (NamedDecl *Friend = cast(&*D)->getFriendDecl()) + return Decl_getDefinition(Friend); + break; + } + + return nullptr; +} + +const Decl *Decl_getReferenced(const Decl *D) { + if (!D) + return nullptr; + + // TODO(sjc): Handle UsingDecl? + return D; +} + +const Decl *Decl_getCanonical(const Decl *D) { + return D->getCanonicalDecl(); +} + +const Decl *Decl_getSpecializedTemplate(const Decl *D) { + if (!D) + return nullptr; + + Decl *Template = nullptr; + if (const CXXRecordDecl *CXXRecord = dyn_cast(&*D)) { + if (const ClassTemplatePartialSpecializationDecl *PartialSpec + = dyn_cast(CXXRecord)) + Template = PartialSpec->getSpecializedTemplate(); + else if (const ClassTemplateSpecializationDecl *ClassSpec + = dyn_cast(CXXRecord)) { + llvm::PointerUnion Result + = ClassSpec->getSpecializedTemplateOrPartial(); + if (Result.is()) + Template = Result.get(); + else + Template = Result.get(); + + } else + Template = CXXRecord->getInstantiatedFromMemberClass(); + } else if (const FunctionDecl *Function = dyn_cast(&*D)) { + Template = Function->getPrimaryTemplate(); + if (!Template) + Template = Function->getInstantiatedFromMemberFunction(); + } else if (const VarDecl *Var = dyn_cast(&*D)) { + if (Var->isStaticDataMember()) + Template = Var->getInstantiatedFromStaticDataMember(); + } else if (const RedeclarableTemplateDecl *Tmpl + = dyn_cast(&*D)) + Template = Tmpl->getInstantiatedFromMemberTemplate(); + + return Template; +} + +CXCursorKind Decl_getTemplateCursorKind(const Decl *D) { + if (!D) + return CXCursor_NoDeclFound; + + switch (D->getKind()) { + case Decl::ClassTemplate: + case Decl::FunctionTemplate: + if (const TemplateDecl *Template = dyn_cast_or_null(&*D)) + return getCursorKindForDecl(Template->getTemplatedDecl()); + break; + + case Decl::ClassTemplatePartialSpecialization: + if (const ClassTemplateSpecializationDecl *PartialSpec + = dyn_cast_or_null(&*D)) { + switch (PartialSpec->getTagKind()) { + case TTK_Interface: + case TTK_Struct: return CXCursor_StructDecl; + case TTK_Class: return CXCursor_ClassDecl; + case TTK_Union: return CXCursor_UnionDecl; + case TTK_Enum: return CXCursor_NoDeclFound; + } + } + break; + + default: + break; + } + + return CXCursor_NoDeclFound; +} + +const Decl *Decl_getArgument(const Decl *D, unsigned i) { + if (!D) + return nullptr; + + if (const ObjCMethodDecl *MD = dyn_cast_or_null(&*D)) { + if (i < MD->param_size()) + return MD->parameters()[i]; + } else if (const FunctionDecl *FD = dyn_cast_or_null(&*D)) { + if (i < FD->param_size()) + return FD->parameters()[i]; + } + + return nullptr; +} + +int Decl_getNumArguments(const Decl *D) { + if (const ObjCMethodDecl *MD = dyn_cast_or_null(&*D)) + return MD->param_size(); + if (const FunctionDecl *FD = dyn_cast_or_null(&*D)) + return FD->param_size(); + + return -1; +} + +BindgenStringRef Decl_getUSR(const Decl *D) { + SmallString<128> Buf; + if (index::generateUSRForDecl(&*D, Buf)) + return stringref(); + else + return stringref(Buf.str()); +} + +BindgenStringRef Decl_getSpelling(const Decl *D) { + const NamedDecl *ND = dyn_cast_or_null(&*D); + if (!ND) + return stringref(); + + SmallString<1024> S; + llvm::raw_svector_ostream os(S); + ND->printName(os); + return stringref(S.str()); +} + +// BindgenStringRef Decl_getDisplayName(const Decl *D) { +// } + +BindgenStringRef Decl_getMangling(const Decl *D, ASTContext *Ctx) { + if (!D || !(isa(&*D) || isa(&*D))) + return stringref(); + + ASTNameGenerator ASTNameGen(*Ctx); + return stringref(ASTNameGen.getName(&*D)); +} + +BindgenStringRefSet Decl_getCXXManglings(const Decl *D, ASTContext *Ctx) { + if (!D || !(isa(&*D) || isa(&*D))) + return BindgenStringRefSet(); + + ASTNameGenerator ASTNameGen(*Ctx); + std::vector Manglings = ASTNameGen.getAllManglings(&*D); + return make_stringrefset(Manglings); +} + +int Decl_getNumTemplateArguments(const Decl *D) { + const FunctionDecl *FD = llvm::dyn_cast_or_null(&*D); + if (!FD) + return -1; + + const FunctionTemplateSpecializationInfo* SpecInfo = + FD->getTemplateSpecializationInfo(); + if (!SpecInfo) { + return -1; + } + + return SpecInfo->TemplateArguments->size(); +} + +CXCursorKind Decl_getCXCursorKind(const Decl *D) { + return getCursorKindForDecl(&*D); +} + +bool Decl_isDefinition(const Decl *D) { + if (auto VD = dyn_cast_or_null(&*D)) + return VD->getDefinition() == &*D; + if (auto FD = dyn_cast_or_null(&*D)) + return FD->getDefinition() == &*D; + if (auto TD = dyn_cast_or_null(&*D)) + return TD->getDefinition() == &*D; + + return false; +} + +SourceLocation *Decl_getLocation(const Decl *D) { + if (!D) + return nullptr; + return new SourceLocation(D->getLocation()); +} + +BindgenStringRef Decl_getRawCommentText(const Decl *D, ASTContext *Ctx) { + if (!D) + return stringref(); + + const RawComment *RC = Ctx->getRawCommentForAnyRedecl(&*D); + StringRef RawText = RC ? RC->getRawText(Ctx->getSourceManager()) : + StringRef(); + return stringref(RawText); +} + +comments::Comment *Decl_getParsedComment(const Decl *D, ASTContext *Ctx) { + if (!D) + return nullptr; + return Ctx->getCommentForDecl(&*D, /*PP=*/nullptr); +} + +QualType Decl_getType(const Decl *D, ASTContext *Ctx) { + if (!D) + return QualType(); + if (auto *TD = dyn_cast(&*D)) + return Ctx->getTypeDeclType(TD); + if (auto *ID = dyn_cast(&*D)) + return Ctx->getObjCInterfaceType(ID); + if (auto *DD = dyn_cast(&*D)) + return DD->getType(); + if (auto *VD = dyn_cast(&*D)) + return VD->getType(); + if (auto *PD = dyn_cast(&*D)) + return PD->getType(); + if (auto *FTD = dyn_cast(&*D)) + return FTD->getTemplatedDecl()->getType(); + return QualType(); +} + +bool Decl_isFunctionInlined(const Decl *D) { + if (auto *FD = dyn_cast_or_null(&*D)) + return FD->isInlined(); + else + return false; +} + +int Decl_getFieldDeclBitWidth(const Decl *D, ASTContext *Ctx) { + if (auto *FD = dyn_cast_or_null(&*D)) { + if (FD->isBitField()) + return FD->getBitWidthValue(*Ctx); + } + return -1; +} + +QualType Decl_getEnumDeclIntegerType(const Decl *D) { + if (auto *TD = dyn_cast_or_null(&*D)) + return TD->getIntegerType(); + else + return QualType(); +} + +int64_t Decl_getEnumConstantValue(const Decl *D) { + if (auto *TD = dyn_cast_or_null(&*D)) + return TD->getInitVal().getSExtValue(); + else + return LLONG_MIN; +} + +uint64_t Decl_getEnumConstantUnsignedValue(const Decl *D) { + if (auto *TD = dyn_cast_or_null(&*D)) + return TD->getInitVal().getZExtValue(); + else + return ULLONG_MAX; +} + +long long Decl_getOffsetOfField(const Decl *D, ASTContext *Ctx) { + if (auto *FD = dyn_cast_or_null(&*D)) + return Ctx->getFieldOffset(FD); + if (auto *IFD = dyn_cast_or_null(&*D)) + return Ctx->getFieldOffset(IFD); + return -1; +} + +BindgenSourceRange Decl_getSourceRange(const Decl *D) { + return BindgenSourceRange(D->getSourceRange()); +} + +QualType Decl_getTypedefDeclUnderlyingType(const Decl *D) { + if (auto *TD = dyn_cast_or_null(&*D)) + return TD->getUnderlyingType(); + else + return QualType(); +} + +CXLinkageKind Decl_getLinkage(const Decl *D) { + if (auto *ND = dyn_cast_or_null(&*D)) + switch (ND->getLinkageInternal()) { + case NoLinkage: + case VisibleNoLinkage: + return CXLinkage_NoLinkage; + case ModuleInternalLinkage: + case InternalLinkage: + return CXLinkage_Internal; + case UniqueExternalLinkage: + return CXLinkage_UniqueExternal; + case ModuleLinkage: + case ExternalLinkage: + return CXLinkage_External; + }; + + return CXLinkage_Invalid; +} + +CXVisibilityKind Decl_getVisibility(const Decl *D) { + if (auto *ND = dyn_cast_or_null(&*D)) + switch (ND->getVisibility()) { + case HiddenVisibility: + return CXVisibility_Hidden; + case ProtectedVisibility: + return CXVisibility_Protected; + case DefaultVisibility: + return CXVisibility_Default; + }; + + return CXVisibility_Invalid; +} + +CX_CXXAccessSpecifier Decl_getAccess(const Decl *D) { + AccessSpecifier spec = AS_none; + if (D) + spec = D->getAccess(); + + switch (spec) { + case AS_public: return CX_CXXPublic; + case AS_protected: return CX_CXXProtected; + case AS_private: return CX_CXXPrivate; + case AS_none: return CX_CXXInvalidAccessSpecifier; + } + + llvm_unreachable("Invalid AccessSpecifier!"); +} + +bool CXXField_isMutable(const Decl *D) { + if (const auto FD = dyn_cast_or_null(&*D)) + return FD->isMutable(); + else + return false; +} + +bool CXXMethod_isStatic(const Decl *D) { + auto *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return Method && Method->isStatic(); +} + +bool CXXMethod_isConst(const Decl *D) { + auto *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return Method && Method->getMethodQualifiers().hasConst(); +} + +bool CXXMethod_isVirtual(const Decl *D) { + auto *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return Method && Method->isVirtual(); +} + +bool CXXMethod_isPureVirtual(const Decl *D) { + auto *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return Method && Method->isVirtual() && Method->isPure(); +} + +QualType Decl_getResultType(const Decl *D, ASTContext *Ctx) { + if (auto *FT = Decl_getType(D, Ctx)->getAs()) + return FT->getReturnType(); + else + return QualType(); +} + +// const Decl *Expr_getSemanticParent(const Expr *E) { +// if (!E) +// return nullptr; + +// const DeclContext *DC = E->getParentContext(); +// if (!DC) +// return nullptr; + +// return cast(DC); +// } + +const Expr *Expr_getArgument(const Expr *E, unsigned i) { + if (const CallExpr *CE = dyn_cast_or_null(&*E)) { + if (i < CE->getNumArgs()) { + return CE->getArg(i); + } + } + if (const CXXConstructExpr *CE = dyn_cast_or_null(&*E)) { + if (i < CE->getNumArgs()) { + return CE->getArg(i); + } + } + return nullptr; +} + +int Expr_getNumArguments(const Expr *E) { + if (const CallExpr *CE = dyn_cast_or_null(&*E)) + return CE->getNumArgs(); + if (const CXXConstructExpr *CE = dyn_cast_or_null(&*E)) + return CE->getNumArgs(); + return -1; +} + +BindgenStringRef Expr_getSpelling(const Expr *E) { + if (auto *SL = dyn_cast_or_null(&*E)) { + SmallString<256> Buf; + llvm::raw_svector_ostream OS(Buf); + SL->outputString(OS); + return stringref(OS.str()); + } + if (auto *D = getDeclFromExpr(&*E)) + return Decl_getSpelling(D); + + return stringref(); +} + +CXCursorKind Expr_getCXCursorKind(const Expr *E) { + switch (E->getStmtClass()) { + case Stmt::NoStmtClass: + return CXCursor_NotImplemented; + case Stmt::CaseStmtClass: + return CXCursor_CaseStmt; + case Stmt::DefaultStmtClass: + return CXCursor_DefaultStmt; + case Stmt::IfStmtClass: + return CXCursor_IfStmt; + case Stmt::SwitchStmtClass: + return CXCursor_SwitchStmt; + case Stmt::WhileStmtClass: + return CXCursor_WhileStmt; + case Stmt::DoStmtClass: + return CXCursor_DoStmt; + case Stmt::ForStmtClass: + return CXCursor_ForStmt; + case Stmt::GotoStmtClass: + return CXCursor_GotoStmt; + case Stmt::IndirectGotoStmtClass: + return CXCursor_IndirectGotoStmt; + case Stmt::ContinueStmtClass: + return CXCursor_ContinueStmt; + case Stmt::BreakStmtClass: + return CXCursor_BreakStmt; + case Stmt::ReturnStmtClass: + return CXCursor_ReturnStmt; + case Stmt::GCCAsmStmtClass: + return CXCursor_GCCAsmStmt; + case Stmt::MSAsmStmtClass: + return CXCursor_MSAsmStmt; + case Stmt::ObjCAtTryStmtClass: + return CXCursor_ObjCAtTryStmt; + case Stmt::ObjCAtCatchStmtClass: + return CXCursor_ObjCAtCatchStmt; + case Stmt::ObjCAtFinallyStmtClass: + return CXCursor_ObjCAtFinallyStmt; + case Stmt::ObjCAtThrowStmtClass: + return CXCursor_ObjCAtThrowStmt; + case Stmt::ObjCAtSynchronizedStmtClass: + return CXCursor_ObjCAtSynchronizedStmt; + case Stmt::ObjCAutoreleasePoolStmtClass: + return CXCursor_ObjCAutoreleasePoolStmt; + case Stmt::ObjCForCollectionStmtClass: + return CXCursor_ObjCForCollectionStmt; + case Stmt::CXXCatchStmtClass: + return CXCursor_CXXCatchStmt; + case Stmt::CXXTryStmtClass: + return CXCursor_CXXTryStmt; + case Stmt::CXXForRangeStmtClass: + return CXCursor_CXXForRangeStmt; + case Stmt::SEHTryStmtClass: + return CXCursor_SEHTryStmt; + case Stmt::SEHExceptStmtClass: + return CXCursor_SEHExceptStmt; + case Stmt::SEHFinallyStmtClass: + return CXCursor_SEHFinallyStmt; + case Stmt::SEHLeaveStmtClass: + return CXCursor_SEHLeaveStmt; + + case Stmt::CoroutineBodyStmtClass: + case Stmt::CoreturnStmtClass: + return CXCursor_UnexposedStmt; + + case Stmt::OpaqueValueExprClass: + if (auto *Src = cast(&*E)->getSourceExpr()) + return Expr_getCXCursorKind(Src); + return CXCursor_UnexposedExpr; + + case Stmt::PseudoObjectExprClass: + return Expr_getCXCursorKind( + cast(&*E)->getSyntacticForm()); + + case Stmt::CompoundStmtClass: + return CXCursor_CompoundStmt; + + case Stmt::NullStmtClass: + return CXCursor_NullStmt; + + case Stmt::LabelStmtClass: + return CXCursor_LabelStmt; + + case Stmt::AttributedStmtClass: + return CXCursor_UnexposedStmt; + + case Stmt::DeclStmtClass: + return CXCursor_DeclStmt; + + case Stmt::CapturedStmtClass: + return CXCursor_UnexposedStmt; + + case Stmt::IntegerLiteralClass: + return CXCursor_IntegerLiteral; + + case Stmt::FixedPointLiteralClass: + return CXCursor_FixedPointLiteral; + + case Stmt::FloatingLiteralClass: + return CXCursor_FloatingLiteral; + + case Stmt::ImaginaryLiteralClass: + return CXCursor_ImaginaryLiteral; + + case Stmt::StringLiteralClass: + return CXCursor_StringLiteral; + + case Stmt::CharacterLiteralClass: + return CXCursor_CharacterLiteral; + + case Stmt::ConstantExprClass: + return Expr_getCXCursorKind(cast(&*E)->getSubExpr()); + + case Stmt::ParenExprClass: + return CXCursor_ParenExpr; + + case Stmt::UnaryOperatorClass: + return CXCursor_UnaryOperator; + + case Stmt::UnaryExprOrTypeTraitExprClass: + case Stmt::CXXNoexceptExprClass: + return CXCursor_UnaryExpr; + + case Stmt::MSPropertySubscriptExprClass: + case Stmt::ArraySubscriptExprClass: + return CXCursor_ArraySubscriptExpr; + + case Stmt::OMPArraySectionExprClass: + return CXCursor_OMPArraySectionExpr; + + case Stmt::BinaryOperatorClass: + return CXCursor_BinaryOperator; + + case Stmt::CompoundAssignOperatorClass: + return CXCursor_CompoundAssignOperator; + + case Stmt::ConditionalOperatorClass: + return CXCursor_ConditionalOperator; + + case Stmt::CStyleCastExprClass: + return CXCursor_CStyleCastExpr; + + case Stmt::CompoundLiteralExprClass: + return CXCursor_CompoundLiteralExpr; + + case Stmt::InitListExprClass: + return CXCursor_InitListExpr; + + case Stmt::AddrLabelExprClass: + return CXCursor_AddrLabelExpr; + + case Stmt::StmtExprClass: + return CXCursor_StmtExpr; + + case Stmt::GenericSelectionExprClass: + return CXCursor_GenericSelectionExpr; + + case Stmt::GNUNullExprClass: + return CXCursor_GNUNullExpr; + + case Stmt::CXXStaticCastExprClass: + return CXCursor_CXXStaticCastExpr; + + case Stmt::CXXDynamicCastExprClass: + return CXCursor_CXXDynamicCastExpr; + + case Stmt::CXXReinterpretCastExprClass: + return CXCursor_CXXReinterpretCastExpr; + + case Stmt::CXXConstCastExprClass: + return CXCursor_CXXConstCastExpr; + + case Stmt::CXXFunctionalCastExprClass: + return CXCursor_CXXFunctionalCastExpr; + + case Stmt::CXXTypeidExprClass: + return CXCursor_CXXTypeidExpr; + + case Stmt::CXXBoolLiteralExprClass: + return CXCursor_CXXBoolLiteralExpr; + + case Stmt::CXXNullPtrLiteralExprClass: + return CXCursor_CXXNullPtrLiteralExpr; + + case Stmt::CXXThisExprClass: + return CXCursor_CXXThisExpr; + + case Stmt::CXXThrowExprClass: + return CXCursor_CXXThrowExpr; + + case Stmt::CXXNewExprClass: + return CXCursor_CXXNewExpr; + + case Stmt::CXXDeleteExprClass: + return CXCursor_CXXDeleteExpr; + + case Stmt::ObjCStringLiteralClass: + return CXCursor_ObjCStringLiteral; + + case Stmt::ObjCEncodeExprClass: + return CXCursor_ObjCEncodeExpr; + + case Stmt::ObjCSelectorExprClass: + return CXCursor_ObjCSelectorExpr; + + case Stmt::ObjCProtocolExprClass: + return CXCursor_ObjCProtocolExpr; + case Stmt::ObjCBoolLiteralExprClass: + return CXCursor_ObjCBoolLiteralExpr; + + case Stmt::ObjCAvailabilityCheckExprClass: + return CXCursor_ObjCAvailabilityCheckExpr; + + case Stmt::ObjCBridgedCastExprClass: + return CXCursor_ObjCBridgedCastExpr; + + case Stmt::BlockExprClass: + return CXCursor_BlockExpr; + + case Stmt::PackExpansionExprClass: + return CXCursor_PackExpansionExpr; + + case Stmt::SizeOfPackExprClass: + return CXCursor_SizeOfPackExpr; + + case Stmt::DeclRefExprClass: + return CXCursor_DeclRefExpr; + + case Stmt::DependentScopeDeclRefExprClass: + case Stmt::SubstNonTypeTemplateParmExprClass: + case Stmt::SubstNonTypeTemplateParmPackExprClass: + case Stmt::FunctionParmPackExprClass: + case Stmt::UnresolvedLookupExprClass: + case Stmt::TypoExprClass: // A typo could actually be a DeclRef or a MemberRef + return CXCursor_DeclRefExpr; + + case Stmt::CXXDependentScopeMemberExprClass: + case Stmt::CXXPseudoDestructorExprClass: + case Stmt::MemberExprClass: + case Stmt::MSPropertyRefExprClass: + case Stmt::ObjCIsaExprClass: + case Stmt::ObjCIvarRefExprClass: + case Stmt::ObjCPropertyRefExprClass: + case Stmt::UnresolvedMemberExprClass: + return CXCursor_MemberRefExpr; + + case Stmt::CallExprClass: + case Stmt::CXXOperatorCallExprClass: + case Stmt::CXXMemberCallExprClass: + case Stmt::CUDAKernelCallExprClass: + case Stmt::CXXConstructExprClass: + case Stmt::CXXInheritedCtorInitExprClass: + case Stmt::CXXTemporaryObjectExprClass: + case Stmt::CXXUnresolvedConstructExprClass: + case Stmt::UserDefinedLiteralClass: + return CXCursor_CallExpr; + + case Stmt::LambdaExprClass: + return CXCursor_LambdaExpr; + + case Stmt::ObjCMessageExprClass: + return CXCursor_ObjCMessageExpr; + + case Stmt::MSDependentExistsStmtClass: + return CXCursor_UnexposedStmt; + case Stmt::OMPParallelDirectiveClass: + return CXCursor_OMPParallelDirective; + case Stmt::OMPSimdDirectiveClass: + return CXCursor_OMPSimdDirective; + case Stmt::OMPForDirectiveClass: + return CXCursor_OMPForDirective; + case Stmt::OMPForSimdDirectiveClass: + return CXCursor_OMPForSimdDirective; + case Stmt::OMPSectionsDirectiveClass: + return CXCursor_OMPSectionsDirective; + case Stmt::OMPSectionDirectiveClass: + return CXCursor_OMPSectionDirective; + case Stmt::OMPSingleDirectiveClass: + return CXCursor_OMPSingleDirective; + case Stmt::OMPMasterDirectiveClass: + return CXCursor_OMPMasterDirective; + case Stmt::OMPCriticalDirectiveClass: + return CXCursor_OMPCriticalDirective; + case Stmt::OMPParallelForDirectiveClass: + return CXCursor_OMPParallelForDirective; + case Stmt::OMPParallelForSimdDirectiveClass: + return CXCursor_OMPParallelForSimdDirective; + case Stmt::OMPParallelSectionsDirectiveClass: + return CXCursor_OMPParallelSectionsDirective; + case Stmt::OMPTaskDirectiveClass: + return CXCursor_OMPTaskDirective; + case Stmt::OMPTaskyieldDirectiveClass: + return CXCursor_OMPTaskyieldDirective; + case Stmt::OMPBarrierDirectiveClass: + return CXCursor_OMPBarrierDirective; + case Stmt::OMPTaskwaitDirectiveClass: + return CXCursor_OMPTaskwaitDirective; + case Stmt::OMPTaskgroupDirectiveClass: + return CXCursor_OMPTaskgroupDirective; + case Stmt::OMPFlushDirectiveClass: + return CXCursor_OMPFlushDirective; + case Stmt::OMPOrderedDirectiveClass: + return CXCursor_OMPOrderedDirective; + case Stmt::OMPAtomicDirectiveClass: + return CXCursor_OMPAtomicDirective; + case Stmt::OMPTargetDirectiveClass: + return CXCursor_OMPTargetDirective; + case Stmt::OMPTargetDataDirectiveClass: + return CXCursor_OMPTargetDataDirective; + case Stmt::OMPTargetEnterDataDirectiveClass: + return CXCursor_OMPTargetEnterDataDirective; + case Stmt::OMPTargetExitDataDirectiveClass: + return CXCursor_OMPTargetExitDataDirective; + case Stmt::OMPTargetParallelDirectiveClass: + return CXCursor_OMPTargetParallelDirective; + case Stmt::OMPTargetParallelForDirectiveClass: + return CXCursor_OMPTargetParallelForDirective; + case Stmt::OMPTargetUpdateDirectiveClass: + return CXCursor_OMPTargetUpdateDirective; + case Stmt::OMPTeamsDirectiveClass: + return CXCursor_OMPTeamsDirective; + case Stmt::OMPCancellationPointDirectiveClass: + return CXCursor_OMPCancellationPointDirective; + case Stmt::OMPCancelDirectiveClass: + return CXCursor_OMPCancelDirective; + case Stmt::OMPTaskLoopDirectiveClass: + return CXCursor_OMPTaskLoopDirective; + case Stmt::OMPTaskLoopSimdDirectiveClass: + return CXCursor_OMPTaskLoopSimdDirective; + case Stmt::OMPDistributeDirectiveClass: + return CXCursor_OMPDistributeDirective; + case Stmt::OMPDistributeParallelForDirectiveClass: + return CXCursor_OMPDistributeParallelForDirective; + case Stmt::OMPDistributeParallelForSimdDirectiveClass: + return CXCursor_OMPDistributeParallelForSimdDirective; + case Stmt::OMPDistributeSimdDirectiveClass: + return CXCursor_OMPDistributeSimdDirective; + case Stmt::OMPTargetParallelForSimdDirectiveClass: + return CXCursor_OMPTargetParallelForSimdDirective; + case Stmt::OMPTargetSimdDirectiveClass: + return CXCursor_OMPTargetSimdDirective; + case Stmt::OMPTeamsDistributeDirectiveClass: + return CXCursor_OMPTeamsDistributeDirective; + case Stmt::OMPTeamsDistributeSimdDirectiveClass: + return CXCursor_OMPTeamsDistributeSimdDirective; + case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: + return CXCursor_OMPTeamsDistributeParallelForSimdDirective; + case Stmt::OMPTeamsDistributeParallelForDirectiveClass: + return CXCursor_OMPTeamsDistributeParallelForDirective; + case Stmt::OMPTargetTeamsDirectiveClass: + return CXCursor_OMPTargetTeamsDirective; + case Stmt::OMPTargetTeamsDistributeDirectiveClass: + return CXCursor_OMPTargetTeamsDistributeDirective; + case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: + return CXCursor_OMPTargetTeamsDistributeParallelForDirective; + case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: + return CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective; + case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: + return CXCursor_OMPTargetTeamsDistributeSimdDirective; + case Stmt::BuiltinBitCastExprClass: + return CXCursor_BuiltinBitCastExpr; + + default: + return CXCursor_UnexposedExpr; + } +} + +SourceLocation *Expr_getLocation(const Expr *E) { + if (!E) + return nullptr; + if (const ImplicitCastExpr *CE = dyn_cast(&*E)) + return Expr_getLocation(CE->getSubExpr()); + + if (const ObjCMessageExpr *Msg = dyn_cast(&*E)) + return new SourceLocation(/*FIXME:*/Msg->getLeftLoc()); + if (const DeclRefExpr *DRE = dyn_cast(&*E)) + return new SourceLocation(DRE->getLocation()); + if (const MemberExpr *Member = dyn_cast(&*E)) + return new SourceLocation(Member->getMemberLoc()); + if (const ObjCIvarRefExpr *Ivar = dyn_cast(&*E)) + return new SourceLocation(Ivar->getLocation()); + if (const SizeOfPackExpr *SizeOfPack = dyn_cast(&*E)) + return new SourceLocation(SizeOfPack->getPackLoc()); + if (const ObjCPropertyRefExpr *PropRef = dyn_cast(&*E)) + return new SourceLocation(PropRef->getLocation()); + + return new SourceLocation(E->getBeginLoc()); +} + +QualType Expr_getType(const Expr *E) { return E->getType(); } + +BindgenSourceRange Expr_getSourceRange(const Expr *E) { + return BindgenSourceRange(E->getSourceRange()); +} + +const Decl *Type_getDeclaration(QualType T) { + const Type *TP = T.getTypePtrOrNull(); + + if (!TP) + return nullptr; + + const Decl *D = nullptr; + +try_again: + switch (TP->getTypeClass()) { + case Type::Typedef: + D = cast(TP)->getDecl(); + break; + case Type::ObjCObject: + D = cast(TP)->getInterface(); + break; + case Type::ObjCInterface: + D = cast(TP)->getDecl(); + break; + case Type::Record: + case Type::Enum: + D = cast(TP)->getDecl(); + break; + case Type::TemplateSpecialization: + if (const RecordType *Record = TP->getAs()) + D = Record->getDecl(); + else + D = cast(TP)->getTemplateName() + .getAsTemplateDecl(); + break; + + case Type::Auto: + case Type::DeducedTemplateSpecialization: + TP = cast(TP)->getDeducedType().getTypePtrOrNull(); + if (TP) + goto try_again; + break; + + case Type::InjectedClassName: + D = cast(TP)->getDecl(); + break; + + // FIXME: Template type parameters! + + case Type::Elaborated: + TP = cast(TP)->getNamedType().getTypePtrOrNull(); + goto try_again; + + default: + break; + } + + if (!D) + return nullptr; + + return D; +} + +class BindgenVisitor : public RecursiveASTVisitor { + ASTUnit &AST; + Visitor VisitFn; + CXClientData Data; + Node Parent; + +public: + explicit BindgenVisitor(ASTUnit &AST, Visitor V, CXClientData data) : AST(AST), VisitFn(V), Data(data) {} + + bool TraverseDecl(Decl *D) { + switch (VisitFn(Node(D), Parent, &AST, Data)) { + case CXChildVisit_Break: + return false; + case CXChildVisit_Continue: + return true; + case CXChildVisit_Recurse: + auto OldParent = Parent; + Parent = Node(D); + bool res = RecursiveASTVisitor::TraverseDecl(D); + Parent = OldParent; + return res; + } + + llvm_unreachable("Visitor return invalid CXChildVisitResult"); + } + + bool TraverseStmt(Stmt *S) { + switch (VisitFn(Node(cast(S)), Parent, &AST, Data)) { + case CXChildVisit_Break: + return false; + case CXChildVisit_Continue: + return true; + case CXChildVisit_Recurse: + auto OldParent = Parent; + Parent = Node(cast(S)); + bool res = RecursiveASTVisitor::TraverseStmt(S); + Parent = OldParent; + return res; + } + } + + // bool TraverseType(Type *T) { + // Parent = Node(T); + // return RecursiveASTVisitor::TraverseStmt(E); + // } +}; + +void Decl_visitChildren(const Decl *Parent, Visitor V, ASTUnit *Unit, CXClientData data) { + BindgenVisitor visitor(*Unit, V, data); + visitor.TraverseDecl(const_cast(&*Parent)); +} +void Expr_visitChildren(const Expr *Parent, Visitor V, ASTUnit *Unit, CXClientData data) { + BindgenVisitor visitor(*Unit, V, data); + visitor.TraverseStmt(const_cast(&*Parent)); +} + +void tokenize(ASTUnit *TU, BindgenSourceRange Range, CXToken **Tokens, + unsigned *NumTokens) { + if (!Tokens || !NumTokens) + return; + + SmallVector CXTokens; + SourceManager &SourceMgr = TU->getSourceManager(); + std::pair BeginLocInfo = + SourceMgr.getDecomposedSpellingLoc(*Range.B); + std::pair EndLocInfo = + SourceMgr.getDecomposedSpellingLoc(*Range.E); + + // Cannot tokenize across files. + if (BeginLocInfo.first != EndLocInfo.first) + return; + + // Create a lexer + bool Invalid = false; + StringRef Buffer + = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid); + if (Invalid) + return; + + Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), + TU->getASTContext().getLangOpts(), + Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end()); + Lex.SetCommentRetentionState(true); + + // Lex tokens until we hit the end of the range. + const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second; + Token Tok; + bool previousWasAt = false; + do { + // Lex the next token + Lex.LexFromRawLexer(Tok); + if (Tok.is(tok::eof)) + break; + + // Initialize the CXToken. + CXToken CXTok; + + // - Common fields + CXTok.int_data[1] = Tok.getLocation().getRawEncoding(); + CXTok.int_data[2] = Tok.getLength(); + CXTok.int_data[3] = 0; + + // - Kind-specific fields + if (Tok.isLiteral()) { + CXTok.int_data[0] = CXToken_Literal; + CXTok.ptr_data = const_cast(Tok.getLiteralData()); + } else if (Tok.is(tok::raw_identifier)) { + // Lookup the identifier to determine whether we have a keyword. + IdentifierInfo *II + = TU->getPreprocessor().LookUpIdentifierInfo(Tok); + + if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) { + CXTok.int_data[0] = CXToken_Keyword; + } + else { + CXTok.int_data[0] = Tok.is(tok::identifier) + ? CXToken_Identifier + : CXToken_Keyword; + } + CXTok.ptr_data = II; + } else if (Tok.is(tok::comment)) { + CXTok.int_data[0] = CXToken_Comment; + CXTok.ptr_data = nullptr; + } else { + CXTok.int_data[0] = CXToken_Punctuation; + CXTok.ptr_data = nullptr; + } + CXTokens.push_back(CXTok); + previousWasAt = Tok.is(tok::at); + } while (Lex.getBufferLocation() < EffectiveBufferEnd); + + *Tokens = new CXToken[CXTokens.size()]; + memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); + *NumTokens = CXTokens.size(); +} + +void disposeTokens(const ASTUnit *TU, CXToken *Tokens, unsigned NumTokens) { + delete[] Tokens; +} + +CXTokenKind getTokenKind(CXToken token) { + return static_cast(token.int_data[0]); +} + +BindgenStringRef getTokenSpelling(ASTUnit *CXXUnit, CXToken CXTok) { + if (!CXXUnit) + return stringref(); + + switch (getTokenKind(CXTok)) { + case CXToken_Identifier: + case CXToken_Keyword: + // We know we have an IdentifierInfo*, so use that. + return stringref(static_cast(CXTok.ptr_data) + ->getNameStart()); + + case CXToken_Literal: { + // We have stashed the starting pointer in the ptr_data field. Use it. + const char *Text = static_cast(CXTok.ptr_data); + return stringref(StringRef(Text, CXTok.int_data[2])); + } + + case CXToken_Punctuation: + case CXToken_Comment: + break; + } + + // We have to find the starting buffer pointer the hard way, by + // deconstructing the source location. + SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]); + std::pair LocInfo + = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc); + bool Invalid = false; + StringRef Buffer + = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); + if (Invalid) + return stringref(); + + return stringref(Buffer.substr(LocInfo.second, CXTok.int_data[2])); +} + +static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { +#define BTCASE(K) case BuiltinType::K: return CXType_##K + switch (BT->getKind()) { + BTCASE(Void); + BTCASE(Bool); + BTCASE(Char_U); + BTCASE(UChar); + BTCASE(Char16); + BTCASE(Char32); + BTCASE(UShort); + BTCASE(UInt); + BTCASE(ULong); + BTCASE(ULongLong); + BTCASE(UInt128); + BTCASE(Char_S); + BTCASE(SChar); + case BuiltinType::WChar_S: return CXType_WChar; + case BuiltinType::WChar_U: return CXType_WChar; + BTCASE(Short); + BTCASE(Int); + BTCASE(Long); + BTCASE(LongLong); + BTCASE(Int128); + BTCASE(Half); + BTCASE(Float); + BTCASE(Double); + BTCASE(LongDouble); + BTCASE(ShortAccum); + BTCASE(Accum); + BTCASE(LongAccum); + BTCASE(UShortAccum); + BTCASE(UAccum); + BTCASE(ULongAccum); + BTCASE(Float16); + BTCASE(Float128); + BTCASE(NullPtr); + BTCASE(Overload); + BTCASE(Dependent); + BTCASE(ObjCId); + BTCASE(ObjCClass); + BTCASE(ObjCSel); +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) BTCASE(Id); +#include "clang/Basic/OpenCLImageTypes.def" +#undef IMAGE_TYPE +#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) BTCASE(Id); +#include "clang/Basic/OpenCLExtensionTypes.def" + BTCASE(OCLSampler); + BTCASE(OCLEvent); + BTCASE(OCLQueue); + BTCASE(OCLReserveID); + default: + return CXType_Unexposed; + } +#undef BTCASE +} + +CXTypeKind Type_kind(QualType T) { + const Type *TP = T.getTypePtrOrNull(); + if (!TP) + return CXType_Invalid; + +#define TKCASE(K) case Type::K: return CXType_##K + switch (TP->getTypeClass()) { + case Type::Builtin: + return GetBuiltinTypeKind(cast(TP)); + TKCASE(Complex); + TKCASE(Pointer); + TKCASE(BlockPointer); + TKCASE(LValueReference); + TKCASE(RValueReference); + TKCASE(Record); + TKCASE(Enum); + TKCASE(Typedef); + TKCASE(ObjCInterface); + TKCASE(ObjCObject); + TKCASE(ObjCObjectPointer); + TKCASE(ObjCTypeParam); + TKCASE(FunctionNoProto); + TKCASE(FunctionProto); + TKCASE(ConstantArray); + TKCASE(IncompleteArray); + TKCASE(VariableArray); + TKCASE(DependentSizedArray); + TKCASE(Vector); + TKCASE(ExtVector); + TKCASE(MemberPointer); + TKCASE(Auto); + TKCASE(Elaborated); + TKCASE(Pipe); + TKCASE(Attributed); + default: + return CXType_Unexposed; + } +#undef TKCASE +} + +BindgenStringRef Type_getTypeSpelling(QualType T, ASTContext *Context) { + SmallString<64> Str; + llvm::raw_svector_ostream OS(Str); + PrintingPolicy PP(Context->getLangOpts()); + + T.print(OS, PP); + return stringref(OS.str()); +} + +bool Type_isConstQualifiedType(QualType T) { + return T.isLocalConstQualified(); +} + +long long Type_getSizeOf(QualType QT, ASTContext *Context) { + // [expr.sizeof] p2: if reference type, return size of referenced type + if (QT->isReferenceType()) + QT = QT.getNonReferenceType(); + // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete + // enumeration + // Note: We get the cxtype, not the cxcursor, so we can't call + // FieldDecl->isBitField() + // [expr.sizeof] p3: pointer ok, function not ok. + // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error + if (QT->isIncompleteType()) + return CXTypeLayoutError_Incomplete; + if (QT->isDependentType()) + return CXTypeLayoutError_Dependent; + if (!QT->isConstantSizeType()) + return CXTypeLayoutError_NotConstantSize; + if (const auto *Deduced = dyn_cast(QT)) + if (Deduced->getDeducedType().isNull()) + return CXTypeLayoutError_Undeduced; + // [gcc extension] lib/AST/ExprConstant.cpp:1372 + // HandleSizeof : {voidtype,functype} == 1 + // not handled by ASTContext.cpp:1313 getTypeInfoImpl + if (QT->isVoidType() || QT->isFunctionType()) + return 1; + return Context->getTypeSizeInChars(QT).getQuantity(); +} + +long long Type_getAlignOf(QualType QT, ASTContext *Context) { + // [expr.alignof] p1: return size_t value for complete object type, reference + // or array. + // [expr.alignof] p3: if reference type, return size of referenced type + if (QT->isReferenceType()) + QT = QT.getNonReferenceType(); + if (!(QT->isIncompleteArrayType() || !QT->isIncompleteType())) + return CXTypeLayoutError_Incomplete; + if (QT->isDependentType()) + return CXTypeLayoutError_Dependent; + if (const auto *Deduced = dyn_cast(QT)) + if (Deduced->getDeducedType().isNull()) + return CXTypeLayoutError_Undeduced; + // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl + // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1 + // if (QT->isVoidType()) return 1; + return Context->getTypeAlignInChars(QT).getQuantity(); +} + +static Optional> +GetTemplateArguments(QualType Type) { + assert(!Type.isNull()); + if (const auto *Specialization = Type->getAs()) + return Specialization->template_arguments(); + + if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) { + const auto *TemplateDecl = + dyn_cast(RecordDecl); + if (TemplateDecl) + return TemplateDecl->getTemplateArgs().asArray(); + } + + return None; +} + +static unsigned GetTemplateArgumentArraySize(ArrayRef TA) { + unsigned size = TA.size(); + for (const auto &Arg : TA) + if (Arg.getKind() == TemplateArgument::Pack) + size += Arg.pack_size() - 1; + return size; +} + +int Type_getNumTemplateArguments(QualType T) { + auto TA = GetTemplateArguments(T); + if (!TA) + return -1; + + return GetTemplateArgumentArraySize(TA.getValue()); +} + +QualType Type_getArgType(QualType T, unsigned i) { + if (T.isNull()) + return QualType(); + + if (const FunctionProtoType *FD = T->getAs()) { + unsigned numParams = FD->getNumParams(); + if (i >= numParams) + return QualType(); + + return FD->getParamType(i); + } + + return QualType(); +} + +int Type_getNumArgTypes(QualType T) { + if (T.isNull()) + return -1; + + if (const FunctionProtoType *FD = T->getAs()) { + return FD->getNumParams(); + } + + if (T->getAs()) { + return 0; + } + + return -1; +} + +QualType Type_getPointeeType(QualType T) { + const Type *TP = T.getTypePtrOrNull(); + + if (!TP) + return QualType(); + +try_again: + switch (TP->getTypeClass()) { + case Type::Pointer: + T = cast(TP)->getPointeeType(); + break; + case Type::BlockPointer: + T = cast(TP)->getPointeeType(); + break; + case Type::LValueReference: + case Type::RValueReference: + T = cast(TP)->getPointeeType(); + break; + case Type::ObjCObjectPointer: + T = cast(TP)->getPointeeType(); + break; + case Type::MemberPointer: + T = cast(TP)->getPointeeType(); + break; + case Type::Auto: + case Type::DeducedTemplateSpecialization: + TP = cast(TP)->getDeducedType().getTypePtrOrNull(); + if (TP) + goto try_again; + break; + default: + T = QualType(); + break; + } + return T; +} + +QualType Type_getElementType(QualType T) { + QualType ET = QualType(); + const Type *TP = T.getTypePtrOrNull(); + + if (TP) { + switch (TP->getTypeClass()) { + case Type::ConstantArray: + ET = cast (TP)->getElementType(); + break; + case Type::IncompleteArray: + ET = cast (TP)->getElementType(); + break; + case Type::VariableArray: + ET = cast (TP)->getElementType(); + break; + case Type::DependentSizedArray: + ET = cast (TP)->getElementType(); + break; + case Type::Vector: + ET = cast (TP)->getElementType(); + break; + case Type::ExtVector: + ET = cast(TP)->getElementType(); + break; + case Type::Complex: + ET = cast (TP)->getElementType(); + break; + default: + break; + } + } + return ET; +} + +int Type_getNumElements(QualType T) { + long long result = -1; + const Type *TP = T.getTypePtrOrNull(); + + if (TP) { + switch (TP->getTypeClass()) { + case Type::ConstantArray: + result = cast (TP)->getSize().getSExtValue(); + break; + case Type::Vector: + result = cast (TP)->getNumElements(); + break; + case Type::ExtVector: + result = cast(TP)->getNumElements(); + break; + default: + break; + } + } + return result; +} + +QualType Type_getCanonicalType(QualType T, ASTContext *Context) { + if (T.isNull()) + return QualType(); + + return Context->getCanonicalType(T); +} + +bool Type_isFunctionTypeVariadic(QualType T) { + if (T.isNull()) + return false; + + if (const FunctionProtoType *FD = T->getAs()) + return (unsigned)FD->isVariadic(); + + if (T->getAs()) + return true; + + return false; +} + +QualType Type_getResultType(QualType T) { + if (T.isNull()) + return QualType(); + + if (const FunctionType *FD = T->getAs()) + return FD->getReturnType(); + + return QualType(); +} + +CXCallingConv Type_getFunctionTypeCallingConv(QualType T) { + if (T.isNull()) + return CXCallingConv_Invalid; + + if (const FunctionType *FD = T->getAs()) { +#define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X + switch (FD->getCallConv()) { + TCALLINGCONV(C); + TCALLINGCONV(X86StdCall); + TCALLINGCONV(X86FastCall); + TCALLINGCONV(X86ThisCall); + TCALLINGCONV(X86Pascal); + TCALLINGCONV(X86RegCall); + TCALLINGCONV(X86VectorCall); + TCALLINGCONV(AArch64VectorCall); + TCALLINGCONV(Win64); + TCALLINGCONV(X86_64SysV); + TCALLINGCONV(AAPCS); + TCALLINGCONV(AAPCS_VFP); + TCALLINGCONV(IntelOclBicc); + TCALLINGCONV(Swift); + TCALLINGCONV(PreserveMost); + TCALLINGCONV(PreserveAll); + case CC_SpirFunction: return CXCallingConv_Unexposed; + case CC_OpenCLKernel: return CXCallingConv_Unexposed; + break; + } +#undef TCALLINGCONV + } + + return CXCallingConv_Invalid; +} + +QualType Type_getNamedType(QualType T) { + const Type *TP = T.getTypePtrOrNull(); + + if (TP && TP->getTypeClass() == Type::Elaborated) + return cast(TP)->getNamedType(); + + return QualType(); +} + +static Optional TemplateArgumentToQualType(const TemplateArgument &A) { + if (A.getKind() == TemplateArgument::Type) + return A.getAsType(); + return None; +} + +static Optional +FindTemplateArgumentTypeAt(ArrayRef TA, unsigned index) { + unsigned current = 0; + for (const auto &A : TA) { + if (A.getKind() == TemplateArgument::Pack) { + if (index < current + A.pack_size()) + return TemplateArgumentToQualType(A.getPackAsArray()[index - current]); + current += A.pack_size(); + continue; + } + if (current == index) + return TemplateArgumentToQualType(A); + current++; + } + return None; +} + +QualType Type_getTemplateArgumentAsType(QualType T, unsigned index) { + if (T.isNull()) + return QualType(); + + auto TA = GetTemplateArguments(T); + if (!TA) + return QualType(); + + Optional QT = FindTemplateArgumentTypeAt(TA.getValue(), index); + return QT.getValueOr(QualType()); +} + +static void createNullLocation(FileEntry **file, int *line, + int *column, int *offset = nullptr) { + if (file) + *file = nullptr; + if (line) + *line = 0; + if (column) + *column = 0; + if (offset) + *offset = 0; +} + +void getSpellingLocation(ASTUnit *AST, const SourceLocation *location, FileEntry **file, int *line, int *column, int *offset) { + if (!location) + return createNullLocation(file, line, column, offset); + + const SourceManager &SM = AST->getSourceManager(); + // FIXME: This should call SourceManager::getSpellingLoc(). + SourceLocation SpellLoc = SM.getFileLoc(*location); + std::pair LocInfo = SM.getDecomposedLoc(SpellLoc); + FileID FID = LocInfo.first; + unsigned FileOffset = LocInfo.second; + + if (FID.isInvalid()) + return createNullLocation(file, line, column, offset); + + if (file) + *file = const_cast(SM.getFileEntryForID(FID)); + if (line) + *line = SM.getLineNumber(FID, FileOffset); + if (column) + *column = SM.getColumnNumber(FID, FileOffset); + if (offset) + *offset = FileOffset; +} + +CXCommentKind Comment_getKind(const comments::Comment *) { + return CXComment_FullComment; +} + +unsigned Comment_getNumChildren(const comments::Comment *C) { + if (!C) + return 0; + + return C->child_count(); +} + +comments::Comment *Comment_getChild(const comments::Comment *C, unsigned index) { + if (!C || index >= C->child_count()) + return nullptr; + + return *(C->child_begin() + index); +} + +BindgenStringRef HTMLTagComment_getTagName(const comments::Comment *C) { + if (auto *HTML = dyn_cast_or_null(C)) { + return stringref(HTML->getTagName()); + } else { + return stringref(); + } +} + +unsigned HTMLStartTag_getNumAttrs(const comments::Comment *C) { + if (auto *HTML = dyn_cast_or_null(C)) { + return HTML->getNumAttrs(); + } else { + return 0; + } +} + +BindgenStringRef HTMLStartTag_getAttrName(const comments::Comment *C, unsigned i) { + if (auto *HTML = dyn_cast_or_null(C)) { + return stringref(HTML->getAttr(i).Name); + } else { + return stringref(); + } +} + +BindgenStringRef HTMLStartTag_getAttrValue(const comments::Comment *C, unsigned i) { + if (auto *HTML = dyn_cast_or_null(C)) { + return stringref(HTML->getAttr(i).Value); + } else { + return stringref(); + } +} + +BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { + switch (Kind) { + case CXCursor_FunctionDecl: + return stringref("FunctionDecl"); + case CXCursor_TypedefDecl: + return stringref("TypedefDecl"); + case CXCursor_EnumDecl: + return stringref("EnumDecl"); + case CXCursor_EnumConstantDecl: + return stringref("EnumConstantDecl"); + case CXCursor_StructDecl: + return stringref("StructDecl"); + case CXCursor_UnionDecl: + return stringref("UnionDecl"); + case CXCursor_ClassDecl: + return stringref("ClassDecl"); + case CXCursor_FieldDecl: + return stringref("FieldDecl"); + case CXCursor_VarDecl: + return stringref("VarDecl"); + case CXCursor_ParmDecl: + return stringref("ParmDecl"); + case CXCursor_ObjCInterfaceDecl: + return stringref("ObjCInterfaceDecl"); + case CXCursor_ObjCCategoryDecl: + return stringref("ObjCCategoryDecl"); + case CXCursor_ObjCProtocolDecl: + return stringref("ObjCProtocolDecl"); + case CXCursor_ObjCPropertyDecl: + return stringref("ObjCPropertyDecl"); + case CXCursor_ObjCIvarDecl: + return stringref("ObjCIvarDecl"); + case CXCursor_ObjCInstanceMethodDecl: + return stringref("ObjCInstanceMethodDecl"); + case CXCursor_ObjCClassMethodDecl: + return stringref("ObjCClassMethodDecl"); + case CXCursor_ObjCImplementationDecl: + return stringref("ObjCImplementationDecl"); + case CXCursor_ObjCCategoryImplDecl: + return stringref("ObjCCategoryImplDecl"); + case CXCursor_CXXMethod: + return stringref("CXXMethod"); + case CXCursor_UnexposedDecl: + return stringref("UnexposedDecl"); + case CXCursor_ObjCSuperClassRef: + return stringref("ObjCSuperClassRef"); + case CXCursor_ObjCProtocolRef: + return stringref("ObjCProtocolRef"); + case CXCursor_ObjCClassRef: + return stringref("ObjCClassRef"); + case CXCursor_TypeRef: + return stringref("TypeRef"); + case CXCursor_TemplateRef: + return stringref("TemplateRef"); + case CXCursor_NamespaceRef: + return stringref("NamespaceRef"); + case CXCursor_MemberRef: + return stringref("MemberRef"); + case CXCursor_LabelRef: + return stringref("LabelRef"); + case CXCursor_OverloadedDeclRef: + return stringref("OverloadedDeclRef"); + case CXCursor_VariableRef: + return stringref("VariableRef"); + case CXCursor_IntegerLiteral: + return stringref("IntegerLiteral"); + case CXCursor_FixedPointLiteral: + return stringref("FixedPointLiteral"); + case CXCursor_FloatingLiteral: + return stringref("FloatingLiteral"); + case CXCursor_ImaginaryLiteral: + return stringref("ImaginaryLiteral"); + case CXCursor_StringLiteral: + return stringref("StringLiteral"); + case CXCursor_CharacterLiteral: + return stringref("CharacterLiteral"); + case CXCursor_ParenExpr: + return stringref("ParenExpr"); + case CXCursor_UnaryOperator: + return stringref("UnaryOperator"); + case CXCursor_ArraySubscriptExpr: + return stringref("ArraySubscriptExpr"); + case CXCursor_OMPArraySectionExpr: + return stringref("OMPArraySectionExpr"); + case CXCursor_BinaryOperator: + return stringref("BinaryOperator"); + case CXCursor_CompoundAssignOperator: + return stringref("CompoundAssignOperator"); + case CXCursor_ConditionalOperator: + return stringref("ConditionalOperator"); + case CXCursor_CStyleCastExpr: + return stringref("CStyleCastExpr"); + case CXCursor_CompoundLiteralExpr: + return stringref("CompoundLiteralExpr"); + case CXCursor_InitListExpr: + return stringref("InitListExpr"); + case CXCursor_AddrLabelExpr: + return stringref("AddrLabelExpr"); + case CXCursor_StmtExpr: + return stringref("StmtExpr"); + case CXCursor_GenericSelectionExpr: + return stringref("GenericSelectionExpr"); + case CXCursor_GNUNullExpr: + return stringref("GNUNullExpr"); + case CXCursor_CXXStaticCastExpr: + return stringref("CXXStaticCastExpr"); + case CXCursor_CXXDynamicCastExpr: + return stringref("CXXDynamicCastExpr"); + case CXCursor_CXXReinterpretCastExpr: + return stringref("CXXReinterpretCastExpr"); + case CXCursor_CXXConstCastExpr: + return stringref("CXXConstCastExpr"); + case CXCursor_CXXFunctionalCastExpr: + return stringref("CXXFunctionalCastExpr"); + case CXCursor_CXXTypeidExpr: + return stringref("CXXTypeidExpr"); + case CXCursor_CXXBoolLiteralExpr: + return stringref("CXXBoolLiteralExpr"); + case CXCursor_CXXNullPtrLiteralExpr: + return stringref("CXXNullPtrLiteralExpr"); + case CXCursor_CXXThisExpr: + return stringref("CXXThisExpr"); + case CXCursor_CXXThrowExpr: + return stringref("CXXThrowExpr"); + case CXCursor_CXXNewExpr: + return stringref("CXXNewExpr"); + case CXCursor_CXXDeleteExpr: + return stringref("CXXDeleteExpr"); + case CXCursor_UnaryExpr: + return stringref("UnaryExpr"); + case CXCursor_ObjCStringLiteral: + return stringref("ObjCStringLiteral"); + case CXCursor_ObjCBoolLiteralExpr: + return stringref("ObjCBoolLiteralExpr"); + case CXCursor_ObjCAvailabilityCheckExpr: + return stringref("ObjCAvailabilityCheckExpr"); + case CXCursor_ObjCSelfExpr: + return stringref("ObjCSelfExpr"); + case CXCursor_ObjCEncodeExpr: + return stringref("ObjCEncodeExpr"); + case CXCursor_ObjCSelectorExpr: + return stringref("ObjCSelectorExpr"); + case CXCursor_ObjCProtocolExpr: + return stringref("ObjCProtocolExpr"); + case CXCursor_ObjCBridgedCastExpr: + return stringref("ObjCBridgedCastExpr"); + case CXCursor_BlockExpr: + return stringref("BlockExpr"); + case CXCursor_PackExpansionExpr: + return stringref("PackExpansionExpr"); + case CXCursor_SizeOfPackExpr: + return stringref("SizeOfPackExpr"); + case CXCursor_LambdaExpr: + return stringref("LambdaExpr"); + case CXCursor_UnexposedExpr: + return stringref("UnexposedExpr"); + case CXCursor_DeclRefExpr: + return stringref("DeclRefExpr"); + case CXCursor_MemberRefExpr: + return stringref("MemberRefExpr"); + case CXCursor_CallExpr: + return stringref("CallExpr"); + case CXCursor_ObjCMessageExpr: + return stringref("ObjCMessageExpr"); + case CXCursor_BuiltinBitCastExpr: + return stringref("BuiltinBitCastExpr"); + case CXCursor_UnexposedStmt: + return stringref("UnexposedStmt"); + case CXCursor_DeclStmt: + return stringref("DeclStmt"); + case CXCursor_LabelStmt: + return stringref("LabelStmt"); + case CXCursor_CompoundStmt: + return stringref("CompoundStmt"); + case CXCursor_CaseStmt: + return stringref("CaseStmt"); + case CXCursor_DefaultStmt: + return stringref("DefaultStmt"); + case CXCursor_IfStmt: + return stringref("IfStmt"); + case CXCursor_SwitchStmt: + return stringref("SwitchStmt"); + case CXCursor_WhileStmt: + return stringref("WhileStmt"); + case CXCursor_DoStmt: + return stringref("DoStmt"); + case CXCursor_ForStmt: + return stringref("ForStmt"); + case CXCursor_GotoStmt: + return stringref("GotoStmt"); + case CXCursor_IndirectGotoStmt: + return stringref("IndirectGotoStmt"); + case CXCursor_ContinueStmt: + return stringref("ContinueStmt"); + case CXCursor_BreakStmt: + return stringref("BreakStmt"); + case CXCursor_ReturnStmt: + return stringref("ReturnStmt"); + case CXCursor_GCCAsmStmt: + return stringref("GCCAsmStmt"); + case CXCursor_MSAsmStmt: + return stringref("MSAsmStmt"); + case CXCursor_ObjCAtTryStmt: + return stringref("ObjCAtTryStmt"); + case CXCursor_ObjCAtCatchStmt: + return stringref("ObjCAtCatchStmt"); + case CXCursor_ObjCAtFinallyStmt: + return stringref("ObjCAtFinallyStmt"); + case CXCursor_ObjCAtThrowStmt: + return stringref("ObjCAtThrowStmt"); + case CXCursor_ObjCAtSynchronizedStmt: + return stringref("ObjCAtSynchronizedStmt"); + case CXCursor_ObjCAutoreleasePoolStmt: + return stringref("ObjCAutoreleasePoolStmt"); + case CXCursor_ObjCForCollectionStmt: + return stringref("ObjCForCollectionStmt"); + case CXCursor_CXXCatchStmt: + return stringref("CXXCatchStmt"); + case CXCursor_CXXTryStmt: + return stringref("CXXTryStmt"); + case CXCursor_CXXForRangeStmt: + return stringref("CXXForRangeStmt"); + case CXCursor_SEHTryStmt: + return stringref("SEHTryStmt"); + case CXCursor_SEHExceptStmt: + return stringref("SEHExceptStmt"); + case CXCursor_SEHFinallyStmt: + return stringref("SEHFinallyStmt"); + case CXCursor_SEHLeaveStmt: + return stringref("SEHLeaveStmt"); + case CXCursor_NullStmt: + return stringref("NullStmt"); + case CXCursor_InvalidFile: + return stringref("InvalidFile"); + case CXCursor_InvalidCode: + return stringref("InvalidCode"); + case CXCursor_NoDeclFound: + return stringref("NoDeclFound"); + case CXCursor_NotImplemented: + return stringref("NotImplemented"); + case CXCursor_TranslationUnit: + return stringref("TranslationUnit"); + case CXCursor_UnexposedAttr: + return stringref("UnexposedAttr"); + case CXCursor_IBActionAttr: + return stringref("attribute(ibaction)"); + case CXCursor_IBOutletAttr: + return stringref("attribute(iboutlet)"); + case CXCursor_IBOutletCollectionAttr: + return stringref("attribute(iboutletcollection)"); + case CXCursor_CXXFinalAttr: + return stringref("attribute(final)"); + case CXCursor_CXXOverrideAttr: + return stringref("attribute(override)"); + case CXCursor_AnnotateAttr: + return stringref("attribute(annotate)"); + case CXCursor_AsmLabelAttr: + return stringref("asm label"); + case CXCursor_PackedAttr: + return stringref("attribute(packed)"); + case CXCursor_PureAttr: + return stringref("attribute(pure)"); + case CXCursor_ConstAttr: + return stringref("attribute(const)"); + case CXCursor_NoDuplicateAttr: + return stringref("attribute(noduplicate)"); + case CXCursor_CUDAConstantAttr: + return stringref("attribute(constant)"); + case CXCursor_CUDADeviceAttr: + return stringref("attribute(device)"); + case CXCursor_CUDAGlobalAttr: + return stringref("attribute(global)"); + case CXCursor_CUDAHostAttr: + return stringref("attribute(host)"); + case CXCursor_CUDASharedAttr: + return stringref("attribute(shared)"); + case CXCursor_VisibilityAttr: + return stringref("attribute(visibility)"); + case CXCursor_DLLExport: + return stringref("attribute(dllexport)"); + case CXCursor_DLLImport: + return stringref("attribute(dllimport)"); + case CXCursor_NSReturnsRetained: + return stringref("attribute(ns_returns_retained)"); + case CXCursor_NSReturnsNotRetained: + return stringref("attribute(ns_returns_not_retained)"); + case CXCursor_NSReturnsAutoreleased: + return stringref("attribute(ns_returns_autoreleased)"); + case CXCursor_NSConsumesSelf: + return stringref("attribute(ns_consumes_self)"); + case CXCursor_NSConsumed: + return stringref("attribute(ns_consumed)"); + case CXCursor_ObjCException: + return stringref("attribute(objc_exception)"); + case CXCursor_ObjCNSObject: + return stringref("attribute(NSObject)"); + case CXCursor_ObjCIndependentClass: + return stringref("attribute(objc_independent_class)"); + case CXCursor_ObjCPreciseLifetime: + return stringref("attribute(objc_precise_lifetime)"); + case CXCursor_ObjCReturnsInnerPointer: + return stringref("attribute(objc_returns_inner_pointer)"); + case CXCursor_ObjCRequiresSuper: + return stringref("attribute(objc_requires_super)"); + case CXCursor_ObjCRootClass: + return stringref("attribute(objc_root_class)"); + case CXCursor_ObjCSubclassingRestricted: + return stringref("attribute(objc_subclassing_restricted)"); + case CXCursor_ObjCExplicitProtocolImpl: + return stringref("attribute(objc_protocol_requires_explicit_implementation)"); + case CXCursor_ObjCDesignatedInitializer: + return stringref("attribute(objc_designated_initializer)"); + case CXCursor_ObjCRuntimeVisible: + return stringref("attribute(objc_runtime_visible)"); + case CXCursor_ObjCBoxable: + return stringref("attribute(objc_boxable)"); + case CXCursor_FlagEnum: + return stringref("attribute(flag_enum)"); + case CXCursor_PreprocessingDirective: + return stringref("preprocessing directive"); + case CXCursor_MacroDefinition: + return stringref("macro definition"); + case CXCursor_MacroExpansion: + return stringref("macro expansion"); + case CXCursor_InclusionDirective: + return stringref("inclusion directive"); + case CXCursor_Namespace: + return stringref("Namespace"); + case CXCursor_LinkageSpec: + return stringref("LinkageSpec"); + case CXCursor_CXXBaseSpecifier: + return stringref("C++ base class specifier"); + case CXCursor_Constructor: + return stringref("CXXConstructor"); + case CXCursor_Destructor: + return stringref("CXXDestructor"); + case CXCursor_ConversionFunction: + return stringref("CXXConversion"); + case CXCursor_TemplateTypeParameter: + return stringref("TemplateTypeParameter"); + case CXCursor_NonTypeTemplateParameter: + return stringref("NonTypeTemplateParameter"); + case CXCursor_TemplateTemplateParameter: + return stringref("TemplateTemplateParameter"); + case CXCursor_FunctionTemplate: + return stringref("FunctionTemplate"); + case CXCursor_ClassTemplate: + return stringref("ClassTemplate"); + case CXCursor_ClassTemplatePartialSpecialization: + return stringref("ClassTemplatePartialSpecialization"); + case CXCursor_NamespaceAlias: + return stringref("NamespaceAlias"); + case CXCursor_UsingDirective: + return stringref("UsingDirective"); + case CXCursor_UsingDeclaration: + return stringref("UsingDeclaration"); + case CXCursor_TypeAliasDecl: + return stringref("TypeAliasDecl"); + case CXCursor_ObjCSynthesizeDecl: + return stringref("ObjCSynthesizeDecl"); + case CXCursor_ObjCDynamicDecl: + return stringref("ObjCDynamicDecl"); + case CXCursor_CXXAccessSpecifier: + return stringref("CXXAccessSpecifier"); + case CXCursor_ModuleImportDecl: + return stringref("ModuleImport"); + case CXCursor_OMPParallelDirective: + return stringref("OMPParallelDirective"); + case CXCursor_OMPSimdDirective: + return stringref("OMPSimdDirective"); + case CXCursor_OMPForDirective: + return stringref("OMPForDirective"); + case CXCursor_OMPForSimdDirective: + return stringref("OMPForSimdDirective"); + case CXCursor_OMPSectionsDirective: + return stringref("OMPSectionsDirective"); + case CXCursor_OMPSectionDirective: + return stringref("OMPSectionDirective"); + case CXCursor_OMPSingleDirective: + return stringref("OMPSingleDirective"); + case CXCursor_OMPMasterDirective: + return stringref("OMPMasterDirective"); + case CXCursor_OMPCriticalDirective: + return stringref("OMPCriticalDirective"); + case CXCursor_OMPParallelForDirective: + return stringref("OMPParallelForDirective"); + case CXCursor_OMPParallelForSimdDirective: + return stringref("OMPParallelForSimdDirective"); + case CXCursor_OMPParallelSectionsDirective: + return stringref("OMPParallelSectionsDirective"); + case CXCursor_OMPTaskDirective: + return stringref("OMPTaskDirective"); + case CXCursor_OMPTaskyieldDirective: + return stringref("OMPTaskyieldDirective"); + case CXCursor_OMPBarrierDirective: + return stringref("OMPBarrierDirective"); + case CXCursor_OMPTaskwaitDirective: + return stringref("OMPTaskwaitDirective"); + case CXCursor_OMPTaskgroupDirective: + return stringref("OMPTaskgroupDirective"); + case CXCursor_OMPFlushDirective: + return stringref("OMPFlushDirective"); + case CXCursor_OMPOrderedDirective: + return stringref("OMPOrderedDirective"); + case CXCursor_OMPAtomicDirective: + return stringref("OMPAtomicDirective"); + case CXCursor_OMPTargetDirective: + return stringref("OMPTargetDirective"); + case CXCursor_OMPTargetDataDirective: + return stringref("OMPTargetDataDirective"); + case CXCursor_OMPTargetEnterDataDirective: + return stringref("OMPTargetEnterDataDirective"); + case CXCursor_OMPTargetExitDataDirective: + return stringref("OMPTargetExitDataDirective"); + case CXCursor_OMPTargetParallelDirective: + return stringref("OMPTargetParallelDirective"); + case CXCursor_OMPTargetParallelForDirective: + return stringref("OMPTargetParallelForDirective"); + case CXCursor_OMPTargetUpdateDirective: + return stringref("OMPTargetUpdateDirective"); + case CXCursor_OMPTeamsDirective: + return stringref("OMPTeamsDirective"); + case CXCursor_OMPCancellationPointDirective: + return stringref("OMPCancellationPointDirective"); + case CXCursor_OMPCancelDirective: + return stringref("OMPCancelDirective"); + case CXCursor_OMPTaskLoopDirective: + return stringref("OMPTaskLoopDirective"); + case CXCursor_OMPTaskLoopSimdDirective: + return stringref("OMPTaskLoopSimdDirective"); + case CXCursor_OMPDistributeDirective: + return stringref("OMPDistributeDirective"); + case CXCursor_OMPDistributeParallelForDirective: + return stringref("OMPDistributeParallelForDirective"); + case CXCursor_OMPDistributeParallelForSimdDirective: + return stringref("OMPDistributeParallelForSimdDirective"); + case CXCursor_OMPDistributeSimdDirective: + return stringref("OMPDistributeSimdDirective"); + case CXCursor_OMPTargetParallelForSimdDirective: + return stringref("OMPTargetParallelForSimdDirective"); + case CXCursor_OMPTargetSimdDirective: + return stringref("OMPTargetSimdDirective"); + case CXCursor_OMPTeamsDistributeDirective: + return stringref("OMPTeamsDistributeDirective"); + case CXCursor_OMPTeamsDistributeSimdDirective: + return stringref("OMPTeamsDistributeSimdDirective"); + case CXCursor_OMPTeamsDistributeParallelForSimdDirective: + return stringref("OMPTeamsDistributeParallelForSimdDirective"); + case CXCursor_OMPTeamsDistributeParallelForDirective: + return stringref("OMPTeamsDistributeParallelForDirective"); + case CXCursor_OMPTargetTeamsDirective: + return stringref("OMPTargetTeamsDirective"); + case CXCursor_OMPTargetTeamsDistributeDirective: + return stringref("OMPTargetTeamsDistributeDirective"); + case CXCursor_OMPTargetTeamsDistributeParallelForDirective: + return stringref("OMPTargetTeamsDistributeParallelForDirective"); + case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective: + return stringref( + "OMPTargetTeamsDistributeParallelForSimdDirective"); + case CXCursor_OMPTargetTeamsDistributeSimdDirective: + return stringref("OMPTargetTeamsDistributeSimdDirective"); + case CXCursor_OverloadCandidate: + return stringref("OverloadCandidate"); + case CXCursor_TypeAliasTemplateDecl: + return stringref("TypeAliasTemplateDecl"); + case CXCursor_StaticAssert: + return stringref("StaticAssert"); + case CXCursor_FriendDecl: + return stringref("FriendDecl"); + case CXCursor_ConvergentAttr: + return stringref("attribute(convergent)"); + case CXCursor_WarnUnusedAttr: + return stringref("attribute(warn_unused)"); + case CXCursor_WarnUnusedResultAttr: + return stringref("attribute(warn_unused_result)"); + case CXCursor_AlignedAttr: + return stringref("attribute(aligned)"); + } + + llvm_unreachable("Unhandled CXCursorKind"); +} + +BindgenStringRef TypeKind_getSpelling(CXTypeKind K) { + const char *s = nullptr; +#define TKIND(X) case CXType_##X: s = "" #X ""; break + switch (K) { + TKIND(Invalid); + TKIND(Unexposed); + TKIND(Void); + TKIND(Bool); + TKIND(Char_U); + TKIND(UChar); + TKIND(Char16); + TKIND(Char32); + TKIND(UShort); + TKIND(UInt); + TKIND(ULong); + TKIND(ULongLong); + TKIND(UInt128); + TKIND(Char_S); + TKIND(SChar); + case CXType_WChar: s = "WChar"; break; + TKIND(Short); + TKIND(Int); + TKIND(Long); + TKIND(LongLong); + TKIND(Int128); + TKIND(Half); + TKIND(Float); + TKIND(Double); + TKIND(LongDouble); + TKIND(ShortAccum); + TKIND(Accum); + TKIND(LongAccum); + TKIND(UShortAccum); + TKIND(UAccum); + TKIND(ULongAccum); + TKIND(Float16); + TKIND(Float128); + TKIND(NullPtr); + TKIND(Overload); + TKIND(Dependent); + TKIND(ObjCId); + TKIND(ObjCClass); + TKIND(ObjCSel); + TKIND(Complex); + TKIND(Pointer); + TKIND(BlockPointer); + TKIND(LValueReference); + TKIND(RValueReference); + TKIND(Record); + TKIND(Enum); + TKIND(Typedef); + TKIND(ObjCInterface); + TKIND(ObjCObject); + TKIND(ObjCObjectPointer); + TKIND(ObjCTypeParam); + TKIND(FunctionNoProto); + TKIND(FunctionProto); + TKIND(ConstantArray); + TKIND(IncompleteArray); + TKIND(VariableArray); + TKIND(DependentSizedArray); + TKIND(Vector); + TKIND(ExtVector); + TKIND(MemberPointer); + TKIND(Auto); + TKIND(Elaborated); + TKIND(Pipe); + TKIND(Attributed); +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id); +#include "clang/Basic/OpenCLImageTypes.def" +#undef IMAGE_TYPE +#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) TKIND(Id); +#include "clang/Basic/OpenCLExtensionTypes.def" + TKIND(OCLSampler); + TKIND(OCLEvent); + TKIND(OCLQueue); + TKIND(OCLReserveID); + } +#undef TKIND + return stringref(s); +} + +BindgenStringRef FileEntry_getName(FileEntry *F) { + if (!F) + return stringref(); + return stringref(F->getName()); +} + +BindgenStringRef getClangVersion() { + return stringref(getClangFullVersion()); +} + +bool CXXBaseSpecifier_isVirtualBase(const CXXBaseSpecifier *B) { + return B && B->isVirtual(); +} diff --git a/src/clang/ClangAST.hpp b/src/clang/ClangAST.hpp new file mode 100644 index 0000000000..4413ac3d34 --- /dev/null +++ b/src/clang/ClangAST.hpp @@ -0,0 +1,253 @@ +#include "clang-c/Documentation.h" +#include "clang-c/Index.h" + +typedef unsigned long size_t; +typedef unsigned long uint64_t; +typedef long int64_t; + +namespace clang { +struct ASTUnit; +struct TargetInfo; +struct CompoundStmt; +struct Decl; +struct Diagnostic; +struct StoredDiagnostic; +struct TranslationUnitDecl; +struct Expr; +struct Type; +struct FileEntry; +struct SourceLocation; +struct CXXBaseSpecifier; +struct ASTContext; +struct SourceRange; + +namespace comments { +struct Comment; +struct FullComment; +} + +} // namespace clang + +struct EvalResult; + +using namespace clang; + +// template +// struct BindgenNode { +// const T *node; +// ASTUnit *unit; + +// BindgenNode() = default; +// BindgenNode(const T *node, ASTUnit *unit) : node(node), unit(unit) {} + +// BindgenNode makeDeclNode(const Decl *newNode) { +// return BindgenNode(newNode, unit); +// } + +// BindgenNode makeExprNode(const Expr *newNode) { +// return BindgenNode(newNode, unit); +// } + +// operator bool() const { +// return node != nullptr; +// } + +// const T *operator->() const { +// return node; +// } + +// const T &operator*() const { +// return *node; +// } +// }; + +struct BindgenStringRef { + char *s; + size_t len; +}; + +#ifndef BINDGEN_IMPLEMENTATION +namespace clang { +struct QualType { + void *ptr; +}; +} +#endif + +struct BindgenStringRefSet { + BindgenStringRef *strings; + size_t len; + + BindgenStringRefSet() : strings(nullptr), len(0) {} +}; + + +struct BindgenSourceRange { + SourceLocation *B; + SourceLocation *E; + + BindgenSourceRange(const SourceRange &range); +}; + + + +void freeString(BindgenStringRef s); +char *cString(BindgenStringRef s); + +ASTContext *ASTUnit_getContext(ASTUnit *); +ASTUnit *parseTranslationUnit(const char *source_filename, + const char *const *command_line_args, + int num_command_line_args, + int options); +void disposeASTUnit(ASTUnit *AU); +unsigned ASTUnit_getNumDiagnostics(const ASTUnit *AU); +const StoredDiagnostic *ASTUnit_getDiagnostic(const ASTUnit *AU, unsigned i); +const TargetInfo *ASTUnit_getTargetInfo(ASTUnit *AU); + +int TargetInfo_getPointerWidth(const TargetInfo *TI); +BindgenStringRef TargetInfo_getTriple(const TargetInfo *TI); + +EvalResult *Expr_Evaluate(const Expr *E, ASTContext *Ctx); +EvalResult *Decl_Evaluate(const Decl *D, ASTContext *Ctx); +CXEvalResultKind EvalResult_getKind(EvalResult *); +double EvalResult_getAsDouble(EvalResult *); +bool EvalResult_isUnsignedInt(EvalResult *); +unsigned long long EvalResult_getAsUnsigned(EvalResult *); +long long EvalResult_getAsLongLong(EvalResult *); +BindgenStringRef EvalResult_getAsStr(EvalResult *); + +BindgenStringRef Diagnostic_format(const StoredDiagnostic *); +CXDiagnosticSeverity Diagnostic_getSeverity(const StoredDiagnostic *); + +const Decl *getTranslationUnitDecl(ASTUnit *); + +bool CursorKind_isInvalid(CXCursorKind kind); + +const Decl *Decl_getLexicalParent(const Decl *D); +const Decl *Decl_getSemanticParent(const Decl *D); +const Decl *Decl_getDefinition(const Decl *D); +const Decl *Decl_getReferenced(const Decl *D); +const Decl *Decl_getCanonical(const Decl *D); +const Decl *Decl_getSpecializedTemplate(const Decl *D); +CXCursorKind Decl_getTemplateCursorKind(const Decl *D); +const Decl *Decl_getArgument(const Decl *D, unsigned i); +int Decl_getNumArguments(const Decl *D); +BindgenStringRef Decl_getUSR(const Decl *D); +BindgenStringRef Decl_getSpelling(const Decl *D); +BindgenStringRef Decl_getDisplayName(const Decl *D); +BindgenStringRef Decl_getMangling(const Decl *D, ASTContext *); +BindgenStringRefSet Decl_getCXXManglings(const Decl *D, ASTContext *); +int Decl_getNumTemplateArguments(const Decl *D); +CXCursorKind Decl_getCXCursorKind(const Decl *D); +bool Decl_isDefinition(const Decl *D); +SourceLocation *Decl_getLocation(const Decl *D); +BindgenStringRef Decl_getRawCommentText(const Decl *D, ASTContext *); +comments::Comment *Decl_getParsedComment(const Decl *D, ASTContext *); +QualType Decl_getType(const Decl *D, ASTContext *); +bool Decl_isFunctionInlined(const Decl *D); +int Decl_getFieldDeclBitWidth(const Decl *D, ASTContext *); +QualType Decl_getEnumDeclIntegerType(const Decl *D); +int64_t Decl_getEnumConstantValue(const Decl *D); +uint64_t Decl_getEnumConstantUnsignedValue(const Decl *D); +long long Decl_getOffsetOfField(const Decl *D, ASTContext *); +BindgenSourceRange Decl_getSourceRange(const Decl *D); +QualType Decl_getTypedefDeclUnderlyingType(const Decl *D); +CXLinkageKind Decl_getLinkage(const Decl *D); +CXVisibilityKind Decl_getVisibility(const Decl *D); +CX_CXXAccessSpecifier Decl_getAccess(const Decl *D); +bool CXXField_isMutable(const Decl *D); +bool CXXMethod_isStatic(const Decl *D); +bool CXXMethod_isConst(const Decl *D); +bool CXXMethod_isVirtual(const Decl *D); +bool CXXMethod_isPureVirtual(const Decl *D); +QualType Decl_getResultType(const Decl *D, ASTContext *); + + +const Expr *Expr_getArgument(const Expr *E, unsigned i); +// const Decl *Expr_getSemanticParent(const Expr *); +int Expr_getNumArguments(const Expr *E); +BindgenStringRef Expr_getUSR(const Expr *E); +BindgenStringRef Expr_getSpelling(const Expr *E); +BindgenStringRef Expr_getDisplayName(const Expr *E); +BindgenStringRef Expr_getMangling(const Expr *E); +BindgenStringRefSet Expr_getCXXManglings(const Expr *E); +CXCursorKind Expr_getCXCursorKind(const Expr *E); +SourceLocation *Expr_getLocation(const Expr *E); +BindgenStringRef Expr_getRawCommentText(const Expr *E); +comments::FullComment *Expr_getParsedComment(const Expr *E); +QualType Expr_getType(const Expr *E); +BindgenSourceRange Expr_getSourceRange(const Expr *E); + +const Decl *Type_getDeclaration(QualType); + +struct Node { + CXCursorKind kind; + + union { + const Decl *decl; + const Expr *expr; + Type *type; + } ptr; + + Node() : kind(CXCursor_NotImplemented) {} + Node(const Decl *decl) : kind(Decl_getCXCursorKind(decl)) { + ptr.decl = decl; + } + Node(const Expr *expr) : kind(Expr_getCXCursorKind(expr)) { + ptr.expr = expr; + } + // Node(Type *T) : kind(Type_getCXCursorKind(T)) { + // ptr.expr = expr; + // } +}; + +typedef CXChildVisitResult (*Visitor)(Node N, Node parent, + ASTUnit *unit, + CXClientData client_data); + +void Decl_visitChildren(const Decl *Parent, Visitor V, ASTUnit *Unit, CXClientData data); +void Expr_visitChildren(const Expr *Parent, Visitor V, ASTUnit *Unit, CXClientData data); + +void tokenize(ASTUnit *TU, BindgenSourceRange Range, CXToken **Tokens, + unsigned *NumTokens); +void disposeTokens(const ASTUnit *TU, CXToken *Tokens, unsigned NumTokens); + +CXTokenKind getTokenKind(CXToken token); +BindgenStringRef getTokenSpelling(ASTUnit *TU, CXToken token); + +CXTypeKind Type_kind(QualType); +BindgenStringRef Type_getTypeSpelling(QualType, ASTContext *); +bool Type_isConstQualifiedType(QualType); +long long Type_getSizeOf(QualType, ASTContext *); +long long Type_getAlignOf(QualType, ASTContext *); +int Type_getNumTemplateArguments(QualType); +QualType Type_getArgType(QualType T, unsigned index); +int Type_getNumArgTypes(QualType); +QualType Type_getPointeeType(QualType); +QualType Type_getElementType(QualType); +int Type_getNumElements(QualType); +QualType Type_getCanonicalType(QualType, ASTContext *); +bool Type_isFunctionTypeVariadic(QualType); +QualType Type_getResultType(QualType); +CXCallingConv Type_getFunctionTypeCallingConv(QualType); +QualType Type_getNamedType(QualType); +QualType Type_getTemplateArgumentAsType(QualType T, unsigned index); + +void getSpellingLocation(ASTUnit *AST, const SourceLocation *T, FileEntry **file, int *line, int *col, int *off); + +CXCommentKind Comment_getKind(const comments::Comment *); +unsigned Comment_getNumChildren(const comments::Comment *); +comments::Comment *Comment_getChild(const comments::Comment *, unsigned index); +BindgenStringRef HTMLTagComment_getTagName(const comments::Comment *); +unsigned HTMLStartTag_getNumAttrs(const comments::Comment *); +BindgenStringRef HTMLStartTag_getAttrName(const comments::Comment *, unsigned); +BindgenStringRef HTMLStartTag_getAttrValue(const comments::Comment *, unsigned); + +BindgenStringRef CursorKind_getSpelling(CXCursorKind); +BindgenStringRef TypeKind_getSpelling(CXTypeKind); + +BindgenStringRef FileEntry_getName(FileEntry *); + +BindgenStringRef getClangVersion(); + +bool CXXBaseSpecifier_isVirtualBase(const CXXBaseSpecifier *); diff --git a/src/clang/clangtool.rs b/src/clang/clangtool.rs new file mode 100644 index 0000000000..0694faa433 --- /dev/null +++ b/src/clang/clangtool.rs @@ -0,0 +1,7160 @@ +/* automatically generated by rust-bindgen */ + +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit { + storage: Storage, + align: [Align; 0], +} +impl __BindgenBitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 + <= self.storage.as_ref().len() + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 + <= self.storage.as_ref().len() + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } +} +pub const _TIME_H: u32 = 1; +pub const _FEATURES_H: u32 = 1; +pub const _ISOC95_SOURCE: u32 = 1; +pub const _ISOC99_SOURCE: u32 = 1; +pub const _ISOC11_SOURCE: u32 = 1; +pub const _POSIX_SOURCE: u32 = 1; +pub const _POSIX_C_SOURCE: u32 = 200809; +pub const _XOPEN_SOURCE: u32 = 700; +pub const _XOPEN_SOURCE_EXTENDED: u32 = 1; +pub const _LARGEFILE64_SOURCE: u32 = 1; +pub const _DEFAULT_SOURCE: u32 = 1; +pub const _ATFILE_SOURCE: u32 = 1; +pub const __USE_ISOC11: u32 = 1; +pub const __USE_ISOC99: u32 = 1; +pub const __USE_ISOC95: u32 = 1; +pub const __USE_ISOCXX11: u32 = 1; +pub const __USE_POSIX: u32 = 1; +pub const __USE_POSIX2: u32 = 1; +pub const __USE_POSIX199309: u32 = 1; +pub const __USE_POSIX199506: u32 = 1; +pub const __USE_XOPEN2K: u32 = 1; +pub const __USE_XOPEN2K8: u32 = 1; +pub const __USE_XOPEN: u32 = 1; +pub const __USE_XOPEN_EXTENDED: u32 = 1; +pub const __USE_UNIX98: u32 = 1; +pub const _LARGEFILE_SOURCE: u32 = 1; +pub const __USE_XOPEN2K8XSI: u32 = 1; +pub const __USE_XOPEN2KXSI: u32 = 1; +pub const __USE_LARGEFILE: u32 = 1; +pub const __USE_LARGEFILE64: u32 = 1; +pub const __USE_MISC: u32 = 1; +pub const __USE_ATFILE: u32 = 1; +pub const __USE_GNU: u32 = 1; +pub const __USE_FORTIFY_LEVEL: u32 = 0; +pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0; +pub const __GLIBC_USE_DEPRECATED_SCANF: u32 = 0; +pub const _STDC_PREDEF_H: u32 = 1; +pub const __STDC_IEC_559__: u32 = 1; +pub const __STDC_IEC_559_COMPLEX__: u32 = 1; +pub const __STDC_ISO_10646__: u32 = 201706; +pub const __GNU_LIBRARY__: u32 = 6; +pub const __GLIBC__: u32 = 2; +pub const __GLIBC_MINOR__: u32 = 30; +pub const _SYS_CDEFS_H: u32 = 1; +pub const __glibc_c99_flexarr_available: u32 = 1; +pub const __WORDSIZE: u32 = 64; +pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; +pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __HAVE_GENERIC_SELECTION: u32 = 0; +pub const _BITS_TIME_H: u32 = 1; +pub const _BITS_TYPES_H: u32 = 1; +pub const __TIMESIZE: u32 = 64; +pub const _BITS_TYPESIZES_H: u32 = 1; +pub const __OFF_T_MATCHES_OFF64_T: u32 = 1; +pub const __INO_T_MATCHES_INO64_T: u32 = 1; +pub const __RLIM_T_MATCHES_RLIM64_T: u32 = 1; +pub const __FD_SETSIZE: u32 = 1024; +pub const _BITS_TIME64_H: u32 = 1; +pub const CLOCK_REALTIME: u32 = 0; +pub const CLOCK_MONOTONIC: u32 = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: u32 = 2; +pub const CLOCK_THREAD_CPUTIME_ID: u32 = 3; +pub const CLOCK_MONOTONIC_RAW: u32 = 4; +pub const CLOCK_REALTIME_COARSE: u32 = 5; +pub const CLOCK_MONOTONIC_COARSE: u32 = 6; +pub const CLOCK_BOOTTIME: u32 = 7; +pub const CLOCK_REALTIME_ALARM: u32 = 8; +pub const CLOCK_BOOTTIME_ALARM: u32 = 9; +pub const CLOCK_TAI: u32 = 11; +pub const TIMER_ABSTIME: u32 = 1; +pub const _BITS_TIMEX_H: u32 = 1; +pub const __timeval_defined: u32 = 1; +pub const ADJ_OFFSET: u32 = 1; +pub const ADJ_FREQUENCY: u32 = 2; +pub const ADJ_MAXERROR: u32 = 4; +pub const ADJ_ESTERROR: u32 = 8; +pub const ADJ_STATUS: u32 = 16; +pub const ADJ_TIMECONST: u32 = 32; +pub const ADJ_TAI: u32 = 128; +pub const ADJ_SETOFFSET: u32 = 256; +pub const ADJ_MICRO: u32 = 4096; +pub const ADJ_NANO: u32 = 8192; +pub const ADJ_TICK: u32 = 16384; +pub const ADJ_OFFSET_SINGLESHOT: u32 = 32769; +pub const ADJ_OFFSET_SS_READ: u32 = 40961; +pub const MOD_OFFSET: u32 = 1; +pub const MOD_FREQUENCY: u32 = 2; +pub const MOD_MAXERROR: u32 = 4; +pub const MOD_ESTERROR: u32 = 8; +pub const MOD_STATUS: u32 = 16; +pub const MOD_TIMECONST: u32 = 32; +pub const MOD_CLKB: u32 = 16384; +pub const MOD_CLKA: u32 = 32769; +pub const MOD_TAI: u32 = 128; +pub const MOD_MICRO: u32 = 4096; +pub const MOD_NANO: u32 = 8192; +pub const STA_PLL: u32 = 1; +pub const STA_PPSFREQ: u32 = 2; +pub const STA_PPSTIME: u32 = 4; +pub const STA_FLL: u32 = 8; +pub const STA_INS: u32 = 16; +pub const STA_DEL: u32 = 32; +pub const STA_UNSYNC: u32 = 64; +pub const STA_FREQHOLD: u32 = 128; +pub const STA_PPSSIGNAL: u32 = 256; +pub const STA_PPSJITTER: u32 = 512; +pub const STA_PPSWANDER: u32 = 1024; +pub const STA_PPSERROR: u32 = 2048; +pub const STA_CLOCKERR: u32 = 4096; +pub const STA_NANO: u32 = 8192; +pub const STA_MODE: u32 = 16384; +pub const STA_CLK: u32 = 32768; +pub const STA_RONLY: u32 = 65280; +pub const __clock_t_defined: u32 = 1; +pub const __time_t_defined: u32 = 1; +pub const __struct_tm_defined: u32 = 1; +pub const _STRUCT_TIMESPEC: u32 = 1; +pub const __clockid_t_defined: u32 = 1; +pub const __timer_t_defined: u32 = 1; +pub const __itimerspec_defined: u32 = 1; +pub const _BITS_TYPES_LOCALE_T_H: u32 = 1; +pub const _BITS_TYPES___LOCALE_T_H: u32 = 1; +pub const TIME_UTC: u32 = 1; +pub const CINDEX_VERSION_MAJOR: u32 = 0; +pub const CINDEX_VERSION_MINOR: u32 = 59; +pub type size_t = ::std::os::raw::c_ulong; +pub type __u_char = ::std::os::raw::c_uchar; +pub type __u_short = ::std::os::raw::c_ushort; +pub type __u_int = ::std::os::raw::c_uint; +pub type __u_long = ::std::os::raw::c_ulong; +pub type __int8_t = ::std::os::raw::c_schar; +pub type __uint8_t = ::std::os::raw::c_uchar; +pub type __int16_t = ::std::os::raw::c_short; +pub type __uint16_t = ::std::os::raw::c_ushort; +pub type __int32_t = ::std::os::raw::c_int; +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __int64_t = ::std::os::raw::c_long; +pub type __uint64_t = ::std::os::raw::c_ulong; +pub type __int_least8_t = __int8_t; +pub type __uint_least8_t = __uint8_t; +pub type __int_least16_t = __int16_t; +pub type __uint_least16_t = __uint16_t; +pub type __int_least32_t = __int32_t; +pub type __uint_least32_t = __uint32_t; +pub type __int_least64_t = __int64_t; +pub type __uint_least64_t = __uint64_t; +pub type __quad_t = ::std::os::raw::c_long; +pub type __u_quad_t = ::std::os::raw::c_ulong; +pub type __intmax_t = ::std::os::raw::c_long; +pub type __uintmax_t = ::std::os::raw::c_ulong; +pub type __dev_t = ::std::os::raw::c_ulong; +pub type __uid_t = ::std::os::raw::c_uint; +pub type __gid_t = ::std::os::raw::c_uint; +pub type __ino_t = ::std::os::raw::c_ulong; +pub type __ino64_t = ::std::os::raw::c_ulong; +pub type __mode_t = ::std::os::raw::c_uint; +pub type __nlink_t = ::std::os::raw::c_ulong; +pub type __off_t = ::std::os::raw::c_long; +pub type __off64_t = ::std::os::raw::c_long; +pub type __pid_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __fsid_t { + pub __val: [::std::os::raw::c_int; 2usize], +} +#[test] +fn bindgen_test_layout___fsid_t() { + assert_eq!( + ::std::mem::size_of::<__fsid_t>(), + 8usize, + concat!("Size of: ", stringify!(__fsid_t)) + ); + assert_eq!( + ::std::mem::align_of::<__fsid_t>(), + 4usize, + concat!("Alignment of ", stringify!(__fsid_t)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<__fsid_t>())).__val as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__fsid_t), + "::", + stringify!(__val) + ) + ); +} +pub type __clock_t = ::std::os::raw::c_long; +pub type __rlim_t = ::std::os::raw::c_ulong; +pub type __rlim64_t = ::std::os::raw::c_ulong; +pub type __id_t = ::std::os::raw::c_uint; +pub type __time_t = ::std::os::raw::c_long; +pub type __useconds_t = ::std::os::raw::c_uint; +pub type __suseconds_t = ::std::os::raw::c_long; +pub type __daddr_t = ::std::os::raw::c_int; +pub type __key_t = ::std::os::raw::c_int; +pub type __clockid_t = ::std::os::raw::c_int; +pub type __timer_t = *mut ::std::os::raw::c_void; +pub type __blksize_t = ::std::os::raw::c_long; +pub type __blkcnt_t = ::std::os::raw::c_long; +pub type __blkcnt64_t = ::std::os::raw::c_long; +pub type __fsblkcnt_t = ::std::os::raw::c_ulong; +pub type __fsblkcnt64_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt64_t = ::std::os::raw::c_ulong; +pub type __fsword_t = ::std::os::raw::c_long; +pub type __ssize_t = ::std::os::raw::c_long; +pub type __syscall_slong_t = ::std::os::raw::c_long; +pub type __syscall_ulong_t = ::std::os::raw::c_ulong; +pub type __loff_t = __off64_t; +pub type __caddr_t = *mut ::std::os::raw::c_char; +pub type __intptr_t = ::std::os::raw::c_long; +pub type __socklen_t = ::std::os::raw::c_uint; +pub type __sig_atomic_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timeval { + pub tv_sec: __time_t, + pub tv_usec: __suseconds_t, +} +#[test] +fn bindgen_test_layout_timeval() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(timeval)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(timeval)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).tv_sec as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(timeval), + "::", + stringify!(tv_sec) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).tv_usec as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(timeval), + "::", + stringify!(tv_usec) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct timex { + pub modes: ::std::os::raw::c_uint, + pub offset: __syscall_slong_t, + pub freq: __syscall_slong_t, + pub maxerror: __syscall_slong_t, + pub esterror: __syscall_slong_t, + pub status: ::std::os::raw::c_int, + pub constant: __syscall_slong_t, + pub precision: __syscall_slong_t, + pub tolerance: __syscall_slong_t, + pub time: timeval, + pub tick: __syscall_slong_t, + pub ppsfreq: __syscall_slong_t, + pub jitter: __syscall_slong_t, + pub shift: ::std::os::raw::c_int, + pub stabil: __syscall_slong_t, + pub jitcnt: __syscall_slong_t, + pub calcnt: __syscall_slong_t, + pub errcnt: __syscall_slong_t, + pub stbcnt: __syscall_slong_t, + pub tai: ::std::os::raw::c_int, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 44usize], u8>, +} +#[test] +fn bindgen_test_layout_timex() { + assert_eq!( + ::std::mem::size_of::(), + 208usize, + concat!("Size of: ", stringify!(timex)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(timex)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).modes as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(modes) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).offset as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(offset) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).freq as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(freq) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).maxerror as *const _ as usize + }, + 24usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(maxerror) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).esterror as *const _ as usize + }, + 32usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(esterror) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).status as *const _ as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(status) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).constant as *const _ as usize + }, + 48usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(constant) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).precision as *const _ as usize + }, + 56usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(precision) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).tolerance as *const _ as usize + }, + 64usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(tolerance) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).time as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tick as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(tick) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ppsfreq as *const _ as usize + }, + 96usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(ppsfreq) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).jitter as *const _ as usize + }, + 104usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(jitter) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).shift as *const _ as usize }, + 112usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(shift) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).stabil as *const _ as usize + }, + 120usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(stabil) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).jitcnt as *const _ as usize + }, + 128usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(jitcnt) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).calcnt as *const _ as usize + }, + 136usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(calcnt) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).errcnt as *const _ as usize + }, + 144usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(errcnt) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).stbcnt as *const _ as usize + }, + 152usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(stbcnt) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tai as *const _ as usize }, + 160usize, + concat!( + "Offset of field: ", + stringify!(timex), + "::", + stringify!(tai) + ) + ); +} +extern "C" { + pub fn clock_adjtime( + __clock_id: __clockid_t, + __utx: *mut timex, + ) -> ::std::os::raw::c_int; +} +pub type clock_t = __clock_t; +pub type time_t = __time_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct tm { + pub tm_sec: ::std::os::raw::c_int, + pub tm_min: ::std::os::raw::c_int, + pub tm_hour: ::std::os::raw::c_int, + pub tm_mday: ::std::os::raw::c_int, + pub tm_mon: ::std::os::raw::c_int, + pub tm_year: ::std::os::raw::c_int, + pub tm_wday: ::std::os::raw::c_int, + pub tm_yday: ::std::os::raw::c_int, + pub tm_isdst: ::std::os::raw::c_int, + pub tm_gmtoff: ::std::os::raw::c_long, + pub tm_zone: *const ::std::os::raw::c_char, +} +#[test] +fn bindgen_test_layout_tm() { + assert_eq!( + ::std::mem::size_of::(), + 56usize, + concat!("Size of: ", stringify!(tm)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(tm)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_sec as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_sec) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_min as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_min) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_hour as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_hour) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_mday as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_mday) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_mon as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_mon) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_year as *const _ as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_year) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_wday as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_wday) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_yday as *const _ as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_yday) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_isdst as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_isdst) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).tm_gmtoff as *const _ as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_gmtoff) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_zone as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_zone) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timespec { + pub tv_sec: __time_t, + pub tv_nsec: __syscall_slong_t, +} +#[test] +fn bindgen_test_layout_timespec() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(timespec)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(timespec)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).tv_sec as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(timespec), + "::", + stringify!(tv_sec) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).tv_nsec as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(timespec), + "::", + stringify!(tv_nsec) + ) + ); +} +pub type clockid_t = __clockid_t; +pub type timer_t = __timer_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct itimerspec { + pub it_interval: timespec, + pub it_value: timespec, +} +#[test] +fn bindgen_test_layout_itimerspec() { + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(itimerspec)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(itimerspec)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).it_interval as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(itimerspec), + "::", + stringify!(it_interval) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).it_value as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(itimerspec), + "::", + stringify!(it_value) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sigevent { + _unused: [u8; 0], +} +pub type pid_t = __pid_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __locale_struct { + pub __locales: [*mut __locale_data; 13usize], + pub __ctype_b: *const ::std::os::raw::c_ushort, + pub __ctype_tolower: *const ::std::os::raw::c_int, + pub __ctype_toupper: *const ::std::os::raw::c_int, + pub __names: [*const ::std::os::raw::c_char; 13usize], +} +#[test] +fn bindgen_test_layout___locale_struct() { + assert_eq!( + ::std::mem::size_of::<__locale_struct>(), + 232usize, + concat!("Size of: ", stringify!(__locale_struct)) + ); + assert_eq!( + ::std::mem::align_of::<__locale_struct>(), + 8usize, + concat!("Alignment of ", stringify!(__locale_struct)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<__locale_struct>())).__locales as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__locale_struct), + "::", + stringify!(__locales) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<__locale_struct>())).__ctype_b as *const _ + as usize + }, + 104usize, + concat!( + "Offset of field: ", + stringify!(__locale_struct), + "::", + stringify!(__ctype_b) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<__locale_struct>())).__ctype_tolower + as *const _ as usize + }, + 112usize, + concat!( + "Offset of field: ", + stringify!(__locale_struct), + "::", + stringify!(__ctype_tolower) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<__locale_struct>())).__ctype_toupper + as *const _ as usize + }, + 120usize, + concat!( + "Offset of field: ", + stringify!(__locale_struct), + "::", + stringify!(__ctype_toupper) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<__locale_struct>())).__names as *const _ + as usize + }, + 128usize, + concat!( + "Offset of field: ", + stringify!(__locale_struct), + "::", + stringify!(__names) + ) + ); +} +pub type __locale_t = *mut __locale_struct; +pub type locale_t = __locale_t; +extern "C" { + pub fn clock() -> clock_t; +} +extern "C" { + pub fn time(__timer: *mut time_t) -> time_t; +} +extern "C" { + pub fn difftime(__time1: time_t, __time0: time_t) -> f64; +} +extern "C" { + pub fn mktime(__tp: *mut tm) -> time_t; +} +extern "C" { + pub fn strftime( + __s: *mut ::std::os::raw::c_char, + __maxsize: size_t, + __format: *const ::std::os::raw::c_char, + __tp: *const tm, + ) -> size_t; +} +extern "C" { + pub fn strptime( + __s: *const ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + __tp: *mut tm, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strftime_l( + __s: *mut ::std::os::raw::c_char, + __maxsize: size_t, + __format: *const ::std::os::raw::c_char, + __tp: *const tm, + __loc: locale_t, + ) -> size_t; +} +extern "C" { + pub fn strptime_l( + __s: *const ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + __tp: *mut tm, + __loc: locale_t, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn gmtime(__timer: *const time_t) -> *mut tm; +} +extern "C" { + pub fn localtime(__timer: *const time_t) -> *mut tm; +} +extern "C" { + pub fn gmtime_r(__timer: *const time_t, __tp: *mut tm) -> *mut tm; +} +extern "C" { + pub fn localtime_r(__timer: *const time_t, __tp: *mut tm) -> *mut tm; +} +extern "C" { + pub fn asctime(__tp: *const tm) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn ctime(__timer: *const time_t) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn asctime_r( + __tp: *const tm, + __buf: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn ctime_r( + __timer: *const time_t, + __buf: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub static mut __tzname: [*mut ::std::os::raw::c_char; 2usize]; +} +extern "C" { + pub static mut __daylight: ::std::os::raw::c_int; +} +extern "C" { + pub static mut __timezone: ::std::os::raw::c_long; +} +extern "C" { + pub static mut tzname: [*mut ::std::os::raw::c_char; 2usize]; +} +extern "C" { + pub fn tzset(); +} +extern "C" { + pub static mut daylight: ::std::os::raw::c_int; +} +extern "C" { + pub static mut timezone: ::std::os::raw::c_long; +} +extern "C" { + pub fn stime(__when: *const time_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timegm(__tp: *mut tm) -> time_t; +} +extern "C" { + pub fn timelocal(__tp: *mut tm) -> time_t; +} +extern "C" { + pub fn dysize(__year: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn nanosleep( + __requested_time: *const timespec, + __remaining: *mut timespec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_getres( + __clock_id: clockid_t, + __res: *mut timespec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_gettime( + __clock_id: clockid_t, + __tp: *mut timespec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_settime( + __clock_id: clockid_t, + __tp: *const timespec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_nanosleep( + __clock_id: clockid_t, + __flags: ::std::os::raw::c_int, + __req: *const timespec, + __rem: *mut timespec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_getcpuclockid( + __pid: pid_t, + __clock_id: *mut clockid_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_create( + __clock_id: clockid_t, + __evp: *mut sigevent, + __timerid: *mut timer_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_delete(__timerid: timer_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_settime( + __timerid: timer_t, + __flags: ::std::os::raw::c_int, + __value: *const itimerspec, + __ovalue: *mut itimerspec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_gettime( + __timerid: timer_t, + __value: *mut itimerspec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_getoverrun(__timerid: timer_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timespec_get( + __ts: *mut timespec, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub static mut getdate_err: ::std::os::raw::c_int; +} +extern "C" { + pub fn getdate(__string: *const ::std::os::raw::c_char) -> *mut tm; +} +extern "C" { + pub fn getdate_r( + __string: *const ::std::os::raw::c_char, + __resbufp: *mut tm, + ) -> ::std::os::raw::c_int; +} +pub mod CXErrorCode { + pub type Type = u32; + pub const CXError_Success: Type = 0; + pub const CXError_Failure: Type = 1; + pub const CXError_Crashed: Type = 2; + pub const CXError_InvalidArguments: Type = 3; + pub const CXError_ASTReadError: Type = 4; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXString { + pub data: *const ::std::os::raw::c_void, + pub private_flags: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_CXString() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(CXString)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXString)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).data as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXString), + "::", + stringify!(data) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).private_flags as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXString), + "::", + stringify!(private_flags) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXStringSet { + pub Strings: *mut CXString, + pub Count: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_CXStringSet() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(CXStringSet)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXStringSet)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Strings as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXStringSet), + "::", + stringify!(Strings) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Count as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXStringSet), + "::", + stringify!(Count) + ) + ); +} +extern "C" { + pub fn clang_getCString(string: CXString) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn clang_disposeString(string: CXString); +} +extern "C" { + pub fn clang_disposeStringSet(set: *mut CXStringSet); +} +extern "C" { + pub fn clang_getBuildSessionTimestamp() -> ::std::os::raw::c_ulonglong; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXVirtualFileOverlayImpl { + _unused: [u8; 0], +} +pub type CXVirtualFileOverlay = *mut CXVirtualFileOverlayImpl; +extern "C" { + pub fn clang_VirtualFileOverlay_create( + options: ::std::os::raw::c_uint, + ) -> CXVirtualFileOverlay; +} +extern "C" { + pub fn clang_VirtualFileOverlay_addFileMapping( + arg1: CXVirtualFileOverlay, + virtualPath: *const ::std::os::raw::c_char, + realPath: *const ::std::os::raw::c_char, + ) -> CXErrorCode::Type; +} +extern "C" { + pub fn clang_VirtualFileOverlay_setCaseSensitivity( + arg1: CXVirtualFileOverlay, + caseSensitive: ::std::os::raw::c_int, + ) -> CXErrorCode::Type; +} +extern "C" { + pub fn clang_VirtualFileOverlay_writeToBuffer( + arg1: CXVirtualFileOverlay, + options: ::std::os::raw::c_uint, + out_buffer_ptr: *mut *mut ::std::os::raw::c_char, + out_buffer_size: *mut ::std::os::raw::c_uint, + ) -> CXErrorCode::Type; +} +extern "C" { + pub fn clang_free(buffer: *mut ::std::os::raw::c_void); +} +extern "C" { + pub fn clang_VirtualFileOverlay_dispose(arg1: CXVirtualFileOverlay); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXModuleMapDescriptorImpl { + _unused: [u8; 0], +} +pub type CXModuleMapDescriptor = *mut CXModuleMapDescriptorImpl; +extern "C" { + pub fn clang_ModuleMapDescriptor_create( + options: ::std::os::raw::c_uint, + ) -> CXModuleMapDescriptor; +} +extern "C" { + pub fn clang_ModuleMapDescriptor_setFrameworkModuleName( + arg1: CXModuleMapDescriptor, + name: *const ::std::os::raw::c_char, + ) -> CXErrorCode::Type; +} +extern "C" { + pub fn clang_ModuleMapDescriptor_setUmbrellaHeader( + arg1: CXModuleMapDescriptor, + name: *const ::std::os::raw::c_char, + ) -> CXErrorCode::Type; +} +extern "C" { + pub fn clang_ModuleMapDescriptor_writeToBuffer( + arg1: CXModuleMapDescriptor, + options: ::std::os::raw::c_uint, + out_buffer_ptr: *mut *mut ::std::os::raw::c_char, + out_buffer_size: *mut ::std::os::raw::c_uint, + ) -> CXErrorCode::Type; +} +extern "C" { + pub fn clang_ModuleMapDescriptor_dispose(arg1: CXModuleMapDescriptor); +} +pub type CXIndex = *mut ::std::os::raw::c_void; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXTargetInfoImpl { + _unused: [u8; 0], +} +pub type CXTargetInfo = *mut CXTargetInfoImpl; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXTranslationUnitImpl { + _unused: [u8; 0], +} +pub type CXTranslationUnit = *mut CXTranslationUnitImpl; +pub type CXClientData = *mut ::std::os::raw::c_void; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXUnsavedFile { + pub Filename: *const ::std::os::raw::c_char, + pub Contents: *const ::std::os::raw::c_char, + pub Length: ::std::os::raw::c_ulong, +} +#[test] +fn bindgen_test_layout_CXUnsavedFile() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(CXUnsavedFile)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXUnsavedFile)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Filename as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXUnsavedFile), + "::", + stringify!(Filename) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Contents as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXUnsavedFile), + "::", + stringify!(Contents) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Length as *const _ + as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXUnsavedFile), + "::", + stringify!(Length) + ) + ); +} +pub mod CXAvailabilityKind { + pub type Type = u32; + pub const CXAvailability_Available: Type = 0; + pub const CXAvailability_Deprecated: Type = 1; + pub const CXAvailability_NotAvailable: Type = 2; + pub const CXAvailability_NotAccessible: Type = 3; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXVersion { + pub Major: ::std::os::raw::c_int, + pub Minor: ::std::os::raw::c_int, + pub Subminor: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_CXVersion() { + assert_eq!( + ::std::mem::size_of::(), + 12usize, + concat!("Size of: ", stringify!(CXVersion)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(CXVersion)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Major as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXVersion), + "::", + stringify!(Major) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Minor as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(CXVersion), + "::", + stringify!(Minor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Subminor as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXVersion), + "::", + stringify!(Subminor) + ) + ); +} +pub mod CXCursor_ExceptionSpecificationKind { + pub type Type = u32; + pub const CXCursor_ExceptionSpecificationKind_None: Type = 0; + pub const CXCursor_ExceptionSpecificationKind_DynamicNone: Type = 1; + pub const CXCursor_ExceptionSpecificationKind_Dynamic: Type = 2; + pub const CXCursor_ExceptionSpecificationKind_MSAny: Type = 3; + pub const CXCursor_ExceptionSpecificationKind_BasicNoexcept: Type = 4; + pub const CXCursor_ExceptionSpecificationKind_ComputedNoexcept: Type = 5; + pub const CXCursor_ExceptionSpecificationKind_Unevaluated: Type = 6; + pub const CXCursor_ExceptionSpecificationKind_Uninstantiated: Type = 7; + pub const CXCursor_ExceptionSpecificationKind_Unparsed: Type = 8; + pub const CXCursor_ExceptionSpecificationKind_NoThrow: Type = 9; +} +extern "C" { + pub fn clang_createIndex( + excludeDeclarationsFromPCH: ::std::os::raw::c_int, + displayDiagnostics: ::std::os::raw::c_int, + ) -> CXIndex; +} +extern "C" { + pub fn clang_disposeIndex(index: CXIndex); +} +pub mod CXGlobalOptFlags { + pub type Type = u32; + pub const CXGlobalOpt_None: Type = 0; + pub const CXGlobalOpt_ThreadBackgroundPriorityForIndexing: Type = 1; + pub const CXGlobalOpt_ThreadBackgroundPriorityForEditing: Type = 2; + pub const CXGlobalOpt_ThreadBackgroundPriorityForAll: Type = 3; +} +extern "C" { + pub fn clang_CXIndex_setGlobalOptions( + arg1: CXIndex, + options: ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_CXIndex_getGlobalOptions( + arg1: CXIndex, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_CXIndex_setInvocationEmissionPathOption( + arg1: CXIndex, + Path: *const ::std::os::raw::c_char, + ); +} +pub type CXFile = *mut ::std::os::raw::c_void; +extern "C" { + pub fn clang_getFileName(SFile: CXFile) -> CXString; +} +extern "C" { + pub fn clang_getFileTime(SFile: CXFile) -> time_t; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXFileUniqueID { + pub data: [::std::os::raw::c_ulonglong; 3usize], +} +#[test] +fn bindgen_test_layout_CXFileUniqueID() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(CXFileUniqueID)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXFileUniqueID)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).data as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXFileUniqueID), + "::", + stringify!(data) + ) + ); +} +extern "C" { + pub fn clang_getFileUniqueID( + file: CXFile, + outID: *mut CXFileUniqueID, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_isFileMultipleIncludeGuarded( + tu: CXTranslationUnit, + file: CXFile, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getFile( + tu: CXTranslationUnit, + file_name: *const ::std::os::raw::c_char, + ) -> CXFile; +} +extern "C" { + pub fn clang_getFileContents( + tu: CXTranslationUnit, + file: CXFile, + size: *mut size_t, + ) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn clang_File_isEqual( + file1: CXFile, + file2: CXFile, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_File_tryGetRealPathName(file: CXFile) -> CXString; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXSourceLocation { + pub ptr_data: [*const ::std::os::raw::c_void; 2usize], + pub int_data: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_CXSourceLocation() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(CXSourceLocation)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXSourceLocation)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ptr_data as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXSourceLocation), + "::", + stringify!(ptr_data) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).int_data as *const _ + as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXSourceLocation), + "::", + stringify!(int_data) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXSourceRange { + pub ptr_data: [*const ::std::os::raw::c_void; 2usize], + pub begin_int_data: ::std::os::raw::c_uint, + pub end_int_data: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_CXSourceRange() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(CXSourceRange)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXSourceRange)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ptr_data as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXSourceRange), + "::", + stringify!(ptr_data) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).begin_int_data as *const _ + as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXSourceRange), + "::", + stringify!(begin_int_data) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).end_int_data as *const _ + as usize + }, + 20usize, + concat!( + "Offset of field: ", + stringify!(CXSourceRange), + "::", + stringify!(end_int_data) + ) + ); +} +extern "C" { + pub fn clang_getNullLocation() -> CXSourceLocation; +} +extern "C" { + pub fn clang_equalLocations( + loc1: CXSourceLocation, + loc2: CXSourceLocation, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getLocation( + tu: CXTranslationUnit, + file: CXFile, + line: ::std::os::raw::c_uint, + column: ::std::os::raw::c_uint, + ) -> CXSourceLocation; +} +extern "C" { + pub fn clang_getLocationForOffset( + tu: CXTranslationUnit, + file: CXFile, + offset: ::std::os::raw::c_uint, + ) -> CXSourceLocation; +} +extern "C" { + pub fn clang_Location_isInSystemHeader( + location: CXSourceLocation, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_Location_isFromMainFile( + location: CXSourceLocation, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_getNullRange() -> CXSourceRange; +} +extern "C" { + pub fn clang_getRange( + begin: CXSourceLocation, + end: CXSourceLocation, + ) -> CXSourceRange; +} +extern "C" { + pub fn clang_equalRanges( + range1: CXSourceRange, + range2: CXSourceRange, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Range_isNull(range: CXSourceRange) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_getExpansionLocation( + location: CXSourceLocation, + file: *mut CXFile, + line: *mut ::std::os::raw::c_uint, + column: *mut ::std::os::raw::c_uint, + offset: *mut ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_getPresumedLocation( + location: CXSourceLocation, + filename: *mut CXString, + line: *mut ::std::os::raw::c_uint, + column: *mut ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_getInstantiationLocation( + location: CXSourceLocation, + file: *mut CXFile, + line: *mut ::std::os::raw::c_uint, + column: *mut ::std::os::raw::c_uint, + offset: *mut ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_getSpellingLocation( + location: CXSourceLocation, + file: *mut CXFile, + line: *mut ::std::os::raw::c_uint, + column: *mut ::std::os::raw::c_uint, + offset: *mut ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_getFileLocation( + location: CXSourceLocation, + file: *mut CXFile, + line: *mut ::std::os::raw::c_uint, + column: *mut ::std::os::raw::c_uint, + offset: *mut ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_getRangeStart(range: CXSourceRange) -> CXSourceLocation; +} +extern "C" { + pub fn clang_getRangeEnd(range: CXSourceRange) -> CXSourceLocation; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXSourceRangeList { + pub count: ::std::os::raw::c_uint, + pub ranges: *mut CXSourceRange, +} +#[test] +fn bindgen_test_layout_CXSourceRangeList() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(CXSourceRangeList)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXSourceRangeList)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).count as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXSourceRangeList), + "::", + stringify!(count) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ranges as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXSourceRangeList), + "::", + stringify!(ranges) + ) + ); +} +extern "C" { + pub fn clang_getSkippedRanges( + tu: CXTranslationUnit, + file: CXFile, + ) -> *mut CXSourceRangeList; +} +extern "C" { + pub fn clang_getAllSkippedRanges( + tu: CXTranslationUnit, + ) -> *mut CXSourceRangeList; +} +extern "C" { + pub fn clang_disposeSourceRangeList(ranges: *mut CXSourceRangeList); +} +pub mod CXDiagnosticSeverity { + pub type Type = u32; + pub const CXDiagnostic_Ignored: Type = 0; + pub const CXDiagnostic_Note: Type = 1; + pub const CXDiagnostic_Warning: Type = 2; + pub const CXDiagnostic_Error: Type = 3; + pub const CXDiagnostic_Fatal: Type = 4; +} +pub type CXDiagnostic = *mut ::std::os::raw::c_void; +pub type CXDiagnosticSet = *mut ::std::os::raw::c_void; +extern "C" { + pub fn clang_getNumDiagnosticsInSet( + Diags: CXDiagnosticSet, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getDiagnosticInSet( + Diags: CXDiagnosticSet, + Index: ::std::os::raw::c_uint, + ) -> CXDiagnostic; +} +pub mod CXLoadDiag_Error { + pub type Type = u32; + pub const CXLoadDiag_None: Type = 0; + pub const CXLoadDiag_Unknown: Type = 1; + pub const CXLoadDiag_CannotLoad: Type = 2; + pub const CXLoadDiag_InvalidFile: Type = 3; +} +extern "C" { + pub fn clang_loadDiagnostics( + file: *const ::std::os::raw::c_char, + error: *mut CXLoadDiag_Error::Type, + errorString: *mut CXString, + ) -> CXDiagnosticSet; +} +extern "C" { + pub fn clang_disposeDiagnosticSet(Diags: CXDiagnosticSet); +} +extern "C" { + pub fn clang_getChildDiagnostics(D: CXDiagnostic) -> CXDiagnosticSet; +} +extern "C" { + pub fn clang_getNumDiagnostics( + Unit: CXTranslationUnit, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getDiagnostic( + Unit: CXTranslationUnit, + Index: ::std::os::raw::c_uint, + ) -> CXDiagnostic; +} +extern "C" { + pub fn clang_getDiagnosticSetFromTU( + Unit: CXTranslationUnit, + ) -> CXDiagnosticSet; +} +extern "C" { + pub fn clang_disposeDiagnostic(Diagnostic: CXDiagnostic); +} +pub mod CXDiagnosticDisplayOptions { + pub type Type = u32; + pub const CXDiagnostic_DisplaySourceLocation: Type = 1; + pub const CXDiagnostic_DisplayColumn: Type = 2; + pub const CXDiagnostic_DisplaySourceRanges: Type = 4; + pub const CXDiagnostic_DisplayOption: Type = 8; + pub const CXDiagnostic_DisplayCategoryId: Type = 16; + pub const CXDiagnostic_DisplayCategoryName: Type = 32; +} +extern "C" { + pub fn clang_formatDiagnostic( + Diagnostic: CXDiagnostic, + Options: ::std::os::raw::c_uint, + ) -> CXString; +} +extern "C" { + pub fn clang_defaultDiagnosticDisplayOptions() -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getDiagnosticSeverity( + arg1: CXDiagnostic, + ) -> CXDiagnosticSeverity::Type; +} +extern "C" { + pub fn clang_getDiagnosticLocation(arg1: CXDiagnostic) -> CXSourceLocation; +} +extern "C" { + pub fn clang_getDiagnosticSpelling(arg1: CXDiagnostic) -> CXString; +} +extern "C" { + pub fn clang_getDiagnosticOption( + Diag: CXDiagnostic, + Disable: *mut CXString, + ) -> CXString; +} +extern "C" { + pub fn clang_getDiagnosticCategory( + arg1: CXDiagnostic, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getDiagnosticCategoryName( + Category: ::std::os::raw::c_uint, + ) -> CXString; +} +extern "C" { + pub fn clang_getDiagnosticCategoryText(arg1: CXDiagnostic) -> CXString; +} +extern "C" { + pub fn clang_getDiagnosticNumRanges( + arg1: CXDiagnostic, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getDiagnosticRange( + Diagnostic: CXDiagnostic, + Range: ::std::os::raw::c_uint, + ) -> CXSourceRange; +} +extern "C" { + pub fn clang_getDiagnosticNumFixIts( + Diagnostic: CXDiagnostic, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getDiagnosticFixIt( + Diagnostic: CXDiagnostic, + FixIt: ::std::os::raw::c_uint, + ReplacementRange: *mut CXSourceRange, + ) -> CXString; +} +extern "C" { + pub fn clang_getTranslationUnitSpelling( + CTUnit: CXTranslationUnit, + ) -> CXString; +} +extern "C" { + pub fn clang_createTranslationUnitFromSourceFile( + CIdx: CXIndex, + source_filename: *const ::std::os::raw::c_char, + num_clang_command_line_args: ::std::os::raw::c_int, + clang_command_line_args: *const *const ::std::os::raw::c_char, + num_unsaved_files: ::std::os::raw::c_uint, + unsaved_files: *mut CXUnsavedFile, + ) -> CXTranslationUnit; +} +extern "C" { + pub fn clang_createTranslationUnit( + CIdx: CXIndex, + ast_filename: *const ::std::os::raw::c_char, + ) -> CXTranslationUnit; +} +extern "C" { + pub fn clang_createTranslationUnit2( + CIdx: CXIndex, + ast_filename: *const ::std::os::raw::c_char, + out_TU: *mut CXTranslationUnit, + ) -> CXErrorCode::Type; +} +pub mod CXTranslationUnit_Flags { + pub type Type = u32; + pub const CXTranslationUnit_None: Type = 0; + pub const CXTranslationUnit_DetailedPreprocessingRecord: Type = 1; + pub const CXTranslationUnit_Incomplete: Type = 2; + pub const CXTranslationUnit_PrecompiledPreamble: Type = 4; + pub const CXTranslationUnit_CacheCompletionResults: Type = 8; + pub const CXTranslationUnit_ForSerialization: Type = 16; + pub const CXTranslationUnit_CXXChainedPCH: Type = 32; + pub const CXTranslationUnit_SkipFunctionBodies: Type = 64; + pub const CXTranslationUnit_IncludeBriefCommentsInCodeCompletion: Type = + 128; + pub const CXTranslationUnit_CreatePreambleOnFirstParse: Type = 256; + pub const CXTranslationUnit_KeepGoing: Type = 512; + pub const CXTranslationUnit_SingleFileParse: Type = 1024; + pub const CXTranslationUnit_LimitSkipFunctionBodiesToPreamble: Type = 2048; + pub const CXTranslationUnit_IncludeAttributedTypes: Type = 4096; + pub const CXTranslationUnit_VisitImplicitAttributes: Type = 8192; + pub const CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles: Type = 16384; +} +extern "C" { + pub fn clang_defaultEditingTranslationUnitOptions() -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_parseTranslationUnit( + CIdx: CXIndex, + source_filename: *const ::std::os::raw::c_char, + command_line_args: *const *const ::std::os::raw::c_char, + num_command_line_args: ::std::os::raw::c_int, + unsaved_files: *mut CXUnsavedFile, + num_unsaved_files: ::std::os::raw::c_uint, + options: ::std::os::raw::c_uint, + ) -> CXTranslationUnit; +} +extern "C" { + pub fn clang_parseTranslationUnit2( + CIdx: CXIndex, + source_filename: *const ::std::os::raw::c_char, + command_line_args: *const *const ::std::os::raw::c_char, + num_command_line_args: ::std::os::raw::c_int, + unsaved_files: *mut CXUnsavedFile, + num_unsaved_files: ::std::os::raw::c_uint, + options: ::std::os::raw::c_uint, + out_TU: *mut CXTranslationUnit, + ) -> CXErrorCode::Type; +} +extern "C" { + pub fn clang_parseTranslationUnit2FullArgv( + CIdx: CXIndex, + source_filename: *const ::std::os::raw::c_char, + command_line_args: *const *const ::std::os::raw::c_char, + num_command_line_args: ::std::os::raw::c_int, + unsaved_files: *mut CXUnsavedFile, + num_unsaved_files: ::std::os::raw::c_uint, + options: ::std::os::raw::c_uint, + out_TU: *mut CXTranslationUnit, + ) -> CXErrorCode::Type; +} +pub mod CXSaveTranslationUnit_Flags { + pub type Type = u32; + pub const CXSaveTranslationUnit_None: Type = 0; +} +extern "C" { + pub fn clang_defaultSaveOptions( + TU: CXTranslationUnit, + ) -> ::std::os::raw::c_uint; +} +pub mod CXSaveError { + pub type Type = u32; + pub const CXSaveError_None: Type = 0; + pub const CXSaveError_Unknown: Type = 1; + pub const CXSaveError_TranslationErrors: Type = 2; + pub const CXSaveError_InvalidTU: Type = 3; +} +extern "C" { + pub fn clang_saveTranslationUnit( + TU: CXTranslationUnit, + FileName: *const ::std::os::raw::c_char, + options: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_suspendTranslationUnit( + arg1: CXTranslationUnit, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_disposeTranslationUnit(arg1: CXTranslationUnit); +} +pub mod CXReparse_Flags { + pub type Type = u32; + pub const CXReparse_None: Type = 0; +} +extern "C" { + pub fn clang_defaultReparseOptions( + TU: CXTranslationUnit, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_reparseTranslationUnit( + TU: CXTranslationUnit, + num_unsaved_files: ::std::os::raw::c_uint, + unsaved_files: *mut CXUnsavedFile, + options: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +pub mod CXTUResourceUsageKind { + pub type Type = u32; + pub const CXTUResourceUsage_AST: Type = 1; + pub const CXTUResourceUsage_Identifiers: Type = 2; + pub const CXTUResourceUsage_Selectors: Type = 3; + pub const CXTUResourceUsage_GlobalCompletionResults: Type = 4; + pub const CXTUResourceUsage_SourceManagerContentCache: Type = 5; + pub const CXTUResourceUsage_AST_SideTables: Type = 6; + pub const CXTUResourceUsage_SourceManager_Membuffer_Malloc: Type = 7; + pub const CXTUResourceUsage_SourceManager_Membuffer_MMap: Type = 8; + pub const CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc: Type = 9; + pub const CXTUResourceUsage_ExternalASTSource_Membuffer_MMap: Type = 10; + pub const CXTUResourceUsage_Preprocessor: Type = 11; + pub const CXTUResourceUsage_PreprocessingRecord: Type = 12; + pub const CXTUResourceUsage_SourceManager_DataStructures: Type = 13; + pub const CXTUResourceUsage_Preprocessor_HeaderSearch: Type = 14; + pub const CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN: Type = 1; + pub const CXTUResourceUsage_MEMORY_IN_BYTES_END: Type = 14; + pub const CXTUResourceUsage_First: Type = 1; + pub const CXTUResourceUsage_Last: Type = 14; +} +extern "C" { + pub fn clang_getTUResourceUsageName( + kind: CXTUResourceUsageKind::Type, + ) -> *const ::std::os::raw::c_char; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXTUResourceUsageEntry { + pub kind: CXTUResourceUsageKind::Type, + pub amount: ::std::os::raw::c_ulong, +} +#[test] +fn bindgen_test_layout_CXTUResourceUsageEntry() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(CXTUResourceUsageEntry)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXTUResourceUsageEntry)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).kind as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXTUResourceUsageEntry), + "::", + stringify!(kind) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).amount + as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXTUResourceUsageEntry), + "::", + stringify!(amount) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXTUResourceUsage { + pub data: *mut ::std::os::raw::c_void, + pub numEntries: ::std::os::raw::c_uint, + pub entries: *mut CXTUResourceUsageEntry, +} +#[test] +fn bindgen_test_layout_CXTUResourceUsage() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(CXTUResourceUsage)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXTUResourceUsage)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).data as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXTUResourceUsage), + "::", + stringify!(data) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).numEntries as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXTUResourceUsage), + "::", + stringify!(numEntries) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).entries as *const _ + as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXTUResourceUsage), + "::", + stringify!(entries) + ) + ); +} +extern "C" { + pub fn clang_getCXTUResourceUsage( + TU: CXTranslationUnit, + ) -> CXTUResourceUsage; +} +extern "C" { + pub fn clang_disposeCXTUResourceUsage(usage: CXTUResourceUsage); +} +extern "C" { + pub fn clang_getTranslationUnitTargetInfo( + CTUnit: CXTranslationUnit, + ) -> CXTargetInfo; +} +extern "C" { + pub fn clang_TargetInfo_dispose(Info: CXTargetInfo); +} +extern "C" { + pub fn clang_TargetInfo_getTriple(Info: CXTargetInfo) -> CXString; +} +extern "C" { + pub fn clang_TargetInfo_getPointerWidth( + Info: CXTargetInfo, + ) -> ::std::os::raw::c_int; +} +pub mod CXCursorKind { + pub type Type = u32; + pub const CXCursor_UnexposedDecl: Type = 1; + pub const CXCursor_StructDecl: Type = 2; + pub const CXCursor_UnionDecl: Type = 3; + pub const CXCursor_ClassDecl: Type = 4; + pub const CXCursor_EnumDecl: Type = 5; + pub const CXCursor_FieldDecl: Type = 6; + pub const CXCursor_EnumConstantDecl: Type = 7; + pub const CXCursor_FunctionDecl: Type = 8; + pub const CXCursor_VarDecl: Type = 9; + pub const CXCursor_ParmDecl: Type = 10; + pub const CXCursor_ObjCInterfaceDecl: Type = 11; + pub const CXCursor_ObjCCategoryDecl: Type = 12; + pub const CXCursor_ObjCProtocolDecl: Type = 13; + pub const CXCursor_ObjCPropertyDecl: Type = 14; + pub const CXCursor_ObjCIvarDecl: Type = 15; + pub const CXCursor_ObjCInstanceMethodDecl: Type = 16; + pub const CXCursor_ObjCClassMethodDecl: Type = 17; + pub const CXCursor_ObjCImplementationDecl: Type = 18; + pub const CXCursor_ObjCCategoryImplDecl: Type = 19; + pub const CXCursor_TypedefDecl: Type = 20; + pub const CXCursor_CXXMethod: Type = 21; + pub const CXCursor_Namespace: Type = 22; + pub const CXCursor_LinkageSpec: Type = 23; + pub const CXCursor_Constructor: Type = 24; + pub const CXCursor_Destructor: Type = 25; + pub const CXCursor_ConversionFunction: Type = 26; + pub const CXCursor_TemplateTypeParameter: Type = 27; + pub const CXCursor_NonTypeTemplateParameter: Type = 28; + pub const CXCursor_TemplateTemplateParameter: Type = 29; + pub const CXCursor_FunctionTemplate: Type = 30; + pub const CXCursor_ClassTemplate: Type = 31; + pub const CXCursor_ClassTemplatePartialSpecialization: Type = 32; + pub const CXCursor_NamespaceAlias: Type = 33; + pub const CXCursor_UsingDirective: Type = 34; + pub const CXCursor_UsingDeclaration: Type = 35; + pub const CXCursor_TypeAliasDecl: Type = 36; + pub const CXCursor_ObjCSynthesizeDecl: Type = 37; + pub const CXCursor_ObjCDynamicDecl: Type = 38; + pub const CXCursor_CXXAccessSpecifier: Type = 39; + pub const CXCursor_FirstDecl: Type = 1; + pub const CXCursor_LastDecl: Type = 39; + pub const CXCursor_FirstRef: Type = 40; + pub const CXCursor_ObjCSuperClassRef: Type = 40; + pub const CXCursor_ObjCProtocolRef: Type = 41; + pub const CXCursor_ObjCClassRef: Type = 42; + pub const CXCursor_TypeRef: Type = 43; + pub const CXCursor_CXXBaseSpecifier: Type = 44; + pub const CXCursor_TemplateRef: Type = 45; + pub const CXCursor_NamespaceRef: Type = 46; + pub const CXCursor_MemberRef: Type = 47; + pub const CXCursor_LabelRef: Type = 48; + pub const CXCursor_OverloadedDeclRef: Type = 49; + pub const CXCursor_VariableRef: Type = 50; + pub const CXCursor_LastRef: Type = 50; + pub const CXCursor_FirstInvalid: Type = 70; + pub const CXCursor_InvalidFile: Type = 70; + pub const CXCursor_NoDeclFound: Type = 71; + pub const CXCursor_NotImplemented: Type = 72; + pub const CXCursor_InvalidCode: Type = 73; + pub const CXCursor_LastInvalid: Type = 73; + pub const CXCursor_FirstExpr: Type = 100; + pub const CXCursor_UnexposedExpr: Type = 100; + pub const CXCursor_DeclRefExpr: Type = 101; + pub const CXCursor_MemberRefExpr: Type = 102; + pub const CXCursor_CallExpr: Type = 103; + pub const CXCursor_ObjCMessageExpr: Type = 104; + pub const CXCursor_BlockExpr: Type = 105; + pub const CXCursor_IntegerLiteral: Type = 106; + pub const CXCursor_FloatingLiteral: Type = 107; + pub const CXCursor_ImaginaryLiteral: Type = 108; + pub const CXCursor_StringLiteral: Type = 109; + pub const CXCursor_CharacterLiteral: Type = 110; + pub const CXCursor_ParenExpr: Type = 111; + pub const CXCursor_UnaryOperator: Type = 112; + pub const CXCursor_ArraySubscriptExpr: Type = 113; + pub const CXCursor_BinaryOperator: Type = 114; + pub const CXCursor_CompoundAssignOperator: Type = 115; + pub const CXCursor_ConditionalOperator: Type = 116; + pub const CXCursor_CStyleCastExpr: Type = 117; + pub const CXCursor_CompoundLiteralExpr: Type = 118; + pub const CXCursor_InitListExpr: Type = 119; + pub const CXCursor_AddrLabelExpr: Type = 120; + pub const CXCursor_StmtExpr: Type = 121; + pub const CXCursor_GenericSelectionExpr: Type = 122; + pub const CXCursor_GNUNullExpr: Type = 123; + pub const CXCursor_CXXStaticCastExpr: Type = 124; + pub const CXCursor_CXXDynamicCastExpr: Type = 125; + pub const CXCursor_CXXReinterpretCastExpr: Type = 126; + pub const CXCursor_CXXConstCastExpr: Type = 127; + pub const CXCursor_CXXFunctionalCastExpr: Type = 128; + pub const CXCursor_CXXTypeidExpr: Type = 129; + pub const CXCursor_CXXBoolLiteralExpr: Type = 130; + pub const CXCursor_CXXNullPtrLiteralExpr: Type = 131; + pub const CXCursor_CXXThisExpr: Type = 132; + pub const CXCursor_CXXThrowExpr: Type = 133; + pub const CXCursor_CXXNewExpr: Type = 134; + pub const CXCursor_CXXDeleteExpr: Type = 135; + pub const CXCursor_UnaryExpr: Type = 136; + pub const CXCursor_ObjCStringLiteral: Type = 137; + pub const CXCursor_ObjCEncodeExpr: Type = 138; + pub const CXCursor_ObjCSelectorExpr: Type = 139; + pub const CXCursor_ObjCProtocolExpr: Type = 140; + pub const CXCursor_ObjCBridgedCastExpr: Type = 141; + pub const CXCursor_PackExpansionExpr: Type = 142; + pub const CXCursor_SizeOfPackExpr: Type = 143; + pub const CXCursor_LambdaExpr: Type = 144; + pub const CXCursor_ObjCBoolLiteralExpr: Type = 145; + pub const CXCursor_ObjCSelfExpr: Type = 146; + pub const CXCursor_OMPArraySectionExpr: Type = 147; + pub const CXCursor_ObjCAvailabilityCheckExpr: Type = 148; + pub const CXCursor_FixedPointLiteral: Type = 149; + pub const CXCursor_LastExpr: Type = 149; + pub const CXCursor_FirstStmt: Type = 200; + pub const CXCursor_UnexposedStmt: Type = 200; + pub const CXCursor_LabelStmt: Type = 201; + pub const CXCursor_CompoundStmt: Type = 202; + pub const CXCursor_CaseStmt: Type = 203; + pub const CXCursor_DefaultStmt: Type = 204; + pub const CXCursor_IfStmt: Type = 205; + pub const CXCursor_SwitchStmt: Type = 206; + pub const CXCursor_WhileStmt: Type = 207; + pub const CXCursor_DoStmt: Type = 208; + pub const CXCursor_ForStmt: Type = 209; + pub const CXCursor_GotoStmt: Type = 210; + pub const CXCursor_IndirectGotoStmt: Type = 211; + pub const CXCursor_ContinueStmt: Type = 212; + pub const CXCursor_BreakStmt: Type = 213; + pub const CXCursor_ReturnStmt: Type = 214; + pub const CXCursor_GCCAsmStmt: Type = 215; + pub const CXCursor_AsmStmt: Type = 215; + pub const CXCursor_ObjCAtTryStmt: Type = 216; + pub const CXCursor_ObjCAtCatchStmt: Type = 217; + pub const CXCursor_ObjCAtFinallyStmt: Type = 218; + pub const CXCursor_ObjCAtThrowStmt: Type = 219; + pub const CXCursor_ObjCAtSynchronizedStmt: Type = 220; + pub const CXCursor_ObjCAutoreleasePoolStmt: Type = 221; + pub const CXCursor_ObjCForCollectionStmt: Type = 222; + pub const CXCursor_CXXCatchStmt: Type = 223; + pub const CXCursor_CXXTryStmt: Type = 224; + pub const CXCursor_CXXForRangeStmt: Type = 225; + pub const CXCursor_SEHTryStmt: Type = 226; + pub const CXCursor_SEHExceptStmt: Type = 227; + pub const CXCursor_SEHFinallyStmt: Type = 228; + pub const CXCursor_MSAsmStmt: Type = 229; + pub const CXCursor_NullStmt: Type = 230; + pub const CXCursor_DeclStmt: Type = 231; + pub const CXCursor_OMPParallelDirective: Type = 232; + pub const CXCursor_OMPSimdDirective: Type = 233; + pub const CXCursor_OMPForDirective: Type = 234; + pub const CXCursor_OMPSectionsDirective: Type = 235; + pub const CXCursor_OMPSectionDirective: Type = 236; + pub const CXCursor_OMPSingleDirective: Type = 237; + pub const CXCursor_OMPParallelForDirective: Type = 238; + pub const CXCursor_OMPParallelSectionsDirective: Type = 239; + pub const CXCursor_OMPTaskDirective: Type = 240; + pub const CXCursor_OMPMasterDirective: Type = 241; + pub const CXCursor_OMPCriticalDirective: Type = 242; + pub const CXCursor_OMPTaskyieldDirective: Type = 243; + pub const CXCursor_OMPBarrierDirective: Type = 244; + pub const CXCursor_OMPTaskwaitDirective: Type = 245; + pub const CXCursor_OMPFlushDirective: Type = 246; + pub const CXCursor_SEHLeaveStmt: Type = 247; + pub const CXCursor_OMPOrderedDirective: Type = 248; + pub const CXCursor_OMPAtomicDirective: Type = 249; + pub const CXCursor_OMPForSimdDirective: Type = 250; + pub const CXCursor_OMPParallelForSimdDirective: Type = 251; + pub const CXCursor_OMPTargetDirective: Type = 252; + pub const CXCursor_OMPTeamsDirective: Type = 253; + pub const CXCursor_OMPTaskgroupDirective: Type = 254; + pub const CXCursor_OMPCancellationPointDirective: Type = 255; + pub const CXCursor_OMPCancelDirective: Type = 256; + pub const CXCursor_OMPTargetDataDirective: Type = 257; + pub const CXCursor_OMPTaskLoopDirective: Type = 258; + pub const CXCursor_OMPTaskLoopSimdDirective: Type = 259; + pub const CXCursor_OMPDistributeDirective: Type = 260; + pub const CXCursor_OMPTargetEnterDataDirective: Type = 261; + pub const CXCursor_OMPTargetExitDataDirective: Type = 262; + pub const CXCursor_OMPTargetParallelDirective: Type = 263; + pub const CXCursor_OMPTargetParallelForDirective: Type = 264; + pub const CXCursor_OMPTargetUpdateDirective: Type = 265; + pub const CXCursor_OMPDistributeParallelForDirective: Type = 266; + pub const CXCursor_OMPDistributeParallelForSimdDirective: Type = 267; + pub const CXCursor_OMPDistributeSimdDirective: Type = 268; + pub const CXCursor_OMPTargetParallelForSimdDirective: Type = 269; + pub const CXCursor_OMPTargetSimdDirective: Type = 270; + pub const CXCursor_OMPTeamsDistributeDirective: Type = 271; + pub const CXCursor_OMPTeamsDistributeSimdDirective: Type = 272; + pub const CXCursor_OMPTeamsDistributeParallelForSimdDirective: Type = 273; + pub const CXCursor_OMPTeamsDistributeParallelForDirective: Type = 274; + pub const CXCursor_OMPTargetTeamsDirective: Type = 275; + pub const CXCursor_OMPTargetTeamsDistributeDirective: Type = 276; + pub const CXCursor_OMPTargetTeamsDistributeParallelForDirective: Type = 277; + pub const CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective: Type = + 278; + pub const CXCursor_OMPTargetTeamsDistributeSimdDirective: Type = 279; + pub const CXCursor_BuiltinBitCastExpr: Type = 280; + pub const CXCursor_LastStmt: Type = 280; + pub const CXCursor_TranslationUnit: Type = 300; + pub const CXCursor_FirstAttr: Type = 400; + pub const CXCursor_UnexposedAttr: Type = 400; + pub const CXCursor_IBActionAttr: Type = 401; + pub const CXCursor_IBOutletAttr: Type = 402; + pub const CXCursor_IBOutletCollectionAttr: Type = 403; + pub const CXCursor_CXXFinalAttr: Type = 404; + pub const CXCursor_CXXOverrideAttr: Type = 405; + pub const CXCursor_AnnotateAttr: Type = 406; + pub const CXCursor_AsmLabelAttr: Type = 407; + pub const CXCursor_PackedAttr: Type = 408; + pub const CXCursor_PureAttr: Type = 409; + pub const CXCursor_ConstAttr: Type = 410; + pub const CXCursor_NoDuplicateAttr: Type = 411; + pub const CXCursor_CUDAConstantAttr: Type = 412; + pub const CXCursor_CUDADeviceAttr: Type = 413; + pub const CXCursor_CUDAGlobalAttr: Type = 414; + pub const CXCursor_CUDAHostAttr: Type = 415; + pub const CXCursor_CUDASharedAttr: Type = 416; + pub const CXCursor_VisibilityAttr: Type = 417; + pub const CXCursor_DLLExport: Type = 418; + pub const CXCursor_DLLImport: Type = 419; + pub const CXCursor_NSReturnsRetained: Type = 420; + pub const CXCursor_NSReturnsNotRetained: Type = 421; + pub const CXCursor_NSReturnsAutoreleased: Type = 422; + pub const CXCursor_NSConsumesSelf: Type = 423; + pub const CXCursor_NSConsumed: Type = 424; + pub const CXCursor_ObjCException: Type = 425; + pub const CXCursor_ObjCNSObject: Type = 426; + pub const CXCursor_ObjCIndependentClass: Type = 427; + pub const CXCursor_ObjCPreciseLifetime: Type = 428; + pub const CXCursor_ObjCReturnsInnerPointer: Type = 429; + pub const CXCursor_ObjCRequiresSuper: Type = 430; + pub const CXCursor_ObjCRootClass: Type = 431; + pub const CXCursor_ObjCSubclassingRestricted: Type = 432; + pub const CXCursor_ObjCExplicitProtocolImpl: Type = 433; + pub const CXCursor_ObjCDesignatedInitializer: Type = 434; + pub const CXCursor_ObjCRuntimeVisible: Type = 435; + pub const CXCursor_ObjCBoxable: Type = 436; + pub const CXCursor_FlagEnum: Type = 437; + pub const CXCursor_ConvergentAttr: Type = 438; + pub const CXCursor_WarnUnusedAttr: Type = 439; + pub const CXCursor_WarnUnusedResultAttr: Type = 440; + pub const CXCursor_AlignedAttr: Type = 441; + pub const CXCursor_LastAttr: Type = 441; + pub const CXCursor_PreprocessingDirective: Type = 500; + pub const CXCursor_MacroDefinition: Type = 501; + pub const CXCursor_MacroExpansion: Type = 502; + pub const CXCursor_MacroInstantiation: Type = 502; + pub const CXCursor_InclusionDirective: Type = 503; + pub const CXCursor_FirstPreprocessing: Type = 500; + pub const CXCursor_LastPreprocessing: Type = 503; + pub const CXCursor_ModuleImportDecl: Type = 600; + pub const CXCursor_TypeAliasTemplateDecl: Type = 601; + pub const CXCursor_StaticAssert: Type = 602; + pub const CXCursor_FriendDecl: Type = 603; + pub const CXCursor_FirstExtraDecl: Type = 600; + pub const CXCursor_LastExtraDecl: Type = 603; + pub const CXCursor_OverloadCandidate: Type = 700; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXCursor { + pub kind: CXCursorKind::Type, + pub xdata: ::std::os::raw::c_int, + pub data: [*const ::std::os::raw::c_void; 3usize], +} +#[test] +fn bindgen_test_layout_CXCursor() { + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(CXCursor)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXCursor)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).kind as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXCursor), + "::", + stringify!(kind) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).xdata as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(CXCursor), + "::", + stringify!(xdata) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).data as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXCursor), + "::", + stringify!(data) + ) + ); +} +extern "C" { + pub fn clang_getNullCursor() -> CXCursor; +} +extern "C" { + pub fn clang_getTranslationUnitCursor(arg1: CXTranslationUnit) -> CXCursor; +} +extern "C" { + pub fn clang_equalCursors( + arg1: CXCursor, + arg2: CXCursor, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Cursor_isNull(cursor: CXCursor) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_hashCursor(arg1: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getCursorKind(arg1: CXCursor) -> CXCursorKind::Type; +} +extern "C" { + pub fn clang_isDeclaration( + arg1: CXCursorKind::Type, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_isInvalidDeclaration(arg1: CXCursor) + -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_isReference( + arg1: CXCursorKind::Type, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_isExpression( + arg1: CXCursorKind::Type, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_isStatement( + arg1: CXCursorKind::Type, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_isAttribute( + arg1: CXCursorKind::Type, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Cursor_hasAttrs(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_isInvalid(arg1: CXCursorKind::Type) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_isTranslationUnit( + arg1: CXCursorKind::Type, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_isPreprocessing( + arg1: CXCursorKind::Type, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_isUnexposed( + arg1: CXCursorKind::Type, + ) -> ::std::os::raw::c_uint; +} +pub mod CXLinkageKind { + pub type Type = u32; + pub const CXLinkage_Invalid: Type = 0; + pub const CXLinkage_NoLinkage: Type = 1; + pub const CXLinkage_Internal: Type = 2; + pub const CXLinkage_UniqueExternal: Type = 3; + pub const CXLinkage_External: Type = 4; +} +extern "C" { + pub fn clang_getCursorLinkage(cursor: CXCursor) -> CXLinkageKind::Type; +} +pub mod CXVisibilityKind { + pub type Type = u32; + pub const CXVisibility_Invalid: Type = 0; + pub const CXVisibility_Hidden: Type = 1; + pub const CXVisibility_Protected: Type = 2; + pub const CXVisibility_Default: Type = 3; +} +extern "C" { + pub fn clang_getCursorVisibility( + cursor: CXCursor, + ) -> CXVisibilityKind::Type; +} +extern "C" { + pub fn clang_getCursorAvailability( + cursor: CXCursor, + ) -> CXAvailabilityKind::Type; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXPlatformAvailability { + pub Platform: CXString, + pub Introduced: CXVersion, + pub Deprecated: CXVersion, + pub Obsoleted: CXVersion, + pub Unavailable: ::std::os::raw::c_int, + pub Message: CXString, +} +#[test] +fn bindgen_test_layout_CXPlatformAvailability() { + assert_eq!( + ::std::mem::size_of::(), + 72usize, + concat!("Size of: ", stringify!(CXPlatformAvailability)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXPlatformAvailability)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Platform + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXPlatformAvailability), + "::", + stringify!(Platform) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Introduced + as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXPlatformAvailability), + "::", + stringify!(Introduced) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Deprecated + as *const _ as usize + }, + 28usize, + concat!( + "Offset of field: ", + stringify!(CXPlatformAvailability), + "::", + stringify!(Deprecated) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Obsoleted + as *const _ as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(CXPlatformAvailability), + "::", + stringify!(Obsoleted) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Unavailable + as *const _ as usize + }, + 52usize, + concat!( + "Offset of field: ", + stringify!(CXPlatformAvailability), + "::", + stringify!(Unavailable) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Message + as *const _ as usize + }, + 56usize, + concat!( + "Offset of field: ", + stringify!(CXPlatformAvailability), + "::", + stringify!(Message) + ) + ); +} +extern "C" { + pub fn clang_getCursorPlatformAvailability( + cursor: CXCursor, + always_deprecated: *mut ::std::os::raw::c_int, + deprecated_message: *mut CXString, + always_unavailable: *mut ::std::os::raw::c_int, + unavailable_message: *mut CXString, + availability: *mut CXPlatformAvailability, + availability_size: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_disposeCXPlatformAvailability( + availability: *mut CXPlatformAvailability, + ); +} +pub mod CXLanguageKind { + pub type Type = u32; + pub const CXLanguage_Invalid: Type = 0; + pub const CXLanguage_C: Type = 1; + pub const CXLanguage_ObjC: Type = 2; + pub const CXLanguage_CPlusPlus: Type = 3; +} +extern "C" { + pub fn clang_getCursorLanguage(cursor: CXCursor) -> CXLanguageKind::Type; +} +pub mod CXTLSKind { + pub type Type = u32; + pub const CXTLS_None: Type = 0; + pub const CXTLS_Dynamic: Type = 1; + pub const CXTLS_Static: Type = 2; +} +extern "C" { + pub fn clang_getCursorTLSKind(cursor: CXCursor) -> CXTLSKind::Type; +} +extern "C" { + pub fn clang_Cursor_getTranslationUnit(arg1: CXCursor) + -> CXTranslationUnit; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXCursorSetImpl { + _unused: [u8; 0], +} +pub type CXCursorSet = *mut CXCursorSetImpl; +extern "C" { + pub fn clang_createCXCursorSet() -> CXCursorSet; +} +extern "C" { + pub fn clang_disposeCXCursorSet(cset: CXCursorSet); +} +extern "C" { + pub fn clang_CXCursorSet_contains( + cset: CXCursorSet, + cursor: CXCursor, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_CXCursorSet_insert( + cset: CXCursorSet, + cursor: CXCursor, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getCursorSemanticParent(cursor: CXCursor) -> CXCursor; +} +extern "C" { + pub fn clang_getCursorLexicalParent(cursor: CXCursor) -> CXCursor; +} +extern "C" { + pub fn clang_getOverriddenCursors( + cursor: CXCursor, + overridden: *mut *mut CXCursor, + num_overridden: *mut ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_disposeOverriddenCursors(overridden: *mut CXCursor); +} +extern "C" { + pub fn clang_getIncludedFile(cursor: CXCursor) -> CXFile; +} +extern "C" { + pub fn clang_getCursor( + arg1: CXTranslationUnit, + arg2: CXSourceLocation, + ) -> CXCursor; +} +extern "C" { + pub fn clang_getCursorLocation(arg1: CXCursor) -> CXSourceLocation; +} +extern "C" { + pub fn clang_getCursorExtent(arg1: CXCursor) -> CXSourceRange; +} +pub mod CXTypeKind { + pub type Type = u32; + pub const CXType_Invalid: Type = 0; + pub const CXType_Unexposed: Type = 1; + pub const CXType_Void: Type = 2; + pub const CXType_Bool: Type = 3; + pub const CXType_Char_U: Type = 4; + pub const CXType_UChar: Type = 5; + pub const CXType_Char16: Type = 6; + pub const CXType_Char32: Type = 7; + pub const CXType_UShort: Type = 8; + pub const CXType_UInt: Type = 9; + pub const CXType_ULong: Type = 10; + pub const CXType_ULongLong: Type = 11; + pub const CXType_UInt128: Type = 12; + pub const CXType_Char_S: Type = 13; + pub const CXType_SChar: Type = 14; + pub const CXType_WChar: Type = 15; + pub const CXType_Short: Type = 16; + pub const CXType_Int: Type = 17; + pub const CXType_Long: Type = 18; + pub const CXType_LongLong: Type = 19; + pub const CXType_Int128: Type = 20; + pub const CXType_Float: Type = 21; + pub const CXType_Double: Type = 22; + pub const CXType_LongDouble: Type = 23; + pub const CXType_NullPtr: Type = 24; + pub const CXType_Overload: Type = 25; + pub const CXType_Dependent: Type = 26; + pub const CXType_ObjCId: Type = 27; + pub const CXType_ObjCClass: Type = 28; + pub const CXType_ObjCSel: Type = 29; + pub const CXType_Float128: Type = 30; + pub const CXType_Half: Type = 31; + pub const CXType_Float16: Type = 32; + pub const CXType_ShortAccum: Type = 33; + pub const CXType_Accum: Type = 34; + pub const CXType_LongAccum: Type = 35; + pub const CXType_UShortAccum: Type = 36; + pub const CXType_UAccum: Type = 37; + pub const CXType_ULongAccum: Type = 38; + pub const CXType_FirstBuiltin: Type = 2; + pub const CXType_LastBuiltin: Type = 38; + pub const CXType_Complex: Type = 100; + pub const CXType_Pointer: Type = 101; + pub const CXType_BlockPointer: Type = 102; + pub const CXType_LValueReference: Type = 103; + pub const CXType_RValueReference: Type = 104; + pub const CXType_Record: Type = 105; + pub const CXType_Enum: Type = 106; + pub const CXType_Typedef: Type = 107; + pub const CXType_ObjCInterface: Type = 108; + pub const CXType_ObjCObjectPointer: Type = 109; + pub const CXType_FunctionNoProto: Type = 110; + pub const CXType_FunctionProto: Type = 111; + pub const CXType_ConstantArray: Type = 112; + pub const CXType_Vector: Type = 113; + pub const CXType_IncompleteArray: Type = 114; + pub const CXType_VariableArray: Type = 115; + pub const CXType_DependentSizedArray: Type = 116; + pub const CXType_MemberPointer: Type = 117; + pub const CXType_Auto: Type = 118; + pub const CXType_Elaborated: Type = 119; + pub const CXType_Pipe: Type = 120; + pub const CXType_OCLImage1dRO: Type = 121; + pub const CXType_OCLImage1dArrayRO: Type = 122; + pub const CXType_OCLImage1dBufferRO: Type = 123; + pub const CXType_OCLImage2dRO: Type = 124; + pub const CXType_OCLImage2dArrayRO: Type = 125; + pub const CXType_OCLImage2dDepthRO: Type = 126; + pub const CXType_OCLImage2dArrayDepthRO: Type = 127; + pub const CXType_OCLImage2dMSAARO: Type = 128; + pub const CXType_OCLImage2dArrayMSAARO: Type = 129; + pub const CXType_OCLImage2dMSAADepthRO: Type = 130; + pub const CXType_OCLImage2dArrayMSAADepthRO: Type = 131; + pub const CXType_OCLImage3dRO: Type = 132; + pub const CXType_OCLImage1dWO: Type = 133; + pub const CXType_OCLImage1dArrayWO: Type = 134; + pub const CXType_OCLImage1dBufferWO: Type = 135; + pub const CXType_OCLImage2dWO: Type = 136; + pub const CXType_OCLImage2dArrayWO: Type = 137; + pub const CXType_OCLImage2dDepthWO: Type = 138; + pub const CXType_OCLImage2dArrayDepthWO: Type = 139; + pub const CXType_OCLImage2dMSAAWO: Type = 140; + pub const CXType_OCLImage2dArrayMSAAWO: Type = 141; + pub const CXType_OCLImage2dMSAADepthWO: Type = 142; + pub const CXType_OCLImage2dArrayMSAADepthWO: Type = 143; + pub const CXType_OCLImage3dWO: Type = 144; + pub const CXType_OCLImage1dRW: Type = 145; + pub const CXType_OCLImage1dArrayRW: Type = 146; + pub const CXType_OCLImage1dBufferRW: Type = 147; + pub const CXType_OCLImage2dRW: Type = 148; + pub const CXType_OCLImage2dArrayRW: Type = 149; + pub const CXType_OCLImage2dDepthRW: Type = 150; + pub const CXType_OCLImage2dArrayDepthRW: Type = 151; + pub const CXType_OCLImage2dMSAARW: Type = 152; + pub const CXType_OCLImage2dArrayMSAARW: Type = 153; + pub const CXType_OCLImage2dMSAADepthRW: Type = 154; + pub const CXType_OCLImage2dArrayMSAADepthRW: Type = 155; + pub const CXType_OCLImage3dRW: Type = 156; + pub const CXType_OCLSampler: Type = 157; + pub const CXType_OCLEvent: Type = 158; + pub const CXType_OCLQueue: Type = 159; + pub const CXType_OCLReserveID: Type = 160; + pub const CXType_ObjCObject: Type = 161; + pub const CXType_ObjCTypeParam: Type = 162; + pub const CXType_Attributed: Type = 163; + pub const CXType_OCLIntelSubgroupAVCMcePayload: Type = 164; + pub const CXType_OCLIntelSubgroupAVCImePayload: Type = 165; + pub const CXType_OCLIntelSubgroupAVCRefPayload: Type = 166; + pub const CXType_OCLIntelSubgroupAVCSicPayload: Type = 167; + pub const CXType_OCLIntelSubgroupAVCMceResult: Type = 168; + pub const CXType_OCLIntelSubgroupAVCImeResult: Type = 169; + pub const CXType_OCLIntelSubgroupAVCRefResult: Type = 170; + pub const CXType_OCLIntelSubgroupAVCSicResult: Type = 171; + pub const CXType_OCLIntelSubgroupAVCImeResultSingleRefStreamout: Type = 172; + pub const CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout: Type = 173; + pub const CXType_OCLIntelSubgroupAVCImeSingleRefStreamin: Type = 174; + pub const CXType_OCLIntelSubgroupAVCImeDualRefStreamin: Type = 175; + pub const CXType_ExtVector: Type = 176; +} +pub mod CXCallingConv { + pub type Type = u32; + pub const CXCallingConv_Default: Type = 0; + pub const CXCallingConv_C: Type = 1; + pub const CXCallingConv_X86StdCall: Type = 2; + pub const CXCallingConv_X86FastCall: Type = 3; + pub const CXCallingConv_X86ThisCall: Type = 4; + pub const CXCallingConv_X86Pascal: Type = 5; + pub const CXCallingConv_AAPCS: Type = 6; + pub const CXCallingConv_AAPCS_VFP: Type = 7; + pub const CXCallingConv_X86RegCall: Type = 8; + pub const CXCallingConv_IntelOclBicc: Type = 9; + pub const CXCallingConv_Win64: Type = 10; + pub const CXCallingConv_X86_64Win64: Type = 10; + pub const CXCallingConv_X86_64SysV: Type = 11; + pub const CXCallingConv_X86VectorCall: Type = 12; + pub const CXCallingConv_Swift: Type = 13; + pub const CXCallingConv_PreserveMost: Type = 14; + pub const CXCallingConv_PreserveAll: Type = 15; + pub const CXCallingConv_AArch64VectorCall: Type = 16; + pub const CXCallingConv_Invalid: Type = 100; + pub const CXCallingConv_Unexposed: Type = 200; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXType { + pub kind: CXTypeKind::Type, + pub data: [*mut ::std::os::raw::c_void; 2usize], +} +#[test] +fn bindgen_test_layout_CXType() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(CXType)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXType)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).kind as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXType), + "::", + stringify!(kind) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).data as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXType), + "::", + stringify!(data) + ) + ); +} +extern "C" { + pub fn clang_getCursorType(C: CXCursor) -> CXType; +} +extern "C" { + pub fn clang_getTypeSpelling(CT: CXType) -> CXString; +} +extern "C" { + pub fn clang_getTypedefDeclUnderlyingType(C: CXCursor) -> CXType; +} +extern "C" { + pub fn clang_getEnumDeclIntegerType(C: CXCursor) -> CXType; +} +extern "C" { + pub fn clang_getEnumConstantDeclValue( + C: CXCursor, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn clang_getEnumConstantDeclUnsignedValue( + C: CXCursor, + ) -> ::std::os::raw::c_ulonglong; +} +extern "C" { + pub fn clang_getFieldDeclBitWidth(C: CXCursor) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_Cursor_getNumArguments(C: CXCursor) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_Cursor_getArgument( + C: CXCursor, + i: ::std::os::raw::c_uint, + ) -> CXCursor; +} +pub mod CXTemplateArgumentKind { + pub type Type = u32; + pub const CXTemplateArgumentKind_Null: Type = 0; + pub const CXTemplateArgumentKind_Type: Type = 1; + pub const CXTemplateArgumentKind_Declaration: Type = 2; + pub const CXTemplateArgumentKind_NullPtr: Type = 3; + pub const CXTemplateArgumentKind_Integral: Type = 4; + pub const CXTemplateArgumentKind_Template: Type = 5; + pub const CXTemplateArgumentKind_TemplateExpansion: Type = 6; + pub const CXTemplateArgumentKind_Expression: Type = 7; + pub const CXTemplateArgumentKind_Pack: Type = 8; + pub const CXTemplateArgumentKind_Invalid: Type = 9; +} +extern "C" { + pub fn clang_Cursor_getNumTemplateArguments( + C: CXCursor, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_Cursor_getTemplateArgumentKind( + C: CXCursor, + I: ::std::os::raw::c_uint, + ) -> CXTemplateArgumentKind::Type; +} +extern "C" { + pub fn clang_Cursor_getTemplateArgumentType( + C: CXCursor, + I: ::std::os::raw::c_uint, + ) -> CXType; +} +extern "C" { + pub fn clang_Cursor_getTemplateArgumentValue( + C: CXCursor, + I: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn clang_Cursor_getTemplateArgumentUnsignedValue( + C: CXCursor, + I: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_ulonglong; +} +extern "C" { + pub fn clang_equalTypes(A: CXType, B: CXType) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getCanonicalType(T: CXType) -> CXType; +} +extern "C" { + pub fn clang_isConstQualifiedType(T: CXType) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Cursor_isMacroFunctionLike( + C: CXCursor, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Cursor_isMacroBuiltin(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Cursor_isFunctionInlined( + C: CXCursor, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_isVolatileQualifiedType(T: CXType) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_isRestrictQualifiedType(T: CXType) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getAddressSpace(T: CXType) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getTypedefName(CT: CXType) -> CXString; +} +extern "C" { + pub fn clang_getPointeeType(T: CXType) -> CXType; +} +extern "C" { + pub fn clang_getTypeDeclaration(T: CXType) -> CXCursor; +} +extern "C" { + pub fn clang_getDeclObjCTypeEncoding(C: CXCursor) -> CXString; +} +extern "C" { + pub fn clang_Type_getObjCEncoding(type_: CXType) -> CXString; +} +extern "C" { + pub fn clang_getTypeKindSpelling(K: CXTypeKind::Type) -> CXString; +} +extern "C" { + pub fn clang_getFunctionTypeCallingConv(T: CXType) -> CXCallingConv::Type; +} +extern "C" { + pub fn clang_getResultType(T: CXType) -> CXType; +} +extern "C" { + pub fn clang_getExceptionSpecificationType( + T: CXType, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_getNumArgTypes(T: CXType) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_getArgType(T: CXType, i: ::std::os::raw::c_uint) -> CXType; +} +extern "C" { + pub fn clang_Type_getObjCObjectBaseType(T: CXType) -> CXType; +} +extern "C" { + pub fn clang_Type_getNumObjCProtocolRefs( + T: CXType, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Type_getObjCProtocolDecl( + T: CXType, + i: ::std::os::raw::c_uint, + ) -> CXCursor; +} +extern "C" { + pub fn clang_Type_getNumObjCTypeArgs(T: CXType) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Type_getObjCTypeArg( + T: CXType, + i: ::std::os::raw::c_uint, + ) -> CXType; +} +extern "C" { + pub fn clang_isFunctionTypeVariadic(T: CXType) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getCursorResultType(C: CXCursor) -> CXType; +} +extern "C" { + pub fn clang_getCursorExceptionSpecificationType( + C: CXCursor, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_isPODType(T: CXType) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getElementType(T: CXType) -> CXType; +} +extern "C" { + pub fn clang_getNumElements(T: CXType) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn clang_getArrayElementType(T: CXType) -> CXType; +} +extern "C" { + pub fn clang_getArraySize(T: CXType) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn clang_Type_getNamedType(T: CXType) -> CXType; +} +extern "C" { + pub fn clang_Type_isTransparentTagTypedef( + T: CXType, + ) -> ::std::os::raw::c_uint; +} +pub mod CXTypeNullabilityKind { + pub type Type = u32; + pub const CXTypeNullability_NonNull: Type = 0; + pub const CXTypeNullability_Nullable: Type = 1; + pub const CXTypeNullability_Unspecified: Type = 2; + pub const CXTypeNullability_Invalid: Type = 3; +} +extern "C" { + pub fn clang_Type_getNullability(T: CXType) -> CXTypeNullabilityKind::Type; +} +pub mod CXTypeLayoutError { + pub type Type = i32; + pub const CXTypeLayoutError_Invalid: Type = -1; + pub const CXTypeLayoutError_Incomplete: Type = -2; + pub const CXTypeLayoutError_Dependent: Type = -3; + pub const CXTypeLayoutError_NotConstantSize: Type = -4; + pub const CXTypeLayoutError_InvalidFieldName: Type = -5; + pub const CXTypeLayoutError_Undeduced: Type = -6; +} +extern "C" { + pub fn clang_Type_getAlignOf(T: CXType) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn clang_Type_getClassType(T: CXType) -> CXType; +} +extern "C" { + pub fn clang_Type_getSizeOf(T: CXType) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn clang_Type_getOffsetOf( + T: CXType, + S: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn clang_Type_getModifiedType(T: CXType) -> CXType; +} +extern "C" { + pub fn clang_Cursor_getOffsetOfField( + C: CXCursor, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn clang_Cursor_isAnonymous(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Cursor_isAnonymousRecordDecl( + C: CXCursor, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Cursor_isInlineNamespace( + C: CXCursor, + ) -> ::std::os::raw::c_uint; +} +pub mod CXRefQualifierKind { + pub type Type = u32; + pub const CXRefQualifier_None: Type = 0; + pub const CXRefQualifier_LValue: Type = 1; + pub const CXRefQualifier_RValue: Type = 2; +} +extern "C" { + pub fn clang_Type_getNumTemplateArguments( + T: CXType, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_Type_getTemplateArgumentAsType( + T: CXType, + i: ::std::os::raw::c_uint, + ) -> CXType; +} +extern "C" { + pub fn clang_Type_getCXXRefQualifier(T: CXType) + -> CXRefQualifierKind::Type; +} +extern "C" { + pub fn clang_Cursor_isBitField(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_isVirtualBase(arg1: CXCursor) -> ::std::os::raw::c_uint; +} +pub mod CX_CXXAccessSpecifier { + pub type Type = u32; + pub const CX_CXXInvalidAccessSpecifier: Type = 0; + pub const CX_CXXPublic: Type = 1; + pub const CX_CXXProtected: Type = 2; + pub const CX_CXXPrivate: Type = 3; +} +extern "C" { + pub fn clang_getCXXAccessSpecifier( + arg1: CXCursor, + ) -> CX_CXXAccessSpecifier::Type; +} +pub mod CX_StorageClass { + pub type Type = u32; + pub const CX_SC_Invalid: Type = 0; + pub const CX_SC_None: Type = 1; + pub const CX_SC_Extern: Type = 2; + pub const CX_SC_Static: Type = 3; + pub const CX_SC_PrivateExtern: Type = 4; + pub const CX_SC_OpenCLWorkGroupLocal: Type = 5; + pub const CX_SC_Auto: Type = 6; + pub const CX_SC_Register: Type = 7; +} +extern "C" { + pub fn clang_Cursor_getStorageClass( + arg1: CXCursor, + ) -> CX_StorageClass::Type; +} +extern "C" { + pub fn clang_getNumOverloadedDecls( + cursor: CXCursor, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getOverloadedDecl( + cursor: CXCursor, + index: ::std::os::raw::c_uint, + ) -> CXCursor; +} +extern "C" { + pub fn clang_getIBOutletCollectionType(arg1: CXCursor) -> CXType; +} +pub mod CXChildVisitResult { + pub type Type = u32; + pub const CXChildVisit_Break: Type = 0; + pub const CXChildVisit_Continue: Type = 1; + pub const CXChildVisit_Recurse: Type = 2; +} +pub type CXCursorVisitor = ::std::option::Option< + unsafe extern "C" fn( + cursor: CXCursor, + parent: CXCursor, + client_data: CXClientData, + ) -> CXChildVisitResult::Type, +>; +extern "C" { + pub fn clang_visitChildren( + parent: CXCursor, + visitor: CXCursorVisitor, + client_data: CXClientData, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getCursorUSR(arg1: CXCursor) -> CXString; +} +extern "C" { + pub fn clang_constructUSR_ObjCClass( + class_name: *const ::std::os::raw::c_char, + ) -> CXString; +} +extern "C" { + pub fn clang_constructUSR_ObjCCategory( + class_name: *const ::std::os::raw::c_char, + category_name: *const ::std::os::raw::c_char, + ) -> CXString; +} +extern "C" { + pub fn clang_constructUSR_ObjCProtocol( + protocol_name: *const ::std::os::raw::c_char, + ) -> CXString; +} +extern "C" { + pub fn clang_constructUSR_ObjCIvar( + name: *const ::std::os::raw::c_char, + classUSR: CXString, + ) -> CXString; +} +extern "C" { + pub fn clang_constructUSR_ObjCMethod( + name: *const ::std::os::raw::c_char, + isInstanceMethod: ::std::os::raw::c_uint, + classUSR: CXString, + ) -> CXString; +} +extern "C" { + pub fn clang_constructUSR_ObjCProperty( + property: *const ::std::os::raw::c_char, + classUSR: CXString, + ) -> CXString; +} +extern "C" { + pub fn clang_getCursorSpelling(arg1: CXCursor) -> CXString; +} +extern "C" { + pub fn clang_Cursor_getSpellingNameRange( + arg1: CXCursor, + pieceIndex: ::std::os::raw::c_uint, + options: ::std::os::raw::c_uint, + ) -> CXSourceRange; +} +pub type CXPrintingPolicy = *mut ::std::os::raw::c_void; +pub mod CXPrintingPolicyProperty { + pub type Type = u32; + pub const CXPrintingPolicy_Indentation: Type = 0; + pub const CXPrintingPolicy_SuppressSpecifiers: Type = 1; + pub const CXPrintingPolicy_SuppressTagKeyword: Type = 2; + pub const CXPrintingPolicy_IncludeTagDefinition: Type = 3; + pub const CXPrintingPolicy_SuppressScope: Type = 4; + pub const CXPrintingPolicy_SuppressUnwrittenScope: Type = 5; + pub const CXPrintingPolicy_SuppressInitializers: Type = 6; + pub const CXPrintingPolicy_ConstantArraySizeAsWritten: Type = 7; + pub const CXPrintingPolicy_AnonymousTagLocations: Type = 8; + pub const CXPrintingPolicy_SuppressStrongLifetime: Type = 9; + pub const CXPrintingPolicy_SuppressLifetimeQualifiers: Type = 10; + pub const CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors: Type = 11; + pub const CXPrintingPolicy_Bool: Type = 12; + pub const CXPrintingPolicy_Restrict: Type = 13; + pub const CXPrintingPolicy_Alignof: Type = 14; + pub const CXPrintingPolicy_UnderscoreAlignof: Type = 15; + pub const CXPrintingPolicy_UseVoidForZeroParams: Type = 16; + pub const CXPrintingPolicy_TerseOutput: Type = 17; + pub const CXPrintingPolicy_PolishForDeclaration: Type = 18; + pub const CXPrintingPolicy_Half: Type = 19; + pub const CXPrintingPolicy_MSWChar: Type = 20; + pub const CXPrintingPolicy_IncludeNewlines: Type = 21; + pub const CXPrintingPolicy_MSVCFormatting: Type = 22; + pub const CXPrintingPolicy_ConstantsAsWritten: Type = 23; + pub const CXPrintingPolicy_SuppressImplicitBase: Type = 24; + pub const CXPrintingPolicy_FullyQualifiedName: Type = 25; + pub const CXPrintingPolicy_LastProperty: Type = 25; +} +extern "C" { + pub fn clang_PrintingPolicy_getProperty( + Policy: CXPrintingPolicy, + Property: CXPrintingPolicyProperty::Type, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_PrintingPolicy_setProperty( + Policy: CXPrintingPolicy, + Property: CXPrintingPolicyProperty::Type, + Value: ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_getCursorPrintingPolicy(arg1: CXCursor) -> CXPrintingPolicy; +} +extern "C" { + pub fn clang_PrintingPolicy_dispose(Policy: CXPrintingPolicy); +} +extern "C" { + pub fn clang_getCursorPrettyPrinted( + Cursor: CXCursor, + Policy: CXPrintingPolicy, + ) -> CXString; +} +extern "C" { + pub fn clang_getCursorDisplayName(arg1: CXCursor) -> CXString; +} +extern "C" { + pub fn clang_getCursorReferenced(arg1: CXCursor) -> CXCursor; +} +extern "C" { + pub fn clang_getCursorDefinition(arg1: CXCursor) -> CXCursor; +} +extern "C" { + pub fn clang_isCursorDefinition(arg1: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getCanonicalCursor(arg1: CXCursor) -> CXCursor; +} +extern "C" { + pub fn clang_Cursor_getObjCSelectorIndex( + arg1: CXCursor, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_Cursor_isDynamicCall(C: CXCursor) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_Cursor_getReceiverType(C: CXCursor) -> CXType; +} +pub mod CXObjCPropertyAttrKind { + pub type Type = u32; + pub const CXObjCPropertyAttr_noattr: Type = 0; + pub const CXObjCPropertyAttr_readonly: Type = 1; + pub const CXObjCPropertyAttr_getter: Type = 2; + pub const CXObjCPropertyAttr_assign: Type = 4; + pub const CXObjCPropertyAttr_readwrite: Type = 8; + pub const CXObjCPropertyAttr_retain: Type = 16; + pub const CXObjCPropertyAttr_copy: Type = 32; + pub const CXObjCPropertyAttr_nonatomic: Type = 64; + pub const CXObjCPropertyAttr_setter: Type = 128; + pub const CXObjCPropertyAttr_atomic: Type = 256; + pub const CXObjCPropertyAttr_weak: Type = 512; + pub const CXObjCPropertyAttr_strong: Type = 1024; + pub const CXObjCPropertyAttr_unsafe_unretained: Type = 2048; + pub const CXObjCPropertyAttr_class: Type = 4096; +} +extern "C" { + pub fn clang_Cursor_getObjCPropertyAttributes( + C: CXCursor, + reserved: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Cursor_getObjCPropertyGetterName(C: CXCursor) -> CXString; +} +extern "C" { + pub fn clang_Cursor_getObjCPropertySetterName(C: CXCursor) -> CXString; +} +pub mod CXObjCDeclQualifierKind { + pub type Type = u32; + pub const CXObjCDeclQualifier_None: Type = 0; + pub const CXObjCDeclQualifier_In: Type = 1; + pub const CXObjCDeclQualifier_Inout: Type = 2; + pub const CXObjCDeclQualifier_Out: Type = 4; + pub const CXObjCDeclQualifier_Bycopy: Type = 8; + pub const CXObjCDeclQualifier_Byref: Type = 16; + pub const CXObjCDeclQualifier_Oneway: Type = 32; +} +extern "C" { + pub fn clang_Cursor_getObjCDeclQualifiers( + C: CXCursor, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Cursor_isObjCOptional(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Cursor_isVariadic(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Cursor_isExternalSymbol( + C: CXCursor, + language: *mut CXString, + definedIn: *mut CXString, + isGenerated: *mut ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Cursor_getCommentRange(C: CXCursor) -> CXSourceRange; +} +extern "C" { + pub fn clang_Cursor_getRawCommentText(C: CXCursor) -> CXString; +} +extern "C" { + pub fn clang_Cursor_getBriefCommentText(C: CXCursor) -> CXString; +} +extern "C" { + pub fn clang_Cursor_getMangling(arg1: CXCursor) -> CXString; +} +extern "C" { + pub fn clang_Cursor_getCXXManglings(arg1: CXCursor) -> *mut CXStringSet; +} +extern "C" { + pub fn clang_Cursor_getObjCManglings(arg1: CXCursor) -> *mut CXStringSet; +} +pub type CXModule = *mut ::std::os::raw::c_void; +extern "C" { + pub fn clang_Cursor_getModule(C: CXCursor) -> CXModule; +} +extern "C" { + pub fn clang_getModuleForFile( + arg1: CXTranslationUnit, + arg2: CXFile, + ) -> CXModule; +} +extern "C" { + pub fn clang_Module_getASTFile(Module: CXModule) -> CXFile; +} +extern "C" { + pub fn clang_Module_getParent(Module: CXModule) -> CXModule; +} +extern "C" { + pub fn clang_Module_getName(Module: CXModule) -> CXString; +} +extern "C" { + pub fn clang_Module_getFullName(Module: CXModule) -> CXString; +} +extern "C" { + pub fn clang_Module_isSystem(Module: CXModule) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_Module_getNumTopLevelHeaders( + arg1: CXTranslationUnit, + Module: CXModule, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Module_getTopLevelHeader( + arg1: CXTranslationUnit, + Module: CXModule, + Index: ::std::os::raw::c_uint, + ) -> CXFile; +} +extern "C" { + pub fn clang_CXXConstructor_isConvertingConstructor( + C: CXCursor, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_CXXConstructor_isCopyConstructor( + C: CXCursor, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_CXXConstructor_isDefaultConstructor( + C: CXCursor, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_CXXConstructor_isMoveConstructor( + C: CXCursor, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_CXXField_isMutable(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_CXXMethod_isDefaulted(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_CXXMethod_isPureVirtual(C: CXCursor) + -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_CXXMethod_isStatic(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_CXXMethod_isVirtual(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_CXXRecord_isAbstract(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_EnumDecl_isScoped(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_CXXMethod_isConst(C: CXCursor) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getTemplateCursorKind(C: CXCursor) -> CXCursorKind::Type; +} +extern "C" { + pub fn clang_getSpecializedCursorTemplate(C: CXCursor) -> CXCursor; +} +extern "C" { + pub fn clang_getCursorReferenceNameRange( + C: CXCursor, + NameFlags: ::std::os::raw::c_uint, + PieceIndex: ::std::os::raw::c_uint, + ) -> CXSourceRange; +} +pub mod CXNameRefFlags { + pub type Type = u32; + pub const CXNameRange_WantQualifier: Type = 1; + pub const CXNameRange_WantTemplateArgs: Type = 2; + pub const CXNameRange_WantSinglePiece: Type = 4; +} +pub mod CXTokenKind { + pub type Type = u32; + pub const CXToken_Punctuation: Type = 0; + pub const CXToken_Keyword: Type = 1; + pub const CXToken_Identifier: Type = 2; + pub const CXToken_Literal: Type = 3; + pub const CXToken_Comment: Type = 4; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXToken { + pub int_data: [::std::os::raw::c_uint; 4usize], + pub ptr_data: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout_CXToken() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(CXToken)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXToken)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).int_data as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXToken), + "::", + stringify!(int_data) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ptr_data as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXToken), + "::", + stringify!(ptr_data) + ) + ); +} +extern "C" { + pub fn clang_getToken( + TU: CXTranslationUnit, + Location: CXSourceLocation, + ) -> *mut CXToken; +} +extern "C" { + pub fn clang_getTokenKind(arg1: CXToken) -> CXTokenKind::Type; +} +extern "C" { + pub fn clang_getTokenSpelling( + arg1: CXTranslationUnit, + arg2: CXToken, + ) -> CXString; +} +extern "C" { + pub fn clang_getTokenLocation( + arg1: CXTranslationUnit, + arg2: CXToken, + ) -> CXSourceLocation; +} +extern "C" { + pub fn clang_getTokenExtent( + arg1: CXTranslationUnit, + arg2: CXToken, + ) -> CXSourceRange; +} +extern "C" { + pub fn clang_tokenize( + TU: CXTranslationUnit, + Range: CXSourceRange, + Tokens: *mut *mut CXToken, + NumTokens: *mut ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_annotateTokens( + TU: CXTranslationUnit, + Tokens: *mut CXToken, + NumTokens: ::std::os::raw::c_uint, + Cursors: *mut CXCursor, + ); +} +extern "C" { + pub fn clang_disposeTokens( + TU: CXTranslationUnit, + Tokens: *mut CXToken, + NumTokens: ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_getCursorKindSpelling(Kind: CXCursorKind::Type) -> CXString; +} +extern "C" { + pub fn clang_getDefinitionSpellingAndExtent( + arg1: CXCursor, + startBuf: *mut *const ::std::os::raw::c_char, + endBuf: *mut *const ::std::os::raw::c_char, + startLine: *mut ::std::os::raw::c_uint, + startColumn: *mut ::std::os::raw::c_uint, + endLine: *mut ::std::os::raw::c_uint, + endColumn: *mut ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_enableStackTraces(); +} +extern "C" { + pub fn clang_executeOnThread( + fn_: ::std::option::Option< + unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void), + >, + user_data: *mut ::std::os::raw::c_void, + stack_size: ::std::os::raw::c_uint, + ); +} +pub type CXCompletionString = *mut ::std::os::raw::c_void; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXCompletionResult { + pub CursorKind: CXCursorKind::Type, + pub CompletionString: CXCompletionString, +} +#[test] +fn bindgen_test_layout_CXCompletionResult() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(CXCompletionResult)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXCompletionResult)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).CursorKind + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXCompletionResult), + "::", + stringify!(CursorKind) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).CompletionString + as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXCompletionResult), + "::", + stringify!(CompletionString) + ) + ); +} +pub mod CXCompletionChunkKind { + pub type Type = u32; + pub const CXCompletionChunk_Optional: Type = 0; + pub const CXCompletionChunk_TypedText: Type = 1; + pub const CXCompletionChunk_Text: Type = 2; + pub const CXCompletionChunk_Placeholder: Type = 3; + pub const CXCompletionChunk_Informative: Type = 4; + pub const CXCompletionChunk_CurrentParameter: Type = 5; + pub const CXCompletionChunk_LeftParen: Type = 6; + pub const CXCompletionChunk_RightParen: Type = 7; + pub const CXCompletionChunk_LeftBracket: Type = 8; + pub const CXCompletionChunk_RightBracket: Type = 9; + pub const CXCompletionChunk_LeftBrace: Type = 10; + pub const CXCompletionChunk_RightBrace: Type = 11; + pub const CXCompletionChunk_LeftAngle: Type = 12; + pub const CXCompletionChunk_RightAngle: Type = 13; + pub const CXCompletionChunk_Comma: Type = 14; + pub const CXCompletionChunk_ResultType: Type = 15; + pub const CXCompletionChunk_Colon: Type = 16; + pub const CXCompletionChunk_SemiColon: Type = 17; + pub const CXCompletionChunk_Equal: Type = 18; + pub const CXCompletionChunk_HorizontalSpace: Type = 19; + pub const CXCompletionChunk_VerticalSpace: Type = 20; +} +extern "C" { + pub fn clang_getCompletionChunkKind( + completion_string: CXCompletionString, + chunk_number: ::std::os::raw::c_uint, + ) -> CXCompletionChunkKind::Type; +} +extern "C" { + pub fn clang_getCompletionChunkText( + completion_string: CXCompletionString, + chunk_number: ::std::os::raw::c_uint, + ) -> CXString; +} +extern "C" { + pub fn clang_getCompletionChunkCompletionString( + completion_string: CXCompletionString, + chunk_number: ::std::os::raw::c_uint, + ) -> CXCompletionString; +} +extern "C" { + pub fn clang_getNumCompletionChunks( + completion_string: CXCompletionString, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getCompletionPriority( + completion_string: CXCompletionString, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getCompletionAvailability( + completion_string: CXCompletionString, + ) -> CXAvailabilityKind::Type; +} +extern "C" { + pub fn clang_getCompletionNumAnnotations( + completion_string: CXCompletionString, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getCompletionAnnotation( + completion_string: CXCompletionString, + annotation_number: ::std::os::raw::c_uint, + ) -> CXString; +} +extern "C" { + pub fn clang_getCompletionParent( + completion_string: CXCompletionString, + kind: *mut CXCursorKind::Type, + ) -> CXString; +} +extern "C" { + pub fn clang_getCompletionBriefComment( + completion_string: CXCompletionString, + ) -> CXString; +} +extern "C" { + pub fn clang_getCursorCompletionString( + cursor: CXCursor, + ) -> CXCompletionString; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXCodeCompleteResults { + pub Results: *mut CXCompletionResult, + pub NumResults: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_CXCodeCompleteResults() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(CXCodeCompleteResults)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXCodeCompleteResults)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).Results + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXCodeCompleteResults), + "::", + stringify!(Results) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).NumResults + as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXCodeCompleteResults), + "::", + stringify!(NumResults) + ) + ); +} +extern "C" { + pub fn clang_getCompletionNumFixIts( + results: *mut CXCodeCompleteResults, + completion_index: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_getCompletionFixIt( + results: *mut CXCodeCompleteResults, + completion_index: ::std::os::raw::c_uint, + fixit_index: ::std::os::raw::c_uint, + replacement_range: *mut CXSourceRange, + ) -> CXString; +} +pub mod CXCodeComplete_Flags { + pub type Type = u32; + pub const CXCodeComplete_IncludeMacros: Type = 1; + pub const CXCodeComplete_IncludeCodePatterns: Type = 2; + pub const CXCodeComplete_IncludeBriefComments: Type = 4; + pub const CXCodeComplete_SkipPreamble: Type = 8; + pub const CXCodeComplete_IncludeCompletionsWithFixIts: Type = 16; +} +pub mod CXCompletionContext { + pub type Type = u32; + pub const CXCompletionContext_Unexposed: Type = 0; + pub const CXCompletionContext_AnyType: Type = 1; + pub const CXCompletionContext_AnyValue: Type = 2; + pub const CXCompletionContext_ObjCObjectValue: Type = 4; + pub const CXCompletionContext_ObjCSelectorValue: Type = 8; + pub const CXCompletionContext_CXXClassTypeValue: Type = 16; + pub const CXCompletionContext_DotMemberAccess: Type = 32; + pub const CXCompletionContext_ArrowMemberAccess: Type = 64; + pub const CXCompletionContext_ObjCPropertyAccess: Type = 128; + pub const CXCompletionContext_EnumTag: Type = 256; + pub const CXCompletionContext_UnionTag: Type = 512; + pub const CXCompletionContext_StructTag: Type = 1024; + pub const CXCompletionContext_ClassTag: Type = 2048; + pub const CXCompletionContext_Namespace: Type = 4096; + pub const CXCompletionContext_NestedNameSpecifier: Type = 8192; + pub const CXCompletionContext_ObjCInterface: Type = 16384; + pub const CXCompletionContext_ObjCProtocol: Type = 32768; + pub const CXCompletionContext_ObjCCategory: Type = 65536; + pub const CXCompletionContext_ObjCInstanceMessage: Type = 131072; + pub const CXCompletionContext_ObjCClassMessage: Type = 262144; + pub const CXCompletionContext_ObjCSelectorName: Type = 524288; + pub const CXCompletionContext_MacroName: Type = 1048576; + pub const CXCompletionContext_NaturalLanguage: Type = 2097152; + pub const CXCompletionContext_IncludedFile: Type = 4194304; + pub const CXCompletionContext_Unknown: Type = 8388607; +} +extern "C" { + pub fn clang_defaultCodeCompleteOptions() -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_codeCompleteAt( + TU: CXTranslationUnit, + complete_filename: *const ::std::os::raw::c_char, + complete_line: ::std::os::raw::c_uint, + complete_column: ::std::os::raw::c_uint, + unsaved_files: *mut CXUnsavedFile, + num_unsaved_files: ::std::os::raw::c_uint, + options: ::std::os::raw::c_uint, + ) -> *mut CXCodeCompleteResults; +} +extern "C" { + pub fn clang_sortCodeCompletionResults( + Results: *mut CXCompletionResult, + NumResults: ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_disposeCodeCompleteResults( + Results: *mut CXCodeCompleteResults, + ); +} +extern "C" { + pub fn clang_codeCompleteGetNumDiagnostics( + Results: *mut CXCodeCompleteResults, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_codeCompleteGetDiagnostic( + Results: *mut CXCodeCompleteResults, + Index: ::std::os::raw::c_uint, + ) -> CXDiagnostic; +} +extern "C" { + pub fn clang_codeCompleteGetContexts( + Results: *mut CXCodeCompleteResults, + ) -> ::std::os::raw::c_ulonglong; +} +extern "C" { + pub fn clang_codeCompleteGetContainerKind( + Results: *mut CXCodeCompleteResults, + IsIncomplete: *mut ::std::os::raw::c_uint, + ) -> CXCursorKind::Type; +} +extern "C" { + pub fn clang_codeCompleteGetContainerUSR( + Results: *mut CXCodeCompleteResults, + ) -> CXString; +} +extern "C" { + pub fn clang_codeCompleteGetObjCSelector( + Results: *mut CXCodeCompleteResults, + ) -> CXString; +} +extern "C" { + pub fn clang_getClangVersion() -> CXString; +} +extern "C" { + pub fn clang_toggleCrashRecovery(isEnabled: ::std::os::raw::c_uint); +} +pub type CXInclusionVisitor = ::std::option::Option< + unsafe extern "C" fn( + included_file: CXFile, + inclusion_stack: *mut CXSourceLocation, + include_len: ::std::os::raw::c_uint, + client_data: CXClientData, + ), +>; +extern "C" { + pub fn clang_getInclusions( + tu: CXTranslationUnit, + visitor: CXInclusionVisitor, + client_data: CXClientData, + ); +} +pub mod CXEvalResultKind { + pub type Type = u32; + pub const CXEval_Int: Type = 1; + pub const CXEval_Float: Type = 2; + pub const CXEval_ObjCStrLiteral: Type = 3; + pub const CXEval_StrLiteral: Type = 4; + pub const CXEval_CFStr: Type = 5; + pub const CXEval_Other: Type = 6; + pub const CXEval_UnExposed: Type = 0; +} +pub type CXEvalResult = *mut ::std::os::raw::c_void; +extern "C" { + pub fn clang_Cursor_Evaluate(C: CXCursor) -> CXEvalResult; +} +extern "C" { + pub fn clang_EvalResult_getKind(E: CXEvalResult) -> CXEvalResultKind::Type; +} +extern "C" { + pub fn clang_EvalResult_getAsInt(E: CXEvalResult) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_EvalResult_getAsLongLong( + E: CXEvalResult, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn clang_EvalResult_isUnsignedInt( + E: CXEvalResult, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_EvalResult_getAsUnsigned( + E: CXEvalResult, + ) -> ::std::os::raw::c_ulonglong; +} +extern "C" { + pub fn clang_EvalResult_getAsDouble(E: CXEvalResult) -> f64; +} +extern "C" { + pub fn clang_EvalResult_getAsStr( + E: CXEvalResult, + ) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn clang_EvalResult_dispose(E: CXEvalResult); +} +pub type CXRemapping = *mut ::std::os::raw::c_void; +extern "C" { + pub fn clang_getRemappings( + path: *const ::std::os::raw::c_char, + ) -> CXRemapping; +} +extern "C" { + pub fn clang_getRemappingsFromFileList( + filePaths: *mut *const ::std::os::raw::c_char, + numFiles: ::std::os::raw::c_uint, + ) -> CXRemapping; +} +extern "C" { + pub fn clang_remap_getNumFiles(arg1: CXRemapping) + -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_remap_getFilenames( + arg1: CXRemapping, + index: ::std::os::raw::c_uint, + original: *mut CXString, + transformed: *mut CXString, + ); +} +extern "C" { + pub fn clang_remap_dispose(arg1: CXRemapping); +} +pub mod CXVisitorResult { + pub type Type = u32; + pub const CXVisit_Break: Type = 0; + pub const CXVisit_Continue: Type = 1; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXCursorAndRangeVisitor { + pub context: *mut ::std::os::raw::c_void, + pub visit: ::std::option::Option< + unsafe extern "C" fn( + context: *mut ::std::os::raw::c_void, + arg1: CXCursor, + arg2: CXSourceRange, + ) -> CXVisitorResult::Type, + >, +} +#[test] +fn bindgen_test_layout_CXCursorAndRangeVisitor() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(CXCursorAndRangeVisitor)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXCursorAndRangeVisitor)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).context + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXCursorAndRangeVisitor), + "::", + stringify!(context) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).visit + as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXCursorAndRangeVisitor), + "::", + stringify!(visit) + ) + ); +} +pub mod CXResult { + pub type Type = u32; + pub const CXResult_Success: Type = 0; + pub const CXResult_Invalid: Type = 1; + pub const CXResult_VisitBreak: Type = 2; +} +extern "C" { + pub fn clang_findReferencesInFile( + cursor: CXCursor, + file: CXFile, + visitor: CXCursorAndRangeVisitor, + ) -> CXResult::Type; +} +extern "C" { + pub fn clang_findIncludesInFile( + TU: CXTranslationUnit, + file: CXFile, + visitor: CXCursorAndRangeVisitor, + ) -> CXResult::Type; +} +pub type CXIdxClientFile = *mut ::std::os::raw::c_void; +pub type CXIdxClientEntity = *mut ::std::os::raw::c_void; +pub type CXIdxClientContainer = *mut ::std::os::raw::c_void; +pub type CXIdxClientASTFile = *mut ::std::os::raw::c_void; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxLoc { + pub ptr_data: [*mut ::std::os::raw::c_void; 2usize], + pub int_data: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_CXIdxLoc() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(CXIdxLoc)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxLoc)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ptr_data as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxLoc), + "::", + stringify!(ptr_data) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).int_data as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXIdxLoc), + "::", + stringify!(int_data) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxIncludedFileInfo { + pub hashLoc: CXIdxLoc, + pub filename: *const ::std::os::raw::c_char, + pub file: CXFile, + pub isImport: ::std::os::raw::c_int, + pub isAngled: ::std::os::raw::c_int, + pub isModuleImport: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_CXIdxIncludedFileInfo() { + assert_eq!( + ::std::mem::size_of::(), + 56usize, + concat!("Size of: ", stringify!(CXIdxIncludedFileInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxIncludedFileInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).hashLoc + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxIncludedFileInfo), + "::", + stringify!(hashLoc) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).filename + as *const _ as usize + }, + 24usize, + concat!( + "Offset of field: ", + stringify!(CXIdxIncludedFileInfo), + "::", + stringify!(filename) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).file as *const _ + as usize + }, + 32usize, + concat!( + "Offset of field: ", + stringify!(CXIdxIncludedFileInfo), + "::", + stringify!(file) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).isImport + as *const _ as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(CXIdxIncludedFileInfo), + "::", + stringify!(isImport) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).isAngled + as *const _ as usize + }, + 44usize, + concat!( + "Offset of field: ", + stringify!(CXIdxIncludedFileInfo), + "::", + stringify!(isAngled) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).isModuleImport + as *const _ as usize + }, + 48usize, + concat!( + "Offset of field: ", + stringify!(CXIdxIncludedFileInfo), + "::", + stringify!(isModuleImport) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxImportedASTFileInfo { + pub file: CXFile, + pub module: CXModule, + pub loc: CXIdxLoc, + pub isImplicit: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_CXIdxImportedASTFileInfo() { + assert_eq!( + ::std::mem::size_of::(), + 48usize, + concat!("Size of: ", stringify!(CXIdxImportedASTFileInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxImportedASTFileInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).file + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxImportedASTFileInfo), + "::", + stringify!(file) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).module + as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxImportedASTFileInfo), + "::", + stringify!(module) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).loc as *const _ + as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXIdxImportedASTFileInfo), + "::", + stringify!(loc) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).isImplicit + as *const _ as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(CXIdxImportedASTFileInfo), + "::", + stringify!(isImplicit) + ) + ); +} +pub mod CXIdxEntityKind { + pub type Type = u32; + pub const CXIdxEntity_Unexposed: Type = 0; + pub const CXIdxEntity_Typedef: Type = 1; + pub const CXIdxEntity_Function: Type = 2; + pub const CXIdxEntity_Variable: Type = 3; + pub const CXIdxEntity_Field: Type = 4; + pub const CXIdxEntity_EnumConstant: Type = 5; + pub const CXIdxEntity_ObjCClass: Type = 6; + pub const CXIdxEntity_ObjCProtocol: Type = 7; + pub const CXIdxEntity_ObjCCategory: Type = 8; + pub const CXIdxEntity_ObjCInstanceMethod: Type = 9; + pub const CXIdxEntity_ObjCClassMethod: Type = 10; + pub const CXIdxEntity_ObjCProperty: Type = 11; + pub const CXIdxEntity_ObjCIvar: Type = 12; + pub const CXIdxEntity_Enum: Type = 13; + pub const CXIdxEntity_Struct: Type = 14; + pub const CXIdxEntity_Union: Type = 15; + pub const CXIdxEntity_CXXClass: Type = 16; + pub const CXIdxEntity_CXXNamespace: Type = 17; + pub const CXIdxEntity_CXXNamespaceAlias: Type = 18; + pub const CXIdxEntity_CXXStaticVariable: Type = 19; + pub const CXIdxEntity_CXXStaticMethod: Type = 20; + pub const CXIdxEntity_CXXInstanceMethod: Type = 21; + pub const CXIdxEntity_CXXConstructor: Type = 22; + pub const CXIdxEntity_CXXDestructor: Type = 23; + pub const CXIdxEntity_CXXConversionFunction: Type = 24; + pub const CXIdxEntity_CXXTypeAlias: Type = 25; + pub const CXIdxEntity_CXXInterface: Type = 26; +} +pub mod CXIdxEntityLanguage { + pub type Type = u32; + pub const CXIdxEntityLang_None: Type = 0; + pub const CXIdxEntityLang_C: Type = 1; + pub const CXIdxEntityLang_ObjC: Type = 2; + pub const CXIdxEntityLang_CXX: Type = 3; + pub const CXIdxEntityLang_Swift: Type = 4; +} +pub mod CXIdxEntityCXXTemplateKind { + pub type Type = u32; + pub const CXIdxEntity_NonTemplate: Type = 0; + pub const CXIdxEntity_Template: Type = 1; + pub const CXIdxEntity_TemplatePartialSpecialization: Type = 2; + pub const CXIdxEntity_TemplateSpecialization: Type = 3; +} +pub mod CXIdxAttrKind { + pub type Type = u32; + pub const CXIdxAttr_Unexposed: Type = 0; + pub const CXIdxAttr_IBAction: Type = 1; + pub const CXIdxAttr_IBOutlet: Type = 2; + pub const CXIdxAttr_IBOutletCollection: Type = 3; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxAttrInfo { + pub kind: CXIdxAttrKind::Type, + pub cursor: CXCursor, + pub loc: CXIdxLoc, +} +#[test] +fn bindgen_test_layout_CXIdxAttrInfo() { + assert_eq!( + ::std::mem::size_of::(), + 64usize, + concat!("Size of: ", stringify!(CXIdxAttrInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxAttrInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).kind as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxAttrInfo), + "::", + stringify!(kind) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).cursor as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxAttrInfo), + "::", + stringify!(cursor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).loc as *const _ as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(CXIdxAttrInfo), + "::", + stringify!(loc) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxEntityInfo { + pub kind: CXIdxEntityKind::Type, + pub templateKind: CXIdxEntityCXXTemplateKind::Type, + pub lang: CXIdxEntityLanguage::Type, + pub name: *const ::std::os::raw::c_char, + pub USR: *const ::std::os::raw::c_char, + pub cursor: CXCursor, + pub attributes: *const *const CXIdxAttrInfo, + pub numAttributes: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_CXIdxEntityInfo() { + assert_eq!( + ::std::mem::size_of::(), + 80usize, + concat!("Size of: ", stringify!(CXIdxEntityInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxEntityInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).kind as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityInfo), + "::", + stringify!(kind) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).templateKind as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityInfo), + "::", + stringify!(templateKind) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).lang as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityInfo), + "::", + stringify!(lang) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).name as *const _ + as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityInfo), + "::", + stringify!(name) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).USR as *const _ as usize + }, + 24usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityInfo), + "::", + stringify!(USR) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).cursor as *const _ + as usize + }, + 32usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityInfo), + "::", + stringify!(cursor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).attributes as *const _ + as usize + }, + 64usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityInfo), + "::", + stringify!(attributes) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).numAttributes + as *const _ as usize + }, + 72usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityInfo), + "::", + stringify!(numAttributes) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxContainerInfo { + pub cursor: CXCursor, +} +#[test] +fn bindgen_test_layout_CXIdxContainerInfo() { + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(CXIdxContainerInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxContainerInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).cursor as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxContainerInfo), + "::", + stringify!(cursor) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxIBOutletCollectionAttrInfo { + pub attrInfo: *const CXIdxAttrInfo, + pub objcClass: *const CXIdxEntityInfo, + pub classCursor: CXCursor, + pub classLoc: CXIdxLoc, +} +#[test] +fn bindgen_test_layout_CXIdxIBOutletCollectionAttrInfo() { + assert_eq!( + ::std::mem::size_of::(), + 72usize, + concat!("Size of: ", stringify!(CXIdxIBOutletCollectionAttrInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxIBOutletCollectionAttrInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).attrInfo + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxIBOutletCollectionAttrInfo), + "::", + stringify!(attrInfo) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())) + .objcClass as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxIBOutletCollectionAttrInfo), + "::", + stringify!(objcClass) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())) + .classCursor as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXIdxIBOutletCollectionAttrInfo), + "::", + stringify!(classCursor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).classLoc + as *const _ as usize + }, + 48usize, + concat!( + "Offset of field: ", + stringify!(CXIdxIBOutletCollectionAttrInfo), + "::", + stringify!(classLoc) + ) + ); +} +pub mod CXIdxDeclInfoFlags { + pub type Type = u32; + pub const CXIdxDeclFlag_Skipped: Type = 1; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxDeclInfo { + pub entityInfo: *const CXIdxEntityInfo, + pub cursor: CXCursor, + pub loc: CXIdxLoc, + pub semanticContainer: *const CXIdxContainerInfo, + pub lexicalContainer: *const CXIdxContainerInfo, + pub isRedeclaration: ::std::os::raw::c_int, + pub isDefinition: ::std::os::raw::c_int, + pub isContainer: ::std::os::raw::c_int, + pub declAsContainer: *const CXIdxContainerInfo, + pub isImplicit: ::std::os::raw::c_int, + pub attributes: *const *const CXIdxAttrInfo, + pub numAttributes: ::std::os::raw::c_uint, + pub flags: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_CXIdxDeclInfo() { + assert_eq!( + ::std::mem::size_of::(), + 128usize, + concat!("Size of: ", stringify!(CXIdxDeclInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxDeclInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).entityInfo as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(entityInfo) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).cursor as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(cursor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).loc as *const _ as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(loc) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).semanticContainer + as *const _ as usize + }, + 64usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(semanticContainer) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).lexicalContainer + as *const _ as usize + }, + 72usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(lexicalContainer) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).isRedeclaration + as *const _ as usize + }, + 80usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(isRedeclaration) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).isDefinition as *const _ + as usize + }, + 84usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(isDefinition) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).isContainer as *const _ + as usize + }, + 88usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(isContainer) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).declAsContainer + as *const _ as usize + }, + 96usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(declAsContainer) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).isImplicit as *const _ + as usize + }, + 104usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(isImplicit) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).attributes as *const _ + as usize + }, + 112usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(attributes) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).numAttributes as *const _ + as usize + }, + 120usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(numAttributes) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).flags as *const _ as usize + }, + 124usize, + concat!( + "Offset of field: ", + stringify!(CXIdxDeclInfo), + "::", + stringify!(flags) + ) + ); +} +pub mod CXIdxObjCContainerKind { + pub type Type = u32; + pub const CXIdxObjCContainer_ForwardRef: Type = 0; + pub const CXIdxObjCContainer_Interface: Type = 1; + pub const CXIdxObjCContainer_Implementation: Type = 2; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxObjCContainerDeclInfo { + pub declInfo: *const CXIdxDeclInfo, + pub kind: CXIdxObjCContainerKind::Type, +} +#[test] +fn bindgen_test_layout_CXIdxObjCContainerDeclInfo() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(CXIdxObjCContainerDeclInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxObjCContainerDeclInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).declInfo + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCContainerDeclInfo), + "::", + stringify!(declInfo) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).kind + as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCContainerDeclInfo), + "::", + stringify!(kind) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxBaseClassInfo { + pub base: *const CXIdxEntityInfo, + pub cursor: CXCursor, + pub loc: CXIdxLoc, +} +#[test] +fn bindgen_test_layout_CXIdxBaseClassInfo() { + assert_eq!( + ::std::mem::size_of::(), + 64usize, + concat!("Size of: ", stringify!(CXIdxBaseClassInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxBaseClassInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).base as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxBaseClassInfo), + "::", + stringify!(base) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).cursor as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxBaseClassInfo), + "::", + stringify!(cursor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).loc as *const _ + as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(CXIdxBaseClassInfo), + "::", + stringify!(loc) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxObjCProtocolRefInfo { + pub protocol: *const CXIdxEntityInfo, + pub cursor: CXCursor, + pub loc: CXIdxLoc, +} +#[test] +fn bindgen_test_layout_CXIdxObjCProtocolRefInfo() { + assert_eq!( + ::std::mem::size_of::(), + 64usize, + concat!("Size of: ", stringify!(CXIdxObjCProtocolRefInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxObjCProtocolRefInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).protocol + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCProtocolRefInfo), + "::", + stringify!(protocol) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).cursor + as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCProtocolRefInfo), + "::", + stringify!(cursor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).loc as *const _ + as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCProtocolRefInfo), + "::", + stringify!(loc) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxObjCProtocolRefListInfo { + pub protocols: *const *const CXIdxObjCProtocolRefInfo, + pub numProtocols: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_CXIdxObjCProtocolRefListInfo() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(CXIdxObjCProtocolRefListInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxObjCProtocolRefListInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).protocols + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCProtocolRefListInfo), + "::", + stringify!(protocols) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())) + .numProtocols as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCProtocolRefListInfo), + "::", + stringify!(numProtocols) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxObjCInterfaceDeclInfo { + pub containerInfo: *const CXIdxObjCContainerDeclInfo, + pub superInfo: *const CXIdxBaseClassInfo, + pub protocols: *const CXIdxObjCProtocolRefListInfo, +} +#[test] +fn bindgen_test_layout_CXIdxObjCInterfaceDeclInfo() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(CXIdxObjCInterfaceDeclInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxObjCInterfaceDeclInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).containerInfo + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCInterfaceDeclInfo), + "::", + stringify!(containerInfo) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).superInfo + as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCInterfaceDeclInfo), + "::", + stringify!(superInfo) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).protocols + as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCInterfaceDeclInfo), + "::", + stringify!(protocols) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxObjCCategoryDeclInfo { + pub containerInfo: *const CXIdxObjCContainerDeclInfo, + pub objcClass: *const CXIdxEntityInfo, + pub classCursor: CXCursor, + pub classLoc: CXIdxLoc, + pub protocols: *const CXIdxObjCProtocolRefListInfo, +} +#[test] +fn bindgen_test_layout_CXIdxObjCCategoryDeclInfo() { + assert_eq!( + ::std::mem::size_of::(), + 80usize, + concat!("Size of: ", stringify!(CXIdxObjCCategoryDeclInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxObjCCategoryDeclInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).containerInfo + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCCategoryDeclInfo), + "::", + stringify!(containerInfo) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).objcClass + as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCCategoryDeclInfo), + "::", + stringify!(objcClass) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).classCursor + as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCCategoryDeclInfo), + "::", + stringify!(classCursor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).classLoc + as *const _ as usize + }, + 48usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCCategoryDeclInfo), + "::", + stringify!(classLoc) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).protocols + as *const _ as usize + }, + 72usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCCategoryDeclInfo), + "::", + stringify!(protocols) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxObjCPropertyDeclInfo { + pub declInfo: *const CXIdxDeclInfo, + pub getter: *const CXIdxEntityInfo, + pub setter: *const CXIdxEntityInfo, +} +#[test] +fn bindgen_test_layout_CXIdxObjCPropertyDeclInfo() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(CXIdxObjCPropertyDeclInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxObjCPropertyDeclInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).declInfo + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCPropertyDeclInfo), + "::", + stringify!(declInfo) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).getter + as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCPropertyDeclInfo), + "::", + stringify!(getter) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).setter + as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXIdxObjCPropertyDeclInfo), + "::", + stringify!(setter) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxCXXClassDeclInfo { + pub declInfo: *const CXIdxDeclInfo, + pub bases: *const *const CXIdxBaseClassInfo, + pub numBases: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_CXIdxCXXClassDeclInfo() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(CXIdxCXXClassDeclInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxCXXClassDeclInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).declInfo + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxCXXClassDeclInfo), + "::", + stringify!(declInfo) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bases as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxCXXClassDeclInfo), + "::", + stringify!(bases) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).numBases + as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(CXIdxCXXClassDeclInfo), + "::", + stringify!(numBases) + ) + ); +} +pub mod CXIdxEntityRefKind { + pub type Type = u32; + pub const CXIdxEntityRef_Direct: Type = 1; + pub const CXIdxEntityRef_Implicit: Type = 2; +} +pub mod CXSymbolRole { + pub type Type = u32; + pub const CXSymbolRole_None: Type = 0; + pub const CXSymbolRole_Declaration: Type = 1; + pub const CXSymbolRole_Definition: Type = 2; + pub const CXSymbolRole_Reference: Type = 4; + pub const CXSymbolRole_Read: Type = 8; + pub const CXSymbolRole_Write: Type = 16; + pub const CXSymbolRole_Call: Type = 32; + pub const CXSymbolRole_Dynamic: Type = 64; + pub const CXSymbolRole_AddressOf: Type = 128; + pub const CXSymbolRole_Implicit: Type = 256; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXIdxEntityRefInfo { + pub kind: CXIdxEntityRefKind::Type, + pub cursor: CXCursor, + pub loc: CXIdxLoc, + pub referencedEntity: *const CXIdxEntityInfo, + pub parentEntity: *const CXIdxEntityInfo, + pub container: *const CXIdxContainerInfo, + pub role: CXSymbolRole::Type, +} +#[test] +fn bindgen_test_layout_CXIdxEntityRefInfo() { + assert_eq!( + ::std::mem::size_of::(), + 96usize, + concat!("Size of: ", stringify!(CXIdxEntityRefInfo)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXIdxEntityRefInfo)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).kind as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityRefInfo), + "::", + stringify!(kind) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).cursor as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityRefInfo), + "::", + stringify!(cursor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).loc as *const _ + as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityRefInfo), + "::", + stringify!(loc) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).referencedEntity + as *const _ as usize + }, + 64usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityRefInfo), + "::", + stringify!(referencedEntity) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).parentEntity + as *const _ as usize + }, + 72usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityRefInfo), + "::", + stringify!(parentEntity) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).container as *const _ + as usize + }, + 80usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityRefInfo), + "::", + stringify!(container) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).role as *const _ + as usize + }, + 88usize, + concat!( + "Offset of field: ", + stringify!(CXIdxEntityRefInfo), + "::", + stringify!(role) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct IndexerCallbacks { + pub abortQuery: ::std::option::Option< + unsafe extern "C" fn( + client_data: CXClientData, + reserved: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, + >, + pub diagnostic: ::std::option::Option< + unsafe extern "C" fn( + client_data: CXClientData, + arg1: CXDiagnosticSet, + reserved: *mut ::std::os::raw::c_void, + ), + >, + pub enteredMainFile: ::std::option::Option< + unsafe extern "C" fn( + client_data: CXClientData, + mainFile: CXFile, + reserved: *mut ::std::os::raw::c_void, + ) -> CXIdxClientFile, + >, + pub ppIncludedFile: ::std::option::Option< + unsafe extern "C" fn( + client_data: CXClientData, + arg1: *const CXIdxIncludedFileInfo, + ) -> CXIdxClientFile, + >, + pub importedASTFile: ::std::option::Option< + unsafe extern "C" fn( + client_data: CXClientData, + arg1: *const CXIdxImportedASTFileInfo, + ) -> CXIdxClientASTFile, + >, + pub startedTranslationUnit: ::std::option::Option< + unsafe extern "C" fn( + client_data: CXClientData, + reserved: *mut ::std::os::raw::c_void, + ) -> CXIdxClientContainer, + >, + pub indexDeclaration: ::std::option::Option< + unsafe extern "C" fn( + client_data: CXClientData, + arg1: *const CXIdxDeclInfo, + ), + >, + pub indexEntityReference: ::std::option::Option< + unsafe extern "C" fn( + client_data: CXClientData, + arg1: *const CXIdxEntityRefInfo, + ), + >, +} +#[test] +fn bindgen_test_layout_IndexerCallbacks() { + assert_eq!( + ::std::mem::size_of::(), + 64usize, + concat!("Size of: ", stringify!(IndexerCallbacks)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(IndexerCallbacks)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).abortQuery as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(IndexerCallbacks), + "::", + stringify!(abortQuery) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).diagnostic as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(IndexerCallbacks), + "::", + stringify!(diagnostic) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).enteredMainFile + as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(IndexerCallbacks), + "::", + stringify!(enteredMainFile) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ppIncludedFile + as *const _ as usize + }, + 24usize, + concat!( + "Offset of field: ", + stringify!(IndexerCallbacks), + "::", + stringify!(ppIncludedFile) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).importedASTFile + as *const _ as usize + }, + 32usize, + concat!( + "Offset of field: ", + stringify!(IndexerCallbacks), + "::", + stringify!(importedASTFile) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).startedTranslationUnit + as *const _ as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(IndexerCallbacks), + "::", + stringify!(startedTranslationUnit) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).indexDeclaration + as *const _ as usize + }, + 48usize, + concat!( + "Offset of field: ", + stringify!(IndexerCallbacks), + "::", + stringify!(indexDeclaration) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).indexEntityReference + as *const _ as usize + }, + 56usize, + concat!( + "Offset of field: ", + stringify!(IndexerCallbacks), + "::", + stringify!(indexEntityReference) + ) + ); +} +extern "C" { + pub fn clang_index_isEntityObjCContainerKind( + arg1: CXIdxEntityKind::Type, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_index_getObjCContainerDeclInfo( + arg1: *const CXIdxDeclInfo, + ) -> *const CXIdxObjCContainerDeclInfo; +} +extern "C" { + pub fn clang_index_getObjCInterfaceDeclInfo( + arg1: *const CXIdxDeclInfo, + ) -> *const CXIdxObjCInterfaceDeclInfo; +} +extern "C" { + pub fn clang_index_getObjCCategoryDeclInfo( + arg1: *const CXIdxDeclInfo, + ) -> *const CXIdxObjCCategoryDeclInfo; +} +extern "C" { + pub fn clang_index_getObjCProtocolRefListInfo( + arg1: *const CXIdxDeclInfo, + ) -> *const CXIdxObjCProtocolRefListInfo; +} +extern "C" { + pub fn clang_index_getObjCPropertyDeclInfo( + arg1: *const CXIdxDeclInfo, + ) -> *const CXIdxObjCPropertyDeclInfo; +} +extern "C" { + pub fn clang_index_getIBOutletCollectionAttrInfo( + arg1: *const CXIdxAttrInfo, + ) -> *const CXIdxIBOutletCollectionAttrInfo; +} +extern "C" { + pub fn clang_index_getCXXClassDeclInfo( + arg1: *const CXIdxDeclInfo, + ) -> *const CXIdxCXXClassDeclInfo; +} +extern "C" { + pub fn clang_index_getClientContainer( + arg1: *const CXIdxContainerInfo, + ) -> CXIdxClientContainer; +} +extern "C" { + pub fn clang_index_setClientContainer( + arg1: *const CXIdxContainerInfo, + arg2: CXIdxClientContainer, + ); +} +extern "C" { + pub fn clang_index_getClientEntity( + arg1: *const CXIdxEntityInfo, + ) -> CXIdxClientEntity; +} +extern "C" { + pub fn clang_index_setClientEntity( + arg1: *const CXIdxEntityInfo, + arg2: CXIdxClientEntity, + ); +} +pub type CXIndexAction = *mut ::std::os::raw::c_void; +extern "C" { + pub fn clang_IndexAction_create(CIdx: CXIndex) -> CXIndexAction; +} +extern "C" { + pub fn clang_IndexAction_dispose(arg1: CXIndexAction); +} +pub mod CXIndexOptFlags { + pub type Type = u32; + pub const CXIndexOpt_None: Type = 0; + pub const CXIndexOpt_SuppressRedundantRefs: Type = 1; + pub const CXIndexOpt_IndexFunctionLocalSymbols: Type = 2; + pub const CXIndexOpt_IndexImplicitTemplateInstantiations: Type = 4; + pub const CXIndexOpt_SuppressWarnings: Type = 8; + pub const CXIndexOpt_SkipParsedBodiesInSession: Type = 16; +} +extern "C" { + pub fn clang_indexSourceFile( + arg1: CXIndexAction, + client_data: CXClientData, + index_callbacks: *mut IndexerCallbacks, + index_callbacks_size: ::std::os::raw::c_uint, + index_options: ::std::os::raw::c_uint, + source_filename: *const ::std::os::raw::c_char, + command_line_args: *const *const ::std::os::raw::c_char, + num_command_line_args: ::std::os::raw::c_int, + unsaved_files: *mut CXUnsavedFile, + num_unsaved_files: ::std::os::raw::c_uint, + out_TU: *mut CXTranslationUnit, + TU_options: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_indexSourceFileFullArgv( + arg1: CXIndexAction, + client_data: CXClientData, + index_callbacks: *mut IndexerCallbacks, + index_callbacks_size: ::std::os::raw::c_uint, + index_options: ::std::os::raw::c_uint, + source_filename: *const ::std::os::raw::c_char, + command_line_args: *const *const ::std::os::raw::c_char, + num_command_line_args: ::std::os::raw::c_int, + unsaved_files: *mut CXUnsavedFile, + num_unsaved_files: ::std::os::raw::c_uint, + out_TU: *mut CXTranslationUnit, + TU_options: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_indexTranslationUnit( + arg1: CXIndexAction, + client_data: CXClientData, + index_callbacks: *mut IndexerCallbacks, + index_callbacks_size: ::std::os::raw::c_uint, + index_options: ::std::os::raw::c_uint, + arg2: CXTranslationUnit, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clang_indexLoc_getFileLocation( + loc: CXIdxLoc, + indexFile: *mut CXIdxClientFile, + file: *mut CXFile, + line: *mut ::std::os::raw::c_uint, + column: *mut ::std::os::raw::c_uint, + offset: *mut ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn clang_indexLoc_getCXSourceLocation( + loc: CXIdxLoc, + ) -> CXSourceLocation; +} +pub type CXFieldVisitor = ::std::option::Option< + unsafe extern "C" fn( + C: CXCursor, + client_data: CXClientData, + ) -> CXVisitorResult::Type, +>; +extern "C" { + pub fn clang_Type_visitFields( + T: CXType, + visitor: CXFieldVisitor, + client_data: CXClientData, + ) -> ::std::os::raw::c_uint; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CXComment { + pub ASTNode: *const ::std::os::raw::c_void, + pub TranslationUnit: CXTranslationUnit, +} +#[test] +fn bindgen_test_layout_CXComment() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(CXComment)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(CXComment)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ASTNode as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(CXComment), + "::", + stringify!(ASTNode) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).TranslationUnit as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(CXComment), + "::", + stringify!(TranslationUnit) + ) + ); +} +extern "C" { + pub fn clang_Cursor_getParsedComment(C: CXCursor) -> CXComment; +} +pub mod CXCommentKind { + pub type Type = u32; + pub const CXComment_Null: Type = 0; + pub const CXComment_Text: Type = 1; + pub const CXComment_InlineCommand: Type = 2; + pub const CXComment_HTMLStartTag: Type = 3; + pub const CXComment_HTMLEndTag: Type = 4; + pub const CXComment_Paragraph: Type = 5; + pub const CXComment_BlockCommand: Type = 6; + pub const CXComment_ParamCommand: Type = 7; + pub const CXComment_TParamCommand: Type = 8; + pub const CXComment_VerbatimBlockCommand: Type = 9; + pub const CXComment_VerbatimBlockLine: Type = 10; + pub const CXComment_VerbatimLine: Type = 11; + pub const CXComment_FullComment: Type = 12; +} +pub mod CXCommentInlineCommandRenderKind { + pub type Type = u32; + pub const CXCommentInlineCommandRenderKind_Normal: Type = 0; + pub const CXCommentInlineCommandRenderKind_Bold: Type = 1; + pub const CXCommentInlineCommandRenderKind_Monospaced: Type = 2; + pub const CXCommentInlineCommandRenderKind_Emphasized: Type = 3; +} +pub mod CXCommentParamPassDirection { + pub type Type = u32; + pub const CXCommentParamPassDirection_In: Type = 0; + pub const CXCommentParamPassDirection_Out: Type = 1; + pub const CXCommentParamPassDirection_InOut: Type = 2; +} +extern "C" { + pub fn clang_Comment_getKind(Comment: CXComment) -> CXCommentKind::Type; +} +extern "C" { + pub fn clang_Comment_getNumChildren( + Comment: CXComment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_Comment_getChild( + Comment: CXComment, + ChildIdx: ::std::os::raw::c_uint, + ) -> CXComment; +} +extern "C" { + pub fn clang_Comment_isWhitespace( + Comment: CXComment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_InlineContentComment_hasTrailingNewline( + Comment: CXComment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_TextComment_getText(Comment: CXComment) -> CXString; +} +extern "C" { + pub fn clang_InlineCommandComment_getCommandName( + Comment: CXComment, + ) -> CXString; +} +extern "C" { + pub fn clang_InlineCommandComment_getRenderKind( + Comment: CXComment, + ) -> CXCommentInlineCommandRenderKind::Type; +} +extern "C" { + pub fn clang_InlineCommandComment_getNumArgs( + Comment: CXComment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_InlineCommandComment_getArgText( + Comment: CXComment, + ArgIdx: ::std::os::raw::c_uint, + ) -> CXString; +} +extern "C" { + pub fn clang_HTMLTagComment_getTagName(Comment: CXComment) -> CXString; +} +extern "C" { + pub fn clang_HTMLStartTagComment_isSelfClosing( + Comment: CXComment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_HTMLStartTag_getNumAttrs( + Comment: CXComment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_HTMLStartTag_getAttrName( + Comment: CXComment, + AttrIdx: ::std::os::raw::c_uint, + ) -> CXString; +} +extern "C" { + pub fn clang_HTMLStartTag_getAttrValue( + Comment: CXComment, + AttrIdx: ::std::os::raw::c_uint, + ) -> CXString; +} +extern "C" { + pub fn clang_BlockCommandComment_getCommandName( + Comment: CXComment, + ) -> CXString; +} +extern "C" { + pub fn clang_BlockCommandComment_getNumArgs( + Comment: CXComment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_BlockCommandComment_getArgText( + Comment: CXComment, + ArgIdx: ::std::os::raw::c_uint, + ) -> CXString; +} +extern "C" { + pub fn clang_BlockCommandComment_getParagraph( + Comment: CXComment, + ) -> CXComment; +} +extern "C" { + pub fn clang_ParamCommandComment_getParamName( + Comment: CXComment, + ) -> CXString; +} +extern "C" { + pub fn clang_ParamCommandComment_isParamIndexValid( + Comment: CXComment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_ParamCommandComment_getParamIndex( + Comment: CXComment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_ParamCommandComment_isDirectionExplicit( + Comment: CXComment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_ParamCommandComment_getDirection( + Comment: CXComment, + ) -> CXCommentParamPassDirection::Type; +} +extern "C" { + pub fn clang_TParamCommandComment_getParamName( + Comment: CXComment, + ) -> CXString; +} +extern "C" { + pub fn clang_TParamCommandComment_isParamPositionValid( + Comment: CXComment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_TParamCommandComment_getDepth( + Comment: CXComment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_TParamCommandComment_getIndex( + Comment: CXComment, + Depth: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn clang_VerbatimBlockLineComment_getText( + Comment: CXComment, + ) -> CXString; +} +extern "C" { + pub fn clang_VerbatimLineComment_getText(Comment: CXComment) -> CXString; +} +extern "C" { + pub fn clang_HTMLTagComment_getAsString(Comment: CXComment) -> CXString; +} +extern "C" { + pub fn clang_FullComment_getAsHTML(Comment: CXComment) -> CXString; +} +extern "C" { + pub fn clang_FullComment_getAsXML(Comment: CXComment) -> CXString; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_ASTUnit { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_TargetInfo { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_CompoundStmt { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_Decl { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_Diagnostic { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_StoredDiagnostic { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_TranslationUnitDecl { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_Expr { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_Type { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_FileEntry { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_SourceLocation { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_CXXBaseSpecifier { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_ASTContext { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_SourceRange { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_comments_Comment { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_comments_FullComment { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct clang_QualType { + pub ptr: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout_clang_QualType() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(clang_QualType)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(clang_QualType)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ptr as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(clang_QualType), + "::", + stringify!(ptr) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct EvalResult { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct BindgenStringRef { + pub s: *mut ::std::os::raw::c_char, + pub len: size_t, +} +#[test] +fn bindgen_test_layout_BindgenStringRef() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(BindgenStringRef)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(BindgenStringRef)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).s as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(BindgenStringRef), + "::", + stringify!(s) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).len as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(BindgenStringRef), + "::", + stringify!(len) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct BindgenStringRefSet { + pub strings: *mut BindgenStringRef, + pub len: size_t, +} +#[test] +fn bindgen_test_layout_BindgenStringRefSet() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(BindgenStringRefSet)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(BindgenStringRefSet)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).strings as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(BindgenStringRefSet), + "::", + stringify!(strings) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).len as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(BindgenStringRefSet), + "::", + stringify!(len) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct BindgenSourceRange { + pub B: *mut clang_SourceLocation, + pub E: *mut clang_SourceLocation, +} +#[test] +fn bindgen_test_layout_BindgenSourceRange() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(BindgenSourceRange)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(BindgenSourceRange)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).B as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(BindgenSourceRange), + "::", + stringify!(B) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).E as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(BindgenSourceRange), + "::", + stringify!(E) + ) + ); +} +extern "C" { + #[link_name = "\u{1}_ZN18BindgenSourceRangeC1ERKN5clang11SourceRangeE"] + pub fn BindgenSourceRange_BindgenSourceRange( + this: *mut BindgenSourceRange, + range: *const clang_SourceRange, + ); +} +impl BindgenSourceRange { + #[inline] + pub unsafe fn new(range: *const clang_SourceRange) -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + BindgenSourceRange_BindgenSourceRange( + __bindgen_tmp.as_mut_ptr(), + range, + ); + __bindgen_tmp.assume_init() + } +} +extern "C" { + #[link_name = "\u{1}_Z10freeString16BindgenStringRef"] + pub fn freeString(s: BindgenStringRef); +} +extern "C" { + #[link_name = "\u{1}_Z7cString16BindgenStringRef"] + pub fn cString(s: BindgenStringRef) -> *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_Z18ASTUnit_getContextPN5clang7ASTUnitE"] + pub fn ASTUnit_getContext( + arg1: *mut clang_ASTUnit, + ) -> *mut clang_ASTContext; +} +extern "C" { + #[link_name = "\u{1}_Z20parseTranslationUnitPKcPKS0_ii"] + pub fn parseTranslationUnit( + source_filename: *const ::std::os::raw::c_char, + command_line_args: *const *const ::std::os::raw::c_char, + num_command_line_args: ::std::os::raw::c_int, + options: ::std::os::raw::c_int, + ) -> *mut clang_ASTUnit; +} +extern "C" { + #[link_name = "\u{1}_Z14disposeASTUnitPN5clang7ASTUnitE"] + pub fn disposeASTUnit(AU: *mut clang_ASTUnit); +} +extern "C" { + #[link_name = "\u{1}_Z25ASTUnit_getNumDiagnosticsPKN5clang7ASTUnitE"] + pub fn ASTUnit_getNumDiagnostics( + AU: *const clang_ASTUnit, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + #[link_name = "\u{1}_Z21ASTUnit_getDiagnosticPKN5clang7ASTUnitEj"] + pub fn ASTUnit_getDiagnostic( + AU: *const clang_ASTUnit, + i: ::std::os::raw::c_uint, + ) -> *const clang_StoredDiagnostic; +} +extern "C" { + #[link_name = "\u{1}_Z21ASTUnit_getTargetInfoPN5clang7ASTUnitE"] + pub fn ASTUnit_getTargetInfo( + AU: *mut clang_ASTUnit, + ) -> *const clang_TargetInfo; +} +extern "C" { + #[link_name = "\u{1}_Z26TargetInfo_getPointerWidthPKN5clang10TargetInfoE"] + pub fn TargetInfo_getPointerWidth( + TI: *const clang_TargetInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_Z20TargetInfo_getTriplePKN5clang10TargetInfoE"] + pub fn TargetInfo_getTriple( + TI: *const clang_TargetInfo, + ) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z13Expr_EvaluatePKN5clang4ExprEPNS_10ASTContextE"] + pub fn Expr_Evaluate( + E: *const clang_Expr, + Ctx: *mut clang_ASTContext, + ) -> *mut EvalResult; +} +extern "C" { + #[link_name = "\u{1}_Z13Decl_EvaluatePKN5clang4DeclEPNS_10ASTContextE"] + pub fn Decl_Evaluate( + D: *const clang_Decl, + Ctx: *mut clang_ASTContext, + ) -> *mut EvalResult; +} +extern "C" { + #[link_name = "\u{1}_Z18EvalResult_getKindP10EvalResult"] + pub fn EvalResult_getKind(arg1: *mut EvalResult) -> CXEvalResultKind::Type; +} +extern "C" { + #[link_name = "\u{1}_Z22EvalResult_getAsDoubleP10EvalResult"] + pub fn EvalResult_getAsDouble(arg1: *mut EvalResult) -> f64; +} +extern "C" { + #[link_name = "\u{1}_Z24EvalResult_isUnsignedIntP10EvalResult"] + pub fn EvalResult_isUnsignedInt(arg1: *mut EvalResult) -> bool; +} +extern "C" { + #[link_name = "\u{1}_Z24EvalResult_getAsUnsignedP10EvalResult"] + pub fn EvalResult_getAsUnsigned( + arg1: *mut EvalResult, + ) -> ::std::os::raw::c_ulonglong; +} +extern "C" { + #[link_name = "\u{1}_Z24EvalResult_getAsLongLongP10EvalResult"] + pub fn EvalResult_getAsLongLong( + arg1: *mut EvalResult, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + #[link_name = "\u{1}_Z19EvalResult_getAsStrP10EvalResult"] + pub fn EvalResult_getAsStr(arg1: *mut EvalResult) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z17Diagnostic_formatPKN5clang16StoredDiagnosticE"] + pub fn Diagnostic_format( + arg1: *const clang_StoredDiagnostic, + ) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z22Diagnostic_getSeverityPKN5clang16StoredDiagnosticE"] + pub fn Diagnostic_getSeverity( + arg1: *const clang_StoredDiagnostic, + ) -> CXDiagnosticSeverity::Type; +} +extern "C" { + #[link_name = "\u{1}_Z22getTranslationUnitDeclPN5clang7ASTUnitE"] + pub fn getTranslationUnitDecl( + arg1: *mut clang_ASTUnit, + ) -> *const clang_Decl; +} +extern "C" { + #[link_name = "\u{1}_Z20CursorKind_isInvalid12CXCursorKind"] + pub fn CursorKind_isInvalid(kind: CXCursorKind::Type) -> bool; +} +extern "C" { + #[link_name = "\u{1}_Z21Decl_getLexicalParentPKN5clang4DeclE"] + pub fn Decl_getLexicalParent(D: *const clang_Decl) -> *const clang_Decl; +} +extern "C" { + #[link_name = "\u{1}_Z22Decl_getSemanticParentPKN5clang4DeclE"] + pub fn Decl_getSemanticParent(D: *const clang_Decl) -> *const clang_Decl; +} +extern "C" { + #[link_name = "\u{1}_Z18Decl_getDefinitionPKN5clang4DeclE"] + pub fn Decl_getDefinition(D: *const clang_Decl) -> *const clang_Decl; +} +extern "C" { + #[link_name = "\u{1}_Z18Decl_getReferencedPKN5clang4DeclE"] + pub fn Decl_getReferenced(D: *const clang_Decl) -> *const clang_Decl; +} +extern "C" { + #[link_name = "\u{1}_Z17Decl_getCanonicalPKN5clang4DeclE"] + pub fn Decl_getCanonical(D: *const clang_Decl) -> *const clang_Decl; +} +extern "C" { + #[link_name = "\u{1}_Z27Decl_getSpecializedTemplatePKN5clang4DeclE"] + pub fn Decl_getSpecializedTemplate( + D: *const clang_Decl, + ) -> *const clang_Decl; +} +extern "C" { + #[link_name = "\u{1}_Z26Decl_getTemplateCursorKindPKN5clang4DeclE"] + pub fn Decl_getTemplateCursorKind( + D: *const clang_Decl, + ) -> CXCursorKind::Type; +} +extern "C" { + #[link_name = "\u{1}_Z16Decl_getArgumentPKN5clang4DeclEj"] + pub fn Decl_getArgument( + D: *const clang_Decl, + i: ::std::os::raw::c_uint, + ) -> *const clang_Decl; +} +extern "C" { + #[link_name = "\u{1}_Z20Decl_getNumArgumentsPKN5clang4DeclE"] + pub fn Decl_getNumArguments(D: *const clang_Decl) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_Z11Decl_getUSRPKN5clang4DeclE"] + pub fn Decl_getUSR(D: *const clang_Decl) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z16Decl_getSpellingPKN5clang4DeclE"] + pub fn Decl_getSpelling(D: *const clang_Decl) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z19Decl_getDisplayNamePKN5clang4DeclE"] + pub fn Decl_getDisplayName(D: *const clang_Decl) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z16Decl_getManglingPKN5clang4DeclEPNS_10ASTContextE"] + pub fn Decl_getMangling( + D: *const clang_Decl, + arg1: *mut clang_ASTContext, + ) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z20Decl_getCXXManglingsPKN5clang4DeclEPNS_10ASTContextE"] + pub fn Decl_getCXXManglings( + D: *const clang_Decl, + arg1: *mut clang_ASTContext, + ) -> BindgenStringRefSet; +} +extern "C" { + #[link_name = "\u{1}_Z28Decl_getNumTemplateArgumentsPKN5clang4DeclE"] + pub fn Decl_getNumTemplateArguments( + D: *const clang_Decl, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_Z20Decl_getCXCursorKindPKN5clang4DeclE"] + pub fn Decl_getCXCursorKind(D: *const clang_Decl) -> CXCursorKind::Type; +} +extern "C" { + #[link_name = "\u{1}_Z17Decl_isDefinitionPKN5clang4DeclE"] + pub fn Decl_isDefinition(D: *const clang_Decl) -> bool; +} +extern "C" { + #[link_name = "\u{1}_Z16Decl_getLocationPKN5clang4DeclE"] + pub fn Decl_getLocation(D: *const clang_Decl) -> *mut clang_SourceLocation; +} +extern "C" { + #[link_name = "\u{1}_Z22Decl_getRawCommentTextPKN5clang4DeclEPNS_10ASTContextE"] + pub fn Decl_getRawCommentText( + D: *const clang_Decl, + arg1: *mut clang_ASTContext, + ) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z21Decl_getParsedCommentPKN5clang4DeclEPNS_10ASTContextE"] + pub fn Decl_getParsedComment( + D: *const clang_Decl, + arg1: *mut clang_ASTContext, + ) -> *mut clang_comments_Comment; +} +extern "C" { + #[link_name = "\u{1}_Z12Decl_getTypePKN5clang4DeclEPNS_10ASTContextE"] + pub fn Decl_getType( + D: *const clang_Decl, + arg1: *mut clang_ASTContext, + ) -> clang_QualType; +} +extern "C" { + #[link_name = "\u{1}_Z22Decl_isFunctionInlinedPKN5clang4DeclE"] + pub fn Decl_isFunctionInlined(D: *const clang_Decl) -> bool; +} +extern "C" { + #[link_name = "\u{1}_Z25Decl_getFieldDeclBitWidthPKN5clang4DeclEPNS_10ASTContextE"] + pub fn Decl_getFieldDeclBitWidth( + D: *const clang_Decl, + arg1: *mut clang_ASTContext, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_Z27Decl_getEnumDeclIntegerTypePKN5clang4DeclE"] + pub fn Decl_getEnumDeclIntegerType(D: *const clang_Decl) -> clang_QualType; +} +extern "C" { + #[link_name = "\u{1}_Z25Decl_getEnumConstantValuePKN5clang4DeclE"] + pub fn Decl_getEnumConstantValue(D: *const clang_Decl) -> i64; +} +extern "C" { + #[link_name = "\u{1}_Z33Decl_getEnumConstantUnsignedValuePKN5clang4DeclE"] + pub fn Decl_getEnumConstantUnsignedValue(D: *const clang_Decl) -> u64; +} +extern "C" { + #[link_name = "\u{1}_Z21Decl_getOffsetOfFieldPKN5clang4DeclEPNS_10ASTContextE"] + pub fn Decl_getOffsetOfField( + D: *const clang_Decl, + arg1: *mut clang_ASTContext, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + #[link_name = "\u{1}_Z19Decl_getSourceRangePKN5clang4DeclE"] + pub fn Decl_getSourceRange(D: *const clang_Decl) -> BindgenSourceRange; +} +extern "C" { + #[link_name = "\u{1}_Z33Decl_getTypedefDeclUnderlyingTypePKN5clang4DeclE"] + pub fn Decl_getTypedefDeclUnderlyingType( + D: *const clang_Decl, + ) -> clang_QualType; +} +extern "C" { + #[link_name = "\u{1}_Z15Decl_getLinkagePKN5clang4DeclE"] + pub fn Decl_getLinkage(D: *const clang_Decl) -> CXLinkageKind::Type; +} +extern "C" { + #[link_name = "\u{1}_Z18Decl_getVisibilityPKN5clang4DeclE"] + pub fn Decl_getVisibility(D: *const clang_Decl) -> CXVisibilityKind::Type; +} +extern "C" { + #[link_name = "\u{1}_Z14Decl_getAccessPKN5clang4DeclE"] + pub fn Decl_getAccess(D: *const clang_Decl) -> CX_CXXAccessSpecifier::Type; +} +extern "C" { + #[link_name = "\u{1}_Z18CXXField_isMutablePKN5clang4DeclE"] + pub fn CXXField_isMutable(D: *const clang_Decl) -> bool; +} +extern "C" { + #[link_name = "\u{1}_Z18CXXMethod_isStaticPKN5clang4DeclE"] + pub fn CXXMethod_isStatic(D: *const clang_Decl) -> bool; +} +extern "C" { + #[link_name = "\u{1}_Z17CXXMethod_isConstPKN5clang4DeclE"] + pub fn CXXMethod_isConst(D: *const clang_Decl) -> bool; +} +extern "C" { + #[link_name = "\u{1}_Z19CXXMethod_isVirtualPKN5clang4DeclE"] + pub fn CXXMethod_isVirtual(D: *const clang_Decl) -> bool; +} +extern "C" { + #[link_name = "\u{1}_Z23CXXMethod_isPureVirtualPKN5clang4DeclE"] + pub fn CXXMethod_isPureVirtual(D: *const clang_Decl) -> bool; +} +extern "C" { + #[link_name = "\u{1}_Z18Decl_getResultTypePKN5clang4DeclEPNS_10ASTContextE"] + pub fn Decl_getResultType( + D: *const clang_Decl, + arg1: *mut clang_ASTContext, + ) -> clang_QualType; +} +extern "C" { + #[link_name = "\u{1}_Z16Expr_getArgumentPKN5clang4ExprEj"] + pub fn Expr_getArgument( + E: *const clang_Expr, + i: ::std::os::raw::c_uint, + ) -> *const clang_Expr; +} +extern "C" { + #[link_name = "\u{1}_Z20Expr_getNumArgumentsPKN5clang4ExprE"] + pub fn Expr_getNumArguments(E: *const clang_Expr) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_Z11Expr_getUSRPKN5clang4ExprE"] + pub fn Expr_getUSR(E: *const clang_Expr) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z16Expr_getSpellingPKN5clang4ExprE"] + pub fn Expr_getSpelling(E: *const clang_Expr) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z19Expr_getDisplayNamePKN5clang4ExprE"] + pub fn Expr_getDisplayName(E: *const clang_Expr) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z16Expr_getManglingPKN5clang4ExprE"] + pub fn Expr_getMangling(E: *const clang_Expr) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z20Expr_getCXXManglingsPKN5clang4ExprE"] + pub fn Expr_getCXXManglings(E: *const clang_Expr) -> BindgenStringRefSet; +} +extern "C" { + #[link_name = "\u{1}_Z20Expr_getCXCursorKindPKN5clang4ExprE"] + pub fn Expr_getCXCursorKind(E: *const clang_Expr) -> CXCursorKind::Type; +} +extern "C" { + #[link_name = "\u{1}_Z16Expr_getLocationPKN5clang4ExprE"] + pub fn Expr_getLocation(E: *const clang_Expr) -> *mut clang_SourceLocation; +} +extern "C" { + #[link_name = "\u{1}_Z22Expr_getRawCommentTextPKN5clang4ExprE"] + pub fn Expr_getRawCommentText(E: *const clang_Expr) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z21Expr_getParsedCommentPKN5clang4ExprE"] + pub fn Expr_getParsedComment( + E: *const clang_Expr, + ) -> *mut clang_comments_FullComment; +} +extern "C" { + #[link_name = "\u{1}_Z12Expr_getTypePKN5clang4ExprE"] + pub fn Expr_getType(E: *const clang_Expr) -> clang_QualType; +} +extern "C" { + #[link_name = "\u{1}_Z19Expr_getSourceRangePKN5clang4ExprE"] + pub fn Expr_getSourceRange(E: *const clang_Expr) -> BindgenSourceRange; +} +extern "C" { + #[link_name = "\u{1}_Z19Type_getDeclarationN5clang8QualTypeE"] + pub fn Type_getDeclaration(arg1: clang_QualType) -> *const clang_Decl; +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Node { + pub kind: CXCursorKind::Type, + pub ptr: Node__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union Node__bindgen_ty_1 { + pub decl: *const clang_Decl, + pub expr: *const clang_Expr, + pub type_: *mut clang_Type, + _bindgen_union_align: u64, +} +#[test] +fn bindgen_test_layout_Node__bindgen_ty_1() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(Node__bindgen_ty_1)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(Node__bindgen_ty_1)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).decl as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(Node__bindgen_ty_1), + "::", + stringify!(decl) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).expr as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(Node__bindgen_ty_1), + "::", + stringify!(expr) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).type_ as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(Node__bindgen_ty_1), + "::", + stringify!(type_) + ) + ); +} +#[test] +fn bindgen_test_layout_Node() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(Node)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(Node)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).kind as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(Node), + "::", + stringify!(kind) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ptr as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(Node), "::", stringify!(ptr)) + ); +} +pub type Visitor = ::std::option::Option< + unsafe extern "C" fn( + N: Node, + parent: Node, + unit: *mut clang_ASTUnit, + client_data: CXClientData, + ) -> CXChildVisitResult::Type, +>; +extern "C" { + #[link_name = "\u{1}_Z18Decl_visitChildrenPKN5clang4DeclEPF18CXChildVisitResult4NodeS4_PNS_7ASTUnitEPvES6_S7_"] + pub fn Decl_visitChildren( + Parent: *const clang_Decl, + V: Visitor, + Unit: *mut clang_ASTUnit, + data: CXClientData, + ); +} +extern "C" { + #[link_name = "\u{1}_Z18Expr_visitChildrenPKN5clang4ExprEPF18CXChildVisitResult4NodeS4_PNS_7ASTUnitEPvES6_S7_"] + pub fn Expr_visitChildren( + Parent: *const clang_Expr, + V: Visitor, + Unit: *mut clang_ASTUnit, + data: CXClientData, + ); +} +extern "C" { + #[link_name = "\u{1}_Z8tokenizePN5clang7ASTUnitE18BindgenSourceRangePP7CXTokenPj"] + pub fn tokenize( + TU: *mut clang_ASTUnit, + Range: BindgenSourceRange, + Tokens: *mut *mut CXToken, + NumTokens: *mut ::std::os::raw::c_uint, + ); +} +extern "C" { + #[link_name = "\u{1}_Z13disposeTokensPKN5clang7ASTUnitEP7CXTokenj"] + pub fn disposeTokens( + TU: *const clang_ASTUnit, + Tokens: *mut CXToken, + NumTokens: ::std::os::raw::c_uint, + ); +} +extern "C" { + #[link_name = "\u{1}_Z12getTokenKind7CXToken"] + pub fn getTokenKind(token: CXToken) -> CXTokenKind::Type; +} +extern "C" { + #[link_name = "\u{1}_Z16getTokenSpellingPN5clang7ASTUnitE7CXToken"] + pub fn getTokenSpelling( + TU: *mut clang_ASTUnit, + token: CXToken, + ) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z9Type_kindN5clang8QualTypeE"] + pub fn Type_kind(arg1: clang_QualType) -> CXTypeKind::Type; +} +extern "C" { + #[link_name = "\u{1}_Z20Type_getTypeSpellingN5clang8QualTypeEPNS_10ASTContextE"] + pub fn Type_getTypeSpelling( + arg1: clang_QualType, + arg2: *mut clang_ASTContext, + ) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z25Type_isConstQualifiedTypeN5clang8QualTypeE"] + pub fn Type_isConstQualifiedType(arg1: clang_QualType) -> bool; +} +extern "C" { + #[link_name = "\u{1}_Z14Type_getSizeOfN5clang8QualTypeEPNS_10ASTContextE"] + pub fn Type_getSizeOf( + arg1: clang_QualType, + arg2: *mut clang_ASTContext, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + #[link_name = "\u{1}_Z15Type_getAlignOfN5clang8QualTypeEPNS_10ASTContextE"] + pub fn Type_getAlignOf( + arg1: clang_QualType, + arg2: *mut clang_ASTContext, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + #[link_name = "\u{1}_Z28Type_getNumTemplateArgumentsN5clang8QualTypeE"] + pub fn Type_getNumTemplateArguments( + arg1: clang_QualType, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_Z15Type_getArgTypeN5clang8QualTypeEj"] + pub fn Type_getArgType( + T: clang_QualType, + index: ::std::os::raw::c_uint, + ) -> clang_QualType; +} +extern "C" { + #[link_name = "\u{1}_Z19Type_getNumArgTypesN5clang8QualTypeE"] + pub fn Type_getNumArgTypes(arg1: clang_QualType) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_Z19Type_getPointeeTypeN5clang8QualTypeE"] + pub fn Type_getPointeeType(arg1: clang_QualType) -> clang_QualType; +} +extern "C" { + #[link_name = "\u{1}_Z19Type_getElementTypeN5clang8QualTypeE"] + pub fn Type_getElementType(arg1: clang_QualType) -> clang_QualType; +} +extern "C" { + #[link_name = "\u{1}_Z19Type_getNumElementsN5clang8QualTypeE"] + pub fn Type_getNumElements(arg1: clang_QualType) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_Z21Type_getCanonicalTypeN5clang8QualTypeEPNS_10ASTContextE"] + pub fn Type_getCanonicalType( + arg1: clang_QualType, + arg2: *mut clang_ASTContext, + ) -> clang_QualType; +} +extern "C" { + #[link_name = "\u{1}_Z27Type_isFunctionTypeVariadicN5clang8QualTypeE"] + pub fn Type_isFunctionTypeVariadic(arg1: clang_QualType) -> bool; +} +extern "C" { + #[link_name = "\u{1}_Z18Type_getResultTypeN5clang8QualTypeE"] + pub fn Type_getResultType(arg1: clang_QualType) -> clang_QualType; +} +extern "C" { + #[link_name = "\u{1}_Z31Type_getFunctionTypeCallingConvN5clang8QualTypeE"] + pub fn Type_getFunctionTypeCallingConv( + arg1: clang_QualType, + ) -> CXCallingConv::Type; +} +extern "C" { + #[link_name = "\u{1}_Z17Type_getNamedTypeN5clang8QualTypeE"] + pub fn Type_getNamedType(arg1: clang_QualType) -> clang_QualType; +} +extern "C" { + #[link_name = "\u{1}_Z30Type_getTemplateArgumentAsTypeN5clang8QualTypeEj"] + pub fn Type_getTemplateArgumentAsType( + T: clang_QualType, + index: ::std::os::raw::c_uint, + ) -> clang_QualType; +} +extern "C" { + #[link_name = "\u{1}_Z19getSpellingLocationPN5clang7ASTUnitEPKNS_14SourceLocationEPPNS_9FileEntryEPiS8_S8_"] + pub fn getSpellingLocation( + AST: *mut clang_ASTUnit, + T: *const clang_SourceLocation, + file: *mut *mut clang_FileEntry, + line: *mut ::std::os::raw::c_int, + col: *mut ::std::os::raw::c_int, + off: *mut ::std::os::raw::c_int, + ); +} +extern "C" { + #[link_name = "\u{1}_Z15Comment_getKindPKN5clang8comments7CommentE"] + pub fn Comment_getKind( + arg1: *const clang_comments_Comment, + ) -> CXCommentKind::Type; +} +extern "C" { + #[link_name = "\u{1}_Z22Comment_getNumChildrenPKN5clang8comments7CommentE"] + pub fn Comment_getNumChildren( + arg1: *const clang_comments_Comment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + #[link_name = "\u{1}_Z16Comment_getChildPKN5clang8comments7CommentEj"] + pub fn Comment_getChild( + arg1: *const clang_comments_Comment, + index: ::std::os::raw::c_uint, + ) -> *mut clang_comments_Comment; +} +extern "C" { + #[link_name = "\u{1}_Z25HTMLTagComment_getTagNamePKN5clang8comments7CommentE"] + pub fn HTMLTagComment_getTagName( + arg1: *const clang_comments_Comment, + ) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z24HTMLStartTag_getNumAttrsPKN5clang8comments7CommentE"] + pub fn HTMLStartTag_getNumAttrs( + arg1: *const clang_comments_Comment, + ) -> ::std::os::raw::c_uint; +} +extern "C" { + #[link_name = "\u{1}_Z24HTMLStartTag_getAttrNamePKN5clang8comments7CommentEj"] + pub fn HTMLStartTag_getAttrName( + arg1: *const clang_comments_Comment, + arg2: ::std::os::raw::c_uint, + ) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z25HTMLStartTag_getAttrValuePKN5clang8comments7CommentEj"] + pub fn HTMLStartTag_getAttrValue( + arg1: *const clang_comments_Comment, + arg2: ::std::os::raw::c_uint, + ) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z22CursorKind_getSpelling12CXCursorKind"] + pub fn CursorKind_getSpelling(arg1: CXCursorKind::Type) + -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z20TypeKind_getSpelling10CXTypeKind"] + pub fn TypeKind_getSpelling(arg1: CXTypeKind::Type) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z17FileEntry_getNamePN5clang9FileEntryE"] + pub fn FileEntry_getName(arg1: *mut clang_FileEntry) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z15getClangVersionv"] + pub fn getClangVersion() -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z30CXXBaseSpecifier_isVirtualBasePKN5clang16CXXBaseSpecifierE"] + pub fn CXXBaseSpecifier_isVirtualBase( + arg1: *const clang_CXXBaseSpecifier, + ) -> bool; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __locale_data { + pub _address: u8, +} diff --git a/src/ir/annotations.rs b/src/ir/annotations.rs index 403bffc100..b686af3501 100644 --- a/src/ir/annotations.rs +++ b/src/ir/annotations.rs @@ -158,7 +158,7 @@ impl Annotations { } fn parse(&mut self, comment: &clang::Comment, matched: &mut bool) { - use clang_sys::CXComment_HTMLStartTag; + use clang::CXComment_HTMLStartTag; if comment.kind() == CXComment_HTMLStartTag && comment.get_tag_name() == "div" && comment diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 23120020ce..b4417e68ec 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -9,7 +9,7 @@ use super::layout::Layout; use super::template::TemplateParameters; use super::traversal::{EdgeKind, Trace, Tracer}; use super::ty::RUST_DERIVE_IN_ARRAY_LIMIT; -use clang; +use clang::{self, *}; use codegen::struct_layout::{align_to, bytes_from_bits_pow2}; use ir::derive::CanDeriveCopy; use parse::{ClangItemParser, ParseError}; @@ -1221,7 +1221,6 @@ impl CompInfo { location: Option, ctx: &mut BindgenContext, ) -> Result { - use clang_sys::*; assert!( ty.template_args().is_none(), "We handle template instantiations elsewhere" @@ -1539,7 +1538,6 @@ impl CompInfo { fn kind_from_cursor( cursor: &clang::Cursor, ) -> Result { - use clang_sys::*; Ok(match cursor.kind() { CXCursor_UnionDecl => CompKind::Union, CXCursor_ClassDecl | CXCursor_StructDecl => CompKind::Struct, diff --git a/src/ir/context.rs b/src/ir/context.rs index 384edb95c9..87c90390db 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -22,7 +22,6 @@ use super::ty::{FloatKind, Type, TypeKind}; use callbacks::ParseCallbacks; use cexpr; use clang::{self, Cursor}; -use clang_sys; use parse::ClangItemParser; use proc_macro2::{Ident, Span}; use std::borrow::Cow; @@ -361,8 +360,8 @@ pub struct BindgenContext { in_codegen: bool, - /// The clang index for parsing. - index: clang::Index, + // /// The clang index for parsing. + // index: clang::Index, /// The translation unit for parsing. translation_unit: clang::TranslationUnit, @@ -547,7 +546,7 @@ impl BindgenContext { let (effective_target, explicit_target) = find_effective_target(&options.clang_args); - let index = clang::Index::new(false, true); + // let index = clang::Index::new(false, true); let parse_options = clang_sys::CXTranslationUnit_DetailedPreprocessingRecord; @@ -565,7 +564,7 @@ impl BindgenContext { }; clang::TranslationUnit::parse( - &index, + // &index, "", &clang_args, &options.input_unsaved_files, @@ -611,7 +610,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" replacements: Default::default(), collected_typerefs: false, in_codegen: false, - index, + // index, translation_unit, target_info, options, @@ -815,7 +814,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" ); assert_eq!( definition.kind(), - clang_sys::CXCursor_TemplateTypeParameter + clang::CXCursor_TemplateTypeParameter ); self.add_item_to_module(&item); @@ -841,7 +840,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" pub fn get_type_param(&self, definition: &clang::Cursor) -> Option { assert_eq!( definition.kind(), - clang_sys::CXCursor_TemplateTypeParameter + clang::CXCursor_TemplateTypeParameter ); self.type_params.get(definition).cloned() } @@ -1651,12 +1650,12 @@ If you encounter an error missing from this list, please file an issue or a PR!" // on accident. let idx = children .iter() - .position(|c| c.kind() == clang_sys::CXCursor_TemplateRef); + .position(|c| c.kind() == clang::CXCursor_TemplateRef); if let Some(idx) = idx { if children .iter() .take(idx) - .all(|c| c.kind() == clang_sys::CXCursor_NamespaceRef) + .all(|c| c.kind() == clang::CXCursor_NamespaceRef) { children = children.into_iter().skip(idx + 1).collect(); } @@ -1665,9 +1664,9 @@ If you encounter an error missing from this list, please file an issue or a PR!" for child in children.iter().rev() { match child.kind() { - clang_sys::CXCursor_TypeRef | - clang_sys::CXCursor_TypedefDecl | - clang_sys::CXCursor_TypeAliasDecl => { + clang::CXCursor_TypeRef | + clang::CXCursor_TypedefDecl | + clang::CXCursor_TypeAliasDecl => { // The `with_id` id will potentially end up unused if we give up // on this type (for example, because it has const value // template args), so if we pass `with_id` as the parent, it is @@ -1682,7 +1681,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" ); args.push(ty); } - clang_sys::CXCursor_TemplateRef => { + clang::CXCursor_TemplateRef => { let ( template_decl_cursor, template_decl_id, @@ -1848,7 +1847,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" ty: &clang::Type, location: Option, ) -> Option { - use clang_sys::{CXCursor_TypeAliasTemplateDecl, CXCursor_TypeRef}; + use clang::{CXCursor_TypeAliasTemplateDecl, CXCursor_TypeRef}; debug!( "builtin_or_resolved_ty: {:?}, {:?}, {:?}", ty, location, parent_id @@ -1967,40 +1966,39 @@ If you encounter an error missing from this list, please file an issue or a PR!" } fn build_builtin_ty(&mut self, ty: &clang::Type) -> Option { - use clang_sys::*; let type_kind = match ty.kind() { - CXType_NullPtr => TypeKind::NullPtr, - CXType_Void => TypeKind::Void, - CXType_Bool => TypeKind::Int(IntKind::Bool), - CXType_Int => TypeKind::Int(IntKind::Int), - CXType_UInt => TypeKind::Int(IntKind::UInt), - CXType_Char_S => TypeKind::Int(IntKind::Char { is_signed: true }), - CXType_Char_U => TypeKind::Int(IntKind::Char { is_signed: false }), - CXType_SChar => TypeKind::Int(IntKind::SChar), - CXType_UChar => TypeKind::Int(IntKind::UChar), - CXType_Short => TypeKind::Int(IntKind::Short), - CXType_UShort => TypeKind::Int(IntKind::UShort), - CXType_WChar => TypeKind::Int(IntKind::WChar), - CXType_Char16 => TypeKind::Int(IntKind::U16), - CXType_Char32 => TypeKind::Int(IntKind::U32), - CXType_Long => TypeKind::Int(IntKind::Long), - CXType_ULong => TypeKind::Int(IntKind::ULong), - CXType_LongLong => TypeKind::Int(IntKind::LongLong), - CXType_ULongLong => TypeKind::Int(IntKind::ULongLong), - CXType_Int128 => TypeKind::Int(IntKind::I128), - CXType_UInt128 => TypeKind::Int(IntKind::U128), - CXType_Float => TypeKind::Float(FloatKind::Float), - CXType_Double => TypeKind::Float(FloatKind::Double), - CXType_LongDouble => TypeKind::Float(FloatKind::LongDouble), - CXType_Float128 => TypeKind::Float(FloatKind::Float128), - CXType_Complex => { + clang::CXType_NullPtr => TypeKind::NullPtr, + clang::CXType_Void => TypeKind::Void, + clang::CXType_Bool => TypeKind::Int(IntKind::Bool), + clang::CXType_Int => TypeKind::Int(IntKind::Int), + clang::CXType_UInt => TypeKind::Int(IntKind::UInt), + clang::CXType_Char_S => TypeKind::Int(IntKind::Char { is_signed: true }), + clang::CXType_Char_U => TypeKind::Int(IntKind::Char { is_signed: false }), + clang::CXType_SChar => TypeKind::Int(IntKind::SChar), + clang::CXType_UChar => TypeKind::Int(IntKind::UChar), + clang::CXType_Short => TypeKind::Int(IntKind::Short), + clang::CXType_UShort => TypeKind::Int(IntKind::UShort), + clang::CXType_WChar => TypeKind::Int(IntKind::WChar), + clang::CXType_Char16 => TypeKind::Int(IntKind::U16), + clang::CXType_Char32 => TypeKind::Int(IntKind::U32), + clang::CXType_Long => TypeKind::Int(IntKind::Long), + clang::CXType_ULong => TypeKind::Int(IntKind::ULong), + clang::CXType_LongLong => TypeKind::Int(IntKind::LongLong), + clang::CXType_ULongLong => TypeKind::Int(IntKind::ULongLong), + clang::CXType_Int128 => TypeKind::Int(IntKind::I128), + clang::CXType_UInt128 => TypeKind::Int(IntKind::U128), + clang::CXType_Float => TypeKind::Float(FloatKind::Float), + clang::CXType_Double => TypeKind::Float(FloatKind::Double), + clang::CXType_LongDouble => TypeKind::Float(FloatKind::LongDouble), + clang::CXType_Float128 => TypeKind::Float(FloatKind::Float128), + clang::CXType_Complex => { let float_type = ty.elem_type().expect("Not able to resolve complex type?"); let float_kind = match float_type.kind() { - CXType_Float => FloatKind::Float, - CXType_Double => FloatKind::Double, - CXType_LongDouble => FloatKind::LongDouble, - CXType_Float128 => FloatKind::Float128, + clang::CXType_Float => FloatKind::Float, + clang::CXType_Double => FloatKind::Double, + clang::CXType_LongDouble => FloatKind::LongDouble, + clang::CXType_Float128 => FloatKind::Float128, _ => panic!( "Non floating-type complex? {:?}, {:?}", ty, float_type, @@ -2121,7 +2119,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" ) -> (Option, ModuleKind) { assert_eq!( cursor.kind(), - ::clang_sys::CXCursor_Namespace, + ::clang::CXCursor_Namespace, "Be a nice person" ); @@ -2198,7 +2196,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Given a CXCursor_Namespace cursor, return the item id of the /// corresponding module, or create one on the fly. pub fn module(&mut self, cursor: clang::Cursor) -> ModuleId { - use clang_sys::*; + use clang::*; assert_eq!(cursor.kind(), CXCursor_Namespace, "Be a nice person"); let cursor = cursor.canonical(); if let Some(id) = self.modules.get(&cursor) { @@ -2753,20 +2751,20 @@ impl TemplateParameters for PartialType { // Wouldn't it be nice if libclang would reliably give us this // information‽ match self.decl().kind() { - clang_sys::CXCursor_ClassTemplate | - clang_sys::CXCursor_FunctionTemplate | - clang_sys::CXCursor_TypeAliasTemplateDecl => { + clang::CXCursor_ClassTemplate | + clang::CXCursor_FunctionTemplate | + clang::CXCursor_TypeAliasTemplateDecl => { let mut num_params = 0; self.decl().visit(|c| { match c.kind() { - clang_sys::CXCursor_TemplateTypeParameter | - clang_sys::CXCursor_TemplateTemplateParameter | - clang_sys::CXCursor_NonTypeTemplateParameter => { + clang::CXCursor_TemplateTypeParameter | + clang::CXCursor_TemplateTemplateParameter | + clang::CXCursor_NonTypeTemplateParameter => { num_params += 1; } _ => {} }; - clang_sys::CXChildVisit_Continue + clang::CXChildVisit_Continue }); num_params } diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index f2013844b2..e8a869415f 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -56,7 +56,7 @@ impl Enum { ty: &clang::Type, ctx: &mut BindgenContext, ) -> Result { - use clang_sys::*; + use clang::*; debug!("Enum::from_ty {:?}", ty); if ty.kind() != CXType_Enum { diff --git a/src/ir/function.rs b/src/ir/function.rs index 0715ec546c..bba9d26df8 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -7,7 +7,6 @@ use super::item::Item; use super::traversal::{EdgeKind, Trace, Tracer}; use super::ty::TypeKind; use clang; -use clang_sys::{self, CXCallingConv}; use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; use proc_macro2; use quote; @@ -29,11 +28,11 @@ impl FunctionKind { fn from_cursor(cursor: &clang::Cursor) -> Option { // FIXME(emilio): Deduplicate logic with `ir::comp`. Some(match cursor.kind() { - clang_sys::CXCursor_FunctionDecl => FunctionKind::Function, - clang_sys::CXCursor_Constructor => { + clang::CXCursor_FunctionDecl => FunctionKind::Function, + clang::CXCursor_Constructor => { FunctionKind::Method(MethodKind::Constructor) } - clang_sys::CXCursor_Destructor => { + clang::CXCursor_Destructor => { FunctionKind::Method(if cursor.method_is_virtual() { MethodKind::VirtualDestructor { pure_virtual: cursor.method_is_pure_virtual(), @@ -42,7 +41,7 @@ impl FunctionKind { MethodKind::Destructor }) } - clang_sys::CXCursor_CXXMethod => { + clang::CXCursor_CXXMethod => { if cursor.method_is_virtual() { FunctionKind::Method(MethodKind::Virtual { pure_virtual: cursor.method_is_pure_virtual(), @@ -177,7 +176,7 @@ pub enum Abi { /// The "win64" ABI. Win64, /// An unknown or invalid ABI. - Unknown(CXCallingConv), + Unknown(clang::CXCallingConv), } impl Abi { @@ -227,8 +226,8 @@ pub struct FunctionSig { abi: Abi, } -fn get_abi(cc: CXCallingConv) -> Abi { - use clang_sys::*; +fn get_abi(cc: clang::CXCallingConv) -> Abi { + use clang::*; match cc { CXCallingConv_Default => Abi::C, CXCallingConv_C => Abi::C, @@ -257,7 +256,7 @@ pub fn cursor_mangling( return None; } - let is_destructor = cursor.kind() == clang_sys::CXCursor_Destructor; + let is_destructor = cursor.kind() == clang::CXCursor_Destructor; if let Ok(mut manglings) = cursor.cxx_manglings() { while let Some(m) = manglings.pop() { // Only generate the destructor group 1, see below. @@ -366,7 +365,7 @@ impl FunctionSig { cursor: &clang::Cursor, ctx: &mut BindgenContext, ) -> Result { - use clang_sys::*; + use clang::*; debug!("FunctionSig::from_ty {:?} {:?}", ty, cursor); // Skip function templates @@ -553,7 +552,7 @@ impl ClangSubItemParser for Function { cursor: clang::Cursor, context: &mut BindgenContext, ) -> Result, ParseError> { - use clang_sys::*; + use clang::*; let kind = match FunctionKind::from_cursor(&cursor) { None => return Err(ParseError::Continue), diff --git a/src/ir/item.rs b/src/ir/item.rs index eb5b4d25dc..8dcd8760a2 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -19,7 +19,6 @@ use super::template::{AsTemplateParam, TemplateParameters}; use super::traversal::{EdgeKind, Trace, Tracer}; use super::ty::{Type, TypeKind}; use clang; -use clang_sys; use lazycell::LazyCell; use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; use regex; @@ -1246,8 +1245,8 @@ fn visit_child( parent_id: Option, ctx: &mut BindgenContext, result: &mut Result, -) -> clang_sys::CXChildVisitResult { - use clang_sys::*; +) -> clang::CXChildVisitResult { + use clang::*; if result.is_ok() { return CXChildVisit_Break; } @@ -1295,7 +1294,7 @@ impl ClangItemParser for Item { parent_id: Option, ctx: &mut BindgenContext, ) -> Result { - use clang_sys::*; + use clang::*; use ir::var::Var; if !cursor.is_valid() { @@ -1538,8 +1537,6 @@ impl ClangItemParser for Item { parent_id: Option, ctx: &mut BindgenContext, ) -> Result { - use clang_sys::*; - debug!( "Item::from_ty_with_id: {:?}\n\ \tty = {:?},\n\ @@ -1547,8 +1544,8 @@ impl ClangItemParser for Item { id, ty, location ); - if ty.kind() == clang_sys::CXType_Unexposed || - location.cur_type().kind() == clang_sys::CXType_Unexposed + if ty.kind() == clang::CXType_Unexposed || + location.cur_type().kind() == clang::CXType_Unexposed { if ty.is_associated_type() || location.cur_type().is_associated_type() @@ -1583,10 +1580,10 @@ impl ClangItemParser for Item { } // First, check we're not recursing. - let mut valid_decl = decl.kind() != CXCursor_NoDeclFound; + let mut valid_decl = decl.kind() != clang::CXCursor_NoDeclFound; let declaration_to_look_for = if valid_decl { decl.canonical() - } else if location.kind() == CXCursor_ClassTemplate { + } else if location.kind() == clang::CXCursor_ClassTemplate { valid_decl = true; location } else { @@ -1706,7 +1703,7 @@ impl ClangItemParser for Item { location ); - if ty.kind() != clang_sys::CXType_Unexposed { + if ty.kind() != clang::CXType_Unexposed { // If the given cursor's type's kind is not Unexposed, then we // aren't looking at a template parameter. This check may need to be // updated in the future if they start properly exposing template @@ -1770,7 +1767,7 @@ impl ClangItemParser for Item { regex::Regex::new(r"^type\-parameter\-\d+\-\d+$").unwrap(); } - if refd.kind() != clang_sys::CXCursor_TemplateTypeParameter { + if refd.kind() != clang::CXCursor_TemplateTypeParameter { return false; } @@ -1783,7 +1780,7 @@ impl ClangItemParser for Item { let definition = if is_template_with_spelling(&location, &ty_spelling) { // Situation (1) location - } else if location.kind() == clang_sys::CXCursor_TypeRef { + } else if location.kind() == clang::CXCursor_TypeRef { // Situation (2) match location.referenced() { Some(refd) @@ -1799,7 +1796,7 @@ impl ClangItemParser for Item { location.visit(|child| { let child_ty = child.cur_type(); - if child_ty.kind() == clang_sys::CXCursor_TypeRef && + if child_ty.kind() == clang::CXCursor_TypeRef && child_ty.spelling() == ty_spelling { match child.referenced() { @@ -1810,13 +1807,13 @@ impl ClangItemParser for Item { ) => { definition = Some(refd); - return clang_sys::CXChildVisit_Break; + return clang::CXChildVisit_Break; } _ => {} } } - clang_sys::CXChildVisit_Continue + clang::CXChildVisit_Continue }); if let Some(def) = definition { diff --git a/src/ir/module.rs b/src/ir/module.rs index 7a22106617..98612554a2 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -77,7 +77,7 @@ impl ClangSubItemParser for Module { cursor: clang::Cursor, ctx: &mut BindgenContext, ) -> Result, ParseError> { - use clang_sys::*; + use clang::*; match cursor.kind() { CXCursor_Namespace => { let module_id = ctx.module(cursor); diff --git a/src/ir/objc.rs b/src/ir/objc.rs index cfbf3dd0ea..a5529a61b3 100644 --- a/src/ir/objc.rs +++ b/src/ir/objc.rs @@ -5,14 +5,14 @@ use super::function::FunctionSig; use super::traversal::{Trace, Tracer}; use super::ty::TypeKind; use clang; -use clang_sys::CXChildVisit_Continue; -use clang_sys::CXCursor_ObjCCategoryDecl; -use clang_sys::CXCursor_ObjCClassMethodDecl; -use clang_sys::CXCursor_ObjCClassRef; -use clang_sys::CXCursor_ObjCInstanceMethodDecl; -use clang_sys::CXCursor_ObjCProtocolDecl; -use clang_sys::CXCursor_ObjCProtocolRef; -use clang_sys::CXCursor_TemplateTypeParameter; +use clang::CXChildVisit_Continue; +use clang::CXCursor_ObjCCategoryDecl; +use clang::CXCursor_ObjCClassMethodDecl; +use clang::CXCursor_ObjCClassRef; +use clang::CXCursor_ObjCInstanceMethodDecl; +use clang::CXCursor_ObjCProtocolDecl; +use clang::CXCursor_ObjCProtocolRef; +use clang::CXCursor_TemplateTypeParameter; use proc_macro2::{Ident, Span, TokenStream}; /// Objective C interface as used in TypeKind diff --git a/src/ir/template.rs b/src/ir/template.rs index 30c578ced3..2fc30f54a6 100644 --- a/src/ir/template.rs +++ b/src/ir/template.rs @@ -222,7 +222,7 @@ impl TemplateInstantiation { ty: &clang::Type, ctx: &mut BindgenContext, ) -> Option { - use clang_sys::*; + use clang::*; let template_args = ty.template_args().map_or(vec![], |args| match ty .canonical_type() diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 0144bdbad1..06006063d3 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -721,7 +721,6 @@ impl Type { parent_id: Option, ctx: &mut BindgenContext, ) -> Result, ParseError> { - use clang_sys::*; { let already_resolved = ctx.builtin_or_resolved_ty( potential_id, @@ -750,8 +749,8 @@ impl Type { // Parse objc protocols as if they were interfaces let mut ty_kind = ty.kind(); match location.kind() { - CXCursor_ObjCProtocolDecl | CXCursor_ObjCCategoryDecl => { - ty_kind = CXType_ObjCInterface + clang::CXCursor_ObjCProtocolDecl | clang::CXCursor_ObjCCategoryDecl => { + ty_kind = clang::CXType_ObjCInterface } _ => {} } @@ -761,11 +760,11 @@ impl Type { // objc template params, which seem to manifest as a typedef. // We are rewriting them as id to suppress multiple conflicting // typedefs at root level - if ty_kind == CXType_Typedef { + if ty_kind == clang::CXType_Typedef { let is_template_type_param = - ty.declaration().kind() == CXCursor_TemplateTypeParameter; + ty.declaration().kind() == clang::CXCursor_TemplateTypeParameter; let is_canonical_objcpointer = - canonical_ty.kind() == CXType_ObjCObjectPointer; + canonical_ty.kind() == clang::CXType_ObjCObjectPointer; // We have found a template type for objc interface if is_canonical_objcpointer && is_template_type_param { @@ -775,7 +774,7 @@ impl Type { } } - if location.kind() == CXCursor_ClassTemplatePartialSpecialization { + if location.kind() == clang::CXCursor_ClassTemplatePartialSpecialization { // Sorry! (Not sorry) warn!( "Found a partial template specialization; bindgen does not \ @@ -788,8 +787,8 @@ impl Type { )); } - let kind = if location.kind() == CXCursor_TemplateRef || - (ty.template_args().is_some() && ty_kind != CXType_Typedef) + let kind = if location.kind() == clang::CXCursor_TemplateRef || + (ty.template_args().is_some() && ty_kind != clang::CXType_Typedef) { // This is a template instantiation. match TemplateInstantiation::from_ty(&ty, ctx) { @@ -798,9 +797,9 @@ impl Type { } } else { match ty_kind { - CXType_Unexposed + clang::CXType_Unexposed if *ty != canonical_ty && - canonical_ty.kind() != CXType_Invalid && + canonical_ty.kind() != clang::CXType_Invalid && ty.ret_type().is_none() && // Sometime clang desugars some types more than // what we need, specially with function @@ -825,7 +824,7 @@ impl Type { ctx, ); } - CXType_Unexposed | CXType_Invalid => { + clang::CXType_Unexposed | clang::CXType_Invalid => { // For some reason Clang doesn't give us any hint in some // situations where we should generate a function pointer (see // tests/headers/func_ptr_in_struct.h), so we do a guess here @@ -851,9 +850,9 @@ impl Type { TypeKind::Comp(complex) } else { match location.kind() { - CXCursor_CXXBaseSpecifier | - CXCursor_ClassTemplate => { - if location.kind() == CXCursor_CXXBaseSpecifier + clang::CXCursor_CXXBaseSpecifier | + clang::CXCursor_ClassTemplate => { + if location.kind() == clang::CXCursor_CXXBaseSpecifier { // In the case we're parsing a base specifier // inside an unexposed or invalid type, it means @@ -925,7 +924,7 @@ impl Type { } } } - CXCursor_TypeAliasTemplateDecl => { + clang::CXCursor_TypeAliasTemplateDecl => { debug!("TypeAliasTemplateDecl"); // We need to manually unwind this one. @@ -934,12 +933,12 @@ impl Type { location.visit(|cur| { match cur.kind() { - CXCursor_TypeAliasDecl => { + clang::CXCursor_TypeAliasDecl => { let current = cur.cur_type(); debug_assert_eq!( current.kind(), - CXType_Typedef + clang::CXType_Typedef ); name = current.spelling(); @@ -954,7 +953,7 @@ impl Type { ctx, )); } - CXCursor_TemplateTypeParameter => { + clang::CXCursor_TemplateTypeParameter => { let param = Item::type_param( None, cur, ctx, ) @@ -967,7 +966,7 @@ impl Type { } _ => {} } - CXChildVisit_Continue + clang::CXChildVisit_Continue }); let inner_type = match inner { @@ -984,7 +983,7 @@ impl Type { TypeKind::TemplateAlias(inner_type, args) } - CXCursor_TemplateRef => { + clang::CXCursor_TemplateRef => { let referenced = location.referenced().unwrap(); let referenced_ty = referenced.cur_type(); @@ -1004,7 +1003,7 @@ impl Type { ctx, ); } - CXCursor_TypeRef => { + clang::CXCursor_TypeRef => { let referenced = location.referenced().unwrap(); let referenced_ty = referenced.cur_type(); let declaration = referenced_ty.declaration(); @@ -1026,11 +1025,11 @@ impl Type { id.into(), )); } - CXCursor_NamespaceRef => { + clang::CXCursor_NamespaceRef => { return Err(ParseError::Continue); } _ => { - if ty.kind() == CXType_Unexposed { + if ty.kind() == clang::CXType_Unexposed { warn!( "Unexposed type {:?}, recursing inside, \ loc: {:?}", @@ -1046,7 +1045,7 @@ impl Type { } } } - CXType_Auto => { + clang::CXType_Auto => { if canonical_ty == *ty { debug!("Couldn't find deduced type: {:?}", ty); return Err(ParseError::Continue); @@ -1067,15 +1066,15 @@ impl Type { // // We might need to, though, if the context is already in the // process of resolving them. - CXType_ObjCObjectPointer | - CXType_MemberPointer | - CXType_Pointer => { + clang::CXType_ObjCObjectPointer | + clang::CXType_MemberPointer | + clang::CXType_Pointer => { let pointee = ty.pointee_type().unwrap(); let inner = Item::from_ty_or_ref(pointee, location, None, ctx); TypeKind::Pointer(inner) } - CXType_BlockPointer => { + clang::CXType_BlockPointer => { let pointee = ty.pointee_type().expect("Not valid Type?"); let inner = Item::from_ty_or_ref(pointee, location, None, ctx); @@ -1083,7 +1082,7 @@ impl Type { } // XXX: RValueReference is most likely wrong, but I don't think we // can even add bindings for that, so huh. - CXType_RValueReference | CXType_LValueReference => { + clang::CXType_RValueReference | clang::CXType_LValueReference => { let inner = Item::from_ty_or_ref( ty.pointee_type().unwrap(), location, @@ -1093,7 +1092,7 @@ impl Type { TypeKind::Reference(inner) } // XXX DependentSizedArray is wrong - CXType_VariableArray | CXType_DependentSizedArray => { + clang::CXType_VariableArray | clang::CXType_DependentSizedArray => { let inner = Item::from_ty( ty.elem_type().as_ref().unwrap(), location, @@ -1103,7 +1102,7 @@ impl Type { .expect("Not able to resolve array element?"); TypeKind::Pointer(inner) } - CXType_IncompleteArray => { + clang::CXType_IncompleteArray => { let inner = Item::from_ty( ty.elem_type().as_ref().unwrap(), location, @@ -1113,17 +1112,17 @@ impl Type { .expect("Not able to resolve array element?"); TypeKind::Array(inner, 0) } - CXType_FunctionNoProto | CXType_FunctionProto => { + clang::CXType_FunctionNoProto | clang::CXType_FunctionProto => { let signature = FunctionSig::from_ty(ty, &location, ctx)?; TypeKind::Function(signature) } - CXType_Typedef => { + clang::CXType_Typedef => { let inner = cursor.typedef_type().expect("Not valid Type?"); let inner = Item::from_ty_or_ref(inner, location, None, ctx); TypeKind::Alias(inner) } - CXType_Enum => { + clang::CXType_Enum => { let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?"); if name.is_empty() { @@ -1135,7 +1134,7 @@ impl Type { TypeKind::Enum(enum_) } - CXType_Record => { + clang::CXType_Record => { let complex = CompInfo::from_ty( potential_id, ty, @@ -1155,7 +1154,7 @@ impl Type { TypeKind::Comp(complex) } - CXType_Vector => { + clang::CXType_Vector => { let inner = Item::from_ty( ty.elem_type().as_ref().unwrap(), location, @@ -1165,7 +1164,7 @@ impl Type { .expect("Not able to resolve vector element?"); TypeKind::Vector(inner, ty.num_elements().unwrap()) } - CXType_ConstantArray => { + clang::CXType_ConstantArray => { let inner = Item::from_ty( ty.elem_type().as_ref().unwrap(), location, @@ -1175,7 +1174,7 @@ impl Type { .expect("Not able to resolve array element?"); TypeKind::Array(inner, ty.num_elements().unwrap()) } - CXType_Elaborated => { + clang::CXType_Elaborated => { return Self::from_clang_ty( potential_id, &ty.named(), @@ -1184,15 +1183,15 @@ impl Type { ctx, ); } - CXType_ObjCId => TypeKind::ObjCId, - CXType_ObjCSel => TypeKind::ObjCSel, - CXType_ObjCClass | CXType_ObjCInterface => { + clang::CXType_ObjCId => TypeKind::ObjCId, + clang::CXType_ObjCSel => TypeKind::ObjCSel, + clang::CXType_ObjCClass | clang::CXType_ObjCInterface => { let interface = ObjCInterface::from_ty(&location, ctx) .expect("Not a valid objc interface?"); name = interface.rust_name(); TypeKind::ObjCInterface(interface) } - CXType_Dependent => { + clang::CXType_Dependent => { return Err(ParseError::Continue); } _ => { diff --git a/src/ir/var.rs b/src/ir/var.rs index 921dcf98c7..41b6c48b1a 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -135,7 +135,7 @@ impl ClangSubItemParser for Var { ) -> Result, ParseError> { use cexpr::expr::EvalResult; use cexpr::literal::CChar; - use clang_sys::*; + use clang::*; match cursor.kind() { CXCursor_MacroDefinition => { if let Some(callbacks) = ctx.parse_callbacks() { @@ -356,7 +356,7 @@ fn get_integer_literal_from_cursor( cursor: &clang::Cursor, unit: &clang::TranslationUnit, ) -> Option { - use clang_sys::*; + use clang::*; let mut value = None; cursor.visit(|c| { match c.kind() { diff --git a/src/lib.rs b/src/lib.rs index 4a8b8d8a7a..9fea93c79d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2275,12 +2275,12 @@ fn parse_one( ctx: &mut BindgenContext, cursor: clang::Cursor, parent: Option, -) -> clang_sys::CXChildVisitResult { +) -> clang::CXChildVisitResult { if !filter_builtins(ctx, &cursor) { return CXChildVisit_Continue; } - use clang_sys::CXChildVisit_Continue; + use clang::CXChildVisit_Continue; match Item::parse(cursor, parent, ctx) { Ok(..) => {} Err(ParseError::Continue) => {} @@ -2293,12 +2293,10 @@ fn parse_one( /// Parse the Clang AST into our `Item` internal representation. fn parse(context: &mut BindgenContext) -> Result<(), ()> { - use clang_sys::*; - let mut any_error = false; for d in context.translation_unit().diags().iter() { let msg = d.format(); - let is_err = d.severity() >= CXDiagnostic_Error; + let is_err = d.severity() >= clang::CXDiagnostic_Error; eprintln!("{}, err: {}", msg, is_err); any_error |= is_err; } @@ -2310,11 +2308,11 @@ fn parse(context: &mut BindgenContext) -> Result<(), ()> { let cursor = context.translation_unit().cursor(); if context.options().emit_ast { - fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult { + fn dump_if_not_builtin(cur: &clang::Cursor) -> clang::CXChildVisitResult { if !cur.is_builtin() { clang::ast_dump(&cur, 0) } else { - CXChildVisit_Continue + clang::CXChildVisit_Continue } } cursor.visit(|cur| dump_if_not_builtin(&cur)); From 59e2432deddf419541fd66e5c7c8bb3bb53d2936 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Sat, 15 Feb 2020 01:39:05 -0800 Subject: [PATCH 02/88] Allow visiting of more AST nodes --- src/clang.rs | 11 ++++++++--- src/clang/ClangAST.cpp | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index 064870b677..fb873e9b18 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -1125,9 +1125,14 @@ where Visitor: FnMut(Cursor) -> CXChildVisitResult, { let func: &mut Visitor = mem::transmute(data); - let node = match node.kind { - CXCursor_StructDecl => ASTNode::Decl(node.ptr.decl), - _ => ASTNode::Invalid, + let node = if (node.kind >= CXCursor_FirstDecl && node.kind <= CXCursor_LastDecl) + || (node.kind >= CXCursor_FirstExtraDecl && node.kind <= CXCursor_LastExtraDecl) + { + ASTNode::Decl(node.ptr.decl) + } else if node.kind >= CXCursor_FirstExpr && node.kind <= CXCursor_LastExpr { + ASTNode::Expr(node.ptr.expr) + } else { + return CXChildVisit_Recurse; }; let child = Cursor { node, diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 07674eccaa..63e7329820 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -490,6 +490,8 @@ const Decl *Decl_getReferenced(const Decl *D) { } const Decl *Decl_getCanonical(const Decl *D) { + if (!D) + return nullptr; return D->getCanonicalDecl(); } From dea6a70df3b7c6edcf747122afefc2bb234dacf1 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 17 Feb 2020 15:03:32 -0800 Subject: [PATCH 03/88] Implement Eq correctly for ASTNode We need to compare on variant contents, not just on variant equality --- src/clang.rs | 52 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index fb873e9b18..98cc4f9dde 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -10,7 +10,7 @@ use regex; use std::ffi::{CStr, CString}; use std::fmt; use std::hash::Hash; -// use std::hash::Hasher; +use std::hash::Hasher; use std::os::raw::{c_char, c_int, c_longlong, c_uint, c_ulong, c_ulonglong}; use std::{mem, ptr, slice}; @@ -75,7 +75,7 @@ pub struct Cursor { unit: *mut clangtool::clang_ASTUnit, } -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone)] pub enum ASTNode { Invalid, Decl(*const clangtool::clang_Decl), @@ -83,6 +83,40 @@ pub enum ASTNode { CXXBaseSpecifier(*const clangtool::clang_CXXBaseSpecifier), } +impl PartialEq for ASTNode { + fn eq(&self, other: &ASTNode) -> bool { + match (*self, *other) { + (ASTNode::Invalid, ASTNode::Invalid) => true, + (ASTNode::Decl(d1), ASTNode::Decl(d2)) => ptr::eq(d1, d2), + (ASTNode::Expr(e1), ASTNode::Expr(e2)) => ptr::eq(e1, e2), + (ASTNode::CXXBaseSpecifier(base1), ASTNode::CXXBaseSpecifier(base2)) => ptr::eq(base1, base2), + _ => false, + } + } +} + +impl Eq for ASTNode {} + +impl Hash for ASTNode { + fn hash(&self, state: &mut H) { + match *self { + ASTNode::Invalid => state.write_u8(1), + ASTNode::Decl(d) => { + state.write_u8(2); + ptr::hash(d, state); + } + ASTNode::Expr(e) => { + state.write_u8(3); + ptr::hash(e, state); + } + ASTNode::CXXBaseSpecifier(b) => { + state.write_u8(4); + ptr::hash(b, state); + } + } + } +} + impl ASTNode { /// Is this node valid? fn is_valid(&self) -> bool { @@ -1142,20 +1176,6 @@ where (*func)(child) } -// impl PartialEq for Cursor { -// fn eq(&self, other: &Cursor) -> bool { -// unsafe { clang_equalCursors(self.x, other.x) == 1 } -// } -// } - -// impl Eq for Cursor {} - -// impl Hash for Cursor { -// fn hash(&self, state: &mut H) { -// unsafe { clang_hashCursor(self.x) }.hash(state) -// } -// } - /// The type of a node in clang's AST. #[derive(Clone, Copy, PartialEq, Eq)] pub struct Type { From d41bb180742444417f89e7755b4db4ee98d954aa Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 17 Feb 2020 15:04:29 -0800 Subject: [PATCH 04/88] Do not visit initial node when visiting children --- src/clang/ClangAST.cpp | 57 +++++++++++++++++++++--------------------- src/clang/ClangAST.hpp | 6 ++--- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 63e7329820..082c1b1683 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1343,41 +1343,42 @@ class BindgenVisitor : public RecursiveASTVisitor { explicit BindgenVisitor(ASTUnit &AST, Visitor V, CXClientData data) : AST(AST), VisitFn(V), Data(data) {} bool TraverseDecl(Decl *D) { - switch (VisitFn(Node(D), Parent, &AST, Data)) { - case CXChildVisit_Break: - return false; - case CXChildVisit_Continue: - return true; - case CXChildVisit_Recurse: - auto OldParent = Parent; - Parent = Node(D); - bool res = RecursiveASTVisitor::TraverseDecl(D); - Parent = OldParent; - return res; + if (Parent) { + switch (VisitFn(Node(D), Parent, &AST, Data)) { + case CXChildVisit_Break: + return false; + case CXChildVisit_Continue: + return true; + case CXChildVisit_Recurse: + break; + } } - llvm_unreachable("Visitor return invalid CXChildVisitResult"); + auto OldParent = Parent; + Parent = Node(D); + bool res = RecursiveASTVisitor::TraverseDecl(D); + Parent = OldParent; + return res; } bool TraverseStmt(Stmt *S) { - switch (VisitFn(Node(cast(S)), Parent, &AST, Data)) { - case CXChildVisit_Break: - return false; - case CXChildVisit_Continue: - return true; - case CXChildVisit_Recurse: - auto OldParent = Parent; - Parent = Node(cast(S)); - bool res = RecursiveASTVisitor::TraverseStmt(S); - Parent = OldParent; - return res; + if (Parent) { + switch (VisitFn(Node(cast(S)), Parent, &AST, Data)) { + case CXChildVisit_Break: + return false; + case CXChildVisit_Continue: + return true; + case CXChildVisit_Recurse: + break; + } } - } - // bool TraverseType(Type *T) { - // Parent = Node(T); - // return RecursiveASTVisitor::TraverseStmt(E); - // } + auto OldParent = Parent; + Parent = Node(cast(S)); + bool res = RecursiveASTVisitor::TraverseStmt(S); + Parent = OldParent; + return res; + } }; void Decl_visitChildren(const Decl *Parent, Visitor V, ASTUnit *Unit, CXClientData data) { diff --git a/src/clang/ClangAST.hpp b/src/clang/ClangAST.hpp index 4413ac3d34..66ef5b5e43 100644 --- a/src/clang/ClangAST.hpp +++ b/src/clang/ClangAST.hpp @@ -196,9 +196,9 @@ struct Node { Node(const Expr *expr) : kind(Expr_getCXCursorKind(expr)) { ptr.expr = expr; } - // Node(Type *T) : kind(Type_getCXCursorKind(T)) { - // ptr.expr = expr; - // } + operator bool() const { + return kind != CXCursor_NotImplemented; + } }; typedef CXChildVisitResult (*Visitor)(Node N, Node parent, From d6b1474845dd5f056bbdcc90a40de8ba0c70357d Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 17 Feb 2020 15:15:16 -0800 Subject: [PATCH 05/88] Do not return attributed or paren types from clang Bindgen currently assumes that it won't see these types from libclang. --- src/clang/ClangAST.cpp | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 082c1b1683..0987101244 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -676,21 +676,37 @@ comments::Comment *Decl_getParsedComment(const Decl *D, ASTContext *Ctx) { } QualType Decl_getType(const Decl *D, ASTContext *Ctx) { + auto ty = QualType(); if (!D) - return QualType(); + return ty; + if (auto *TD = dyn_cast(&*D)) - return Ctx->getTypeDeclType(TD); + ty = Ctx->getTypeDeclType(TD); if (auto *ID = dyn_cast(&*D)) - return Ctx->getObjCInterfaceType(ID); + ty = Ctx->getObjCInterfaceType(ID); if (auto *DD = dyn_cast(&*D)) - return DD->getType(); + ty = DD->getType(); if (auto *VD = dyn_cast(&*D)) - return VD->getType(); + ty = VD->getType(); if (auto *PD = dyn_cast(&*D)) - return PD->getType(); + ty = PD->getType(); if (auto *FTD = dyn_cast(&*D)) - return FTD->getTemplatedDecl()->getType(); - return QualType(); + ty = FTD->getTemplatedDecl()->getType(); + + if (ty.isNull()) + return ty; + + // libclang does not return AttributedTypes if + // CXTranslationUnit_IncludeAttributedTypes is not set, and bindgen assumes it + // is not set. + if (auto *ATT = ty->getAs()) + return ATT->getEquivalentType(); + + // libclang does not return ParenTypes + if (auto *PTT = ty->getAs()) + return PTT->getInnerType(); + + return ty; } bool Decl_isFunctionInlined(const Decl *D) { From b8926d9b1be6aec9d07f3da40218c3bb1ce50ffd Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 17 Feb 2020 15:27:22 -0800 Subject: [PATCH 06/88] Handle null QualTypes gracefully --- src/clang/ClangAST.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 0987101244..bd3dae023a 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1640,6 +1640,8 @@ bool Type_isConstQualifiedType(QualType T) { } long long Type_getSizeOf(QualType QT, ASTContext *Context) { + if (QT.isNull()) + return CXTypeLayoutError_Invalid; // [expr.sizeof] p2: if reference type, return size of referenced type if (QT->isReferenceType()) QT = QT.getNonReferenceType(); @@ -1710,6 +1712,8 @@ static unsigned GetTemplateArgumentArraySize(ArrayRef TA) { } int Type_getNumTemplateArguments(QualType T) { + if (T.isNull()) + return -1; auto TA = GetTemplateArguments(T); if (!TA) return -1; From b02deab52b320d587d9e78d3b00db14f666e24f8 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 18 Feb 2020 16:49:14 -0800 Subject: [PATCH 07/88] Check for null in more ClangAST functions --- src/clang/ClangAST.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index bd3dae023a..912457b310 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -639,7 +639,10 @@ int Decl_getNumTemplateArguments(const Decl *D) { } CXCursorKind Decl_getCXCursorKind(const Decl *D) { - return getCursorKindForDecl(&*D); + if (!D) + return CXCursor_NoDeclFound; + else + return getCursorKindForDecl(&*D); } bool Decl_isDefinition(const Decl *D) { @@ -1378,6 +1381,9 @@ class BindgenVisitor : public RecursiveASTVisitor { } bool TraverseStmt(Stmt *S) { + if (!S) + return true; + if (Parent) { switch (VisitFn(Node(cast(S)), Parent, &AST, Data)) { case CXChildVisit_Break: @@ -1669,6 +1675,8 @@ long long Type_getSizeOf(QualType QT, ASTContext *Context) { } long long Type_getAlignOf(QualType QT, ASTContext *Context) { + if (QT.isNull()) + return CXTypeLayoutError_Invalid; // [expr.alignof] p1: return size_t value for complete object type, reference // or array. // [expr.alignof] p3: if reference type, return size of referenced type From 7fb94d1610a360371ccf8f8ba41077d917ec84ab Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 18 Feb 2020 16:49:31 -0800 Subject: [PATCH 08/88] Return the first type that matches in getType --- src/clang/ClangAST.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 912457b310..0a406aa73c 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -685,19 +685,18 @@ QualType Decl_getType(const Decl *D, ASTContext *Ctx) { if (auto *TD = dyn_cast(&*D)) ty = Ctx->getTypeDeclType(TD); - if (auto *ID = dyn_cast(&*D)) + else if (auto *ID = dyn_cast(&*D)) ty = Ctx->getObjCInterfaceType(ID); - if (auto *DD = dyn_cast(&*D)) + else if (auto *DD = dyn_cast(&*D)) ty = DD->getType(); - if (auto *VD = dyn_cast(&*D)) + else if (auto *VD = dyn_cast(&*D)) ty = VD->getType(); - if (auto *PD = dyn_cast(&*D)) + else if (auto *PD = dyn_cast(&*D)) ty = PD->getType(); - if (auto *FTD = dyn_cast(&*D)) + else if (auto *FTD = dyn_cast(&*D)) ty = FTD->getTemplatedDecl()->getType(); - - if (ty.isNull()) - return ty; + else + return QualType(); // libclang does not return AttributedTypes if // CXTranslationUnit_IncludeAttributedTypes is not set, and bindgen assumes it From 26526816ecbce28a08ebf029ef298460fc93c530 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 18 Feb 2020 16:49:48 -0800 Subject: [PATCH 09/88] Validate that we can lay out a RecordDecl before getting field offsets --- src/clang/ClangAST.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 0a406aa73c..affa931a81 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -747,11 +747,46 @@ uint64_t Decl_getEnumConstantUnsignedValue(const Decl *D) { return ULLONG_MAX; } +static bool isTypeIncompleteForLayout(QualType QT) { + return QT->isIncompleteType() && !QT->isIncompleteArrayType(); +} + +static long long visitRecordForValidation(const RecordDecl *RD) { + for (const auto *I : RD->fields()){ + QualType FQT = I->getType(); + if (isTypeIncompleteForLayout(FQT)) + return CXTypeLayoutError_Incomplete; + if (FQT->isDependentType()) + return CXTypeLayoutError_Dependent; + // recurse + if (const RecordType *ChildType = I->getType()->getAs()) { + if (const RecordDecl *Child = ChildType->getDecl()) { + long long ret = visitRecordForValidation(Child); + if (ret < 0) + return ret; + } + } + // else try next field + } + return 0; +} + long long Decl_getOffsetOfField(const Decl *D, ASTContext *Ctx) { + auto *RD = dyn_cast_or_null(D->getDeclContext()); + if (!RD) + return -1; + RD = RD->getDefinition(); + if (!RD || RD->isInvalidDecl() || !RD->isCompleteDefinition()) + return -1; + auto Err = visitRecordForValidation(RD); + if (Err < 0) + return Err; + if (auto *FD = dyn_cast_or_null(&*D)) return Ctx->getFieldOffset(FD); if (auto *IFD = dyn_cast_or_null(&*D)) return Ctx->getFieldOffset(IFD); + return -1; } From 8dd51547e8563f509a41f50adc6685441358ff12 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 18 Feb 2020 16:50:13 -0800 Subject: [PATCH 10/88] Don't visit implicit decls or CXXRecordDecl in ClassTemplates --- src/clang/ClangAST.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index affa931a81..1d4607d6db 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1395,8 +1395,22 @@ class BindgenVisitor : public RecursiveASTVisitor { public: explicit BindgenVisitor(ASTUnit &AST, Visitor V, CXClientData data) : AST(AST), VisitFn(V), Data(data) {} + bool shouldVisitImplicitCode() { + return false; + } + bool TraverseDecl(Decl *D) { - if (Parent) { + if (!D || D->isImplicit()) + return true; + + bool skip = !Parent; + + // libclang doesn't visit the CXXRecordDecl inside ClassTemplateDecl nodes + if (Parent.kind == CXCursor_ClassTemplate + && isa(D)) + skip = true; + + if (!skip) { switch (VisitFn(Node(D), Parent, &AST, Data)) { case CXChildVisit_Break: return false; From ecdbf8452a3ef43d17793f539f76b410b33df093 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 18 Feb 2020 19:14:03 -0800 Subject: [PATCH 11/88] Make ClassTemplateDecl canonical for templated classes --- src/clang/ClangAST.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 1d4607d6db..e42b11778a 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -320,6 +320,14 @@ const Decl *Decl_getSemanticParent(const Decl *D) { if (!DC) return nullptr; + // We replace CXXRecordDecl's inside ClassTemplateDecls with just the + // ClassTemplateDecl because we never expose the inner CXXRecordDecl to Rust. + if (auto *RD = dyn_cast(DC)) { + auto *ClassTemplate = RD->getDescribedClassTemplate(); + if (ClassTemplate) + return ClassTemplate; + } + return cast(DC); } From 93b975a320d02599a4d4a61a2bb9339b4f5bf84d Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 18 Feb 2020 19:14:56 -0800 Subject: [PATCH 12/88] Remove unnecessary manual implementations of PartialEq, etc. --- src/clang.rs | 55 +--------------------------------------------------- 1 file changed, 1 insertion(+), 54 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index 98cc4f9dde..fd63a090e6 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -75,7 +75,7 @@ pub struct Cursor { unit: *mut clangtool::clang_ASTUnit, } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] pub enum ASTNode { Invalid, Decl(*const clangtool::clang_Decl), @@ -83,40 +83,6 @@ pub enum ASTNode { CXXBaseSpecifier(*const clangtool::clang_CXXBaseSpecifier), } -impl PartialEq for ASTNode { - fn eq(&self, other: &ASTNode) -> bool { - match (*self, *other) { - (ASTNode::Invalid, ASTNode::Invalid) => true, - (ASTNode::Decl(d1), ASTNode::Decl(d2)) => ptr::eq(d1, d2), - (ASTNode::Expr(e1), ASTNode::Expr(e2)) => ptr::eq(e1, e2), - (ASTNode::CXXBaseSpecifier(base1), ASTNode::CXXBaseSpecifier(base2)) => ptr::eq(base1, base2), - _ => false, - } - } -} - -impl Eq for ASTNode {} - -impl Hash for ASTNode { - fn hash(&self, state: &mut H) { - match *self { - ASTNode::Invalid => state.write_u8(1), - ASTNode::Decl(d) => { - state.write_u8(2); - ptr::hash(d, state); - } - ASTNode::Expr(e) => { - state.write_u8(3); - ptr::hash(e, state); - } - ASTNode::CXXBaseSpecifier(b) => { - state.write_u8(4); - ptr::hash(b, state); - } - } - } -} - impl ASTNode { /// Is this node valid? fn is_valid(&self) -> bool { @@ -136,25 +102,6 @@ impl ASTNode { } -// impl PartialEq for clangtool::BindgenNode { -// fn eq(&self, other: &Self) -> bool { -// ptr::eq(self.node, other.node) -// && ptr::eq(self.context, other.context) -// } -// } - -// impl Eq for clangtool::BindgenNode { -// } - -// impl Hash for clangtool::BindgenNode { -// fn hash(&self, state: &mut H) -// where H: Hasher -// { -// self.node.hash(state); -// self.context.hash(state); -// } -// } - impl fmt::Debug for Cursor { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!( From ad220b0a371c90a8a333e23f3f54e4dde5729c3a Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 19 Feb 2020 13:29:46 -0800 Subject: [PATCH 13/88] Clean up visitors --- src/clang/ClangAST.cpp | 7 +++++-- src/clang/ClangAST.hpp | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index e42b11778a..10c71a6e0a 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1408,7 +1408,9 @@ class BindgenVisitor : public RecursiveASTVisitor { } bool TraverseDecl(Decl *D) { - if (!D || D->isImplicit()) + if (!D) + return false; + if (D->isImplicit()) return true; bool skip = !Parent; @@ -1438,7 +1440,8 @@ class BindgenVisitor : public RecursiveASTVisitor { bool TraverseStmt(Stmt *S) { if (!S) - return true; + return false; + if (Parent) { switch (VisitFn(Node(cast(S)), Parent, &AST, Data)) { diff --git a/src/clang/ClangAST.hpp b/src/clang/ClangAST.hpp index 66ef5b5e43..326f3ddba3 100644 --- a/src/clang/ClangAST.hpp +++ b/src/clang/ClangAST.hpp @@ -186,7 +186,6 @@ struct Node { union { const Decl *decl; const Expr *expr; - Type *type; } ptr; Node() : kind(CXCursor_NotImplemented) {} From b42adbdea169ccfea6481366bffab502cd18dc28 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 19 Feb 2020 13:30:05 -0800 Subject: [PATCH 14/88] Visit templated type locations --- src/clang/ClangAST.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 10c71a6e0a..5913eb9846 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1460,6 +1460,24 @@ class BindgenVisitor : public RecursiveASTVisitor { Parent = OldParent; return res; } + + bool TraverseTypeLoc(TypeLoc TL) { + if (!TL) + return false; + + if (auto DT = TL.getAs()) { + if (Expr *E = DT.getUnderlyingExpr()) { + if (!TraverseStmt(E)) + return false; + } + } else if (auto DT = TL.getAs()) { + if (!TraverseDecl(DT.getDecl())) + return false; + } + + bool res = RecursiveASTVisitor::TraverseTypeLoc(TL); + return res; + } }; void Decl_visitChildren(const Decl *Parent, Visitor V, ASTUnit *Unit, CXClientData data) { From 66688933f7c40cd20a7dd1891b12b4b03498c227 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 19 Feb 2020 13:50:49 -0800 Subject: [PATCH 15/88] Correctly report comment kinds --- src/clang/ClangAST.cpp | 48 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 5913eb9846..130479f451 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -2072,8 +2072,52 @@ void getSpellingLocation(ASTUnit *AST, const SourceLocation *location, FileEntry *offset = FileOffset; } -CXCommentKind Comment_getKind(const comments::Comment *) { - return CXComment_FullComment; +CXCommentKind Comment_getKind(const comments::Comment *C) { + using namespace comments; + if (!C) + return CXComment_Null; + + switch (C->getCommentKind()) { + case Comment::NoCommentKind: + return CXComment_Null; + + case Comment::TextCommentKind: + return CXComment_Text; + + case Comment::InlineCommandCommentKind: + return CXComment_InlineCommand; + + case Comment::HTMLStartTagCommentKind: + return CXComment_HTMLStartTag; + + case Comment::HTMLEndTagCommentKind: + return CXComment_HTMLEndTag; + + case Comment::ParagraphCommentKind: + return CXComment_Paragraph; + + case Comment::BlockCommandCommentKind: + return CXComment_BlockCommand; + + case Comment::ParamCommandCommentKind: + return CXComment_ParamCommand; + + case Comment::TParamCommandCommentKind: + return CXComment_TParamCommand; + + case Comment::VerbatimBlockCommentKind: + return CXComment_VerbatimBlockCommand; + + case Comment::VerbatimBlockLineCommentKind: + return CXComment_VerbatimBlockLine; + + case Comment::VerbatimLineCommentKind: + return CXComment_VerbatimLine; + + case Comment::FullCommentKind: + return CXComment_FullComment; + } + llvm_unreachable("unknown CommentKind"); } unsigned Comment_getNumChildren(const comments::Comment *C) { From a1bdd7504fb51dfb9661b97af3261dd679405602 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 19 Feb 2020 14:38:05 -0800 Subject: [PATCH 16/88] Visit more TypeLocs --- src/clang/ClangAST.cpp | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 130479f451..414a2b17c0 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1465,13 +1465,32 @@ class BindgenVisitor : public RecursiveASTVisitor { if (!TL) return false; - if (auto DT = TL.getAs()) { - if (Expr *E = DT.getUnderlyingExpr()) { - if (!TraverseStmt(E)) - return false; - } - } else if (auto DT = TL.getAs()) { - if (!TraverseDecl(DT.getDecl())) + if (auto T = TL.getAs()) { + if (!TraverseStmt(T.getUnderlyingExpr())) + return false; + } else if (auto T = TL.getAs()) { + if (!TraverseStmt(T.getUnderlyingExpr())) + return false; + } else if (auto T = TL.getAs()) { + if (!TraverseDecl(T.getTypedefNameDecl())) + return false; + } else if (auto T = TL.getAs()) { + if (!TraverseDecl(T.getDecl())) + return false; + } else if (auto T = TL.getAs()) { + if (!TraverseDecl(T.getDecl())) + return false; + } else if (auto T = TL.getAs()) { + if (!TraverseDecl(T.getDecl())) + return false; + } else if (auto T = TL.getAs()) { + if (!TraverseDecl(T.getDecl())) + return false; + } else if (auto T = TL.getAs()) { + if (!TraverseDecl(T.getDecl())) + return false; + } else if (auto T = TL.getAs()) { + if (!TraverseDecl(T.getDecl())) return false; } From f8dec454d1aec963277a94ff2604862be4dfaa79 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 19 Feb 2020 15:14:46 -0800 Subject: [PATCH 17/88] Visit CXXBaseSpecifier nodes --- src/clang.rs | 5 ++++- src/clang/ClangAST.cpp | 25 +++++++++++++++++++++++++ src/clang/ClangAST.hpp | 5 +++++ src/clang/clangtool.rs | 12 +++++++++--- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index fd63a090e6..20ee96c98b 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -459,7 +459,8 @@ impl Cursor { let x = match self.node { ASTNode::Decl(d) => clangtool::Decl_getType(d, self.context()), ASTNode::Expr(e) => clangtool::Expr_getType(e), - _ => mem::zeroed(), + ASTNode::CXXBaseSpecifier(base) => clangtool::CXXBaseSpecifier_getType(base), + ASTNode::Invalid => mem::zeroed(), }; Type { x, unit: self.unit } } @@ -1112,6 +1113,8 @@ where ASTNode::Decl(node.ptr.decl) } else if node.kind >= CXCursor_FirstExpr && node.kind <= CXCursor_LastExpr { ASTNode::Expr(node.ptr.expr) + } else if node.kind == CXCursor_CXXBaseSpecifier { + ASTNode::CXXBaseSpecifier(node.ptr.base) } else { return CXChildVisit_Recurse; }; diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 414a2b17c0..fb5db90784 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1497,6 +1497,25 @@ class BindgenVisitor : public RecursiveASTVisitor { bool res = RecursiveASTVisitor::TraverseTypeLoc(TL); return res; } + + bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) { + if (Parent) { + switch (VisitFn(Node(&Base), Parent, &AST, Data)) { + case CXChildVisit_Break: + return false; + case CXChildVisit_Continue: + return true; + case CXChildVisit_Recurse: + break; + } + } + + auto OldParent = Parent; + Parent = Node(&Base); + bool res = RecursiveASTVisitor::TraverseCXXBaseSpecifier(Base); + Parent = OldParent; + return res; + } }; void Decl_visitChildren(const Decl *Parent, Visitor V, ASTUnit *Unit, CXClientData data) { @@ -2762,3 +2781,9 @@ BindgenStringRef getClangVersion() { bool CXXBaseSpecifier_isVirtualBase(const CXXBaseSpecifier *B) { return B && B->isVirtual(); } + +QualType CXXBaseSpecifier_getType(const CXXBaseSpecifier *B) { + if (!B) + return QualType(); + return B->getType(); +} diff --git a/src/clang/ClangAST.hpp b/src/clang/ClangAST.hpp index 326f3ddba3..b03de22c48 100644 --- a/src/clang/ClangAST.hpp +++ b/src/clang/ClangAST.hpp @@ -186,6 +186,7 @@ struct Node { union { const Decl *decl; const Expr *expr; + const CXXBaseSpecifier *base; } ptr; Node() : kind(CXCursor_NotImplemented) {} @@ -195,6 +196,9 @@ struct Node { Node(const Expr *expr) : kind(Expr_getCXCursorKind(expr)) { ptr.expr = expr; } + Node(const CXXBaseSpecifier *base) : kind(CXCursor_CXXBaseSpecifier) { + ptr.base = base; + } operator bool() const { return kind != CXCursor_NotImplemented; } @@ -250,3 +254,4 @@ BindgenStringRef FileEntry_getName(FileEntry *); BindgenStringRef getClangVersion(); bool CXXBaseSpecifier_isVirtualBase(const CXXBaseSpecifier *); +QualType CXXBaseSpecifier_getType(const CXXBaseSpecifier *); diff --git a/src/clang/clangtool.rs b/src/clang/clangtool.rs index 0694faa433..c356aa27f9 100644 --- a/src/clang/clangtool.rs +++ b/src/clang/clangtool.rs @@ -6847,7 +6847,7 @@ pub struct Node { pub union Node__bindgen_ty_1 { pub decl: *const clang_Decl, pub expr: *const clang_Expr, - pub type_: *mut clang_Type, + pub base: *const clang_CXXBaseSpecifier, _bindgen_union_align: u64, } #[test] @@ -6890,7 +6890,7 @@ fn bindgen_test_layout_Node__bindgen_ty_1() { ); assert_eq!( unsafe { - &(*(::std::ptr::null::())).type_ as *const _ + &(*(::std::ptr::null::())).base as *const _ as usize }, 0usize, @@ -6898,7 +6898,7 @@ fn bindgen_test_layout_Node__bindgen_ty_1() { "Offset of field: ", stringify!(Node__bindgen_ty_1), "::", - stringify!(type_) + stringify!(base) ) ); } @@ -7153,6 +7153,12 @@ extern "C" { arg1: *const clang_CXXBaseSpecifier, ) -> bool; } +extern "C" { + #[link_name = "\u{1}_Z24CXXBaseSpecifier_getTypePKN5clang16CXXBaseSpecifierE"] + pub fn CXXBaseSpecifier_getType( + arg1: *const clang_CXXBaseSpecifier, + ) -> clang_QualType; +} #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct __locale_data { From 1618ffcc98159a83d9994cf7823b52687263e3ce Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 19 Feb 2020 17:58:31 -0800 Subject: [PATCH 18/88] Clean up warning --- src/clang.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index 20ee96c98b..8901bd2858 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -10,7 +10,6 @@ use regex; use std::ffi::{CStr, CString}; use std::fmt; use std::hash::Hash; -use std::hash::Hasher; use std::os::raw::{c_char, c_int, c_longlong, c_uint, c_ulong, c_ulonglong}; use std::{mem, ptr, slice}; @@ -99,7 +98,6 @@ impl ASTNode { } } } - } impl fmt::Debug for Cursor { From 9ce79396f0faac54037a685b2c6fad27fbc8e913 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 19 Feb 2020 18:00:23 -0800 Subject: [PATCH 19/88] Add Attr to node and track node kinds correctly Added some misc CXXBaseSpecifier accessors and fixed visiting CXXBaseSpecifiers --- src/clang.rs | 117 ++++++++++++++------------- src/clang/ClangAST.cpp | 179 ++++++++++++++++++++++++++++++++--------- src/clang/ClangAST.hpp | 45 ++++------- src/clang/clangtool.rs | 50 ++++++++++++ 4 files changed, 265 insertions(+), 126 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index 8901bd2858..1e8694ae5e 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -71,6 +71,7 @@ impl fmt::Display for clangtool::BindgenStringRef { #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Cursor { node: ASTNode, + kind: CXCursorKind, unit: *mut clangtool::clang_ASTUnit, } @@ -80,6 +81,7 @@ pub enum ASTNode { Decl(*const clangtool::clang_Decl), Expr(*const clangtool::clang_Expr), CXXBaseSpecifier(*const clangtool::clang_CXXBaseSpecifier), + Attr(*const clangtool::clang_Attr), } impl ASTNode { @@ -93,8 +95,9 @@ impl ASTNode { match *self { ASTNode::Decl(d) => clangtool::Decl_getCXCursorKind(d), ASTNode::Expr(e) => clangtool::Expr_getCXCursorKind(e), - ASTNode::Invalid => CXCursor_InvalidFile, ASTNode::CXXBaseSpecifier(_) => CXCursor_CXXBaseSpecifier, + ASTNode::Attr(a) => clangtool::Attr_getCXCursorKind(a), + ASTNode::Invalid => CXCursor_InvalidFile, } } } @@ -114,6 +117,18 @@ impl fmt::Debug for Cursor { } impl Cursor { + fn new(node: ASTNode, unit: *mut clangtool::clang_ASTUnit) -> Self { + Self { + node, + kind: node.kind(), + unit, + } + } + + fn with_node(&self, node: ASTNode) -> Self { + Self::new(node, self.unit) + } + fn context(&self) -> *mut clangtool::clang_ASTContext { unsafe { clangtool::ASTUnit_getContext(self.unit) } } @@ -151,6 +166,8 @@ impl Cursor { match self.node { ASTNode::Decl(d) => clangtool::Decl_getSpelling(d).to_string(), ASTNode::Expr(e) => clangtool::Expr_getSpelling(e).to_string(), + ASTNode::CXXBaseSpecifier(b) => clangtool::CXXBaseSpecifier_getSpelling(b) + .to_string(), _ => String::new(), } } @@ -230,10 +247,7 @@ impl Cursor { }, _ => ASTNode::Invalid, }; - Cursor { - node, - unit: self.unit, - } + self.with_node(node) } /// Get the referent's semantic parent, if one is available. @@ -251,10 +265,7 @@ impl Cursor { if node == self.node || !node.is_valid() { return None; } - Some(Cursor { - node, - unit: self.unit, - }) + Some(self.with_node(node)) } /// Get the referent's semantic parent. @@ -328,12 +339,9 @@ impl Cursor { semantic_parent.unwrap().fallible_semantic_parent(); } - let tu = Cursor { - node: ASTNode::Decl(unsafe { - clangtool::getTranslationUnitDecl(self.unit) - }), - unit: self.unit, - }; + let tu = self.with_node(ASTNode::Decl(unsafe { + clangtool::getTranslationUnitDecl(self.unit) + })); // Yes, this can happen with, e.g., macro definitions. semantic_parent == tu.fallible_semantic_parent() } @@ -352,7 +360,7 @@ impl Cursor { /// Get the kind of referent this cursor is pointing to. pub fn kind(&self) -> CXCursorKind { - self.node.kind() + self.kind } /// Returns true is the cursor is a definition @@ -408,7 +416,9 @@ impl Cursor { let x = match self.node { ASTNode::Decl(d) => clangtool::Decl_getLocation(d), ASTNode::Expr(e) => clangtool::Expr_getLocation(e), - _ => ptr::null(), + ASTNode::CXXBaseSpecifier(b) => clangtool::CXXBaseSpecifier_getLocation(b), + ASTNode::Attr(b) => clangtool::Attr_getLocation(b), + ASTNode::Invalid => ptr::null(), }; SourceLocation { x, unit: self.unit } } @@ -458,7 +468,7 @@ impl Cursor { ASTNode::Decl(d) => clangtool::Decl_getType(d, self.context()), ASTNode::Expr(e) => clangtool::Expr_getType(e), ASTNode::CXXBaseSpecifier(base) => clangtool::CXXBaseSpecifier_getType(base), - ASTNode::Invalid => mem::zeroed(), + _ => mem::zeroed(), }; Type { x, unit: self.unit } } @@ -477,10 +487,7 @@ impl Cursor { if def.is_null() { None } else { - Some(Cursor { - node: ASTNode::Decl(def), - unit: self.unit, - }) + Some(self.with_node(ASTNode::Decl(def))) } } @@ -493,10 +500,7 @@ impl Cursor { if ptr.is_null() { None } else { - Some(Cursor { - node: ASTNode::Decl(ptr), - unit: self.unit, - }) + Some(self.with_node(ASTNode::Decl(ptr))) } }, _ => return None, @@ -515,10 +519,7 @@ impl Cursor { }, _ => ASTNode::Invalid, }; - Cursor { - node, - unit: self.unit, - } + self.with_node(node) } /// Given that this cursor points to either a template specialization or a @@ -531,10 +532,7 @@ impl Cursor { if ptr.is_null() { None } else { - Some(Cursor { - node: ASTNode::Decl(ptr), - unit: self.unit, - }) + Some(self.with_node(ASTNode::Decl(ptr))) } }, _ => None, @@ -576,7 +574,15 @@ impl Cursor { mem::transmute(&mut visitor), ); } - _ => {} + ASTNode::CXXBaseSpecifier(b) => unsafe { + clangtool::CXXBaseSpecifier_visitChildren( + b, + Some(visit_children::), + self.unit, + mem::transmute(&mut visitor), + ); + } + _ => panic!("Tried to visit: {:?}", self), } } @@ -781,10 +787,7 @@ impl Cursor { }, _ => ASTNode::Invalid, }; - Cursor { - node, - unit: self.unit, - } + self.with_node(node) }) .collect() }) @@ -1096,7 +1099,7 @@ pub fn is_valid_identifier(name: &str) -> bool { } unsafe extern "C" fn visit_children( - node: clangtool::Node, + raw_node: clangtool::Node, _parent: clangtool::Node, unit: *mut clangtool::clang_ASTUnit, data: clangtool::CXClientData, @@ -1105,19 +1108,23 @@ where Visitor: FnMut(Cursor) -> CXChildVisitResult, { let func: &mut Visitor = mem::transmute(data); - let node = if (node.kind >= CXCursor_FirstDecl && node.kind <= CXCursor_LastDecl) - || (node.kind >= CXCursor_FirstExtraDecl && node.kind <= CXCursor_LastExtraDecl) + let node = if (raw_node.kind >= CXCursor_FirstDecl && raw_node.kind <= CXCursor_LastDecl) + || (raw_node.kind >= CXCursor_FirstExtraDecl && raw_node.kind <= CXCursor_LastExtraDecl) + || raw_node.kind == CXCursor_TypeRef { - ASTNode::Decl(node.ptr.decl) - } else if node.kind >= CXCursor_FirstExpr && node.kind <= CXCursor_LastExpr { - ASTNode::Expr(node.ptr.expr) - } else if node.kind == CXCursor_CXXBaseSpecifier { - ASTNode::CXXBaseSpecifier(node.ptr.base) + ASTNode::Decl(raw_node.ptr.decl) + } else if raw_node.kind >= CXCursor_FirstExpr && raw_node.kind <= CXCursor_LastExpr { + ASTNode::Expr(raw_node.ptr.expr) + } else if raw_node.kind == CXCursor_CXXBaseSpecifier { + ASTNode::CXXBaseSpecifier(raw_node.ptr.base) + } else if raw_node.kind >= CXCursor_FirstAttr && raw_node.kind <= CXCursor_LastAttr { + ASTNode::Attr(raw_node.ptr.attr) } else { return CXChildVisit_Recurse; }; let child = Cursor { node, + kind: raw_node.kind, unit, }; @@ -1200,10 +1207,10 @@ impl Type { /// Get a cursor pointing to this type's declaration. pub fn declaration(&self) -> Cursor { unsafe { - Cursor { - node: ASTNode::Decl(clangtool::Type_getDeclaration(self.x)), - unit: self.unit, - } + Cursor::new( + ASTNode::Decl(clangtool::Type_getDeclaration(self.x)), + self.unit, + ) } } @@ -1870,10 +1877,10 @@ impl TranslationUnit { /// Get a cursor pointing to the root of this translation unit's AST. pub fn cursor(&self) -> Cursor { unsafe { - Cursor { - node: ASTNode::Decl(clangtool::getTranslationUnitDecl(self.x)), - unit: self.x, - } + Cursor::new( + ASTNode::Decl(clangtool::getTranslationUnitDecl(self.x)), + self.x, + ) } } diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index fb5db90784..518099047d 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -124,8 +124,9 @@ ASTUnit *parseTranslationUnit(const char *source_filename, const char *const *command_line_args, int num_command_line_args, int options) { - - ArrayRef Args(command_line_args, num_command_line_args); + SmallVector Args; + Args.push_back("clang"); + Args.append(command_line_args, command_line_args + num_command_line_args); // Configure the diagnostics. IntrusiveRefCntPtr @@ -231,6 +232,8 @@ EvalResult *Decl_Evaluate(const Decl *D, ASTContext *Ctx) { } CXEvalResultKind EvalResult_getKind(EvalResult *ER) { + if (!ER) + return CXEval_UnExposed; return ER->EvalType; } @@ -686,6 +689,20 @@ comments::Comment *Decl_getParsedComment(const Decl *D, ASTContext *Ctx) { return Ctx->getCommentForDecl(&*D, /*PP=*/nullptr); } +static QualType make_type_compatible(QualType QT) { + // libclang does not return AttributedTypes if + // CXTranslationUnit_IncludeAttributedTypes is not set, and bindgen assumes it + // is not set. + if (auto *ATT = QT->getAs()) + return ATT->getEquivalentType(); + + // libclang does not return ParenTypes + if (auto *PTT = QT->getAs()) + return PTT->getInnerType(); + + return QT; +} + QualType Decl_getType(const Decl *D, ASTContext *Ctx) { auto ty = QualType(); if (!D) @@ -706,17 +723,7 @@ QualType Decl_getType(const Decl *D, ASTContext *Ctx) { else return QualType(); - // libclang does not return AttributedTypes if - // CXTranslationUnit_IncludeAttributedTypes is not set, and bindgen assumes it - // is not set. - if (auto *ATT = ty->getAs()) - return ATT->getEquivalentType(); - - // libclang does not return ParenTypes - if (auto *PTT = ty->getAs()) - return PTT->getInnerType(); - - return ty; + return make_type_compatible(ty); } bool Decl_isFunctionInlined(const Decl *D) { @@ -736,7 +743,7 @@ int Decl_getFieldDeclBitWidth(const Decl *D, ASTContext *Ctx) { QualType Decl_getEnumDeclIntegerType(const Decl *D) { if (auto *TD = dyn_cast_or_null(&*D)) - return TD->getIntegerType(); + return make_type_compatible(TD->getIntegerType()); else return QualType(); } @@ -804,7 +811,7 @@ BindgenSourceRange Decl_getSourceRange(const Decl *D) { QualType Decl_getTypedefDeclUnderlyingType(const Decl *D) { if (auto *TD = dyn_cast_or_null(&*D)) - return TD->getUnderlyingType(); + return make_type_compatible(TD->getUnderlyingType()); else return QualType(); } @@ -890,7 +897,7 @@ bool CXXMethod_isPureVirtual(const Decl *D) { QualType Decl_getResultType(const Decl *D, ASTContext *Ctx) { if (auto *FT = Decl_getType(D, Ctx)->getAs()) - return FT->getReturnType(); + return make_type_compatible(FT->getReturnType()); else return QualType(); } @@ -1330,7 +1337,7 @@ SourceLocation *Expr_getLocation(const Expr *E) { return new SourceLocation(E->getBeginLoc()); } -QualType Expr_getType(const Expr *E) { return E->getType(); } +QualType Expr_getType(const Expr *E) { return make_type_compatible(E->getType()); } BindgenSourceRange Expr_getSourceRange(const Expr *E) { return BindgenSourceRange(E->getSourceRange()); @@ -1407,7 +1414,7 @@ class BindgenVisitor : public RecursiveASTVisitor { return false; } - bool TraverseDecl(Decl *D) { + bool TraverseDeclTyped(Decl *D, CXCursorKind kind) { if (!D) return false; if (D->isImplicit()) @@ -1420,8 +1427,10 @@ class BindgenVisitor : public RecursiveASTVisitor { && isa(D)) skip = true; + // D->dump(); + Node node(D, kind); if (!skip) { - switch (VisitFn(Node(D), Parent, &AST, Data)) { + switch (VisitFn(node, Parent, &AST, Data)) { case CXChildVisit_Break: return false; case CXChildVisit_Continue: @@ -1432,19 +1441,24 @@ class BindgenVisitor : public RecursiveASTVisitor { } auto OldParent = Parent; - Parent = Node(D); + Parent = node; bool res = RecursiveASTVisitor::TraverseDecl(D); Parent = OldParent; return res; } - bool TraverseStmt(Stmt *S) { + bool TraverseDecl(Decl *D) { + return TraverseDeclTyped(D, Decl_getCXCursorKind(D)); + } + + bool TraverseStmtTyped(Stmt *S, CXCursorKind kind) { if (!S) return false; - + Node node(cast(S), kind); if (Parent) { - switch (VisitFn(Node(cast(S)), Parent, &AST, Data)) { + // S->dump(); + switch (VisitFn(node, Parent, &AST, Data)) { case CXChildVisit_Break: return false; case CXChildVisit_Continue: @@ -1455,16 +1469,24 @@ class BindgenVisitor : public RecursiveASTVisitor { } auto OldParent = Parent; - Parent = Node(cast(S)); + Parent = node; bool res = RecursiveASTVisitor::TraverseStmt(S); Parent = OldParent; return res; } + bool TraverseStmt(Stmt *S) { + if (!S) + return false; + return TraverseStmtTyped(S, Expr_getCXCursorKind(cast(S))); + } + bool TraverseTypeLoc(TypeLoc TL) { if (!TL) return false; + // TL.getType().dump(); + if (auto T = TL.getAs()) { if (!TraverseStmt(T.getUnderlyingExpr())) return false; @@ -1472,25 +1494,30 @@ class BindgenVisitor : public RecursiveASTVisitor { if (!TraverseStmt(T.getUnderlyingExpr())) return false; } else if (auto T = TL.getAs()) { - if (!TraverseDecl(T.getTypedefNameDecl())) + if (!TraverseDeclTyped(T.getTypedefNameDecl(), CXCursor_TypeRef)) return false; } else if (auto T = TL.getAs()) { - if (!TraverseDecl(T.getDecl())) + if (!TraverseDeclTyped(T.getDecl(), CXCursor_TypeRef)) return false; } else if (auto T = TL.getAs()) { - if (!TraverseDecl(T.getDecl())) + if (!TraverseDeclTyped(T.getDecl(), CXCursor_TypeRef)) return false; } else if (auto T = TL.getAs()) { - if (!TraverseDecl(T.getDecl())) - return false; + if (T.isDefinition()) { + if (!TraverseDecl(T.getDecl())) + return false; + } else { + if (!TraverseDeclTyped(T.getDecl(), CXCursor_TypeRef)) + return false; + } } else if (auto T = TL.getAs()) { - if (!TraverseDecl(T.getDecl())) + if (!TraverseDeclTyped(T.getDecl(), CXCursor_TypeRef)) return false; } else if (auto T = TL.getAs()) { - if (!TraverseDecl(T.getDecl())) + if (!TraverseDeclTyped(T.getDecl(), CXCursor_TypeRef)) return false; } else if (auto T = TL.getAs()) { - if (!TraverseDecl(T.getDecl())) + if (!TraverseDeclTyped(T.getDecl(), CXCursor_TypeRef)) return false; } @@ -1516,6 +1543,12 @@ class BindgenVisitor : public RecursiveASTVisitor { Parent = OldParent; return res; } + + bool VisitAttr(Attr *A) { + if (Parent) + VisitFn(Node(A), Parent, &AST, Data); + return true; + } }; void Decl_visitChildren(const Decl *Parent, Visitor V, ASTUnit *Unit, CXClientData data) { @@ -1526,6 +1559,10 @@ void Expr_visitChildren(const Expr *Parent, Visitor V, ASTUnit *Unit, CXClientDa BindgenVisitor visitor(*Unit, V, data); visitor.TraverseStmt(const_cast(&*Parent)); } +void CXXBaseSpecifier_visitChildren(const CXXBaseSpecifier *Parent, Visitor V, ASTUnit *Unit, CXClientData data) { + BindgenVisitor visitor(*Unit, V, data); + visitor.TraverseCXXBaseSpecifier(*Parent); +} void tokenize(ASTUnit *TU, BindgenSourceRange Range, CXToken **Tokens, unsigned *NumTokens) { @@ -1853,7 +1890,7 @@ QualType Type_getArgType(QualType T, unsigned i) { if (i >= numParams) return QualType(); - return FD->getParamType(i); + return make_type_compatible(FD->getParamType(i)); } return QualType(); @@ -1908,7 +1945,7 @@ QualType Type_getPointeeType(QualType T) { T = QualType(); break; } - return T; + return make_type_compatible(T); } QualType Type_getElementType(QualType T) { @@ -1942,7 +1979,7 @@ QualType Type_getElementType(QualType T) { break; } } - return ET; + return make_type_compatible(ET); } int Type_getNumElements(QualType T) { @@ -1971,7 +2008,7 @@ QualType Type_getCanonicalType(QualType T, ASTContext *Context) { if (T.isNull()) return QualType(); - return Context->getCanonicalType(T); + return make_type_compatible(Context->getCanonicalType(T)); } bool Type_isFunctionTypeVariadic(QualType T) { @@ -1992,7 +2029,7 @@ QualType Type_getResultType(QualType T) { return QualType(); if (const FunctionType *FD = T->getAs()) - return FD->getReturnType(); + return make_type_compatible(FD->getReturnType()); return QualType(); } @@ -2034,7 +2071,7 @@ QualType Type_getNamedType(QualType T) { const Type *TP = T.getTypePtrOrNull(); if (TP && TP->getTypeClass() == Type::Elaborated) - return cast(TP)->getNamedType(); + return make_type_compatible(cast(TP)->getNamedType()); return QualType(); } @@ -2071,7 +2108,7 @@ QualType Type_getTemplateArgumentAsType(QualType T, unsigned index) { return QualType(); Optional QT = FindTemplateArgumentTypeAt(TA.getValue(), index); - return QT.getValueOr(QualType()); + return make_type_compatible(QT.getValueOr(QualType())); } static void createNullLocation(FileEntry **file, int *line, @@ -2785,5 +2822,67 @@ bool CXXBaseSpecifier_isVirtualBase(const CXXBaseSpecifier *B) { QualType CXXBaseSpecifier_getType(const CXXBaseSpecifier *B) { if (!B) return QualType(); - return B->getType(); + return make_type_compatible(B->getType()); +} + +CXCursorKind Attr_getCXCursorKind(const Attr *A) { + assert(A && "Invalid arguments!"); + switch (A->getKind()) { + default: break; + case attr::IBAction: return CXCursor_IBActionAttr; + case attr::IBOutlet: return CXCursor_IBOutletAttr; + case attr::IBOutletCollection: return CXCursor_IBOutletCollectionAttr; + case attr::Final: return CXCursor_CXXFinalAttr; + case attr::Override: return CXCursor_CXXOverrideAttr; + case attr::Annotate: return CXCursor_AnnotateAttr; + case attr::AsmLabel: return CXCursor_AsmLabelAttr; + case attr::Packed: return CXCursor_PackedAttr; + case attr::Pure: return CXCursor_PureAttr; + case attr::Const: return CXCursor_ConstAttr; + case attr::NoDuplicate: return CXCursor_NoDuplicateAttr; + case attr::CUDAConstant: return CXCursor_CUDAConstantAttr; + case attr::CUDADevice: return CXCursor_CUDADeviceAttr; + case attr::CUDAGlobal: return CXCursor_CUDAGlobalAttr; + case attr::CUDAHost: return CXCursor_CUDAHostAttr; + case attr::CUDAShared: return CXCursor_CUDASharedAttr; + case attr::Visibility: return CXCursor_VisibilityAttr; + case attr::DLLExport: return CXCursor_DLLExport; + case attr::DLLImport: return CXCursor_DLLImport; + case attr::NSReturnsRetained: return CXCursor_NSReturnsRetained; + case attr::NSReturnsNotRetained: return CXCursor_NSReturnsNotRetained; + case attr::NSReturnsAutoreleased: return CXCursor_NSReturnsAutoreleased; + case attr::NSConsumesSelf: return CXCursor_NSConsumesSelf; + case attr::NSConsumed: return CXCursor_NSConsumed; + case attr::ObjCException: return CXCursor_ObjCException; + case attr::ObjCNSObject: return CXCursor_ObjCNSObject; + case attr::ObjCIndependentClass: return CXCursor_ObjCIndependentClass; + case attr::ObjCPreciseLifetime: return CXCursor_ObjCPreciseLifetime; + case attr::ObjCReturnsInnerPointer: return CXCursor_ObjCReturnsInnerPointer; + case attr::ObjCRequiresSuper: return CXCursor_ObjCRequiresSuper; + case attr::ObjCRootClass: return CXCursor_ObjCRootClass; + case attr::ObjCSubclassingRestricted: return CXCursor_ObjCSubclassingRestricted; + case attr::ObjCExplicitProtocolImpl: return CXCursor_ObjCExplicitProtocolImpl; + case attr::ObjCDesignatedInitializer: return CXCursor_ObjCDesignatedInitializer; + case attr::ObjCRuntimeVisible: return CXCursor_ObjCRuntimeVisible; + case attr::ObjCBoxable: return CXCursor_ObjCBoxable; + case attr::FlagEnum: return CXCursor_FlagEnum; + case attr::Convergent: return CXCursor_ConvergentAttr; + case attr::WarnUnused: return CXCursor_WarnUnusedAttr; + case attr::WarnUnusedResult: return CXCursor_WarnUnusedResultAttr; + case attr::Aligned: return CXCursor_AlignedAttr; + } + + return CXCursor_UnexposedAttr; +} + +BindgenStringRef CXXBaseSpecifier_getSpelling(const CXXBaseSpecifier *B) { + return stringref(B->getType().getAsString()); +} + +SourceLocation *CXXBaseSpecifier_getLocation(const CXXBaseSpecifier *B) { + return new SourceLocation(B->getBaseTypeLoc()); +} + +SourceLocation *Attr_getLocation(const Attr *A) { + return new SourceLocation(A->getLocation()); } diff --git a/src/clang/ClangAST.hpp b/src/clang/ClangAST.hpp index b03de22c48..ca6bf054e5 100644 --- a/src/clang/ClangAST.hpp +++ b/src/clang/ClangAST.hpp @@ -20,6 +20,7 @@ struct SourceLocation; struct CXXBaseSpecifier; struct ASTContext; struct SourceRange; +struct Attr; namespace comments { struct Comment; @@ -32,35 +33,6 @@ struct EvalResult; using namespace clang; -// template -// struct BindgenNode { -// const T *node; -// ASTUnit *unit; - -// BindgenNode() = default; -// BindgenNode(const T *node, ASTUnit *unit) : node(node), unit(unit) {} - -// BindgenNode makeDeclNode(const Decl *newNode) { -// return BindgenNode(newNode, unit); -// } - -// BindgenNode makeExprNode(const Expr *newNode) { -// return BindgenNode(newNode, unit); -// } - -// operator bool() const { -// return node != nullptr; -// } - -// const T *operator->() const { -// return node; -// } - -// const T &operator*() const { -// return *node; -// } -// }; - struct BindgenStringRef { char *s; size_t len; @@ -180,6 +152,8 @@ BindgenSourceRange Expr_getSourceRange(const Expr *E); const Decl *Type_getDeclaration(QualType); +CXCursorKind Attr_getCXCursorKind(const Attr *); + struct Node { CXCursorKind kind; @@ -187,18 +161,22 @@ struct Node { const Decl *decl; const Expr *expr; const CXXBaseSpecifier *base; + const Attr *attr; } ptr; Node() : kind(CXCursor_NotImplemented) {} - Node(const Decl *decl) : kind(Decl_getCXCursorKind(decl)) { + Node(const Decl *decl, CXCursorKind kind) : kind(kind) { ptr.decl = decl; } - Node(const Expr *expr) : kind(Expr_getCXCursorKind(expr)) { + Node(const Expr *expr, CXCursorKind kind) : kind(kind) { ptr.expr = expr; } Node(const CXXBaseSpecifier *base) : kind(CXCursor_CXXBaseSpecifier) { ptr.base = base; } + Node(const Attr *attr) : kind(Attr_getCXCursorKind(attr)) { + ptr.attr = attr; + } operator bool() const { return kind != CXCursor_NotImplemented; } @@ -210,6 +188,8 @@ typedef CXChildVisitResult (*Visitor)(Node N, Node parent, void Decl_visitChildren(const Decl *Parent, Visitor V, ASTUnit *Unit, CXClientData data); void Expr_visitChildren(const Expr *Parent, Visitor V, ASTUnit *Unit, CXClientData data); +void CXXBaseSpecifier_visitChildren(const CXXBaseSpecifier *Parent, Visitor V, + ASTUnit *Unit, CXClientData data); void tokenize(ASTUnit *TU, BindgenSourceRange Range, CXToken **Tokens, unsigned *NumTokens); @@ -255,3 +235,6 @@ BindgenStringRef getClangVersion(); bool CXXBaseSpecifier_isVirtualBase(const CXXBaseSpecifier *); QualType CXXBaseSpecifier_getType(const CXXBaseSpecifier *); +BindgenStringRef CXXBaseSpecifier_getSpelling(const CXXBaseSpecifier *); +SourceLocation *CXXBaseSpecifier_getLocation(const CXXBaseSpecifier *); +SourceLocation *Attr_getLocation(const Attr *); diff --git a/src/clang/clangtool.rs b/src/clang/clangtool.rs index c356aa27f9..f9f2657724 100644 --- a/src/clang/clangtool.rs +++ b/src/clang/clangtool.rs @@ -6271,6 +6271,11 @@ pub struct clang_SourceRange { } #[repr(C)] #[derive(Debug, Copy, Clone)] +pub struct clang_Attr { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] pub struct clang_comments_Comment { _unused: [u8; 0], } @@ -6836,6 +6841,10 @@ extern "C" { #[link_name = "\u{1}_Z19Type_getDeclarationN5clang8QualTypeE"] pub fn Type_getDeclaration(arg1: clang_QualType) -> *const clang_Decl; } +extern "C" { + #[link_name = "\u{1}_Z20Attr_getCXCursorKindPKN5clang4AttrE"] + pub fn Attr_getCXCursorKind(arg1: *const clang_Attr) -> CXCursorKind::Type; +} #[repr(C)] #[derive(Copy, Clone)] pub struct Node { @@ -6848,6 +6857,7 @@ pub union Node__bindgen_ty_1 { pub decl: *const clang_Decl, pub expr: *const clang_Expr, pub base: *const clang_CXXBaseSpecifier, + pub attr: *const clang_Attr, _bindgen_union_align: u64, } #[test] @@ -6901,6 +6911,19 @@ fn bindgen_test_layout_Node__bindgen_ty_1() { stringify!(base) ) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).attr as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(Node__bindgen_ty_1), + "::", + stringify!(attr) + ) + ); } #[test] fn bindgen_test_layout_Node() { @@ -6956,6 +6979,15 @@ extern "C" { data: CXClientData, ); } +extern "C" { + #[link_name = "\u{1}_Z30CXXBaseSpecifier_visitChildrenPKN5clang16CXXBaseSpecifierEPF18CXChildVisitResult4NodeS4_PNS_7ASTUnitEPvES6_S7_"] + pub fn CXXBaseSpecifier_visitChildren( + Parent: *const clang_CXXBaseSpecifier, + V: Visitor, + Unit: *mut clang_ASTUnit, + data: CXClientData, + ); +} extern "C" { #[link_name = "\u{1}_Z8tokenizePN5clang7ASTUnitE18BindgenSourceRangePP7CXTokenPj"] pub fn tokenize( @@ -7159,6 +7191,24 @@ extern "C" { arg1: *const clang_CXXBaseSpecifier, ) -> clang_QualType; } +extern "C" { + #[link_name = "\u{1}_Z28CXXBaseSpecifier_getSpellingPKN5clang16CXXBaseSpecifierE"] + pub fn CXXBaseSpecifier_getSpelling( + arg1: *const clang_CXXBaseSpecifier, + ) -> BindgenStringRef; +} +extern "C" { + #[link_name = "\u{1}_Z28CXXBaseSpecifier_getLocationPKN5clang16CXXBaseSpecifierE"] + pub fn CXXBaseSpecifier_getLocation( + arg1: *const clang_CXXBaseSpecifier, + ) -> *mut clang_SourceLocation; +} +extern "C" { + #[link_name = "\u{1}_Z16Attr_getLocationPKN5clang4AttrE"] + pub fn Attr_getLocation( + arg1: *const clang_Attr, + ) -> *mut clang_SourceLocation; +} #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct __locale_data { From e883c52278ccb5b017d8fb31e68d6b0560751afa Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 10:41:42 -0800 Subject: [PATCH 20/88] Build stringref from llvm::StringRef Needed for compatibility with latest Clang --- src/clang/ClangAST.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 518099047d..da138777be 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -43,6 +43,15 @@ BindgenStringRef stringref(const std::string &s) { return stringref(s.c_str()); } +BindgenStringRef stringref(llvm::StringRef S) { + BindgenStringRef ref; + ref.len = S.size(); + ref.s = new char[ref.len + 1]; + strncpy(ref.s, S.data(), ref.len); + ref.s[ref.len] = '\0'; + return ref; +} + // From libclang/CIndex.cpp static const Decl *getDeclFromExpr(const Stmt *E) { if (const ImplicitCastExpr *CE = dyn_cast(E)) From 0317bfa5951c235fe0f2da9fa79da6cc8c6e7a84 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 11:17:20 -0800 Subject: [PATCH 21/88] Support building against latest LLVM master --- build.rs | 18 +++++++++++++++++- src/clang/CMakeLists.txt | 4 +--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/build.rs b/build.rs index bdfa777120..528977e89e 100644 --- a/build.rs +++ b/build.rs @@ -306,6 +306,7 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: "ProfileData", "BinaryFormat", "Core", + "FrontendOpenMP", ], ) .unwrap_or("-lLLVM".to_string()) @@ -325,7 +326,22 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: )) .unwrap_or(String::new()) .split_whitespace() - .map(|lib| String::from(lib.trim_start_matches("-l"))) + .map(|lib| { + if lib.starts_with("-l") { + lib[2..].to_string() + } else { + // Sometimes llvm-config gives us an absolute path + // to the library, and I can't figure out a way to + // give an absolute path of a library to rustc. + Path::new(lib) + .file_stem() + .unwrap() + .to_str() + .unwrap() + .trim_start_matches("lib") + .into() + } + }) ); Self { diff --git a/src/clang/CMakeLists.txt b/src/clang/CMakeLists.txt index 3b36cba192..3565fc30ad 100644 --- a/src/clang/CMakeLists.txt +++ b/src/clang/CMakeLists.txt @@ -9,7 +9,6 @@ if( PROJECT_NAME STREQUAL "LLVM" ) # We are building in-tree, we can use LLVM cmake functions add_definitions(-DCLANG_BIN_PATH="${CMAKE_INSTALL_PREFIX}/bin") - add_definitions(-DCLANG_VERSION_STRING="${PACKAGE_VERSION}") add_clang_library(clangAst ${SRCS} DEPENDS clang-headers) @@ -34,7 +33,6 @@ else() else() message(FATAL_ERROR "Cannot find path to clang binary") endif() - add_definitions(-DCLANG_VERSION_STRING="${LLVM_PACKAGE_VERSION}") set(LLVM_LINK_COMPONENTS support) @@ -48,7 +46,7 @@ endif() add_definitions(-DCLANG_LIBDIR_SUFFIX="${LLVM_LIBDIR_SUFFIX}") set_target_properties(clangAst PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 14 CXX_EXTENSIONS OFF ) From 832820ea72d36e7edb163a28fa905928795945a1 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 11:19:05 -0800 Subject: [PATCH 22/88] Add support for visiting preprocessor entities --- src/clang.rs | 6 ++++- src/clang/ClangAST.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++ src/clang/ClangAST.hpp | 6 +++++ src/clang/clangtool.rs | 25 +++++++++++++++++++ 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/clang.rs b/src/clang.rs index 1e8694ae5e..18e83829cb 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -82,6 +82,7 @@ pub enum ASTNode { Expr(*const clangtool::clang_Expr), CXXBaseSpecifier(*const clangtool::clang_CXXBaseSpecifier), Attr(*const clangtool::clang_Attr), + PreprocessedEntity(*const clangtool::clang_PreprocessedEntity), } impl ASTNode { @@ -97,7 +98,7 @@ impl ASTNode { ASTNode::Expr(e) => clangtool::Expr_getCXCursorKind(e), ASTNode::CXXBaseSpecifier(_) => CXCursor_CXXBaseSpecifier, ASTNode::Attr(a) => clangtool::Attr_getCXCursorKind(a), - ASTNode::Invalid => CXCursor_InvalidFile, + _ => CXCursor_InvalidFile, } } } @@ -418,6 +419,7 @@ impl Cursor { ASTNode::Expr(e) => clangtool::Expr_getLocation(e), ASTNode::CXXBaseSpecifier(b) => clangtool::CXXBaseSpecifier_getLocation(b), ASTNode::Attr(b) => clangtool::Attr_getLocation(b), + ASTNode::PreprocessedEntity(p) => clangtool::PreprocessedEntity_getLocation(p), ASTNode::Invalid => ptr::null(), }; SourceLocation { x, unit: self.unit } @@ -1119,6 +1121,8 @@ where ASTNode::CXXBaseSpecifier(raw_node.ptr.base) } else if raw_node.kind >= CXCursor_FirstAttr && raw_node.kind <= CXCursor_LastAttr { ASTNode::Attr(raw_node.ptr.attr) + } else if raw_node.kind >= CXCursor_FirstPreprocessing && raw_node.kind <= CXCursor_LastPreprocessing { + ASTNode::PreprocessedEntity(raw_node.ptr.ppe) } else { return CXChildVisit_Recurse; }; diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index da138777be..0c6de65978 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -14,7 +14,9 @@ #include "clang/Basic/Version.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/CompilerInvocation.h" #include "clang/Index/USRGeneration.h" +#include "clang/Lex/PreprocessorOptions.h" #include "clang-c/Documentation.h" #include "clang-c/Index.h" @@ -152,6 +154,13 @@ ASTUnit *parseTranslationUnit(const char *source_filename, if (!Invoc) return nullptr; + auto &PPOpts = Invoc->getPreprocessorOpts(); + + if (options & CXTranslationUnit_DetailedPreprocessingRecord) { + // Tell the preprocessor to save a detailed preprocessing record + PPOpts.DetailedRecord = true; + } + return ASTUnit::LoadFromCompilerInvocationAction( std::move(Invoc), std::make_shared(), Diags); } @@ -1558,6 +1567,49 @@ class BindgenVisitor : public RecursiveASTVisitor { VisitFn(Node(A), Parent, &AST, Data); return true; } + + bool VisitTranslationUnitDecl(TranslationUnitDecl *TU) { + if (!AST.getPreprocessor().getPreprocessingRecord()) + return true; + + PreprocessingRecord &PPRec = + *AST.getPreprocessor().getPreprocessingRecord(); + SourceManager &SM = AST.getSourceManager(); + + bool OnlyLocalDecls = !AST.isMainFileAST() && AST.getOnlyLocalDecls(); + + if (OnlyLocalDecls) + return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(), + PPRec); + + return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec); + } + +private: + template + bool visitPreprocessedEntities(InputIterator First, InputIterator Last, + PreprocessingRecord &PPRec) { + for (; First != Last; ++First) { + PreprocessedEntity *PPE = *First; + if (!PPE) + continue; + + Node node; + if (isa(PPE)) { + node = Node(PPE, CXCursor_MacroExpansion); + } else if (isa(PPE)) { + node = Node(PPE, CXCursor_MacroDefinition); + } else if (isa(PPE)) { + node = Node(PPE, CXCursor_InclusionDirective); + } + if (node) { + if (VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break) + return false; + } + } + + return true; + } }; void Decl_visitChildren(const Decl *Parent, Visitor V, ASTUnit *Unit, CXClientData data) { @@ -2895,3 +2947,7 @@ SourceLocation *CXXBaseSpecifier_getLocation(const CXXBaseSpecifier *B) { SourceLocation *Attr_getLocation(const Attr *A) { return new SourceLocation(A->getLocation()); } + +SourceLocation *PreprocessedEntity_getLocation(const PreprocessedEntity *PPE) { + return new SourceLocation(PPE->getSourceRange().getBegin()); +} diff --git a/src/clang/ClangAST.hpp b/src/clang/ClangAST.hpp index ca6bf054e5..5f606e9b39 100644 --- a/src/clang/ClangAST.hpp +++ b/src/clang/ClangAST.hpp @@ -21,6 +21,7 @@ struct CXXBaseSpecifier; struct ASTContext; struct SourceRange; struct Attr; +struct PreprocessedEntity; namespace comments { struct Comment; @@ -162,6 +163,7 @@ struct Node { const Expr *expr; const CXXBaseSpecifier *base; const Attr *attr; + const PreprocessedEntity *ppe; } ptr; Node() : kind(CXCursor_NotImplemented) {} @@ -177,6 +179,9 @@ struct Node { Node(const Attr *attr) : kind(Attr_getCXCursorKind(attr)) { ptr.attr = attr; } + Node(const PreprocessedEntity *ppe, CXCursorKind kind) : kind(kind) { + ptr.ppe = ppe; + } operator bool() const { return kind != CXCursor_NotImplemented; } @@ -238,3 +243,4 @@ QualType CXXBaseSpecifier_getType(const CXXBaseSpecifier *); BindgenStringRef CXXBaseSpecifier_getSpelling(const CXXBaseSpecifier *); SourceLocation *CXXBaseSpecifier_getLocation(const CXXBaseSpecifier *); SourceLocation *Attr_getLocation(const Attr *); +SourceLocation *PreprocessedEntity_getLocation(const PreprocessedEntity *); diff --git a/src/clang/clangtool.rs b/src/clang/clangtool.rs index f9f2657724..20bf1fc24d 100644 --- a/src/clang/clangtool.rs +++ b/src/clang/clangtool.rs @@ -6276,6 +6276,11 @@ pub struct clang_Attr { } #[repr(C)] #[derive(Debug, Copy, Clone)] +pub struct clang_PreprocessedEntity { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] pub struct clang_comments_Comment { _unused: [u8; 0], } @@ -6858,6 +6863,7 @@ pub union Node__bindgen_ty_1 { pub expr: *const clang_Expr, pub base: *const clang_CXXBaseSpecifier, pub attr: *const clang_Attr, + pub ppe: *const clang_PreprocessedEntity, _bindgen_union_align: u64, } #[test] @@ -6924,6 +6930,19 @@ fn bindgen_test_layout_Node__bindgen_ty_1() { stringify!(attr) ) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ppe as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(Node__bindgen_ty_1), + "::", + stringify!(ppe) + ) + ); } #[test] fn bindgen_test_layout_Node() { @@ -7209,6 +7228,12 @@ extern "C" { arg1: *const clang_Attr, ) -> *mut clang_SourceLocation; } +extern "C" { + #[link_name = "\u{1}_Z30PreprocessedEntity_getLocationPKN5clang18PreprocessedEntityE"] + pub fn PreprocessedEntity_getLocation( + arg1: *const clang_PreprocessedEntity, + ) -> *mut clang_SourceLocation; +} #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct __locale_data { From 3fc7daf560f1b672636c344667e0259346741303 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 11:20:13 -0800 Subject: [PATCH 23/88] Check for valid source range before tokenizing --- src/clang/ClangAST.cpp | 2 +- src/clang/ClangAST.hpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 0c6de65978..3e06fd4eed 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1627,7 +1627,7 @@ void CXXBaseSpecifier_visitChildren(const CXXBaseSpecifier *Parent, Visitor V, A void tokenize(ASTUnit *TU, BindgenSourceRange Range, CXToken **Tokens, unsigned *NumTokens) { - if (!Tokens || !NumTokens) + if (!Tokens || !NumTokens || !Range) return; SmallVector CXTokens; diff --git a/src/clang/ClangAST.hpp b/src/clang/ClangAST.hpp index 5f606e9b39..bece5cab8b 100644 --- a/src/clang/ClangAST.hpp +++ b/src/clang/ClangAST.hpp @@ -60,6 +60,9 @@ struct BindgenSourceRange { SourceLocation *E; BindgenSourceRange(const SourceRange &range); + operator bool() const { + return B && E; + } }; From 7913cbdee1b56bf5d8d3ac03eb0f432ea2fe43a7 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 11:21:52 -0800 Subject: [PATCH 24/88] Avoid infinite recursion when visiting decls as TypeRefs --- src/clang.rs | 3 ++- src/clang/ClangAST.cpp | 12 ++++++++---- src/clang/ClangAST.hpp | 2 +- src/clang/clangtool.rs | 7 +++++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index 18e83829cb..27ef2e6e93 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -480,9 +480,10 @@ impl Cursor { /// a declaration, get the cursor pointing to the referenced type or type of /// the declared thing. pub fn definition(&self) -> Option { + let is_reference = self.kind == CXCursor_TypeRef; let def = match self.node { ASTNode::Decl(d) => unsafe { - clangtool::Decl_getDefinition(d) + clangtool::Decl_getDefinition(d, is_reference) }, _ => return None, }; diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 3e06fd4eed..b9180dd140 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -359,7 +359,7 @@ const Decl *Decl_getSemanticParent(const Decl *D) { // return D.unit; // } -const Decl *Decl_getDefinition(const Decl *D) { +const Decl *Decl_getDefinition(const Decl *D, bool isReference) { if (!D) return nullptr; @@ -485,7 +485,7 @@ const Decl *Decl_getDefinition(const Decl *D) { case Decl::UsingShadow: case Decl::ConstructorUsingShadow: return Decl_getDefinition( - cast(&*D)->getTargetDecl()); + cast(&*D)->getTargetDecl(), isReference); case Decl::ObjCMethod: case Decl::ObjCCategory: @@ -498,12 +498,12 @@ const Decl *Decl_getDefinition(const Decl *D) { case Decl::Friend: if (NamedDecl *Friend = cast(&*D)->getFriendDecl()) - return Decl_getDefinition(Friend); + return Decl_getDefinition(Friend, isReference); break; case Decl::FriendTemplate: if (NamedDecl *Friend = cast(&*D)->getFriendDecl()) - return Decl_getDefinition(Friend); + return Decl_getDefinition(Friend, isReference); break; } @@ -1458,6 +1458,10 @@ class BindgenVisitor : public RecursiveASTVisitor { } } + // Do not recurse through references + if (kind >= CXCursor_FirstRef && kind <= CXCursor_LastRef) + return true; + auto OldParent = Parent; Parent = node; bool res = RecursiveASTVisitor::TraverseDecl(D); diff --git a/src/clang/ClangAST.hpp b/src/clang/ClangAST.hpp index bece5cab8b..96431f8f11 100644 --- a/src/clang/ClangAST.hpp +++ b/src/clang/ClangAST.hpp @@ -101,7 +101,7 @@ bool CursorKind_isInvalid(CXCursorKind kind); const Decl *Decl_getLexicalParent(const Decl *D); const Decl *Decl_getSemanticParent(const Decl *D); -const Decl *Decl_getDefinition(const Decl *D); +const Decl *Decl_getDefinition(const Decl *D, bool isReference); const Decl *Decl_getReferenced(const Decl *D); const Decl *Decl_getCanonical(const Decl *D); const Decl *Decl_getSpecializedTemplate(const Decl *D); diff --git a/src/clang/clangtool.rs b/src/clang/clangtool.rs index 20bf1fc24d..723847f584 100644 --- a/src/clang/clangtool.rs +++ b/src/clang/clangtool.rs @@ -6607,8 +6607,11 @@ extern "C" { pub fn Decl_getSemanticParent(D: *const clang_Decl) -> *const clang_Decl; } extern "C" { - #[link_name = "\u{1}_Z18Decl_getDefinitionPKN5clang4DeclE"] - pub fn Decl_getDefinition(D: *const clang_Decl) -> *const clang_Decl; + #[link_name = "\u{1}_Z18Decl_getDefinitionPKN5clang4DeclEb"] + pub fn Decl_getDefinition( + D: *const clang_Decl, + isReference: bool, + ) -> *const clang_Decl; } extern "C" { #[link_name = "\u{1}_Z18Decl_getReferencedPKN5clang4DeclE"] From 7e3a4ae63919568ba7a1d712e516189c0e8a1ee7 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 11:23:09 -0800 Subject: [PATCH 25/88] Implement support for getDefinition on Objective-C nodes --- src/clang/ClangAST.cpp | 54 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index b9180dd140..d102fd73c2 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -487,13 +487,61 @@ const Decl *Decl_getDefinition(const Decl *D, bool isReference) { return Decl_getDefinition( cast(&*D)->getTargetDecl(), isReference); - case Decl::ObjCMethod: + case Decl::ObjCMethod: { + const ObjCMethodDecl *Method = cast(D); + if (Method->isThisDeclarationADefinition()) + return D; + + // Dig out the method definition in the associated + // @implementation, if we have it. + // FIXME: The ASTs should make finding the definition easier. + if (const ObjCInterfaceDecl *Class + = dyn_cast(Method->getDeclContext())) + if (ObjCImplementationDecl *ClassImpl = Class->getImplementation()) + if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(), + Method->isInstanceMethod())) + if (Def->isThisDeclarationADefinition()) + return Def; + + break; + } + case Decl::ObjCCategory: + if (ObjCCategoryImplDecl *Impl = cast(D)->getImplementation()) + return Impl; + break; + case Decl::ObjCProtocol: - case Decl::ObjCInterface: + if (const ObjCProtocolDecl *Def = cast(D)->getDefinition()) + return Def; + break; + + case Decl::ObjCInterface: { + // There are two notions of a "definition" for an Objective-C + // class: the interface and its implementation. When we resolved a + // reference to an Objective-C class, produce the @interface as + // the definition; when we were provided with the interface, + // produce the @implementation as the definition. + const ObjCInterfaceDecl *IFace = cast(D); + if (isReference) { + if (const ObjCInterfaceDecl *Def = IFace->getDefinition()) + return Def; + } else if (ObjCImplementationDecl *Impl = IFace->getImplementation()) + return Impl; + break; + } + case Decl::ObjCProperty: + // FIXME: We don't really know where to find the + // ObjCPropertyImplDecls that implement this property. + break; + case Decl::ObjCCompatibleAlias: - llvm_unreachable("Objective-C not implemented"); + if (const ObjCInterfaceDecl *Class + = cast(D)->getClassInterface()) + if (const ObjCInterfaceDecl *Def = Class->getDefinition()) + return Def; + break; case Decl::Friend: From a68c996cc4a463f593b1011ea946878a7396a140 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 11:23:49 -0800 Subject: [PATCH 26/88] Add type null checks --- src/clang/ClangAST.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index d102fd73c2..8bd113416c 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -756,6 +756,9 @@ comments::Comment *Decl_getParsedComment(const Decl *D, ASTContext *Ctx) { } static QualType make_type_compatible(QualType QT) { + if (QT.isNull()) + return QT; + // libclang does not return AttributedTypes if // CXTranslationUnit_IncludeAttributedTypes is not set, and bindgen assumes it // is not set. @@ -962,10 +965,11 @@ bool CXXMethod_isPureVirtual(const Decl *D) { } QualType Decl_getResultType(const Decl *D, ASTContext *Ctx) { - if (auto *FT = Decl_getType(D, Ctx)->getAs()) - return make_type_compatible(FT->getReturnType()); - else - return QualType(); + auto Ty = Decl_getType(D, Ctx); + if (!Ty.isNull()) + if (auto *FT = Ty->getAs()) + return make_type_compatible(FT->getReturnType()); + return QualType(); } // const Decl *Expr_getSemanticParent(const Expr *E) { From d0e7d586f820b0d067d4a010dc23e0fb55e42fcd Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 11:24:00 -0800 Subject: [PATCH 27/88] Check that expr is not value dependent before evaluating --- src/clang/ClangAST.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 8bd113416c..a7de9c80da 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -211,7 +211,7 @@ struct EvalResult { }; EvalResult *Expr_Evaluate(const Expr *E, ASTContext *Ctx) { - if (!E) + if (!E || E->isValueDependent()) return nullptr; Expr::EvalResult res; From 0446e60583842f014dd198e60f75f4377a465127 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 11:24:33 -0800 Subject: [PATCH 28/88] Clean up record validation and support validating class bases as well --- src/clang/ClangAST.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index a7de9c80da..2c1c6a48e4 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -836,6 +836,11 @@ static bool isTypeIncompleteForLayout(QualType QT) { } static long long visitRecordForValidation(const RecordDecl *RD) { + if (!RD) + return -1; + RD = RD->getDefinition(); + if (!RD || RD->isInvalidDecl() || !RD->isCompleteDefinition()) + return -1; for (const auto *I : RD->fields()){ QualType FQT = I->getType(); if (isTypeIncompleteForLayout(FQT)) @@ -852,16 +857,19 @@ static long long visitRecordForValidation(const RecordDecl *RD) { } // else try next field } + if (auto *Class = dyn_cast(RD)) { + for (const CXXBaseSpecifier &Base : Class->bases()) { + auto *baseDecl = Base.getType()->getAsCXXRecordDecl(); + long long ret = visitRecordForValidation(baseDecl); + if (ret < 0) + return ret; + } + } return 0; } long long Decl_getOffsetOfField(const Decl *D, ASTContext *Ctx) { auto *RD = dyn_cast_or_null(D->getDeclContext()); - if (!RD) - return -1; - RD = RD->getDefinition(); - if (!RD || RD->isInvalidDecl() || !RD->isCompleteDefinition()) - return -1; auto Err = visitRecordForValidation(RD); if (Err < 0) return Err; @@ -1485,9 +1493,7 @@ class BindgenVisitor : public RecursiveASTVisitor { } bool TraverseDeclTyped(Decl *D, CXCursorKind kind) { - if (!D) - return false; - if (D->isImplicit()) + if (!D || D->isImplicit()) return true; bool skip = !Parent; From fec0814f9576568d1814ed4e4b5b81342a187547 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 11:24:56 -0800 Subject: [PATCH 29/88] Clean up traversal We should return true to continue traversal at invalid nodes. We should also recurse through Stmt nodes that aren't Exprs, since we don't handle them in bindgen. --- src/clang/ClangAST.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 2c1c6a48e4..bc2b9054ab 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1531,13 +1531,13 @@ class BindgenVisitor : public RecursiveASTVisitor { return TraverseDeclTyped(D, Decl_getCXCursorKind(D)); } - bool TraverseStmtTyped(Stmt *S, CXCursorKind kind) { - if (!S) - return false; + bool TraverseExprTyped(Expr *E, CXCursorKind kind) { + if (!E) + return true; - Node node(cast(S), kind); + Node node(E, kind); if (Parent) { - // S->dump(); + // E->dump(); switch (VisitFn(node, Parent, &AST, Data)) { case CXChildVisit_Break: return false; @@ -1550,20 +1550,22 @@ class BindgenVisitor : public RecursiveASTVisitor { auto OldParent = Parent; Parent = node; - bool res = RecursiveASTVisitor::TraverseStmt(S); + bool res = RecursiveASTVisitor::TraverseStmt(E); Parent = OldParent; return res; } bool TraverseStmt(Stmt *S) { if (!S) - return false; - return TraverseStmtTyped(S, Expr_getCXCursorKind(cast(S))); + return true; + if (auto *E = dyn_cast(S)) + return TraverseExprTyped(E, Expr_getCXCursorKind(E)); + return RecursiveASTVisitor::TraverseStmt(S); } bool TraverseTypeLoc(TypeLoc TL) { if (!TL) - return false; + return true; // TL.getType().dump(); From 1e3af567c6457276687d2cbd4ce5e13d1d81efc8 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 11:26:04 -0800 Subject: [PATCH 30/88] Validate cursor based on its own kind, not the derived kind of its node --- src/clang.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clang.rs b/src/clang.rs index 27ef2e6e93..34f2d17677 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -408,7 +408,7 @@ impl Cursor { /// Is this cursor pointing a valid referent? pub fn is_valid(&self) -> bool { - self.node.is_valid() + unsafe { !clangtool::CursorKind_isInvalid(self.kind) } } /// Get the source location for the referent. From 7735a89b849e246eb923d1d7a2bbecbfbd57b02a Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 12:09:24 -0800 Subject: [PATCH 31/88] Rewrite TypeLoc traversal Fixes header_const_tparam_hpp --- src/clang/ClangAST.cpp | 87 ++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index bc2b9054ab..69008408b5 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1563,48 +1563,61 @@ class BindgenVisitor : public RecursiveASTVisitor { return RecursiveASTVisitor::TraverseStmt(S); } - bool TraverseTypeLoc(TypeLoc TL) { + bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { if (!TL) return true; + return TraverseStmt(TL.getUnderlyingExpr()); + } - // TL.getType().dump(); + bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { + if (!TL) + return true; + return TraverseStmt(TL.getUnderlyingExpr()); + } - if (auto T = TL.getAs()) { - if (!TraverseStmt(T.getUnderlyingExpr())) - return false; - } else if (auto T = TL.getAs()) { - if (!TraverseStmt(T.getUnderlyingExpr())) - return false; - } else if (auto T = TL.getAs()) { - if (!TraverseDeclTyped(T.getTypedefNameDecl(), CXCursor_TypeRef)) - return false; - } else if (auto T = TL.getAs()) { - if (!TraverseDeclTyped(T.getDecl(), CXCursor_TypeRef)) - return false; - } else if (auto T = TL.getAs()) { - if (!TraverseDeclTyped(T.getDecl(), CXCursor_TypeRef)) - return false; - } else if (auto T = TL.getAs()) { - if (T.isDefinition()) { - if (!TraverseDecl(T.getDecl())) - return false; - } else { - if (!TraverseDeclTyped(T.getDecl(), CXCursor_TypeRef)) - return false; - } - } else if (auto T = TL.getAs()) { - if (!TraverseDeclTyped(T.getDecl(), CXCursor_TypeRef)) - return false; - } else if (auto T = TL.getAs()) { - if (!TraverseDeclTyped(T.getDecl(), CXCursor_TypeRef)) - return false; - } else if (auto T = TL.getAs()) { - if (!TraverseDeclTyped(T.getDecl(), CXCursor_TypeRef)) - return false; - } + bool VisitTypedefTypeLoc(TypedefTypeLoc TL) { + if (!TL) + return true; + return TraverseDeclTyped(TL.getTypedefNameDecl(), CXCursor_TypeRef); + } - bool res = RecursiveASTVisitor::TraverseTypeLoc(TL); - return res; + bool VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { + if (!TL) + return true; + return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); + } + + bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { + if (!TL) + return true; + return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); + } + + bool VisitTagTypeLoc(TagTypeLoc TL) { + if (!TL) + return true; + if (TL.isDefinition()) + return TraverseDecl(TL.getDecl()); + else + return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); + } + + bool VisitRecordTypeLoc(RecordTypeLoc TL) { + if (!TL) + return true; + return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); + } + + bool VisitEnumTypeLoc(EnumTypeLoc TL) { + if (!TL) + return true; + return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); + } + + bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { + if (!TL) + return true; + return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); } bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) { From 19badfdc7133d81e067e3343a6724e2106077b87 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 12:15:24 -0800 Subject: [PATCH 32/88] Fix logic in Expr_Evaluate We weren't returning results for anything but string literals. Fixes header_constant_evaluate_h --- src/clang/ClangAST.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 69008408b5..240ff00e44 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -226,9 +226,8 @@ EvalResult *Expr_Evaluate(const Expr *E, ASTContext *Ctx) { } else if (E->getStmtClass() == Stmt::StringLiteralClass) { auto StrE = cast(&*E); return new EvalResult(StrE->getString().str()); - } else { - return new EvalResult(res.Val); } + return new EvalResult(res.Val); } return nullptr; From 0362eac4cc5ddc2e8a223f406c358895f11e4239 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 13:45:33 -0800 Subject: [PATCH 33/88] Add SourceRange getters for CXXBaseSpecifier, Attr, and PreprocessedEntity --- src/clang.rs | 3 +++ src/clang/ClangAST.cpp | 12 ++++++++++++ src/clang/ClangAST.hpp | 3 +++ src/clang/clangtool.rs | 16 ++++++++++++++++ 4 files changed, 34 insertions(+) diff --git a/src/clang.rs b/src/clang.rs index 34f2d17677..249f97df46 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -432,6 +432,9 @@ impl Cursor { match self.node { ASTNode::Decl(d) => clangtool::Decl_getSourceRange(d), ASTNode::Expr(e) => clangtool::Expr_getSourceRange(e), + ASTNode::CXXBaseSpecifier(b) => clangtool::CXXBaseSpecifier_getSourceRange(b), + ASTNode::Attr(b) => clangtool::Attr_getSourceRange(b), + ASTNode::PreprocessedEntity(b) => clangtool::PreprocessedEntity_getSourceRange(b), _ => clangtool::BindgenSourceRange::null(), } } diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 240ff00e44..8807b5b472 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -3027,3 +3027,15 @@ SourceLocation *Attr_getLocation(const Attr *A) { SourceLocation *PreprocessedEntity_getLocation(const PreprocessedEntity *PPE) { return new SourceLocation(PPE->getSourceRange().getBegin()); } + +BindgenSourceRange CXXBaseSpecifier_getSourceRange(const CXXBaseSpecifier *B) { + return BindgenSourceRange(B->getSourceRange()); +} + +BindgenSourceRange Attr_getSourceRange(const Attr *A) { + return BindgenSourceRange(A->getRange()); +} + +BindgenSourceRange PreprocessedEntity_getSourceRange(const PreprocessedEntity *PPE) { + return BindgenSourceRange(PPE->getSourceRange()); +} diff --git a/src/clang/ClangAST.hpp b/src/clang/ClangAST.hpp index 96431f8f11..274652a07b 100644 --- a/src/clang/ClangAST.hpp +++ b/src/clang/ClangAST.hpp @@ -247,3 +247,6 @@ BindgenStringRef CXXBaseSpecifier_getSpelling(const CXXBaseSpecifier *); SourceLocation *CXXBaseSpecifier_getLocation(const CXXBaseSpecifier *); SourceLocation *Attr_getLocation(const Attr *); SourceLocation *PreprocessedEntity_getLocation(const PreprocessedEntity *); +BindgenSourceRange CXXBaseSpecifier_getSourceRange(const CXXBaseSpecifier *); +BindgenSourceRange Attr_getSourceRange(const Attr *); +BindgenSourceRange PreprocessedEntity_getSourceRange(const PreprocessedEntity *); diff --git a/src/clang/clangtool.rs b/src/clang/clangtool.rs index 723847f584..81e682a140 100644 --- a/src/clang/clangtool.rs +++ b/src/clang/clangtool.rs @@ -7237,6 +7237,22 @@ extern "C" { arg1: *const clang_PreprocessedEntity, ) -> *mut clang_SourceLocation; } +extern "C" { + #[link_name = "\u{1}_Z31CXXBaseSpecifier_getSourceRangePKN5clang16CXXBaseSpecifierE"] + pub fn CXXBaseSpecifier_getSourceRange( + arg1: *const clang_CXXBaseSpecifier, + ) -> BindgenSourceRange; +} +extern "C" { + #[link_name = "\u{1}_Z19Attr_getSourceRangePKN5clang4AttrE"] + pub fn Attr_getSourceRange(arg1: *const clang_Attr) -> BindgenSourceRange; +} +extern "C" { + #[link_name = "\u{1}_Z33PreprocessedEntity_getSourceRangePKN5clang18PreprocessedEntityE"] + pub fn PreprocessedEntity_getSourceRange( + arg1: *const clang_PreprocessedEntity, + ) -> BindgenSourceRange; +} #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct __locale_data { From 3523b23f9c900b567afdc67191f6d999cf9c2894 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 14:20:49 -0800 Subject: [PATCH 34/88] Clean up string transfer from C->Rust --- src/clang.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clang.rs b/src/clang.rs index 249f97df46..df5f91a15b 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -51,7 +51,7 @@ trait ToCString { impl ToCString for clangtool::BindgenStringRef { fn to_cstring(&self) -> CString { if !self.s.is_null() { - unsafe { CString::from_raw(clangtool::cString(*self)) } + unsafe { CStr::from_ptr(self.s).into() } } else { return CString::new("").unwrap(); } From 0e76552d4c77acd0918a92d2b4631cffebce44cc Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 14:21:05 -0800 Subject: [PATCH 35/88] Adjust the end of the range given in tokenize Clang uses source ranges which start at the first character of the first token and end at the first character of the last token, while libclang assumes that the end of the range has been adjusted to after the last character of the last token. tokenize is the only place we rely on this, so just adjust it here. --- src/clang.rs | 5 +++++ src/clang/ClangAST.cpp | 19 +++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index df5f91a15b..7446b36df1 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -427,6 +427,11 @@ impl Cursor { } /// Get the source location range for the referent. + /// + /// Warning: This range goes from the start of the first token to the start + /// of the last token, unlike the ranges provided by libclang, which are + /// half-open ranges of characters (end is past the last character in the + /// last token). pub fn extent(&self) -> clangtool::BindgenSourceRange { unsafe { match self.node { diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 8807b5b472..01296b7f4a 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1706,12 +1706,27 @@ void tokenize(ASTUnit *TU, BindgenSourceRange Range, CXToken **Tokens, if (!Tokens || !NumTokens || !Range) return; - SmallVector CXTokens; + // Translate the Range end location to after the last token, instead of + // the beginning of the last token. SourceManager &SourceMgr = TU->getSourceManager(); + SourceLocation EndLoc = *Range.E; + bool IsTokenRange = true; + if (EndLoc.isValid() && EndLoc.isMacroID() && !SourceMgr.isMacroArgExpansion(EndLoc)) { + CharSourceRange Expansion = SourceMgr.getExpansionRange(EndLoc); + EndLoc = Expansion.getEnd(); + IsTokenRange = Expansion.isTokenRange(); + } + if (IsTokenRange && EndLoc.isValid()) { + unsigned Length = Lexer::MeasureTokenLength(SourceMgr.getSpellingLoc(EndLoc), + SourceMgr, TU->getLangOpts()); + EndLoc = EndLoc.getLocWithOffset(Length); + } + + SmallVector CXTokens; std::pair BeginLocInfo = SourceMgr.getDecomposedSpellingLoc(*Range.B); std::pair EndLocInfo = - SourceMgr.getDecomposedSpellingLoc(*Range.E); + SourceMgr.getDecomposedSpellingLoc(EndLoc); // Cannot tokenize across files. if (BeginLocInfo.first != EndLocInfo.first) From d09a320704962612aa9e5063d740358cea1d972c Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 17:46:07 -0800 Subject: [PATCH 36/88] Add support for visiting children of reference cursors --- src/clang.rs | 39 +++++++++++++++++++++++---------------- src/clang/ClangAST.cpp | 17 +++++++++++------ src/clang/ClangAST.hpp | 11 +++++++---- src/clang/clangtool.rs | 9 ++++++--- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index 7446b36df1..6da9fdd98a 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -488,7 +488,7 @@ impl Cursor { /// a declaration, get the cursor pointing to the referenced type or type of /// the declared thing. pub fn definition(&self) -> Option { - let is_reference = self.kind == CXCursor_TypeRef; + let is_reference = self.kind >= CXCursor_FirstRef && self.kind <= CXCursor_LastRef; let def = match self.node { ASTNode::Decl(d) => unsafe { clangtool::Decl_getDefinition(d, is_reference) @@ -572,6 +572,7 @@ impl Cursor { ASTNode::Decl(d) => unsafe { clangtool::Decl_visitChildren( d, + self.kind, Some(visit_children::), self.unit, mem::transmute(&mut visitor), @@ -580,6 +581,7 @@ impl Cursor { ASTNode::Expr(e) => unsafe { clangtool::Expr_visitChildren( e, + self.kind, Some(visit_children::), self.unit, mem::transmute(&mut visitor), @@ -588,6 +590,7 @@ impl Cursor { ASTNode::CXXBaseSpecifier(b) => unsafe { clangtool::CXXBaseSpecifier_visitChildren( b, + self.kind, Some(visit_children::), self.unit, mem::transmute(&mut visitor), @@ -1119,21 +1122,25 @@ where Visitor: FnMut(Cursor) -> CXChildVisitResult, { let func: &mut Visitor = mem::transmute(data); - let node = if (raw_node.kind >= CXCursor_FirstDecl && raw_node.kind <= CXCursor_LastDecl) - || (raw_node.kind >= CXCursor_FirstExtraDecl && raw_node.kind <= CXCursor_LastExtraDecl) - || raw_node.kind == CXCursor_TypeRef - { - ASTNode::Decl(raw_node.ptr.decl) - } else if raw_node.kind >= CXCursor_FirstExpr && raw_node.kind <= CXCursor_LastExpr { - ASTNode::Expr(raw_node.ptr.expr) - } else if raw_node.kind == CXCursor_CXXBaseSpecifier { - ASTNode::CXXBaseSpecifier(raw_node.ptr.base) - } else if raw_node.kind >= CXCursor_FirstAttr && raw_node.kind <= CXCursor_LastAttr { - ASTNode::Attr(raw_node.ptr.attr) - } else if raw_node.kind >= CXCursor_FirstPreprocessing && raw_node.kind <= CXCursor_LastPreprocessing { - ASTNode::PreprocessedEntity(raw_node.ptr.ppe) - } else { - return CXChildVisit_Recurse; + let node = { + // CXCursor_CXXBaseSpecifier must come before decls, because it is in + // the range [FirstRef, LastRef] + if raw_node.kind == CXCursor_CXXBaseSpecifier { + ASTNode::CXXBaseSpecifier(raw_node.ptr.base) + } else if (raw_node.kind >= CXCursor_FirstDecl && raw_node.kind <= CXCursor_LastDecl) + || (raw_node.kind >= CXCursor_FirstExtraDecl && raw_node.kind <= CXCursor_LastExtraDecl) + || (raw_node.kind >= CXCursor_FirstRef && raw_node.kind <= CXCursor_LastRef) + { + ASTNode::Decl(raw_node.ptr.decl) + } else if raw_node.kind >= CXCursor_FirstExpr && raw_node.kind <= CXCursor_LastExpr { + ASTNode::Expr(raw_node.ptr.expr) + } else if raw_node.kind >= CXCursor_FirstAttr && raw_node.kind <= CXCursor_LastAttr { + ASTNode::Attr(raw_node.ptr.attr) + } else if raw_node.kind >= CXCursor_FirstPreprocessing && raw_node.kind <= CXCursor_LastPreprocessing { + ASTNode::PreprocessedEntity(raw_node.ptr.ppe) + } else { + return CXChildVisit_Recurse; + } }; let child = Cursor { node, diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 01296b7f4a..7aec76e6a5 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1516,7 +1516,8 @@ class BindgenVisitor : public RecursiveASTVisitor { } // Do not recurse through references - if (kind >= CXCursor_FirstRef && kind <= CXCursor_LastRef) + if (kind >= CXCursor_FirstRef && kind <= CXCursor_LastRef + && kind != CXCursor_CXXBaseSpecifier) return true; auto OldParent = Parent; @@ -1688,15 +1689,19 @@ class BindgenVisitor : public RecursiveASTVisitor { } }; -void Decl_visitChildren(const Decl *Parent, Visitor V, ASTUnit *Unit, CXClientData data) { +void Decl_visitChildren(const Decl *Parent, CXCursorKind kind, Visitor V, + ASTUnit *Unit, CXClientData data) { BindgenVisitor visitor(*Unit, V, data); - visitor.TraverseDecl(const_cast(&*Parent)); + visitor.TraverseDeclTyped(const_cast(&*Parent), kind); } -void Expr_visitChildren(const Expr *Parent, Visitor V, ASTUnit *Unit, CXClientData data) { +void Expr_visitChildren(const Expr *Parent, CXCursorKind kind, Visitor V, + ASTUnit *Unit, CXClientData data) { BindgenVisitor visitor(*Unit, V, data); - visitor.TraverseStmt(const_cast(&*Parent)); + visitor.TraverseExprTyped(const_cast(&*Parent), kind); } -void CXXBaseSpecifier_visitChildren(const CXXBaseSpecifier *Parent, Visitor V, ASTUnit *Unit, CXClientData data) { +void CXXBaseSpecifier_visitChildren(const CXXBaseSpecifier *Parent, + CXCursorKind kind, Visitor V, ASTUnit *Unit, + CXClientData data) { BindgenVisitor visitor(*Unit, V, data); visitor.TraverseCXXBaseSpecifier(*Parent); } diff --git a/src/clang/ClangAST.hpp b/src/clang/ClangAST.hpp index 274652a07b..43d484941d 100644 --- a/src/clang/ClangAST.hpp +++ b/src/clang/ClangAST.hpp @@ -194,10 +194,13 @@ typedef CXChildVisitResult (*Visitor)(Node N, Node parent, ASTUnit *unit, CXClientData client_data); -void Decl_visitChildren(const Decl *Parent, Visitor V, ASTUnit *Unit, CXClientData data); -void Expr_visitChildren(const Expr *Parent, Visitor V, ASTUnit *Unit, CXClientData data); -void CXXBaseSpecifier_visitChildren(const CXXBaseSpecifier *Parent, Visitor V, - ASTUnit *Unit, CXClientData data); +void Decl_visitChildren(const Decl *Parent, CXCursorKind kind, Visitor V, + ASTUnit *Unit, CXClientData data); +void Expr_visitChildren(const Expr *Parent, CXCursorKind kind, Visitor V, + ASTUnit *Unit, CXClientData data); +void CXXBaseSpecifier_visitChildren(const CXXBaseSpecifier *Parent, + CXCursorKind kind, Visitor V, ASTUnit *Unit, + CXClientData data); void tokenize(ASTUnit *TU, BindgenSourceRange Range, CXToken **Tokens, unsigned *NumTokens); diff --git a/src/clang/clangtool.rs b/src/clang/clangtool.rs index 81e682a140..9bca6a1684 100644 --- a/src/clang/clangtool.rs +++ b/src/clang/clangtool.rs @@ -6984,27 +6984,30 @@ pub type Visitor = ::std::option::Option< ) -> CXChildVisitResult::Type, >; extern "C" { - #[link_name = "\u{1}_Z18Decl_visitChildrenPKN5clang4DeclEPF18CXChildVisitResult4NodeS4_PNS_7ASTUnitEPvES6_S7_"] + #[link_name = "\u{1}_Z18Decl_visitChildrenPKN5clang4DeclE12CXCursorKindPF18CXChildVisitResult4NodeS5_PNS_7ASTUnitEPvES7_S8_"] pub fn Decl_visitChildren( Parent: *const clang_Decl, + kind: CXCursorKind::Type, V: Visitor, Unit: *mut clang_ASTUnit, data: CXClientData, ); } extern "C" { - #[link_name = "\u{1}_Z18Expr_visitChildrenPKN5clang4ExprEPF18CXChildVisitResult4NodeS4_PNS_7ASTUnitEPvES6_S7_"] + #[link_name = "\u{1}_Z18Expr_visitChildrenPKN5clang4ExprE12CXCursorKindPF18CXChildVisitResult4NodeS5_PNS_7ASTUnitEPvES7_S8_"] pub fn Expr_visitChildren( Parent: *const clang_Expr, + kind: CXCursorKind::Type, V: Visitor, Unit: *mut clang_ASTUnit, data: CXClientData, ); } extern "C" { - #[link_name = "\u{1}_Z30CXXBaseSpecifier_visitChildrenPKN5clang16CXXBaseSpecifierEPF18CXChildVisitResult4NodeS4_PNS_7ASTUnitEPvES6_S7_"] + #[link_name = "\u{1}_Z30CXXBaseSpecifier_visitChildrenPKN5clang16CXXBaseSpecifierE12CXCursorKindPF18CXChildVisitResult4NodeS5_PNS_7ASTUnitEPvES7_S8_"] pub fn CXXBaseSpecifier_visitChildren( Parent: *const clang_CXXBaseSpecifier, + kind: CXCursorKind::Type, V: Visitor, Unit: *mut clang_ASTUnit, data: CXClientData, From f78bee217e689df7c798151ec825065d27789778 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 17:46:37 -0800 Subject: [PATCH 37/88] Visit type and template references in SizeOfPackExpr --- src/clang/ClangAST.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 7aec76e6a5..f62a92e453 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1563,6 +1563,21 @@ class BindgenVisitor : public RecursiveASTVisitor { return RecursiveASTVisitor::TraverseStmt(S); } + bool VisitSizeOfPackExpr(SizeOfPackExpr *E) { + NamedDecl *Pack = E->getPack(); + if (isa(Pack)) { + Node node(Pack, CXCursor_TypeRef); + Node parent(E, Expr_getCXCursorKind(E)); + return VisitFn(node, parent, &AST, Data) != CXChildVisit_Break; + } + if (isa(Pack)) { + Node node(Pack, CXCursor_TemplateRef); + Node parent(E, Expr_getCXCursorKind(E)); + return VisitFn(node, parent, &AST, Data) != CXChildVisit_Break; + } + return true; + } + bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { if (!TL) return true; From 9dc234637a03534940097db442b538c78018395f Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 17:46:59 -0800 Subject: [PATCH 38/88] Visit references from template names --- src/clang/ClangAST.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index f62a92e453..40ed939af4 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1635,6 +1635,52 @@ class BindgenVisitor : public RecursiveASTVisitor { return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); } + bool TraverseTemplateName(TemplateName Name) { + Node node; + switch (Name.getKind()) { + case TemplateName::Template: + node = Node(Name.getAsTemplateDecl(), CXCursor_TemplateRef); + break; + + case TemplateName::OverloadedTemplate: + // libclang visits this, but we don't need it for bindgen + return true; + + case TemplateName::AssumedTemplate: + return true; + + case TemplateName::DependentTemplate: + return true; + + case TemplateName::QualifiedTemplate: + node = Node(Name.getAsQualifiedTemplateName()->getDecl(), CXCursor_TemplateRef); + break; + + case TemplateName::SubstTemplateTemplateParm: + node = Node(Name.getAsSubstTemplateTemplateParm()->getParameter(), CXCursor_TemplateRef); + break; + + case TemplateName::SubstTemplateTemplateParmPack: + node = Node(Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), CXCursor_TemplateRef); + break; + } + + switch (VisitFn(node, Parent, &AST, Data)) { + case CXChildVisit_Break: + return false; + case CXChildVisit_Continue: + return true; + case CXChildVisit_Recurse: + break; + } + + auto OldParent = Parent; + Parent = node; + bool res = RecursiveASTVisitor::TraverseTemplateName(Name); + Parent = OldParent; + return res; + } + bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) { if (Parent) { switch (VisitFn(Node(&Base), Parent, &AST, Data)) { From fca97533b410f114ec1846bce8b703ef65044a25 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 18:30:29 -0800 Subject: [PATCH 39/88] Support correct spelling of objective-c decls --- src/clang/ClangAST.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 40ed939af4..4fdb8b211b 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -670,8 +670,33 @@ BindgenStringRef Decl_getUSR(const Decl *D) { } BindgenStringRef Decl_getSpelling(const Decl *D) { + if (!D) + return stringref(); + const NamedDecl *ND = dyn_cast_or_null(&*D); - if (!ND) + if (!ND) { + if (const ObjCPropertyImplDecl *PropImpl = + dyn_cast(D)) + if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl()) + return stringref(Property->getIdentifier()->getName()); + + if (const ImportDecl *ImportD = dyn_cast(D)) + if (Module *Mod = ImportD->getImportedModule()) + return stringref(Mod->getFullModuleName()); + + return stringref(); + } + + if (const ObjCMethodDecl *OMD = dyn_cast(ND)) + return stringref(OMD->getSelector().getAsString()); + + if (const ObjCCategoryImplDecl *CIMP = dyn_cast(ND)) + // No, this isn't the same as the code below. getIdentifier() is non-virtual + // and returns different names. NamedDecl returns the class name and + // ObjCCategoryImplDecl returns the category name. + return stringref(CIMP->getIdentifier()->getNameStart()); + + if (isa(D)) return stringref(); SmallString<1024> S; From 3e034d12d46d4fc2bc43d995a0eff1627dba8afa Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 18:30:54 -0800 Subject: [PATCH 40/88] Get correct result type for Objective-C methods --- src/clang/ClangAST.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 4fdb8b211b..e07a6b383b 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -997,11 +997,10 @@ bool CXXMethod_isPureVirtual(const Decl *D) { } QualType Decl_getResultType(const Decl *D, ASTContext *Ctx) { - auto Ty = Decl_getType(D, Ctx); - if (!Ty.isNull()) - if (auto *FT = Ty->getAs()) - return make_type_compatible(FT->getReturnType()); - return QualType(); + if (auto *MD = dyn_cast_or_null(D)) + return MD->getReturnType(); + + return Type_getResultType(Decl_getType(D, Ctx)); } // const Decl *Expr_getSemanticParent(const Expr *E) { From ae382f1d95e735e104128b8274c4e814f879d243 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 18:52:37 -0800 Subject: [PATCH 41/88] Support Objective-C categories and references --- src/clang/ClangAST.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index e07a6b383b..6bfb4bce31 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -568,6 +568,14 @@ const Decl *Decl_getReferenced(const Decl *D) { const Decl *Decl_getCanonical(const Decl *D) { if (!D) return nullptr; + if (const ObjCCategoryImplDecl *CatImplD = dyn_cast(D)) + if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl()) + return CatD; + + if (const ObjCImplDecl *ImplD = dyn_cast(D)) + if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) + return IFD; + return D->getCanonicalDecl(); } @@ -1526,6 +1534,17 @@ class BindgenVisitor : public RecursiveASTVisitor { && isa(D)) skip = true; + // libclang exposes forward class and protocol declarations as references + if (kind == CXCursor_ObjCInterfaceDecl) { + auto *ID = cast(D); + if (!ID->isThisDeclarationADefinition()) + kind = CXCursor_ObjCClassRef; + } else if (kind == CXCursor_ObjCProtocolDecl) { + auto *PD = cast(D); + if (!PD->isThisDeclarationADefinition()) + kind = CXCursor_ObjCProtocolRef; + } + // D->dump(); Node node(D, kind); if (!skip) { @@ -1602,6 +1621,11 @@ class BindgenVisitor : public RecursiveASTVisitor { return true; } + bool VisitTypeLoc(TypeLoc TL) { + // if (TL) TL.getTypePtr()->dump(); + return true; + } + bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { if (!TL) return true; @@ -1747,6 +1771,32 @@ class BindgenVisitor : public RecursiveASTVisitor { return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec); } + bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { + Node interfaceNode(ND->getClassInterface(), CXCursor_ObjCClassRef); + if (VisitFn(interfaceNode, Parent, &AST, Data) == CXChildVisit_Break) + return false; + + // TypeParamList is visited in RecursiveASTvisitor + + for (auto I : ND->protocols()) + if (VisitFn(Node(&*I, CXCursor_ObjCProtocolRef), Parent, &AST, Data) == CXChildVisit_Break) + return false; + + // We may need to do the weird hacky thing that the libclang visitor does in + // VisitObjCContainerDecl, but I hope not... + return true; + } + + bool VisitObjCProtocolDecl(ObjCProtocolDecl *PD) { + for (auto I : PD->protocols()) + if (VisitFn(Node(&*I, CXCursor_ObjCProtocolRef), Parent, &AST, Data) == CXChildVisit_Break) + return false; + + // We may need to do the weird hacky thing that the libclang visitor does in + // VisitObjCContainerDecl, but I hope not... + return true; + } + private: template bool visitPreprocessedEntities(InputIterator First, InputIterator Last, From 1ed07816209ae323bd035658a18d140fc6561148 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 20 Feb 2020 22:48:39 -0800 Subject: [PATCH 42/88] Handle Objective-C id, class, and sel types correctly --- src/clang.rs | 2 +- src/clang/ClangAST.cpp | 44 +++++++++++++++++++++++++++++++++++++++++- src/clang/ClangAST.hpp | 2 +- src/clang/clangtool.rs | 7 +++++-- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index 6da9fdd98a..bdda391c10 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -1221,7 +1221,7 @@ impl Type { /// Get this type's kind. pub fn kind(&self) -> CXTypeKind { - unsafe { clangtool::Type_kind(self.x) } + unsafe { clangtool::Type_kind(self.x, self.context()) } } /// Get a cursor pointing to this type's declaration. diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 6bfb4bce31..c40fc4924f 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1683,6 +1683,36 @@ class BindgenVisitor : public RecursiveASTVisitor { return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); } + bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { + if (!TL) + return true; + + ASTContext &Context = AST.getASTContext(); + QualType Ty; + switch (TL.getTypePtr()->getKind()) { + case BuiltinType::ObjCId: + Ty = Context.getObjCIdType(); + break; + case BuiltinType::ObjCClass: + Ty = Context.getObjCClassType(); + break; + case BuiltinType::ObjCSel: + Ty = Context.getObjCSelType(); + break; + default: + break; + } + + if (!Ty.isNull()) { + if (auto *TD = Ty->getAs()) { + Node node(TD->getDecl(), CXCursor_TypeRef); + return VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break; + } + } + + return true; + } + bool TraverseTemplateName(TemplateName Name) { Node node; switch (Name.getKind()) { @@ -2036,11 +2066,23 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { #undef BTCASE } -CXTypeKind Type_kind(QualType T) { +CXTypeKind Type_kind(QualType T, ASTContext *Context) { const Type *TP = T.getTypePtrOrNull(); if (!TP) return CXType_Invalid; + // libclang checks for these builtin types specially and matches on things + // that appear to be correct + if (Context->getLangOpts().ObjC) { + QualType UT = T.getUnqualifiedType(); + if (Context->isObjCIdType(UT)) + return CXType_ObjCId; + if (Context->isObjCClassType(UT)) + return CXType_ObjCClass; + if (Context->isObjCSelType(UT)) + return CXType_ObjCSel; + } + #define TKCASE(K) case Type::K: return CXType_##K switch (TP->getTypeClass()) { case Type::Builtin: diff --git a/src/clang/ClangAST.hpp b/src/clang/ClangAST.hpp index 43d484941d..4aaa36015a 100644 --- a/src/clang/ClangAST.hpp +++ b/src/clang/ClangAST.hpp @@ -209,7 +209,7 @@ void disposeTokens(const ASTUnit *TU, CXToken *Tokens, unsigned NumTokens); CXTokenKind getTokenKind(CXToken token); BindgenStringRef getTokenSpelling(ASTUnit *TU, CXToken token); -CXTypeKind Type_kind(QualType); +CXTypeKind Type_kind(QualType, ASTContext *); BindgenStringRef Type_getTypeSpelling(QualType, ASTContext *); bool Type_isConstQualifiedType(QualType); long long Type_getSizeOf(QualType, ASTContext *); diff --git a/src/clang/clangtool.rs b/src/clang/clangtool.rs index 9bca6a1684..b60ba24cfe 100644 --- a/src/clang/clangtool.rs +++ b/src/clang/clangtool.rs @@ -7042,8 +7042,11 @@ extern "C" { ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z9Type_kindN5clang8QualTypeE"] - pub fn Type_kind(arg1: clang_QualType) -> CXTypeKind::Type; + #[link_name = "\u{1}_Z9Type_kindN5clang8QualTypeEPNS_10ASTContextE"] + pub fn Type_kind( + arg1: clang_QualType, + arg2: *mut clang_ASTContext, + ) -> CXTypeKind::Type; } extern "C" { #[link_name = "\u{1}_Z20Type_getTypeSpellingN5clang8QualTypeEPNS_10ASTContextE"] From 8c0ffe38e57ab6fbe36b2616ed41471a83740f1e Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 21 Feb 2020 00:23:35 -0800 Subject: [PATCH 43/88] Visit more Objective-C AST nodes --- src/clang/ClangAST.cpp | 90 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index c40fc4924f..281fc59a40 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1524,7 +1524,7 @@ class BindgenVisitor : public RecursiveASTVisitor { } bool TraverseDeclTyped(Decl *D, CXCursorKind kind) { - if (!D || D->isImplicit()) + if (!D || (D->isImplicit() && !isa(D))) return true; bool skip = !Parent; @@ -1713,6 +1713,40 @@ class BindgenVisitor : public RecursiveASTVisitor { return true; } + bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { + if (!TL) + return true; + + return TraverseDeclTyped(TL.getIFaceDecl(), CXCursor_ObjCClassRef); + } + + bool VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) { + if (!TL) + return true; + Node node(TL.getDecl(), CXCursor_TypeRef); + if (VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break) + return false; + for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { + Node node(TL.getProtocol(I), CXCursor_ObjCProtocolRef); + if (VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break) + return false; + } + return true; + } + + bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { + if (!TL) + return true; + + for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { + Node node(TL.getProtocol(I), CXCursor_ObjCProtocolRef); + if (VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break) + return false; + } + + return true; + } + bool TraverseTemplateName(TemplateName Name) { Node node; switch (Name.getKind()) { @@ -1801,6 +1835,22 @@ class BindgenVisitor : public RecursiveASTVisitor { return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec); } + bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { + // We handle forward declarations in TraverseDecl + if (!D || !D->isThisDeclarationADefinition()) + return true; + + if (D->getSuperClass() + && VisitFn(Node(D->getSuperClass(), CXCursor_ObjCSuperClassRef), Parent, &AST, Data) == CXChildVisit_Break) + return false; + + for (auto I : D->protocols()) + if (VisitFn(Node(&*I, CXCursor_ObjCProtocolRef), Parent, &AST, Data) == CXChildVisit_Break) + return false; + + return true; + } + bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { Node interfaceNode(ND->getClassInterface(), CXCursor_ObjCClassRef); if (VisitFn(interfaceNode, Parent, &AST, Data) == CXChildVisit_Break) @@ -1827,6 +1877,44 @@ class BindgenVisitor : public RecursiveASTVisitor { return true; } + bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD) { + if (!PD) + return true; + + // FIXME: This implements a workaround with @property declarations also + // being + // installed in the DeclContext for the @interface. Eventually this code + // should be removed. + ObjCCategoryDecl *CDecl = dyn_cast(PD->getDeclContext()); + if (!CDecl || !CDecl->IsClassExtension()) + return true; + + ObjCInterfaceDecl *ID = CDecl->getClassInterface(); + if (!ID) + return true; + + IdentifierInfo *PropertyId = PD->getIdentifier(); + ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl( + cast(ID), PropertyId, PD->getQueryKind()); + + if (!prevDecl) + return true; + + // Visit synthesized methods since they will be skipped when visiting + // the @interface. + if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl()) + if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl) + if (!TraverseDecl(MD)) + return false; + + if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl()) + if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl) + if (!TraverseDecl(MD)) + return false; + + return true; + } + private: template bool visitPreprocessedEntities(InputIterator First, InputIterator Last, From e0ed47a64b29842505645968eaf12964bd517779 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 21 Feb 2020 00:56:53 -0800 Subject: [PATCH 44/88] Sanitize a couple more type return sites --- src/clang/ClangAST.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 281fc59a40..f6e915f663 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -795,11 +795,11 @@ static QualType make_type_compatible(QualType QT) { // CXTranslationUnit_IncludeAttributedTypes is not set, and bindgen assumes it // is not set. if (auto *ATT = QT->getAs()) - return ATT->getEquivalentType(); + return make_type_compatible(ATT->getEquivalentType()); // libclang does not return ParenTypes if (auto *PTT = QT->getAs()) - return PTT->getInnerType(); + return make_type_compatible(PTT->getInnerType()); return QT; } @@ -1006,7 +1006,7 @@ bool CXXMethod_isPureVirtual(const Decl *D) { QualType Decl_getResultType(const Decl *D, ASTContext *Ctx) { if (auto *MD = dyn_cast_or_null(D)) - return MD->getReturnType(); + return make_type_compatible(MD->getReturnType()); return Type_getResultType(Decl_getType(D, Ctx)); } From 137e47eeb9fb3f536f59cee43fefcce3e490a15f Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 21 Feb 2020 01:21:16 -0800 Subject: [PATCH 45/88] Explicitly visit ObjCTypeParamDecls RecursiveASTVisitor doesn't call TraverseDecl for these, it calls TraverseObjCTypeParamDecl directly, so we need to intercept this at the Visit function. --- src/clang/ClangAST.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index f6e915f663..6ec8057faf 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1915,6 +1915,12 @@ class BindgenVisitor : public RecursiveASTVisitor { return true; } + bool VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) { + if (!D) + return true; + return TraverseDecl(D) != CXChildVisit_Break; + } + private: template bool visitPreprocessedEntities(InputIterator First, InputIterator Last, From 919124d99364a491aede76e9d34817bc3bd714ab Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 21 Feb 2020 01:22:28 -0800 Subject: [PATCH 46/88] Fix incorrect comparison for break value --- src/clang/ClangAST.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 6ec8057faf..5865b08133 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1706,7 +1706,7 @@ class BindgenVisitor : public RecursiveASTVisitor { if (!Ty.isNull()) { if (auto *TD = Ty->getAs()) { Node node(TD->getDecl(), CXCursor_TypeRef); - return VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break; + return VisitFn(node, Parent, &AST, Data) != CXChildVisit_Break; } } From 6115d41c3fe37ccc6005ca6464b22355fcb5ba0b Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 21 Feb 2020 02:08:20 -0800 Subject: [PATCH 47/88] Fix warning --- src/clang.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clang.rs b/src/clang.rs index bdda391c10..ba77cec5a0 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -260,7 +260,7 @@ impl Cursor { ASTNode::Decl(d) => unsafe { ASTNode::Decl(clangtool::Decl_getSemanticParent(d)) }, - ASTNode::Expr(e) => panic!("Unimplemented for Expr"), + ASTNode::Expr(_) => panic!("Unimplemented for Expr"), _ => return None, }; if node == self.node || !node.is_valid() { From 2c28a58c05f6721f8e2eee9260c0f8a4e07b420e Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 21 Feb 2020 02:08:32 -0800 Subject: [PATCH 48/88] Implement support for parsing of unsaved files --- src/clang.rs | 2 ++ src/clang/ClangAST.cpp | 31 ++++++++++++++++++++++++++----- src/clang/ClangAST.hpp | 5 +++-- src/clang/clangtool.rs | 4 +++- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index ba77cec5a0..b46364ec38 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -1870,6 +1870,8 @@ impl TranslationUnit { c_args.as_ptr(), c_args.len() as c_int, opts, + c_unsaved.as_mut_ptr(), + c_unsaved.len() as c_uint, ) }; if tu.is_null() { diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 5865b08133..142f2cad6e 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -1,5 +1,6 @@ #include +#include "llvm/Support/CrashRecoveryContext.h" #include "clang/AST/Comment.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclFriend.h" @@ -133,12 +134,25 @@ ASTContext *ASTUnit_getContext(ASTUnit *Unit) { ASTUnit *parseTranslationUnit(const char *source_filename, const char *const *command_line_args, - int num_command_line_args, - int options) { + int num_command_line_args, int options, + struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files) { SmallVector Args; Args.push_back("clang"); Args.append(command_line_args, command_line_args + num_command_line_args); + std::unique_ptr> RemappedFiles( + new std::vector()); + // Recover resources if we crash before exiting this function. + llvm::CrashRecoveryContextCleanupRegistrar< + std::vector > RemappedCleanup(RemappedFiles.get()); + + for (auto &UF : llvm::makeArrayRef(unsaved_files, num_unsaved_files)) { + std::unique_ptr MB = + llvm::MemoryBuffer::getMemBufferCopy(StringRef(UF.Contents, UF.Length), UF.Filename); + RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release())); + } + // Configure the diagnostics. IntrusiveRefCntPtr Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); @@ -161,8 +175,11 @@ ASTUnit *parseTranslationUnit(const char *source_filename, PPOpts.DetailedRecord = true; } - return ASTUnit::LoadFromCompilerInvocationAction( - std::move(Invoc), std::make_shared(), Diags); + return ASTUnit::LoadFromCommandLine( + Args.data(), Args.data() + Args.size(), + std::make_shared(), Diags, StringRef(), + /*OnlyLocalDecls*/ false, CaptureDiagnostics, *RemappedFiles.get(), + /*RemappedFilesKeepOriginalName*/ true); } void disposeASTUnit(ASTUnit *AU) { @@ -801,6 +818,10 @@ static QualType make_type_compatible(QualType QT) { if (auto *PTT = QT->getAs()) return make_type_compatible(PTT->getInnerType()); + // Decayed types should be passed as their original type + if (auto *DT = QT->getAs()) + return make_type_compatible(DT->getOriginalType()); + return QT; } @@ -2317,7 +2338,7 @@ QualType Type_getArgType(QualType T, unsigned i) { unsigned numParams = FD->getNumParams(); if (i >= numParams) return QualType(); - + // FD->getParamType(i)->dump(); return make_type_compatible(FD->getParamType(i)); } diff --git a/src/clang/ClangAST.hpp b/src/clang/ClangAST.hpp index 4aaa36015a..03ae701031 100644 --- a/src/clang/ClangAST.hpp +++ b/src/clang/ClangAST.hpp @@ -73,8 +73,9 @@ char *cString(BindgenStringRef s); ASTContext *ASTUnit_getContext(ASTUnit *); ASTUnit *parseTranslationUnit(const char *source_filename, const char *const *command_line_args, - int num_command_line_args, - int options); + int num_command_line_args, int options, + CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files); void disposeASTUnit(ASTUnit *AU); unsigned ASTUnit_getNumDiagnostics(const ASTUnit *AU); const StoredDiagnostic *ASTUnit_getDiagnostic(const ASTUnit *AU, unsigned i); diff --git a/src/clang/clangtool.rs b/src/clang/clangtool.rs index b60ba24cfe..f77dcb291d 100644 --- a/src/clang/clangtool.rs +++ b/src/clang/clangtool.rs @@ -6491,12 +6491,14 @@ extern "C" { ) -> *mut clang_ASTContext; } extern "C" { - #[link_name = "\u{1}_Z20parseTranslationUnitPKcPKS0_ii"] + #[link_name = "\u{1}_Z20parseTranslationUnitPKcPKS0_iiP13CXUnsavedFilej"] pub fn parseTranslationUnit( source_filename: *const ::std::os::raw::c_char, command_line_args: *const *const ::std::os::raw::c_char, num_command_line_args: ::std::os::raw::c_int, options: ::std::os::raw::c_int, + unsaved_files: *mut CXUnsavedFile, + num_unsaved_files: ::std::os::raw::c_uint, ) -> *mut clang_ASTUnit; } extern "C" { From 4ea460900cd969fe034b7de27d5ba31fd7f01303 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 21 Feb 2020 13:40:07 -0800 Subject: [PATCH 49/88] Use command-line args to tell preprocessor to keep detailed records We used to build a CompilerInvocation and directly set the preprocessor option to keep detailed records, but we can just tack on CLI args for the same thing. --- src/clang/ClangAST.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 142f2cad6e..990f772e52 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -164,20 +164,16 @@ ASTUnit *parseTranslationUnit(const char *source_filename, if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles) CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes; - auto Invoc = createInvocationFromCommandLine(Args, Diags); - if (!Invoc) - return nullptr; - - auto &PPOpts = Invoc->getPreprocessorOpts(); - if (options & CXTranslationUnit_DetailedPreprocessingRecord) { // Tell the preprocessor to save a detailed preprocessing record - PPOpts.DetailedRecord = true; + Args.push_back("-Xclang"); + Args.push_back("-detailed-preprocessing-record"); } return ASTUnit::LoadFromCommandLine( Args.data(), Args.data() + Args.size(), - std::make_shared(), Diags, StringRef(), + std::make_shared(), Diags, + /*ResourceFilePath*/ StringRef(), /*OnlyLocalDecls*/ false, CaptureDiagnostics, *RemappedFiles.get(), /*RemappedFilesKeepOriginalName*/ true); } From 5c2d4f9ed2606eeb8bfb1b0f3475d298bc547921 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 21 Feb 2020 16:08:57 -0800 Subject: [PATCH 50/88] Clean up build script --- build.rs | 74 ++++++++++++++++++++++------------------ src/clang/CMakeLists.txt | 10 +++--- 2 files changed, 45 insertions(+), 39 deletions(-) diff --git a/build.rs b/build.rs index 528977e89e..1fc104ae14 100644 --- a/build.rs +++ b/build.rs @@ -81,6 +81,11 @@ mod clang_ast { build_native(&llvm_info); } + fn build_var(name: &str) -> Option { + println!("cargo:rerun-if-env-changed={}", name); + env::var(name).ok() + } + /// Call out to CMake, build the clang ast library, and tell cargo where to look /// for it. Note that `CMAKE_BUILD_TYPE` gets implicitly determined by the /// cmake crate according to the following: @@ -93,32 +98,28 @@ mod clang_ast { println!("cargo:rerun-if-changed=src/clang/ClangAST.cpp"); println!("cargo:rerun-if-changed=src/clang/ClangAST.hpp"); - // Build libclangAst.a with cmake + // Build libbindgenClangAST.a with cmake let dst = cmake::Config::new("src/clang") - // Where to find LLVM/Clang CMake files .define("LLVM_DIR", &format!("{}/cmake/llvm", llvm_lib_dir)) .define("Clang_DIR", &format!("{}/cmake/clang", llvm_lib_dir)) - // What to build - .build_target("clangAst") + .build_target("bindgenClangAST") .build(); let out_dir = dst.display(); - // Set up search path for newly built libclangAst.a + // Set up search path for newly built libbindgenClangAST.a println!("cargo:rustc-link-search=native={}/build/lib", out_dir); println!("cargo:rustc-link-search=native={}/build", out_dir); - // Statically link against 'clangAst' - println!("cargo:rustc-link-lib=static=clangAst"); + // Statically link against our library, 'bindgenClangAST' + println!("cargo:rustc-link-lib=static=bindgenClangAST"); // Link against these Clang libs. The ordering here is important! Libraries // must be listed before their dependencies when statically linking. println!("cargo:rustc-link-search=native={}", llvm_lib_dir); for lib in &[ "clangIndex", - "clangTooling", "clangFrontend", - "clangASTMatchers", "clangParse", "clangSerialization", "clangSema", @@ -128,7 +129,6 @@ mod clang_ast { "clangFormat", "clangToolingCore", "clangAST", - "clangRewrite", "clangLex", "clangBasic", ] { @@ -163,10 +163,9 @@ mod clang_ast { fn new() -> Self { fn find_llvm_config() -> Option { // Explicitly provided path in LLVM_CONFIG_PATH - env::var("LLVM_CONFIG_PATH") - .ok() + build_var("LLVM_CONFIG_PATH") // Relative to LLVM_LIB_DIR - .or(env::var("LLVM_LIB_DIR").ok().map(|d| { + .or(build_var("LLVM_LIB_DIR").map(|d| { String::from( Path::new(&d) .join("../bin/llvm-config") @@ -200,10 +199,11 @@ mod clang_ast { } /// Invoke given `command`, if any, with the specified arguments. - fn invoke_command(command: Option<&String>, args: I) -> Option + fn invoke_command(command: Option, args: I) -> Option where I: IntoIterator, S: AsRef, + C: AsRef, { command.and_then(|c| { Command::new(c).args(args).output().ok().and_then(|output| { @@ -218,8 +218,7 @@ mod clang_ast { let llvm_config = find_llvm_config(); let lib_dir = { - let path_str = env::var("LLVM_LIB_DIR") - .ok() + let path_str = build_var("LLVM_LIB_DIR") .or(invoke_command(llvm_config.as_ref(), &["--libdir"])) .expect( " @@ -292,31 +291,38 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: "--link-shared" }; + let llvm_version = invoke_command(llvm_config.as_ref(), &["--version"]); + + let llvm_major_version = llvm_version + .and_then(|version| { + let major: i32 = version.split(".").next()?.parse().ok()?; + Some(major) + }); + + // LLVM components that we need to link against for the clang libs + let mut llvm_components = vec![ + "MC", + "MCParser", + "Support", + "Option", + "BitReader", + "ProfileData", + "BinaryFormat", + "Core", + ]; + // Construct the list of libs we need to link against - let mut libs: Vec = invoke_command( - llvm_config.as_ref(), - &[ - "--libs", - link_mode, - "MC", - "MCParser", - "Support", - "Option", - "BitReader", - "ProfileData", - "BinaryFormat", - "Core", - "FrontendOpenMP", - ], - ) + let mut args = llvm_components; + args.insert(0, "--libs"); + args.insert(1, link_mode); + let mut libs: Vec = invoke_command(llvm_config.as_ref(), &args) .unwrap_or("-lLLVM".to_string()) .split_whitespace() .map(|lib| String::from(lib.trim_start_matches("-l"))) .collect(); libs.extend( - env::var("LLVM_SYSTEM_LIBS") - .ok() + build_var("LLVM_SYSTEM_LIBS") .or(invoke_command( llvm_config.as_ref(), &[ diff --git a/src/clang/CMakeLists.txt b/src/clang/CMakeLists.txt index 3565fc30ad..9b524fa459 100644 --- a/src/clang/CMakeLists.txt +++ b/src/clang/CMakeLists.txt @@ -10,7 +10,7 @@ if( PROJECT_NAME STREQUAL "LLVM" ) add_definitions(-DCLANG_BIN_PATH="${CMAKE_INSTALL_PREFIX}/bin") - add_clang_library(clangAst ${SRCS} DEPENDS clang-headers) + add_clang_library(bindgenClangAST ${SRCS} DEPENDS clang-headers) set(LLVM_LINK_COMPONENTS support) else() @@ -40,23 +40,23 @@ else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") # The library - add_library(clangAst STATIC ${SRCS}) + add_library(bindgenClangAST STATIC ${SRCS}) endif() add_definitions(-DCLANG_LIBDIR_SUFFIX="${LLVM_LIBDIR_SUFFIX}") -set_target_properties(clangAst PROPERTIES +set_target_properties(bindgenClangAST PROPERTIES CXX_STANDARD 14 CXX_EXTENSIONS OFF ) # PRIVATE was added to make clangAst build with LLVM 6.0. Keyword # description: https://cmake.org/pipermail/cmake/2016-May/063400.html -target_link_libraries(clangAst PRIVATE +target_link_libraries(bindgenClangAST PRIVATE clangAST clangFrontend clangIndex + clangSema clangTooling clangBasic - clangASTMatchers ) From 2334ffcee48c959772ee9ae2b169b63cb95de6f0 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 21 Feb 2020 16:09:03 -0800 Subject: [PATCH 51/88] Don't try to link against LLVM FrontendOpenMP component for LLVM version <= 9 --- build.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build.rs b/build.rs index 1fc104ae14..fd5d93c557 100644 --- a/build.rs +++ b/build.rs @@ -311,6 +311,13 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: "Core", ]; + // llvmAST requires FrontendOpenMP from version 10 and newer + if let Some(version) = llvm_major_version { + if version > 9 { + llvm_components.push("FrontendOpenMP"); + } + } + // Construct the list of libs we need to link against let mut args = llvm_components; args.insert(0, "--libs"); From 272ef10069dea274cbbf762896a5b7e9acc2ae83 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 21 Feb 2020 16:09:43 -0800 Subject: [PATCH 52/88] Guard OpenCLExtensionTypes for only clang version 9+ --- src/clang/ClangAST.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/clang/ClangAST.cpp b/src/clang/ClangAST.cpp index 990f772e52..dd55a2b0e1 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/ClangAST.cpp @@ -2165,8 +2165,10 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) BTCASE(Id); #include "clang/Basic/OpenCLImageTypes.def" #undef IMAGE_TYPE +#if CLANG_VERSION_MAJOR > 8 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) BTCASE(Id); #include "clang/Basic/OpenCLExtensionTypes.def" +#endif // CLANG_VERSION_MAJOR > 8 BTCASE(OCLSampler); BTCASE(OCLEvent); BTCASE(OCLQueue); From 9fc99748bfe0284c1b588dc6c73c829c4f52e654 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 21 Feb 2020 17:21:42 -0800 Subject: [PATCH 53/88] Reorganize clang interface and extract LLVM code --- build.rs | 16 +- src/clang.rs | 380 +- src/clang/CMakeLists.txt | 15 +- src/clang/clang_interface.cpp | 1545 +++++++ .../{ClangAST.hpp => clang_interface.hpp} | 5 + .../{clangtool.rs => clang_interface.rs} | 0 src/clang/clang_interface_impl.hpp | 27 + .../{ClangAST.cpp => libclang_compat.cpp} | 3991 +++++------------ 8 files changed, 3024 insertions(+), 2955 deletions(-) create mode 100644 src/clang/clang_interface.cpp rename src/clang/{ClangAST.hpp => clang_interface.hpp} (99%) rename src/clang/{clangtool.rs => clang_interface.rs} (100%) create mode 100644 src/clang/clang_interface_impl.hpp rename src/clang/{ClangAST.cpp => libclang_compat.cpp} (57%) diff --git a/build.rs b/build.rs index fd5d93c557..94e5892bbd 100644 --- a/build.rs +++ b/build.rs @@ -96,23 +96,25 @@ mod clang_ast { // Find where the (already built) LLVM lib dir is let llvm_lib_dir = &llvm_info.lib_dir; - println!("cargo:rerun-if-changed=src/clang/ClangAST.cpp"); - println!("cargo:rerun-if-changed=src/clang/ClangAST.hpp"); - // Build libbindgenClangAST.a with cmake + println!("cargo:rerun-if-changed=src/clang/clang_interface.hpp"); + println!("cargo:rerun-if-changed=src/clang/clang_interface_impl.hpp"); + println!("cargo:rerun-if-changed=src/clang/clang_interface.cpp"); + println!("cargo:rerun-if-changed=src/clang/libclang_compat.cpp"); + // Build libBindgenClangInterface.a with cmake let dst = cmake::Config::new("src/clang") .define("LLVM_DIR", &format!("{}/cmake/llvm", llvm_lib_dir)) .define("Clang_DIR", &format!("{}/cmake/clang", llvm_lib_dir)) - .build_target("bindgenClangAST") + .build_target("BindgenClangInterface") .build(); let out_dir = dst.display(); - // Set up search path for newly built libbindgenClangAST.a + // Set up search path for newly built libBindgenClangInterface.a println!("cargo:rustc-link-search=native={}/build/lib", out_dir); println!("cargo:rustc-link-search=native={}/build", out_dir); - // Statically link against our library, 'bindgenClangAST' - println!("cargo:rustc-link-lib=static=bindgenClangAST"); + // Statically link against our library, 'BindgenClangInterface' + println!("cargo:rustc-link-lib=static=BindgenClangInterface"); // Link against these Clang libs. The ordering here is important! Libraries // must be listed before their dependencies when statically linking. diff --git a/src/clang.rs b/src/clang.rs index b46364ec38..6e00519614 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -14,31 +14,31 @@ use std::os::raw::{c_char, c_int, c_longlong, c_uint, c_ulong, c_ulonglong}; use std::{mem, ptr, slice}; #[allow(non_camel_case_types, non_snake_case)] -mod clangtool; -pub use self::clangtool::CXDiagnosticSeverity::Type as CXDiagnosticSeverity; -pub use self::clangtool::CXCallingConv::Type as CXCallingConv; -pub use self::clangtool::CXLinkageKind::Type as CXLinkageKind; -pub use self::clangtool::CX_CXXAccessSpecifier::Type as CX_CXXAccessSpecifier; -pub use self::clangtool::CXEvalResultKind::Type as CXEvalResultKind; -pub use self::clangtool::CXTokenKind::Type as CXTokenKind; -pub use self::clangtool::CXVisibilityKind::Type as CXVisibilityKind; -pub use self::clangtool::CXChildVisitResult::Type as CXChildVisitResult; -pub use self::clangtool::CXCursorKind::Type as CXCursorKind; -pub use self::clangtool::CXTypeKind::Type as CXTypeKind; -pub use self::clangtool::CXCommentKind::*; -pub use self::clangtool::CXDiagnosticSeverity::*; -pub use self::clangtool::CXCallingConv::*; -pub use self::clangtool::CX_CXXAccessSpecifier::*; -pub use self::clangtool::CXChildVisitResult::*; -pub use self::clangtool::CXCursorKind::*; -pub use self::clangtool::CXEvalResultKind::*; -pub use self::clangtool::CXLinkageKind::*; -pub use self::clangtool::CXTypeKind::*; -pub use self::clangtool::CXTokenKind::*; -pub use self::clangtool::CXVisitorResult::*; -pub use self::clangtool::CXVisibilityKind::*; - -impl clangtool::BindgenSourceRange { +mod clang_interface; +pub use self::clang_interface::CXDiagnosticSeverity::Type as CXDiagnosticSeverity; +pub use self::clang_interface::CXCallingConv::Type as CXCallingConv; +pub use self::clang_interface::CXLinkageKind::Type as CXLinkageKind; +pub use self::clang_interface::CX_CXXAccessSpecifier::Type as CX_CXXAccessSpecifier; +pub use self::clang_interface::CXEvalResultKind::Type as CXEvalResultKind; +pub use self::clang_interface::CXTokenKind::Type as CXTokenKind; +pub use self::clang_interface::CXVisibilityKind::Type as CXVisibilityKind; +pub use self::clang_interface::CXChildVisitResult::Type as CXChildVisitResult; +pub use self::clang_interface::CXCursorKind::Type as CXCursorKind; +pub use self::clang_interface::CXTypeKind::Type as CXTypeKind; +pub use self::clang_interface::CXCommentKind::*; +pub use self::clang_interface::CXDiagnosticSeverity::*; +pub use self::clang_interface::CXCallingConv::*; +pub use self::clang_interface::CX_CXXAccessSpecifier::*; +pub use self::clang_interface::CXChildVisitResult::*; +pub use self::clang_interface::CXCursorKind::*; +pub use self::clang_interface::CXEvalResultKind::*; +pub use self::clang_interface::CXLinkageKind::*; +pub use self::clang_interface::CXTypeKind::*; +pub use self::clang_interface::CXTokenKind::*; +pub use self::clang_interface::CXVisitorResult::*; +pub use self::clang_interface::CXVisibilityKind::*; + +impl clang_interface::BindgenSourceRange { fn null() -> Self { Self { B: ptr::null_mut(), E: ptr::null_mut() } } @@ -48,7 +48,7 @@ trait ToCString { fn to_cstring(&self) -> CString; } -impl ToCString for clangtool::BindgenStringRef { +impl ToCString for clang_interface::BindgenStringRef { fn to_cstring(&self) -> CString { if !self.s.is_null() { unsafe { CStr::from_ptr(self.s).into() } @@ -58,7 +58,7 @@ impl ToCString for clangtool::BindgenStringRef { } } -impl fmt::Display for clangtool::BindgenStringRef { +impl fmt::Display for clang_interface::BindgenStringRef { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let str = self.to_cstring(); write!(f, "{}", str.to_str().unwrap()) @@ -72,32 +72,32 @@ impl fmt::Display for clangtool::BindgenStringRef { pub struct Cursor { node: ASTNode, kind: CXCursorKind, - unit: *mut clangtool::clang_ASTUnit, + unit: *mut clang_interface::clang_ASTUnit, } #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub enum ASTNode { Invalid, - Decl(*const clangtool::clang_Decl), - Expr(*const clangtool::clang_Expr), - CXXBaseSpecifier(*const clangtool::clang_CXXBaseSpecifier), - Attr(*const clangtool::clang_Attr), - PreprocessedEntity(*const clangtool::clang_PreprocessedEntity), + Decl(*const clang_interface::clang_Decl), + Expr(*const clang_interface::clang_Expr), + CXXBaseSpecifier(*const clang_interface::clang_CXXBaseSpecifier), + Attr(*const clang_interface::clang_Attr), + PreprocessedEntity(*const clang_interface::clang_PreprocessedEntity), } impl ASTNode { /// Is this node valid? fn is_valid(&self) -> bool { - unsafe { !clangtool::CursorKind_isInvalid(self.kind()) } + unsafe { !clang_interface::CursorKind_isInvalid(self.kind()) } } fn kind(&self) -> CXCursorKind { unsafe { match *self { - ASTNode::Decl(d) => clangtool::Decl_getCXCursorKind(d), - ASTNode::Expr(e) => clangtool::Expr_getCXCursorKind(e), + ASTNode::Decl(d) => clang_interface::Decl_getCXCursorKind(d), + ASTNode::Expr(e) => clang_interface::Expr_getCXCursorKind(e), ASTNode::CXXBaseSpecifier(_) => CXCursor_CXXBaseSpecifier, - ASTNode::Attr(a) => clangtool::Attr_getCXCursorKind(a), + ASTNode::Attr(a) => clang_interface::Attr_getCXCursorKind(a), _ => CXCursor_InvalidFile, } } @@ -118,7 +118,7 @@ impl fmt::Debug for Cursor { } impl Cursor { - fn new(node: ASTNode, unit: *mut clangtool::clang_ASTUnit) -> Self { + fn new(node: ASTNode, unit: *mut clang_interface::clang_ASTUnit) -> Self { Self { node, kind: node.kind(), @@ -130,8 +130,8 @@ impl Cursor { Self::new(node, self.unit) } - fn context(&self) -> *mut clangtool::clang_ASTContext { - unsafe { clangtool::ASTUnit_getContext(self.unit) } + fn context(&self) -> *mut clang_interface::clang_ASTContext { + unsafe { clang_interface::ASTUnit_getContext(self.unit) } } /// Get the Unified Symbol Resolution for this cursor's referent, if @@ -141,7 +141,7 @@ impl Cursor { pub fn usr(&self) -> Option { let s = unsafe { match self.node { - ASTNode::Decl(d) => clangtool::Decl_getUSR(d), + ASTNode::Decl(d) => clang_interface::Decl_getUSR(d), _ => return None, } }; @@ -165,9 +165,9 @@ impl Cursor { pub fn spelling(&self) -> String { unsafe { match self.node { - ASTNode::Decl(d) => clangtool::Decl_getSpelling(d).to_string(), - ASTNode::Expr(e) => clangtool::Expr_getSpelling(e).to_string(), - ASTNode::CXXBaseSpecifier(b) => clangtool::CXXBaseSpecifier_getSpelling(b) + ASTNode::Decl(d) => clang_interface::Decl_getSpelling(d).to_string(), + ASTNode::Expr(e) => clang_interface::Expr_getSpelling(e).to_string(), + ASTNode::CXXBaseSpecifier(b) => clang_interface::CXXBaseSpecifier_getSpelling(b) .to_string(), _ => String::new(), } @@ -181,8 +181,8 @@ impl Cursor { // pub fn display_name(&self) -> String { // unsafe { // match self.node { - // ASTNode::Decl(d) => clangtool::Decl_getDisplayName(d).to_string(), - // ASTNode::Expr(e) => clangtool::Expr_getDisplayName(e).to_string(), + // ASTNode::Decl(d) => clang_interface::Decl_getDisplayName(d).to_string(), + // ASTNode::Expr(e) => clang_interface::Expr_getDisplayName(e).to_string(), // _ => String::new(), // } // } @@ -192,7 +192,7 @@ impl Cursor { pub fn mangling(&self) -> String { unsafe { match self.node { - ASTNode::Decl(d) => clangtool::Decl_getMangling(d, self.context()).to_string(), + ASTNode::Decl(d) => clang_interface::Decl_getMangling(d, self.context()).to_string(), _ => String::new(), } } @@ -203,7 +203,7 @@ impl Cursor { pub fn cxx_manglings(&self) -> Result, ()> { unsafe { let manglings = match self.node { - ASTNode::Decl(d) => clangtool::Decl_getCXXManglings(d, self.context()), + ASTNode::Decl(d) => clang_interface::Decl_getCXXManglings(d, self.context()), _ => return Err(()), }; let count = manglings.len as usize; @@ -244,7 +244,7 @@ impl Cursor { pub fn lexical_parent(&self) -> Cursor { let node = match self.node { ASTNode::Decl(d) => unsafe { - ASTNode::Decl(clangtool::Decl_getLexicalParent(d)) + ASTNode::Decl(clang_interface::Decl_getLexicalParent(d)) }, _ => ASTNode::Invalid, }; @@ -258,7 +258,7 @@ impl Cursor { pub fn fallible_semantic_parent(&self) -> Option { let node = match self.node { ASTNode::Decl(d) => unsafe { - ASTNode::Decl(clangtool::Decl_getSemanticParent(d)) + ASTNode::Decl(clang_interface::Decl_getSemanticParent(d)) }, ASTNode::Expr(_) => panic!("Unimplemented for Expr"), _ => return None, @@ -297,7 +297,7 @@ impl Cursor { .num_template_args() .or_else(|| { let n: c_int = - unsafe { clangtool::Decl_getNumTemplateArguments(decl) }; + unsafe { clang_interface::Decl_getNumTemplateArguments(decl) }; if n >= 0 { Some(n as u32) @@ -322,7 +322,7 @@ impl Cursor { /// bindgen assumes there will only be one of them alive at a time, and /// disposes it on drop. That can change if this would be required, but I /// think we can survive fine without it. - pub fn translation_unit(&self) -> *mut clangtool::clang_ASTUnit { + pub fn translation_unit(&self) -> *mut clang_interface::clang_ASTUnit { self.unit } @@ -341,7 +341,7 @@ impl Cursor { } let tu = self.with_node(ASTNode::Decl(unsafe { - clangtool::getTranslationUnitDecl(self.unit) + clang_interface::getTranslationUnitDecl(self.unit) })); // Yes, this can happen with, e.g., macro definitions. semantic_parent == tu.fallible_semantic_parent() @@ -368,7 +368,7 @@ impl Cursor { pub fn is_definition(&self) -> bool { match self.node { ASTNode::Decl(d) => unsafe { - clangtool::Decl_isDefinition(d) + clang_interface::Decl_isDefinition(d) }, _ => false, } @@ -408,18 +408,18 @@ impl Cursor { /// Is this cursor pointing a valid referent? pub fn is_valid(&self) -> bool { - unsafe { !clangtool::CursorKind_isInvalid(self.kind) } + unsafe { !clang_interface::CursorKind_isInvalid(self.kind) } } /// Get the source location for the referent. pub fn location(&self) -> SourceLocation { unsafe { let x = match self.node { - ASTNode::Decl(d) => clangtool::Decl_getLocation(d), - ASTNode::Expr(e) => clangtool::Expr_getLocation(e), - ASTNode::CXXBaseSpecifier(b) => clangtool::CXXBaseSpecifier_getLocation(b), - ASTNode::Attr(b) => clangtool::Attr_getLocation(b), - ASTNode::PreprocessedEntity(p) => clangtool::PreprocessedEntity_getLocation(p), + ASTNode::Decl(d) => clang_interface::Decl_getLocation(d), + ASTNode::Expr(e) => clang_interface::Expr_getLocation(e), + ASTNode::CXXBaseSpecifier(b) => clang_interface::CXXBaseSpecifier_getLocation(b), + ASTNode::Attr(b) => clang_interface::Attr_getLocation(b), + ASTNode::PreprocessedEntity(p) => clang_interface::PreprocessedEntity_getLocation(p), ASTNode::Invalid => ptr::null(), }; SourceLocation { x, unit: self.unit } @@ -432,15 +432,15 @@ impl Cursor { /// of the last token, unlike the ranges provided by libclang, which are /// half-open ranges of characters (end is past the last character in the /// last token). - pub fn extent(&self) -> clangtool::BindgenSourceRange { + pub fn extent(&self) -> clang_interface::BindgenSourceRange { unsafe { match self.node { - ASTNode::Decl(d) => clangtool::Decl_getSourceRange(d), - ASTNode::Expr(e) => clangtool::Expr_getSourceRange(e), - ASTNode::CXXBaseSpecifier(b) => clangtool::CXXBaseSpecifier_getSourceRange(b), - ASTNode::Attr(b) => clangtool::Attr_getSourceRange(b), - ASTNode::PreprocessedEntity(b) => clangtool::PreprocessedEntity_getSourceRange(b), - _ => clangtool::BindgenSourceRange::null(), + ASTNode::Decl(d) => clang_interface::Decl_getSourceRange(d), + ASTNode::Expr(e) => clang_interface::Expr_getSourceRange(e), + ASTNode::CXXBaseSpecifier(b) => clang_interface::CXXBaseSpecifier_getSourceRange(b), + ASTNode::Attr(b) => clang_interface::Attr_getSourceRange(b), + ASTNode::PreprocessedEntity(b) => clang_interface::PreprocessedEntity_getSourceRange(b), + _ => clang_interface::BindgenSourceRange::null(), } } } @@ -449,7 +449,7 @@ impl Cursor { pub fn raw_comment(&self) -> Option { let s = match self.node { ASTNode::Decl(d) => unsafe { - clangtool::Decl_getRawCommentText(d, self.context()).to_string() + clang_interface::Decl_getRawCommentText(d, self.context()).to_string() }, _ => return None, }; @@ -464,7 +464,7 @@ impl Cursor { pub fn comment(&self) -> Comment { let x = match self.node { ASTNode::Decl(d) => unsafe { - clangtool::Decl_getParsedComment(d, self.context()) + clang_interface::Decl_getParsedComment(d, self.context()) }, _ => ptr::null(), }; @@ -475,9 +475,9 @@ impl Cursor { pub fn cur_type(&self) -> Type { unsafe { let x = match self.node { - ASTNode::Decl(d) => clangtool::Decl_getType(d, self.context()), - ASTNode::Expr(e) => clangtool::Expr_getType(e), - ASTNode::CXXBaseSpecifier(base) => clangtool::CXXBaseSpecifier_getType(base), + ASTNode::Decl(d) => clang_interface::Decl_getType(d, self.context()), + ASTNode::Expr(e) => clang_interface::Expr_getType(e), + ASTNode::CXXBaseSpecifier(base) => clang_interface::CXXBaseSpecifier_getType(base), _ => mem::zeroed(), }; Type { x, unit: self.unit } @@ -491,7 +491,7 @@ impl Cursor { let is_reference = self.kind >= CXCursor_FirstRef && self.kind <= CXCursor_LastRef; let def = match self.node { ASTNode::Decl(d) => unsafe { - clangtool::Decl_getDefinition(d, is_reference) + clang_interface::Decl_getDefinition(d, is_reference) }, _ => return None, }; @@ -507,7 +507,7 @@ impl Cursor { pub fn referenced(&self) -> Option { match self.node { ASTNode::Decl(d) => unsafe { - let ptr = clangtool::Decl_getReferenced(d); + let ptr = clang_interface::Decl_getReferenced(d); if ptr.is_null() { None } else { @@ -526,7 +526,7 @@ impl Cursor { pub fn canonical(&self) -> Cursor { let node = match self.node { ASTNode::Decl(d) => unsafe { - ASTNode::Decl(clangtool::Decl_getCanonical(d)) + ASTNode::Decl(clang_interface::Decl_getCanonical(d)) }, _ => ASTNode::Invalid, }; @@ -539,7 +539,7 @@ impl Cursor { pub fn specialized(&self) -> Option { match self.node { ASTNode::Decl(d) => unsafe { - let ptr = clangtool::Decl_getSpecializedTemplate(d); + let ptr = clang_interface::Decl_getSpecializedTemplate(d); if ptr.is_null() { None } else { @@ -555,7 +555,7 @@ impl Cursor { pub fn template_kind(&self) -> CXCursorKind { match self.node { ASTNode::Decl(d) => unsafe { - clangtool::Decl_getTemplateCursorKind(d) + clang_interface::Decl_getTemplateCursorKind(d) }, _ => CXCursor_NoDeclFound, } @@ -570,7 +570,7 @@ impl Cursor { { match self.node { ASTNode::Decl(d) => unsafe { - clangtool::Decl_visitChildren( + clang_interface::Decl_visitChildren( d, self.kind, Some(visit_children::), @@ -579,7 +579,7 @@ impl Cursor { ); } ASTNode::Expr(e) => unsafe { - clangtool::Expr_visitChildren( + clang_interface::Expr_visitChildren( e, self.kind, Some(visit_children::), @@ -588,7 +588,7 @@ impl Cursor { ); } ASTNode::CXXBaseSpecifier(b) => unsafe { - clangtool::CXXBaseSpecifier_visitChildren( + clang_interface::CXXBaseSpecifier_visitChildren( b, self.kind, Some(visit_children::), @@ -657,7 +657,7 @@ impl Cursor { pub fn is_inlined_function(&self) -> bool { match self.node { ASTNode::Decl(d) => unsafe { - clangtool::Decl_isFunctionInlined(d) + clang_interface::Decl_isFunctionInlined(d) }, _ => false, } @@ -668,7 +668,7 @@ impl Cursor { pub fn bit_width(&self) -> Option { let w = match self.node { ASTNode::Decl(d) => unsafe { - clangtool::Decl_getFieldDeclBitWidth(d, self.context()) + clang_interface::Decl_getFieldDeclBitWidth(d, self.context()) }, _ => -1, }; @@ -684,7 +684,7 @@ impl Cursor { pub fn enum_type(&self) -> Option { let x = unsafe { match self.node { - ASTNode::Decl(d) => clangtool::Decl_getEnumDeclIntegerType(d), + ASTNode::Decl(d) => clang_interface::Decl_getEnumDeclIntegerType(d), _ => mem::zeroed(), } }; @@ -701,7 +701,7 @@ impl Cursor { pub fn enum_val_signed(&self) -> Option { match self.node { ASTNode::Decl(d) => unsafe { - Some(clangtool::Decl_getEnumConstantValue(d)) + Some(clang_interface::Decl_getEnumConstantValue(d)) } _ => None, } @@ -713,7 +713,7 @@ impl Cursor { pub fn enum_val_unsigned(&self) -> Option { match self.node { ASTNode::Decl(d) => unsafe { - Some(clangtool::Decl_getEnumConstantUnsignedValue(d)) + Some(clang_interface::Decl_getEnumConstantUnsignedValue(d)) } _ => None, } @@ -755,7 +755,7 @@ impl Cursor { pub fn typedef_type(&self) -> Option { match self.node { ASTNode::Decl(d) => Some(Type { - x: unsafe { clangtool::Decl_getTypedefDeclUnderlyingType(d) }, + x: unsafe { clang_interface::Decl_getTypedefDeclUnderlyingType(d) }, unit: self.unit, }), _ => None, @@ -767,7 +767,7 @@ impl Cursor { /// This only applies to functions and variables. pub fn linkage(&self) -> CXLinkageKind { match self.node { - ASTNode::Decl(d) => unsafe { clangtool::Decl_getLinkage(d) }, + ASTNode::Decl(d) => unsafe { clang_interface::Decl_getLinkage(d) }, _ => CXLinkage_Invalid, } } @@ -775,7 +775,7 @@ impl Cursor { /// Get the visibility of this cursor's referent. pub fn visibility(&self) -> CXVisibilityKind { match self.node { - ASTNode::Decl(d) => unsafe { clangtool::Decl_getVisibility(d) }, + ASTNode::Decl(d) => unsafe { clang_interface::Decl_getVisibility(d) }, _ => CXVisibility_Invalid, } } @@ -794,10 +794,10 @@ impl Cursor { .map(|i| { let node = match self.node { ASTNode::Decl(d) => unsafe { - ASTNode::Decl(clangtool::Decl_getArgument(d, i as c_uint)) + ASTNode::Decl(clang_interface::Decl_getArgument(d, i as c_uint)) }, ASTNode::Expr(e) => unsafe { - ASTNode::Expr(clangtool::Expr_getArgument(e, i as c_uint)) + ASTNode::Expr(clang_interface::Expr_getArgument(e, i as c_uint)) }, _ => ASTNode::Invalid, }; @@ -815,10 +815,10 @@ impl Cursor { pub fn num_args(&self) -> Result { let w = match self.node { ASTNode::Decl(d) => unsafe { - clangtool::Decl_getNumArguments(d) + clang_interface::Decl_getNumArguments(d) }, ASTNode::Expr(e) => unsafe { - clangtool::Expr_getNumArguments(e) + clang_interface::Expr_getNumArguments(e) }, _ => -1, }; @@ -833,7 +833,7 @@ impl Cursor { pub fn access_specifier(&self) -> CX_CXXAccessSpecifier { match self.node { ASTNode::Decl(d) => unsafe { - clangtool::Decl_getAccess(d) + clang_interface::Decl_getAccess(d) }, // TODO(sjc): handle CXXBaseSpecifier cursors _ => CX_CXXInvalidAccessSpecifier, @@ -845,7 +845,7 @@ impl Cursor { pub fn is_mutable_field(&self) -> bool { match self.node { ASTNode::Decl(d) => unsafe { - clangtool::CXXField_isMutable(d) + clang_interface::CXXField_isMutable(d) }, _ => false, } @@ -855,7 +855,7 @@ impl Cursor { pub fn offset_of_field(&self) -> Result { let offset = match self.node { ASTNode::Decl(d) => unsafe { - clangtool::Decl_getOffsetOfField(d, self.context()) + clang_interface::Decl_getOffsetOfField(d, self.context()) }, _ => -1, }; @@ -870,7 +870,7 @@ impl Cursor { pub fn method_is_static(&self) -> bool { match self.node { ASTNode::Decl(d) => unsafe { - clangtool::CXXMethod_isStatic(d) + clang_interface::CXXMethod_isStatic(d) }, _ => false, } @@ -880,7 +880,7 @@ impl Cursor { pub fn method_is_const(&self) -> bool { match self.node { ASTNode::Decl(d) => unsafe { - clangtool::CXXMethod_isConst(d) + clang_interface::CXXMethod_isConst(d) }, _ => false, } @@ -890,7 +890,7 @@ impl Cursor { pub fn method_is_virtual(&self) -> bool { match self.node { ASTNode::Decl(d) => unsafe { - clangtool::CXXMethod_isVirtual(d) + clang_interface::CXXMethod_isVirtual(d) }, _ => false, } @@ -900,7 +900,7 @@ impl Cursor { pub fn method_is_pure_virtual(&self) -> bool { match self.node { ASTNode::Decl(d) => unsafe { - clangtool::CXXMethod_isPureVirtual(d) + clang_interface::CXXMethod_isPureVirtual(d) }, _ => false, } @@ -910,7 +910,7 @@ impl Cursor { pub fn is_virtual_base(&self) -> bool { match self.node { ASTNode::CXXBaseSpecifier(b) => unsafe { - clangtool::CXXBaseSpecifier_isVirtualBase(b) + clang_interface::CXXBaseSpecifier_isVirtualBase(b) }, _ => false, } @@ -940,8 +940,8 @@ impl Cursor { } unsafe { let x = match self.node { - ASTNode::Decl(d) => clangtool::Decl_Evaluate(d, self.context()), - ASTNode::Expr(e) => clangtool::Expr_Evaluate(e, self.context()), + ASTNode::Decl(d) => clang_interface::Decl_Evaluate(d, self.context()), + ASTNode::Expr(e) => clang_interface::Expr_Evaluate(e, self.context()), _ => return None, }; Some(EvalResult { x }) @@ -952,7 +952,7 @@ impl Cursor { pub fn ret_type(&self) -> Option { match self.node { ASTNode::Decl(d) => Some(Type { - x: unsafe { clangtool::Decl_getResultType(d, self.context()) }, + x: unsafe { clang_interface::Decl_getResultType(d, self.context()) }, unit: self.unit, }), _ => None, @@ -1013,8 +1013,8 @@ impl Cursor { /// A struct that owns the tokenizer result from a given cursor. pub struct RawTokens<'a> { cursor: &'a Cursor, - tu: *mut clangtool::clang_ASTUnit, - tokens: *mut clangtool::CXToken, + tu: *mut clang_interface::clang_ASTUnit, + tokens: *mut clang_interface::CXToken, token_count: c_uint, } @@ -1024,7 +1024,7 @@ impl<'a> RawTokens<'a> { let mut token_count = 0; let range = cursor.extent(); let tu = cursor.translation_unit(); - unsafe { clangtool::tokenize(tu, range, &mut tokens, &mut token_count) }; + unsafe { clang_interface::tokenize(tu, range, &mut tokens, &mut token_count) }; Self { cursor, tu, @@ -1033,7 +1033,7 @@ impl<'a> RawTokens<'a> { } } - fn as_slice(&self) -> &[clangtool::CXToken] { + fn as_slice(&self) -> &[clang_interface::CXToken] { if self.tokens.is_null() { return &[]; } @@ -1053,7 +1053,7 @@ impl<'a> Drop for RawTokens<'a> { fn drop(&mut self) { if !self.tokens.is_null() { unsafe { - clangtool::disposeTokens( + clang_interface::disposeTokens( self.tu, self.tokens, self.token_count as c_uint, @@ -1083,8 +1083,8 @@ impl ClangToken { /// An iterator over a set of Tokens. pub struct ClangTokenIterator<'a> { - tu: *mut clangtool::clang_ASTUnit, - raw: slice::Iter<'a, clangtool::CXToken>, + tu: *mut clang_interface::clang_ASTUnit, + raw: slice::Iter<'a, clang_interface::CXToken>, } impl<'a> Iterator for ClangTokenIterator<'a> { @@ -1093,8 +1093,8 @@ impl<'a> Iterator for ClangTokenIterator<'a> { fn next(&mut self) -> Option { let raw = self.raw.next()?; unsafe { - let kind = clangtool::getTokenKind(*raw); - let spelling = clangtool::getTokenSpelling(self.tu, *raw).to_cstring(); + let kind = clang_interface::getTokenKind(*raw); + let spelling = clang_interface::getTokenSpelling(self.tu, *raw).to_cstring(); Some(ClangToken { kind, spelling }) } } @@ -1113,10 +1113,10 @@ pub fn is_valid_identifier(name: &str) -> bool { } unsafe extern "C" fn visit_children( - raw_node: clangtool::Node, - _parent: clangtool::Node, - unit: *mut clangtool::clang_ASTUnit, - data: clangtool::CXClientData, + raw_node: clang_interface::Node, + _parent: clang_interface::Node, + unit: *mut clang_interface::clang_ASTUnit, + data: clang_interface::CXClientData, ) -> CXChildVisitResult where Visitor: FnMut(Cursor) -> CXChildVisitResult, @@ -1154,17 +1154,17 @@ where /// The type of a node in clang's AST. #[derive(Clone, Copy, PartialEq, Eq)] pub struct Type { - x: clangtool::clang_QualType, - unit: *mut clangtool::clang_ASTUnit, + x: clang_interface::clang_QualType, + unit: *mut clang_interface::clang_ASTUnit, } -impl PartialEq for clangtool::clang_QualType { +impl PartialEq for clang_interface::clang_QualType { fn eq(&self, other: &Self) -> bool { ptr::eq(self.ptr, other.ptr) } } -impl Eq for clangtool::clang_QualType {} +impl Eq for clang_interface::clang_QualType {} impl fmt::Debug for Type { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { @@ -1201,7 +1201,7 @@ pub enum LayoutError { impl ::std::convert::From for LayoutError { fn from(val: i32) -> Self { use self::LayoutError::*; - use self::clangtool::CXTypeLayoutError::*; + use self::clang_interface::CXTypeLayoutError::*; match val { CXTypeLayoutError_Invalid => Invalid, @@ -1215,20 +1215,20 @@ impl ::std::convert::From for LayoutError { } impl Type { - fn context(&self) -> *mut clangtool::clang_ASTContext { - unsafe { clangtool::ASTUnit_getContext(self.unit) } + fn context(&self) -> *mut clang_interface::clang_ASTContext { + unsafe { clang_interface::ASTUnit_getContext(self.unit) } } /// Get this type's kind. pub fn kind(&self) -> CXTypeKind { - unsafe { clangtool::Type_kind(self.x, self.context()) } + unsafe { clang_interface::Type_kind(self.x, self.context()) } } /// Get a cursor pointing to this type's declaration. pub fn declaration(&self) -> Cursor { unsafe { Cursor::new( - ASTNode::Decl(clangtool::Type_getDeclaration(self.x)), + ASTNode::Decl(clang_interface::Type_getDeclaration(self.x)), self.unit, ) } @@ -1262,7 +1262,7 @@ impl Type { /// Get a raw display name for this type. pub fn spelling(&self) -> String { - let s = unsafe { clangtool::Type_getTypeSpelling(self.x, self.context()).to_string() }; + let s = unsafe { clang_interface::Type_getTypeSpelling(self.x, self.context()).to_string() }; // Clang 5.0 introduced changes in the spelling API so it returned the // full qualified name. Let's undo that here. if s.split("::").all(|s| is_valid_identifier(s)) { @@ -1276,7 +1276,7 @@ impl Type { /// Is this type const qualified? pub fn is_const(&self) -> bool { - unsafe { clangtool::Type_isConstQualifiedType(self.x) } + unsafe { clang_interface::Type_isConstQualifiedType(self.x) } } #[inline] @@ -1294,7 +1294,7 @@ impl Type { } // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 CXType_Auto if self.is_non_deductible_auto_type() => return -6, - _ => unsafe { clangtool::Type_getSizeOf(self.x, self.context()) }, + _ => unsafe { clang_interface::Type_getSizeOf(self.x, self.context()) }, } } @@ -1307,7 +1307,7 @@ impl Type { } // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 CXType_Auto if self.is_non_deductible_auto_type() => return -6, - _ => unsafe { clangtool::Type_getAlignOf(self.x, self.context()) }, + _ => unsafe { clang_interface::Type_getAlignOf(self.x, self.context()) }, } } @@ -1377,11 +1377,11 @@ impl Type { // If an old libclang is loaded, we have no hope of answering this // question correctly. However, that's no reason to panic when // generating bindings for simple C headers with an old libclang. - // if !clangtool::Type_getNumTemplateArguments::is_loaded() { + // if !clang_interface::Type_getNumTemplateArguments::is_loaded() { // return None; // } - let n = unsafe { clangtool::Type_getNumTemplateArguments(self.x) }; + let n = unsafe { clang_interface::Type_getNumTemplateArguments(self.x) }; if n >= 0 { Some(n as u32) } else { @@ -1408,7 +1408,7 @@ impl Type { self.num_args().ok().map(|num| { (0..num) .map(|i| Type { - x: unsafe { clangtool::Type_getArgType(self.x, i as c_uint) }, + x: unsafe { clang_interface::Type_getArgType(self.x, i as c_uint) }, unit: self.unit, }) .collect() @@ -1420,7 +1420,7 @@ impl Type { /// Returns Err if the type is not a function prototype. pub fn num_args(&self) -> Result { unsafe { - let w = clangtool::Type_getNumArgTypes(self.x); + let w = clang_interface::Type_getNumArgTypes(self.x); if w == -1 { Err(()) } else { @@ -1440,7 +1440,7 @@ impl Type { CXType_BlockPointer | CXType_ObjCObjectPointer => { let ret = Type { - x: unsafe { clangtool::Type_getPointeeType(self.x) }, + x: unsafe { clang_interface::Type_getPointeeType(self.x) }, unit: self.unit, }; debug_assert!(ret.is_valid()); @@ -1454,7 +1454,7 @@ impl Type { /// type of its elements. pub fn elem_type(&self) -> Option { let current_type = Type { - x: unsafe { clangtool::Type_getElementType(self.x) }, + x: unsafe { clang_interface::Type_getElementType(self.x) }, unit: self.unit, }; if current_type.is_valid() { @@ -1467,7 +1467,7 @@ impl Type { /// Given that this type is an array or vector type, return its number of /// elements. pub fn num_elements(&self) -> Option { - let num_elements_returned = unsafe { clangtool::Type_getNumElements(self.x) }; + let num_elements_returned = unsafe { clang_interface::Type_getNumElements(self.x) }; if num_elements_returned != -1 { Some(num_elements_returned as usize) } else { @@ -1480,7 +1480,7 @@ impl Type { pub fn canonical_type(&self) -> Type { unsafe { Type { - x: clangtool::Type_getCanonicalType(self.x, self.context()), + x: clang_interface::Type_getCanonicalType(self.x, self.context()), unit: self.unit, } } @@ -1488,14 +1488,14 @@ impl Type { /// Is this type a variadic function type? pub fn is_variadic(&self) -> bool { - unsafe { clangtool::Type_isFunctionTypeVariadic(self.x) } + unsafe { clang_interface::Type_isFunctionTypeVariadic(self.x) } } /// Given that this type is a function type, get the type of its return /// value. pub fn ret_type(&self) -> Option { let rt = Type { - x: unsafe { clangtool::Type_getResultType(self.x) }, + x: unsafe { clang_interface::Type_getResultType(self.x) }, unit: self.unit, }; if rt.is_valid() { @@ -1507,8 +1507,8 @@ impl Type { /// Given that this type is a function type, get its calling convention. If /// this is not a function type, `CXCallingConv_Invalid` is returned. - pub fn call_conv(&self) -> clangtool::CXCallingConv::Type { - unsafe { clangtool::Type_getFunctionTypeCallingConv(self.x) } + pub fn call_conv(&self) -> clang_interface::CXCallingConv::Type { + unsafe { clang_interface::Type_getFunctionTypeCallingConv(self.x) } } /// For elaborated types (types which use `class`, `struct`, or `union` to @@ -1516,7 +1516,7 @@ impl Type { pub fn named(&self) -> Type { unsafe { Type { - x: clangtool::Type_getNamedType(self.x), + x: clang_interface::Type_getNamedType(self.x), unit: self.unit, } } @@ -1597,8 +1597,8 @@ impl CanonicalTypeDeclaration { /// An iterator for a type's template arguments. pub struct TypeTemplateArgIterator { - x: clangtool::clang_QualType, - unit: *mut clangtool::clang_ASTUnit, + x: clang_interface::clang_QualType, + unit: *mut clang_interface::clang_ASTUnit, length: u32, index: u32, } @@ -1610,7 +1610,7 @@ impl Iterator for TypeTemplateArgIterator { let idx = self.index as c_uint; self.index += 1; Some(Type { - x: unsafe { clangtool::Type_getTemplateArgumentAsType(self.x, idx) }, + x: unsafe { clang_interface::Type_getTemplateArgumentAsType(self.x, idx) }, unit: self.unit, }) } else { @@ -1629,8 +1629,8 @@ impl ExactSizeIterator for TypeTemplateArgIterator { /// A `SourceLocation` is a file, line, column, and byte offset location for /// some source text. pub struct SourceLocation { - x: *const clangtool::clang_SourceLocation, - unit: *mut clangtool::clang_ASTUnit, + x: *const clang_interface::clang_SourceLocation, + unit: *mut clang_interface::clang_ASTUnit, } impl SourceLocation { @@ -1642,7 +1642,7 @@ impl SourceLocation { let mut line = 0; let mut col = 0; let mut off = 0; - clangtool::getSpellingLocation( + clang_interface::getSpellingLocation( self.unit, self.x, &mut file, &mut line, &mut col, &mut off, ); (File { x: file }, line as usize, col as usize, off as usize) @@ -1665,20 +1665,20 @@ impl fmt::Display for SourceLocation { /// /// Comments are sort of parsed by Clang, and have a tree structure. pub struct Comment { - x: *const clangtool::clang_comments_Comment, + x: *const clang_interface::clang_comments_Comment, } impl Comment { /// What kind of comment is this? - pub fn kind(&self) -> clangtool::CXCommentKind::Type { - unsafe { clangtool::Comment_getKind(self.x) } + pub fn kind(&self) -> clang_interface::CXCommentKind::Type { + unsafe { clang_interface::Comment_getKind(self.x) } } /// Get this comment's children comment pub fn get_children(&self) -> CommentChildrenIterator { CommentChildrenIterator { parent: self.x, - length: unsafe { clangtool::Comment_getNumChildren(self.x) }, + length: unsafe { clang_interface::Comment_getNumChildren(self.x) }, index: 0, } } @@ -1686,14 +1686,14 @@ impl Comment { /// Given that this comment is the start or end of an HTML tag, get its tag /// name. pub fn get_tag_name(&self) -> String { - unsafe { clangtool::HTMLTagComment_getTagName(self.x).to_string() } + unsafe { clang_interface::HTMLTagComment_getTagName(self.x).to_string() } } /// Given that this comment is an HTML start tag, get its attributes. pub fn get_tag_attrs(&self) -> CommentAttributesIterator { CommentAttributesIterator { x: self.x, - length: unsafe { clangtool::HTMLStartTag_getNumAttrs(self.x) }, + length: unsafe { clang_interface::HTMLStartTag_getNumAttrs(self.x) }, index: 0, } } @@ -1701,7 +1701,7 @@ impl Comment { /// An iterator for a comment's children pub struct CommentChildrenIterator { - parent: *const clangtool::clang_comments_Comment, + parent: *const clang_interface::clang_comments_Comment, length: c_uint, index: c_uint, } @@ -1713,7 +1713,7 @@ impl Iterator for CommentChildrenIterator { let idx = self.index; self.index += 1; Some(Comment { - x: unsafe { clangtool::Comment_getChild(self.parent, idx) }, + x: unsafe { clang_interface::Comment_getChild(self.parent, idx) }, }) } else { None @@ -1731,7 +1731,7 @@ pub struct CommentAttribute { /// An iterator for a comment's attributes pub struct CommentAttributesIterator { - x: *const clangtool::clang_comments_Comment, + x: *const clang_interface::clang_comments_Comment, length: c_uint, index: c_uint, } @@ -1744,12 +1744,12 @@ impl Iterator for CommentAttributesIterator { self.index += 1; Some(CommentAttribute { name: unsafe { - clangtool::HTMLStartTag_getAttrName( + clang_interface::HTMLStartTag_getAttrName( self.x, idx, ).to_string() }, value: unsafe { - clangtool::HTMLStartTag_getAttrValue( + clang_interface::HTMLStartTag_getAttrValue( self.x, idx, ).to_string() }, @@ -1762,7 +1762,7 @@ impl Iterator for CommentAttributesIterator { /// A source file. pub struct File { - x: *mut clangtool::clang_FileEntry, + x: *mut clang_interface::clang_FileEntry, } impl File { @@ -1771,7 +1771,7 @@ impl File { if self.x.is_null() { return None; } - Some(unsafe { clangtool::FileEntry_getName(self.x).to_string() }) + Some(unsafe { clang_interface::FileEntry_getName(self.x).to_string() }) } } @@ -1836,7 +1836,7 @@ pub struct Token { /// A translation unit (or "compilation unit"). pub struct TranslationUnit { - x: *mut clangtool::clang_ASTUnit, + x: *mut clang_interface::clang_ASTUnit, } impl fmt::Debug for TranslationUnit { @@ -1861,11 +1861,11 @@ impl TranslationUnit { .collect(); let c_args: Vec<*const c_char> = _c_args.iter().map(|s| s.as_ptr()).collect(); - let mut c_unsaved: Vec = + let mut c_unsaved: Vec = unsaved.iter().map(|f| f.x).collect(); let tu = unsafe { // TODO(sjc): add back in unsaved files and opts - clangtool::parseTranslationUnit( + clang_interface::parseTranslationUnit( fname.as_ptr(), c_args.as_ptr(), c_args.len() as c_int, @@ -1885,11 +1885,11 @@ impl TranslationUnit { /// unit. pub fn diags(&self) -> Vec { unsafe { - let num = clangtool::ASTUnit_getNumDiagnostics(self.x) as usize; + let num = clang_interface::ASTUnit_getNumDiagnostics(self.x) as usize; let mut diags = vec![]; for i in 0..num { diags.push(Diagnostic { - x: clangtool::ASTUnit_getDiagnostic(self.x, i as c_uint), + x: clang_interface::ASTUnit_getDiagnostic(self.x, i as c_uint), }); } diags @@ -1900,7 +1900,7 @@ impl TranslationUnit { pub fn cursor(&self) -> Cursor { unsafe { Cursor::new( - ASTNode::Decl(clangtool::getTranslationUnitDecl(self.x)), + ASTNode::Decl(clang_interface::getTranslationUnitDecl(self.x)), self.x, ) } @@ -1915,14 +1915,14 @@ impl TranslationUnit { impl Drop for TranslationUnit { fn drop(&mut self) { unsafe { - clangtool::disposeASTUnit(self.x); + clang_interface::disposeASTUnit(self.x); } } } /// A diagnostic message generated while parsing a translation unit. pub struct Diagnostic { - x: *const clangtool::clang_StoredDiagnostic, + x: *const clang_interface::clang_StoredDiagnostic, } impl Diagnostic { @@ -1930,13 +1930,13 @@ impl Diagnostic { /// flags. pub fn format(&self) -> String { unsafe { - clangtool::Diagnostic_format(self.x).to_string() + clang_interface::Diagnostic_format(self.x).to_string() } } /// What is the severity of this diagnostic message? - pub fn severity(&self) -> clangtool::CXDiagnosticSeverity::Type { - unsafe { clangtool::Diagnostic_getSeverity(self.x) } + pub fn severity(&self) -> clang_interface::CXDiagnosticSeverity::Type { + unsafe { clang_interface::Diagnostic_getSeverity(self.x) } } } @@ -1944,14 +1944,14 @@ impl Diagnostic { // /// Destroy this diagnostic message. // fn drop(&mut self) { // unsafe { -// clangtool::Diagnostic_dispose(self.x); +// clang_interface::Diagnostic_dispose(self.x); // } // } // } /// A file which has not been saved to disk. pub struct UnsavedFile { - x: clangtool::CXUnsavedFile, + x: clang_interface::CXUnsavedFile, /// The name of the unsaved file. Kept here to avoid leaving dangling pointers in /// `CXUnsavedFile`. pub name: CString, @@ -1963,7 +1963,7 @@ impl UnsavedFile { pub fn new(name: &str, contents: &str) -> UnsavedFile { let name = CString::new(name).unwrap(); let contents = CString::new(contents).unwrap(); - let x = clangtool::CXUnsavedFile { + let x = clang_interface::CXUnsavedFile { Filename: name.as_ptr(), Contents: contents.as_ptr(), Length: contents.as_bytes().len() as c_ulong, @@ -1988,12 +1988,12 @@ impl fmt::Debug for UnsavedFile { /// Convert a cursor kind into a static string. pub fn kind_to_str(x: CXCursorKind) -> String { - unsafe { clangtool::CursorKind_getSpelling(x).to_string() } + unsafe { clang_interface::CursorKind_getSpelling(x).to_string() } } /// Convert a type kind to a static string. pub fn type_to_str(x: CXTypeKind) -> String { - unsafe { clangtool::TypeKind_getSpelling(x).to_string() } + unsafe { clang_interface::TypeKind_getSpelling(x).to_string() } } /// Dump the Clang AST to stdout for debugging purposes. @@ -2139,7 +2139,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { format!(" {}spelling = \"{}\"", prefix, ty.spelling()), ); let num_template_args = - unsafe { clangtool::Type_getNumTemplateArguments(ty.x) }; + unsafe { clang_interface::Type_getNumTemplateArguments(ty.x) }; if num_template_args >= 0 { print_indent( depth, @@ -2224,26 +2224,26 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { /// Try to extract the clang version to a string pub fn extract_clang_version() -> String { - let version = unsafe { clangtool::getClangVersion() }; + let version = unsafe { clang_interface::getClangVersion() }; version.to_string() } /// A wrapper for the result of evaluating an expression. #[derive(Debug)] pub struct EvalResult { - x: *mut clangtool::EvalResult, + x: *mut clang_interface::EvalResult, } impl EvalResult { fn kind(&self) -> CXEvalResultKind { - unsafe { clangtool::EvalResult_getKind(self.x) } + unsafe { clang_interface::EvalResult_getKind(self.x) } } /// Try to get back the result as a double. pub fn as_double(&self) -> Option { match self.kind() { CXEval_Float => { - Some(unsafe { clangtool::EvalResult_getAsDouble(self.x) } as f64) + Some(unsafe { clang_interface::EvalResult_getAsDouble(self.x) } as f64) } _ => None, } @@ -2255,8 +2255,8 @@ impl EvalResult { return None; } - if unsafe { clangtool::EvalResult_isUnsignedInt(self.x) } { - let value = unsafe { clangtool::EvalResult_getAsUnsigned(self.x) }; + if unsafe { clang_interface::EvalResult_isUnsignedInt(self.x) } { + let value = unsafe { clang_interface::EvalResult_getAsUnsigned(self.x) }; if value > i64::max_value() as c_ulonglong { return None; } @@ -2264,7 +2264,7 @@ impl EvalResult { return Some(value as i64); } - let value = unsafe { clangtool::EvalResult_getAsLongLong(self.x) }; + let value = unsafe { clang_interface::EvalResult_getAsLongLong(self.x) }; if value > i64::max_value() as c_longlong { return None; } @@ -2280,7 +2280,7 @@ impl EvalResult { match self.kind() { CXEval_StrLiteral => { let ret = unsafe { - CStr::from_ptr(clangtool::cString(clangtool::EvalResult_getAsStr(self.x))) + CStr::from_ptr(clang_interface::cString(clang_interface::EvalResult_getAsStr(self.x))) }; Some(ret.to_bytes().to_vec()) } @@ -2291,7 +2291,7 @@ impl EvalResult { // impl Drop for EvalResult { // fn drop(&mut self) { -// unsafe { clangtool::EvalResult_dispose(self.x) }; +// unsafe { clang_interface::EvalResult_dispose(self.x) }; // } // } @@ -2310,9 +2310,9 @@ impl TargetInfo { let triple; let pointer_width; unsafe { - let ti = clangtool::ASTUnit_getTargetInfo(tu.x); - triple = clangtool::TargetInfo_getTriple(ti).to_string(); - pointer_width = clangtool::TargetInfo_getPointerWidth(ti); + let ti = clang_interface::ASTUnit_getTargetInfo(tu.x); + triple = clang_interface::TargetInfo_getTriple(ti).to_string(); + pointer_width = clang_interface::TargetInfo_getPointerWidth(ti); } assert!(pointer_width > 0); assert_eq!(pointer_width % 8, 0); diff --git a/src/clang/CMakeLists.txt b/src/clang/CMakeLists.txt index 9b524fa459..665669f412 100644 --- a/src/clang/CMakeLists.txt +++ b/src/clang/CMakeLists.txt @@ -1,8 +1,9 @@ cmake_minimum_required(VERSION 3.4.3) -project(BindgenClangAST) +project(BindgenClangInterface) set(SRCS - ClangAST.cpp + clang_interface.cpp + libclang_compat.cpp ) if( PROJECT_NAME STREQUAL "LLVM" ) @@ -10,7 +11,7 @@ if( PROJECT_NAME STREQUAL "LLVM" ) add_definitions(-DCLANG_BIN_PATH="${CMAKE_INSTALL_PREFIX}/bin") - add_clang_library(bindgenClangAST ${SRCS} DEPENDS clang-headers) + add_clang_library(BindgenClangInterface ${SRCS} DEPENDS clang-headers) set(LLVM_LINK_COMPONENTS support) else() @@ -40,19 +41,19 @@ else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") # The library - add_library(bindgenClangAST STATIC ${SRCS}) + add_library(BindgenClangInterface STATIC ${SRCS}) endif() add_definitions(-DCLANG_LIBDIR_SUFFIX="${LLVM_LIBDIR_SUFFIX}") -set_target_properties(bindgenClangAST PROPERTIES +set_target_properties(BindgenClangInterface PROPERTIES CXX_STANDARD 14 CXX_EXTENSIONS OFF ) -# PRIVATE was added to make clangAst build with LLVM 6.0. Keyword +# PRIVATE was added to make BindgenClangInterface build with LLVM 6.0. Keyword # description: https://cmake.org/pipermail/cmake/2016-May/063400.html -target_link_libraries(bindgenClangAST PRIVATE +target_link_libraries(BindgenClangInterface PRIVATE clangAST clangFrontend clangIndex diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp new file mode 100644 index 0000000000..480e645d18 --- /dev/null +++ b/src/clang/clang_interface.cpp @@ -0,0 +1,1545 @@ +#include + +#include "clang/AST/Comment.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclFriend.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprObjC.h" +#include "clang/AST/Mangle.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Version.h" +#include "clang/Frontend/ASTUnit.h" +#include "clang/Index/USRGeneration.h" +#include "clang/Lex/PreprocessorOptions.h" +#include "clang-c/Documentation.h" +#include "clang-c/Index.h" + +#include "clang_interface_impl.hpp" + +using namespace clang; + +BindgenStringRef stringref() { + BindgenStringRef ref; + ref.s = nullptr; + ref.len = 0; + return ref; +} + +BindgenStringRef stringref(const char *newStr) { + BindgenStringRef ref; + ref.len = strlen(newStr); + ref.s = new char[ref.len + 1]; + strncpy(ref.s, newStr, ref.len); + ref.s[ref.len] = '\0'; + return ref; +} + +BindgenStringRef stringref(const std::string &s) { + return stringref(s.c_str()); +} + +BindgenStringRef stringref(llvm::StringRef S) { + BindgenStringRef ref; + ref.len = S.size(); + ref.s = new char[ref.len + 1]; + strncpy(ref.s, S.data(), ref.len); + ref.s[ref.len] = '\0'; + return ref; +} + +BindgenSourceRange::BindgenSourceRange(const SourceRange &range) { + B = new SourceLocation(range.getBegin()); + E = new SourceLocation(range.getEnd()); +} + +BindgenStringRefSet make_stringrefset(std::vector &string_vec) { + BindgenStringRefSet set; + set.len = string_vec.size(); + set.strings = new BindgenStringRef[set.len]; + for (size_t i = 0; i < set.len; ++i) + set.strings[i] = stringref(string_vec[i]); + return set; +} + + +void freeString(BindgenStringRef s) { + delete[] s.s; +} + +char *cString(BindgenStringRef s) { return s.s; } + +ASTContext *ASTUnit_getContext(ASTUnit *Unit) { + return &Unit->getASTContext(); +} + +void disposeASTUnit(ASTUnit *AU) { + delete AU; +} + +unsigned ASTUnit_getNumDiagnostics(const ASTUnit *AU) { + return AU->stored_diag_size(); +} + +const StoredDiagnostic *ASTUnit_getDiagnostic(const ASTUnit *AU, unsigned i) { + return (AU->stored_diag_begin()+i); +} + +const TargetInfo *ASTUnit_getTargetInfo(ASTUnit *Unit) { + return &Unit->getASTContext().getTargetInfo(); +} + +int TargetInfo_getPointerWidth(const TargetInfo *TI) { + if (!TI) + return -1; + return TI->getMaxPointerWidth(); +} + +BindgenStringRef TargetInfo_getTriple(const TargetInfo *TI) { + if (!TI) + return stringref(); + + std::string Triple = TI->getTriple().normalize(); + return stringref(Triple); +} + +struct EvalResult { + CXEvalResultKind EvalType; + APValue Val; + std::string stringVal; + + EvalResult() : EvalType(CXEval_UnExposed) {} + EvalResult(APValue Val) : EvalType(CXEval_UnExposed), Val(Val) { + if (Val.isInt()) + EvalType = CXEval_Int; + else if (Val.isFloat()) + EvalType = CXEval_Float; + } + EvalResult(std::string str) : EvalType(CXEval_StrLiteral), stringVal(str) {} +}; + +EvalResult *Expr_Evaluate(const Expr *E, ASTContext *Ctx) { + if (!E || E->isValueDependent()) + return nullptr; + + Expr::EvalResult res; + if (E->EvaluateAsRValue(res, *Ctx)) { + if (E->getStmtClass() == Stmt::ImplicitCastExprClass) { + const ImplicitCastExpr *I = dyn_cast(&*E); + auto *subExpr = I->getSubExprAsWritten(); + if (subExpr->getStmtClass() == Stmt::StringLiteralClass) { + auto StrE = cast(I->getSubExprAsWritten()); + return new EvalResult(StrE->getString().str()); + } + } else if (E->getStmtClass() == Stmt::StringLiteralClass) { + auto StrE = cast(&*E); + return new EvalResult(StrE->getString().str()); + } + return new EvalResult(res.Val); + } + + return nullptr; +} + +EvalResult *Decl_Evaluate(const Decl *D, ASTContext *Ctx) { + if (!D) + return nullptr; + + const Expr *E; + if (auto *Var = dyn_cast(&*D)) + E = Var->getInit(); + else if (auto *Field = dyn_cast(&*D)) + E = Field->getInClassInitializer(); + else + return nullptr; + + return Expr_Evaluate(E, Ctx); +} + +CXEvalResultKind EvalResult_getKind(EvalResult *ER) { + if (!ER) + return CXEval_UnExposed; + return ER->EvalType; +} + +double EvalResult_getAsDouble(EvalResult *ER) { + if (!ER) + return 0; + auto apFloat = ER->Val.getFloat(); + bool ignored; + apFloat.convert(llvm::APFloat::IEEEdouble(), + llvm::APFloat::rmNearestTiesToEven, &ignored); + return apFloat.convertToDouble(); +} + +bool EvalResult_isUnsignedInt(EvalResult *ER) { + return ER && + ER->EvalType == CXEval_Int && + ER->Val.getInt().isUnsigned(); +} + +long long EvalResult_getAsLongLong(EvalResult *ER) { + if (!ER) + return 0; + + auto intVal = ER->Val.getInt(); + if (intVal.isUnsigned()) + return intVal.getZExtValue(); + else + return intVal.getExtValue(); +} + +unsigned long long EvalResult_getAsUnsigned(EvalResult *ER) { + return static_cast(EvalResult_getAsLongLong(ER)); +} + +BindgenStringRef EvalResult_getAsStr(EvalResult *ER) { + if (!ER) + return stringref(); + + return stringref(ER->stringVal); +} + +BindgenStringRef Diagnostic_format(const StoredDiagnostic *D) { + if (!D) + return stringref(); + + return stringref(D->getMessage()); +} + +const Decl *getTranslationUnitDecl(ASTUnit *Unit) { + return Unit->getASTContext().getTranslationUnitDecl(); +} + +bool CursorKind_isInvalid(CXCursorKind kind) { + return kind >= CXCursor_FirstInvalid && kind <= CXCursor_LastInvalid; +} + +const Decl *Decl_getLexicalParent(const Decl *D) { + if (!D) + return nullptr; + + const DeclContext *DC = D->getLexicalDeclContext(); + if (!DC) + return nullptr; + + return cast(DC); +} + +const Decl *Decl_getSemanticParent(const Decl *D) { + if (!D) + return nullptr; + + const DeclContext *DC = D->getDeclContext(); + if (!DC) + return nullptr; + + // We replace CXXRecordDecl's inside ClassTemplateDecls with just the + // ClassTemplateDecl because we never expose the inner CXXRecordDecl to Rust. + if (auto *RD = dyn_cast(DC)) { + auto *ClassTemplate = RD->getDescribedClassTemplate(); + if (ClassTemplate) + return ClassTemplate; + } + + return cast(DC); +} + +const Decl *Decl_getReferenced(const Decl *D) { + if (!D) + return nullptr; + + // Bindgen doesn't handle UsingDecl references specially, but if we did, this + // is where that would go. + + return D; +} + +const Decl *Decl_getCanonical(const Decl *D) { + if (!D) + return nullptr; + if (const ObjCCategoryImplDecl *CatImplD = dyn_cast(D)) + if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl()) + return CatD; + + if (const ObjCImplDecl *ImplD = dyn_cast(D)) + if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) + return IFD; + + return D->getCanonicalDecl(); +} + +const Decl *Decl_getArgument(const Decl *D, unsigned i) { + if (!D) + return nullptr; + + if (const ObjCMethodDecl *MD = dyn_cast_or_null(&*D)) { + if (i < MD->param_size()) + return MD->parameters()[i]; + } else if (const FunctionDecl *FD = dyn_cast_or_null(&*D)) { + if (i < FD->param_size()) + return FD->parameters()[i]; + } + + return nullptr; +} + +int Decl_getNumArguments(const Decl *D) { + if (const ObjCMethodDecl *MD = dyn_cast_or_null(&*D)) + return MD->param_size(); + if (const FunctionDecl *FD = dyn_cast_or_null(&*D)) + return FD->param_size(); + + return -1; +} + +BindgenStringRef Decl_getUSR(const Decl *D) { + SmallString<128> Buf; + if (index::generateUSRForDecl(&*D, Buf)) + return stringref(); + else + return stringref(Buf.str()); +} + +BindgenStringRef Decl_getMangling(const Decl *D, ASTContext *Ctx) { + if (!D || !(isa(&*D) || isa(&*D))) + return stringref(); + + ASTNameGenerator ASTNameGen(*Ctx); + return stringref(ASTNameGen.getName(&*D)); +} + +BindgenStringRefSet Decl_getCXXManglings(const Decl *D, ASTContext *Ctx) { + if (!D || !(isa(&*D) || isa(&*D))) + return BindgenStringRefSet(); + + ASTNameGenerator ASTNameGen(*Ctx); + std::vector Manglings = ASTNameGen.getAllManglings(&*D); + return make_stringrefset(Manglings); +} + +CXCursorKind Decl_getCXCursorKind(const Decl *D) { + if (!D) + return CXCursor_NoDeclFound; + else + return getCursorKindForDecl(&*D); +} + +bool Decl_isDefinition(const Decl *D) { + if (auto VD = dyn_cast_or_null(&*D)) + return VD->getDefinition() == &*D; + if (auto FD = dyn_cast_or_null(&*D)) + return FD->getDefinition() == &*D; + if (auto TD = dyn_cast_or_null(&*D)) + return TD->getDefinition() == &*D; + + return false; +} + +SourceLocation *Decl_getLocation(const Decl *D) { + if (!D) + return nullptr; + return new SourceLocation(D->getLocation()); +} + +BindgenStringRef Decl_getRawCommentText(const Decl *D, ASTContext *Ctx) { + if (!D) + return stringref(); + + auto *RC = Ctx->getRawCommentForAnyRedecl(&*D); + return RC ? stringref(RC->getRawText(Ctx->getSourceManager())) : stringref(); +} + +comments::Comment *Decl_getParsedComment(const Decl *D, ASTContext *Ctx) { + if (!D) + return nullptr; + return Ctx->getCommentForDecl(&*D, nullptr); +} + +QualType make_type_compatible(QualType QT) { + if (QT.isNull()) + return QT; + + // libclang does not return AttributedTypes if + // CXTranslationUnit_IncludeAttributedTypes is not set, and bindgen assumes it + // is not set. + if (auto *ATT = QT->getAs()) + return make_type_compatible(ATT->getEquivalentType()); + + // libclang does not return ParenTypes + if (auto *PTT = QT->getAs()) + return make_type_compatible(PTT->getInnerType()); + + // Decayed types should be passed as their original type + if (auto *DT = QT->getAs()) + return make_type_compatible(DT->getOriginalType()); + + return QT; +} + +QualType Decl_getType(const Decl *D, ASTContext *Ctx) { + auto ty = QualType(); + if (!D) + return ty; + + if (auto *TD = dyn_cast(&*D)) + ty = Ctx->getTypeDeclType(TD); + else if (auto *ID = dyn_cast(&*D)) + ty = Ctx->getObjCInterfaceType(ID); + else if (auto *DD = dyn_cast(&*D)) + ty = DD->getType(); + else if (auto *VD = dyn_cast(&*D)) + ty = VD->getType(); + else if (auto *PD = dyn_cast(&*D)) + ty = PD->getType(); + else if (auto *FTD = dyn_cast(&*D)) + ty = FTD->getTemplatedDecl()->getType(); + else + return QualType(); + + return make_type_compatible(ty); +} + +bool Decl_isFunctionInlined(const Decl *D) { + if (auto *FD = dyn_cast_or_null(&*D)) + return FD->isInlined(); + else + return false; +} + +int Decl_getFieldDeclBitWidth(const Decl *D, ASTContext *Ctx) { + if (auto *FD = dyn_cast_or_null(&*D)) { + if (FD->isBitField()) + return FD->getBitWidthValue(*Ctx); + } + return -1; +} + +QualType Decl_getEnumDeclIntegerType(const Decl *D) { + if (auto *TD = dyn_cast_or_null(&*D)) + return make_type_compatible(TD->getIntegerType()); + else + return QualType(); +} + +int64_t Decl_getEnumConstantValue(const Decl *D) { + if (auto *TD = dyn_cast_or_null(&*D)) + return TD->getInitVal().getSExtValue(); + else + return LLONG_MIN; +} + +uint64_t Decl_getEnumConstantUnsignedValue(const Decl *D) { + if (auto *TD = dyn_cast_or_null(&*D)) + return TD->getInitVal().getZExtValue(); + else + return ULLONG_MAX; +} + +long long Decl_getOffsetOfField(const Decl *D, ASTContext *Ctx) { + auto *RD = dyn_cast_or_null(D->getDeclContext()); + auto Err = visitRecordForValidation(RD); + if (Err < 0) + return Err; + + if (auto *FD = dyn_cast_or_null(&*D)) + return Ctx->getFieldOffset(FD); + if (auto *IFD = dyn_cast_or_null(&*D)) + return Ctx->getFieldOffset(IFD); + + return -1; +} + +BindgenSourceRange Decl_getSourceRange(const Decl *D) { + return BindgenSourceRange(D->getSourceRange()); +} + +QualType Decl_getTypedefDeclUnderlyingType(const Decl *D) { + if (auto *TD = dyn_cast_or_null(&*D)) + return make_type_compatible(TD->getUnderlyingType()); + else + return QualType(); +} + +bool CXXField_isMutable(const Decl *D) { + if (const auto FD = dyn_cast_or_null(&*D)) + return FD->isMutable(); + else + return false; +} + +bool CXXMethod_isStatic(const Decl *D) { + auto *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return Method && Method->isStatic(); +} + +bool CXXMethod_isConst(const Decl *D) { + auto *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return Method && Method->getMethodQualifiers().hasConst(); +} + +bool CXXMethod_isVirtual(const Decl *D) { + auto *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return Method && Method->isVirtual(); +} + +bool CXXMethod_isPureVirtual(const Decl *D) { + auto *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return Method && Method->isVirtual() && Method->isPure(); +} + +QualType Decl_getResultType(const Decl *D, ASTContext *Ctx) { + if (auto *MD = dyn_cast_or_null(D)) + return make_type_compatible(MD->getReturnType()); + + return Type_getResultType(Decl_getType(D, Ctx)); +} + +BindgenStringRef Expr_getSpelling(const Expr *E) { + if (auto *SL = dyn_cast_or_null(&*E)) { + SmallString<256> Buf; + llvm::raw_svector_ostream OS(Buf); + SL->outputString(OS); + return stringref(OS.str()); + } + if (auto *D = getDeclFromExpr(&*E)) + return Decl_getSpelling(D); + + return stringref(); +} + +CXCursorKind Expr_getCXCursorKind(const Expr *E) { + switch (E->getStmtClass()) { + case Stmt::NoStmtClass: + return CXCursor_NotImplemented; + case Stmt::CaseStmtClass: + return CXCursor_CaseStmt; + case Stmt::DefaultStmtClass: + return CXCursor_DefaultStmt; + case Stmt::IfStmtClass: + return CXCursor_IfStmt; + case Stmt::SwitchStmtClass: + return CXCursor_SwitchStmt; + case Stmt::WhileStmtClass: + return CXCursor_WhileStmt; + case Stmt::DoStmtClass: + return CXCursor_DoStmt; + case Stmt::ForStmtClass: + return CXCursor_ForStmt; + case Stmt::GotoStmtClass: + return CXCursor_GotoStmt; + case Stmt::IndirectGotoStmtClass: + return CXCursor_IndirectGotoStmt; + case Stmt::ContinueStmtClass: + return CXCursor_ContinueStmt; + case Stmt::BreakStmtClass: + return CXCursor_BreakStmt; + case Stmt::ReturnStmtClass: + return CXCursor_ReturnStmt; + case Stmt::GCCAsmStmtClass: + return CXCursor_GCCAsmStmt; + case Stmt::MSAsmStmtClass: + return CXCursor_MSAsmStmt; + case Stmt::ObjCAtTryStmtClass: + return CXCursor_ObjCAtTryStmt; + case Stmt::ObjCAtCatchStmtClass: + return CXCursor_ObjCAtCatchStmt; + case Stmt::ObjCAtFinallyStmtClass: + return CXCursor_ObjCAtFinallyStmt; + case Stmt::ObjCAtThrowStmtClass: + return CXCursor_ObjCAtThrowStmt; + case Stmt::ObjCAtSynchronizedStmtClass: + return CXCursor_ObjCAtSynchronizedStmt; + case Stmt::ObjCAutoreleasePoolStmtClass: + return CXCursor_ObjCAutoreleasePoolStmt; + case Stmt::ObjCForCollectionStmtClass: + return CXCursor_ObjCForCollectionStmt; + case Stmt::CXXCatchStmtClass: + return CXCursor_CXXCatchStmt; + case Stmt::CXXTryStmtClass: + return CXCursor_CXXTryStmt; + case Stmt::CXXForRangeStmtClass: + return CXCursor_CXXForRangeStmt; + case Stmt::SEHTryStmtClass: + return CXCursor_SEHTryStmt; + case Stmt::SEHExceptStmtClass: + return CXCursor_SEHExceptStmt; + case Stmt::SEHFinallyStmtClass: + return CXCursor_SEHFinallyStmt; + case Stmt::SEHLeaveStmtClass: + return CXCursor_SEHLeaveStmt; + + case Stmt::CoroutineBodyStmtClass: + case Stmt::CoreturnStmtClass: + return CXCursor_UnexposedStmt; + + case Stmt::OpaqueValueExprClass: + if (auto *Src = cast(&*E)->getSourceExpr()) + return Expr_getCXCursorKind(Src); + return CXCursor_UnexposedExpr; + + case Stmt::PseudoObjectExprClass: + return Expr_getCXCursorKind( + cast(&*E)->getSyntacticForm()); + + case Stmt::CompoundStmtClass: + return CXCursor_CompoundStmt; + + case Stmt::NullStmtClass: + return CXCursor_NullStmt; + + case Stmt::LabelStmtClass: + return CXCursor_LabelStmt; + + case Stmt::AttributedStmtClass: + return CXCursor_UnexposedStmt; + + case Stmt::DeclStmtClass: + return CXCursor_DeclStmt; + + case Stmt::CapturedStmtClass: + return CXCursor_UnexposedStmt; + + case Stmt::IntegerLiteralClass: + return CXCursor_IntegerLiteral; + + case Stmt::FixedPointLiteralClass: + return CXCursor_FixedPointLiteral; + + case Stmt::FloatingLiteralClass: + return CXCursor_FloatingLiteral; + + case Stmt::ImaginaryLiteralClass: + return CXCursor_ImaginaryLiteral; + + case Stmt::StringLiteralClass: + return CXCursor_StringLiteral; + + case Stmt::CharacterLiteralClass: + return CXCursor_CharacterLiteral; + + case Stmt::ConstantExprClass: + return Expr_getCXCursorKind(cast(&*E)->getSubExpr()); + + case Stmt::ParenExprClass: + return CXCursor_ParenExpr; + + case Stmt::UnaryOperatorClass: + return CXCursor_UnaryOperator; + + case Stmt::UnaryExprOrTypeTraitExprClass: + case Stmt::CXXNoexceptExprClass: + return CXCursor_UnaryExpr; + + case Stmt::MSPropertySubscriptExprClass: + case Stmt::ArraySubscriptExprClass: + return CXCursor_ArraySubscriptExpr; + + case Stmt::OMPArraySectionExprClass: + return CXCursor_OMPArraySectionExpr; + + case Stmt::BinaryOperatorClass: + return CXCursor_BinaryOperator; + + case Stmt::CompoundAssignOperatorClass: + return CXCursor_CompoundAssignOperator; + + case Stmt::ConditionalOperatorClass: + return CXCursor_ConditionalOperator; + + case Stmt::CStyleCastExprClass: + return CXCursor_CStyleCastExpr; + + case Stmt::CompoundLiteralExprClass: + return CXCursor_CompoundLiteralExpr; + + case Stmt::InitListExprClass: + return CXCursor_InitListExpr; + + case Stmt::AddrLabelExprClass: + return CXCursor_AddrLabelExpr; + + case Stmt::StmtExprClass: + return CXCursor_StmtExpr; + + case Stmt::GenericSelectionExprClass: + return CXCursor_GenericSelectionExpr; + + case Stmt::GNUNullExprClass: + return CXCursor_GNUNullExpr; + + case Stmt::CXXStaticCastExprClass: + return CXCursor_CXXStaticCastExpr; + + case Stmt::CXXDynamicCastExprClass: + return CXCursor_CXXDynamicCastExpr; + + case Stmt::CXXReinterpretCastExprClass: + return CXCursor_CXXReinterpretCastExpr; + + case Stmt::CXXConstCastExprClass: + return CXCursor_CXXConstCastExpr; + + case Stmt::CXXFunctionalCastExprClass: + return CXCursor_CXXFunctionalCastExpr; + + case Stmt::CXXTypeidExprClass: + return CXCursor_CXXTypeidExpr; + + case Stmt::CXXBoolLiteralExprClass: + return CXCursor_CXXBoolLiteralExpr; + + case Stmt::CXXNullPtrLiteralExprClass: + return CXCursor_CXXNullPtrLiteralExpr; + + case Stmt::CXXThisExprClass: + return CXCursor_CXXThisExpr; + + case Stmt::CXXThrowExprClass: + return CXCursor_CXXThrowExpr; + + case Stmt::CXXNewExprClass: + return CXCursor_CXXNewExpr; + + case Stmt::CXXDeleteExprClass: + return CXCursor_CXXDeleteExpr; + + case Stmt::ObjCStringLiteralClass: + return CXCursor_ObjCStringLiteral; + + case Stmt::ObjCEncodeExprClass: + return CXCursor_ObjCEncodeExpr; + + case Stmt::ObjCSelectorExprClass: + return CXCursor_ObjCSelectorExpr; + + case Stmt::ObjCProtocolExprClass: + return CXCursor_ObjCProtocolExpr; + case Stmt::ObjCBoolLiteralExprClass: + return CXCursor_ObjCBoolLiteralExpr; + + case Stmt::ObjCAvailabilityCheckExprClass: + return CXCursor_ObjCAvailabilityCheckExpr; + + case Stmt::ObjCBridgedCastExprClass: + return CXCursor_ObjCBridgedCastExpr; + + case Stmt::BlockExprClass: + return CXCursor_BlockExpr; + + case Stmt::PackExpansionExprClass: + return CXCursor_PackExpansionExpr; + + case Stmt::SizeOfPackExprClass: + return CXCursor_SizeOfPackExpr; + + case Stmt::DeclRefExprClass: + return CXCursor_DeclRefExpr; + + case Stmt::DependentScopeDeclRefExprClass: + case Stmt::SubstNonTypeTemplateParmExprClass: + case Stmt::SubstNonTypeTemplateParmPackExprClass: + case Stmt::FunctionParmPackExprClass: + case Stmt::UnresolvedLookupExprClass: + case Stmt::TypoExprClass: // A typo could actually be a DeclRef or a MemberRef + return CXCursor_DeclRefExpr; + + case Stmt::CXXDependentScopeMemberExprClass: + case Stmt::CXXPseudoDestructorExprClass: + case Stmt::MemberExprClass: + case Stmt::MSPropertyRefExprClass: + case Stmt::ObjCIsaExprClass: + case Stmt::ObjCIvarRefExprClass: + case Stmt::ObjCPropertyRefExprClass: + case Stmt::UnresolvedMemberExprClass: + return CXCursor_MemberRefExpr; + + case Stmt::CallExprClass: + case Stmt::CXXOperatorCallExprClass: + case Stmt::CXXMemberCallExprClass: + case Stmt::CUDAKernelCallExprClass: + case Stmt::CXXConstructExprClass: + case Stmt::CXXInheritedCtorInitExprClass: + case Stmt::CXXTemporaryObjectExprClass: + case Stmt::CXXUnresolvedConstructExprClass: + case Stmt::UserDefinedLiteralClass: + return CXCursor_CallExpr; + + case Stmt::LambdaExprClass: + return CXCursor_LambdaExpr; + + case Stmt::ObjCMessageExprClass: + return CXCursor_ObjCMessageExpr; + + case Stmt::MSDependentExistsStmtClass: + return CXCursor_UnexposedStmt; + case Stmt::OMPParallelDirectiveClass: + return CXCursor_OMPParallelDirective; + case Stmt::OMPSimdDirectiveClass: + return CXCursor_OMPSimdDirective; + case Stmt::OMPForDirectiveClass: + return CXCursor_OMPForDirective; + case Stmt::OMPForSimdDirectiveClass: + return CXCursor_OMPForSimdDirective; + case Stmt::OMPSectionsDirectiveClass: + return CXCursor_OMPSectionsDirective; + case Stmt::OMPSectionDirectiveClass: + return CXCursor_OMPSectionDirective; + case Stmt::OMPSingleDirectiveClass: + return CXCursor_OMPSingleDirective; + case Stmt::OMPMasterDirectiveClass: + return CXCursor_OMPMasterDirective; + case Stmt::OMPCriticalDirectiveClass: + return CXCursor_OMPCriticalDirective; + case Stmt::OMPParallelForDirectiveClass: + return CXCursor_OMPParallelForDirective; + case Stmt::OMPParallelForSimdDirectiveClass: + return CXCursor_OMPParallelForSimdDirective; + case Stmt::OMPParallelSectionsDirectiveClass: + return CXCursor_OMPParallelSectionsDirective; + case Stmt::OMPTaskDirectiveClass: + return CXCursor_OMPTaskDirective; + case Stmt::OMPTaskyieldDirectiveClass: + return CXCursor_OMPTaskyieldDirective; + case Stmt::OMPBarrierDirectiveClass: + return CXCursor_OMPBarrierDirective; + case Stmt::OMPTaskwaitDirectiveClass: + return CXCursor_OMPTaskwaitDirective; + case Stmt::OMPTaskgroupDirectiveClass: + return CXCursor_OMPTaskgroupDirective; + case Stmt::OMPFlushDirectiveClass: + return CXCursor_OMPFlushDirective; + case Stmt::OMPOrderedDirectiveClass: + return CXCursor_OMPOrderedDirective; + case Stmt::OMPAtomicDirectiveClass: + return CXCursor_OMPAtomicDirective; + case Stmt::OMPTargetDirectiveClass: + return CXCursor_OMPTargetDirective; + case Stmt::OMPTargetDataDirectiveClass: + return CXCursor_OMPTargetDataDirective; + case Stmt::OMPTargetEnterDataDirectiveClass: + return CXCursor_OMPTargetEnterDataDirective; + case Stmt::OMPTargetExitDataDirectiveClass: + return CXCursor_OMPTargetExitDataDirective; + case Stmt::OMPTargetParallelDirectiveClass: + return CXCursor_OMPTargetParallelDirective; + case Stmt::OMPTargetParallelForDirectiveClass: + return CXCursor_OMPTargetParallelForDirective; + case Stmt::OMPTargetUpdateDirectiveClass: + return CXCursor_OMPTargetUpdateDirective; + case Stmt::OMPTeamsDirectiveClass: + return CXCursor_OMPTeamsDirective; + case Stmt::OMPCancellationPointDirectiveClass: + return CXCursor_OMPCancellationPointDirective; + case Stmt::OMPCancelDirectiveClass: + return CXCursor_OMPCancelDirective; + case Stmt::OMPTaskLoopDirectiveClass: + return CXCursor_OMPTaskLoopDirective; + case Stmt::OMPTaskLoopSimdDirectiveClass: + return CXCursor_OMPTaskLoopSimdDirective; + case Stmt::OMPDistributeDirectiveClass: + return CXCursor_OMPDistributeDirective; + case Stmt::OMPDistributeParallelForDirectiveClass: + return CXCursor_OMPDistributeParallelForDirective; + case Stmt::OMPDistributeParallelForSimdDirectiveClass: + return CXCursor_OMPDistributeParallelForSimdDirective; + case Stmt::OMPDistributeSimdDirectiveClass: + return CXCursor_OMPDistributeSimdDirective; + case Stmt::OMPTargetParallelForSimdDirectiveClass: + return CXCursor_OMPTargetParallelForSimdDirective; + case Stmt::OMPTargetSimdDirectiveClass: + return CXCursor_OMPTargetSimdDirective; + case Stmt::OMPTeamsDistributeDirectiveClass: + return CXCursor_OMPTeamsDistributeDirective; + case Stmt::OMPTeamsDistributeSimdDirectiveClass: + return CXCursor_OMPTeamsDistributeSimdDirective; + case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: + return CXCursor_OMPTeamsDistributeParallelForSimdDirective; + case Stmt::OMPTeamsDistributeParallelForDirectiveClass: + return CXCursor_OMPTeamsDistributeParallelForDirective; + case Stmt::OMPTargetTeamsDirectiveClass: + return CXCursor_OMPTargetTeamsDirective; + case Stmt::OMPTargetTeamsDistributeDirectiveClass: + return CXCursor_OMPTargetTeamsDistributeDirective; + case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: + return CXCursor_OMPTargetTeamsDistributeParallelForDirective; + case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: + return CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective; + case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: + return CXCursor_OMPTargetTeamsDistributeSimdDirective; + case Stmt::BuiltinBitCastExprClass: + return CXCursor_BuiltinBitCastExpr; + + default: + return CXCursor_UnexposedExpr; + } +} + +QualType Expr_getType(const Expr *E) { return make_type_compatible(E->getType()); } + +BindgenSourceRange Expr_getSourceRange(const Expr *E) { + return BindgenSourceRange(E->getSourceRange()); +} + +class BindgenVisitor : public RecursiveASTVisitor { + ASTUnit &AST; + Visitor VisitFn; + CXClientData Data; + Node Parent; + +public: + explicit BindgenVisitor(ASTUnit &AST, Visitor V, CXClientData data) : AST(AST), VisitFn(V), Data(data) {} + + bool shouldVisitImplicitCode() { + return false; + } + + bool TraverseDeclTyped(Decl *D, CXCursorKind kind) { + if (!D || (D->isImplicit() && !isa(D))) + return true; + + bool skip = !Parent; + + // libclang doesn't visit the CXXRecordDecl inside ClassTemplateDecl nodes + if (Parent.kind == CXCursor_ClassTemplate + && isa(D)) + skip = true; + + // libclang exposes forward class and protocol declarations as references + if (kind == CXCursor_ObjCInterfaceDecl) { + auto *ID = cast(D); + if (!ID->isThisDeclarationADefinition()) + kind = CXCursor_ObjCClassRef; + } else if (kind == CXCursor_ObjCProtocolDecl) { + auto *PD = cast(D); + if (!PD->isThisDeclarationADefinition()) + kind = CXCursor_ObjCProtocolRef; + } + + // D->dump(); + Node node(D, kind); + if (!skip) { + switch (VisitFn(node, Parent, &AST, Data)) { + case CXChildVisit_Break: + return false; + case CXChildVisit_Continue: + return true; + case CXChildVisit_Recurse: + break; + } + } + + // Do not recurse through references + if (kind >= CXCursor_FirstRef && kind <= CXCursor_LastRef + && kind != CXCursor_CXXBaseSpecifier) + return true; + + auto OldParent = Parent; + Parent = node; + bool res = RecursiveASTVisitor::TraverseDecl(D); + Parent = OldParent; + return res; + } + + bool TraverseDecl(Decl *D) { + return TraverseDeclTyped(D, Decl_getCXCursorKind(D)); + } + + bool TraverseExprTyped(Expr *E, CXCursorKind kind) { + if (!E) + return true; + + Node node(E, kind); + if (Parent) { + // E->dump(); + switch (VisitFn(node, Parent, &AST, Data)) { + case CXChildVisit_Break: + return false; + case CXChildVisit_Continue: + return true; + case CXChildVisit_Recurse: + break; + } + } + + auto OldParent = Parent; + Parent = node; + bool res = RecursiveASTVisitor::TraverseStmt(E); + Parent = OldParent; + return res; + } + + bool TraverseStmt(Stmt *S) { + if (!S) + return true; + if (auto *E = dyn_cast(S)) + return TraverseExprTyped(E, Expr_getCXCursorKind(E)); + return RecursiveASTVisitor::TraverseStmt(S); + } + + bool VisitSizeOfPackExpr(SizeOfPackExpr *E) { + NamedDecl *Pack = E->getPack(); + if (isa(Pack)) { + Node node(Pack, CXCursor_TypeRef); + Node parent(E, Expr_getCXCursorKind(E)); + return VisitFn(node, parent, &AST, Data) != CXChildVisit_Break; + } + if (isa(Pack)) { + Node node(Pack, CXCursor_TemplateRef); + Node parent(E, Expr_getCXCursorKind(E)); + return VisitFn(node, parent, &AST, Data) != CXChildVisit_Break; + } + return true; + } + + bool VisitTypeLoc(TypeLoc TL) { + // if (TL) TL.getTypePtr()->dump(); + return true; + } + + bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { + if (!TL) + return true; + return TraverseStmt(TL.getUnderlyingExpr()); + } + + bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { + if (!TL) + return true; + return TraverseStmt(TL.getUnderlyingExpr()); + } + + bool VisitTypedefTypeLoc(TypedefTypeLoc TL) { + if (!TL) + return true; + return TraverseDeclTyped(TL.getTypedefNameDecl(), CXCursor_TypeRef); + } + + bool VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { + if (!TL) + return true; + return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); + } + + bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { + if (!TL) + return true; + return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); + } + + bool VisitTagTypeLoc(TagTypeLoc TL) { + if (!TL) + return true; + if (TL.isDefinition()) + return TraverseDecl(TL.getDecl()); + else + return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); + } + + bool VisitRecordTypeLoc(RecordTypeLoc TL) { + if (!TL) + return true; + return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); + } + + bool VisitEnumTypeLoc(EnumTypeLoc TL) { + if (!TL) + return true; + return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); + } + + bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { + if (!TL) + return true; + return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); + } + + bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { + if (!TL) + return true; + + ASTContext &Context = AST.getASTContext(); + QualType Ty; + switch (TL.getTypePtr()->getKind()) { + case BuiltinType::ObjCId: + Ty = Context.getObjCIdType(); + break; + case BuiltinType::ObjCClass: + Ty = Context.getObjCClassType(); + break; + case BuiltinType::ObjCSel: + Ty = Context.getObjCSelType(); + break; + default: + break; + } + + if (!Ty.isNull()) { + if (auto *TD = Ty->getAs()) { + Node node(TD->getDecl(), CXCursor_TypeRef); + return VisitFn(node, Parent, &AST, Data) != CXChildVisit_Break; + } + } + + return true; + } + + bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { + if (!TL) + return true; + + return TraverseDeclTyped(TL.getIFaceDecl(), CXCursor_ObjCClassRef); + } + + bool VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) { + if (!TL) + return true; + Node node(TL.getDecl(), CXCursor_TypeRef); + if (VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break) + return false; + for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { + Node node(TL.getProtocol(I), CXCursor_ObjCProtocolRef); + if (VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break) + return false; + } + return true; + } + + bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { + if (!TL) + return true; + + for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { + Node node(TL.getProtocol(I), CXCursor_ObjCProtocolRef); + if (VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break) + return false; + } + + return true; + } + + bool TraverseTemplateName(TemplateName Name) { + Node node; + switch (Name.getKind()) { + case TemplateName::Template: + node = Node(Name.getAsTemplateDecl(), CXCursor_TemplateRef); + break; + + case TemplateName::OverloadedTemplate: + // libclang visits this, but we don't need it for bindgen + return true; + + case TemplateName::AssumedTemplate: + return true; + + case TemplateName::DependentTemplate: + return true; + + case TemplateName::QualifiedTemplate: + node = Node(Name.getAsQualifiedTemplateName()->getDecl(), CXCursor_TemplateRef); + break; + + case TemplateName::SubstTemplateTemplateParm: + node = Node(Name.getAsSubstTemplateTemplateParm()->getParameter(), CXCursor_TemplateRef); + break; + + case TemplateName::SubstTemplateTemplateParmPack: + node = Node(Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), CXCursor_TemplateRef); + break; + } + + switch (VisitFn(node, Parent, &AST, Data)) { + case CXChildVisit_Break: + return false; + case CXChildVisit_Continue: + return true; + case CXChildVisit_Recurse: + break; + } + + auto OldParent = Parent; + Parent = node; + bool res = RecursiveASTVisitor::TraverseTemplateName(Name); + Parent = OldParent; + return res; + } + + bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) { + if (Parent) { + switch (VisitFn(Node(&Base), Parent, &AST, Data)) { + case CXChildVisit_Break: + return false; + case CXChildVisit_Continue: + return true; + case CXChildVisit_Recurse: + break; + } + } + + auto OldParent = Parent; + Parent = Node(&Base); + bool res = RecursiveASTVisitor::TraverseCXXBaseSpecifier(Base); + Parent = OldParent; + return res; + } + + bool VisitAttr(Attr *A) { + if (Parent) + VisitFn(Node(A), Parent, &AST, Data); + return true; + } + + bool VisitTranslationUnitDecl(TranslationUnitDecl *TU) { + if (!AST.getPreprocessor().getPreprocessingRecord()) + return true; + + PreprocessingRecord &PPRec = + *AST.getPreprocessor().getPreprocessingRecord(); + SourceManager &SM = AST.getSourceManager(); + + bool OnlyLocalDecls = !AST.isMainFileAST() && AST.getOnlyLocalDecls(); + + if (OnlyLocalDecls) + return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(), + PPRec); + + return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec); + } + + bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { + // We handle forward declarations in TraverseDecl + if (!D || !D->isThisDeclarationADefinition()) + return true; + + if (D->getSuperClass() + && VisitFn(Node(D->getSuperClass(), CXCursor_ObjCSuperClassRef), Parent, &AST, Data) == CXChildVisit_Break) + return false; + + for (auto I : D->protocols()) + if (VisitFn(Node(&*I, CXCursor_ObjCProtocolRef), Parent, &AST, Data) == CXChildVisit_Break) + return false; + + return true; + } + + bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { + Node interfaceNode(ND->getClassInterface(), CXCursor_ObjCClassRef); + if (VisitFn(interfaceNode, Parent, &AST, Data) == CXChildVisit_Break) + return false; + + // TypeParamList is visited in RecursiveASTvisitor + + for (auto I : ND->protocols()) + if (VisitFn(Node(&*I, CXCursor_ObjCProtocolRef), Parent, &AST, Data) == CXChildVisit_Break) + return false; + + // We may need to do the weird hacky thing that the libclang visitor does in + // VisitObjCContainerDecl, but I hope not... + return true; + } + + bool VisitObjCProtocolDecl(ObjCProtocolDecl *PD) { + for (auto I : PD->protocols()) + if (VisitFn(Node(&*I, CXCursor_ObjCProtocolRef), Parent, &AST, Data) == CXChildVisit_Break) + return false; + + // We may need to do the weird hacky thing that the libclang visitor does in + // VisitObjCContainerDecl, but I hope not... + return true; + } + + bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD) { + if (!PD) + return true; + + // FIXME: This implements a workaround with @property declarations also + // being + // installed in the DeclContext for the @interface. Eventually this code + // should be removed. + ObjCCategoryDecl *CDecl = dyn_cast(PD->getDeclContext()); + if (!CDecl || !CDecl->IsClassExtension()) + return true; + + ObjCInterfaceDecl *ID = CDecl->getClassInterface(); + if (!ID) + return true; + + IdentifierInfo *PropertyId = PD->getIdentifier(); + ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl( + cast(ID), PropertyId, PD->getQueryKind()); + + if (!prevDecl) + return true; + + // Visit synthesized methods since they will be skipped when visiting + // the @interface. + if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl()) + if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl) + if (!TraverseDecl(MD)) + return false; + + if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl()) + if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl) + if (!TraverseDecl(MD)) + return false; + + return true; + } + + bool VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) { + if (!D) + return true; + return TraverseDecl(D) != CXChildVisit_Break; + } + +private: + template + bool visitPreprocessedEntities(InputIterator First, InputIterator Last, + PreprocessingRecord &PPRec) { + for (; First != Last; ++First) { + PreprocessedEntity *PPE = *First; + if (!PPE) + continue; + + Node node; + if (isa(PPE)) { + node = Node(PPE, CXCursor_MacroExpansion); + } else if (isa(PPE)) { + node = Node(PPE, CXCursor_MacroDefinition); + } else if (isa(PPE)) { + node = Node(PPE, CXCursor_InclusionDirective); + } + if (node) { + if (VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break) + return false; + } + } + + return true; + } +}; + +void Decl_visitChildren(const Decl *Parent, CXCursorKind kind, Visitor V, + ASTUnit *Unit, CXClientData data) { + BindgenVisitor visitor(*Unit, V, data); + visitor.TraverseDeclTyped(const_cast(&*Parent), kind); +} +void Expr_visitChildren(const Expr *Parent, CXCursorKind kind, Visitor V, + ASTUnit *Unit, CXClientData data) { + BindgenVisitor visitor(*Unit, V, data); + visitor.TraverseExprTyped(const_cast(&*Parent), kind); +} +void CXXBaseSpecifier_visitChildren(const CXXBaseSpecifier *Parent, + CXCursorKind kind, Visitor V, ASTUnit *Unit, + CXClientData data) { + BindgenVisitor visitor(*Unit, V, data); + visitor.TraverseCXXBaseSpecifier(*Parent); +} + +void disposeTokens(const ASTUnit *TU, CXToken *Tokens, unsigned NumTokens) { + delete[] Tokens; +} + +BindgenStringRef Type_getTypeSpelling(QualType T, ASTContext *Context) { + SmallString<64> Str; + llvm::raw_svector_ostream OS(Str); + PrintingPolicy PP(Context->getLangOpts()); + + T.print(OS, PP); + return stringref(OS.str()); +} + +bool Type_isConstQualifiedType(QualType T) { + return T.isLocalConstQualified(); +} + +int Type_getNumTemplateArguments(QualType T) { + if (T.isNull()) + return -1; + auto TA = GetTemplateArguments(T); + if (!TA) + return -1; + + return GetTemplateArgumentArraySize(TA.getValue()); +} + +QualType Type_getArgType(QualType T, unsigned i) { + if (T.isNull()) + return QualType(); + + if (const FunctionProtoType *FD = T->getAs()) { + unsigned numParams = FD->getNumParams(); + if (i >= numParams) + return QualType(); + return make_type_compatible(FD->getParamType(i)); + } + + return QualType(); +} + +int Type_getNumArgTypes(QualType T) { + if (T.isNull()) + return -1; + + if (const FunctionProtoType *FD = T->getAs()) { + return FD->getNumParams(); + } + + if (T->getAs()) { + return 0; + } + + return -1; +} + +QualType Type_getCanonicalType(QualType T, ASTContext *Context) { + if (T.isNull()) + return QualType(); + + return make_type_compatible(Context->getCanonicalType(T)); +} + +bool Type_isFunctionTypeVariadic(QualType T) { + if (T.isNull()) + return false; + + if (const FunctionProtoType *FD = T->getAs()) + return (unsigned)FD->isVariadic(); + + if (T->getAs()) + return true; + + return false; +} + +QualType Type_getResultType(QualType T) { + if (T.isNull()) + return QualType(); + + if (const FunctionType *FD = T->getAs()) + return make_type_compatible(FD->getReturnType()); + + return QualType(); +} + +QualType Type_getNamedType(QualType T) { + const Type *TP = T.getTypePtrOrNull(); + + if (TP && TP->getTypeClass() == Type::Elaborated) + return make_type_compatible(cast(TP)->getNamedType()); + + return QualType(); +} + +QualType Type_getTemplateArgumentAsType(QualType T, unsigned index) { + if (T.isNull()) + return QualType(); + + auto TA = GetTemplateArguments(T); + if (!TA) + return QualType(); + + Optional QT = FindTemplateArgumentTypeAt(TA.getValue(), index); + return make_type_compatible(QT.getValueOr(QualType())); +} + +unsigned Comment_getNumChildren(const comments::Comment *C) { + if (!C) + return 0; + + return C->child_count(); +} + +comments::Comment *Comment_getChild(const comments::Comment *C, unsigned index) { + if (!C || index >= C->child_count()) + return nullptr; + + return *(C->child_begin() + index); +} + +BindgenStringRef HTMLTagComment_getTagName(const comments::Comment *C) { + if (auto *HTML = dyn_cast_or_null(C)) { + return stringref(HTML->getTagName()); + } else { + return stringref(); + } +} + +unsigned HTMLStartTag_getNumAttrs(const comments::Comment *C) { + if (auto *HTML = dyn_cast_or_null(C)) { + return HTML->getNumAttrs(); + } else { + return 0; + } +} + +BindgenStringRef HTMLStartTag_getAttrName(const comments::Comment *C, unsigned i) { + if (auto *HTML = dyn_cast_or_null(C)) { + return stringref(HTML->getAttr(i).Name); + } else { + return stringref(); + } +} + +BindgenStringRef HTMLStartTag_getAttrValue(const comments::Comment *C, unsigned i) { + if (auto *HTML = dyn_cast_or_null(C)) { + return stringref(HTML->getAttr(i).Value); + } else { + return stringref(); + } +} + +BindgenStringRef FileEntry_getName(FileEntry *F) { + if (!F) + return stringref(); + return stringref(F->getName()); +} + +BindgenStringRef getClangVersion() { + return stringref(getClangFullVersion()); +} + +bool CXXBaseSpecifier_isVirtualBase(const CXXBaseSpecifier *B) { + return B && B->isVirtual(); +} + +QualType CXXBaseSpecifier_getType(const CXXBaseSpecifier *B) { + if (!B) + return QualType(); + return make_type_compatible(B->getType()); +} + +BindgenStringRef CXXBaseSpecifier_getSpelling(const CXXBaseSpecifier *B) { + return stringref(B->getType().getAsString()); +} + +SourceLocation *CXXBaseSpecifier_getLocation(const CXXBaseSpecifier *B) { + return new SourceLocation(B->getBaseTypeLoc()); +} + +SourceLocation *Attr_getLocation(const Attr *A) { + return new SourceLocation(A->getLocation()); +} + +SourceLocation *PreprocessedEntity_getLocation(const PreprocessedEntity *PPE) { + return new SourceLocation(PPE->getSourceRange().getBegin()); +} + +BindgenSourceRange CXXBaseSpecifier_getSourceRange(const CXXBaseSpecifier *B) { + return BindgenSourceRange(B->getSourceRange()); +} + +BindgenSourceRange Attr_getSourceRange(const Attr *A) { + return BindgenSourceRange(A->getRange()); +} + +BindgenSourceRange PreprocessedEntity_getSourceRange(const PreprocessedEntity *PPE) { + return BindgenSourceRange(PPE->getSourceRange()); +} diff --git a/src/clang/ClangAST.hpp b/src/clang/clang_interface.hpp similarity index 99% rename from src/clang/ClangAST.hpp rename to src/clang/clang_interface.hpp index 03ae701031..d627cae0dd 100644 --- a/src/clang/ClangAST.hpp +++ b/src/clang/clang_interface.hpp @@ -1,3 +1,6 @@ +#ifndef BINDGEN_CLANG_AST_H +#define BINDGEN_CLANG_AST_H + #include "clang-c/Documentation.h" #include "clang-c/Index.h" @@ -254,3 +257,5 @@ SourceLocation *PreprocessedEntity_getLocation(const PreprocessedEntity *); BindgenSourceRange CXXBaseSpecifier_getSourceRange(const CXXBaseSpecifier *); BindgenSourceRange Attr_getSourceRange(const Attr *); BindgenSourceRange PreprocessedEntity_getSourceRange(const PreprocessedEntity *); + +#endif // BINDGEN_CLANG_AST_H diff --git a/src/clang/clangtool.rs b/src/clang/clang_interface.rs similarity index 100% rename from src/clang/clangtool.rs rename to src/clang/clang_interface.rs diff --git a/src/clang/clang_interface_impl.hpp b/src/clang/clang_interface_impl.hpp new file mode 100644 index 0000000000..05fbbb3df0 --- /dev/null +++ b/src/clang/clang_interface_impl.hpp @@ -0,0 +1,27 @@ +#ifndef BINDGEN_CLANG_INTERFACE_IMPL_H +#define BINDGEN_CLANG_INTERFACE_IMPL_H + +#include "clang/AST/Decl.h" +#include "clang/AST/Expr.h" + +#define BINDGEN_IMPLEMENTATION +#include "clang_interface.hpp" + +using namespace clang; + +// Utility functions defined in ClangAST.cpp +BindgenStringRef stringref(); +BindgenStringRef stringref(const char *newStr); +BindgenStringRef stringref(const std::string &s); +BindgenStringRef stringref(llvm::StringRef S); +QualType make_type_compatible(QualType QT); + +// Functions defined in libclang_compat.cpp +const Decl *getDeclFromExpr(const Stmt *E); +long long visitRecordForValidation(const RecordDecl *RD); +Optional> GetTemplateArguments(QualType Type); +unsigned GetTemplateArgumentArraySize(ArrayRef TA); +Optional FindTemplateArgumentTypeAt(ArrayRef TA, + unsigned index); + +#endif // BINDGEN_CLANG_INTERFACE_IMPL_H diff --git a/src/clang/ClangAST.cpp b/src/clang/libclang_compat.cpp similarity index 57% rename from src/clang/ClangAST.cpp rename to src/clang/libclang_compat.cpp index dd55a2b0e1..3986950dbf 100644 --- a/src/clang/ClangAST.cpp +++ b/src/clang/libclang_compat.cpp @@ -1,4 +1,7 @@ -#include +// The functions in this file are adapted from the LLVM Project, used under the +// Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "llvm/Support/CrashRecoveryContext.h" #include "clang/AST/Comment.h" @@ -9,54 +12,18 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" -#include "clang/AST/Mangle.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Basic/Version.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" -#include "clang/Index/USRGeneration.h" -#include "clang/Lex/PreprocessorOptions.h" #include "clang-c/Documentation.h" #include "clang-c/Index.h" -#define BINDGEN_IMPLEMENTATION -#include "ClangAST.hpp" +#include "clang_interface_impl.hpp" using namespace clang; -BindgenStringRef stringref() { - BindgenStringRef ref; - ref.s = nullptr; - ref.len = 0; - return ref; -} - -BindgenStringRef stringref(const char *newStr) { - BindgenStringRef ref; - ref.len = strlen(newStr); - ref.s = new char[ref.len + 1]; - strncpy(ref.s, newStr, ref.len); - ref.s[ref.len] = '\0'; - return ref; -} - -BindgenStringRef stringref(const std::string &s) { - return stringref(s.c_str()); -} - -BindgenStringRef stringref(llvm::StringRef S) { - BindgenStringRef ref; - ref.len = S.size(); - ref.s = new char[ref.len + 1]; - strncpy(ref.s, S.data(), ref.len); - ref.s[ref.len] = '\0'; - return ref; -} - -// From libclang/CIndex.cpp -static const Decl *getDeclFromExpr(const Stmt *E) { +// From CIndex.cpp +const Decl *getDeclFromExpr(const Stmt *E) { if (const ImplicitCastExpr *CE = dyn_cast(E)) return getDeclFromExpr(CE->getSubExpr()); @@ -107,2587 +74,222 @@ static const Decl *getDeclFromExpr(const Stmt *E) { return nullptr; } -BindgenSourceRange::BindgenSourceRange(const SourceRange &range) { - B = new SourceLocation(range.getBegin()); - E = new SourceLocation(range.getEnd()); -} - -BindgenStringRefSet make_stringrefset(std::vector &string_vec) { - BindgenStringRefSet set; - set.len = string_vec.size(); - set.strings = new BindgenStringRef[set.len]; - for (size_t i = 0; i < set.len; ++i) - set.strings[i] = stringref(string_vec[i]); - return set; -} - - -void freeString(BindgenStringRef s) { - delete[] s.s; -} - -char *cString(BindgenStringRef s) { return s.s; } - -ASTContext *ASTUnit_getContext(ASTUnit *Unit) { - return &Unit->getASTContext(); +// From CXType.cpp +static bool isTypeIncompleteForLayout(QualType QT) { + return QT->isIncompleteType() && !QT->isIncompleteArrayType(); } -ASTUnit *parseTranslationUnit(const char *source_filename, - const char *const *command_line_args, - int num_command_line_args, int options, - struct CXUnsavedFile *unsaved_files, - unsigned num_unsaved_files) { - SmallVector Args; - Args.push_back("clang"); - Args.append(command_line_args, command_line_args + num_command_line_args); - - std::unique_ptr> RemappedFiles( - new std::vector()); - // Recover resources if we crash before exiting this function. - llvm::CrashRecoveryContextCleanupRegistrar< - std::vector > RemappedCleanup(RemappedFiles.get()); - - for (auto &UF : llvm::makeArrayRef(unsaved_files, num_unsaved_files)) { - std::unique_ptr MB = - llvm::MemoryBuffer::getMemBufferCopy(StringRef(UF.Contents, UF.Length), UF.Filename); - RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release())); +// Adapted from CXType.cpp +long long visitRecordForValidation(const RecordDecl *RD) { + if (!RD) + return -1; + RD = RD->getDefinition(); + if (!RD || RD->isInvalidDecl() || !RD->isCompleteDefinition()) + return -1; + for (const auto *I : RD->fields()){ + QualType FQT = I->getType(); + if (isTypeIncompleteForLayout(FQT)) + return CXTypeLayoutError_Incomplete; + if (FQT->isDependentType()) + return CXTypeLayoutError_Dependent; + // recurse + if (const RecordType *ChildType = I->getType()->getAs()) { + if (const RecordDecl *Child = ChildType->getDecl()) { + long long ret = visitRecordForValidation(Child); + if (ret < 0) + return ret; + } + } + // else try next field } - - // Configure the diagnostics. - IntrusiveRefCntPtr - Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); - - if (options & CXTranslationUnit_KeepGoing) - Diags->setFatalsAsError(true); - - CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All; - if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles) - CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes; - - if (options & CXTranslationUnit_DetailedPreprocessingRecord) { - // Tell the preprocessor to save a detailed preprocessing record - Args.push_back("-Xclang"); - Args.push_back("-detailed-preprocessing-record"); + if (auto *Class = dyn_cast(RD)) { + for (const CXXBaseSpecifier &Base : Class->bases()) { + auto *baseDecl = Base.getType()->getAsCXXRecordDecl(); + long long ret = visitRecordForValidation(baseDecl); + if (ret < 0) + return ret; + } } - - return ASTUnit::LoadFromCommandLine( - Args.data(), Args.data() + Args.size(), - std::make_shared(), Diags, - /*ResourceFilePath*/ StringRef(), - /*OnlyLocalDecls*/ false, CaptureDiagnostics, *RemappedFiles.get(), - /*RemappedFilesKeepOriginalName*/ true); -} - -void disposeASTUnit(ASTUnit *AU) { - delete AU; -} - -unsigned ASTUnit_getNumDiagnostics(const ASTUnit *AU) { - return AU->stored_diag_size(); -} - -const StoredDiagnostic *ASTUnit_getDiagnostic(const ASTUnit *AU, unsigned i) { - return (AU->stored_diag_begin()+i); -} - -const TargetInfo *ASTUnit_getTargetInfo(ASTUnit *Unit) { - return &Unit->getASTContext().getTargetInfo(); + return 0; } -int TargetInfo_getPointerWidth(const TargetInfo *TI) { - if (!TI) - return -1; - return TI->getMaxPointerWidth(); +// From CXType.cpp +static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { +#define BTCASE(K) case BuiltinType::K: return CXType_##K + switch (BT->getKind()) { + BTCASE(Void); + BTCASE(Bool); + BTCASE(Char_U); + BTCASE(UChar); + BTCASE(Char16); + BTCASE(Char32); + BTCASE(UShort); + BTCASE(UInt); + BTCASE(ULong); + BTCASE(ULongLong); + BTCASE(UInt128); + BTCASE(Char_S); + BTCASE(SChar); + case BuiltinType::WChar_S: return CXType_WChar; + case BuiltinType::WChar_U: return CXType_WChar; + BTCASE(Short); + BTCASE(Int); + BTCASE(Long); + BTCASE(LongLong); + BTCASE(Int128); + BTCASE(Half); + BTCASE(Float); + BTCASE(Double); + BTCASE(LongDouble); + BTCASE(ShortAccum); + BTCASE(Accum); + BTCASE(LongAccum); + BTCASE(UShortAccum); + BTCASE(UAccum); + BTCASE(ULongAccum); + BTCASE(Float16); + BTCASE(Float128); + BTCASE(NullPtr); + BTCASE(Overload); + BTCASE(Dependent); + BTCASE(ObjCId); + BTCASE(ObjCClass); + BTCASE(ObjCSel); +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) BTCASE(Id); +#include "clang/Basic/OpenCLImageTypes.def" +#undef IMAGE_TYPE +#if CLANG_VERSION_MAJOR > 8 +#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) BTCASE(Id); +#include "clang/Basic/OpenCLExtensionTypes.def" +#endif // CLANG_VERSION_MAJOR > 8 + BTCASE(OCLSampler); + BTCASE(OCLEvent); + BTCASE(OCLQueue); + BTCASE(OCLReserveID); + default: + return CXType_Unexposed; + } +#undef BTCASE } -BindgenStringRef TargetInfo_getTriple(const TargetInfo *TI) { - if (!TI) - return stringref(); - - std::string Triple = TI->getTriple().normalize(); - return stringref(Triple); -} +// Adapted from GetTypeKind in CXType.cpp +CXTypeKind Type_kind(QualType T, ASTContext *Context) { + const Type *TP = T.getTypePtrOrNull(); + if (!TP) + return CXType_Invalid; -struct EvalResult { - CXEvalResultKind EvalType; - APValue Val; - std::string stringVal; - - EvalResult() : EvalType(CXEval_UnExposed) {} - EvalResult(APValue Val) : EvalType(CXEval_UnExposed), Val(Val) { - if (Val.isInt()) - EvalType = CXEval_Int; - else if (Val.isFloat()) - EvalType = CXEval_Float; + // libclang checks for these builtin types specially and matches on things + // that appear to be correct + if (Context->getLangOpts().ObjC) { + QualType UT = T.getUnqualifiedType(); + if (Context->isObjCIdType(UT)) + return CXType_ObjCId; + if (Context->isObjCClassType(UT)) + return CXType_ObjCClass; + if (Context->isObjCSelType(UT)) + return CXType_ObjCSel; } - EvalResult(std::string str) : EvalType(CXEval_StrLiteral), stringVal(str) {} -}; - -EvalResult *Expr_Evaluate(const Expr *E, ASTContext *Ctx) { - if (!E || E->isValueDependent()) - return nullptr; - Expr::EvalResult res; - if (E->EvaluateAsRValue(res, *Ctx)) { - if (E->getStmtClass() == Stmt::ImplicitCastExprClass) { - const ImplicitCastExpr *I = dyn_cast(&*E); - auto *subExpr = I->getSubExprAsWritten(); - if (subExpr->getStmtClass() == Stmt::StringLiteralClass) { - auto StrE = cast(I->getSubExprAsWritten()); - return new EvalResult(StrE->getString().str()); - } - } else if (E->getStmtClass() == Stmt::StringLiteralClass) { - auto StrE = cast(&*E); - return new EvalResult(StrE->getString().str()); - } - return new EvalResult(res.Val); +#define TKCASE(K) case Type::K: return CXType_##K + switch (TP->getTypeClass()) { + case Type::Builtin: + return GetBuiltinTypeKind(cast(TP)); + TKCASE(Complex); + TKCASE(Pointer); + TKCASE(BlockPointer); + TKCASE(LValueReference); + TKCASE(RValueReference); + TKCASE(Record); + TKCASE(Enum); + TKCASE(Typedef); + TKCASE(ObjCInterface); + TKCASE(ObjCObject); + TKCASE(ObjCObjectPointer); + TKCASE(ObjCTypeParam); + TKCASE(FunctionNoProto); + TKCASE(FunctionProto); + TKCASE(ConstantArray); + TKCASE(IncompleteArray); + TKCASE(VariableArray); + TKCASE(DependentSizedArray); + TKCASE(Vector); + TKCASE(ExtVector); + TKCASE(MemberPointer); + TKCASE(Auto); + TKCASE(Elaborated); + TKCASE(Pipe); + TKCASE(Attributed); + default: + return CXType_Unexposed; } - - return nullptr; +#undef TKCASE } -EvalResult *Decl_Evaluate(const Decl *D, ASTContext *Ctx) { - if (!D) - return nullptr; +// From CXType.cpp +Optional> +GetTemplateArguments(QualType Type) { + assert(!Type.isNull()); + if (const auto *Specialization = Type->getAs()) + return Specialization->template_arguments(); - const Expr *E; - if (auto *Var = dyn_cast(&*D)) - E = Var->getInit(); - else if (auto *Field = dyn_cast(&*D)) - E = Field->getInClassInitializer(); - else - return nullptr; + if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) { + const auto *TemplateDecl = + dyn_cast(RecordDecl); + if (TemplateDecl) + return TemplateDecl->getTemplateArgs().asArray(); + } - return Expr_Evaluate(E, Ctx); + return None; } -CXEvalResultKind EvalResult_getKind(EvalResult *ER) { - if (!ER) - return CXEval_UnExposed; - return ER->EvalType; +// From CXType.cpp +unsigned GetTemplateArgumentArraySize(ArrayRef TA) { + unsigned size = TA.size(); + for (const auto &Arg : TA) + if (Arg.getKind() == TemplateArgument::Pack) + size += Arg.pack_size() - 1; + return size; } -double EvalResult_getAsDouble(EvalResult *ER) { - if (!ER) - return 0; - auto apFloat = ER->Val.getFloat(); - bool ignored; - apFloat.convert(llvm::APFloat::IEEEdouble(), - llvm::APFloat::rmNearestTiesToEven, &ignored); - return apFloat.convertToDouble(); +// From CXType.cpp +static Optional TemplateArgumentToQualType(const TemplateArgument &A) { + if (A.getKind() == TemplateArgument::Type) + return A.getAsType(); + return None; } -bool EvalResult_isUnsignedInt(EvalResult *ER) { - return ER && - ER->EvalType == CXEval_Int && - ER->Val.getInt().isUnsigned(); +// From CXType.cpp +Optional +FindTemplateArgumentTypeAt(ArrayRef TA, unsigned index) { + unsigned current = 0; + for (const auto &A : TA) { + if (A.getKind() == TemplateArgument::Pack) { + if (index < current + A.pack_size()) + return TemplateArgumentToQualType(A.getPackAsArray()[index - current]); + current += A.pack_size(); + continue; + } + if (current == index) + return TemplateArgumentToQualType(A); + current++; + } + return None; } -long long EvalResult_getAsLongLong(EvalResult *ER) { - if (!ER) - return 0; - - auto intVal = ER->Val.getInt(); - if (intVal.isUnsigned()) - return intVal.getZExtValue(); - else - return intVal.getExtValue(); -} - -unsigned long long EvalResult_getAsUnsigned(EvalResult *ER) { - return static_cast(EvalResult_getAsLongLong(ER)); -} - -BindgenStringRef EvalResult_getAsStr(EvalResult *ER) { - if (!ER) - return stringref(); - - return stringref(ER->stringVal); -} - -BindgenStringRef Diagnostic_format(const StoredDiagnostic *D) { - if (!D) - return stringref(); - - return stringref(D->getMessage()); -} - -CXDiagnosticSeverity Diagnostic_getSeverity(const StoredDiagnostic *D) { - switch (D->getLevel()) { - case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored; - case DiagnosticsEngine::Note: return CXDiagnostic_Note; - case DiagnosticsEngine::Remark: - // The 'Remark' level isn't represented in the stable API. - case DiagnosticsEngine::Warning: return CXDiagnostic_Warning; - case DiagnosticsEngine::Error: return CXDiagnostic_Error; - case DiagnosticsEngine::Fatal: return CXDiagnostic_Fatal; - } - - llvm_unreachable("Invalid diagnostic level"); -} - -const Decl *getTranslationUnitDecl(ASTUnit *Unit) { - return Unit->getASTContext().getTranslationUnitDecl(); -} - -bool CursorKind_isInvalid(CXCursorKind kind) { - return kind >= CXCursor_FirstInvalid && kind <= CXCursor_LastInvalid; -} - -const Decl *Decl_getLexicalParent(const Decl *D) { - if (!D) - return nullptr; - - const DeclContext *DC = D->getLexicalDeclContext(); - if (!DC) - return nullptr; - - return cast(DC); -} - -const Decl *Decl_getSemanticParent(const Decl *D) { - if (!D) - return nullptr; - - const DeclContext *DC = D->getDeclContext(); - if (!DC) - return nullptr; - - // We replace CXXRecordDecl's inside ClassTemplateDecls with just the - // ClassTemplateDecl because we never expose the inner CXXRecordDecl to Rust. - if (auto *RD = dyn_cast(DC)) { - auto *ClassTemplate = RD->getDescribedClassTemplate(); - if (ClassTemplate) - return ClassTemplate; - } - - return cast(DC); -} - -// ASTUnit *Decl_getTranslationUnit(const Decl *D) { -// if (!D) -// return nullptr; - -// return D.unit; -// } - -const Decl *Decl_getDefinition(const Decl *D, bool isReference) { - if (!D) - return nullptr; - - switch (D->getKind()) { - // Declaration kinds that don't really separate the notions of - // declaration and definition. - case Decl::Namespace: - case Decl::Typedef: - case Decl::TypeAlias: - case Decl::TypeAliasTemplate: - case Decl::TemplateTypeParm: - case Decl::EnumConstant: - case Decl::Field: - case Decl::Binding: - case Decl::MSProperty: - case Decl::IndirectField: - case Decl::ObjCIvar: - case Decl::ObjCAtDefsField: - case Decl::ImplicitParam: - case Decl::ParmVar: - case Decl::NonTypeTemplateParm: - case Decl::TemplateTemplateParm: - case Decl::ObjCCategoryImpl: - case Decl::ObjCImplementation: - case Decl::AccessSpec: - case Decl::LinkageSpec: - case Decl::Export: - case Decl::ObjCPropertyImpl: - case Decl::FileScopeAsm: - case Decl::StaticAssert: - case Decl::Block: - case Decl::Captured: - case Decl::OMPCapturedExpr: - case Decl::Label: // FIXME: Is this right?? - case Decl::ClassScopeFunctionSpecialization: - case Decl::CXXDeductionGuide: - case Decl::Import: - case Decl::OMPThreadPrivate: - case Decl::OMPAllocate: - case Decl::OMPDeclareReduction: - case Decl::OMPDeclareMapper: - case Decl::OMPRequires: - case Decl::ObjCTypeParam: - case Decl::BuiltinTemplate: - case Decl::PragmaComment: - case Decl::PragmaDetectMismatch: - case Decl::UsingPack: - case Decl::Concept: - return D; - - // Declaration kinds that don't make any sense here, but are - // nonetheless harmless. - case Decl::Empty: - case Decl::TranslationUnit: - case Decl::ExternCContext: - break; - - // Declaration kinds for which the definition is not resolvable. - case Decl::UnresolvedUsingTypename: - case Decl::UnresolvedUsingValue: - break; - - case Decl::UsingDirective: - return cast(&*D)->getNominatedNamespace(); - - case Decl::NamespaceAlias: - return cast(&*D)->getNamespace(); - - case Decl::Enum: - case Decl::Record: - case Decl::CXXRecord: - case Decl::ClassTemplateSpecialization: - case Decl::ClassTemplatePartialSpecialization: - if (TagDecl *Def = cast(&*D)->getDefinition()) - return Def; - break; - - case Decl::Function: - case Decl::CXXMethod: - case Decl::CXXConstructor: - case Decl::CXXDestructor: - case Decl::CXXConversion: { - const FunctionDecl *Def = nullptr; - if (cast(&*D)->getBody(Def)) - return Def; - break; - } - - case Decl::Var: - case Decl::VarTemplateSpecialization: - case Decl::VarTemplatePartialSpecialization: - case Decl::Decomposition: { - // Ask the variable if it has a definition. - if (const VarDecl *Def = cast(&*D)->getDefinition()) - return Def; - break; - } - - case Decl::FunctionTemplate: { - const FunctionDecl *Def = nullptr; - if (cast(&*D)->getTemplatedDecl()->getBody(Def)) - return Def->getDescribedFunctionTemplate(); - break; - } - - case Decl::ClassTemplate: { - if (RecordDecl *Def = - cast(&*D)->getTemplatedDecl()->getDefinition()) - return cast(Def)->getDescribedClassTemplate(); - break; - } - - case Decl::VarTemplate: { - if (VarDecl *Def = - cast(&*D)->getTemplatedDecl()->getDefinition()) - return cast(Def)->getDescribedVarTemplate(); - break; - } - - case Decl::Using: - return cast(&*D); - - case Decl::UsingShadow: - case Decl::ConstructorUsingShadow: - return Decl_getDefinition( - cast(&*D)->getTargetDecl(), isReference); - - case Decl::ObjCMethod: { - const ObjCMethodDecl *Method = cast(D); - if (Method->isThisDeclarationADefinition()) - return D; - - // Dig out the method definition in the associated - // @implementation, if we have it. - // FIXME: The ASTs should make finding the definition easier. - if (const ObjCInterfaceDecl *Class - = dyn_cast(Method->getDeclContext())) - if (ObjCImplementationDecl *ClassImpl = Class->getImplementation()) - if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(), - Method->isInstanceMethod())) - if (Def->isThisDeclarationADefinition()) - return Def; - - break; - } - - case Decl::ObjCCategory: - if (ObjCCategoryImplDecl *Impl = cast(D)->getImplementation()) - return Impl; - break; - - case Decl::ObjCProtocol: - if (const ObjCProtocolDecl *Def = cast(D)->getDefinition()) - return Def; - break; - - case Decl::ObjCInterface: { - // There are two notions of a "definition" for an Objective-C - // class: the interface and its implementation. When we resolved a - // reference to an Objective-C class, produce the @interface as - // the definition; when we were provided with the interface, - // produce the @implementation as the definition. - const ObjCInterfaceDecl *IFace = cast(D); - if (isReference) { - if (const ObjCInterfaceDecl *Def = IFace->getDefinition()) - return Def; - } else if (ObjCImplementationDecl *Impl = IFace->getImplementation()) - return Impl; - break; - } - - case Decl::ObjCProperty: - // FIXME: We don't really know where to find the - // ObjCPropertyImplDecls that implement this property. - break; - - case Decl::ObjCCompatibleAlias: - if (const ObjCInterfaceDecl *Class - = cast(D)->getClassInterface()) - if (const ObjCInterfaceDecl *Def = Class->getDefinition()) - return Def; - - break; - - case Decl::Friend: - if (NamedDecl *Friend = cast(&*D)->getFriendDecl()) - return Decl_getDefinition(Friend, isReference); - break; - - case Decl::FriendTemplate: - if (NamedDecl *Friend = cast(&*D)->getFriendDecl()) - return Decl_getDefinition(Friend, isReference); - break; - } - - return nullptr; -} - -const Decl *Decl_getReferenced(const Decl *D) { - if (!D) - return nullptr; - - // TODO(sjc): Handle UsingDecl? - return D; -} - -const Decl *Decl_getCanonical(const Decl *D) { - if (!D) - return nullptr; - if (const ObjCCategoryImplDecl *CatImplD = dyn_cast(D)) - if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl()) - return CatD; - - if (const ObjCImplDecl *ImplD = dyn_cast(D)) - if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) - return IFD; - - return D->getCanonicalDecl(); -} - -const Decl *Decl_getSpecializedTemplate(const Decl *D) { - if (!D) - return nullptr; - - Decl *Template = nullptr; - if (const CXXRecordDecl *CXXRecord = dyn_cast(&*D)) { - if (const ClassTemplatePartialSpecializationDecl *PartialSpec - = dyn_cast(CXXRecord)) - Template = PartialSpec->getSpecializedTemplate(); - else if (const ClassTemplateSpecializationDecl *ClassSpec - = dyn_cast(CXXRecord)) { - llvm::PointerUnion Result - = ClassSpec->getSpecializedTemplateOrPartial(); - if (Result.is()) - Template = Result.get(); - else - Template = Result.get(); - - } else - Template = CXXRecord->getInstantiatedFromMemberClass(); - } else if (const FunctionDecl *Function = dyn_cast(&*D)) { - Template = Function->getPrimaryTemplate(); - if (!Template) - Template = Function->getInstantiatedFromMemberFunction(); - } else if (const VarDecl *Var = dyn_cast(&*D)) { - if (Var->isStaticDataMember()) - Template = Var->getInstantiatedFromStaticDataMember(); - } else if (const RedeclarableTemplateDecl *Tmpl - = dyn_cast(&*D)) - Template = Tmpl->getInstantiatedFromMemberTemplate(); - - return Template; -} - -CXCursorKind Decl_getTemplateCursorKind(const Decl *D) { - if (!D) - return CXCursor_NoDeclFound; - - switch (D->getKind()) { - case Decl::ClassTemplate: - case Decl::FunctionTemplate: - if (const TemplateDecl *Template = dyn_cast_or_null(&*D)) - return getCursorKindForDecl(Template->getTemplatedDecl()); - break; - - case Decl::ClassTemplatePartialSpecialization: - if (const ClassTemplateSpecializationDecl *PartialSpec - = dyn_cast_or_null(&*D)) { - switch (PartialSpec->getTagKind()) { - case TTK_Interface: - case TTK_Struct: return CXCursor_StructDecl; - case TTK_Class: return CXCursor_ClassDecl; - case TTK_Union: return CXCursor_UnionDecl; - case TTK_Enum: return CXCursor_NoDeclFound; - } - } - break; - - default: - break; - } - - return CXCursor_NoDeclFound; -} - -const Decl *Decl_getArgument(const Decl *D, unsigned i) { - if (!D) - return nullptr; - - if (const ObjCMethodDecl *MD = dyn_cast_or_null(&*D)) { - if (i < MD->param_size()) - return MD->parameters()[i]; - } else if (const FunctionDecl *FD = dyn_cast_or_null(&*D)) { - if (i < FD->param_size()) - return FD->parameters()[i]; - } - - return nullptr; -} - -int Decl_getNumArguments(const Decl *D) { - if (const ObjCMethodDecl *MD = dyn_cast_or_null(&*D)) - return MD->param_size(); - if (const FunctionDecl *FD = dyn_cast_or_null(&*D)) - return FD->param_size(); - - return -1; -} - -BindgenStringRef Decl_getUSR(const Decl *D) { - SmallString<128> Buf; - if (index::generateUSRForDecl(&*D, Buf)) - return stringref(); - else - return stringref(Buf.str()); -} - -BindgenStringRef Decl_getSpelling(const Decl *D) { - if (!D) - return stringref(); - - const NamedDecl *ND = dyn_cast_or_null(&*D); - if (!ND) { - if (const ObjCPropertyImplDecl *PropImpl = - dyn_cast(D)) - if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl()) - return stringref(Property->getIdentifier()->getName()); - - if (const ImportDecl *ImportD = dyn_cast(D)) - if (Module *Mod = ImportD->getImportedModule()) - return stringref(Mod->getFullModuleName()); - - return stringref(); - } - - if (const ObjCMethodDecl *OMD = dyn_cast(ND)) - return stringref(OMD->getSelector().getAsString()); - - if (const ObjCCategoryImplDecl *CIMP = dyn_cast(ND)) - // No, this isn't the same as the code below. getIdentifier() is non-virtual - // and returns different names. NamedDecl returns the class name and - // ObjCCategoryImplDecl returns the category name. - return stringref(CIMP->getIdentifier()->getNameStart()); - - if (isa(D)) - return stringref(); - - SmallString<1024> S; - llvm::raw_svector_ostream os(S); - ND->printName(os); - return stringref(S.str()); -} - -// BindgenStringRef Decl_getDisplayName(const Decl *D) { -// } - -BindgenStringRef Decl_getMangling(const Decl *D, ASTContext *Ctx) { - if (!D || !(isa(&*D) || isa(&*D))) - return stringref(); - - ASTNameGenerator ASTNameGen(*Ctx); - return stringref(ASTNameGen.getName(&*D)); -} - -BindgenStringRefSet Decl_getCXXManglings(const Decl *D, ASTContext *Ctx) { - if (!D || !(isa(&*D) || isa(&*D))) - return BindgenStringRefSet(); - - ASTNameGenerator ASTNameGen(*Ctx); - std::vector Manglings = ASTNameGen.getAllManglings(&*D); - return make_stringrefset(Manglings); -} - -int Decl_getNumTemplateArguments(const Decl *D) { - const FunctionDecl *FD = llvm::dyn_cast_or_null(&*D); - if (!FD) - return -1; - - const FunctionTemplateSpecializationInfo* SpecInfo = - FD->getTemplateSpecializationInfo(); - if (!SpecInfo) { - return -1; - } - - return SpecInfo->TemplateArguments->size(); -} - -CXCursorKind Decl_getCXCursorKind(const Decl *D) { - if (!D) - return CXCursor_NoDeclFound; - else - return getCursorKindForDecl(&*D); -} - -bool Decl_isDefinition(const Decl *D) { - if (auto VD = dyn_cast_or_null(&*D)) - return VD->getDefinition() == &*D; - if (auto FD = dyn_cast_or_null(&*D)) - return FD->getDefinition() == &*D; - if (auto TD = dyn_cast_or_null(&*D)) - return TD->getDefinition() == &*D; - - return false; -} - -SourceLocation *Decl_getLocation(const Decl *D) { - if (!D) - return nullptr; - return new SourceLocation(D->getLocation()); -} - -BindgenStringRef Decl_getRawCommentText(const Decl *D, ASTContext *Ctx) { - if (!D) - return stringref(); - - const RawComment *RC = Ctx->getRawCommentForAnyRedecl(&*D); - StringRef RawText = RC ? RC->getRawText(Ctx->getSourceManager()) : - StringRef(); - return stringref(RawText); -} - -comments::Comment *Decl_getParsedComment(const Decl *D, ASTContext *Ctx) { - if (!D) - return nullptr; - return Ctx->getCommentForDecl(&*D, /*PP=*/nullptr); -} - -static QualType make_type_compatible(QualType QT) { - if (QT.isNull()) - return QT; - - // libclang does not return AttributedTypes if - // CXTranslationUnit_IncludeAttributedTypes is not set, and bindgen assumes it - // is not set. - if (auto *ATT = QT->getAs()) - return make_type_compatible(ATT->getEquivalentType()); - - // libclang does not return ParenTypes - if (auto *PTT = QT->getAs()) - return make_type_compatible(PTT->getInnerType()); - - // Decayed types should be passed as their original type - if (auto *DT = QT->getAs()) - return make_type_compatible(DT->getOriginalType()); - - return QT; -} - -QualType Decl_getType(const Decl *D, ASTContext *Ctx) { - auto ty = QualType(); - if (!D) - return ty; - - if (auto *TD = dyn_cast(&*D)) - ty = Ctx->getTypeDeclType(TD); - else if (auto *ID = dyn_cast(&*D)) - ty = Ctx->getObjCInterfaceType(ID); - else if (auto *DD = dyn_cast(&*D)) - ty = DD->getType(); - else if (auto *VD = dyn_cast(&*D)) - ty = VD->getType(); - else if (auto *PD = dyn_cast(&*D)) - ty = PD->getType(); - else if (auto *FTD = dyn_cast(&*D)) - ty = FTD->getTemplatedDecl()->getType(); - else - return QualType(); - - return make_type_compatible(ty); -} - -bool Decl_isFunctionInlined(const Decl *D) { - if (auto *FD = dyn_cast_or_null(&*D)) - return FD->isInlined(); - else - return false; -} - -int Decl_getFieldDeclBitWidth(const Decl *D, ASTContext *Ctx) { - if (auto *FD = dyn_cast_or_null(&*D)) { - if (FD->isBitField()) - return FD->getBitWidthValue(*Ctx); - } - return -1; -} - -QualType Decl_getEnumDeclIntegerType(const Decl *D) { - if (auto *TD = dyn_cast_or_null(&*D)) - return make_type_compatible(TD->getIntegerType()); - else - return QualType(); -} - -int64_t Decl_getEnumConstantValue(const Decl *D) { - if (auto *TD = dyn_cast_or_null(&*D)) - return TD->getInitVal().getSExtValue(); - else - return LLONG_MIN; -} - -uint64_t Decl_getEnumConstantUnsignedValue(const Decl *D) { - if (auto *TD = dyn_cast_or_null(&*D)) - return TD->getInitVal().getZExtValue(); - else - return ULLONG_MAX; -} - -static bool isTypeIncompleteForLayout(QualType QT) { - return QT->isIncompleteType() && !QT->isIncompleteArrayType(); -} - -static long long visitRecordForValidation(const RecordDecl *RD) { - if (!RD) - return -1; - RD = RD->getDefinition(); - if (!RD || RD->isInvalidDecl() || !RD->isCompleteDefinition()) - return -1; - for (const auto *I : RD->fields()){ - QualType FQT = I->getType(); - if (isTypeIncompleteForLayout(FQT)) - return CXTypeLayoutError_Incomplete; - if (FQT->isDependentType()) - return CXTypeLayoutError_Dependent; - // recurse - if (const RecordType *ChildType = I->getType()->getAs()) { - if (const RecordDecl *Child = ChildType->getDecl()) { - long long ret = visitRecordForValidation(Child); - if (ret < 0) - return ret; - } - } - // else try next field - } - if (auto *Class = dyn_cast(RD)) { - for (const CXXBaseSpecifier &Base : Class->bases()) { - auto *baseDecl = Base.getType()->getAsCXXRecordDecl(); - long long ret = visitRecordForValidation(baseDecl); - if (ret < 0) - return ret; - } - } - return 0; -} - -long long Decl_getOffsetOfField(const Decl *D, ASTContext *Ctx) { - auto *RD = dyn_cast_or_null(D->getDeclContext()); - auto Err = visitRecordForValidation(RD); - if (Err < 0) - return Err; - - if (auto *FD = dyn_cast_or_null(&*D)) - return Ctx->getFieldOffset(FD); - if (auto *IFD = dyn_cast_or_null(&*D)) - return Ctx->getFieldOffset(IFD); - - return -1; -} - -BindgenSourceRange Decl_getSourceRange(const Decl *D) { - return BindgenSourceRange(D->getSourceRange()); -} - -QualType Decl_getTypedefDeclUnderlyingType(const Decl *D) { - if (auto *TD = dyn_cast_or_null(&*D)) - return make_type_compatible(TD->getUnderlyingType()); - else - return QualType(); -} - -CXLinkageKind Decl_getLinkage(const Decl *D) { - if (auto *ND = dyn_cast_or_null(&*D)) - switch (ND->getLinkageInternal()) { - case NoLinkage: - case VisibleNoLinkage: - return CXLinkage_NoLinkage; - case ModuleInternalLinkage: - case InternalLinkage: - return CXLinkage_Internal; - case UniqueExternalLinkage: - return CXLinkage_UniqueExternal; - case ModuleLinkage: - case ExternalLinkage: - return CXLinkage_External; - }; - - return CXLinkage_Invalid; -} - -CXVisibilityKind Decl_getVisibility(const Decl *D) { - if (auto *ND = dyn_cast_or_null(&*D)) - switch (ND->getVisibility()) { - case HiddenVisibility: - return CXVisibility_Hidden; - case ProtectedVisibility: - return CXVisibility_Protected; - case DefaultVisibility: - return CXVisibility_Default; - }; - - return CXVisibility_Invalid; -} - -CX_CXXAccessSpecifier Decl_getAccess(const Decl *D) { - AccessSpecifier spec = AS_none; - if (D) - spec = D->getAccess(); - - switch (spec) { - case AS_public: return CX_CXXPublic; - case AS_protected: return CX_CXXProtected; - case AS_private: return CX_CXXPrivate; - case AS_none: return CX_CXXInvalidAccessSpecifier; - } - - llvm_unreachable("Invalid AccessSpecifier!"); -} - -bool CXXField_isMutable(const Decl *D) { - if (const auto FD = dyn_cast_or_null(&*D)) - return FD->isMutable(); - else - return false; -} - -bool CXXMethod_isStatic(const Decl *D) { - auto *Method = - D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; - return Method && Method->isStatic(); -} - -bool CXXMethod_isConst(const Decl *D) { - auto *Method = - D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; - return Method && Method->getMethodQualifiers().hasConst(); -} - -bool CXXMethod_isVirtual(const Decl *D) { - auto *Method = - D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; - return Method && Method->isVirtual(); -} - -bool CXXMethod_isPureVirtual(const Decl *D) { - auto *Method = - D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; - return Method && Method->isVirtual() && Method->isPure(); -} - -QualType Decl_getResultType(const Decl *D, ASTContext *Ctx) { - if (auto *MD = dyn_cast_or_null(D)) - return make_type_compatible(MD->getReturnType()); - - return Type_getResultType(Decl_getType(D, Ctx)); -} - -// const Decl *Expr_getSemanticParent(const Expr *E) { -// if (!E) -// return nullptr; - -// const DeclContext *DC = E->getParentContext(); -// if (!DC) -// return nullptr; - -// return cast(DC); -// } - -const Expr *Expr_getArgument(const Expr *E, unsigned i) { - if (const CallExpr *CE = dyn_cast_or_null(&*E)) { - if (i < CE->getNumArgs()) { - return CE->getArg(i); - } - } - if (const CXXConstructExpr *CE = dyn_cast_or_null(&*E)) { - if (i < CE->getNumArgs()) { - return CE->getArg(i); - } - } - return nullptr; -} - -int Expr_getNumArguments(const Expr *E) { - if (const CallExpr *CE = dyn_cast_or_null(&*E)) - return CE->getNumArgs(); - if (const CXXConstructExpr *CE = dyn_cast_or_null(&*E)) - return CE->getNumArgs(); - return -1; -} - -BindgenStringRef Expr_getSpelling(const Expr *E) { - if (auto *SL = dyn_cast_or_null(&*E)) { - SmallString<256> Buf; - llvm::raw_svector_ostream OS(Buf); - SL->outputString(OS); - return stringref(OS.str()); - } - if (auto *D = getDeclFromExpr(&*E)) - return Decl_getSpelling(D); - - return stringref(); -} - -CXCursorKind Expr_getCXCursorKind(const Expr *E) { - switch (E->getStmtClass()) { - case Stmt::NoStmtClass: - return CXCursor_NotImplemented; - case Stmt::CaseStmtClass: - return CXCursor_CaseStmt; - case Stmt::DefaultStmtClass: - return CXCursor_DefaultStmt; - case Stmt::IfStmtClass: - return CXCursor_IfStmt; - case Stmt::SwitchStmtClass: - return CXCursor_SwitchStmt; - case Stmt::WhileStmtClass: - return CXCursor_WhileStmt; - case Stmt::DoStmtClass: - return CXCursor_DoStmt; - case Stmt::ForStmtClass: - return CXCursor_ForStmt; - case Stmt::GotoStmtClass: - return CXCursor_GotoStmt; - case Stmt::IndirectGotoStmtClass: - return CXCursor_IndirectGotoStmt; - case Stmt::ContinueStmtClass: - return CXCursor_ContinueStmt; - case Stmt::BreakStmtClass: - return CXCursor_BreakStmt; - case Stmt::ReturnStmtClass: - return CXCursor_ReturnStmt; - case Stmt::GCCAsmStmtClass: - return CXCursor_GCCAsmStmt; - case Stmt::MSAsmStmtClass: - return CXCursor_MSAsmStmt; - case Stmt::ObjCAtTryStmtClass: - return CXCursor_ObjCAtTryStmt; - case Stmt::ObjCAtCatchStmtClass: - return CXCursor_ObjCAtCatchStmt; - case Stmt::ObjCAtFinallyStmtClass: - return CXCursor_ObjCAtFinallyStmt; - case Stmt::ObjCAtThrowStmtClass: - return CXCursor_ObjCAtThrowStmt; - case Stmt::ObjCAtSynchronizedStmtClass: - return CXCursor_ObjCAtSynchronizedStmt; - case Stmt::ObjCAutoreleasePoolStmtClass: - return CXCursor_ObjCAutoreleasePoolStmt; - case Stmt::ObjCForCollectionStmtClass: - return CXCursor_ObjCForCollectionStmt; - case Stmt::CXXCatchStmtClass: - return CXCursor_CXXCatchStmt; - case Stmt::CXXTryStmtClass: - return CXCursor_CXXTryStmt; - case Stmt::CXXForRangeStmtClass: - return CXCursor_CXXForRangeStmt; - case Stmt::SEHTryStmtClass: - return CXCursor_SEHTryStmt; - case Stmt::SEHExceptStmtClass: - return CXCursor_SEHExceptStmt; - case Stmt::SEHFinallyStmtClass: - return CXCursor_SEHFinallyStmt; - case Stmt::SEHLeaveStmtClass: - return CXCursor_SEHLeaveStmt; - - case Stmt::CoroutineBodyStmtClass: - case Stmt::CoreturnStmtClass: - return CXCursor_UnexposedStmt; - - case Stmt::OpaqueValueExprClass: - if (auto *Src = cast(&*E)->getSourceExpr()) - return Expr_getCXCursorKind(Src); - return CXCursor_UnexposedExpr; - - case Stmt::PseudoObjectExprClass: - return Expr_getCXCursorKind( - cast(&*E)->getSyntacticForm()); - - case Stmt::CompoundStmtClass: - return CXCursor_CompoundStmt; - - case Stmt::NullStmtClass: - return CXCursor_NullStmt; - - case Stmt::LabelStmtClass: - return CXCursor_LabelStmt; - - case Stmt::AttributedStmtClass: - return CXCursor_UnexposedStmt; - - case Stmt::DeclStmtClass: - return CXCursor_DeclStmt; - - case Stmt::CapturedStmtClass: - return CXCursor_UnexposedStmt; - - case Stmt::IntegerLiteralClass: - return CXCursor_IntegerLiteral; - - case Stmt::FixedPointLiteralClass: - return CXCursor_FixedPointLiteral; - - case Stmt::FloatingLiteralClass: - return CXCursor_FloatingLiteral; - - case Stmt::ImaginaryLiteralClass: - return CXCursor_ImaginaryLiteral; - - case Stmt::StringLiteralClass: - return CXCursor_StringLiteral; - - case Stmt::CharacterLiteralClass: - return CXCursor_CharacterLiteral; - - case Stmt::ConstantExprClass: - return Expr_getCXCursorKind(cast(&*E)->getSubExpr()); - - case Stmt::ParenExprClass: - return CXCursor_ParenExpr; - - case Stmt::UnaryOperatorClass: - return CXCursor_UnaryOperator; - - case Stmt::UnaryExprOrTypeTraitExprClass: - case Stmt::CXXNoexceptExprClass: - return CXCursor_UnaryExpr; - - case Stmt::MSPropertySubscriptExprClass: - case Stmt::ArraySubscriptExprClass: - return CXCursor_ArraySubscriptExpr; - - case Stmt::OMPArraySectionExprClass: - return CXCursor_OMPArraySectionExpr; - - case Stmt::BinaryOperatorClass: - return CXCursor_BinaryOperator; - - case Stmt::CompoundAssignOperatorClass: - return CXCursor_CompoundAssignOperator; - - case Stmt::ConditionalOperatorClass: - return CXCursor_ConditionalOperator; - - case Stmt::CStyleCastExprClass: - return CXCursor_CStyleCastExpr; - - case Stmt::CompoundLiteralExprClass: - return CXCursor_CompoundLiteralExpr; - - case Stmt::InitListExprClass: - return CXCursor_InitListExpr; - - case Stmt::AddrLabelExprClass: - return CXCursor_AddrLabelExpr; - - case Stmt::StmtExprClass: - return CXCursor_StmtExpr; - - case Stmt::GenericSelectionExprClass: - return CXCursor_GenericSelectionExpr; - - case Stmt::GNUNullExprClass: - return CXCursor_GNUNullExpr; - - case Stmt::CXXStaticCastExprClass: - return CXCursor_CXXStaticCastExpr; - - case Stmt::CXXDynamicCastExprClass: - return CXCursor_CXXDynamicCastExpr; - - case Stmt::CXXReinterpretCastExprClass: - return CXCursor_CXXReinterpretCastExpr; - - case Stmt::CXXConstCastExprClass: - return CXCursor_CXXConstCastExpr; - - case Stmt::CXXFunctionalCastExprClass: - return CXCursor_CXXFunctionalCastExpr; - - case Stmt::CXXTypeidExprClass: - return CXCursor_CXXTypeidExpr; - - case Stmt::CXXBoolLiteralExprClass: - return CXCursor_CXXBoolLiteralExpr; - - case Stmt::CXXNullPtrLiteralExprClass: - return CXCursor_CXXNullPtrLiteralExpr; - - case Stmt::CXXThisExprClass: - return CXCursor_CXXThisExpr; - - case Stmt::CXXThrowExprClass: - return CXCursor_CXXThrowExpr; - - case Stmt::CXXNewExprClass: - return CXCursor_CXXNewExpr; - - case Stmt::CXXDeleteExprClass: - return CXCursor_CXXDeleteExpr; - - case Stmt::ObjCStringLiteralClass: - return CXCursor_ObjCStringLiteral; - - case Stmt::ObjCEncodeExprClass: - return CXCursor_ObjCEncodeExpr; - - case Stmt::ObjCSelectorExprClass: - return CXCursor_ObjCSelectorExpr; - - case Stmt::ObjCProtocolExprClass: - return CXCursor_ObjCProtocolExpr; - case Stmt::ObjCBoolLiteralExprClass: - return CXCursor_ObjCBoolLiteralExpr; - - case Stmt::ObjCAvailabilityCheckExprClass: - return CXCursor_ObjCAvailabilityCheckExpr; - - case Stmt::ObjCBridgedCastExprClass: - return CXCursor_ObjCBridgedCastExpr; - - case Stmt::BlockExprClass: - return CXCursor_BlockExpr; - - case Stmt::PackExpansionExprClass: - return CXCursor_PackExpansionExpr; - - case Stmt::SizeOfPackExprClass: - return CXCursor_SizeOfPackExpr; - - case Stmt::DeclRefExprClass: - return CXCursor_DeclRefExpr; - - case Stmt::DependentScopeDeclRefExprClass: - case Stmt::SubstNonTypeTemplateParmExprClass: - case Stmt::SubstNonTypeTemplateParmPackExprClass: - case Stmt::FunctionParmPackExprClass: - case Stmt::UnresolvedLookupExprClass: - case Stmt::TypoExprClass: // A typo could actually be a DeclRef or a MemberRef - return CXCursor_DeclRefExpr; - - case Stmt::CXXDependentScopeMemberExprClass: - case Stmt::CXXPseudoDestructorExprClass: - case Stmt::MemberExprClass: - case Stmt::MSPropertyRefExprClass: - case Stmt::ObjCIsaExprClass: - case Stmt::ObjCIvarRefExprClass: - case Stmt::ObjCPropertyRefExprClass: - case Stmt::UnresolvedMemberExprClass: - return CXCursor_MemberRefExpr; - - case Stmt::CallExprClass: - case Stmt::CXXOperatorCallExprClass: - case Stmt::CXXMemberCallExprClass: - case Stmt::CUDAKernelCallExprClass: - case Stmt::CXXConstructExprClass: - case Stmt::CXXInheritedCtorInitExprClass: - case Stmt::CXXTemporaryObjectExprClass: - case Stmt::CXXUnresolvedConstructExprClass: - case Stmt::UserDefinedLiteralClass: - return CXCursor_CallExpr; - - case Stmt::LambdaExprClass: - return CXCursor_LambdaExpr; - - case Stmt::ObjCMessageExprClass: - return CXCursor_ObjCMessageExpr; - - case Stmt::MSDependentExistsStmtClass: - return CXCursor_UnexposedStmt; - case Stmt::OMPParallelDirectiveClass: - return CXCursor_OMPParallelDirective; - case Stmt::OMPSimdDirectiveClass: - return CXCursor_OMPSimdDirective; - case Stmt::OMPForDirectiveClass: - return CXCursor_OMPForDirective; - case Stmt::OMPForSimdDirectiveClass: - return CXCursor_OMPForSimdDirective; - case Stmt::OMPSectionsDirectiveClass: - return CXCursor_OMPSectionsDirective; - case Stmt::OMPSectionDirectiveClass: - return CXCursor_OMPSectionDirective; - case Stmt::OMPSingleDirectiveClass: - return CXCursor_OMPSingleDirective; - case Stmt::OMPMasterDirectiveClass: - return CXCursor_OMPMasterDirective; - case Stmt::OMPCriticalDirectiveClass: - return CXCursor_OMPCriticalDirective; - case Stmt::OMPParallelForDirectiveClass: - return CXCursor_OMPParallelForDirective; - case Stmt::OMPParallelForSimdDirectiveClass: - return CXCursor_OMPParallelForSimdDirective; - case Stmt::OMPParallelSectionsDirectiveClass: - return CXCursor_OMPParallelSectionsDirective; - case Stmt::OMPTaskDirectiveClass: - return CXCursor_OMPTaskDirective; - case Stmt::OMPTaskyieldDirectiveClass: - return CXCursor_OMPTaskyieldDirective; - case Stmt::OMPBarrierDirectiveClass: - return CXCursor_OMPBarrierDirective; - case Stmt::OMPTaskwaitDirectiveClass: - return CXCursor_OMPTaskwaitDirective; - case Stmt::OMPTaskgroupDirectiveClass: - return CXCursor_OMPTaskgroupDirective; - case Stmt::OMPFlushDirectiveClass: - return CXCursor_OMPFlushDirective; - case Stmt::OMPOrderedDirectiveClass: - return CXCursor_OMPOrderedDirective; - case Stmt::OMPAtomicDirectiveClass: - return CXCursor_OMPAtomicDirective; - case Stmt::OMPTargetDirectiveClass: - return CXCursor_OMPTargetDirective; - case Stmt::OMPTargetDataDirectiveClass: - return CXCursor_OMPTargetDataDirective; - case Stmt::OMPTargetEnterDataDirectiveClass: - return CXCursor_OMPTargetEnterDataDirective; - case Stmt::OMPTargetExitDataDirectiveClass: - return CXCursor_OMPTargetExitDataDirective; - case Stmt::OMPTargetParallelDirectiveClass: - return CXCursor_OMPTargetParallelDirective; - case Stmt::OMPTargetParallelForDirectiveClass: - return CXCursor_OMPTargetParallelForDirective; - case Stmt::OMPTargetUpdateDirectiveClass: - return CXCursor_OMPTargetUpdateDirective; - case Stmt::OMPTeamsDirectiveClass: - return CXCursor_OMPTeamsDirective; - case Stmt::OMPCancellationPointDirectiveClass: - return CXCursor_OMPCancellationPointDirective; - case Stmt::OMPCancelDirectiveClass: - return CXCursor_OMPCancelDirective; - case Stmt::OMPTaskLoopDirectiveClass: - return CXCursor_OMPTaskLoopDirective; - case Stmt::OMPTaskLoopSimdDirectiveClass: - return CXCursor_OMPTaskLoopSimdDirective; - case Stmt::OMPDistributeDirectiveClass: - return CXCursor_OMPDistributeDirective; - case Stmt::OMPDistributeParallelForDirectiveClass: - return CXCursor_OMPDistributeParallelForDirective; - case Stmt::OMPDistributeParallelForSimdDirectiveClass: - return CXCursor_OMPDistributeParallelForSimdDirective; - case Stmt::OMPDistributeSimdDirectiveClass: - return CXCursor_OMPDistributeSimdDirective; - case Stmt::OMPTargetParallelForSimdDirectiveClass: - return CXCursor_OMPTargetParallelForSimdDirective; - case Stmt::OMPTargetSimdDirectiveClass: - return CXCursor_OMPTargetSimdDirective; - case Stmt::OMPTeamsDistributeDirectiveClass: - return CXCursor_OMPTeamsDistributeDirective; - case Stmt::OMPTeamsDistributeSimdDirectiveClass: - return CXCursor_OMPTeamsDistributeSimdDirective; - case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: - return CXCursor_OMPTeamsDistributeParallelForSimdDirective; - case Stmt::OMPTeamsDistributeParallelForDirectiveClass: - return CXCursor_OMPTeamsDistributeParallelForDirective; - case Stmt::OMPTargetTeamsDirectiveClass: - return CXCursor_OMPTargetTeamsDirective; - case Stmt::OMPTargetTeamsDistributeDirectiveClass: - return CXCursor_OMPTargetTeamsDistributeDirective; - case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: - return CXCursor_OMPTargetTeamsDistributeParallelForDirective; - case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: - return CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective; - case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: - return CXCursor_OMPTargetTeamsDistributeSimdDirective; - case Stmt::BuiltinBitCastExprClass: - return CXCursor_BuiltinBitCastExpr; - - default: - return CXCursor_UnexposedExpr; - } -} - -SourceLocation *Expr_getLocation(const Expr *E) { - if (!E) - return nullptr; - if (const ImplicitCastExpr *CE = dyn_cast(&*E)) - return Expr_getLocation(CE->getSubExpr()); - - if (const ObjCMessageExpr *Msg = dyn_cast(&*E)) - return new SourceLocation(/*FIXME:*/Msg->getLeftLoc()); - if (const DeclRefExpr *DRE = dyn_cast(&*E)) - return new SourceLocation(DRE->getLocation()); - if (const MemberExpr *Member = dyn_cast(&*E)) - return new SourceLocation(Member->getMemberLoc()); - if (const ObjCIvarRefExpr *Ivar = dyn_cast(&*E)) - return new SourceLocation(Ivar->getLocation()); - if (const SizeOfPackExpr *SizeOfPack = dyn_cast(&*E)) - return new SourceLocation(SizeOfPack->getPackLoc()); - if (const ObjCPropertyRefExpr *PropRef = dyn_cast(&*E)) - return new SourceLocation(PropRef->getLocation()); - - return new SourceLocation(E->getBeginLoc()); -} - -QualType Expr_getType(const Expr *E) { return make_type_compatible(E->getType()); } - -BindgenSourceRange Expr_getSourceRange(const Expr *E) { - return BindgenSourceRange(E->getSourceRange()); -} - -const Decl *Type_getDeclaration(QualType T) { - const Type *TP = T.getTypePtrOrNull(); - - if (!TP) - return nullptr; - - const Decl *D = nullptr; - -try_again: - switch (TP->getTypeClass()) { - case Type::Typedef: - D = cast(TP)->getDecl(); - break; - case Type::ObjCObject: - D = cast(TP)->getInterface(); - break; - case Type::ObjCInterface: - D = cast(TP)->getDecl(); - break; - case Type::Record: - case Type::Enum: - D = cast(TP)->getDecl(); - break; - case Type::TemplateSpecialization: - if (const RecordType *Record = TP->getAs()) - D = Record->getDecl(); - else - D = cast(TP)->getTemplateName() - .getAsTemplateDecl(); - break; - - case Type::Auto: - case Type::DeducedTemplateSpecialization: - TP = cast(TP)->getDeducedType().getTypePtrOrNull(); - if (TP) - goto try_again; - break; - - case Type::InjectedClassName: - D = cast(TP)->getDecl(); - break; - - // FIXME: Template type parameters! - - case Type::Elaborated: - TP = cast(TP)->getNamedType().getTypePtrOrNull(); - goto try_again; - - default: - break; - } - - if (!D) - return nullptr; - - return D; -} - -class BindgenVisitor : public RecursiveASTVisitor { - ASTUnit &AST; - Visitor VisitFn; - CXClientData Data; - Node Parent; - -public: - explicit BindgenVisitor(ASTUnit &AST, Visitor V, CXClientData data) : AST(AST), VisitFn(V), Data(data) {} - - bool shouldVisitImplicitCode() { - return false; - } - - bool TraverseDeclTyped(Decl *D, CXCursorKind kind) { - if (!D || (D->isImplicit() && !isa(D))) - return true; - - bool skip = !Parent; - - // libclang doesn't visit the CXXRecordDecl inside ClassTemplateDecl nodes - if (Parent.kind == CXCursor_ClassTemplate - && isa(D)) - skip = true; - - // libclang exposes forward class and protocol declarations as references - if (kind == CXCursor_ObjCInterfaceDecl) { - auto *ID = cast(D); - if (!ID->isThisDeclarationADefinition()) - kind = CXCursor_ObjCClassRef; - } else if (kind == CXCursor_ObjCProtocolDecl) { - auto *PD = cast(D); - if (!PD->isThisDeclarationADefinition()) - kind = CXCursor_ObjCProtocolRef; - } - - // D->dump(); - Node node(D, kind); - if (!skip) { - switch (VisitFn(node, Parent, &AST, Data)) { - case CXChildVisit_Break: - return false; - case CXChildVisit_Continue: - return true; - case CXChildVisit_Recurse: - break; - } - } - - // Do not recurse through references - if (kind >= CXCursor_FirstRef && kind <= CXCursor_LastRef - && kind != CXCursor_CXXBaseSpecifier) - return true; - - auto OldParent = Parent; - Parent = node; - bool res = RecursiveASTVisitor::TraverseDecl(D); - Parent = OldParent; - return res; - } - - bool TraverseDecl(Decl *D) { - return TraverseDeclTyped(D, Decl_getCXCursorKind(D)); - } - - bool TraverseExprTyped(Expr *E, CXCursorKind kind) { - if (!E) - return true; - - Node node(E, kind); - if (Parent) { - // E->dump(); - switch (VisitFn(node, Parent, &AST, Data)) { - case CXChildVisit_Break: - return false; - case CXChildVisit_Continue: - return true; - case CXChildVisit_Recurse: - break; - } - } - - auto OldParent = Parent; - Parent = node; - bool res = RecursiveASTVisitor::TraverseStmt(E); - Parent = OldParent; - return res; - } - - bool TraverseStmt(Stmt *S) { - if (!S) - return true; - if (auto *E = dyn_cast(S)) - return TraverseExprTyped(E, Expr_getCXCursorKind(E)); - return RecursiveASTVisitor::TraverseStmt(S); - } - - bool VisitSizeOfPackExpr(SizeOfPackExpr *E) { - NamedDecl *Pack = E->getPack(); - if (isa(Pack)) { - Node node(Pack, CXCursor_TypeRef); - Node parent(E, Expr_getCXCursorKind(E)); - return VisitFn(node, parent, &AST, Data) != CXChildVisit_Break; - } - if (isa(Pack)) { - Node node(Pack, CXCursor_TemplateRef); - Node parent(E, Expr_getCXCursorKind(E)); - return VisitFn(node, parent, &AST, Data) != CXChildVisit_Break; - } - return true; - } - - bool VisitTypeLoc(TypeLoc TL) { - // if (TL) TL.getTypePtr()->dump(); - return true; - } - - bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { - if (!TL) - return true; - return TraverseStmt(TL.getUnderlyingExpr()); - } - - bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { - if (!TL) - return true; - return TraverseStmt(TL.getUnderlyingExpr()); - } - - bool VisitTypedefTypeLoc(TypedefTypeLoc TL) { - if (!TL) - return true; - return TraverseDeclTyped(TL.getTypedefNameDecl(), CXCursor_TypeRef); - } - - bool VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { - if (!TL) - return true; - return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); - } - - bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { - if (!TL) - return true; - return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); - } - - bool VisitTagTypeLoc(TagTypeLoc TL) { - if (!TL) - return true; - if (TL.isDefinition()) - return TraverseDecl(TL.getDecl()); - else - return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); - } - - bool VisitRecordTypeLoc(RecordTypeLoc TL) { - if (!TL) - return true; - return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); - } - - bool VisitEnumTypeLoc(EnumTypeLoc TL) { - if (!TL) - return true; - return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); - } - - bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { - if (!TL) - return true; - return TraverseDeclTyped(TL.getDecl(), CXCursor_TypeRef); - } - - bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { - if (!TL) - return true; - - ASTContext &Context = AST.getASTContext(); - QualType Ty; - switch (TL.getTypePtr()->getKind()) { - case BuiltinType::ObjCId: - Ty = Context.getObjCIdType(); - break; - case BuiltinType::ObjCClass: - Ty = Context.getObjCClassType(); - break; - case BuiltinType::ObjCSel: - Ty = Context.getObjCSelType(); - break; - default: - break; - } - - if (!Ty.isNull()) { - if (auto *TD = Ty->getAs()) { - Node node(TD->getDecl(), CXCursor_TypeRef); - return VisitFn(node, Parent, &AST, Data) != CXChildVisit_Break; - } - } - - return true; - } - - bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { - if (!TL) - return true; - - return TraverseDeclTyped(TL.getIFaceDecl(), CXCursor_ObjCClassRef); - } - - bool VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) { - if (!TL) - return true; - Node node(TL.getDecl(), CXCursor_TypeRef); - if (VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break) - return false; - for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { - Node node(TL.getProtocol(I), CXCursor_ObjCProtocolRef); - if (VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break) - return false; - } - return true; - } - - bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { - if (!TL) - return true; - - for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { - Node node(TL.getProtocol(I), CXCursor_ObjCProtocolRef); - if (VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break) - return false; - } - - return true; - } - - bool TraverseTemplateName(TemplateName Name) { - Node node; - switch (Name.getKind()) { - case TemplateName::Template: - node = Node(Name.getAsTemplateDecl(), CXCursor_TemplateRef); - break; - - case TemplateName::OverloadedTemplate: - // libclang visits this, but we don't need it for bindgen - return true; - - case TemplateName::AssumedTemplate: - return true; - - case TemplateName::DependentTemplate: - return true; - - case TemplateName::QualifiedTemplate: - node = Node(Name.getAsQualifiedTemplateName()->getDecl(), CXCursor_TemplateRef); - break; - - case TemplateName::SubstTemplateTemplateParm: - node = Node(Name.getAsSubstTemplateTemplateParm()->getParameter(), CXCursor_TemplateRef); - break; - - case TemplateName::SubstTemplateTemplateParmPack: - node = Node(Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), CXCursor_TemplateRef); - break; - } - - switch (VisitFn(node, Parent, &AST, Data)) { - case CXChildVisit_Break: - return false; - case CXChildVisit_Continue: - return true; - case CXChildVisit_Recurse: - break; - } - - auto OldParent = Parent; - Parent = node; - bool res = RecursiveASTVisitor::TraverseTemplateName(Name); - Parent = OldParent; - return res; - } - - bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) { - if (Parent) { - switch (VisitFn(Node(&Base), Parent, &AST, Data)) { - case CXChildVisit_Break: - return false; - case CXChildVisit_Continue: - return true; - case CXChildVisit_Recurse: - break; - } - } - - auto OldParent = Parent; - Parent = Node(&Base); - bool res = RecursiveASTVisitor::TraverseCXXBaseSpecifier(Base); - Parent = OldParent; - return res; - } - - bool VisitAttr(Attr *A) { - if (Parent) - VisitFn(Node(A), Parent, &AST, Data); - return true; - } - - bool VisitTranslationUnitDecl(TranslationUnitDecl *TU) { - if (!AST.getPreprocessor().getPreprocessingRecord()) - return true; - - PreprocessingRecord &PPRec = - *AST.getPreprocessor().getPreprocessingRecord(); - SourceManager &SM = AST.getSourceManager(); - - bool OnlyLocalDecls = !AST.isMainFileAST() && AST.getOnlyLocalDecls(); - - if (OnlyLocalDecls) - return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(), - PPRec); - - return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec); - } - - bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { - // We handle forward declarations in TraverseDecl - if (!D || !D->isThisDeclarationADefinition()) - return true; - - if (D->getSuperClass() - && VisitFn(Node(D->getSuperClass(), CXCursor_ObjCSuperClassRef), Parent, &AST, Data) == CXChildVisit_Break) - return false; - - for (auto I : D->protocols()) - if (VisitFn(Node(&*I, CXCursor_ObjCProtocolRef), Parent, &AST, Data) == CXChildVisit_Break) - return false; - - return true; - } - - bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { - Node interfaceNode(ND->getClassInterface(), CXCursor_ObjCClassRef); - if (VisitFn(interfaceNode, Parent, &AST, Data) == CXChildVisit_Break) - return false; - - // TypeParamList is visited in RecursiveASTvisitor - - for (auto I : ND->protocols()) - if (VisitFn(Node(&*I, CXCursor_ObjCProtocolRef), Parent, &AST, Data) == CXChildVisit_Break) - return false; - - // We may need to do the weird hacky thing that the libclang visitor does in - // VisitObjCContainerDecl, but I hope not... - return true; - } - - bool VisitObjCProtocolDecl(ObjCProtocolDecl *PD) { - for (auto I : PD->protocols()) - if (VisitFn(Node(&*I, CXCursor_ObjCProtocolRef), Parent, &AST, Data) == CXChildVisit_Break) - return false; - - // We may need to do the weird hacky thing that the libclang visitor does in - // VisitObjCContainerDecl, but I hope not... - return true; - } - - bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD) { - if (!PD) - return true; - - // FIXME: This implements a workaround with @property declarations also - // being - // installed in the DeclContext for the @interface. Eventually this code - // should be removed. - ObjCCategoryDecl *CDecl = dyn_cast(PD->getDeclContext()); - if (!CDecl || !CDecl->IsClassExtension()) - return true; - - ObjCInterfaceDecl *ID = CDecl->getClassInterface(); - if (!ID) - return true; - - IdentifierInfo *PropertyId = PD->getIdentifier(); - ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl( - cast(ID), PropertyId, PD->getQueryKind()); - - if (!prevDecl) - return true; - - // Visit synthesized methods since they will be skipped when visiting - // the @interface. - if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl()) - if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl) - if (!TraverseDecl(MD)) - return false; - - if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl()) - if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl) - if (!TraverseDecl(MD)) - return false; - - return true; - } - - bool VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) { - if (!D) - return true; - return TraverseDecl(D) != CXChildVisit_Break; - } - -private: - template - bool visitPreprocessedEntities(InputIterator First, InputIterator Last, - PreprocessingRecord &PPRec) { - for (; First != Last; ++First) { - PreprocessedEntity *PPE = *First; - if (!PPE) - continue; - - Node node; - if (isa(PPE)) { - node = Node(PPE, CXCursor_MacroExpansion); - } else if (isa(PPE)) { - node = Node(PPE, CXCursor_MacroDefinition); - } else if (isa(PPE)) { - node = Node(PPE, CXCursor_InclusionDirective); - } - if (node) { - if (VisitFn(node, Parent, &AST, Data) == CXChildVisit_Break) - return false; - } - } - - return true; - } -}; - -void Decl_visitChildren(const Decl *Parent, CXCursorKind kind, Visitor V, - ASTUnit *Unit, CXClientData data) { - BindgenVisitor visitor(*Unit, V, data); - visitor.TraverseDeclTyped(const_cast(&*Parent), kind); -} -void Expr_visitChildren(const Expr *Parent, CXCursorKind kind, Visitor V, - ASTUnit *Unit, CXClientData data) { - BindgenVisitor visitor(*Unit, V, data); - visitor.TraverseExprTyped(const_cast(&*Parent), kind); -} -void CXXBaseSpecifier_visitChildren(const CXXBaseSpecifier *Parent, - CXCursorKind kind, Visitor V, ASTUnit *Unit, - CXClientData data) { - BindgenVisitor visitor(*Unit, V, data); - visitor.TraverseCXXBaseSpecifier(*Parent); -} - -void tokenize(ASTUnit *TU, BindgenSourceRange Range, CXToken **Tokens, - unsigned *NumTokens) { - if (!Tokens || !NumTokens || !Range) - return; - - // Translate the Range end location to after the last token, instead of - // the beginning of the last token. - SourceManager &SourceMgr = TU->getSourceManager(); - SourceLocation EndLoc = *Range.E; - bool IsTokenRange = true; - if (EndLoc.isValid() && EndLoc.isMacroID() && !SourceMgr.isMacroArgExpansion(EndLoc)) { - CharSourceRange Expansion = SourceMgr.getExpansionRange(EndLoc); - EndLoc = Expansion.getEnd(); - IsTokenRange = Expansion.isTokenRange(); - } - if (IsTokenRange && EndLoc.isValid()) { - unsigned Length = Lexer::MeasureTokenLength(SourceMgr.getSpellingLoc(EndLoc), - SourceMgr, TU->getLangOpts()); - EndLoc = EndLoc.getLocWithOffset(Length); - } - - SmallVector CXTokens; - std::pair BeginLocInfo = - SourceMgr.getDecomposedSpellingLoc(*Range.B); - std::pair EndLocInfo = - SourceMgr.getDecomposedSpellingLoc(EndLoc); - - // Cannot tokenize across files. - if (BeginLocInfo.first != EndLocInfo.first) - return; - - // Create a lexer - bool Invalid = false; - StringRef Buffer - = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid); - if (Invalid) - return; - - Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), - TU->getASTContext().getLangOpts(), - Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end()); - Lex.SetCommentRetentionState(true); - - // Lex tokens until we hit the end of the range. - const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second; - Token Tok; - bool previousWasAt = false; - do { - // Lex the next token - Lex.LexFromRawLexer(Tok); - if (Tok.is(tok::eof)) - break; - - // Initialize the CXToken. - CXToken CXTok; - - // - Common fields - CXTok.int_data[1] = Tok.getLocation().getRawEncoding(); - CXTok.int_data[2] = Tok.getLength(); - CXTok.int_data[3] = 0; - - // - Kind-specific fields - if (Tok.isLiteral()) { - CXTok.int_data[0] = CXToken_Literal; - CXTok.ptr_data = const_cast(Tok.getLiteralData()); - } else if (Tok.is(tok::raw_identifier)) { - // Lookup the identifier to determine whether we have a keyword. - IdentifierInfo *II - = TU->getPreprocessor().LookUpIdentifierInfo(Tok); - - if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) { - CXTok.int_data[0] = CXToken_Keyword; - } - else { - CXTok.int_data[0] = Tok.is(tok::identifier) - ? CXToken_Identifier - : CXToken_Keyword; - } - CXTok.ptr_data = II; - } else if (Tok.is(tok::comment)) { - CXTok.int_data[0] = CXToken_Comment; - CXTok.ptr_data = nullptr; - } else { - CXTok.int_data[0] = CXToken_Punctuation; - CXTok.ptr_data = nullptr; - } - CXTokens.push_back(CXTok); - previousWasAt = Tok.is(tok::at); - } while (Lex.getBufferLocation() < EffectiveBufferEnd); - - *Tokens = new CXToken[CXTokens.size()]; - memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); - *NumTokens = CXTokens.size(); -} - -void disposeTokens(const ASTUnit *TU, CXToken *Tokens, unsigned NumTokens) { - delete[] Tokens; -} - -CXTokenKind getTokenKind(CXToken token) { - return static_cast(token.int_data[0]); -} - -BindgenStringRef getTokenSpelling(ASTUnit *CXXUnit, CXToken CXTok) { - if (!CXXUnit) - return stringref(); - - switch (getTokenKind(CXTok)) { - case CXToken_Identifier: - case CXToken_Keyword: - // We know we have an IdentifierInfo*, so use that. - return stringref(static_cast(CXTok.ptr_data) - ->getNameStart()); - - case CXToken_Literal: { - // We have stashed the starting pointer in the ptr_data field. Use it. - const char *Text = static_cast(CXTok.ptr_data); - return stringref(StringRef(Text, CXTok.int_data[2])); - } - - case CXToken_Punctuation: - case CXToken_Comment: - break; - } - - // We have to find the starting buffer pointer the hard way, by - // deconstructing the source location. - SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]); - std::pair LocInfo - = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc); - bool Invalid = false; - StringRef Buffer - = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); - if (Invalid) - return stringref(); - - return stringref(Buffer.substr(LocInfo.second, CXTok.int_data[2])); -} - -static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { -#define BTCASE(K) case BuiltinType::K: return CXType_##K - switch (BT->getKind()) { - BTCASE(Void); - BTCASE(Bool); - BTCASE(Char_U); - BTCASE(UChar); - BTCASE(Char16); - BTCASE(Char32); - BTCASE(UShort); - BTCASE(UInt); - BTCASE(ULong); - BTCASE(ULongLong); - BTCASE(UInt128); - BTCASE(Char_S); - BTCASE(SChar); - case BuiltinType::WChar_S: return CXType_WChar; - case BuiltinType::WChar_U: return CXType_WChar; - BTCASE(Short); - BTCASE(Int); - BTCASE(Long); - BTCASE(LongLong); - BTCASE(Int128); - BTCASE(Half); - BTCASE(Float); - BTCASE(Double); - BTCASE(LongDouble); - BTCASE(ShortAccum); - BTCASE(Accum); - BTCASE(LongAccum); - BTCASE(UShortAccum); - BTCASE(UAccum); - BTCASE(ULongAccum); - BTCASE(Float16); - BTCASE(Float128); - BTCASE(NullPtr); - BTCASE(Overload); - BTCASE(Dependent); - BTCASE(ObjCId); - BTCASE(ObjCClass); - BTCASE(ObjCSel); -#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) BTCASE(Id); -#include "clang/Basic/OpenCLImageTypes.def" -#undef IMAGE_TYPE -#if CLANG_VERSION_MAJOR > 8 -#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) BTCASE(Id); -#include "clang/Basic/OpenCLExtensionTypes.def" -#endif // CLANG_VERSION_MAJOR > 8 - BTCASE(OCLSampler); - BTCASE(OCLEvent); - BTCASE(OCLQueue); - BTCASE(OCLReserveID); - default: - return CXType_Unexposed; - } -#undef BTCASE -} - -CXTypeKind Type_kind(QualType T, ASTContext *Context) { - const Type *TP = T.getTypePtrOrNull(); - if (!TP) - return CXType_Invalid; - - // libclang checks for these builtin types specially and matches on things - // that appear to be correct - if (Context->getLangOpts().ObjC) { - QualType UT = T.getUnqualifiedType(); - if (Context->isObjCIdType(UT)) - return CXType_ObjCId; - if (Context->isObjCClassType(UT)) - return CXType_ObjCClass; - if (Context->isObjCSelType(UT)) - return CXType_ObjCSel; - } - -#define TKCASE(K) case Type::K: return CXType_##K - switch (TP->getTypeClass()) { - case Type::Builtin: - return GetBuiltinTypeKind(cast(TP)); - TKCASE(Complex); - TKCASE(Pointer); - TKCASE(BlockPointer); - TKCASE(LValueReference); - TKCASE(RValueReference); - TKCASE(Record); - TKCASE(Enum); - TKCASE(Typedef); - TKCASE(ObjCInterface); - TKCASE(ObjCObject); - TKCASE(ObjCObjectPointer); - TKCASE(ObjCTypeParam); - TKCASE(FunctionNoProto); - TKCASE(FunctionProto); - TKCASE(ConstantArray); - TKCASE(IncompleteArray); - TKCASE(VariableArray); - TKCASE(DependentSizedArray); - TKCASE(Vector); - TKCASE(ExtVector); - TKCASE(MemberPointer); - TKCASE(Auto); - TKCASE(Elaborated); - TKCASE(Pipe); - TKCASE(Attributed); - default: - return CXType_Unexposed; - } -#undef TKCASE -} - -BindgenStringRef Type_getTypeSpelling(QualType T, ASTContext *Context) { - SmallString<64> Str; - llvm::raw_svector_ostream OS(Str); - PrintingPolicy PP(Context->getLangOpts()); - - T.print(OS, PP); - return stringref(OS.str()); -} - -bool Type_isConstQualifiedType(QualType T) { - return T.isLocalConstQualified(); -} - -long long Type_getSizeOf(QualType QT, ASTContext *Context) { - if (QT.isNull()) - return CXTypeLayoutError_Invalid; - // [expr.sizeof] p2: if reference type, return size of referenced type - if (QT->isReferenceType()) - QT = QT.getNonReferenceType(); - // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete - // enumeration - // Note: We get the cxtype, not the cxcursor, so we can't call - // FieldDecl->isBitField() - // [expr.sizeof] p3: pointer ok, function not ok. - // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error - if (QT->isIncompleteType()) - return CXTypeLayoutError_Incomplete; - if (QT->isDependentType()) - return CXTypeLayoutError_Dependent; - if (!QT->isConstantSizeType()) - return CXTypeLayoutError_NotConstantSize; - if (const auto *Deduced = dyn_cast(QT)) - if (Deduced->getDeducedType().isNull()) - return CXTypeLayoutError_Undeduced; - // [gcc extension] lib/AST/ExprConstant.cpp:1372 - // HandleSizeof : {voidtype,functype} == 1 - // not handled by ASTContext.cpp:1313 getTypeInfoImpl - if (QT->isVoidType() || QT->isFunctionType()) - return 1; - return Context->getTypeSizeInChars(QT).getQuantity(); -} - -long long Type_getAlignOf(QualType QT, ASTContext *Context) { - if (QT.isNull()) - return CXTypeLayoutError_Invalid; - // [expr.alignof] p1: return size_t value for complete object type, reference - // or array. - // [expr.alignof] p3: if reference type, return size of referenced type - if (QT->isReferenceType()) - QT = QT.getNonReferenceType(); - if (!(QT->isIncompleteArrayType() || !QT->isIncompleteType())) - return CXTypeLayoutError_Incomplete; - if (QT->isDependentType()) - return CXTypeLayoutError_Dependent; - if (const auto *Deduced = dyn_cast(QT)) - if (Deduced->getDeducedType().isNull()) - return CXTypeLayoutError_Undeduced; - // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl - // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1 - // if (QT->isVoidType()) return 1; - return Context->getTypeAlignInChars(QT).getQuantity(); -} - -static Optional> -GetTemplateArguments(QualType Type) { - assert(!Type.isNull()); - if (const auto *Specialization = Type->getAs()) - return Specialization->template_arguments(); - - if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) { - const auto *TemplateDecl = - dyn_cast(RecordDecl); - if (TemplateDecl) - return TemplateDecl->getTemplateArgs().asArray(); - } - - return None; -} - -static unsigned GetTemplateArgumentArraySize(ArrayRef TA) { - unsigned size = TA.size(); - for (const auto &Arg : TA) - if (Arg.getKind() == TemplateArgument::Pack) - size += Arg.pack_size() - 1; - return size; -} - -int Type_getNumTemplateArguments(QualType T) { - if (T.isNull()) - return -1; - auto TA = GetTemplateArguments(T); - if (!TA) - return -1; - - return GetTemplateArgumentArraySize(TA.getValue()); -} - -QualType Type_getArgType(QualType T, unsigned i) { - if (T.isNull()) - return QualType(); - - if (const FunctionProtoType *FD = T->getAs()) { - unsigned numParams = FD->getNumParams(); - if (i >= numParams) - return QualType(); - // FD->getParamType(i)->dump(); - return make_type_compatible(FD->getParamType(i)); - } - - return QualType(); -} - -int Type_getNumArgTypes(QualType T) { - if (T.isNull()) - return -1; - - if (const FunctionProtoType *FD = T->getAs()) { - return FD->getNumParams(); - } - - if (T->getAs()) { - return 0; - } - - return -1; -} - -QualType Type_getPointeeType(QualType T) { - const Type *TP = T.getTypePtrOrNull(); - - if (!TP) - return QualType(); - -try_again: - switch (TP->getTypeClass()) { - case Type::Pointer: - T = cast(TP)->getPointeeType(); - break; - case Type::BlockPointer: - T = cast(TP)->getPointeeType(); - break; - case Type::LValueReference: - case Type::RValueReference: - T = cast(TP)->getPointeeType(); - break; - case Type::ObjCObjectPointer: - T = cast(TP)->getPointeeType(); - break; - case Type::MemberPointer: - T = cast(TP)->getPointeeType(); - break; - case Type::Auto: - case Type::DeducedTemplateSpecialization: - TP = cast(TP)->getDeducedType().getTypePtrOrNull(); - if (TP) - goto try_again; - break; - default: - T = QualType(); - break; - } - return make_type_compatible(T); -} - -QualType Type_getElementType(QualType T) { - QualType ET = QualType(); - const Type *TP = T.getTypePtrOrNull(); - - if (TP) { - switch (TP->getTypeClass()) { - case Type::ConstantArray: - ET = cast (TP)->getElementType(); - break; - case Type::IncompleteArray: - ET = cast (TP)->getElementType(); - break; - case Type::VariableArray: - ET = cast (TP)->getElementType(); - break; - case Type::DependentSizedArray: - ET = cast (TP)->getElementType(); - break; - case Type::Vector: - ET = cast (TP)->getElementType(); - break; - case Type::ExtVector: - ET = cast(TP)->getElementType(); - break; - case Type::Complex: - ET = cast (TP)->getElementType(); - break; - default: - break; - } - } - return make_type_compatible(ET); -} - -int Type_getNumElements(QualType T) { - long long result = -1; - const Type *TP = T.getTypePtrOrNull(); - - if (TP) { - switch (TP->getTypeClass()) { - case Type::ConstantArray: - result = cast (TP)->getSize().getSExtValue(); - break; - case Type::Vector: - result = cast (TP)->getNumElements(); - break; - case Type::ExtVector: - result = cast(TP)->getNumElements(); - break; - default: - break; - } - } - return result; -} - -QualType Type_getCanonicalType(QualType T, ASTContext *Context) { - if (T.isNull()) - return QualType(); - - return make_type_compatible(Context->getCanonicalType(T)); -} - -bool Type_isFunctionTypeVariadic(QualType T) { - if (T.isNull()) - return false; - - if (const FunctionProtoType *FD = T->getAs()) - return (unsigned)FD->isVariadic(); - - if (T->getAs()) - return true; - - return false; -} - -QualType Type_getResultType(QualType T) { - if (T.isNull()) - return QualType(); - - if (const FunctionType *FD = T->getAs()) - return make_type_compatible(FD->getReturnType()); - - return QualType(); -} - -CXCallingConv Type_getFunctionTypeCallingConv(QualType T) { - if (T.isNull()) - return CXCallingConv_Invalid; - - if (const FunctionType *FD = T->getAs()) { -#define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X - switch (FD->getCallConv()) { - TCALLINGCONV(C); - TCALLINGCONV(X86StdCall); - TCALLINGCONV(X86FastCall); - TCALLINGCONV(X86ThisCall); - TCALLINGCONV(X86Pascal); - TCALLINGCONV(X86RegCall); - TCALLINGCONV(X86VectorCall); - TCALLINGCONV(AArch64VectorCall); - TCALLINGCONV(Win64); - TCALLINGCONV(X86_64SysV); - TCALLINGCONV(AAPCS); - TCALLINGCONV(AAPCS_VFP); - TCALLINGCONV(IntelOclBicc); - TCALLINGCONV(Swift); - TCALLINGCONV(PreserveMost); - TCALLINGCONV(PreserveAll); - case CC_SpirFunction: return CXCallingConv_Unexposed; - case CC_OpenCLKernel: return CXCallingConv_Unexposed; - break; - } -#undef TCALLINGCONV - } - - return CXCallingConv_Invalid; -} - -QualType Type_getNamedType(QualType T) { - const Type *TP = T.getTypePtrOrNull(); - - if (TP && TP->getTypeClass() == Type::Elaborated) - return make_type_compatible(cast(TP)->getNamedType()); - - return QualType(); -} - -static Optional TemplateArgumentToQualType(const TemplateArgument &A) { - if (A.getKind() == TemplateArgument::Type) - return A.getAsType(); - return None; -} - -static Optional -FindTemplateArgumentTypeAt(ArrayRef TA, unsigned index) { - unsigned current = 0; - for (const auto &A : TA) { - if (A.getKind() == TemplateArgument::Pack) { - if (index < current + A.pack_size()) - return TemplateArgumentToQualType(A.getPackAsArray()[index - current]); - current += A.pack_size(); - continue; - } - if (current == index) - return TemplateArgumentToQualType(A); - current++; - } - return None; -} - -QualType Type_getTemplateArgumentAsType(QualType T, unsigned index) { - if (T.isNull()) - return QualType(); - - auto TA = GetTemplateArguments(T); - if (!TA) - return QualType(); - - Optional QT = FindTemplateArgumentTypeAt(TA.getValue(), index); - return make_type_compatible(QT.getValueOr(QualType())); -} - -static void createNullLocation(FileEntry **file, int *line, - int *column, int *offset = nullptr) { - if (file) - *file = nullptr; - if (line) - *line = 0; - if (column) - *column = 0; - if (offset) - *offset = 0; -} - -void getSpellingLocation(ASTUnit *AST, const SourceLocation *location, FileEntry **file, int *line, int *column, int *offset) { - if (!location) - return createNullLocation(file, line, column, offset); - - const SourceManager &SM = AST->getSourceManager(); - // FIXME: This should call SourceManager::getSpellingLoc(). - SourceLocation SpellLoc = SM.getFileLoc(*location); - std::pair LocInfo = SM.getDecomposedLoc(SpellLoc); - FileID FID = LocInfo.first; - unsigned FileOffset = LocInfo.second; - - if (FID.isInvalid()) - return createNullLocation(file, line, column, offset); - - if (file) - *file = const_cast(SM.getFileEntryForID(FID)); - if (line) - *line = SM.getLineNumber(FID, FileOffset); - if (column) - *column = SM.getColumnNumber(FID, FileOffset); - if (offset) - *offset = FileOffset; -} - -CXCommentKind Comment_getKind(const comments::Comment *C) { - using namespace comments; - if (!C) - return CXComment_Null; - - switch (C->getCommentKind()) { - case Comment::NoCommentKind: - return CXComment_Null; - - case Comment::TextCommentKind: - return CXComment_Text; - - case Comment::InlineCommandCommentKind: - return CXComment_InlineCommand; - - case Comment::HTMLStartTagCommentKind: - return CXComment_HTMLStartTag; - - case Comment::HTMLEndTagCommentKind: - return CXComment_HTMLEndTag; - - case Comment::ParagraphCommentKind: - return CXComment_Paragraph; - - case Comment::BlockCommandCommentKind: - return CXComment_BlockCommand; - - case Comment::ParamCommandCommentKind: - return CXComment_ParamCommand; - - case Comment::TParamCommandCommentKind: - return CXComment_TParamCommand; - - case Comment::VerbatimBlockCommentKind: - return CXComment_VerbatimBlockCommand; - - case Comment::VerbatimBlockLineCommentKind: - return CXComment_VerbatimBlockLine; - - case Comment::VerbatimLineCommentKind: - return CXComment_VerbatimLine; - - case Comment::FullCommentKind: - return CXComment_FullComment; - } - llvm_unreachable("unknown CommentKind"); -} - -unsigned Comment_getNumChildren(const comments::Comment *C) { - if (!C) - return 0; - - return C->child_count(); -} - -comments::Comment *Comment_getChild(const comments::Comment *C, unsigned index) { - if (!C || index >= C->child_count()) - return nullptr; - - return *(C->child_begin() + index); -} - -BindgenStringRef HTMLTagComment_getTagName(const comments::Comment *C) { - if (auto *HTML = dyn_cast_or_null(C)) { - return stringref(HTML->getTagName()); - } else { - return stringref(); - } -} - -unsigned HTMLStartTag_getNumAttrs(const comments::Comment *C) { - if (auto *HTML = dyn_cast_or_null(C)) { - return HTML->getNumAttrs(); - } else { - return 0; - } -} - -BindgenStringRef HTMLStartTag_getAttrName(const comments::Comment *C, unsigned i) { - if (auto *HTML = dyn_cast_or_null(C)) { - return stringref(HTML->getAttr(i).Name); - } else { - return stringref(); - } -} - -BindgenStringRef HTMLStartTag_getAttrValue(const comments::Comment *C, unsigned i) { - if (auto *HTML = dyn_cast_or_null(C)) { - return stringref(HTML->getAttr(i).Value); - } else { - return stringref(); - } +// Adapted from CXSourceLocation.cpp +static void createNullLocation(FileEntry **file, int *line, + int *column, int *offset = nullptr) { + if (file) + *file = nullptr; + if (line) + *line = 0; + if (column) + *column = 0; + if (offset) + *offset = 0; } +// Adapted from clang_getCursorKindSpelling in CIndex.cpp BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { switch (Kind) { case CXCursor_FunctionDecl: @@ -3167,185 +769,1072 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("attribute(aligned)"); } - llvm_unreachable("Unhandled CXCursorKind"); + llvm_unreachable("Unhandled CXCursorKind"); +} + +// Adapted from clang_getTypeKindSpelling in CXType.cpp +BindgenStringRef TypeKind_getSpelling(CXTypeKind K) { + const char *s = nullptr; +#define TKIND(X) case CXType_##X: s = "" #X ""; break + switch (K) { + TKIND(Invalid); + TKIND(Unexposed); + TKIND(Void); + TKIND(Bool); + TKIND(Char_U); + TKIND(UChar); + TKIND(Char16); + TKIND(Char32); + TKIND(UShort); + TKIND(UInt); + TKIND(ULong); + TKIND(ULongLong); + TKIND(UInt128); + TKIND(Char_S); + TKIND(SChar); + case CXType_WChar: s = "WChar"; break; + TKIND(Short); + TKIND(Int); + TKIND(Long); + TKIND(LongLong); + TKIND(Int128); + TKIND(Half); + TKIND(Float); + TKIND(Double); + TKIND(LongDouble); + TKIND(ShortAccum); + TKIND(Accum); + TKIND(LongAccum); + TKIND(UShortAccum); + TKIND(UAccum); + TKIND(ULongAccum); + TKIND(Float16); + TKIND(Float128); + TKIND(NullPtr); + TKIND(Overload); + TKIND(Dependent); + TKIND(ObjCId); + TKIND(ObjCClass); + TKIND(ObjCSel); + TKIND(Complex); + TKIND(Pointer); + TKIND(BlockPointer); + TKIND(LValueReference); + TKIND(RValueReference); + TKIND(Record); + TKIND(Enum); + TKIND(Typedef); + TKIND(ObjCInterface); + TKIND(ObjCObject); + TKIND(ObjCObjectPointer); + TKIND(ObjCTypeParam); + TKIND(FunctionNoProto); + TKIND(FunctionProto); + TKIND(ConstantArray); + TKIND(IncompleteArray); + TKIND(VariableArray); + TKIND(DependentSizedArray); + TKIND(Vector); + TKIND(ExtVector); + TKIND(MemberPointer); + TKIND(Auto); + TKIND(Elaborated); + TKIND(Pipe); + TKIND(Attributed); +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id); +#include "clang/Basic/OpenCLImageTypes.def" +#undef IMAGE_TYPE +#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) TKIND(Id); +#include "clang/Basic/OpenCLExtensionTypes.def" + TKIND(OCLSampler); + TKIND(OCLEvent); + TKIND(OCLQueue); + TKIND(OCLReserveID); + } +#undef TKIND + return stringref(s); +} + +// From GetCursorKind in CXCursor.cpp +CXCursorKind Attr_getCXCursorKind(const Attr *A) { + assert(A && "Invalid arguments!"); + switch (A->getKind()) { + default: break; + case attr::IBAction: return CXCursor_IBActionAttr; + case attr::IBOutlet: return CXCursor_IBOutletAttr; + case attr::IBOutletCollection: return CXCursor_IBOutletCollectionAttr; + case attr::Final: return CXCursor_CXXFinalAttr; + case attr::Override: return CXCursor_CXXOverrideAttr; + case attr::Annotate: return CXCursor_AnnotateAttr; + case attr::AsmLabel: return CXCursor_AsmLabelAttr; + case attr::Packed: return CXCursor_PackedAttr; + case attr::Pure: return CXCursor_PureAttr; + case attr::Const: return CXCursor_ConstAttr; + case attr::NoDuplicate: return CXCursor_NoDuplicateAttr; + case attr::CUDAConstant: return CXCursor_CUDAConstantAttr; + case attr::CUDADevice: return CXCursor_CUDADeviceAttr; + case attr::CUDAGlobal: return CXCursor_CUDAGlobalAttr; + case attr::CUDAHost: return CXCursor_CUDAHostAttr; + case attr::CUDAShared: return CXCursor_CUDASharedAttr; + case attr::Visibility: return CXCursor_VisibilityAttr; + case attr::DLLExport: return CXCursor_DLLExport; + case attr::DLLImport: return CXCursor_DLLImport; + case attr::NSReturnsRetained: return CXCursor_NSReturnsRetained; + case attr::NSReturnsNotRetained: return CXCursor_NSReturnsNotRetained; + case attr::NSReturnsAutoreleased: return CXCursor_NSReturnsAutoreleased; + case attr::NSConsumesSelf: return CXCursor_NSConsumesSelf; + case attr::NSConsumed: return CXCursor_NSConsumed; + case attr::ObjCException: return CXCursor_ObjCException; + case attr::ObjCNSObject: return CXCursor_ObjCNSObject; + case attr::ObjCIndependentClass: return CXCursor_ObjCIndependentClass; + case attr::ObjCPreciseLifetime: return CXCursor_ObjCPreciseLifetime; + case attr::ObjCReturnsInnerPointer: return CXCursor_ObjCReturnsInnerPointer; + case attr::ObjCRequiresSuper: return CXCursor_ObjCRequiresSuper; + case attr::ObjCRootClass: return CXCursor_ObjCRootClass; + case attr::ObjCSubclassingRestricted: return CXCursor_ObjCSubclassingRestricted; + case attr::ObjCExplicitProtocolImpl: return CXCursor_ObjCExplicitProtocolImpl; + case attr::ObjCDesignatedInitializer: return CXCursor_ObjCDesignatedInitializer; + case attr::ObjCRuntimeVisible: return CXCursor_ObjCRuntimeVisible; + case attr::ObjCBoxable: return CXCursor_ObjCBoxable; + case attr::FlagEnum: return CXCursor_FlagEnum; + case attr::Convergent: return CXCursor_ConvergentAttr; + case attr::WarnUnused: return CXCursor_WarnUnusedAttr; + case attr::WarnUnusedResult: return CXCursor_WarnUnusedResultAttr; + case attr::Aligned: return CXCursor_AlignedAttr; + } + + return CXCursor_UnexposedAttr; +} + +// Adapted from clang_Comment_getKind in CXComment.cpp +CXCommentKind Comment_getKind(const comments::Comment *C) { + using namespace comments; + if (!C) + return CXComment_Null; + + switch (C->getCommentKind()) { + case Comment::NoCommentKind: + return CXComment_Null; + + case Comment::TextCommentKind: + return CXComment_Text; + + case Comment::InlineCommandCommentKind: + return CXComment_InlineCommand; + + case Comment::HTMLStartTagCommentKind: + return CXComment_HTMLStartTag; + + case Comment::HTMLEndTagCommentKind: + return CXComment_HTMLEndTag; + + case Comment::ParagraphCommentKind: + return CXComment_Paragraph; + + case Comment::BlockCommandCommentKind: + return CXComment_BlockCommand; + + case Comment::ParamCommandCommentKind: + return CXComment_ParamCommand; + + case Comment::TParamCommandCommentKind: + return CXComment_TParamCommand; + + case Comment::VerbatimBlockCommentKind: + return CXComment_VerbatimBlockCommand; + + case Comment::VerbatimBlockLineCommentKind: + return CXComment_VerbatimBlockLine; + + case Comment::VerbatimLineCommentKind: + return CXComment_VerbatimLine; + + case Comment::FullCommentKind: + return CXComment_FullComment; + } + llvm_unreachable("unknown CommentKind"); +} + +// Adapted from clang_parseTranslationUnit_Impl in CIndex.cpp +ASTUnit *parseTranslationUnit(const char *source_filename, + const char *const *command_line_args, + int num_command_line_args, int options, + struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files) { + SmallVector Args; + Args.push_back("clang"); + Args.append(command_line_args, command_line_args + num_command_line_args); + + std::unique_ptr> RemappedFiles( + new std::vector()); + // Recover resources if we crash before exiting this function. + llvm::CrashRecoveryContextCleanupRegistrar< + std::vector > RemappedCleanup(RemappedFiles.get()); + + for (auto &UF : llvm::makeArrayRef(unsaved_files, num_unsaved_files)) { + std::unique_ptr MB = + llvm::MemoryBuffer::getMemBufferCopy(StringRef(UF.Contents, UF.Length), UF.Filename); + RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release())); + } + + // Configure the diagnostics. + IntrusiveRefCntPtr + Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); + + if (options & CXTranslationUnit_KeepGoing) + Diags->setFatalsAsError(true); + + CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All; + if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles) + CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes; + + if (options & CXTranslationUnit_DetailedPreprocessingRecord) { + // Tell the preprocessor to save a detailed preprocessing record + Args.push_back("-Xclang"); + Args.push_back("-detailed-preprocessing-record"); + } + + return ASTUnit::LoadFromCommandLine( + Args.data(), Args.data() + Args.size(), + std::make_shared(), Diags, + /*ResourceFilePath*/ StringRef(), + /*OnlyLocalDecls*/ false, CaptureDiagnostics, *RemappedFiles.get(), + /*RemappedFilesKeepOriginalName*/ true); +} + +// Adapted from CXStoredDiagnostic::getSeverity in CXStoredDiagnostic.cpp +CXDiagnosticSeverity Diagnostic_getSeverity(const StoredDiagnostic *D) { + switch (D->getLevel()) { + case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored; + case DiagnosticsEngine::Note: return CXDiagnostic_Note; + case DiagnosticsEngine::Remark: + // The 'Remark' level isn't represented in the stable API. + case DiagnosticsEngine::Warning: return CXDiagnostic_Warning; + case DiagnosticsEngine::Error: return CXDiagnostic_Error; + case DiagnosticsEngine::Fatal: return CXDiagnostic_Fatal; + } + + llvm_unreachable("Invalid diagnostic level"); +} + +// Adapted from clang_getCursorDefinition in CIndex.cpp +const Decl *Decl_getDefinition(const Decl *D, bool isReference) { + if (!D) + return nullptr; + + switch (D->getKind()) { + // Declaration kinds that don't really separate the notions of + // declaration and definition. + case Decl::Namespace: + case Decl::Typedef: + case Decl::TypeAlias: + case Decl::TypeAliasTemplate: + case Decl::TemplateTypeParm: + case Decl::EnumConstant: + case Decl::Field: + case Decl::Binding: + case Decl::MSProperty: + case Decl::IndirectField: + case Decl::ObjCIvar: + case Decl::ObjCAtDefsField: + case Decl::ImplicitParam: + case Decl::ParmVar: + case Decl::NonTypeTemplateParm: + case Decl::TemplateTemplateParm: + case Decl::ObjCCategoryImpl: + case Decl::ObjCImplementation: + case Decl::AccessSpec: + case Decl::LinkageSpec: + case Decl::Export: + case Decl::ObjCPropertyImpl: + case Decl::FileScopeAsm: + case Decl::StaticAssert: + case Decl::Block: + case Decl::Captured: + case Decl::OMPCapturedExpr: + case Decl::Label: // FIXME: Is this right?? + case Decl::ClassScopeFunctionSpecialization: + case Decl::CXXDeductionGuide: + case Decl::Import: + case Decl::OMPThreadPrivate: + case Decl::OMPAllocate: + case Decl::OMPDeclareReduction: + case Decl::OMPDeclareMapper: + case Decl::OMPRequires: + case Decl::ObjCTypeParam: + case Decl::BuiltinTemplate: + case Decl::PragmaComment: + case Decl::PragmaDetectMismatch: + case Decl::UsingPack: + case Decl::Concept: + return D; + + // Declaration kinds that don't make any sense here, but are + // nonetheless harmless. + case Decl::Empty: + case Decl::TranslationUnit: + case Decl::ExternCContext: + break; + + // Declaration kinds for which the definition is not resolvable. + case Decl::UnresolvedUsingTypename: + case Decl::UnresolvedUsingValue: + break; + + case Decl::UsingDirective: + return cast(&*D)->getNominatedNamespace(); + + case Decl::NamespaceAlias: + return cast(&*D)->getNamespace(); + + case Decl::Enum: + case Decl::Record: + case Decl::CXXRecord: + case Decl::ClassTemplateSpecialization: + case Decl::ClassTemplatePartialSpecialization: + if (TagDecl *Def = cast(&*D)->getDefinition()) + return Def; + break; + + case Decl::Function: + case Decl::CXXMethod: + case Decl::CXXConstructor: + case Decl::CXXDestructor: + case Decl::CXXConversion: { + const FunctionDecl *Def = nullptr; + if (cast(&*D)->getBody(Def)) + return Def; + break; + } + + case Decl::Var: + case Decl::VarTemplateSpecialization: + case Decl::VarTemplatePartialSpecialization: + case Decl::Decomposition: { + // Ask the variable if it has a definition. + if (const VarDecl *Def = cast(&*D)->getDefinition()) + return Def; + break; + } + + case Decl::FunctionTemplate: { + const FunctionDecl *Def = nullptr; + if (cast(&*D)->getTemplatedDecl()->getBody(Def)) + return Def->getDescribedFunctionTemplate(); + break; + } + + case Decl::ClassTemplate: { + if (RecordDecl *Def = + cast(&*D)->getTemplatedDecl()->getDefinition()) + return cast(Def)->getDescribedClassTemplate(); + break; + } + + case Decl::VarTemplate: { + if (VarDecl *Def = + cast(&*D)->getTemplatedDecl()->getDefinition()) + return cast(Def)->getDescribedVarTemplate(); + break; + } + + case Decl::Using: + return cast(&*D); + + case Decl::UsingShadow: + case Decl::ConstructorUsingShadow: + return Decl_getDefinition( + cast(&*D)->getTargetDecl(), isReference); + + case Decl::ObjCMethod: { + const ObjCMethodDecl *Method = cast(D); + if (Method->isThisDeclarationADefinition()) + return D; + + // Dig out the method definition in the associated + // @implementation, if we have it. + // FIXME: The ASTs should make finding the definition easier. + if (const ObjCInterfaceDecl *Class + = dyn_cast(Method->getDeclContext())) + if (ObjCImplementationDecl *ClassImpl = Class->getImplementation()) + if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(), + Method->isInstanceMethod())) + if (Def->isThisDeclarationADefinition()) + return Def; + + break; + } + + case Decl::ObjCCategory: + if (ObjCCategoryImplDecl *Impl = cast(D)->getImplementation()) + return Impl; + break; + + case Decl::ObjCProtocol: + if (const ObjCProtocolDecl *Def = cast(D)->getDefinition()) + return Def; + break; + + case Decl::ObjCInterface: { + // There are two notions of a "definition" for an Objective-C + // class: the interface and its implementation. When we resolved a + // reference to an Objective-C class, produce the @interface as + // the definition; when we were provided with the interface, + // produce the @implementation as the definition. + const ObjCInterfaceDecl *IFace = cast(D); + if (isReference) { + if (const ObjCInterfaceDecl *Def = IFace->getDefinition()) + return Def; + } else if (ObjCImplementationDecl *Impl = IFace->getImplementation()) + return Impl; + break; + } + + case Decl::ObjCProperty: + // FIXME: We don't really know where to find the + // ObjCPropertyImplDecls that implement this property. + break; + + case Decl::ObjCCompatibleAlias: + if (const ObjCInterfaceDecl *Class + = cast(D)->getClassInterface()) + if (const ObjCInterfaceDecl *Def = Class->getDefinition()) + return Def; + + break; + + case Decl::Friend: + if (NamedDecl *Friend = cast(&*D)->getFriendDecl()) + return Decl_getDefinition(Friend, isReference); + break; + + case Decl::FriendTemplate: + if (NamedDecl *Friend = cast(&*D)->getFriendDecl()) + return Decl_getDefinition(Friend, isReference); + break; + } + + return nullptr; +} + +// Adapted from clang_getSpecializedCursorTemplate in CIndexCXX.cpp +const Decl *Decl_getSpecializedTemplate(const Decl *D) { + if (!D) + return nullptr; + + Decl *Template = nullptr; + if (const CXXRecordDecl *CXXRecord = dyn_cast(&*D)) { + if (const ClassTemplatePartialSpecializationDecl *PartialSpec + = dyn_cast(CXXRecord)) + Template = PartialSpec->getSpecializedTemplate(); + else if (const ClassTemplateSpecializationDecl *ClassSpec + = dyn_cast(CXXRecord)) { + llvm::PointerUnion Result + = ClassSpec->getSpecializedTemplateOrPartial(); + if (Result.is()) + Template = Result.get(); + else + Template = Result.get(); + + } else + Template = CXXRecord->getInstantiatedFromMemberClass(); + } else if (const FunctionDecl *Function = dyn_cast(&*D)) { + Template = Function->getPrimaryTemplate(); + if (!Template) + Template = Function->getInstantiatedFromMemberFunction(); + } else if (const VarDecl *Var = dyn_cast(&*D)) { + if (Var->isStaticDataMember()) + Template = Var->getInstantiatedFromStaticDataMember(); + } else if (const RedeclarableTemplateDecl *Tmpl + = dyn_cast(&*D)) + Template = Tmpl->getInstantiatedFromMemberTemplate(); + + return Template; +} + +// Adapted from clang_getTemplateCursorKind in CIndexCXX.cpp +CXCursorKind Decl_getTemplateCursorKind(const Decl *D) { + if (!D) + return CXCursor_NoDeclFound; + + switch (D->getKind()) { + case Decl::ClassTemplate: + case Decl::FunctionTemplate: + if (const TemplateDecl *Template = dyn_cast_or_null(&*D)) + return getCursorKindForDecl(Template->getTemplatedDecl()); + break; + + case Decl::ClassTemplatePartialSpecialization: + if (const ClassTemplateSpecializationDecl *PartialSpec + = dyn_cast_or_null(&*D)) { + switch (PartialSpec->getTagKind()) { + case TTK_Interface: + case TTK_Struct: return CXCursor_StructDecl; + case TTK_Class: return CXCursor_ClassDecl; + case TTK_Union: return CXCursor_UnionDecl; + case TTK_Enum: return CXCursor_NoDeclFound; + } + } + break; + + default: + break; + } + + return CXCursor_NoDeclFound; +} + +// Adapted from getDeclSpelling in CIndex.cpp +BindgenStringRef Decl_getSpelling(const Decl *D) { + if (!D) + return stringref(); + + const NamedDecl *ND = dyn_cast_or_null(&*D); + if (!ND) { + if (const ObjCPropertyImplDecl *PropImpl = + dyn_cast(D)) + if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl()) + return stringref(Property->getIdentifier()->getName()); + + if (const ImportDecl *ImportD = dyn_cast(D)) + if (Module *Mod = ImportD->getImportedModule()) + return stringref(Mod->getFullModuleName()); + + return stringref(); + } + + if (const ObjCMethodDecl *OMD = dyn_cast(ND)) + return stringref(OMD->getSelector().getAsString()); + + if (const ObjCCategoryImplDecl *CIMP = dyn_cast(ND)) + // No, this isn't the same as the code below. getIdentifier() is non-virtual + // and returns different names. NamedDecl returns the class name and + // ObjCCategoryImplDecl returns the category name. + return stringref(CIMP->getIdentifier()->getNameStart()); + + if (isa(D)) + return stringref(); + + SmallString<1024> S; + llvm::raw_svector_ostream os(S); + ND->printName(os); + return stringref(S.str()); +} + +// Adapted from clang_Cursor_getNumTemplateArguments in CXCursor.cpp +int Decl_getNumTemplateArguments(const Decl *D) { + const FunctionDecl *FD = llvm::dyn_cast_or_null(&*D); + if (!FD) + return -1; + + const FunctionTemplateSpecializationInfo* SpecInfo = + FD->getTemplateSpecializationInfo(); + if (!SpecInfo) { + return -1; + } + + return SpecInfo->TemplateArguments->size(); +} + +// Adapted from clang_getCursorLinkage in CIndex.cpp +CXLinkageKind Decl_getLinkage(const Decl *D) { + if (auto *ND = dyn_cast_or_null(&*D)) + switch (ND->getLinkageInternal()) { + case NoLinkage: + case VisibleNoLinkage: + return CXLinkage_NoLinkage; + case ModuleInternalLinkage: + case InternalLinkage: + return CXLinkage_Internal; + case UniqueExternalLinkage: + return CXLinkage_UniqueExternal; + case ModuleLinkage: + case ExternalLinkage: + return CXLinkage_External; + }; + + return CXLinkage_Invalid; +} + +// Adapted from clang_getCursorVisibility in CIndex.cpp +CXVisibilityKind Decl_getVisibility(const Decl *D) { + if (auto *ND = dyn_cast_or_null(&*D)) + switch (ND->getVisibility()) { + case HiddenVisibility: + return CXVisibility_Hidden; + case ProtectedVisibility: + return CXVisibility_Protected; + case DefaultVisibility: + return CXVisibility_Default; + }; + + return CXVisibility_Invalid; +} + +// Adapted from clang_getCXXAccessSpecifier in CIndexCXX.cpp +CX_CXXAccessSpecifier Decl_getAccess(const Decl *D) { + AccessSpecifier spec = AS_none; + if (D) + spec = D->getAccess(); + + switch (spec) { + case AS_public: return CX_CXXPublic; + case AS_protected: return CX_CXXProtected; + case AS_private: return CX_CXXPrivate; + case AS_none: return CX_CXXInvalidAccessSpecifier; + } + + llvm_unreachable("Invalid AccessSpecifier!"); +} + +// Adapted from clang_Cursor_getArgument in CXCursor.cpp +const Expr *Expr_getArgument(const Expr *E, unsigned i) { + if (const CallExpr *CE = dyn_cast_or_null(&*E)) { + if (i < CE->getNumArgs()) { + return CE->getArg(i); + } + } + if (const CXXConstructExpr *CE = dyn_cast_or_null(&*E)) { + if (i < CE->getNumArgs()) { + return CE->getArg(i); + } + } + return nullptr; +} + +// Adapted from clang_Cursor_getNumArguments in CXCursor.cpp +int Expr_getNumArguments(const Expr *E) { + if (const CallExpr *CE = dyn_cast_or_null(&*E)) + return CE->getNumArgs(); + if (const CXXConstructExpr *CE = dyn_cast_or_null(&*E)) + return CE->getNumArgs(); + return -1; +} + +// Adapted from getLocationFromExpr in CIndex.cpp +SourceLocation *Expr_getLocation(const Expr *E) { + if (!E) + return nullptr; + if (const ImplicitCastExpr *CE = dyn_cast(&*E)) + return Expr_getLocation(CE->getSubExpr()); + + if (const ObjCMessageExpr *Msg = dyn_cast(&*E)) + return new SourceLocation(/*FIXME:*/Msg->getLeftLoc()); + if (const DeclRefExpr *DRE = dyn_cast(&*E)) + return new SourceLocation(DRE->getLocation()); + if (const MemberExpr *Member = dyn_cast(&*E)) + return new SourceLocation(Member->getMemberLoc()); + if (const ObjCIvarRefExpr *Ivar = dyn_cast(&*E)) + return new SourceLocation(Ivar->getLocation()); + if (const SizeOfPackExpr *SizeOfPack = dyn_cast(&*E)) + return new SourceLocation(SizeOfPack->getPackLoc()); + if (const ObjCPropertyRefExpr *PropRef = dyn_cast(&*E)) + return new SourceLocation(PropRef->getLocation()); + + return new SourceLocation(E->getBeginLoc()); +} + +// Adapted from clang_getTypeDeclaration in CXType.cpp +const Decl *Type_getDeclaration(QualType T) { + const Type *TP = T.getTypePtrOrNull(); + + if (!TP) + return nullptr; + + const Decl *D = nullptr; + +try_again: + switch (TP->getTypeClass()) { + case Type::Typedef: + D = cast(TP)->getDecl(); + break; + case Type::ObjCObject: + D = cast(TP)->getInterface(); + break; + case Type::ObjCInterface: + D = cast(TP)->getDecl(); + break; + case Type::Record: + case Type::Enum: + D = cast(TP)->getDecl(); + break; + case Type::TemplateSpecialization: + if (const RecordType *Record = TP->getAs()) + D = Record->getDecl(); + else + D = cast(TP)->getTemplateName() + .getAsTemplateDecl(); + break; + + case Type::Auto: + case Type::DeducedTemplateSpecialization: + TP = cast(TP)->getDeducedType().getTypePtrOrNull(); + if (TP) + goto try_again; + break; + + case Type::InjectedClassName: + D = cast(TP)->getDecl(); + break; + + // FIXME: Template type parameters! + + case Type::Elaborated: + TP = cast(TP)->getNamedType().getTypePtrOrNull(); + goto try_again; + + default: + break; + } + + if (!D) + return nullptr; + + return D; } -BindgenStringRef TypeKind_getSpelling(CXTypeKind K) { - const char *s = nullptr; -#define TKIND(X) case CXType_##X: s = "" #X ""; break - switch (K) { - TKIND(Invalid); - TKIND(Unexposed); - TKIND(Void); - TKIND(Bool); - TKIND(Char_U); - TKIND(UChar); - TKIND(Char16); - TKIND(Char32); - TKIND(UShort); - TKIND(UInt); - TKIND(ULong); - TKIND(ULongLong); - TKIND(UInt128); - TKIND(Char_S); - TKIND(SChar); - case CXType_WChar: s = "WChar"; break; - TKIND(Short); - TKIND(Int); - TKIND(Long); - TKIND(LongLong); - TKIND(Int128); - TKIND(Half); - TKIND(Float); - TKIND(Double); - TKIND(LongDouble); - TKIND(ShortAccum); - TKIND(Accum); - TKIND(LongAccum); - TKIND(UShortAccum); - TKIND(UAccum); - TKIND(ULongAccum); - TKIND(Float16); - TKIND(Float128); - TKIND(NullPtr); - TKIND(Overload); - TKIND(Dependent); - TKIND(ObjCId); - TKIND(ObjCClass); - TKIND(ObjCSel); - TKIND(Complex); - TKIND(Pointer); - TKIND(BlockPointer); - TKIND(LValueReference); - TKIND(RValueReference); - TKIND(Record); - TKIND(Enum); - TKIND(Typedef); - TKIND(ObjCInterface); - TKIND(ObjCObject); - TKIND(ObjCObjectPointer); - TKIND(ObjCTypeParam); - TKIND(FunctionNoProto); - TKIND(FunctionProto); - TKIND(ConstantArray); - TKIND(IncompleteArray); - TKIND(VariableArray); - TKIND(DependentSizedArray); - TKIND(Vector); - TKIND(ExtVector); - TKIND(MemberPointer); - TKIND(Auto); - TKIND(Elaborated); - TKIND(Pipe); - TKIND(Attributed); -#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id); -#include "clang/Basic/OpenCLImageTypes.def" -#undef IMAGE_TYPE -#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) TKIND(Id); -#include "clang/Basic/OpenCLExtensionTypes.def" - TKIND(OCLSampler); - TKIND(OCLEvent); - TKIND(OCLQueue); - TKIND(OCLReserveID); +// Adapted from getTokens and others in CIndex.cpp +void tokenize(ASTUnit *TU, BindgenSourceRange Range, CXToken **Tokens, + unsigned *NumTokens) { + if (!Tokens || !NumTokens || !Range) + return; + + // Translate the Range end location to after the last token, instead of + // the beginning of the last token. + SourceManager &SourceMgr = TU->getSourceManager(); + SourceLocation EndLoc = *Range.E; + bool IsTokenRange = true; + if (EndLoc.isValid() && EndLoc.isMacroID() && !SourceMgr.isMacroArgExpansion(EndLoc)) { + CharSourceRange Expansion = SourceMgr.getExpansionRange(EndLoc); + EndLoc = Expansion.getEnd(); + IsTokenRange = Expansion.isTokenRange(); + } + if (IsTokenRange && EndLoc.isValid()) { + unsigned Length = Lexer::MeasureTokenLength(SourceMgr.getSpellingLoc(EndLoc), + SourceMgr, TU->getLangOpts()); + EndLoc = EndLoc.getLocWithOffset(Length); + } + + SmallVector CXTokens; + std::pair BeginLocInfo = + SourceMgr.getDecomposedSpellingLoc(*Range.B); + std::pair EndLocInfo = + SourceMgr.getDecomposedSpellingLoc(EndLoc); + + // Cannot tokenize across files. + if (BeginLocInfo.first != EndLocInfo.first) + return; + + // Create a lexer + bool Invalid = false; + StringRef Buffer + = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid); + if (Invalid) + return; + + Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), + TU->getASTContext().getLangOpts(), + Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end()); + Lex.SetCommentRetentionState(true); + + // Lex tokens until we hit the end of the range. + const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second; + Token Tok; + bool previousWasAt = false; + do { + // Lex the next token + Lex.LexFromRawLexer(Tok); + if (Tok.is(tok::eof)) + break; + + // Initialize the CXToken. + CXToken CXTok; + + // - Common fields + CXTok.int_data[1] = Tok.getLocation().getRawEncoding(); + CXTok.int_data[2] = Tok.getLength(); + CXTok.int_data[3] = 0; + + // - Kind-specific fields + if (Tok.isLiteral()) { + CXTok.int_data[0] = CXToken_Literal; + CXTok.ptr_data = const_cast(Tok.getLiteralData()); + } else if (Tok.is(tok::raw_identifier)) { + // Lookup the identifier to determine whether we have a keyword. + IdentifierInfo *II + = TU->getPreprocessor().LookUpIdentifierInfo(Tok); + + if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) { + CXTok.int_data[0] = CXToken_Keyword; + } + else { + CXTok.int_data[0] = Tok.is(tok::identifier) + ? CXToken_Identifier + : CXToken_Keyword; + } + CXTok.ptr_data = II; + } else if (Tok.is(tok::comment)) { + CXTok.int_data[0] = CXToken_Comment; + CXTok.ptr_data = nullptr; + } else { + CXTok.int_data[0] = CXToken_Punctuation; + CXTok.ptr_data = nullptr; + } + CXTokens.push_back(CXTok); + previousWasAt = Tok.is(tok::at); + } while (Lex.getBufferLocation() < EffectiveBufferEnd); + + *Tokens = new CXToken[CXTokens.size()]; + memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); + *NumTokens = CXTokens.size(); +} + +// Originally clang_getTokenKind in CIndex.cpp +CXTokenKind getTokenKind(CXToken token) { + return static_cast(token.int_data[0]); +} + +// Adapted from clang_getTokenSpelling in CIndex.cpp +BindgenStringRef getTokenSpelling(ASTUnit *CXXUnit, CXToken CXTok) { + if (!CXXUnit) + return stringref(); + + switch (getTokenKind(CXTok)) { + case CXToken_Identifier: + case CXToken_Keyword: + // We know we have an IdentifierInfo*, so use that. + return stringref(static_cast(CXTok.ptr_data) + ->getNameStart()); + + case CXToken_Literal: { + // We have stashed the starting pointer in the ptr_data field. Use it. + const char *Text = static_cast(CXTok.ptr_data); + return stringref(StringRef(Text, CXTok.int_data[2])); + } + + case CXToken_Punctuation: + case CXToken_Comment: + break; } -#undef TKIND - return stringref(s); -} -BindgenStringRef FileEntry_getName(FileEntry *F) { - if (!F) + // We have to find the starting buffer pointer the hard way, by + // deconstructing the source location. + SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]); + std::pair LocInfo + = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc); + bool Invalid = false; + StringRef Buffer + = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); + if (Invalid) return stringref(); - return stringref(F->getName()); + + return stringref(Buffer.substr(LocInfo.second, CXTok.int_data[2])); } -BindgenStringRef getClangVersion() { - return stringref(getClangFullVersion()); +// Adapted from clang_Type_getSizeOf in CXType.cpp +long long Type_getSizeOf(QualType QT, ASTContext *Context) { + if (QT.isNull()) + return CXTypeLayoutError_Invalid; + // [expr.sizeof] p2: if reference type, return size of referenced type + if (QT->isReferenceType()) + QT = QT.getNonReferenceType(); + // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete + // enumeration + // Note: We get the cxtype, not the cxcursor, so we can't call + // FieldDecl->isBitField() + // [expr.sizeof] p3: pointer ok, function not ok. + // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error + if (QT->isIncompleteType()) + return CXTypeLayoutError_Incomplete; + if (QT->isDependentType()) + return CXTypeLayoutError_Dependent; + if (!QT->isConstantSizeType()) + return CXTypeLayoutError_NotConstantSize; + if (const auto *Deduced = dyn_cast(QT)) + if (Deduced->getDeducedType().isNull()) + return CXTypeLayoutError_Undeduced; + // [gcc extension] lib/AST/ExprConstant.cpp:1372 + // HandleSizeof : {voidtype,functype} == 1 + // not handled by ASTContext.cpp:1313 getTypeInfoImpl + if (QT->isVoidType() || QT->isFunctionType()) + return 1; + return Context->getTypeSizeInChars(QT).getQuantity(); } -bool CXXBaseSpecifier_isVirtualBase(const CXXBaseSpecifier *B) { - return B && B->isVirtual(); +// Adapted from clang_Type_getAlignOf in CXType.cpp +long long Type_getAlignOf(QualType QT, ASTContext *Context) { + if (QT.isNull()) + return CXTypeLayoutError_Invalid; + // [expr.alignof] p1: return size_t value for complete object type, reference + // or array. + // [expr.alignof] p3: if reference type, return size of referenced type + if (QT->isReferenceType()) + QT = QT.getNonReferenceType(); + if (!(QT->isIncompleteArrayType() || !QT->isIncompleteType())) + return CXTypeLayoutError_Incomplete; + if (QT->isDependentType()) + return CXTypeLayoutError_Dependent; + if (const auto *Deduced = dyn_cast(QT)) + if (Deduced->getDeducedType().isNull()) + return CXTypeLayoutError_Undeduced; + // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl + // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1 + // if (QT->isVoidType()) return 1; + return Context->getTypeAlignInChars(QT).getQuantity(); } -QualType CXXBaseSpecifier_getType(const CXXBaseSpecifier *B) { - if (!B) +// Adapted from clang_getPointeeType in CXType.cpp +QualType Type_getPointeeType(QualType T) { + const Type *TP = T.getTypePtrOrNull(); + + if (!TP) return QualType(); - return make_type_compatible(B->getType()); -} -CXCursorKind Attr_getCXCursorKind(const Attr *A) { - assert(A && "Invalid arguments!"); - switch (A->getKind()) { - default: break; - case attr::IBAction: return CXCursor_IBActionAttr; - case attr::IBOutlet: return CXCursor_IBOutletAttr; - case attr::IBOutletCollection: return CXCursor_IBOutletCollectionAttr; - case attr::Final: return CXCursor_CXXFinalAttr; - case attr::Override: return CXCursor_CXXOverrideAttr; - case attr::Annotate: return CXCursor_AnnotateAttr; - case attr::AsmLabel: return CXCursor_AsmLabelAttr; - case attr::Packed: return CXCursor_PackedAttr; - case attr::Pure: return CXCursor_PureAttr; - case attr::Const: return CXCursor_ConstAttr; - case attr::NoDuplicate: return CXCursor_NoDuplicateAttr; - case attr::CUDAConstant: return CXCursor_CUDAConstantAttr; - case attr::CUDADevice: return CXCursor_CUDADeviceAttr; - case attr::CUDAGlobal: return CXCursor_CUDAGlobalAttr; - case attr::CUDAHost: return CXCursor_CUDAHostAttr; - case attr::CUDAShared: return CXCursor_CUDASharedAttr; - case attr::Visibility: return CXCursor_VisibilityAttr; - case attr::DLLExport: return CXCursor_DLLExport; - case attr::DLLImport: return CXCursor_DLLImport; - case attr::NSReturnsRetained: return CXCursor_NSReturnsRetained; - case attr::NSReturnsNotRetained: return CXCursor_NSReturnsNotRetained; - case attr::NSReturnsAutoreleased: return CXCursor_NSReturnsAutoreleased; - case attr::NSConsumesSelf: return CXCursor_NSConsumesSelf; - case attr::NSConsumed: return CXCursor_NSConsumed; - case attr::ObjCException: return CXCursor_ObjCException; - case attr::ObjCNSObject: return CXCursor_ObjCNSObject; - case attr::ObjCIndependentClass: return CXCursor_ObjCIndependentClass; - case attr::ObjCPreciseLifetime: return CXCursor_ObjCPreciseLifetime; - case attr::ObjCReturnsInnerPointer: return CXCursor_ObjCReturnsInnerPointer; - case attr::ObjCRequiresSuper: return CXCursor_ObjCRequiresSuper; - case attr::ObjCRootClass: return CXCursor_ObjCRootClass; - case attr::ObjCSubclassingRestricted: return CXCursor_ObjCSubclassingRestricted; - case attr::ObjCExplicitProtocolImpl: return CXCursor_ObjCExplicitProtocolImpl; - case attr::ObjCDesignatedInitializer: return CXCursor_ObjCDesignatedInitializer; - case attr::ObjCRuntimeVisible: return CXCursor_ObjCRuntimeVisible; - case attr::ObjCBoxable: return CXCursor_ObjCBoxable; - case attr::FlagEnum: return CXCursor_FlagEnum; - case attr::Convergent: return CXCursor_ConvergentAttr; - case attr::WarnUnused: return CXCursor_WarnUnusedAttr; - case attr::WarnUnusedResult: return CXCursor_WarnUnusedResultAttr; - case attr::Aligned: return CXCursor_AlignedAttr; +try_again: + switch (TP->getTypeClass()) { + case Type::Pointer: + T = cast(TP)->getPointeeType(); + break; + case Type::BlockPointer: + T = cast(TP)->getPointeeType(); + break; + case Type::LValueReference: + case Type::RValueReference: + T = cast(TP)->getPointeeType(); + break; + case Type::ObjCObjectPointer: + T = cast(TP)->getPointeeType(); + break; + case Type::MemberPointer: + T = cast(TP)->getPointeeType(); + break; + case Type::Auto: + case Type::DeducedTemplateSpecialization: + TP = cast(TP)->getDeducedType().getTypePtrOrNull(); + if (TP) + goto try_again; + break; + default: + T = QualType(); + break; } - - return CXCursor_UnexposedAttr; + return make_type_compatible(T); } -BindgenStringRef CXXBaseSpecifier_getSpelling(const CXXBaseSpecifier *B) { - return stringref(B->getType().getAsString()); -} +// Adapted from clang_getElementType in CXType.cpp +QualType Type_getElementType(QualType T) { + QualType ET = QualType(); + const Type *TP = T.getTypePtrOrNull(); -SourceLocation *CXXBaseSpecifier_getLocation(const CXXBaseSpecifier *B) { - return new SourceLocation(B->getBaseTypeLoc()); + if (TP) { + switch (TP->getTypeClass()) { + case Type::ConstantArray: + ET = cast (TP)->getElementType(); + break; + case Type::IncompleteArray: + ET = cast (TP)->getElementType(); + break; + case Type::VariableArray: + ET = cast (TP)->getElementType(); + break; + case Type::DependentSizedArray: + ET = cast (TP)->getElementType(); + break; + case Type::Vector: + ET = cast (TP)->getElementType(); + break; + case Type::ExtVector: + ET = cast(TP)->getElementType(); + break; + case Type::Complex: + ET = cast (TP)->getElementType(); + break; + default: + break; + } + } + return make_type_compatible(ET); } -SourceLocation *Attr_getLocation(const Attr *A) { - return new SourceLocation(A->getLocation()); -} +// Adapted from clang_getNumElements in CXType.cpp +int Type_getNumElements(QualType T) { + long long result = -1; + const Type *TP = T.getTypePtrOrNull(); -SourceLocation *PreprocessedEntity_getLocation(const PreprocessedEntity *PPE) { - return new SourceLocation(PPE->getSourceRange().getBegin()); + if (TP) { + switch (TP->getTypeClass()) { + case Type::ConstantArray: + result = cast (TP)->getSize().getSExtValue(); + break; + case Type::Vector: + result = cast (TP)->getNumElements(); + break; + case Type::ExtVector: + result = cast(TP)->getNumElements(); + break; + default: + break; + } + } + return result; } -BindgenSourceRange CXXBaseSpecifier_getSourceRange(const CXXBaseSpecifier *B) { - return BindgenSourceRange(B->getSourceRange()); +// Adapted from clang_getFunctionTypeCallingConv in CXType.cpp +CXCallingConv Type_getFunctionTypeCallingConv(QualType T) { + if (T.isNull()) + return CXCallingConv_Invalid; + + if (const FunctionType *FD = T->getAs()) { +#define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X + switch (FD->getCallConv()) { + TCALLINGCONV(C); + TCALLINGCONV(X86StdCall); + TCALLINGCONV(X86FastCall); + TCALLINGCONV(X86ThisCall); + TCALLINGCONV(X86Pascal); + TCALLINGCONV(X86RegCall); + TCALLINGCONV(X86VectorCall); + TCALLINGCONV(AArch64VectorCall); + TCALLINGCONV(Win64); + TCALLINGCONV(X86_64SysV); + TCALLINGCONV(AAPCS); + TCALLINGCONV(AAPCS_VFP); + TCALLINGCONV(IntelOclBicc); + TCALLINGCONV(Swift); + TCALLINGCONV(PreserveMost); + TCALLINGCONV(PreserveAll); + case CC_SpirFunction: return CXCallingConv_Unexposed; + case CC_OpenCLKernel: return CXCallingConv_Unexposed; + break; + } +#undef TCALLINGCONV + } + + return CXCallingConv_Invalid; } -BindgenSourceRange Attr_getSourceRange(const Attr *A) { - return BindgenSourceRange(A->getRange()); -} +// Adapted from clang_getSpellingLocation in CXSourceLocation.cpp +void getSpellingLocation(ASTUnit *AST, const SourceLocation *location, FileEntry **file, int *line, int *column, int *offset) { + if (!location) + return createNullLocation(file, line, column, offset); -BindgenSourceRange PreprocessedEntity_getSourceRange(const PreprocessedEntity *PPE) { - return BindgenSourceRange(PPE->getSourceRange()); + const SourceManager &SM = AST->getSourceManager(); + // FIXME: This should call SourceManager::getSpellingLoc(). + SourceLocation SpellLoc = SM.getFileLoc(*location); + std::pair LocInfo = SM.getDecomposedLoc(SpellLoc); + FileID FID = LocInfo.first; + unsigned FileOffset = LocInfo.second; + + if (FID.isInvalid()) + return createNullLocation(file, line, column, offset); + + if (file) + *file = const_cast(SM.getFileEntryForID(FID)); + if (line) + *line = SM.getLineNumber(FID, FileOffset); + if (column) + *column = SM.getColumnNumber(FID, FileOffset); + if (offset) + *offset = FileOffset; } From 02cb2264b064e6291764d3c62506bcbcc1775463 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 21 Feb 2020 17:32:33 -0800 Subject: [PATCH 54/88] Use Ubuntu 16.04 LLVM packages so we can link against the correct libstdc++ --- ci/before_install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/before_install.sh b/ci/before_install.sh index 41b397716b..12107d0f17 100644 --- a/ci/before_install.sh +++ b/ci/before_install.sh @@ -8,9 +8,9 @@ fi function llvm_linux_target_triple() { if [ "$1" == "5.0" ]; then - echo "linux-x86_64-ubuntu14.04" + echo "linux-x86_64-ubuntu16.04" else - echo "x86_64-linux-gnu-ubuntu-14.04" + echo "x86_64-linux-gnu-ubuntu-16.04" fi } From a6ddacd21770af7b7a3dbdfd85caa9a59a800a23 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 26 Feb 2020 18:12:51 -0800 Subject: [PATCH 55/88] Make clang interface compile with Clang 8 --- src/clang/clang_interface.cpp | 24 ++++++++++++++--- src/clang/libclang_compat.cpp | 49 ++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index 480e645d18..cef7f95209 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -308,16 +308,24 @@ BindgenStringRef Decl_getMangling(const Decl *D, ASTContext *Ctx) { if (!D || !(isa(&*D) || isa(&*D))) return stringref(); - ASTNameGenerator ASTNameGen(*Ctx); - return stringref(ASTNameGen.getName(&*D)); +#if CLANG_VERSION_MAJOR > 8 + ASTNameGenerator NameGen(*Ctx); +#else + index::CodegenNameGenerator NameGen(*Ctx); +#endif // CLANG_VERSION_MAJOR > 8 + return stringref(NameGen.getName(&*D)); } BindgenStringRefSet Decl_getCXXManglings(const Decl *D, ASTContext *Ctx) { if (!D || !(isa(&*D) || isa(&*D))) return BindgenStringRefSet(); - ASTNameGenerator ASTNameGen(*Ctx); - std::vector Manglings = ASTNameGen.getAllManglings(&*D); +#if CLANG_VERSION_MAJOR > 8 + ASTNameGenerator NameGen(*Ctx); +#else + index::CodegenNameGenerator NameGen(*Ctx); +#endif // CLANG_VERSION_MAJOR > 8 + std::vector Manglings = NameGen.getAllManglings(&*D); return make_stringrefset(Manglings); } @@ -480,7 +488,11 @@ bool CXXMethod_isStatic(const Decl *D) { bool CXXMethod_isConst(const Decl *D) { auto *Method = D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; +#if CLANG_VERSION_MAJOR > 8 return Method && Method->getMethodQualifiers().hasConst(); +#else + return Method && Method->getTypeQualifiers().hasConst(); +#endif // CLANG_VERSION_MAJOR > 8 } bool CXXMethod_isVirtual(const Decl *D) { @@ -874,8 +886,10 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { return CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective; case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: return CXCursor_OMPTargetTeamsDistributeSimdDirective; +#if CLANG_VERSION_MAJOR > 8 case Stmt::BuiltinBitCastExprClass: return CXCursor_BuiltinBitCastExpr; +#endif // CLANG_VERSION_MAJOR > 8 default: return CXCursor_UnexposedExpr; @@ -1136,8 +1150,10 @@ class BindgenVisitor : public RecursiveASTVisitor { // libclang visits this, but we don't need it for bindgen return true; +#if CLANG_VERSION_MAJOR > 8 case TemplateName::AssumedTemplate: return true; +#endif // CLANG_VERSION_MAJOR > 8 case TemplateName::DependentTemplate: return true; diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 3986950dbf..ab8acc27be 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -155,13 +155,13 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { BTCASE(ObjCId); BTCASE(ObjCClass); BTCASE(ObjCSel); +#if CLANG_VERSION_MAJOR > 7 +#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) BTCASE(Id); +#include "clang/Basic/OpenCLExtensionTypes.def" +#endif // CLANG_VERSION_MAJOR > 7 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) BTCASE(Id); #include "clang/Basic/OpenCLImageTypes.def" #undef IMAGE_TYPE -#if CLANG_VERSION_MAJOR > 8 -#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) BTCASE(Id); -#include "clang/Basic/OpenCLExtensionTypes.def" -#endif // CLANG_VERSION_MAJOR > 8 BTCASE(OCLSampler); BTCASE(OCLEvent); BTCASE(OCLQueue); @@ -213,12 +213,14 @@ CXTypeKind Type_kind(QualType T, ASTContext *Context) { TKCASE(VariableArray); TKCASE(DependentSizedArray); TKCASE(Vector); - TKCASE(ExtVector); TKCASE(MemberPointer); TKCASE(Auto); TKCASE(Elaborated); TKCASE(Pipe); TKCASE(Attributed); +#if CLANG_VERSION_MAJOR > 8 + TKCASE(ExtVector); +#endif // CLANG_VERSION_MAJOR > 8 default: return CXType_Unexposed; } @@ -454,8 +456,10 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("CallExpr"); case CXCursor_ObjCMessageExpr: return stringref("ObjCMessageExpr"); +#if CLANG_VERSION_MAJOR > 8 case CXCursor_BuiltinBitCastExpr: return stringref("BuiltinBitCastExpr"); +#endif // CLANG_VERSION_MAJOR > 8 case CXCursor_UnexposedStmt: return stringref("UnexposedStmt"); case CXCursor_DeclStmt: @@ -759,6 +763,7 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("StaticAssert"); case CXCursor_FriendDecl: return stringref("FriendDecl"); +#if CLANG_VERSION_MAJOR > 8 case CXCursor_ConvergentAttr: return stringref("attribute(convergent)"); case CXCursor_WarnUnusedAttr: @@ -767,6 +772,7 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("attribute(warn_unused_result)"); case CXCursor_AlignedAttr: return stringref("attribute(aligned)"); +#endif // CLANG_VERSION_MAJOR > 8 } llvm_unreachable("Unhandled CXCursorKind"); @@ -835,12 +841,14 @@ BindgenStringRef TypeKind_getSpelling(CXTypeKind K) { TKIND(VariableArray); TKIND(DependentSizedArray); TKIND(Vector); - TKIND(ExtVector); TKIND(MemberPointer); TKIND(Auto); TKIND(Elaborated); TKIND(Pipe); TKIND(Attributed); +#if CLANG_VERSION_MAJOR > 8 + TKIND(ExtVector); +#endif // CLANG_VERSION_MAJOR > 8 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id); #include "clang/Basic/OpenCLImageTypes.def" #undef IMAGE_TYPE @@ -897,10 +905,12 @@ CXCursorKind Attr_getCXCursorKind(const Attr *A) { case attr::ObjCRuntimeVisible: return CXCursor_ObjCRuntimeVisible; case attr::ObjCBoxable: return CXCursor_ObjCBoxable; case attr::FlagEnum: return CXCursor_FlagEnum; +#if CLANG_VERSION_MAJOR > 8 case attr::Convergent: return CXCursor_ConvergentAttr; case attr::WarnUnused: return CXCursor_WarnUnusedAttr; case attr::WarnUnusedResult: return CXCursor_WarnUnusedResultAttr; case attr::Aligned: return CXCursor_AlignedAttr; +#endif // CLANG_VERSION_MAJOR > 8 } return CXCursor_UnexposedAttr; @@ -981,12 +991,19 @@ ASTUnit *parseTranslationUnit(const char *source_filename, IntrusiveRefCntPtr Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); - if (options & CXTranslationUnit_KeepGoing) + if (options & CXTranslationUnit_KeepGoing) { +#if CLANG_VERSION_MAJOR > 8 Diags->setFatalsAsError(true); +#else + Diags->setSuppressAfterFatalError(false); +#endif // CLANG_VERSION_MAJOR > 8 + } +#if CLANG_VERSION_MAJOR > 8 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All; if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles) CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes; +#endif // CLANG_VERSION_MAJOR > 8 if (options & CXTranslationUnit_DetailedPreprocessingRecord) { // Tell the preprocessor to save a detailed preprocessing record @@ -998,7 +1015,13 @@ ASTUnit *parseTranslationUnit(const char *source_filename, Args.data(), Args.data() + Args.size(), std::make_shared(), Diags, /*ResourceFilePath*/ StringRef(), - /*OnlyLocalDecls*/ false, CaptureDiagnostics, *RemappedFiles.get(), + /*OnlyLocalDecls*/ false, +#if CLANG_VERSION_MAJOR > 8 + CaptureDiagnostics, +#else + /*CaptureDiagnostics*/true, +#endif // CLANG_VERSION_MAJOR > 8 + *RemappedFiles.get(), /*RemappedFilesKeepOriginalName*/ true); } @@ -1057,16 +1080,18 @@ const Decl *Decl_getDefinition(const Decl *D, bool isReference) { case Decl::CXXDeductionGuide: case Decl::Import: case Decl::OMPThreadPrivate: +#if CLANG_VERSION_MAJOR > 8 case Decl::OMPAllocate: - case Decl::OMPDeclareReduction: case Decl::OMPDeclareMapper: + case Decl::Concept: +#endif // CLANG_VERSION_MAJOR > 8 + case Decl::OMPDeclareReduction: case Decl::OMPRequires: case Decl::ObjCTypeParam: case Decl::BuiltinTemplate: case Decl::PragmaComment: case Decl::PragmaDetectMismatch: case Decl::UsingPack: - case Decl::Concept: return D; // Declaration kinds that don't make any sense here, but are @@ -1651,9 +1676,11 @@ long long Type_getSizeOf(QualType QT, ASTContext *Context) { return CXTypeLayoutError_Dependent; if (!QT->isConstantSizeType()) return CXTypeLayoutError_NotConstantSize; +#if CLANG_VERSION_MAJOR > 8 if (const auto *Deduced = dyn_cast(QT)) if (Deduced->getDeducedType().isNull()) return CXTypeLayoutError_Undeduced; +#endif // CLANG_VERSION_MAJOR > 8 // [gcc extension] lib/AST/ExprConstant.cpp:1372 // HandleSizeof : {voidtype,functype} == 1 // not handled by ASTContext.cpp:1313 getTypeInfoImpl @@ -1675,9 +1702,11 @@ long long Type_getAlignOf(QualType QT, ASTContext *Context) { return CXTypeLayoutError_Incomplete; if (QT->isDependentType()) return CXTypeLayoutError_Dependent; +#if CLANG_VERSION_MAJOR > 8 if (const auto *Deduced = dyn_cast(QT)) if (Deduced->getDeducedType().isNull()) return CXTypeLayoutError_Undeduced; +#endif // CLANG_VERSION_MAJOR > 8 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1 // if (QT->isVoidType()) return 1; From 8d82749cec41d85beed5cb64fb9456d8ec97718d Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 2 Mar 2020 12:06:28 -0800 Subject: [PATCH 56/88] Build with Clang 7 --- src/clang/clang_interface.cpp | 14 +++++++++++--- src/clang/libclang_compat.cpp | 29 ++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index cef7f95209..0b81bc9dc9 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -488,11 +488,15 @@ bool CXXMethod_isStatic(const Decl *D) { bool CXXMethod_isConst(const Decl *D) { auto *Method = D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + if (!Method) + return false; #if CLANG_VERSION_MAJOR > 8 - return Method && Method->getMethodQualifiers().hasConst(); + return Method->getMethodQualifiers().hasConst(); +#elif CLANG_VERSION_MAJOR > 7 + return Method->getTypeQualifiers().hasConst(); #else - return Method && Method->getTypeQualifiers().hasConst(); -#endif // CLANG_VERSION_MAJOR > 8 + return Method->getTypeQualifiers() & Qualifiers::Const; +#endif // CLANG_VERSION_MAJOR } bool CXXMethod_isVirtual(const Decl *D) { @@ -622,8 +626,10 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { case Stmt::IntegerLiteralClass: return CXCursor_IntegerLiteral; +#if CLANG_VERSION_MAJOR > 7 case Stmt::FixedPointLiteralClass: return CXCursor_FixedPointLiteral; +#endif // CLANG_VERSION_MAJOR > 7 case Stmt::FloatingLiteralClass: return CXCursor_FloatingLiteral; @@ -637,8 +643,10 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { case Stmt::CharacterLiteralClass: return CXCursor_CharacterLiteral; +#if CLANG_VERSION_MAJOR > 7 case Stmt::ConstantExprClass: return Expr_getCXCursorKind(cast(&*E)->getSubExpr()); +#endif // CLANG_VERSION_MAJOR > 7 case Stmt::ParenExprClass: return CXCursor_ParenExpr; diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index ab8acc27be..327c11b1dc 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -180,7 +180,12 @@ CXTypeKind Type_kind(QualType T, ASTContext *Context) { // libclang checks for these builtin types specially and matches on things // that appear to be correct - if (Context->getLangOpts().ObjC) { +#if CLANG_VERSION_MAJOR > 7 + bool isObjc = Context->getLangOpts().ObjC; +#else + bool isObjc = Context->getLangOpts().ObjC1; +#endif // CLANG_VERSION_MAJOR + if (isObjc) { QualType UT = T.getUnqualifiedType(); if (Context->isObjCIdType(UT)) return CXType_ObjCId; @@ -203,9 +208,7 @@ CXTypeKind Type_kind(QualType T, ASTContext *Context) { TKCASE(Enum); TKCASE(Typedef); TKCASE(ObjCInterface); - TKCASE(ObjCObject); TKCASE(ObjCObjectPointer); - TKCASE(ObjCTypeParam); TKCASE(FunctionNoProto); TKCASE(FunctionProto); TKCASE(ConstantArray); @@ -217,7 +220,11 @@ CXTypeKind Type_kind(QualType T, ASTContext *Context) { TKCASE(Auto); TKCASE(Elaborated); TKCASE(Pipe); +#if CLANG_VERSION_MAJOR > 7 TKCASE(Attributed); + TKCASE(ObjCObject); + TKCASE(ObjCTypeParam); +#endif // CLANG_VERSION_MAJOR > 7 #if CLANG_VERSION_MAJOR > 8 TKCASE(ExtVector); #endif // CLANG_VERSION_MAJOR > 8 @@ -576,6 +583,7 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("attribute(dllexport)"); case CXCursor_DLLImport: return stringref("attribute(dllimport)"); +#if CLANG_VERSION_MAJOR > 7 case CXCursor_NSReturnsRetained: return stringref("attribute(ns_returns_retained)"); case CXCursor_NSReturnsNotRetained: @@ -612,6 +620,7 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("attribute(objc_boxable)"); case CXCursor_FlagEnum: return stringref("attribute(flag_enum)"); +#endif // CLANG_VERSION_MAJOR > 7 case CXCursor_PreprocessingDirective: return stringref("preprocessing directive"); case CXCursor_MacroDefinition: @@ -831,9 +840,7 @@ BindgenStringRef TypeKind_getSpelling(CXTypeKind K) { TKIND(Enum); TKIND(Typedef); TKIND(ObjCInterface); - TKIND(ObjCObject); TKIND(ObjCObjectPointer); - TKIND(ObjCTypeParam); TKIND(FunctionNoProto); TKIND(FunctionProto); TKIND(ConstantArray); @@ -845,7 +852,13 @@ BindgenStringRef TypeKind_getSpelling(CXTypeKind K) { TKIND(Auto); TKIND(Elaborated); TKIND(Pipe); +#if CLANG_VERSION_MAJOR > 7 TKIND(Attributed); + TKIND(ObjCObject); + TKIND(ObjCTypeParam); +#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) TKIND(Id); +#include "clang/Basic/OpenCLExtensionTypes.def" +#endif // CLANG_VERSION_MAJOR > 7 #if CLANG_VERSION_MAJOR > 8 TKIND(ExtVector); #endif // CLANG_VERSION_MAJOR > 8 @@ -887,6 +900,7 @@ CXCursorKind Attr_getCXCursorKind(const Attr *A) { case attr::Visibility: return CXCursor_VisibilityAttr; case attr::DLLExport: return CXCursor_DLLExport; case attr::DLLImport: return CXCursor_DLLImport; +#if CLANG_VERSION_MAJOR > 7 case attr::NSReturnsRetained: return CXCursor_NSReturnsRetained; case attr::NSReturnsNotRetained: return CXCursor_NSReturnsNotRetained; case attr::NSReturnsAutoreleased: return CXCursor_NSReturnsAutoreleased; @@ -905,6 +919,7 @@ CXCursorKind Attr_getCXCursorKind(const Attr *A) { case attr::ObjCRuntimeVisible: return CXCursor_ObjCRuntimeVisible; case attr::ObjCBoxable: return CXCursor_ObjCBoxable; case attr::FlagEnum: return CXCursor_FlagEnum; +#endif // CLANG_VERSION_MAJOR > 7 #if CLANG_VERSION_MAJOR > 8 case attr::Convergent: return CXCursor_ConvergentAttr; case attr::WarnUnused: return CXCursor_WarnUnusedAttr; @@ -1086,7 +1101,9 @@ const Decl *Decl_getDefinition(const Decl *D, bool isReference) { case Decl::Concept: #endif // CLANG_VERSION_MAJOR > 8 case Decl::OMPDeclareReduction: +#if CLANG_VERSION_MAJOR > 7 case Decl::OMPRequires: +#endif // CLANG_VERSION_MAJOR > 7 case Decl::ObjCTypeParam: case Decl::BuiltinTemplate: case Decl::PragmaComment: @@ -1824,7 +1841,9 @@ CXCallingConv Type_getFunctionTypeCallingConv(QualType T) { TCALLINGCONV(X86Pascal); TCALLINGCONV(X86RegCall); TCALLINGCONV(X86VectorCall); +#if CLANG_VERSION_MAJOR > 7 TCALLINGCONV(AArch64VectorCall); +#endif // CLANG_VERSION_MAJOR > 7 TCALLINGCONV(Win64); TCALLINGCONV(X86_64SysV); TCALLINGCONV(AAPCS); From 80fe522325a44e24d0892040353320b038a59281 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 2 Mar 2020 14:32:22 -0800 Subject: [PATCH 57/88] Build with Clang 6 --- src/clang/libclang_compat.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 327c11b1dc..15717b3aa0 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -141,12 +141,14 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { BTCASE(Float); BTCASE(Double); BTCASE(LongDouble); +#if CLANG_VERSION_MAJOR > 6 BTCASE(ShortAccum); BTCASE(Accum); BTCASE(LongAccum); BTCASE(UShortAccum); BTCASE(UAccum); BTCASE(ULongAccum); +#endif // CLANG_VERSION_MAJOR > 6 BTCASE(Float16); BTCASE(Float128); BTCASE(NullPtr); @@ -365,8 +367,10 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("VariableRef"); case CXCursor_IntegerLiteral: return stringref("IntegerLiteral"); +#if CLANG_VERSION_MAJOR > 6 case CXCursor_FixedPointLiteral: return stringref("FixedPointLiteral"); +#endif // CLANG_VERSION_MAJOR > 6 case CXCursor_FloatingLiteral: return stringref("FloatingLiteral"); case CXCursor_ImaginaryLiteral: @@ -817,12 +821,14 @@ BindgenStringRef TypeKind_getSpelling(CXTypeKind K) { TKIND(Float); TKIND(Double); TKIND(LongDouble); +#if CLANG_VERSION_MAJOR > 6 TKIND(ShortAccum); TKIND(Accum); TKIND(LongAccum); TKIND(UShortAccum); TKIND(UAccum); TKIND(ULongAccum); +#endif // CLANG_VERSION_MAJOR > 6 TKIND(Float16); TKIND(Float128); TKIND(NullPtr); @@ -1474,7 +1480,11 @@ SourceLocation *Expr_getLocation(const Expr *E) { if (const ObjCPropertyRefExpr *PropRef = dyn_cast(&*E)) return new SourceLocation(PropRef->getLocation()); +#if CLANG_VERSION_MAJOR > 6 return new SourceLocation(E->getBeginLoc()); +#else + return new SourceLocation(E->getLocStart()); +#endif } // Adapted from clang_getTypeDeclaration in CXType.cpp @@ -1548,9 +1558,13 @@ void tokenize(ASTUnit *TU, BindgenSourceRange Range, CXToken **Tokens, SourceLocation EndLoc = *Range.E; bool IsTokenRange = true; if (EndLoc.isValid() && EndLoc.isMacroID() && !SourceMgr.isMacroArgExpansion(EndLoc)) { +#if CLANG_VERSION_MAJOR > 6 CharSourceRange Expansion = SourceMgr.getExpansionRange(EndLoc); EndLoc = Expansion.getEnd(); IsTokenRange = Expansion.isTokenRange(); +#else + EndLoc = SourceMgr.getExpansionRange(EndLoc).second; +#endif } if (IsTokenRange && EndLoc.isValid()) { unsigned Length = Lexer::MeasureTokenLength(SourceMgr.getSpellingLoc(EndLoc), From 4e6809b4c8277baef6cf29fa76aaddd02f07a5b3 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 2 Mar 2020 14:35:25 -0800 Subject: [PATCH 58/88] Build with Clang 5 --- src/clang/clang_interface.cpp | 86 +++++++++++++++++++++++++++++++++++ src/clang/libclang_compat.cpp | 6 ++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index 0b81bc9dc9..7a62d5c7e4 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -923,12 +923,17 @@ class BindgenVisitor : public RecursiveASTVisitor { return false; } + void setParent(Node n) { + Parent = n; + } + bool TraverseDeclTyped(Decl *D, CXCursorKind kind) { if (!D || (D->isImplicit() && !isa(D))) return true; bool skip = !Parent; + // D->dump(); // libclang doesn't visit the CXXRecordDecl inside ClassTemplateDecl nodes if (Parent.kind == CXCursor_ClassTemplate && isa(D)) @@ -1195,6 +1200,8 @@ class BindgenVisitor : public RecursiveASTVisitor { return res; } +#if CLANG_VERSION_MAJOR > 5 + bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) { if (Parent) { switch (VisitFn(Node(&Base), Parent, &AST, Data)) { @@ -1214,6 +1221,79 @@ class BindgenVisitor : public RecursiveASTVisitor { return res; } +#else // CLANG_VERSION_MAJOR <= 5 + + // We need to visit the record decl instead of the base specifier here because + // clang <= 5 doesn't traverse CXXBaseSpecifiers + bool TraverseCXXRecordDecl(CXXRecordDecl *D) { + // D->dump(); + if (D && D->isCompleteDefinition()) { + bool recurse = false; + for (const auto &I : D->bases()) { + switch (VisitFn(Node(&I), Node(D, CXCursor_ClassDecl), &AST, Data)) { + case CXChildVisit_Break: + return false; + case CXChildVisit_Continue: + break; + case CXChildVisit_Recurse: + // Skip siblings and move on to other children of D + recurse = true; + break; + } + if (recurse) + break; + if (!TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc())) + return false; + } + } + + auto OldParent = Parent; + Parent = Node(D, CXCursor_ClassDecl); + bool res = RecursiveASTVisitor::TraverseCXXRecordDecl(D); + Parent = OldParent; + return res; + } + +#endif // CLANG_VERSION_MAJOR > 5 + +#if CLANG_VERSION_MAJOR < 6 + bool TraverseClassTemplateDecl(ClassTemplateDecl *D) { + auto params = D->getTemplateParameters(); + if (params) { + for (const auto &P : *params) { + if (!TraverseDecl(P)) + return false; + } + } + + return TraverseCXXRecordDecl(D->getTemplatedDecl()); + } + + bool TraverseVarTemplateDecl(VarTemplateDecl *D) { + auto params = D->getTemplateParameters(); + if (params) { + for (const auto &P : *params) { + if (!TraverseDecl(P)) + return false; + } + } + + return TraverseVarDecl(D->getTemplatedDecl()); + } + + bool TraverseFunctionTemplateDecl(FunctionTemplateDecl *D) { + auto params = D->getTemplateParameters(); + if (params) { + for (const auto &P : *params) { + if (!TraverseDecl(P)) + return false; + } + } + + return TraverseFunctionDecl(D->getTemplatedDecl()); + } +#endif // CLANG_VERSION_MAJOR < 6 + bool VisitAttr(Attr *A) { if (Parent) VisitFn(Node(A), Parent, &AST, Data); @@ -1364,7 +1444,13 @@ void CXXBaseSpecifier_visitChildren(const CXXBaseSpecifier *Parent, CXCursorKind kind, Visitor V, ASTUnit *Unit, CXClientData data) { BindgenVisitor visitor(*Unit, V, data); +#if CLANG_VERSION_MAJOR > 5 visitor.TraverseCXXBaseSpecifier(*Parent); +#else + // Clang <= 5 doesn't have RecursiveASTvisitor::TraverseCXXBaseSpecifier + visitor.setParent(Node(Parent)); + visitor.TraverseTypeLoc(Parent->getTypeSourceInfo()->getTypeLoc()); +#endif } void disposeTokens(const ASTUnit *TU, CXToken *Tokens, unsigned NumTokens) { diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 15717b3aa0..1c9b80c7d6 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -149,7 +149,9 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { BTCASE(UAccum); BTCASE(ULongAccum); #endif // CLANG_VERSION_MAJOR > 6 +#if CLANG_VERSION_MAJOR > 5 BTCASE(Float16); +#endif // CLANG_VERSION_MAJOR > 5 BTCASE(Float128); BTCASE(NullPtr); BTCASE(Overload); @@ -829,8 +831,9 @@ BindgenStringRef TypeKind_getSpelling(CXTypeKind K) { TKIND(UAccum); TKIND(ULongAccum); #endif // CLANG_VERSION_MAJOR > 6 +#if CLANG_VERSION_MAJOR > 5 TKIND(Float16); - TKIND(Float128); +#endif // CLANG_VERSION_MAJOR > 5 TKIND(NullPtr); TKIND(Overload); TKIND(Dependent); @@ -856,6 +859,7 @@ BindgenStringRef TypeKind_getSpelling(CXTypeKind K) { TKIND(Vector); TKIND(MemberPointer); TKIND(Auto); + TKIND(Float128); TKIND(Elaborated); TKIND(Pipe); #if CLANG_VERSION_MAJOR > 7 From d6d48c0171598962069e1bd9ad47cdcbdad46d75 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 2 Mar 2020 14:47:31 -0800 Subject: [PATCH 59/88] Build with Clang 4 --- build.rs | 25 +++++++++++++++++------- src/clang/clang_interface.cpp | 4 ++++ src/clang/libclang_compat.cpp | 36 ++++++++++++++++++++++++++++++----- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/build.rs b/build.rs index 94e5892bbd..48ad8aedaa 100644 --- a/build.rs +++ b/build.rs @@ -159,6 +159,9 @@ mod clang_ast { /// List of libs we need to link against pub libs: Vec, + + /// LLVM version in (major, minor) form, if available + pub version: Option<(i32, i32)>, } impl LLVMInfo { @@ -293,12 +296,17 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: "--link-shared" }; - let llvm_version = invoke_command(llvm_config.as_ref(), &["--version"]); - - let llvm_major_version = llvm_version + let version_string = invoke_command(llvm_config.as_ref(), &["--version"]) + .or_else(|| { + invoke_command(Some(&format!("{}/../bin/clang", lib_dir)), &["--version"]) + .and_then(|output| Some(output.split(" ").nth(2)?.to_string())) + }); + let version = version_string .and_then(|version| { - let major: i32 = version.split(".").next()?.parse().ok()?; - Some(major) + let mut split = version.split("."); + let major: i32 = split.next()?.parse().ok()?; + let minor: i32 = split.next()?.parse().ok()?; + Some((major, minor)) }); // LLVM components that we need to link against for the clang libs @@ -309,12 +317,14 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: "Option", "BitReader", "ProfileData", - "BinaryFormat", "Core", ]; // llvmAST requires FrontendOpenMP from version 10 and newer - if let Some(version) = llvm_major_version { + if let Some((version, _minor_version)) = version { + if version > 4 { + llvm_components.push("BinaryFormat"); + } if version > 9 { llvm_components.push("FrontendOpenMP"); } @@ -362,6 +372,7 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: Self { lib_dir, libs, + version, } } } diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index 7a62d5c7e4..b038b0423a 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -1631,7 +1631,11 @@ BindgenStringRef CXXBaseSpecifier_getSpelling(const CXXBaseSpecifier *B) { } SourceLocation *CXXBaseSpecifier_getLocation(const CXXBaseSpecifier *B) { +#if CLANG_VERSION_MAJOR > 4 return new SourceLocation(B->getBaseTypeLoc()); +#else // CLANG_VERSION_MAJOR <= 4 + return new SourceLocation(B->getLocStart()); +#endif } SourceLocation *Attr_getLocation(const Attr *A) { diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 1c9b80c7d6..5cb2448b66 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -137,7 +137,6 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { BTCASE(Long); BTCASE(LongLong); BTCASE(Int128); - BTCASE(Half); BTCASE(Float); BTCASE(Double); BTCASE(LongDouble); @@ -163,13 +162,16 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) BTCASE(Id); #include "clang/Basic/OpenCLExtensionTypes.def" #endif // CLANG_VERSION_MAJOR > 7 +#if CLANG_VERSION_MAJOR > 4 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) BTCASE(Id); #include "clang/Basic/OpenCLImageTypes.def" #undef IMAGE_TYPE + BTCASE(Half); BTCASE(OCLSampler); BTCASE(OCLEvent); BTCASE(OCLQueue); BTCASE(OCLReserveID); +#endif // CLANG_VERSION_MAJOR > 4 default: return CXType_Unexposed; } @@ -223,7 +225,9 @@ CXTypeKind Type_kind(QualType T, ASTContext *Context) { TKCASE(MemberPointer); TKCASE(Auto); TKCASE(Elaborated); +#if CLANG_VERSION_MAJOR > 4 TKCASE(Pipe); +#endif // CLANG_VERSION_MAJOR > 4 #if CLANG_VERSION_MAJOR > 7 TKCASE(Attributed); TKCASE(ObjCObject); @@ -872,15 +876,17 @@ BindgenStringRef TypeKind_getSpelling(CXTypeKind K) { #if CLANG_VERSION_MAJOR > 8 TKIND(ExtVector); #endif // CLANG_VERSION_MAJOR > 8 +#if CLANG_VERSION_MAJOR > 4 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id); #include "clang/Basic/OpenCLImageTypes.def" #undef IMAGE_TYPE -#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) TKIND(Id); -#include "clang/Basic/OpenCLExtensionTypes.def" + TKIND(Half); + TKIND(Pipe); TKIND(OCLSampler); TKIND(OCLEvent); TKIND(OCLQueue); TKIND(OCLReserveID); +#endif // CLANG_VERSION_MAJOR > 4 } #undef TKIND return stringref(s); @@ -1019,9 +1025,11 @@ ASTUnit *parseTranslationUnit(const char *source_filename, if (options & CXTranslationUnit_KeepGoing) { #if CLANG_VERSION_MAJOR > 8 Diags->setFatalsAsError(true); -#else +#elif CLANG_VERSION_MAJOR > 4 Diags->setSuppressAfterFatalError(false); -#endif // CLANG_VERSION_MAJOR > 8 +#else // CLANG_VERSION_MAJOR <= 4 + Diags->setFatalsAsError(true); +#endif } #if CLANG_VERSION_MAJOR > 8 @@ -1102,7 +1110,9 @@ const Decl *Decl_getDefinition(const Decl *D, bool isReference) { case Decl::OMPCapturedExpr: case Decl::Label: // FIXME: Is this right?? case Decl::ClassScopeFunctionSpecialization: +#if CLANG_VERSION_MAJOR > 4 case Decl::CXXDeductionGuide: +#endif // CLANG_VERSION_MAJOR > 4 case Decl::Import: case Decl::OMPThreadPrivate: #if CLANG_VERSION_MAJOR > 8 @@ -1396,12 +1406,16 @@ CXLinkageKind Decl_getLinkage(const Decl *D) { case NoLinkage: case VisibleNoLinkage: return CXLinkage_NoLinkage; +#if CLANG_VERSION_MAJOR > 4 case ModuleInternalLinkage: +#endif // CLANG_VERSION_MAJOR > 4 case InternalLinkage: return CXLinkage_Internal; case UniqueExternalLinkage: return CXLinkage_UniqueExternal; +#if CLANG_VERSION_MAJOR > 4 case ModuleLinkage: +#endif // CLANG_VERSION_MAJOR > 4 case ExternalLinkage: return CXLinkage_External; }; @@ -1524,8 +1538,12 @@ const Decl *Type_getDeclaration(QualType T) { break; case Type::Auto: +#if CLANG_VERSION_MAJOR > 4 case Type::DeducedTemplateSpecialization: TP = cast(TP)->getDeducedType().getTypePtrOrNull(); +#else // CLANG_VERSION_MAJOR <= 4 + TP = cast(TP)->getDeducedType().getTypePtrOrNull(); +#endif // CLANG_VERSION_MAJOR > 4 if (TP) goto try_again; break; @@ -1774,8 +1792,12 @@ QualType Type_getPointeeType(QualType T) { T = cast(TP)->getPointeeType(); break; case Type::Auto: +#if CLANG_VERSION_MAJOR > 4 case Type::DeducedTemplateSpecialization: TP = cast(TP)->getDeducedType().getTypePtrOrNull(); +#else // CLANG_VERSION_MAJOR <= 4 + TP = cast(TP)->getDeducedType().getTypePtrOrNull(); +#endif // CLANG_VERSION_MAJOR > 4 if (TP) goto try_again; break; @@ -1862,7 +1884,11 @@ CXCallingConv Type_getFunctionTypeCallingConv(QualType T) { #if CLANG_VERSION_MAJOR > 7 TCALLINGCONV(AArch64VectorCall); #endif // CLANG_VERSION_MAJOR > 7 +#if CLANG_VERSION_MAJOR > 4 TCALLINGCONV(Win64); +#else + TCALLINGCONV(X86_64Win64); +#endif // CLANG_VERSION_MAJOR > 4 TCALLINGCONV(X86_64SysV); TCALLINGCONV(AAPCS); TCALLINGCONV(AAPCS_VFP); From 2c1444ddeff54332381418683418338f76c951dc Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 2 Mar 2020 14:53:56 -0800 Subject: [PATCH 60/88] Move getMangling functions to libclang_compat.cpp --- src/clang/clang_interface.cpp | 25 -------------- src/clang/clang_interface_impl.hpp | 1 + src/clang/libclang_compat.cpp | 53 ++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index b038b0423a..046636a221 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -304,31 +304,6 @@ BindgenStringRef Decl_getUSR(const Decl *D) { return stringref(Buf.str()); } -BindgenStringRef Decl_getMangling(const Decl *D, ASTContext *Ctx) { - if (!D || !(isa(&*D) || isa(&*D))) - return stringref(); - -#if CLANG_VERSION_MAJOR > 8 - ASTNameGenerator NameGen(*Ctx); -#else - index::CodegenNameGenerator NameGen(*Ctx); -#endif // CLANG_VERSION_MAJOR > 8 - return stringref(NameGen.getName(&*D)); -} - -BindgenStringRefSet Decl_getCXXManglings(const Decl *D, ASTContext *Ctx) { - if (!D || !(isa(&*D) || isa(&*D))) - return BindgenStringRefSet(); - -#if CLANG_VERSION_MAJOR > 8 - ASTNameGenerator NameGen(*Ctx); -#else - index::CodegenNameGenerator NameGen(*Ctx); -#endif // CLANG_VERSION_MAJOR > 8 - std::vector Manglings = NameGen.getAllManglings(&*D); - return make_stringrefset(Manglings); -} - CXCursorKind Decl_getCXCursorKind(const Decl *D) { if (!D) return CXCursor_NoDeclFound; diff --git a/src/clang/clang_interface_impl.hpp b/src/clang/clang_interface_impl.hpp index 05fbbb3df0..60f4798673 100644 --- a/src/clang/clang_interface_impl.hpp +++ b/src/clang/clang_interface_impl.hpp @@ -14,6 +14,7 @@ BindgenStringRef stringref(); BindgenStringRef stringref(const char *newStr); BindgenStringRef stringref(const std::string &s); BindgenStringRef stringref(llvm::StringRef S); +BindgenStringRefSet make_stringrefset(std::vector &string_vec); QualType make_type_compatible(QualType QT); // Functions defined in libclang_compat.cpp diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 5cb2448b66..8c6f1409ef 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -1930,3 +1930,56 @@ void getSpellingLocation(ASTUnit *AST, const SourceLocation *location, FileEntry if (offset) *offset = FileOffset; } + +// From CIndex.cpp +static std::string getMangledStructor(std::unique_ptr &M, + std::unique_ptr &DL, + const NamedDecl *ND, + unsigned StructorType) { + std::string FrontendBuf; + llvm::raw_string_ostream FOS(FrontendBuf); + + if (const auto *CD = dyn_cast_or_null(ND)) + M->mangleCXXCtor(CD, static_cast(StructorType), FOS); + else if (const auto *DD = dyn_cast_or_null(ND)) + M->mangleCXXDtor(DD, static_cast(StructorType), FOS); + + std::string BackendBuf; + llvm::raw_string_ostream BOS(BackendBuf); + + llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL); + + return BOS.str(); +} + +// Adapted from clang_Cursor_getMangling in CIndex.cpp +BindgenStringRef Decl_getMangling(const Decl *D, ASTContext *Ctx) { + if (!D || !(isa(&*D) || isa(&*D))) + return stringref(); + +#if CLANG_VERSION_MAJOR > 8 + ASTNameGenerator NameGen(*Ctx); + return stringref(NameGen.getName(&*D)); +#else // CLANG_VERSION_MAJOR <= 8 + index::CodegenNameGenerator NameGen(*Ctx); + return stringref(NameGen.getName(&*D)); +#endif // CLANG_VERSION_MAJOR > 8 +} + +// Adapted from clang_Cursor_getCXXManglings in CIndex.cpp +BindgenStringRefSet Decl_getCXXManglings(const Decl *D, ASTContext *Ctx) { + if (!D || !(isa(&*D) || isa(&*D))) + return BindgenStringRefSet(); + + std::vector Manglings; + +#if CLANG_VERSION_MAJOR > 8 + ASTNameGenerator NameGen(*Ctx); + Manglings = NameGen.getAllManglings(&*D); +#else // CLANG_VERSION_MAJOR <= 8 + index::CodegenNameGenerator NameGen(*Ctx); + Manglings = NameGen.getAllManglings(&*D); +#endif // CLANG_VERSION_MAJOR > 8 + + return make_stringrefset(Manglings); +} From 7df04f4e5f252a7642381a5f67b2139e7448eef6 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 2 Mar 2020 14:59:40 -0800 Subject: [PATCH 61/88] Build with Clang 3.9 --- src/clang/clang_interface.cpp | 12 +++++++++++- src/clang/libclang_compat.cpp | 18 +++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index 046636a221..f959307aea 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -95,7 +95,8 @@ const TargetInfo *ASTUnit_getTargetInfo(ASTUnit *Unit) { int TargetInfo_getPointerWidth(const TargetInfo *TI) { if (!TI) return -1; - return TI->getMaxPointerWidth(); + // Address space 0 is the normal address space for all platforms + return TI->getPointerWidth(0); } BindgenStringRef TargetInfo_getTriple(const TargetInfo *TI) { @@ -170,8 +171,13 @@ double EvalResult_getAsDouble(EvalResult *ER) { return 0; auto apFloat = ER->Val.getFloat(); bool ignored; +#if CLANG_VERSION_MAJOR > 3 apFloat.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven, &ignored); +#else // CLANG_VERSION_MAJOR <= 3.9 + apFloat.convert(llvm::APFloat::IEEEdouble, + llvm::APFloat::rmNearestTiesToEven, &ignored); +#endif return apFloat.convertToDouble(); } @@ -849,6 +855,7 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { return CXCursor_OMPDistributeSimdDirective; case Stmt::OMPTargetParallelForSimdDirectiveClass: return CXCursor_OMPTargetParallelForSimdDirective; +#if CLANG_VERSION_MAJOR > 3 case Stmt::OMPTargetSimdDirectiveClass: return CXCursor_OMPTargetSimdDirective; case Stmt::OMPTeamsDistributeDirectiveClass: @@ -869,6 +876,7 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { return CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective; case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: return CXCursor_OMPTargetTeamsDistributeSimdDirective; +#endif // CLANG_VERSION_MAJOR > 3 #if CLANG_VERSION_MAJOR > 8 case Stmt::BuiltinBitCastExprClass: return CXCursor_BuiltinBitCastExpr; @@ -1100,6 +1108,7 @@ class BindgenVisitor : public RecursiveASTVisitor { return TraverseDeclTyped(TL.getIFaceDecl(), CXCursor_ObjCClassRef); } +#if CLANG_VERSION_MAJOR > 3 bool VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) { if (!TL) return true; @@ -1113,6 +1122,7 @@ class BindgenVisitor : public RecursiveASTVisitor { } return true; } +#endif // CLANG_VERSION_MAJOR > 3 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { if (!TL) diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 8c6f1409ef..7ed9b4922a 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -753,6 +753,7 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("OMPDistributeSimdDirective"); case CXCursor_OMPTargetParallelForSimdDirective: return stringref("OMPTargetParallelForSimdDirective"); +#if CLANG_VERSION_MAJOR > 3 case CXCursor_OMPTargetSimdDirective: return stringref("OMPTargetSimdDirective"); case CXCursor_OMPTeamsDistributeDirective: @@ -774,14 +775,15 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { "OMPTargetTeamsDistributeParallelForSimdDirective"); case CXCursor_OMPTargetTeamsDistributeSimdDirective: return stringref("OMPTargetTeamsDistributeSimdDirective"); + case CXCursor_FriendDecl: + return stringref("FriendDecl"); +#endif // CLANG_VERSION_MAJOR > 3 case CXCursor_OverloadCandidate: return stringref("OverloadCandidate"); case CXCursor_TypeAliasTemplateDecl: return stringref("TypeAliasTemplateDecl"); case CXCursor_StaticAssert: return stringref("StaticAssert"); - case CXCursor_FriendDecl: - return stringref("FriendDecl"); #if CLANG_VERSION_MAJOR > 8 case CXCursor_ConvergentAttr: return stringref("attribute(convergent)"); @@ -1110,6 +1112,11 @@ const Decl *Decl_getDefinition(const Decl *D, bool isReference) { case Decl::OMPCapturedExpr: case Decl::Label: // FIXME: Is this right?? case Decl::ClassScopeFunctionSpecialization: +#if CLANG_VERSION_MAJOR > 3 + case Decl::Binding: + case Decl::Export: + case Decl::UsingPack: +#endif // CLANG_VERSION_MAJOR > 3 #if CLANG_VERSION_MAJOR > 4 case Decl::CXXDeductionGuide: #endif // CLANG_VERSION_MAJOR > 4 @@ -1172,7 +1179,10 @@ const Decl *Decl_getDefinition(const Decl *D, bool isReference) { case Decl::Var: case Decl::VarTemplateSpecialization: case Decl::VarTemplatePartialSpecialization: - case Decl::Decomposition: { +#if CLANG_VERSION_MAJOR > 3 + case Decl::Decomposition: +#endif // CLANG_VERSION_MAJOR > 3 + { // Ask the variable if it has a definition. if (const VarDecl *Def = cast(&*D)->getDefinition()) return Def; @@ -1879,7 +1889,9 @@ CXCallingConv Type_getFunctionTypeCallingConv(QualType T) { TCALLINGCONV(X86FastCall); TCALLINGCONV(X86ThisCall); TCALLINGCONV(X86Pascal); +#if CLANG_VERSION_MAJOR > 3 TCALLINGCONV(X86RegCall); +#endif // CLANG_VERSION_MAJOR > 3 TCALLINGCONV(X86VectorCall); #if CLANG_VERSION_MAJOR > 7 TCALLINGCONV(AArch64VectorCall); From bc57ed19d8141a2f987d39776cc69f6f8f5a9587 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 2 Mar 2020 15:02:03 -0800 Subject: [PATCH 62/88] Build with Clang 3.8 --- build.rs | 104 ++++++++++++++++++++------------- src/clang/clang_interface.cpp | 20 +++++-- src/clang/clang_interface.hpp | 18 +++++- src/clang/libclang_compat.cpp | 106 ++++++++++++++++++++++++++++++---- 4 files changed, 192 insertions(+), 56 deletions(-) diff --git a/build.rs b/build.rs index 48ad8aedaa..bbee9641d6 100644 --- a/build.rs +++ b/build.rs @@ -95,6 +95,17 @@ mod clang_ast { fn build_native(llvm_info: &LLVMInfo) { // Find where the (already built) LLVM lib dir is let llvm_lib_dir = &llvm_info.lib_dir; + let mut llvm_cmake_dir = format!("{}/cmake/llvm", llvm_lib_dir); + let mut clang_cmake_dir = format!("{}/cmake/clang", llvm_lib_dir); + + if let Some((major_version, minor_version)) = llvm_info.version { + if (major_version == 3 && minor_version <= 8) + || major_version < 3 + { + llvm_cmake_dir = format!("{}/../share/llvm/cmake", llvm_lib_dir); + clang_cmake_dir = format!("{}/../share/clang/cmake", llvm_lib_dir); + } + } println!("cargo:rerun-if-changed=src/clang/clang_interface.hpp"); println!("cargo:rerun-if-changed=src/clang/clang_interface_impl.hpp"); @@ -102,8 +113,8 @@ mod clang_ast { println!("cargo:rerun-if-changed=src/clang/libclang_compat.cpp"); // Build libBindgenClangInterface.a with cmake let dst = cmake::Config::new("src/clang") - .define("LLVM_DIR", &format!("{}/cmake/llvm", llvm_lib_dir)) - .define("Clang_DIR", &format!("{}/cmake/clang", llvm_lib_dir)) + .define("LLVM_DIR", &llvm_cmake_dir) + .define("Clang_DIR", &clang_cmake_dir) .build_target("BindgenClangInterface") .build(); @@ -170,37 +181,41 @@ mod clang_ast { // Explicitly provided path in LLVM_CONFIG_PATH build_var("LLVM_CONFIG_PATH") // Relative to LLVM_LIB_DIR - .or(build_var("LLVM_LIB_DIR").map(|d| { - String::from( - Path::new(&d) - .join("../bin/llvm-config") - .canonicalize() - .unwrap() - .to_string_lossy(), - ) - })) + .or_else(|| { + build_var("LLVM_LIB_DIR").map(|d| { + String::from( + Path::new(&d) + .join("../bin/llvm-config") + .canonicalize() + .unwrap() + .to_string_lossy(), + ) + }) + }) // In PATH - .or([ - "llvm-config-7.0", - "llvm-config-6.1", - "llvm-config-6.0", - "llvm-config", - // Homebrew install location on MacOS - "/usr/local/opt/llvm/bin/llvm-config", - ] - .iter() - .find_map(|c| { - if Command::new(c) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .spawn() - .is_ok() - { - Some(String::from(*c)) - } else { - None - } - })) + .or_else(|| { + [ + "llvm-config-7.0", + "llvm-config-6.1", + "llvm-config-6.0", + "llvm-config", + // Homebrew install location on MacOS + "/usr/local/opt/llvm/bin/llvm-config", + ] + .iter() + .find_map(|c| { + if Command::new(c) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn() + .is_ok() + { + Some(String::from(*c)) + } else { + None + } + }) + }) } /// Invoke given `command`, if any, with the specified arguments. @@ -309,6 +324,13 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: Some((major, minor)) }); + let mut supports_link_mode = true; + if let Some((major_version, minor_version)) = version { + if major_version < 3 || (major_version == 3 && minor_version <= 8) { + supports_link_mode = false; + } + } + // LLVM components that we need to link against for the clang libs let mut llvm_components = vec![ "MC", @@ -333,7 +355,9 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: // Construct the list of libs we need to link against let mut args = llvm_components; args.insert(0, "--libs"); - args.insert(1, link_mode); + if supports_link_mode { + args.insert(1, link_mode); + } let mut libs: Vec = invoke_command(llvm_config.as_ref(), &args) .unwrap_or("-lLLVM".to_string()) .split_whitespace() @@ -342,13 +366,13 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: libs.extend( build_var("LLVM_SYSTEM_LIBS") - .or(invoke_command( - llvm_config.as_ref(), - &[ - "--system-libs", - link_mode, - ], - )) + .or_else(|| { + let mut args = vec!["--system-libs"]; + if supports_link_mode { + args.push(link_mode); + } + invoke_command(llvm_config.as_ref(), args) + }) .unwrap_or(String::new()) .split_whitespace() .map(|lib| { diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index f959307aea..a9cbbfac89 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -321,7 +321,7 @@ bool Decl_isDefinition(const Decl *D) { if (auto VD = dyn_cast_or_null(&*D)) return VD->getDefinition() == &*D; if (auto FD = dyn_cast_or_null(&*D)) - return FD->getDefinition() == &*D; + return FD->isThisDeclarationADefinition(); if (auto TD = dyn_cast_or_null(&*D)) return TD->getDefinition() == &*D; @@ -726,8 +726,10 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { case Stmt::ObjCBoolLiteralExprClass: return CXCursor_ObjCBoolLiteralExpr; +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) case Stmt::ObjCAvailabilityCheckExprClass: return CXCursor_ObjCAvailabilityCheckExpr; +#endif // CLANG_VERSION > 3.8 case Stmt::ObjCBridgedCastExprClass: return CXCursor_ObjCBridgedCastExpr; @@ -767,7 +769,9 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { case Stmt::CXXMemberCallExprClass: case Stmt::CUDAKernelCallExprClass: case Stmt::CXXConstructExprClass: - case Stmt::CXXInheritedCtorInitExprClass: +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) + case Stmt::CXXInheritedCtorInitExprClass: +#endif // CLANG_VERSION > 3.8 case Stmt::CXXTemporaryObjectExprClass: case Stmt::CXXUnresolvedConstructExprClass: case Stmt::UserDefinedLiteralClass: @@ -823,6 +827,7 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { return CXCursor_OMPAtomicDirective; case Stmt::OMPTargetDirectiveClass: return CXCursor_OMPTargetDirective; +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) case Stmt::OMPTargetDataDirectiveClass: return CXCursor_OMPTargetDataDirective; case Stmt::OMPTargetEnterDataDirectiveClass: @@ -835,6 +840,7 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { return CXCursor_OMPTargetParallelForDirective; case Stmt::OMPTargetUpdateDirectiveClass: return CXCursor_OMPTargetUpdateDirective; +#endif // CLANG_VERSION > 3.8 case Stmt::OMPTeamsDirectiveClass: return CXCursor_OMPTeamsDirective; case Stmt::OMPCancellationPointDirectiveClass: @@ -847,6 +853,7 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { return CXCursor_OMPTaskLoopSimdDirective; case Stmt::OMPDistributeDirectiveClass: return CXCursor_OMPDistributeDirective; +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) case Stmt::OMPDistributeParallelForDirectiveClass: return CXCursor_OMPDistributeParallelForDirective; case Stmt::OMPDistributeParallelForSimdDirectiveClass: @@ -855,6 +862,7 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { return CXCursor_OMPDistributeSimdDirective; case Stmt::OMPTargetParallelForSimdDirectiveClass: return CXCursor_OMPTargetParallelForSimdDirective; +#endif // CLANG_VERSION > 3.8 #if CLANG_VERSION_MAJOR > 3 case Stmt::OMPTargetSimdDirectiveClass: return CXCursor_OMPTargetSimdDirective; @@ -1361,8 +1369,12 @@ class BindgenVisitor : public RecursiveASTVisitor { return true; IdentifierInfo *PropertyId = PD->getIdentifier(); - ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl( - cast(ID), PropertyId, PD->getQueryKind()); + ObjCPropertyDecl *prevDecl = +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) + ObjCPropertyDecl::findPropertyDecl(cast(ID), PropertyId, PD->getQueryKind()); +#else // CLANG_VERSION <= 3.8 + ObjCPropertyDecl::findPropertyDecl(cast(ID), PropertyId); +#endif if (!prevDecl) return true; diff --git a/src/clang/clang_interface.hpp b/src/clang/clang_interface.hpp index d627cae0dd..d3f05a61c9 100644 --- a/src/clang/clang_interface.hpp +++ b/src/clang/clang_interface.hpp @@ -29,7 +29,23 @@ struct PreprocessedEntity; namespace comments { struct Comment; struct FullComment; -} +} // namespace comments + +#if CLANG_VERSION_MAJOR < 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR <= 8) +// Clang <= 3.8 doesn't include this enum, but we can still expose the same +// functionality +typedef enum { + CXEval_Int = 1 , + CXEval_Float = 2, + CXEval_ObjCStrLiteral = 3, + CXEval_StrLiteral = 4, + CXEval_CFStr = 5, + CXEval_Other = 6, + + CXEval_UnExposed = 0 + +} CXEvalResultKind ; +#endif } // namespace clang diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 7ed9b4922a..803310b920 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -17,6 +17,11 @@ #include "clang/Frontend/CompilerInvocation.h" #include "clang-c/Documentation.h" #include "clang-c/Index.h" +#if CLANG_VERSION_MAJOR <= 8 && \ + (CLANG_VERSION_MAJOR > 3 || \ + CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR > 8) +#include "clang/Index/CodegenNameGenerator.h" +#endif // CLANG_VERSION_MAJOR <= 8 #include "clang_interface_impl.hpp" @@ -54,10 +59,12 @@ const Decl *getDeclFromExpr(const Stmt *E) { return getDeclFromExpr(CE->getCallee()); if (const CXXConstructExpr *CE = dyn_cast(E)) if (!CE->isElidable()) - return CE->getConstructor(); + return CE->getConstructor(); +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) if (const CXXInheritedCtorInitExpr *CE = dyn_cast(E)) return CE->getConstructor(); +#endif // CLANG_VERSION > 3.8 if (const ObjCMessageExpr *OME = dyn_cast(E)) return OME->getMethodDecl(); @@ -151,7 +158,9 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { #if CLANG_VERSION_MAJOR > 5 BTCASE(Float16); #endif // CLANG_VERSION_MAJOR > 5 +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) BTCASE(Float128); +#endif BTCASE(NullPtr); BTCASE(Overload); BTCASE(Dependent); @@ -224,7 +233,9 @@ CXTypeKind Type_kind(QualType T, ASTContext *Context) { TKCASE(Vector); TKCASE(MemberPointer); TKCASE(Auto); +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) TKCASE(Elaborated); +#endif // CLANG_VERSION > 3.8 #if CLANG_VERSION_MAJOR > 4 TKCASE(Pipe); #endif // CLANG_VERSION_MAJOR > 4 @@ -246,8 +257,10 @@ CXTypeKind Type_kind(QualType T, ASTContext *Context) { Optional> GetTemplateArguments(QualType Type) { assert(!Type.isNull()); +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) if (const auto *Specialization = Type->getAs()) return Specialization->template_arguments(); +#endif if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) { const auto *TemplateDecl = @@ -443,8 +456,10 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("ObjCStringLiteral"); case CXCursor_ObjCBoolLiteralExpr: return stringref("ObjCBoolLiteralExpr"); +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) case CXCursor_ObjCAvailabilityCheckExpr: return stringref("ObjCAvailabilityCheckExpr"); +#endif case CXCursor_ObjCSelfExpr: return stringref("ObjCSelfExpr"); case CXCursor_ObjCEncodeExpr: @@ -723,6 +738,7 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("OMPTargetDirective"); case CXCursor_OMPTargetDataDirective: return stringref("OMPTargetDataDirective"); +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) case CXCursor_OMPTargetEnterDataDirective: return stringref("OMPTargetEnterDataDirective"); case CXCursor_OMPTargetExitDataDirective: @@ -733,6 +749,7 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("OMPTargetParallelForDirective"); case CXCursor_OMPTargetUpdateDirective: return stringref("OMPTargetUpdateDirective"); +#endif case CXCursor_OMPTeamsDirective: return stringref("OMPTeamsDirective"); case CXCursor_OMPCancellationPointDirective: @@ -745,6 +762,7 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("OMPTaskLoopSimdDirective"); case CXCursor_OMPDistributeDirective: return stringref("OMPDistributeDirective"); +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) case CXCursor_OMPDistributeParallelForDirective: return stringref("OMPDistributeParallelForDirective"); case CXCursor_OMPDistributeParallelForSimdDirective: @@ -753,6 +771,7 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("OMPDistributeSimdDirective"); case CXCursor_OMPTargetParallelForSimdDirective: return stringref("OMPTargetParallelForSimdDirective"); +#endif #if CLANG_VERSION_MAJOR > 3 case CXCursor_OMPTargetSimdDirective: return stringref("OMPTargetSimdDirective"); @@ -782,8 +801,10 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind Kind) { return stringref("OverloadCandidate"); case CXCursor_TypeAliasTemplateDecl: return stringref("TypeAliasTemplateDecl"); +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) case CXCursor_StaticAssert: return stringref("StaticAssert"); +#endif #if CLANG_VERSION_MAJOR > 8 case CXCursor_ConvergentAttr: return stringref("attribute(convergent)"); @@ -825,7 +846,6 @@ BindgenStringRef TypeKind_getSpelling(CXTypeKind K) { TKIND(Long); TKIND(LongLong); TKIND(Int128); - TKIND(Half); TKIND(Float); TKIND(Double); TKIND(LongDouble); @@ -865,9 +885,10 @@ BindgenStringRef TypeKind_getSpelling(CXTypeKind K) { TKIND(Vector); TKIND(MemberPointer); TKIND(Auto); +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) TKIND(Float128); TKIND(Elaborated); - TKIND(Pipe); +#endif #if CLANG_VERSION_MAJOR > 7 TKIND(Attributed); TKIND(ObjCObject); @@ -1024,6 +1045,7 @@ ASTUnit *parseTranslationUnit(const char *source_filename, IntrusiveRefCntPtr Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) if (options & CXTranslationUnit_KeepGoing) { #if CLANG_VERSION_MAJOR > 8 Diags->setFatalsAsError(true); @@ -1033,6 +1055,7 @@ ASTUnit *parseTranslationUnit(const char *source_filename, Diags->setFatalsAsError(true); #endif } +#endif // CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) #if CLANG_VERSION_MAJOR > 8 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All; @@ -1090,7 +1113,6 @@ const Decl *Decl_getDefinition(const Decl *D, bool isReference) { case Decl::TemplateTypeParm: case Decl::EnumConstant: case Decl::Field: - case Decl::Binding: case Decl::MSProperty: case Decl::IndirectField: case Decl::ObjCIvar: @@ -1103,13 +1125,11 @@ const Decl *Decl_getDefinition(const Decl *D, bool isReference) { case Decl::ObjCImplementation: case Decl::AccessSpec: case Decl::LinkageSpec: - case Decl::Export: case Decl::ObjCPropertyImpl: case Decl::FileScopeAsm: case Decl::StaticAssert: case Decl::Block: case Decl::Captured: - case Decl::OMPCapturedExpr: case Decl::Label: // FIXME: Is this right?? case Decl::ClassScopeFunctionSpecialization: #if CLANG_VERSION_MAJOR > 3 @@ -1127,15 +1147,17 @@ const Decl *Decl_getDefinition(const Decl *D, bool isReference) { case Decl::OMPDeclareMapper: case Decl::Concept: #endif // CLANG_VERSION_MAJOR > 8 - case Decl::OMPDeclareReduction: #if CLANG_VERSION_MAJOR > 7 case Decl::OMPRequires: #endif // CLANG_VERSION_MAJOR > 7 case Decl::ObjCTypeParam: case Decl::BuiltinTemplate: +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) + case Decl::OMPCapturedExpr: + case Decl::OMPDeclareReduction: case Decl::PragmaComment: case Decl::PragmaDetectMismatch: - case Decl::UsingPack: +#endif // CLANG_VERSION > 3.8 return D; // Declaration kinds that don't make any sense here, but are @@ -1214,7 +1236,9 @@ const Decl *Decl_getDefinition(const Decl *D, bool isReference) { return cast(&*D); case Decl::UsingShadow: +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) case Decl::ConstructorUsingShadow: +#endif // CLANG_VERSION > 3.8 return Decl_getDefinition( cast(&*D)->getTargetDecl(), isReference); @@ -1905,11 +1929,15 @@ CXCallingConv Type_getFunctionTypeCallingConv(QualType T) { TCALLINGCONV(AAPCS); TCALLINGCONV(AAPCS_VFP); TCALLINGCONV(IntelOclBicc); +#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) TCALLINGCONV(Swift); TCALLINGCONV(PreserveMost); TCALLINGCONV(PreserveAll); - case CC_SpirFunction: return CXCallingConv_Unexposed; case CC_OpenCLKernel: return CXCallingConv_Unexposed; +#else // CLANG_VERSION <= 3.8 + case CC_SpirKernel: return CXCallingConv_Unexposed; +#endif // CLANG_VERSION > 3.8 + case CC_SpirFunction: return CXCallingConv_Unexposed; break; } #undef TCALLINGCONV @@ -1972,9 +2000,31 @@ BindgenStringRef Decl_getMangling(const Decl *D, ASTContext *Ctx) { #if CLANG_VERSION_MAJOR > 8 ASTNameGenerator NameGen(*Ctx); return stringref(NameGen.getName(&*D)); -#else // CLANG_VERSION_MAJOR <= 8 +#elif CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) index::CodegenNameGenerator NameGen(*Ctx); return stringref(NameGen.getName(&*D)); +#else // CLANG_VERSION <= 3.8 + // First apply frontend mangling. + const NamedDecl *ND = cast(D); + std::unique_ptr MC(Ctx->createMangleContext()); + + std::string FrontendBuf; + llvm::raw_string_ostream FrontendBufOS(FrontendBuf); + if (MC->shouldMangleDeclName(ND)) { + MC->mangleName(ND, FrontendBufOS); + } else { + ND->printName(FrontendBufOS); + } + + // Now apply backend mangling. + std::unique_ptr DL( + new llvm::DataLayout(Ctx->getTargetInfo().getDataLayoutString())); + + std::string FinalBuf; + llvm::raw_string_ostream FinalBufOS(FinalBuf); + llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()), + *DL); + return stringref(FinalBuf); #endif // CLANG_VERSION_MAJOR > 8 } @@ -1988,9 +2038,43 @@ BindgenStringRefSet Decl_getCXXManglings(const Decl *D, ASTContext *Ctx) { #if CLANG_VERSION_MAJOR > 8 ASTNameGenerator NameGen(*Ctx); Manglings = NameGen.getAllManglings(&*D); -#else // CLANG_VERSION_MAJOR <= 8 +#elif CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) index::CodegenNameGenerator NameGen(*Ctx); Manglings = NameGen.getAllManglings(&*D); +#else // CLANG_VERSION <= 3.8 + const NamedDecl *ND = cast(D); + + std::unique_ptr M(Ctx->createMangleContext()); + std::unique_ptr DL( + new llvm::DataLayout(Ctx->getTargetInfo().getDataLayoutString())); + + auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) { + auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false, + /*IsCSSMethod=*/true); + auto CC = MD->getType()->getAs()->getCallConv(); + return CC == DefaultCC; + }; + + if (const auto *CD = dyn_cast_or_null(ND)) { + Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base)); + + if (Ctx->getTargetInfo().getCXXABI().isItaniumFamily()) + if (!CD->getParent()->isAbstract()) + Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete)); + + if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) + if (CD->hasAttr() && CD->isDefaultConstructor()) + if (!(hasDefaultCXXMethodCC(*Ctx, CD) && CD->getNumParams() == 0)) + Manglings.emplace_back(getMangledStructor(M, DL, CD, + Ctor_DefaultClosure)); + } else if (const auto *DD = dyn_cast_or_null(ND)) { + Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base)); + if (Ctx->getTargetInfo().getCXXABI().isItaniumFamily()) { + Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete)); + if (DD->isVirtual()) + Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting)); + } + } #endif // CLANG_VERSION_MAJOR > 8 return make_stringrefset(Manglings); From 4e3c5dd2744c1ab22cd4fbb94e1abb5d823ddf78 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 2 Mar 2020 15:08:46 -0800 Subject: [PATCH 63/88] Include correct headers compatible with all Clang versions --- src/clang/clang_interface.cpp | 3 ++- src/clang/clang_interface.hpp | 1 + src/clang/libclang_compat.cpp | 8 ++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index a9cbbfac89..6058b711e9 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -8,12 +8,13 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" -#include "clang/AST/Mangle.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Index/USRGeneration.h" +#include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" #include "clang-c/Documentation.h" #include "clang-c/Index.h" diff --git a/src/clang/clang_interface.hpp b/src/clang/clang_interface.hpp index d3f05a61c9..4c75b9eed6 100644 --- a/src/clang/clang_interface.hpp +++ b/src/clang/clang_interface.hpp @@ -1,6 +1,7 @@ #ifndef BINDGEN_CLANG_AST_H #define BINDGEN_CLANG_AST_H +#include "clang/Basic/Version.h" #include "clang-c/Documentation.h" #include "clang-c/Index.h" diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 803310b920..1d68b10f22 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -12,11 +12,19 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/Mangle.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/Version.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" #include "clang-c/Documentation.h" #include "clang-c/Index.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Mangler.h" + #if CLANG_VERSION_MAJOR <= 8 && \ (CLANG_VERSION_MAJOR > 3 || \ CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR > 8) From d18d554ab022e6728911dd5f4eebc214a748de7d Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 2 Mar 2020 15:14:29 -0800 Subject: [PATCH 64/88] Fix expectations for tests that now check struct field offsets Before Clang 9 these tests did not emit field offset checks because libclang didn't expose information in these cases. This is fixed in the new interface now, so we can expect bindgen to emit these checks with all libclang versions. --- tests/expectations/tests/class.rs | 196 ++++++++++++++++++ tests/expectations/tests/class_1_0.rs | 196 ++++++++++++++++++ ...erive-hash-struct-with-incomplete-array.rs | 49 +++++ .../tests/incomplete-array-padding.rs | 5 + .../tests/issue-643-inner-struct.rs | 48 +++++ tests/expectations/tests/layout_align.rs | 61 ++++++ tests/expectations/tests/zero-sized-array.rs | 26 +++ 7 files changed, 581 insertions(+) diff --git a/tests/expectations/tests/class.rs b/tests/expectations/tests/class.rs index 9275884859..49e080d0aa 100644 --- a/tests/expectations/tests/class.rs +++ b/tests/expectations/tests/class.rs @@ -202,6 +202,45 @@ fn bindgen_test_layout_C_with_incomplete_array() { 4usize, concat!("Alignment of ", stringify!(C_with_incomplete_array)) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).a as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(C_with_incomplete_array), + "::", + stringify!(a) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).big_array + as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(C_with_incomplete_array), + "::", + stringify!(big_array) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).incomplete_array + as *const _ as usize + }, + 37usize, + concat!( + "Offset of field: ", + stringify!(C_with_incomplete_array), + "::", + stringify!(incomplete_array) + ) + ); } impl Default for C_with_incomplete_array { fn default() -> Self { @@ -226,6 +265,32 @@ fn bindgen_test_layout_C_with_incomplete_array_2() { 4usize, concat!("Alignment of ", stringify!(C_with_incomplete_array_2)) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).a as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(C_with_incomplete_array_2), + "::", + stringify!(a) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())) + .incomplete_array as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(C_with_incomplete_array_2), + "::", + stringify!(incomplete_array) + ) + ); } #[repr(C)] pub struct C_with_zero_length_array_and_incomplete_array { @@ -252,6 +317,66 @@ fn bindgen_test_layout_C_with_zero_length_array_and_incomplete_array() { stringify!(C_with_zero_length_array_and_incomplete_array) ) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array, + >())) + .a as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array), + "::", + stringify!(a) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array, + >())) + .big_array as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array), + "::", + stringify!(big_array) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array, + >())) + .zero_length_array as *const _ as usize + }, + 37usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array), + "::", + stringify!(zero_length_array) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array, + >())) + .incomplete_array as *const _ as usize + }, + 37usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array), + "::", + stringify!(incomplete_array) + ) + ); } impl Default for C_with_zero_length_array_and_incomplete_array { fn default() -> Self { @@ -285,6 +410,51 @@ fn bindgen_test_layout_C_with_zero_length_array_and_incomplete_array_2() { stringify!(C_with_zero_length_array_and_incomplete_array_2) ) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array_2, + >())) + .a as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array_2), + "::", + stringify!(a) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array_2, + >())) + .zero_length_array as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array_2), + "::", + stringify!(zero_length_array) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array_2, + >())) + .incomplete_array as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array_2), + "::", + stringify!(incomplete_array) + ) + ); } #[repr(C)] #[derive(Debug, Default, Hash, PartialOrd, Ord, PartialEq, Eq)] @@ -331,6 +501,32 @@ fn bindgen_test_layout_IncompleteArrayNonCopiable() { 8usize, concat!("Alignment of ", stringify!(IncompleteArrayNonCopiable)) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).whatever + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(IncompleteArrayNonCopiable), + "::", + stringify!(whatever) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())) + .incomplete_array as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(IncompleteArrayNonCopiable), + "::", + stringify!(incomplete_array) + ) + ); } impl Default for IncompleteArrayNonCopiable { fn default() -> Self { diff --git a/tests/expectations/tests/class_1_0.rs b/tests/expectations/tests/class_1_0.rs index 82a568b149..b86534a7db 100644 --- a/tests/expectations/tests/class_1_0.rs +++ b/tests/expectations/tests/class_1_0.rs @@ -255,6 +255,45 @@ fn bindgen_test_layout_C_with_incomplete_array() { 4usize, concat!("Alignment of ", stringify!(C_with_incomplete_array)) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).a as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(C_with_incomplete_array), + "::", + stringify!(a) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).big_array + as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(C_with_incomplete_array), + "::", + stringify!(big_array) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).incomplete_array + as *const _ as usize + }, + 37usize, + concat!( + "Offset of field: ", + stringify!(C_with_incomplete_array), + "::", + stringify!(incomplete_array) + ) + ); } impl Default for C_with_incomplete_array { fn default() -> Self { @@ -279,6 +318,32 @@ fn bindgen_test_layout_C_with_incomplete_array_2() { 4usize, concat!("Alignment of ", stringify!(C_with_incomplete_array_2)) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).a as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(C_with_incomplete_array_2), + "::", + stringify!(a) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())) + .incomplete_array as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(C_with_incomplete_array_2), + "::", + stringify!(incomplete_array) + ) + ); } #[repr(C)] pub struct C_with_zero_length_array_and_incomplete_array { @@ -305,6 +370,66 @@ fn bindgen_test_layout_C_with_zero_length_array_and_incomplete_array() { stringify!(C_with_zero_length_array_and_incomplete_array) ) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array, + >())) + .a as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array), + "::", + stringify!(a) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array, + >())) + .big_array as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array), + "::", + stringify!(big_array) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array, + >())) + .zero_length_array as *const _ as usize + }, + 37usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array), + "::", + stringify!(zero_length_array) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array, + >())) + .incomplete_array as *const _ as usize + }, + 37usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array), + "::", + stringify!(incomplete_array) + ) + ); } impl Default for C_with_zero_length_array_and_incomplete_array { fn default() -> Self { @@ -338,6 +463,51 @@ fn bindgen_test_layout_C_with_zero_length_array_and_incomplete_array_2() { stringify!(C_with_zero_length_array_and_incomplete_array_2) ) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array_2, + >())) + .a as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array_2), + "::", + stringify!(a) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array_2, + >())) + .zero_length_array as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array_2), + "::", + stringify!(zero_length_array) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::< + C_with_zero_length_array_and_incomplete_array_2, + >())) + .incomplete_array as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(C_with_zero_length_array_and_incomplete_array_2), + "::", + stringify!(incomplete_array) + ) + ); } #[repr(C)] #[derive(Debug, Default, Hash, PartialEq, Eq)] @@ -384,6 +554,32 @@ fn bindgen_test_layout_IncompleteArrayNonCopiable() { 8usize, concat!("Alignment of ", stringify!(IncompleteArrayNonCopiable)) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).whatever + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(IncompleteArrayNonCopiable), + "::", + stringify!(whatever) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())) + .incomplete_array as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(IncompleteArrayNonCopiable), + "::", + stringify!(incomplete_array) + ) + ); } impl Default for IncompleteArrayNonCopiable { fn default() -> Self { diff --git a/tests/expectations/tests/derive-hash-struct-with-incomplete-array.rs b/tests/expectations/tests/derive-hash-struct-with-incomplete-array.rs index 45869e9470..336cda1c03 100644 --- a/tests/expectations/tests/derive-hash-struct-with-incomplete-array.rs +++ b/tests/expectations/tests/derive-hash-struct-with-incomplete-array.rs @@ -92,6 +92,24 @@ fn bindgen_test_layout_test2() { 4usize, concat!("Alignment of ", stringify!(test2)) ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(test2), "::", stringify!(a)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).incomplete_array as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(test2), + "::", + stringify!(incomplete_array) + ) + ); } #[repr(C)] #[derive(Debug, Default)] @@ -112,4 +130,35 @@ fn bindgen_test_layout_test3() { 4usize, concat!("Alignment of ", stringify!(test3)) ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).a as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(test3), "::", stringify!(a)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).zero_length_array as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(test3), + "::", + stringify!(zero_length_array) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).incomplete_array as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(test3), + "::", + stringify!(incomplete_array) + ) + ); } diff --git a/tests/expectations/tests/incomplete-array-padding.rs b/tests/expectations/tests/incomplete-array-padding.rs index 3f2110b0c6..f5661ed576 100644 --- a/tests/expectations/tests/incomplete-array-padding.rs +++ b/tests/expectations/tests/incomplete-array-padding.rs @@ -142,6 +142,11 @@ fn bindgen_test_layout_foo() { 8usize, concat!("Alignment of ", stringify!(foo)) ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).b as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(foo), "::", stringify!(b)) + ); } impl Default for foo { fn default() -> Self { diff --git a/tests/expectations/tests/issue-643-inner-struct.rs b/tests/expectations/tests/issue-643-inner-struct.rs index 3b8d97b722..7a3d37f6cd 100644 --- a/tests/expectations/tests/issue-643-inner-struct.rs +++ b/tests/expectations/tests/issue-643-inner-struct.rs @@ -119,6 +119,54 @@ fn bindgen_test_layout_rte_ring() { 8usize, concat!("Alignment of ", stringify!(rte_ring)) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).memzone as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(rte_ring), + "::", + stringify!(memzone) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).prod as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(rte_ring), + "::", + stringify!(prod) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).cons as *const _ as usize + }, + 12usize, + concat!( + "Offset of field: ", + stringify!(rte_ring), + "::", + stringify!(cons) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ring as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(rte_ring), + "::", + stringify!(ring) + ) + ); } impl Default for rte_ring { fn default() -> Self { diff --git a/tests/expectations/tests/layout_align.rs b/tests/expectations/tests/layout_align.rs index 2ff900d519..93c4ecac1f 100644 --- a/tests/expectations/tests/layout_align.rs +++ b/tests/expectations/tests/layout_align.rs @@ -150,6 +150,67 @@ fn bindgen_test_layout_rte_kni_fifo() { 8usize, concat!("Alignment of ", stringify!(rte_kni_fifo)) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).write as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(rte_kni_fifo), + "::", + stringify!(write) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).read as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(rte_kni_fifo), + "::", + stringify!(read) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).len as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(rte_kni_fifo), + "::", + stringify!(len) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).elem_size as *const _ + as usize + }, + 12usize, + concat!( + "Offset of field: ", + stringify!(rte_kni_fifo), + "::", + stringify!(elem_size) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).buffer as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(rte_kni_fifo), + "::", + stringify!(buffer) + ) + ); } impl Default for rte_kni_fifo { fn default() -> Self { diff --git a/tests/expectations/tests/zero-sized-array.rs b/tests/expectations/tests/zero-sized-array.rs index 75cf7572fb..adb3210760 100644 --- a/tests/expectations/tests/zero-sized-array.rs +++ b/tests/expectations/tests/zero-sized-array.rs @@ -138,6 +138,19 @@ fn bindgen_test_layout_DynamicallySizedArray() { 1usize, concat!("Alignment of ", stringify!(DynamicallySizedArray)) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).arr as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(DynamicallySizedArray), + "::", + stringify!(arr) + ) + ); } /// No `_address` field here either. #[repr(C)] @@ -157,4 +170,17 @@ fn bindgen_test_layout_ContainsDynamicallySizedArray() { 1usize, concat!("Alignment of ", stringify!(ContainsDynamicallySizedArray)) ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).dsa + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(ContainsDynamicallySizedArray), + "::", + stringify!(dsa) + ) + ); } From da05e77aa681b5665550319e11e37aa6480c22ab Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 2 Mar 2020 17:20:17 -0800 Subject: [PATCH 65/88] Update expectations for clang 3.9 Several bugs/limitations that existed with clang 3.9 are now gone. --- .../{libclang-4 => }/constant-evaluate.rs | 0 ...0600-cannot-apply-unary-negation-to-u32.rs | 0 .../issue-769-bad-instantiation-test.rs | 0 .../tests/libclang-3.8/constant-evaluate.rs | 37 ----------- ...0600-cannot-apply-unary-negation-to-u32.rs | 11 ---- .../issue-769-bad-instantiation-test.rs | 39 ------------ .../type_alias_template_specialized.rs | 36 ----------- .../tests/libclang-3.9/constant-evaluate.rs | 26 -------- ...0600-cannot-apply-unary-negation-to-u32.rs | 11 ---- .../issue-769-bad-instantiation-test.rs | 39 ------------ .../type_alias_template_specialized.rs | 36 ----------- .../type_alias_template_specialized.rs | 60 ------------------ .../tests/libclang-5/constant-evaluate.rs | 27 -------- ...0600-cannot-apply-unary-negation-to-u32.rs | 11 ---- .../issue-769-bad-instantiation-test.rs | 40 ------------ .../tests/libclang-9/constant-evaluate.rs | 27 -------- ...0600-cannot-apply-unary-negation-to-u32.rs | 11 ---- .../issue-769-bad-instantiation-test.rs | 40 ------------ .../type_alias_template_specialized.rs | 63 ------------------- .../type_alias_template_specialized.rs | 0 20 files changed, 514 deletions(-) rename tests/expectations/tests/{libclang-4 => }/constant-evaluate.rs (100%) rename tests/expectations/tests/{libclang-4 => }/error-E0600-cannot-apply-unary-negation-to-u32.rs (100%) rename tests/expectations/tests/{libclang-4 => }/issue-769-bad-instantiation-test.rs (100%) delete mode 100644 tests/expectations/tests/libclang-3.8/constant-evaluate.rs delete mode 100644 tests/expectations/tests/libclang-3.8/error-E0600-cannot-apply-unary-negation-to-u32.rs delete mode 100644 tests/expectations/tests/libclang-3.8/issue-769-bad-instantiation-test.rs delete mode 100644 tests/expectations/tests/libclang-3.8/type_alias_template_specialized.rs delete mode 100644 tests/expectations/tests/libclang-3.9/constant-evaluate.rs delete mode 100644 tests/expectations/tests/libclang-3.9/error-E0600-cannot-apply-unary-negation-to-u32.rs delete mode 100644 tests/expectations/tests/libclang-3.9/issue-769-bad-instantiation-test.rs delete mode 100644 tests/expectations/tests/libclang-3.9/type_alias_template_specialized.rs delete mode 100644 tests/expectations/tests/libclang-4/type_alias_template_specialized.rs delete mode 100644 tests/expectations/tests/libclang-5/constant-evaluate.rs delete mode 100644 tests/expectations/tests/libclang-5/error-E0600-cannot-apply-unary-negation-to-u32.rs delete mode 100644 tests/expectations/tests/libclang-5/issue-769-bad-instantiation-test.rs delete mode 100644 tests/expectations/tests/libclang-9/constant-evaluate.rs delete mode 100644 tests/expectations/tests/libclang-9/error-E0600-cannot-apply-unary-negation-to-u32.rs delete mode 100644 tests/expectations/tests/libclang-9/issue-769-bad-instantiation-test.rs delete mode 100644 tests/expectations/tests/libclang-9/type_alias_template_specialized.rs rename tests/expectations/tests/{libclang-5 => }/type_alias_template_specialized.rs (100%) diff --git a/tests/expectations/tests/libclang-4/constant-evaluate.rs b/tests/expectations/tests/constant-evaluate.rs similarity index 100% rename from tests/expectations/tests/libclang-4/constant-evaluate.rs rename to tests/expectations/tests/constant-evaluate.rs diff --git a/tests/expectations/tests/libclang-4/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/error-E0600-cannot-apply-unary-negation-to-u32.rs similarity index 100% rename from tests/expectations/tests/libclang-4/error-E0600-cannot-apply-unary-negation-to-u32.rs rename to tests/expectations/tests/error-E0600-cannot-apply-unary-negation-to-u32.rs diff --git a/tests/expectations/tests/libclang-4/issue-769-bad-instantiation-test.rs b/tests/expectations/tests/issue-769-bad-instantiation-test.rs similarity index 100% rename from tests/expectations/tests/libclang-4/issue-769-bad-instantiation-test.rs rename to tests/expectations/tests/issue-769-bad-instantiation-test.rs diff --git a/tests/expectations/tests/libclang-3.8/constant-evaluate.rs b/tests/expectations/tests/libclang-3.8/constant-evaluate.rs deleted file mode 100644 index 73455f3a6a..0000000000 --- a/tests/expectations/tests/libclang-3.8/constant-evaluate.rs +++ /dev/null @@ -1,37 +0,0 @@ -/* automatically generated by rust-bindgen */ - - -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] - - -pub const foo: _bindgen_ty_1 = _bindgen_ty_1::foo; -pub const bar: _bindgen_ty_1 = _bindgen_ty_1::bar; -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum _bindgen_ty_1 { foo = 4, bar = 8, } -pub type EasyToOverflow = ::std::os::raw::c_ulonglong; -pub const k: EasyToOverflow = 2147483648; -extern "C" { - pub static k_expr: EasyToOverflow; -} -extern "C" { - pub static wow: EasyToOverflow; -} -extern "C" { - pub static BAZ: ::std::os::raw::c_longlong; -} -extern "C" { - pub static fuzz: f64; -} -extern "C" { - pub static BAZZ: ::std::os::raw::c_char; -} -extern "C" { - pub static WAT: ::std::os::raw::c_char; -} -extern "C" { - pub static mut bytestring: *const ::std::os::raw::c_char; -} -extern "C" { - pub static mut NOT_UTF8: *const ::std::os::raw::c_char; -} diff --git a/tests/expectations/tests/libclang-3.8/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/libclang-3.8/error-E0600-cannot-apply-unary-negation-to-u32.rs deleted file mode 100644 index 04833a6581..0000000000 --- a/tests/expectations/tests/libclang-3.8/error-E0600-cannot-apply-unary-negation-to-u32.rs +++ /dev/null @@ -1,11 +0,0 @@ -/* automatically generated by rust-bindgen */ - -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![allow(overflowing_literals)] - -pub const a: u32 = 18446744073709551611; diff --git a/tests/expectations/tests/libclang-3.8/issue-769-bad-instantiation-test.rs b/tests/expectations/tests/libclang-3.8/issue-769-bad-instantiation-test.rs deleted file mode 100644 index 0603873df2..0000000000 --- a/tests/expectations/tests/libclang-3.8/issue-769-bad-instantiation-test.rs +++ /dev/null @@ -1,39 +0,0 @@ -/* automatically generated by rust-bindgen */ - - -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] - - -#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] -pub mod root { - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct Rooted { - pub member: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, - } - impl Default for Rooted { - fn default() -> Self { - unsafe { ::std::mem::zeroed() } - } - } - #[test] - fn __bindgen_test_layout_Rooted_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify ! ( root :: Rooted < :: std :: os :: raw :: c_int > ) - ) - ); - assert_eq ! ( :: std :: mem :: align_of :: < root :: Rooted < :: std :: os :: raw :: c_int > > ( ) , 4usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: Rooted < :: std :: os :: raw :: c_int > ) ) ); - } - #[test] - fn __bindgen_test_layout_Rooted_open0_int_close0_instantiation_1() { - assert_eq ! ( :: std :: mem :: size_of :: < root :: Rooted < :: std :: os :: raw :: c_int > > ( ) , 4usize , concat ! ( "Size of template specialization: " , stringify ! ( root :: Rooted < :: std :: os :: raw :: c_int > ) ) ); - assert_eq ! ( :: std :: mem :: align_of :: < root :: Rooted < :: std :: os :: raw :: c_int > > ( ) , 4usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: Rooted < :: std :: os :: raw :: c_int > ) ) ); - } -} diff --git a/tests/expectations/tests/libclang-3.8/type_alias_template_specialized.rs b/tests/expectations/tests/libclang-3.8/type_alias_template_specialized.rs deleted file mode 100644 index a0d9ade6d0..0000000000 --- a/tests/expectations/tests/libclang-3.8/type_alias_template_specialized.rs +++ /dev/null @@ -1,36 +0,0 @@ -/* automatically generated by rust-bindgen */ - - -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] - - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Rooted { - pub ptr: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Rooted() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Rooted)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Rooted)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ptr as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Rooted), - "::", - stringify!(ptr) - ) - ); -} -///
-pub type MaybeWrapped = a; diff --git a/tests/expectations/tests/libclang-3.9/constant-evaluate.rs b/tests/expectations/tests/libclang-3.9/constant-evaluate.rs deleted file mode 100644 index 7e6fcd60de..0000000000 --- a/tests/expectations/tests/libclang-3.9/constant-evaluate.rs +++ /dev/null @@ -1,26 +0,0 @@ -/* automatically generated by rust-bindgen */ - - -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] - - -pub const foo: _bindgen_ty_1 = _bindgen_ty_1::foo; -pub const bar: _bindgen_ty_1 = _bindgen_ty_1::bar; -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum _bindgen_ty_1 { - foo = 4, - bar = 8, -} -pub type EasyToOverflow = ::std::os::raw::c_ulonglong; -pub const k: EasyToOverflow = 2147483648; -pub const k_expr: EasyToOverflow = 0; -extern "C" { - pub static wow: EasyToOverflow; -} -pub const BAZ: ::std::os::raw::c_longlong = 24; -pub const fuzz: f64 = 51.0; -pub const BAZZ: ::std::os::raw::c_char = 53; -pub const WAT: ::std::os::raw::c_char = 0; -pub const bytestring: &'static [u8; 4usize] = b"Foo\0"; -pub const NOT_UTF8: [u8; 5usize] = [240u8, 40u8, 140u8, 40u8, 0u8]; diff --git a/tests/expectations/tests/libclang-3.9/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/libclang-3.9/error-E0600-cannot-apply-unary-negation-to-u32.rs deleted file mode 100644 index 04833a6581..0000000000 --- a/tests/expectations/tests/libclang-3.9/error-E0600-cannot-apply-unary-negation-to-u32.rs +++ /dev/null @@ -1,11 +0,0 @@ -/* automatically generated by rust-bindgen */ - -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![allow(overflowing_literals)] - -pub const a: u32 = 18446744073709551611; diff --git a/tests/expectations/tests/libclang-3.9/issue-769-bad-instantiation-test.rs b/tests/expectations/tests/libclang-3.9/issue-769-bad-instantiation-test.rs deleted file mode 100644 index 0603873df2..0000000000 --- a/tests/expectations/tests/libclang-3.9/issue-769-bad-instantiation-test.rs +++ /dev/null @@ -1,39 +0,0 @@ -/* automatically generated by rust-bindgen */ - - -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] - - -#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] -pub mod root { - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct Rooted { - pub member: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, - } - impl Default for Rooted { - fn default() -> Self { - unsafe { ::std::mem::zeroed() } - } - } - #[test] - fn __bindgen_test_layout_Rooted_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify ! ( root :: Rooted < :: std :: os :: raw :: c_int > ) - ) - ); - assert_eq ! ( :: std :: mem :: align_of :: < root :: Rooted < :: std :: os :: raw :: c_int > > ( ) , 4usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: Rooted < :: std :: os :: raw :: c_int > ) ) ); - } - #[test] - fn __bindgen_test_layout_Rooted_open0_int_close0_instantiation_1() { - assert_eq ! ( :: std :: mem :: size_of :: < root :: Rooted < :: std :: os :: raw :: c_int > > ( ) , 4usize , concat ! ( "Size of template specialization: " , stringify ! ( root :: Rooted < :: std :: os :: raw :: c_int > ) ) ); - assert_eq ! ( :: std :: mem :: align_of :: < root :: Rooted < :: std :: os :: raw :: c_int > > ( ) , 4usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: Rooted < :: std :: os :: raw :: c_int > ) ) ); - } -} diff --git a/tests/expectations/tests/libclang-3.9/type_alias_template_specialized.rs b/tests/expectations/tests/libclang-3.9/type_alias_template_specialized.rs deleted file mode 100644 index a0d9ade6d0..0000000000 --- a/tests/expectations/tests/libclang-3.9/type_alias_template_specialized.rs +++ /dev/null @@ -1,36 +0,0 @@ -/* automatically generated by rust-bindgen */ - - -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] - - -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Rooted { - pub ptr: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_Rooted() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Rooted)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Rooted)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ptr as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Rooted), - "::", - stringify!(ptr) - ) - ); -} -///
-pub type MaybeWrapped
= a; diff --git a/tests/expectations/tests/libclang-4/type_alias_template_specialized.rs b/tests/expectations/tests/libclang-4/type_alias_template_specialized.rs deleted file mode 100644 index a09323a8f2..0000000000 --- a/tests/expectations/tests/libclang-4/type_alias_template_specialized.rs +++ /dev/null @@ -1,60 +0,0 @@ -/* automatically generated by rust-bindgen */ - - -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] - - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Rooted { - pub ptr: MaybeWrapped<::std::os::raw::c_int>, -} -#[test] -fn bindgen_test_layout_Rooted() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Rooted)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Rooted)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ptr as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Rooted), - "::", - stringify!(ptr) - ) - ); -} -impl Default for Rooted { - fn default() -> Self { - unsafe { ::std::mem::zeroed() } - } -} -///
-pub type MaybeWrapped
= a; -#[test] -fn __bindgen_test_layout_MaybeWrapped_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(MaybeWrapped<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(MaybeWrapped<::std::os::raw::c_int>) - ) - ); -} diff --git a/tests/expectations/tests/libclang-5/constant-evaluate.rs b/tests/expectations/tests/libclang-5/constant-evaluate.rs deleted file mode 100644 index 07df8114df..0000000000 --- a/tests/expectations/tests/libclang-5/constant-evaluate.rs +++ /dev/null @@ -1,27 +0,0 @@ -/* automatically generated by rust-bindgen */ - -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const foo: _bindgen_ty_1 = _bindgen_ty_1::foo; -pub const bar: _bindgen_ty_1 = _bindgen_ty_1::bar; -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum _bindgen_ty_1 { - foo = 4, - bar = 8, -} -pub type EasyToOverflow = ::std::os::raw::c_ulonglong; -pub const k: EasyToOverflow = 2147483648; -pub const k_expr: EasyToOverflow = 1152921504606846976; -pub const wow: EasyToOverflow = 2147483648; -pub const BAZ: ::std::os::raw::c_longlong = 24; -pub const fuzz: f64 = 51.0; -pub const BAZZ: ::std::os::raw::c_char = 53; -pub const WAT: ::std::os::raw::c_char = 0; -pub const bytestring: &'static [u8; 4usize] = b"Foo\0"; -pub const NOT_UTF8: [u8; 5usize] = [240u8, 40u8, 140u8, 40u8, 0u8]; diff --git a/tests/expectations/tests/libclang-5/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/libclang-5/error-E0600-cannot-apply-unary-negation-to-u32.rs deleted file mode 100644 index ce5d0362d6..0000000000 --- a/tests/expectations/tests/libclang-5/error-E0600-cannot-apply-unary-negation-to-u32.rs +++ /dev/null @@ -1,11 +0,0 @@ -/* automatically generated by rust-bindgen */ - -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![allow(overflowing_literals)] - -pub const a: u32 = 4294967291; diff --git a/tests/expectations/tests/libclang-5/issue-769-bad-instantiation-test.rs b/tests/expectations/tests/libclang-5/issue-769-bad-instantiation-test.rs deleted file mode 100644 index 86fad78d46..0000000000 --- a/tests/expectations/tests/libclang-5/issue-769-bad-instantiation-test.rs +++ /dev/null @@ -1,40 +0,0 @@ -/* automatically generated by rust-bindgen */ - - -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] - - -#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] -pub mod root { - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct Rooted { - pub member: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, - } - impl Default for Rooted { - fn default() -> Self { - unsafe { ::std::mem::zeroed() } - } - } - pub type AutoValueVector_Alias = ::std::os::raw::c_int; - #[test] - fn __bindgen_test_layout_Rooted_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify ! ( root :: Rooted < :: std :: os :: raw :: c_int > ) - ) - ); - assert_eq ! ( :: std :: mem :: align_of :: < root :: Rooted < :: std :: os :: raw :: c_int > > ( ) , 4usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: Rooted < :: std :: os :: raw :: c_int > ) ) ); - } - #[test] - fn __bindgen_test_layout_Rooted_open0_AutoValueVector_Alias_close0_instantiation() { - assert_eq ! ( :: std :: mem :: size_of :: < root :: Rooted < root :: AutoValueVector_Alias > > ( ) , 4usize , concat ! ( "Size of template specialization: " , stringify ! ( root :: Rooted < root :: AutoValueVector_Alias > ) ) ); - assert_eq ! ( :: std :: mem :: align_of :: < root :: Rooted < root :: AutoValueVector_Alias > > ( ) , 4usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: Rooted < root :: AutoValueVector_Alias > ) ) ); - } -} diff --git a/tests/expectations/tests/libclang-9/constant-evaluate.rs b/tests/expectations/tests/libclang-9/constant-evaluate.rs deleted file mode 100644 index 07df8114df..0000000000 --- a/tests/expectations/tests/libclang-9/constant-evaluate.rs +++ /dev/null @@ -1,27 +0,0 @@ -/* automatically generated by rust-bindgen */ - -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -pub const foo: _bindgen_ty_1 = _bindgen_ty_1::foo; -pub const bar: _bindgen_ty_1 = _bindgen_ty_1::bar; -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum _bindgen_ty_1 { - foo = 4, - bar = 8, -} -pub type EasyToOverflow = ::std::os::raw::c_ulonglong; -pub const k: EasyToOverflow = 2147483648; -pub const k_expr: EasyToOverflow = 1152921504606846976; -pub const wow: EasyToOverflow = 2147483648; -pub const BAZ: ::std::os::raw::c_longlong = 24; -pub const fuzz: f64 = 51.0; -pub const BAZZ: ::std::os::raw::c_char = 53; -pub const WAT: ::std::os::raw::c_char = 0; -pub const bytestring: &'static [u8; 4usize] = b"Foo\0"; -pub const NOT_UTF8: [u8; 5usize] = [240u8, 40u8, 140u8, 40u8, 0u8]; diff --git a/tests/expectations/tests/libclang-9/error-E0600-cannot-apply-unary-negation-to-u32.rs b/tests/expectations/tests/libclang-9/error-E0600-cannot-apply-unary-negation-to-u32.rs deleted file mode 100644 index ce5d0362d6..0000000000 --- a/tests/expectations/tests/libclang-9/error-E0600-cannot-apply-unary-negation-to-u32.rs +++ /dev/null @@ -1,11 +0,0 @@ -/* automatically generated by rust-bindgen */ - -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] -#![allow(overflowing_literals)] - -pub const a: u32 = 4294967291; diff --git a/tests/expectations/tests/libclang-9/issue-769-bad-instantiation-test.rs b/tests/expectations/tests/libclang-9/issue-769-bad-instantiation-test.rs deleted file mode 100644 index 86fad78d46..0000000000 --- a/tests/expectations/tests/libclang-9/issue-769-bad-instantiation-test.rs +++ /dev/null @@ -1,40 +0,0 @@ -/* automatically generated by rust-bindgen */ - - -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] - - -#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] -pub mod root { - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct Rooted { - pub member: T, - pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, - } - impl Default for Rooted { - fn default() -> Self { - unsafe { ::std::mem::zeroed() } - } - } - pub type AutoValueVector_Alias = ::std::os::raw::c_int; - #[test] - fn __bindgen_test_layout_Rooted_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify ! ( root :: Rooted < :: std :: os :: raw :: c_int > ) - ) - ); - assert_eq ! ( :: std :: mem :: align_of :: < root :: Rooted < :: std :: os :: raw :: c_int > > ( ) , 4usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: Rooted < :: std :: os :: raw :: c_int > ) ) ); - } - #[test] - fn __bindgen_test_layout_Rooted_open0_AutoValueVector_Alias_close0_instantiation() { - assert_eq ! ( :: std :: mem :: size_of :: < root :: Rooted < root :: AutoValueVector_Alias > > ( ) , 4usize , concat ! ( "Size of template specialization: " , stringify ! ( root :: Rooted < root :: AutoValueVector_Alias > ) ) ); - assert_eq ! ( :: std :: mem :: align_of :: < root :: Rooted < root :: AutoValueVector_Alias > > ( ) , 4usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: Rooted < root :: AutoValueVector_Alias > ) ) ); - } -} diff --git a/tests/expectations/tests/libclang-9/type_alias_template_specialized.rs b/tests/expectations/tests/libclang-9/type_alias_template_specialized.rs deleted file mode 100644 index 89e37fe81e..0000000000 --- a/tests/expectations/tests/libclang-9/type_alias_template_specialized.rs +++ /dev/null @@ -1,63 +0,0 @@ -/* automatically generated by rust-bindgen */ - -#![allow( - dead_code, - non_snake_case, - non_camel_case_types, - non_upper_case_globals -)] - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Rooted { - pub ptr: MaybeWrapped<::std::os::raw::c_int>, -} -#[test] -fn bindgen_test_layout_Rooted() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(Rooted)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Rooted)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).ptr as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Rooted), - "::", - stringify!(ptr) - ) - ); -} -impl Default for Rooted { - fn default() -> Self { - unsafe { ::std::mem::zeroed() } - } -} -///
-pub type MaybeWrapped
= a; -#[test] -fn __bindgen_test_layout_MaybeWrapped_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 4usize, - concat!( - "Size of template specialization: ", - stringify!(MaybeWrapped<::std::os::raw::c_int>) - ) - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, - concat!( - "Alignment of template specialization: ", - stringify!(MaybeWrapped<::std::os::raw::c_int>) - ) - ); -} diff --git a/tests/expectations/tests/libclang-5/type_alias_template_specialized.rs b/tests/expectations/tests/type_alias_template_specialized.rs similarity index 100% rename from tests/expectations/tests/libclang-5/type_alias_template_specialized.rs rename to tests/expectations/tests/type_alias_template_specialized.rs From deea9364ede2f7740651df1acbcfc523bdc16377 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 2 Mar 2020 18:25:54 -0800 Subject: [PATCH 66/88] Support getSpelling for PreprocessedEntity --- src/clang.rs | 1 + src/clang/clang_interface.cpp | 10 ++++++++++ src/clang/clang_interface.hpp | 1 + src/clang/clang_interface.rs | 6 ++++++ 4 files changed, 18 insertions(+) diff --git a/src/clang.rs b/src/clang.rs index 6e00519614..b34a33b7dc 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -169,6 +169,7 @@ impl Cursor { ASTNode::Expr(e) => clang_interface::Expr_getSpelling(e).to_string(), ASTNode::CXXBaseSpecifier(b) => clang_interface::CXXBaseSpecifier_getSpelling(b) .to_string(), + ASTNode::PreprocessedEntity(e) => clang_interface::PreprocessedEntity_getSpelling(e).to_string(), _ => String::new(), } } diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index 6058b711e9..c6fc5303cb 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -1655,3 +1655,13 @@ BindgenSourceRange Attr_getSourceRange(const Attr *A) { BindgenSourceRange PreprocessedEntity_getSourceRange(const PreprocessedEntity *PPE) { return BindgenSourceRange(PPE->getSourceRange()); } + +BindgenStringRef PreprocessedEntity_getSpelling(const PreprocessedEntity *PPE) { + if (!PPE) + return stringref(); + if (const auto *MDR = dyn_cast_or_null(PPE)) + return stringref(MDR->getName()->getName()); + if (const auto *ME = dyn_cast(PPE)) + return stringref(ME->getName()->getName()); + return stringref(); +} diff --git a/src/clang/clang_interface.hpp b/src/clang/clang_interface.hpp index 4c75b9eed6..e01b95a3d2 100644 --- a/src/clang/clang_interface.hpp +++ b/src/clang/clang_interface.hpp @@ -260,6 +260,7 @@ BindgenStringRef HTMLStartTag_getAttrValue(const comments::Comment *, unsigned); BindgenStringRef CursorKind_getSpelling(CXCursorKind); BindgenStringRef TypeKind_getSpelling(CXTypeKind); +BindgenStringRef PreprocessedEntity_getSpelling(const PreprocessedEntity *); BindgenStringRef FileEntry_getName(FileEntry *); diff --git a/src/clang/clang_interface.rs b/src/clang/clang_interface.rs index f77dcb291d..9e13b6c294 100644 --- a/src/clang/clang_interface.rs +++ b/src/clang/clang_interface.rs @@ -7201,6 +7201,12 @@ extern "C" { #[link_name = "\u{1}_Z20TypeKind_getSpelling10CXTypeKind"] pub fn TypeKind_getSpelling(arg1: CXTypeKind::Type) -> BindgenStringRef; } +extern "C" { + #[link_name = "\u{1}_Z30PreprocessedEntity_getSpellingPKN5clang18PreprocessedEntityE"] + pub fn PreprocessedEntity_getSpelling( + arg1: *const clang_PreprocessedEntity, + ) -> BindgenStringRef; +} extern "C" { #[link_name = "\u{1}_Z17FileEntry_getNamePN5clang9FileEntryE"] pub fn FileEntry_getName(arg1: *mut clang_FileEntry) -> BindgenStringRef; From 9ccb4d17fa539f11b693e0ad4b4a3b899270d447 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 2 Mar 2020 18:26:12 -0800 Subject: [PATCH 67/88] Move CXEvalResultKind definition for LLVM <= 3.8 into impl header I can't easily bindgen clang_interface.hpp if it includes C++ headers, but we don't need clang/basic/Version.h in that header anyway if we move this into clang_interface_impl.hpp instead. --- src/clang/clang_interface.hpp | 17 ----------------- src/clang/clang_interface_impl.hpp | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/clang/clang_interface.hpp b/src/clang/clang_interface.hpp index e01b95a3d2..582bfd761f 100644 --- a/src/clang/clang_interface.hpp +++ b/src/clang/clang_interface.hpp @@ -1,7 +1,6 @@ #ifndef BINDGEN_CLANG_AST_H #define BINDGEN_CLANG_AST_H -#include "clang/Basic/Version.h" #include "clang-c/Documentation.h" #include "clang-c/Index.h" @@ -32,22 +31,6 @@ struct Comment; struct FullComment; } // namespace comments -#if CLANG_VERSION_MAJOR < 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR <= 8) -// Clang <= 3.8 doesn't include this enum, but we can still expose the same -// functionality -typedef enum { - CXEval_Int = 1 , - CXEval_Float = 2, - CXEval_ObjCStrLiteral = 3, - CXEval_StrLiteral = 4, - CXEval_CFStr = 5, - CXEval_Other = 6, - - CXEval_UnExposed = 0 - -} CXEvalResultKind ; -#endif - } // namespace clang struct EvalResult; diff --git a/src/clang/clang_interface_impl.hpp b/src/clang/clang_interface_impl.hpp index 60f4798673..b39f3fe4fb 100644 --- a/src/clang/clang_interface_impl.hpp +++ b/src/clang/clang_interface_impl.hpp @@ -3,12 +3,33 @@ #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" +#include "clang/Basic/Version.h" #define BINDGEN_IMPLEMENTATION #include "clang_interface.hpp" using namespace clang; +namespace clang { + +#if CLANG_VERSION_MAJOR < 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR <= 8) +// Clang <= 3.8 doesn't include this enum, but we can still expose the same +// functionality +typedef enum { + CXEval_Int = 1 , + CXEval_Float = 2, + CXEval_ObjCStrLiteral = 3, + CXEval_StrLiteral = 4, + CXEval_CFStr = 5, + CXEval_Other = 6, + + CXEval_UnExposed = 0 + +} CXEvalResultKind ; +#endif + +} // namespace clang + // Utility functions defined in ClangAST.cpp BindgenStringRef stringref(); BindgenStringRef stringref(const char *newStr); From 94db32be67559d66e4cf75572d06b4e0f00d43b4 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 3 Mar 2020 13:09:44 -0800 Subject: [PATCH 68/88] Do not visit children of implicit decls unless the decl is base The libclang visitor will visit children of an implicit decl only if that decl is the top-level parent passed in `Decl_visitChildren`. Otherwise, we should skip traversal of implicit decls. --- src/clang/clang_interface.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index c6fc5303cb..11e19ec150 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -912,7 +912,7 @@ class BindgenVisitor : public RecursiveASTVisitor { explicit BindgenVisitor(ASTUnit &AST, Visitor V, CXClientData data) : AST(AST), VisitFn(V), Data(data) {} bool shouldVisitImplicitCode() { - return false; + return true; } void setParent(Node n) { @@ -920,8 +920,8 @@ class BindgenVisitor : public RecursiveASTVisitor { } bool TraverseDeclTyped(Decl *D, CXCursorKind kind) { - if (!D || (D->isImplicit() && !isa(D))) - return true; + if (!D) + return false; bool skip = !Parent; @@ -945,6 +945,10 @@ class BindgenVisitor : public RecursiveASTVisitor { // D->dump(); Node node(D, kind); if (!skip) { + // We don't want to visit implicit decls or their children + if (D->isImplicit() && !isa(D)) + return true; + switch (VisitFn(node, Parent, &AST, Data)) { case CXChildVisit_Break: return false; From 40ed73d9215a3f175c057fae0de68631de373cba Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 3 Mar 2020 14:07:23 -0800 Subject: [PATCH 69/88] Add doc strings --- src/clang.rs | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index b34a33b7dc..e2a07ee9cd 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -13,7 +13,7 @@ use std::hash::Hash; use std::os::raw::{c_char, c_int, c_longlong, c_uint, c_ulong, c_ulonglong}; use std::{mem, ptr, slice}; -#[allow(non_camel_case_types, non_snake_case)] +#[allow(non_camel_case_types, non_snake_case, missing_docs)] mod clang_interface; pub use self::clang_interface::CXDiagnosticSeverity::Type as CXDiagnosticSeverity; pub use self::clang_interface::CXCallingConv::Type as CXCallingConv; @@ -71,17 +71,39 @@ impl fmt::Display for clang_interface::BindgenStringRef { #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Cursor { node: ASTNode, + + /// Kind of this cursor, may differ from the kind of the node, e.g. TypeRef + /// kind referring to a ClassDecl. kind: CXCursorKind, + + /// AST unit that this cursor is part of. + /// + /// Some clang interfaces require access to an ASTUnit, so we keep this + /// available. unit: *mut clang_interface::clang_ASTUnit, } +/// Clang AST nodes. +/// +/// Each variant wraps a raw pointer to a type of Clang AST node that we handle. #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub enum ASTNode { + /// Placeholder for an invalid AST node Invalid, + + /// Declaration AST node (const Decl*) Decl(*const clang_interface::clang_Decl), + + /// Expression AST node (const Expr*) Expr(*const clang_interface::clang_Expr), + + /// C++ base specifier AST node (const CXXBaseSpecifier*) CXXBaseSpecifier(*const clang_interface::clang_CXXBaseSpecifier), + + /// Attribute AST node (const Attr*) Attr(*const clang_interface::clang_Attr), + + /// Preprocessor entity node (const PreprocessedEntity*) PreprocessedEntity(*const clang_interface::clang_PreprocessedEntity), } @@ -91,6 +113,8 @@ impl ASTNode { unsafe { !clang_interface::CursorKind_isInvalid(self.kind()) } } + /// Kind of the AST node. This is NOT the kind of the cursor itself, and may + /// differ from a cursor holding the node. fn kind(&self) -> CXCursorKind { unsafe { match *self { @@ -118,6 +142,7 @@ impl fmt::Debug for Cursor { } impl Cursor { + /// Create a new Cursor from an ASTNode and a clang ASTUnit fn new(node: ASTNode, unit: *mut clang_interface::clang_ASTUnit) -> Self { Self { node, @@ -126,10 +151,13 @@ impl Cursor { } } + /// Create a new Cursor with the given ASTNode in the same clang ASTUnit as + /// self. fn with_node(&self, node: ASTNode) -> Self { Self::new(node, self.unit) } + /// Get the clang ASTContext for this cursor fn context(&self) -> *mut clang_interface::clang_ASTContext { unsafe { clang_interface::ASTUnit_getContext(self.unit) } } @@ -175,20 +203,6 @@ impl Cursor { } } - // /// Get this cursor's referent's display name. - // /// - // /// This is not necessarily a valid identifier. It includes extra - // /// information, such as parameters for a function, etc. - // pub fn display_name(&self) -> String { - // unsafe { - // match self.node { - // ASTNode::Decl(d) => clang_interface::Decl_getDisplayName(d).to_string(), - // ASTNode::Expr(e) => clang_interface::Expr_getDisplayName(e).to_string(), - // _ => String::new(), - // } - // } - // } - /// Get the mangled name of this cursor's referent. pub fn mangling(&self) -> String { unsafe { From b7e161d8550c74b3d398d79a521498cf6d850d4d Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 3 Mar 2020 14:10:00 -0800 Subject: [PATCH 70/88] Remove completed TODO --- src/clang.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/clang.rs b/src/clang.rs index e2a07ee9cd..f9579a6a7f 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -1879,7 +1879,6 @@ impl TranslationUnit { let mut c_unsaved: Vec = unsaved.iter().map(|f| f.x).collect(); let tu = unsafe { - // TODO(sjc): add back in unsaved files and opts clang_interface::parseTranslationUnit( fname.as_ptr(), c_args.as_ptr(), From 3b16276770c61f180f1e85141f4f17a7132d049d Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 3 Mar 2020 14:26:53 -0800 Subject: [PATCH 71/88] Add support for getting the access specifier of CXXBaseSpecifier nodes --- src/clang.rs | 6 +++--- src/clang/clang_interface.cpp | 14 ++++++++++++++ src/clang/clang_interface.hpp | 1 + src/clang/clang_interface.rs | 6 ++++++ src/clang/clang_interface_impl.hpp | 1 + src/clang/libclang_compat.cpp | 6 +----- 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index f9579a6a7f..102a9b4209 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -847,10 +847,10 @@ impl Cursor { /// Get the access specifier for this cursor's referent. pub fn access_specifier(&self) -> CX_CXXAccessSpecifier { match self.node { - ASTNode::Decl(d) => unsafe { - clang_interface::Decl_getAccess(d) + ASTNode::Decl(d) => unsafe { clang_interface::Decl_getAccess(d) }, + ASTNode::CXXBaseSpecifier(b) => unsafe { + clang_interface::CXXBaseSpecifier_getAccess(b) }, - // TODO(sjc): handle CXXBaseSpecifier cursors _ => CX_CXXInvalidAccessSpecifier, } } diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index 11e19ec150..a9399ead40 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -1669,3 +1669,17 @@ BindgenStringRef PreprocessedEntity_getSpelling(const PreprocessedEntity *PPE) { return stringref(ME->getName()->getName()); return stringref(); } + +CX_CXXAccessSpecifier Decl_getAccess(const Decl *D) { + auto spec = AS_none; + if (D) + spec = D->getAccess(); + return TranslateCXXAccessSpecifier(spec); +} + +CX_CXXAccessSpecifier CXXBaseSpecifier_getAccess(const CXXBaseSpecifier *B) { + auto spec = AS_none; + if (B) + spec = B->getAccessSpecifier(); + return TranslateCXXAccessSpecifier(spec); +} diff --git a/src/clang/clang_interface.hpp b/src/clang/clang_interface.hpp index 582bfd761f..65f384f2f8 100644 --- a/src/clang/clang_interface.hpp +++ b/src/clang/clang_interface.hpp @@ -256,6 +256,7 @@ SourceLocation *CXXBaseSpecifier_getLocation(const CXXBaseSpecifier *); SourceLocation *Attr_getLocation(const Attr *); SourceLocation *PreprocessedEntity_getLocation(const PreprocessedEntity *); BindgenSourceRange CXXBaseSpecifier_getSourceRange(const CXXBaseSpecifier *); +CX_CXXAccessSpecifier CXXBaseSpecifier_getAccess(const CXXBaseSpecifier *); BindgenSourceRange Attr_getSourceRange(const Attr *); BindgenSourceRange PreprocessedEntity_getSourceRange(const PreprocessedEntity *); diff --git a/src/clang/clang_interface.rs b/src/clang/clang_interface.rs index 9e13b6c294..51282cd65e 100644 --- a/src/clang/clang_interface.rs +++ b/src/clang/clang_interface.rs @@ -7257,6 +7257,12 @@ extern "C" { arg1: *const clang_CXXBaseSpecifier, ) -> BindgenSourceRange; } +extern "C" { + #[link_name = "\u{1}_Z26CXXBaseSpecifier_getAccessPKN5clang16CXXBaseSpecifierE"] + pub fn CXXBaseSpecifier_getAccess( + arg1: *const clang_CXXBaseSpecifier, + ) -> CX_CXXAccessSpecifier::Type; +} extern "C" { #[link_name = "\u{1}_Z19Attr_getSourceRangePKN5clang4AttrE"] pub fn Attr_getSourceRange(arg1: *const clang_Attr) -> BindgenSourceRange; diff --git a/src/clang/clang_interface_impl.hpp b/src/clang/clang_interface_impl.hpp index b39f3fe4fb..1c5076994f 100644 --- a/src/clang/clang_interface_impl.hpp +++ b/src/clang/clang_interface_impl.hpp @@ -45,5 +45,6 @@ Optional> GetTemplateArguments(QualType Type); unsigned GetTemplateArgumentArraySize(ArrayRef TA); Optional FindTemplateArgumentTypeAt(ArrayRef TA, unsigned index); +CX_CXXAccessSpecifier TranslateCXXAccessSpecifier(AccessSpecifier spec); #endif // BINDGEN_CLANG_INTERFACE_IMPL_H diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 1d68b10f22..e90aeff0f9 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -1481,11 +1481,7 @@ CXVisibilityKind Decl_getVisibility(const Decl *D) { } // Adapted from clang_getCXXAccessSpecifier in CIndexCXX.cpp -CX_CXXAccessSpecifier Decl_getAccess(const Decl *D) { - AccessSpecifier spec = AS_none; - if (D) - spec = D->getAccess(); - +CX_CXXAccessSpecifier TranslateCXXAccessSpecifier(AccessSpecifier spec) { switch (spec) { case AS_public: return CX_CXXPublic; case AS_protected: return CX_CXXProtected; From c11af7488e2591e5c5ae76c57799e6650f7cfe8e Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 3 Mar 2020 14:27:32 -0800 Subject: [PATCH 72/88] Reimplement get_included_file_name --- src/clang.rs | 23 +++++++++++++---------- src/clang/clang_interface.cpp | 8 +++++++- src/clang/clang_interface.hpp | 3 ++- src/clang/clang_interface.rs | 10 ++++++++-- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index 102a9b4209..efb2673c45 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -1012,16 +1012,19 @@ impl Cursor { /// /// Returns None if the cursor does not include a file, otherwise the file's full name pub fn get_included_file_name(&self) -> Option { - // TODO(sjc): implement - None - // let file = unsafe { clang_sys::clang_getIncludedFile(self.x) }; - // if file.is_null() { - // None - // } else { - // Some(unsafe { - // cxstring_into_string(clang_sys::clang_getFileName(file)) - // }) - // } + let file = match self.node { + ASTNode::PreprocessedEntity(e) => unsafe { + clang_interface::PreprocessedEntity_getIncludedFile(e) + }, + _ => ptr::null(), + }; + if file.is_null() { + None + } else { + Some(unsafe { + clang_interface::FileEntry_getName(file).to_string() + }) + } } } diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index a9399ead40..44bebbd90f 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -1608,7 +1608,7 @@ BindgenStringRef HTMLStartTag_getAttrValue(const comments::Comment *C, unsigned } } -BindgenStringRef FileEntry_getName(FileEntry *F) { +BindgenStringRef FileEntry_getName(const FileEntry *F) { if (!F) return stringref(); return stringref(F->getName()); @@ -1670,6 +1670,12 @@ BindgenStringRef PreprocessedEntity_getSpelling(const PreprocessedEntity *PPE) { return stringref(); } +const FileEntry *PreprocessedEntity_getIncludedFile(const PreprocessedEntity *PPE) { + if (const auto *ID = dyn_cast_or_null(PPE)) + return ID->getFile(); + return nullptr; +} + CX_CXXAccessSpecifier Decl_getAccess(const Decl *D) { auto spec = AS_none; if (D) diff --git a/src/clang/clang_interface.hpp b/src/clang/clang_interface.hpp index 65f384f2f8..90d1ed3777 100644 --- a/src/clang/clang_interface.hpp +++ b/src/clang/clang_interface.hpp @@ -245,7 +245,7 @@ BindgenStringRef CursorKind_getSpelling(CXCursorKind); BindgenStringRef TypeKind_getSpelling(CXTypeKind); BindgenStringRef PreprocessedEntity_getSpelling(const PreprocessedEntity *); -BindgenStringRef FileEntry_getName(FileEntry *); +BindgenStringRef FileEntry_getName(const FileEntry *); BindgenStringRef getClangVersion(); @@ -255,6 +255,7 @@ BindgenStringRef CXXBaseSpecifier_getSpelling(const CXXBaseSpecifier *); SourceLocation *CXXBaseSpecifier_getLocation(const CXXBaseSpecifier *); SourceLocation *Attr_getLocation(const Attr *); SourceLocation *PreprocessedEntity_getLocation(const PreprocessedEntity *); +const FileEntry *PreprocessedEntity_getIncludedFile(const PreprocessedEntity *); BindgenSourceRange CXXBaseSpecifier_getSourceRange(const CXXBaseSpecifier *); CX_CXXAccessSpecifier CXXBaseSpecifier_getAccess(const CXXBaseSpecifier *); BindgenSourceRange Attr_getSourceRange(const Attr *); diff --git a/src/clang/clang_interface.rs b/src/clang/clang_interface.rs index 51282cd65e..8e3ffa37b2 100644 --- a/src/clang/clang_interface.rs +++ b/src/clang/clang_interface.rs @@ -7208,8 +7208,8 @@ extern "C" { ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z17FileEntry_getNamePN5clang9FileEntryE"] - pub fn FileEntry_getName(arg1: *mut clang_FileEntry) -> BindgenStringRef; + #[link_name = "\u{1}_Z17FileEntry_getNamePKN5clang9FileEntryE"] + pub fn FileEntry_getName(arg1: *const clang_FileEntry) -> BindgenStringRef; } extern "C" { #[link_name = "\u{1}_Z15getClangVersionv"] @@ -7251,6 +7251,12 @@ extern "C" { arg1: *const clang_PreprocessedEntity, ) -> *mut clang_SourceLocation; } +extern "C" { + #[link_name = "\u{1}_Z34PreprocessedEntity_getIncludedFilePKN5clang18PreprocessedEntityE"] + pub fn PreprocessedEntity_getIncludedFile( + arg1: *const clang_PreprocessedEntity, + ) -> *const clang_FileEntry; +} extern "C" { #[link_name = "\u{1}_Z31CXXBaseSpecifier_getSourceRangePKN5clang16CXXBaseSpecifierE"] pub fn CXXBaseSpecifier_getSourceRange( From 35b3d98782bbd4d164b453f10b3633a5032fbb06 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 3 Mar 2020 14:30:50 -0800 Subject: [PATCH 73/88] Clean up old comments and whitespace --- src/clang.rs | 8 -------- src/clang/clang_interface.cpp | 37 +++++++++++++++++------------------ 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index efb2673c45..efafbdc390 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -1392,13 +1392,6 @@ impl Type { /// Get the number of template arguments this type has, or `None` if it is /// not some kind of template. pub fn num_template_args(&self) -> Option { - // If an old libclang is loaded, we have no hope of answering this - // question correctly. However, that's no reason to panic when - // generating bindings for simple C headers with an old libclang. - // if !clang_interface::Type_getNumTemplateArguments::is_loaded() { - // return None; - // } - let n = unsafe { clang_interface::Type_getNumTemplateArguments(self.x) }; if n >= 0 { Some(n as u32) @@ -1866,7 +1859,6 @@ impl fmt::Debug for TranslationUnit { impl TranslationUnit { /// Parse a source file into a translation unit. pub fn parse( - // ix: &Index, file: &str, cmd_args: &[String], unsaved: &[UnsavedFile], diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index 44bebbd90f..74d3d83052 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -65,7 +65,6 @@ BindgenStringRefSet make_stringrefset(std::vector &string_vec) { set.strings[i] = stringref(string_vec[i]); return set; } - void freeString(BindgenStringRef s) { delete[] s.s; @@ -228,7 +227,7 @@ bool CursorKind_isInvalid(CXCursorKind kind) { const Decl *Decl_getLexicalParent(const Decl *D) { if (!D) return nullptr; - + const DeclContext *DC = D->getLexicalDeclContext(); if (!DC) return nullptr; @@ -239,7 +238,7 @@ const Decl *Decl_getLexicalParent(const Decl *D) { const Decl *Decl_getSemanticParent(const Decl *D) { if (!D) return nullptr; - + const DeclContext *DC = D->getDeclContext(); if (!DC) return nullptr; @@ -754,22 +753,22 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { case Stmt::UnresolvedLookupExprClass: case Stmt::TypoExprClass: // A typo could actually be a DeclRef or a MemberRef return CXCursor_DeclRefExpr; - + case Stmt::CXXDependentScopeMemberExprClass: case Stmt::CXXPseudoDestructorExprClass: - case Stmt::MemberExprClass: + case Stmt::MemberExprClass: case Stmt::MSPropertyRefExprClass: case Stmt::ObjCIsaExprClass: - case Stmt::ObjCIvarRefExprClass: - case Stmt::ObjCPropertyRefExprClass: + case Stmt::ObjCIvarRefExprClass: + case Stmt::ObjCPropertyRefExprClass: case Stmt::UnresolvedMemberExprClass: return CXCursor_MemberRefExpr; - - case Stmt::CallExprClass: + + case Stmt::CallExprClass: case Stmt::CXXOperatorCallExprClass: case Stmt::CXXMemberCallExprClass: case Stmt::CUDAKernelCallExprClass: - case Stmt::CXXConstructExprClass: + case Stmt::CXXConstructExprClass: #if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9) case Stmt::CXXInheritedCtorInitExprClass: #endif // CLANG_VERSION > 3.8 @@ -777,13 +776,13 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { case Stmt::CXXUnresolvedConstructExprClass: case Stmt::UserDefinedLiteralClass: return CXCursor_CallExpr; - + case Stmt::LambdaExprClass: return CXCursor_LambdaExpr; - + case Stmt::ObjCMessageExprClass: return CXCursor_ObjCMessageExpr; - + case Stmt::MSDependentExistsStmtClass: return CXCursor_UnexposedStmt; case Stmt::OMPParallelDirectiveClass: @@ -1492,22 +1491,22 @@ QualType Type_getArgType(QualType T, unsigned i) { return QualType(); return make_type_compatible(FD->getParamType(i)); } - + return QualType(); } int Type_getNumArgTypes(QualType T) { if (T.isNull()) return -1; - + if (const FunctionProtoType *FD = T->getAs()) { return FD->getNumParams(); } - + if (T->getAs()) { return 0; } - + return -1; } @@ -1527,14 +1526,14 @@ bool Type_isFunctionTypeVariadic(QualType T) { if (T->getAs()) return true; - + return false; } QualType Type_getResultType(QualType T) { if (T.isNull()) return QualType(); - + if (const FunctionType *FD = T->getAs()) return make_type_compatible(FD->getReturnType()); From 3b222e1839fb808414765def95cfc896233176db Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 3 Mar 2020 14:32:13 -0800 Subject: [PATCH 74/88] Cargo fmt modified and new files --- build.rs | 131 +++++++++++++--------- src/clang.rs | 311 ++++++++++++++++++++++++++++++++------------------- 2 files changed, 277 insertions(+), 165 deletions(-) diff --git a/build.rs b/build.rs index bbee9641d6..c26974e090 100644 --- a/build.rs +++ b/build.rs @@ -99,11 +99,11 @@ mod clang_ast { let mut clang_cmake_dir = format!("{}/cmake/clang", llvm_lib_dir); if let Some((major_version, minor_version)) = llvm_info.version { - if (major_version == 3 && minor_version <= 8) - || major_version < 3 - { - llvm_cmake_dir = format!("{}/../share/llvm/cmake", llvm_lib_dir); - clang_cmake_dir = format!("{}/../share/clang/cmake", llvm_lib_dir); + if (major_version == 3 && minor_version <= 8) || major_version < 3 { + llvm_cmake_dir = + format!("{}/../share/llvm/cmake", llvm_lib_dir); + clang_cmake_dir = + format!("{}/../share/clang/cmake", llvm_lib_dir); } } @@ -180,7 +180,7 @@ mod clang_ast { fn find_llvm_config() -> Option { // Explicitly provided path in LLVM_CONFIG_PATH build_var("LLVM_CONFIG_PATH") - // Relative to LLVM_LIB_DIR + // Relative to LLVM_LIB_DIR .or_else(|| { build_var("LLVM_LIB_DIR").map(|d| { String::from( @@ -192,7 +192,7 @@ mod clang_ast { ) }) }) - // In PATH + // In PATH .or_else(|| { [ "llvm-config-7.0", @@ -202,37 +202,46 @@ mod clang_ast { // Homebrew install location on MacOS "/usr/local/opt/llvm/bin/llvm-config", ] - .iter() - .find_map(|c| { - if Command::new(c) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .spawn() - .is_ok() - { - Some(String::from(*c)) - } else { - None - } - }) + .iter() + .find_map(|c| { + if Command::new(c) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn() + .is_ok() + { + Some(String::from(*c)) + } else { + None + } + }) }) } /// Invoke given `command`, if any, with the specified arguments. - fn invoke_command(command: Option, args: I) -> Option - where + fn invoke_command( + command: Option, + args: I, + ) -> Option + where I: IntoIterator, S: AsRef, C: AsRef, { command.and_then(|c| { - Command::new(c).args(args).output().ok().and_then(|output| { - if output.status.success() { - Some(String::from_utf8_lossy(&output.stdout).trim().to_string()) - } else { - None - } - }) + Command::new(c).args(args).output().ok().and_then( + |output| { + if output.status.success() { + Some( + String::from_utf8_lossy(&output.stdout) + .trim() + .to_string(), + ) + } else { + None + } + }, + ) }) } @@ -256,7 +265,10 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: ) }; - let llvm_shared_libs = invoke_command(llvm_config.as_ref(), &["--libs", "--link-shared"]); + let llvm_shared_libs = invoke_command( + llvm_config.as_ref(), + &["--libs", "--link-shared"], + ); // /lib/rustlib//lib/ contains a libLLVM DSO for the // rust compiler. On MacOS, this lib is named libLLVM.dylib, which will @@ -277,10 +289,14 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: } // Windows is not supported }; let mut dylib_file = String::from("lib"); - dylib_file.push_str(llvm_shared_libs.trim_start_matches("-l")); + dylib_file + .push_str(llvm_shared_libs.trim_start_matches("-l")); dylib_file.push_str(dylib_suffix); - let sysroot = - invoke_command(env::var("RUSTC").ok().as_ref(), &["--print=sysroot"]).unwrap(); + let sysroot = invoke_command( + env::var("RUSTC").ok().as_ref(), + &["--print=sysroot"], + ) + .unwrap(); // Does /lib/rustlib//lib/ exist? let mut libllvm_path = PathBuf::new(); @@ -302,7 +318,8 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: } else { vec!["--shared-mode"] }; - invoke_command(llvm_config.as_ref(), &args).map_or(false, |c| c == "static") + invoke_command(llvm_config.as_ref(), &args) + .map_or(false, |c| c == "static") }; let link_mode = if link_statically { @@ -311,22 +328,29 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: "--link-shared" }; - let version_string = invoke_command(llvm_config.as_ref(), &["--version"]) - .or_else(|| { - invoke_command(Some(&format!("{}/../bin/clang", lib_dir)), &["--version"]) - .and_then(|output| Some(output.split(" ").nth(2)?.to_string())) - }); - let version = version_string - .and_then(|version| { - let mut split = version.split("."); - let major: i32 = split.next()?.parse().ok()?; - let minor: i32 = split.next()?.parse().ok()?; - Some((major, minor)) - }); + let version_string = invoke_command( + llvm_config.as_ref(), + &["--version"], + ) + .or_else(|| { + invoke_command( + Some(&format!("{}/../bin/clang", lib_dir)), + &["--version"], + ) + .and_then(|output| Some(output.split(" ").nth(2)?.to_string())) + }); + let version = version_string.and_then(|version| { + let mut split = version.split("."); + let major: i32 = split.next()?.parse().ok()?; + let minor: i32 = split.next()?.parse().ok()?; + Some((major, minor)) + }); let mut supports_link_mode = true; if let Some((major_version, minor_version)) = version { - if major_version < 3 || (major_version == 3 && minor_version <= 8) { + if major_version < 3 + || (major_version == 3 && minor_version <= 8) + { supports_link_mode = false; } } @@ -358,11 +382,12 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: if supports_link_mode { args.insert(1, link_mode); } - let mut libs: Vec = invoke_command(llvm_config.as_ref(), &args) - .unwrap_or("-lLLVM".to_string()) - .split_whitespace() - .map(|lib| String::from(lib.trim_start_matches("-l"))) - .collect(); + let mut libs: Vec = + invoke_command(llvm_config.as_ref(), &args) + .unwrap_or("-lLLVM".to_string()) + .split_whitespace() + .map(|lib| String::from(lib.trim_start_matches("-l"))) + .collect(); libs.extend( build_var("LLVM_SYSTEM_LIBS") @@ -390,7 +415,7 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: .trim_start_matches("lib") .into() } - }) + }), ); Self { diff --git a/src/clang.rs b/src/clang.rs index efafbdc390..be29b84d5d 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -15,32 +15,35 @@ use std::{mem, ptr, slice}; #[allow(non_camel_case_types, non_snake_case, missing_docs)] mod clang_interface; -pub use self::clang_interface::CXDiagnosticSeverity::Type as CXDiagnosticSeverity; pub use self::clang_interface::CXCallingConv::Type as CXCallingConv; -pub use self::clang_interface::CXLinkageKind::Type as CXLinkageKind; -pub use self::clang_interface::CX_CXXAccessSpecifier::Type as CX_CXXAccessSpecifier; -pub use self::clang_interface::CXEvalResultKind::Type as CXEvalResultKind; -pub use self::clang_interface::CXTokenKind::Type as CXTokenKind; -pub use self::clang_interface::CXVisibilityKind::Type as CXVisibilityKind; -pub use self::clang_interface::CXChildVisitResult::Type as CXChildVisitResult; -pub use self::clang_interface::CXCursorKind::Type as CXCursorKind; -pub use self::clang_interface::CXTypeKind::Type as CXTypeKind; -pub use self::clang_interface::CXCommentKind::*; -pub use self::clang_interface::CXDiagnosticSeverity::*; pub use self::clang_interface::CXCallingConv::*; -pub use self::clang_interface::CX_CXXAccessSpecifier::*; +pub use self::clang_interface::CXChildVisitResult::Type as CXChildVisitResult; pub use self::clang_interface::CXChildVisitResult::*; +pub use self::clang_interface::CXCommentKind::*; +pub use self::clang_interface::CXCursorKind::Type as CXCursorKind; pub use self::clang_interface::CXCursorKind::*; +pub use self::clang_interface::CXDiagnosticSeverity::Type as CXDiagnosticSeverity; +pub use self::clang_interface::CXDiagnosticSeverity::*; +pub use self::clang_interface::CXEvalResultKind::Type as CXEvalResultKind; pub use self::clang_interface::CXEvalResultKind::*; +pub use self::clang_interface::CXLinkageKind::Type as CXLinkageKind; pub use self::clang_interface::CXLinkageKind::*; -pub use self::clang_interface::CXTypeKind::*; +pub use self::clang_interface::CXTokenKind::Type as CXTokenKind; pub use self::clang_interface::CXTokenKind::*; -pub use self::clang_interface::CXVisitorResult::*; +pub use self::clang_interface::CXTypeKind::Type as CXTypeKind; +pub use self::clang_interface::CXTypeKind::*; +pub use self::clang_interface::CXVisibilityKind::Type as CXVisibilityKind; pub use self::clang_interface::CXVisibilityKind::*; +pub use self::clang_interface::CXVisitorResult::*; +pub use self::clang_interface::CX_CXXAccessSpecifier::Type as CX_CXXAccessSpecifier; +pub use self::clang_interface::CX_CXXAccessSpecifier::*; impl clang_interface::BindgenSourceRange { fn null() -> Self { - Self { B: ptr::null_mut(), E: ptr::null_mut() } + Self { + B: ptr::null_mut(), + E: ptr::null_mut(), + } } } @@ -193,11 +196,19 @@ impl Cursor { pub fn spelling(&self) -> String { unsafe { match self.node { - ASTNode::Decl(d) => clang_interface::Decl_getSpelling(d).to_string(), - ASTNode::Expr(e) => clang_interface::Expr_getSpelling(e).to_string(), - ASTNode::CXXBaseSpecifier(b) => clang_interface::CXXBaseSpecifier_getSpelling(b) - .to_string(), - ASTNode::PreprocessedEntity(e) => clang_interface::PreprocessedEntity_getSpelling(e).to_string(), + ASTNode::Decl(d) => { + clang_interface::Decl_getSpelling(d).to_string() + } + ASTNode::Expr(e) => { + clang_interface::Expr_getSpelling(e).to_string() + } + ASTNode::CXXBaseSpecifier(b) => { + clang_interface::CXXBaseSpecifier_getSpelling(b).to_string() + } + ASTNode::PreprocessedEntity(e) => { + clang_interface::PreprocessedEntity_getSpelling(e) + .to_string() + } _ => String::new(), } } @@ -207,7 +218,10 @@ impl Cursor { pub fn mangling(&self) -> String { unsafe { match self.node { - ASTNode::Decl(d) => clang_interface::Decl_getMangling(d, self.context()).to_string(), + ASTNode::Decl(d) => { + clang_interface::Decl_getMangling(d, self.context()) + .to_string() + } _ => String::new(), } } @@ -218,7 +232,9 @@ impl Cursor { pub fn cxx_manglings(&self) -> Result, ()> { unsafe { let manglings = match self.node { - ASTNode::Decl(d) => clang_interface::Decl_getCXXManglings(d, self.context()), + ASTNode::Decl(d) => { + clang_interface::Decl_getCXXManglings(d, self.context()) + } _ => return Err(()), }; let count = manglings.len as usize; @@ -311,8 +327,9 @@ impl Cursor { self.cur_type() .num_template_args() .or_else(|| { - let n: c_int = - unsafe { clang_interface::Decl_getNumTemplateArguments(decl) }; + let n: c_int = unsafe { + clang_interface::Decl_getNumTemplateArguments(decl) + }; if n >= 0 { Some(n as u32) @@ -345,11 +362,10 @@ impl Cursor { pub fn is_toplevel(&self) -> bool { let mut semantic_parent = self.fallible_semantic_parent(); - while semantic_parent.is_some() && - (semantic_parent.unwrap().kind() == CXCursor_Namespace || - semantic_parent.unwrap().kind() == - CXCursor_NamespaceAlias || - semantic_parent.unwrap().kind() == CXCursor_NamespaceRef) + while semantic_parent.is_some() + && (semantic_parent.unwrap().kind() == CXCursor_Namespace + || semantic_parent.unwrap().kind() == CXCursor_NamespaceAlias + || semantic_parent.unwrap().kind() == CXCursor_NamespaceRef) { semantic_parent = semantic_parent.unwrap().fallible_semantic_parent(); @@ -367,9 +383,9 @@ impl Cursor { /// clang doesn't expose a proper declaration for these types. pub fn is_template_like(&self) -> bool { match self.kind() { - CXCursor_ClassTemplate | - CXCursor_ClassTemplatePartialSpecialization | - CXCursor_TypeAliasTemplateDecl => true, + CXCursor_ClassTemplate + | CXCursor_ClassTemplatePartialSpecialization + | CXCursor_TypeAliasTemplateDecl => true, _ => false, } } @@ -397,9 +413,9 @@ impl Cursor { /// Is the referent a fully specialized template specialization without any /// remaining free template arguments? pub fn is_fully_specialized_template(&self) -> bool { - self.is_template_specialization() && - self.kind() != CXCursor_ClassTemplatePartialSpecialization && - self.num_template_args().unwrap_or(0) > 0 + self.is_template_specialization() + && self.kind() != CXCursor_ClassTemplatePartialSpecialization + && self.num_template_args().unwrap_or(0) > 0 } /// Is the referent a template specialization that still has remaining free @@ -432,9 +448,13 @@ impl Cursor { let x = match self.node { ASTNode::Decl(d) => clang_interface::Decl_getLocation(d), ASTNode::Expr(e) => clang_interface::Expr_getLocation(e), - ASTNode::CXXBaseSpecifier(b) => clang_interface::CXXBaseSpecifier_getLocation(b), + ASTNode::CXXBaseSpecifier(b) => { + clang_interface::CXXBaseSpecifier_getLocation(b) + } ASTNode::Attr(b) => clang_interface::Attr_getLocation(b), - ASTNode::PreprocessedEntity(p) => clang_interface::PreprocessedEntity_getLocation(p), + ASTNode::PreprocessedEntity(p) => { + clang_interface::PreprocessedEntity_getLocation(p) + } ASTNode::Invalid => ptr::null(), }; SourceLocation { x, unit: self.unit } @@ -452,9 +472,13 @@ impl Cursor { match self.node { ASTNode::Decl(d) => clang_interface::Decl_getSourceRange(d), ASTNode::Expr(e) => clang_interface::Expr_getSourceRange(e), - ASTNode::CXXBaseSpecifier(b) => clang_interface::CXXBaseSpecifier_getSourceRange(b), + ASTNode::CXXBaseSpecifier(b) => { + clang_interface::CXXBaseSpecifier_getSourceRange(b) + } ASTNode::Attr(b) => clang_interface::Attr_getSourceRange(b), - ASTNode::PreprocessedEntity(b) => clang_interface::PreprocessedEntity_getSourceRange(b), + ASTNode::PreprocessedEntity(b) => { + clang_interface::PreprocessedEntity_getSourceRange(b) + } _ => clang_interface::BindgenSourceRange::null(), } } @@ -464,7 +488,8 @@ impl Cursor { pub fn raw_comment(&self) -> Option { let s = match self.node { ASTNode::Decl(d) => unsafe { - clang_interface::Decl_getRawCommentText(d, self.context()).to_string() + clang_interface::Decl_getRawCommentText(d, self.context()) + .to_string() }, _ => return None, }; @@ -490,9 +515,13 @@ impl Cursor { pub fn cur_type(&self) -> Type { unsafe { let x = match self.node { - ASTNode::Decl(d) => clang_interface::Decl_getType(d, self.context()), + ASTNode::Decl(d) => { + clang_interface::Decl_getType(d, self.context()) + } ASTNode::Expr(e) => clang_interface::Expr_getType(e), - ASTNode::CXXBaseSpecifier(base) => clang_interface::CXXBaseSpecifier_getType(base), + ASTNode::CXXBaseSpecifier(base) => { + clang_interface::CXXBaseSpecifier_getType(base) + } _ => mem::zeroed(), }; Type { x, unit: self.unit } @@ -503,7 +532,8 @@ impl Cursor { /// a declaration, get the cursor pointing to the referenced type or type of /// the declared thing. pub fn definition(&self) -> Option { - let is_reference = self.kind >= CXCursor_FirstRef && self.kind <= CXCursor_LastRef; + let is_reference = + self.kind >= CXCursor_FirstRef && self.kind <= CXCursor_LastRef; let def = match self.node { ASTNode::Decl(d) => unsafe { clang_interface::Decl_getDefinition(d, is_reference) @@ -592,7 +622,7 @@ impl Cursor { self.unit, mem::transmute(&mut visitor), ); - } + }, ASTNode::Expr(e) => unsafe { clang_interface::Expr_visitChildren( e, @@ -601,7 +631,7 @@ impl Cursor { self.unit, mem::transmute(&mut visitor), ); - } + }, ASTNode::CXXBaseSpecifier(b) => unsafe { clang_interface::CXXBaseSpecifier_visitChildren( b, @@ -610,7 +640,7 @@ impl Cursor { self.unit, mem::transmute(&mut visitor), ); - } + }, _ => panic!("Tried to visit: {:?}", self), } } @@ -699,7 +729,9 @@ impl Cursor { pub fn enum_type(&self) -> Option { let x = unsafe { match self.node { - ASTNode::Decl(d) => clang_interface::Decl_getEnumDeclIntegerType(d), + ASTNode::Decl(d) => { + clang_interface::Decl_getEnumDeclIntegerType(d) + } _ => mem::zeroed(), } }; @@ -717,7 +749,7 @@ impl Cursor { match self.node { ASTNode::Decl(d) => unsafe { Some(clang_interface::Decl_getEnumConstantValue(d)) - } + }, _ => None, } } @@ -729,7 +761,7 @@ impl Cursor { match self.node { ASTNode::Decl(d) => unsafe { Some(clang_interface::Decl_getEnumConstantUnsignedValue(d)) - } + }, _ => None, } } @@ -748,11 +780,11 @@ impl Cursor { let mut found_attr = false; self.visit(|cur| { let kind = cur.kind(); - found_attr = clang_kind.map_or(false, |k| k == kind) || - (kind == CXCursor_UnexposedAttr && - cur.tokens().iter().any(|t| { - t.kind == CXToken_Identifier && - t.spelling() == name.as_bytes() + found_attr = clang_kind.map_or(false, |k| k == kind) + || (kind == CXCursor_UnexposedAttr + && cur.tokens().iter().any(|t| { + t.kind == CXToken_Identifier + && t.spelling() == name.as_bytes() })); if found_attr { @@ -770,7 +802,9 @@ impl Cursor { pub fn typedef_type(&self) -> Option { match self.node { ASTNode::Decl(d) => Some(Type { - x: unsafe { clang_interface::Decl_getTypedefDeclUnderlyingType(d) }, + x: unsafe { + clang_interface::Decl_getTypedefDeclUnderlyingType(d) + }, unit: self.unit, }), _ => None, @@ -790,7 +824,9 @@ impl Cursor { /// Get the visibility of this cursor's referent. pub fn visibility(&self) -> CXVisibilityKind { match self.node { - ASTNode::Decl(d) => unsafe { clang_interface::Decl_getVisibility(d) }, + ASTNode::Decl(d) => unsafe { + clang_interface::Decl_getVisibility(d) + }, _ => CXVisibility_Invalid, } } @@ -809,10 +845,16 @@ impl Cursor { .map(|i| { let node = match self.node { ASTNode::Decl(d) => unsafe { - ASTNode::Decl(clang_interface::Decl_getArgument(d, i as c_uint)) + ASTNode::Decl(clang_interface::Decl_getArgument( + d, + i as c_uint, + )) }, ASTNode::Expr(e) => unsafe { - ASTNode::Expr(clang_interface::Expr_getArgument(e, i as c_uint)) + ASTNode::Expr(clang_interface::Expr_getArgument( + e, + i as c_uint, + )) }, _ => ASTNode::Invalid, }; @@ -939,8 +981,8 @@ impl Cursor { { let mut found_cant_eval = false; self.visit(|c| { - if c.kind() == CXCursor_TypeRef && - c.cur_type().canonical_type().kind() == CXType_Unexposed + if c.kind() == CXCursor_TypeRef + && c.cur_type().canonical_type().kind() == CXType_Unexposed { found_cant_eval = true; return CXChildVisit_Break; @@ -955,8 +997,12 @@ impl Cursor { } unsafe { let x = match self.node { - ASTNode::Decl(d) => clang_interface::Decl_Evaluate(d, self.context()), - ASTNode::Expr(e) => clang_interface::Expr_Evaluate(e, self.context()), + ASTNode::Decl(d) => { + clang_interface::Decl_Evaluate(d, self.context()) + } + ASTNode::Expr(e) => { + clang_interface::Expr_Evaluate(e, self.context()) + } _ => return None, }; Some(EvalResult { x }) @@ -967,7 +1013,9 @@ impl Cursor { pub fn ret_type(&self) -> Option { match self.node { ASTNode::Decl(d) => Some(Type { - x: unsafe { clang_interface::Decl_getResultType(d, self.context()) }, + x: unsafe { + clang_interface::Decl_getResultType(d, self.context()) + }, unit: self.unit, }), _ => None, @@ -1042,7 +1090,9 @@ impl<'a> RawTokens<'a> { let mut token_count = 0; let range = cursor.extent(); let tu = cursor.translation_unit(); - unsafe { clang_interface::tokenize(tu, range, &mut tokens, &mut token_count) }; + unsafe { + clang_interface::tokenize(tu, range, &mut tokens, &mut token_count) + }; Self { cursor, tu, @@ -1112,7 +1162,8 @@ impl<'a> Iterator for ClangTokenIterator<'a> { let raw = self.raw.next()?; unsafe { let kind = clang_interface::getTokenKind(*raw); - let spelling = clang_interface::getTokenSpelling(self.tu, *raw).to_cstring(); + let spelling = + clang_interface::getTokenSpelling(self.tu, *raw).to_cstring(); Some(ClangToken { kind, spelling }) } } @@ -1145,16 +1196,25 @@ where // the range [FirstRef, LastRef] if raw_node.kind == CXCursor_CXXBaseSpecifier { ASTNode::CXXBaseSpecifier(raw_node.ptr.base) - } else if (raw_node.kind >= CXCursor_FirstDecl && raw_node.kind <= CXCursor_LastDecl) - || (raw_node.kind >= CXCursor_FirstExtraDecl && raw_node.kind <= CXCursor_LastExtraDecl) - || (raw_node.kind >= CXCursor_FirstRef && raw_node.kind <= CXCursor_LastRef) + } else if (raw_node.kind >= CXCursor_FirstDecl + && raw_node.kind <= CXCursor_LastDecl) + || (raw_node.kind >= CXCursor_FirstExtraDecl + && raw_node.kind <= CXCursor_LastExtraDecl) + || (raw_node.kind >= CXCursor_FirstRef + && raw_node.kind <= CXCursor_LastRef) { ASTNode::Decl(raw_node.ptr.decl) - } else if raw_node.kind >= CXCursor_FirstExpr && raw_node.kind <= CXCursor_LastExpr { + } else if raw_node.kind >= CXCursor_FirstExpr + && raw_node.kind <= CXCursor_LastExpr + { ASTNode::Expr(raw_node.ptr.expr) - } else if raw_node.kind >= CXCursor_FirstAttr && raw_node.kind <= CXCursor_LastAttr { + } else if raw_node.kind >= CXCursor_FirstAttr + && raw_node.kind <= CXCursor_LastAttr + { ASTNode::Attr(raw_node.ptr.attr) - } else if raw_node.kind >= CXCursor_FirstPreprocessing && raw_node.kind <= CXCursor_LastPreprocessing { + } else if raw_node.kind >= CXCursor_FirstPreprocessing + && raw_node.kind <= CXCursor_LastPreprocessing + { ASTNode::PreprocessedEntity(raw_node.ptr.ppe) } else { return CXChildVisit_Recurse; @@ -1218,8 +1278,8 @@ pub enum LayoutError { impl ::std::convert::From for LayoutError { fn from(val: i32) -> Self { - use self::LayoutError::*; use self::clang_interface::CXTypeLayoutError::*; + use self::LayoutError::*; match val { CXTypeLayoutError_Invalid => Invalid, @@ -1280,7 +1340,10 @@ impl Type { /// Get a raw display name for this type. pub fn spelling(&self) -> String { - let s = unsafe { clang_interface::Type_getTypeSpelling(self.x, self.context()).to_string() }; + let s = unsafe { + clang_interface::Type_getTypeSpelling(self.x, self.context()) + .to_string() + }; // Clang 5.0 introduced changes in the spelling API so it returned the // full qualified name. Let's undo that here. if s.split("::").all(|s| is_valid_identifier(s)) { @@ -1312,7 +1375,9 @@ impl Type { } // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 CXType_Auto if self.is_non_deductible_auto_type() => return -6, - _ => unsafe { clang_interface::Type_getSizeOf(self.x, self.context()) }, + _ => unsafe { + clang_interface::Type_getSizeOf(self.x, self.context()) + }, } } @@ -1325,7 +1390,9 @@ impl Type { } // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 CXType_Auto if self.is_non_deductible_auto_type() => return -6, - _ => unsafe { clang_interface::Type_getAlignOf(self.x, self.context()) }, + _ => unsafe { + clang_interface::Type_getAlignOf(self.x, self.context()) + }, } } @@ -1392,7 +1459,8 @@ impl Type { /// Get the number of template arguments this type has, or `None` if it is /// not some kind of template. pub fn num_template_args(&self) -> Option { - let n = unsafe { clang_interface::Type_getNumTemplateArguments(self.x) }; + let n = + unsafe { clang_interface::Type_getNumTemplateArguments(self.x) }; if n >= 0 { Some(n as u32) } else { @@ -1419,7 +1487,9 @@ impl Type { self.num_args().ok().map(|num| { (0..num) .map(|i| Type { - x: unsafe { clang_interface::Type_getArgType(self.x, i as c_uint) }, + x: unsafe { + clang_interface::Type_getArgType(self.x, i as c_uint) + }, unit: self.unit, }) .collect() @@ -1444,12 +1514,12 @@ impl Type { /// to. pub fn pointee_type(&self) -> Option { match self.kind() { - CXType_Pointer | - CXType_RValueReference | - CXType_LValueReference | - CXType_MemberPointer | - CXType_BlockPointer | - CXType_ObjCObjectPointer => { + CXType_Pointer + | CXType_RValueReference + | CXType_LValueReference + | CXType_MemberPointer + | CXType_BlockPointer + | CXType_ObjCObjectPointer => { let ret = Type { x: unsafe { clang_interface::Type_getPointeeType(self.x) }, unit: self.unit, @@ -1478,7 +1548,8 @@ impl Type { /// Given that this type is an array or vector type, return its number of /// elements. pub fn num_elements(&self) -> Option { - let num_elements_returned = unsafe { clang_interface::Type_getNumElements(self.x) }; + let num_elements_returned = + unsafe { clang_interface::Type_getNumElements(self.x) }; if num_elements_returned != -1 { Some(num_elements_returned as usize) } else { @@ -1491,7 +1562,10 @@ impl Type { pub fn canonical_type(&self) -> Type { unsafe { Type { - x: clang_interface::Type_getCanonicalType(self.x, self.context()), + x: clang_interface::Type_getCanonicalType( + self.x, + self.context(), + ), unit: self.unit, } } @@ -1548,11 +1622,11 @@ impl Type { // Yep, the spelling of this containing type-parameter is extremely // nasty... But can happen in . Unfortunately I couldn't // reduce it enough :( - self.template_args().map_or(false, |args| args.len() > 0) && - match self.declaration().kind() { - CXCursor_ClassTemplatePartialSpecialization | - CXCursor_TypeAliasTemplateDecl | - CXCursor_TemplateTemplateParameter => false, + self.template_args().map_or(false, |args| args.len() > 0) + && match self.declaration().kind() { + CXCursor_ClassTemplatePartialSpecialization + | CXCursor_TypeAliasTemplateDecl + | CXCursor_TemplateTemplateParameter => false, _ => true, } } @@ -1578,9 +1652,9 @@ impl Type { ASSOC_TYPE_RE.is_match(spelling.as_ref()) } - self.kind() == CXType_Unexposed && - (hacky_parse_associated_type(self.spelling()) || - hacky_parse_associated_type( + self.kind() == CXType_Unexposed + && (hacky_parse_associated_type(self.spelling()) + || hacky_parse_associated_type( self.canonical_type().spelling(), )) } @@ -1621,7 +1695,9 @@ impl Iterator for TypeTemplateArgIterator { let idx = self.index as c_uint; self.index += 1; Some(Type { - x: unsafe { clang_interface::Type_getTemplateArgumentAsType(self.x, idx) }, + x: unsafe { + clang_interface::Type_getTemplateArgumentAsType(self.x, idx) + }, unit: self.unit, }) } else { @@ -1697,14 +1773,18 @@ impl Comment { /// Given that this comment is the start or end of an HTML tag, get its tag /// name. pub fn get_tag_name(&self) -> String { - unsafe { clang_interface::HTMLTagComment_getTagName(self.x).to_string() } + unsafe { + clang_interface::HTMLTagComment_getTagName(self.x).to_string() + } } /// Given that this comment is an HTML start tag, get its attributes. pub fn get_tag_attrs(&self) -> CommentAttributesIterator { CommentAttributesIterator { x: self.x, - length: unsafe { clang_interface::HTMLStartTag_getNumAttrs(self.x) }, + length: unsafe { + clang_interface::HTMLStartTag_getNumAttrs(self.x) + }, index: 0, } } @@ -1724,7 +1804,9 @@ impl Iterator for CommentChildrenIterator { let idx = self.index; self.index += 1; Some(Comment { - x: unsafe { clang_interface::Comment_getChild(self.parent, idx) }, + x: unsafe { + clang_interface::Comment_getChild(self.parent, idx) + }, }) } else { None @@ -1755,14 +1837,12 @@ impl Iterator for CommentAttributesIterator { self.index += 1; Some(CommentAttribute { name: unsafe { - clang_interface::HTMLStartTag_getAttrName( - self.x, idx, - ).to_string() + clang_interface::HTMLStartTag_getAttrName(self.x, idx) + .to_string() }, value: unsafe { - clang_interface::HTMLStartTag_getAttrValue( - self.x, idx, - ).to_string() + clang_interface::HTMLStartTag_getAttrValue(self.x, idx) + .to_string() }, }) } else { @@ -1894,11 +1974,15 @@ impl TranslationUnit { /// unit. pub fn diags(&self) -> Vec { unsafe { - let num = clang_interface::ASTUnit_getNumDiagnostics(self.x) as usize; + let num = + clang_interface::ASTUnit_getNumDiagnostics(self.x) as usize; let mut diags = vec![]; for i in 0..num { diags.push(Diagnostic { - x: clang_interface::ASTUnit_getDiagnostic(self.x, i as c_uint), + x: clang_interface::ASTUnit_getDiagnostic( + self.x, + i as c_uint, + ), }); } diags @@ -1938,9 +2022,7 @@ impl Diagnostic { /// Format this diagnostic message as a string, using the given option bit /// flags. pub fn format(&self) -> String { - unsafe { - clang_interface::Diagnostic_format(self.x).to_string() - } + unsafe { clang_interface::Diagnostic_format(self.x).to_string() } } /// What is the severity of this diagnostic message? @@ -2252,7 +2334,8 @@ impl EvalResult { pub fn as_double(&self) -> Option { match self.kind() { CXEval_Float => { - Some(unsafe { clang_interface::EvalResult_getAsDouble(self.x) } as f64) + Some(unsafe { clang_interface::EvalResult_getAsDouble(self.x) } + as f64) } _ => None, } @@ -2265,7 +2348,8 @@ impl EvalResult { } if unsafe { clang_interface::EvalResult_isUnsignedInt(self.x) } { - let value = unsafe { clang_interface::EvalResult_getAsUnsigned(self.x) }; + let value = + unsafe { clang_interface::EvalResult_getAsUnsigned(self.x) }; if value > i64::max_value() as c_ulonglong { return None; } @@ -2273,7 +2357,8 @@ impl EvalResult { return Some(value as i64); } - let value = unsafe { clang_interface::EvalResult_getAsLongLong(self.x) }; + let value = + unsafe { clang_interface::EvalResult_getAsLongLong(self.x) }; if value > i64::max_value() as c_longlong { return None; } @@ -2289,7 +2374,9 @@ impl EvalResult { match self.kind() { CXEval_StrLiteral => { let ret = unsafe { - CStr::from_ptr(clang_interface::cString(clang_interface::EvalResult_getAsStr(self.x))) + CStr::from_ptr(clang_interface::cString( + clang_interface::EvalResult_getAsStr(self.x), + )) }; Some(ret.to_bytes().to_vec()) } From b4c7c2d4bbae0419558864cc56f7a7bde34d1c27 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 3 Mar 2020 15:28:55 -0800 Subject: [PATCH 75/88] Remove outdated uses of clang_sys --- src/clang.rs | 4 +++- src/clang/clang_interface.hpp | 2 +- src/clang/clang_interface.rs | 4 ++-- src/clang/libclang_compat.cpp | 2 +- src/ir/context.rs | 4 +--- src/lib.rs | 38 ----------------------------------- 6 files changed, 8 insertions(+), 46 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index be29b84d5d..fbe94b2ffd 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -30,6 +30,8 @@ pub use self::clang_interface::CXLinkageKind::Type as CXLinkageKind; pub use self::clang_interface::CXLinkageKind::*; pub use self::clang_interface::CXTokenKind::Type as CXTokenKind; pub use self::clang_interface::CXTokenKind::*; +pub use self::clang_interface::CXTranslationUnit_Flags::Type as CXTranslationUnit_Flags; +pub use self::clang_interface::CXTranslationUnit_Flags::*; pub use self::clang_interface::CXTypeKind::Type as CXTypeKind; pub use self::clang_interface::CXTypeKind::*; pub use self::clang_interface::CXVisibilityKind::Type as CXVisibilityKind; @@ -1942,7 +1944,7 @@ impl TranslationUnit { file: &str, cmd_args: &[String], unsaved: &[UnsavedFile], - opts: clang_sys::CXTranslationUnit_Flags, + opts: CXTranslationUnit_Flags, ) -> Option { let fname = CString::new(file).unwrap(); let _c_args: Vec = cmd_args diff --git a/src/clang/clang_interface.hpp b/src/clang/clang_interface.hpp index 90d1ed3777..c6793c933f 100644 --- a/src/clang/clang_interface.hpp +++ b/src/clang/clang_interface.hpp @@ -76,7 +76,7 @@ char *cString(BindgenStringRef s); ASTContext *ASTUnit_getContext(ASTUnit *); ASTUnit *parseTranslationUnit(const char *source_filename, const char *const *command_line_args, - int num_command_line_args, int options, + int num_command_line_args, unsigned int options, CXUnsavedFile *unsaved_files, unsigned num_unsaved_files); void disposeASTUnit(ASTUnit *AU); diff --git a/src/clang/clang_interface.rs b/src/clang/clang_interface.rs index 8e3ffa37b2..06e5d252c1 100644 --- a/src/clang/clang_interface.rs +++ b/src/clang/clang_interface.rs @@ -6491,12 +6491,12 @@ extern "C" { ) -> *mut clang_ASTContext; } extern "C" { - #[link_name = "\u{1}_Z20parseTranslationUnitPKcPKS0_iiP13CXUnsavedFilej"] + #[link_name = "\u{1}_Z20parseTranslationUnitPKcPKS0_ijP13CXUnsavedFilej"] pub fn parseTranslationUnit( source_filename: *const ::std::os::raw::c_char, command_line_args: *const *const ::std::os::raw::c_char, num_command_line_args: ::std::os::raw::c_int, - options: ::std::os::raw::c_int, + options: ::std::os::raw::c_uint, unsaved_files: *mut CXUnsavedFile, num_unsaved_files: ::std::os::raw::c_uint, ) -> *mut clang_ASTUnit; diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index e90aeff0f9..205c7ddcdd 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -1030,7 +1030,7 @@ CXCommentKind Comment_getKind(const comments::Comment *C) { // Adapted from clang_parseTranslationUnit_Impl in CIndex.cpp ASTUnit *parseTranslationUnit(const char *source_filename, const char *const *command_line_args, - int num_command_line_args, int options, + int num_command_line_args, unsigned int options, struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files) { SmallVector Args; diff --git a/src/ir/context.rs b/src/ir/context.rs index 87c90390db..55b464d2f7 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -546,10 +546,8 @@ impl BindgenContext { let (effective_target, explicit_target) = find_effective_target(&options.clang_args); - // let index = clang::Index::new(false, true); - let parse_options = - clang_sys::CXTranslationUnit_DetailedPreprocessingRecord; + clang::CXTranslationUnit_DetailedPreprocessingRecord; let translation_unit = { let _t = diff --git a/src/lib.rs b/src/lib.rs index 9fea93c79d..c344c80fd4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1941,32 +1941,6 @@ impl Default for BindgenOptions { } } -#[cfg(feature = "runtime")] -fn ensure_libclang_is_loaded() { - if clang_sys::is_loaded() { - return; - } - - // XXX (issue #350): Ensure that our dynamically loaded `libclang` - // doesn't get dropped prematurely, nor is loaded multiple times - // across different threads. - - lazy_static! { - static ref LIBCLANG: std::sync::Arc = { - clang_sys::load().expect("Unable to find libclang"); - clang_sys::get_library().expect( - "We just loaded libclang and it had better still be \ - here!", - ) - }; - } - - clang_sys::set_library(Some(LIBCLANG.clone())); -} - -#[cfg(not(feature = "runtime"))] -fn ensure_libclang_is_loaded() {} - /// Generated Rust bindings. #[derive(Debug)] pub struct Bindings { @@ -1979,16 +1953,6 @@ impl Bindings { pub(crate) fn generate( mut options: BindgenOptions, ) -> Result { - ensure_libclang_is_loaded(); - - #[cfg(feature = "runtime")] - debug!( - "Generating bindings, libclang at {}", - clang_sys::get_library().unwrap().path().display() - ); - #[cfg(not(feature = "runtime"))] - debug!("Generating bindings, libclang linked"); - options.build(); fn detect_include_paths(options: &mut BindgenOptions) { @@ -2341,8 +2305,6 @@ pub struct ClangVersion { /// Get the major and the minor semver numbers of Clang's version pub fn clang_version() -> ClangVersion { - ensure_libclang_is_loaded(); - let raw_v: String = clang::extract_clang_version(); let split_v: Option> = raw_v .split_whitespace() From 22e39c203f0598587ffff74254b3872b82e3258b Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 4 Mar 2020 13:55:36 -0800 Subject: [PATCH 76/88] Include missing header --- src/clang/libclang_compat.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 205c7ddcdd..0519a639a4 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "llvm/Support/CrashRecoveryContext.h" +#include "clang/AST/Attr.h" #include "clang/AST/Comment.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclFriend.h" From bf1155a433841f8326137ccd9687279931ef0db4 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Sat, 14 Mar 2020 17:04:04 -0700 Subject: [PATCH 77/88] Plug memory leaks --- src/clang.rs | 50 +++++++++++++++++++++++++++-------- src/clang/CMakeLists.txt | 3 +++ src/clang/clang_interface.cpp | 34 +++++++++++++++++++++--- src/clang/clang_interface.hpp | 12 +++++++-- src/clang/clang_interface.rs | 46 ++++++++++++++++++++++++-------- src/clang/libclang_compat.cpp | 5 ++++ 6 files changed, 123 insertions(+), 27 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index fbe94b2ffd..341e91d010 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -49,6 +49,12 @@ impl clang_interface::BindgenSourceRange { } } +impl Drop for clang_interface::BindgenSourceRange { + fn drop(&mut self) { + unsafe { clang_interface::deleteSourceRange(self); } + } +} + trait ToCString { fn to_cstring(&self) -> CString; } @@ -70,6 +76,18 @@ impl fmt::Display for clang_interface::BindgenStringRef { } } +impl Drop for clang_interface::BindgenStringRef { + fn drop(&mut self) { + unsafe { clang_interface::deleteString(self); } + } +} + +impl Drop for clang_interface::BindgenStringRefSet { + fn drop(&mut self) { + unsafe { clang_interface::deleteStringSet(self); } + } +} + /// A cursor into the Clang AST, pointing to an AST node. /// /// We call the AST node pointed to by the cursor the cursor's "referent". @@ -246,7 +264,6 @@ impl Cursor { let string_ptr = manglings.strings.offset(i as isize); result.push((*string_ptr).to_string()); } - // clang_disposeStringSet(manglings); Ok(result) } } @@ -457,7 +474,7 @@ impl Cursor { ASTNode::PreprocessedEntity(p) => { clang_interface::PreprocessedEntity_getLocation(p) } - ASTNode::Invalid => ptr::null(), + ASTNode::Invalid => ptr::null_mut(), }; SourceLocation { x, unit: self.unit } } @@ -1090,11 +1107,11 @@ impl<'a> RawTokens<'a> { fn new(cursor: &'a Cursor) -> Self { let mut tokens = ptr::null_mut(); let mut token_count = 0; - let range = cursor.extent(); let tu = cursor.translation_unit(); + let range = cursor.extent(); unsafe { - clang_interface::tokenize(tu, range, &mut tokens, &mut token_count) - }; + clang_interface::tokenize(tu, range, &mut tokens, &mut token_count); + } Self { cursor, tu, @@ -1718,7 +1735,7 @@ impl ExactSizeIterator for TypeTemplateArgIterator { /// A `SourceLocation` is a file, line, column, and byte offset location for /// some source text. pub struct SourceLocation { - x: *const clang_interface::clang_SourceLocation, + x: *mut clang_interface::clang_SourceLocation, unit: *mut clang_interface::clang_ASTUnit, } @@ -1750,6 +1767,14 @@ impl fmt::Display for SourceLocation { } } +impl Drop for SourceLocation { + fn drop(&mut self) { + unsafe { + clang_interface::deleteSourceLocation(self.x); + } + } +} + /// A comment in the source text. /// /// Comments are sort of parsed by Clang, and have a tree structure. @@ -2327,6 +2352,12 @@ pub struct EvalResult { x: *mut clang_interface::EvalResult, } +impl Drop for EvalResult { + fn drop(&mut self) { + unsafe { clang_interface::deleteEvalResult(self.x); } + } +} + impl EvalResult { fn kind(&self) -> CXEvalResultKind { unsafe { clang_interface::EvalResult_getKind(self.x) } @@ -2375,11 +2406,8 @@ impl EvalResult { pub fn as_literal_string(&self) -> Option> { match self.kind() { CXEval_StrLiteral => { - let ret = unsafe { - CStr::from_ptr(clang_interface::cString( - clang_interface::EvalResult_getAsStr(self.x), - )) - }; + let mut stringref = unsafe { clang_interface::EvalResult_getAsStr(self.x) }; + let ret = unsafe { CStr::from_ptr(clang_interface::cString(&mut stringref)) }; Some(ret.to_bytes().to_vec()) } _ => None, diff --git a/src/clang/CMakeLists.txt b/src/clang/CMakeLists.txt index 665669f412..b4afda5a32 100644 --- a/src/clang/CMakeLists.txt +++ b/src/clang/CMakeLists.txt @@ -44,6 +44,9 @@ else() add_library(BindgenClangInterface STATIC ${SRCS}) endif() +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + + add_definitions(-DCLANG_LIBDIR_SUFFIX="${LLVM_LIBDIR_SUFFIX}") set_target_properties(BindgenClangInterface PROPERTIES diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index 74d3d83052..4a561b74b7 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -66,11 +66,39 @@ BindgenStringRefSet make_stringrefset(std::vector &string_vec) { return set; } -void freeString(BindgenStringRef s) { - delete[] s.s; +void deleteString(BindgenStringRef *s) { + if (s) + delete[] s->s; } -char *cString(BindgenStringRef s) { return s.s; } +char *cString(BindgenStringRef *s) { + return s ? s->s : nullptr; +} + +void deleteStringSet(BindgenStringRefSet *s) { + if (s) { + for (size_t i = 0; i < s->len; ++i) { + delete[] s->strings[i].s; + } + delete[] s->strings; + } +} + +void deleteSourceLocation(SourceLocation *s) { + if (s) + delete s; +} + +void deleteSourceRange(BindgenSourceRange *s) { + if (s) { + delete s->B; + delete s->E; + } +} + +void deleteEvalResult(EvalResult *e) { + delete e; +} ASTContext *ASTUnit_getContext(ASTUnit *Unit) { return &Unit->getASTContext(); diff --git a/src/clang/clang_interface.hpp b/src/clang/clang_interface.hpp index c6793c933f..de03f8dcf0 100644 --- a/src/clang/clang_interface.hpp +++ b/src/clang/clang_interface.hpp @@ -70,8 +70,16 @@ struct BindgenSourceRange { -void freeString(BindgenStringRef s); -char *cString(BindgenStringRef s); +void deleteString(BindgenStringRef *s); +char *cString(BindgenStringRef *s); + +void deleteStringSet(BindgenStringRefSet *s); + +void deleteSourceLocation(SourceLocation *s); + +void deleteSourceRange(BindgenSourceRange *s); + +void deleteEvalResult(EvalResult *e); ASTContext *ASTUnit_getContext(ASTUnit *); ASTUnit *parseTranslationUnit(const char *source_filename, diff --git a/src/clang/clang_interface.rs b/src/clang/clang_interface.rs index 06e5d252c1..e2b9fb8f3e 100644 --- a/src/clang/clang_interface.rs +++ b/src/clang/clang_interface.rs @@ -92,6 +92,7 @@ pub const _FEATURES_H: u32 = 1; pub const _ISOC95_SOURCE: u32 = 1; pub const _ISOC99_SOURCE: u32 = 1; pub const _ISOC11_SOURCE: u32 = 1; +pub const _ISOC2X_SOURCE: u32 = 1; pub const _POSIX_SOURCE: u32 = 1; pub const _POSIX_C_SOURCE: u32 = 200809; pub const _XOPEN_SOURCE: u32 = 700; @@ -99,6 +100,7 @@ pub const _XOPEN_SOURCE_EXTENDED: u32 = 1; pub const _LARGEFILE64_SOURCE: u32 = 1; pub const _DEFAULT_SOURCE: u32 = 1; pub const _ATFILE_SOURCE: u32 = 1; +pub const __GLIBC_USE_ISOC2X: u32 = 1; pub const __USE_ISOC11: u32 = 1; pub const __USE_ISOC99: u32 = 1; pub const __USE_ISOC95: u32 = 1; @@ -129,12 +131,13 @@ pub const __STDC_IEC_559_COMPLEX__: u32 = 1; pub const __STDC_ISO_10646__: u32 = 201706; pub const __GNU_LIBRARY__: u32 = 6; pub const __GLIBC__: u32 = 2; -pub const __GLIBC_MINOR__: u32 = 30; +pub const __GLIBC_MINOR__: u32 = 31; pub const _SYS_CDEFS_H: u32 = 1; pub const __glibc_c99_flexarr_available: u32 = 1; pub const __WORDSIZE: u32 = 64; pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __LONG_DOUBLE_USES_FLOAT128: u32 = 0; pub const __HAVE_GENERIC_SELECTION: u32 = 0; pub const _BITS_TIME_H: u32 = 1; pub const _BITS_TYPES_H: u32 = 1; @@ -143,6 +146,7 @@ pub const _BITS_TYPESIZES_H: u32 = 1; pub const __OFF_T_MATCHES_OFF64_T: u32 = 1; pub const __INO_T_MATCHES_INO64_T: u32 = 1; pub const __RLIM_T_MATCHES_RLIM64_T: u32 = 1; +pub const __STATFS_MATCHES_STATFS64: u32 = 1; pub const __FD_SETSIZE: u32 = 1024; pub const _BITS_TIME64_H: u32 = 1; pub const CLOCK_REALTIME: u32 = 0; @@ -204,6 +208,13 @@ pub const __clock_t_defined: u32 = 1; pub const __time_t_defined: u32 = 1; pub const __struct_tm_defined: u32 = 1; pub const _STRUCT_TIMESPEC: u32 = 1; +pub const _BITS_ENDIAN_H: u32 = 1; +pub const __LITTLE_ENDIAN: u32 = 1234; +pub const __BIG_ENDIAN: u32 = 4321; +pub const __PDP_ENDIAN: u32 = 3412; +pub const _BITS_ENDIANNESS_H: u32 = 1; +pub const __BYTE_ORDER: u32 = 1234; +pub const __FLOAT_WORD_ORDER: u32 = 1234; pub const __clockid_t_defined: u32 = 1; pub const __timer_t_defined: u32 = 1; pub const __itimerspec_defined: u32 = 1; @@ -1040,9 +1051,6 @@ extern "C" { extern "C" { pub static mut timezone: ::std::os::raw::c_long; } -extern "C" { - pub fn stime(__when: *const time_t) -> ::std::os::raw::c_int; -} extern "C" { pub fn timegm(__tp: *mut tm) -> time_t; } @@ -6325,7 +6333,7 @@ pub struct EvalResult { _unused: [u8; 0], } #[repr(C)] -#[derive(Debug, Copy, Clone)] +#[derive(Debug)] pub struct BindgenStringRef { pub s: *mut ::std::os::raw::c_char, pub len: size_t, @@ -6369,7 +6377,7 @@ fn bindgen_test_layout_BindgenStringRef() { ); } #[repr(C)] -#[derive(Debug, Copy, Clone)] +#[derive(Debug)] pub struct BindgenStringRefSet { pub strings: *mut BindgenStringRef, pub len: size_t, @@ -6414,7 +6422,7 @@ fn bindgen_test_layout_BindgenStringRefSet() { ); } #[repr(C)] -#[derive(Debug, Copy, Clone)] +#[derive(Debug)] pub struct BindgenSourceRange { pub B: *mut clang_SourceLocation, pub E: *mut clang_SourceLocation, @@ -6477,12 +6485,28 @@ impl BindgenSourceRange { } } extern "C" { - #[link_name = "\u{1}_Z10freeString16BindgenStringRef"] - pub fn freeString(s: BindgenStringRef); + #[link_name = "\u{1}_Z12deleteStringP16BindgenStringRef"] + pub fn deleteString(s: *mut BindgenStringRef); +} +extern "C" { + #[link_name = "\u{1}_Z7cStringP16BindgenStringRef"] + pub fn cString(s: *mut BindgenStringRef) -> *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_Z15deleteStringSetP19BindgenStringRefSet"] + pub fn deleteStringSet(s: *mut BindgenStringRefSet); +} +extern "C" { + #[link_name = "\u{1}_Z20deleteSourceLocationPN5clang14SourceLocationE"] + pub fn deleteSourceLocation(s: *mut clang_SourceLocation); +} +extern "C" { + #[link_name = "\u{1}_Z17deleteSourceRangeP18BindgenSourceRange"] + pub fn deleteSourceRange(s: *mut BindgenSourceRange); } extern "C" { - #[link_name = "\u{1}_Z7cString16BindgenStringRef"] - pub fn cString(s: BindgenStringRef) -> *mut ::std::os::raw::c_char; + #[link_name = "\u{1}_Z16deleteEvalResultP10EvalResult"] + pub fn deleteEvalResult(e: *mut EvalResult); } extern "C" { #[link_name = "\u{1}_Z18ASTUnit_getContextPN5clang7ASTUnitE"] diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 0519a639a4..9d584c29dd 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -1639,6 +1639,11 @@ void tokenize(ASTUnit *TU, BindgenSourceRange Range, CXToken **Tokens, std::pair EndLocInfo = SourceMgr.getDecomposedSpellingLoc(EndLoc); + // BindgenSourceRange elements need to be manually destructed because it is + // C-style struct shared with Rust. + delete Range.B; + delete Range.E; + // Cannot tokenize across files. if (BeginLocInfo.first != EndLocInfo.first) return; From 8fa4e6a114c98f1513e897af9666ca82ac4e729b Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 18 Mar 2020 16:18:40 -0700 Subject: [PATCH 78/88] Fix build warning --- src/clang/clang_interface.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index 4a561b74b7..ab53573625 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -96,10 +96,6 @@ void deleteSourceRange(BindgenSourceRange *s) { } } -void deleteEvalResult(EvalResult *e) { - delete e; -} - ASTContext *ASTUnit_getContext(ASTUnit *Unit) { return &Unit->getASTContext(); } @@ -150,6 +146,10 @@ struct EvalResult { EvalResult(std::string str) : EvalType(CXEval_StrLiteral), stringVal(str) {} }; +void deleteEvalResult(EvalResult *e) { + delete e; +} + EvalResult *Expr_Evaluate(const Expr *E, ASTContext *Ctx) { if (!E || E->isValueDependent()) return nullptr; From 854d6634667ee9bfff88fec9ed8fc249c0ea3d78 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 18 Mar 2020 16:18:54 -0700 Subject: [PATCH 79/88] Include instead of explicitly defining types --- src/clang/clang_interface.hpp | 5 +- src/clang/clang_interface.rs | 360 +++++++++++++++++++++++++++++++++- 2 files changed, 358 insertions(+), 7 deletions(-) diff --git a/src/clang/clang_interface.hpp b/src/clang/clang_interface.hpp index de03f8dcf0..6efcd76133 100644 --- a/src/clang/clang_interface.hpp +++ b/src/clang/clang_interface.hpp @@ -1,13 +1,10 @@ #ifndef BINDGEN_CLANG_AST_H #define BINDGEN_CLANG_AST_H +#include #include "clang-c/Documentation.h" #include "clang-c/Index.h" -typedef unsigned long size_t; -typedef unsigned long uint64_t; -typedef long int64_t; - namespace clang { struct ASTUnit; struct TargetInfo; diff --git a/src/clang/clang_interface.rs b/src/clang/clang_interface.rs index e2b9fb8f3e..c9032f49ba 100644 --- a/src/clang/clang_interface.rs +++ b/src/clang/clang_interface.rs @@ -87,7 +87,19 @@ where } } } -pub const _TIME_H: u32 = 1; +pub const _GLIBCXX_CSTDINT: u32 = 1; +pub const _GLIBCXX_CXX_CONFIG_H: u32 = 1; +pub const _GLIBCXX_RELEASE: u32 = 9; +pub const __GLIBCXX__: u32 = 20200130; +pub const _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY: u32 = 1; +pub const _GLIBCXX_USE_DEPRECATED: u32 = 1; +pub const _GLIBCXX_EXTERN_TEMPLATE: u32 = 1; +pub const _GLIBCXX_USE_DUAL_ABI: u32 = 1; +pub const _GLIBCXX_USE_CXX11_ABI: u32 = 1; +pub const _GLIBCXX_INLINE_VERSION: u32 = 0; +pub const _GLIBCXX_USE_ALLOCATOR_NEW: u32 = 1; +pub const _GLIBCXX_OS_DEFINES: u32 = 1; +pub const __NO_CTYPE: u32 = 1; pub const _FEATURES_H: u32 = 1; pub const _ISOC95_SOURCE: u32 = 1; pub const _ISOC99_SOURCE: u32 = 1; @@ -139,7 +151,254 @@ pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; pub const __SYSCALL_WORDSIZE: u32 = 64; pub const __LONG_DOUBLE_USES_FLOAT128: u32 = 0; pub const __HAVE_GENERIC_SELECTION: u32 = 0; -pub const _BITS_TIME_H: u32 = 1; +pub const _GLIBCXX_CPU_DEFINES: u32 = 1; +pub const _GLIBCXX_FAST_MATH: u32 = 0; +pub const _GLIBCXX_USE_FLOAT128: u32 = 1; +pub const _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP: u32 = 1; +pub const _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE: u32 = 1; +pub const _GLIBCXX_HAVE_BUILTIN_LAUNDER: u32 = 1; +pub const _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED: u32 = 1; +pub const _GLIBCXX_HAVE_ACOSF: u32 = 1; +pub const _GLIBCXX_HAVE_ACOSL: u32 = 1; +pub const _GLIBCXX_HAVE_ALIGNED_ALLOC: u32 = 1; +pub const _GLIBCXX_HAVE_ARPA_INET_H: u32 = 1; +pub const _GLIBCXX_HAVE_ASINF: u32 = 1; +pub const _GLIBCXX_HAVE_ASINL: u32 = 1; +pub const _GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE: u32 = 1; +pub const _GLIBCXX_HAVE_ATAN2F: u32 = 1; +pub const _GLIBCXX_HAVE_ATAN2L: u32 = 1; +pub const _GLIBCXX_HAVE_ATANF: u32 = 1; +pub const _GLIBCXX_HAVE_ATANL: u32 = 1; +pub const _GLIBCXX_HAVE_ATOMIC_LOCK_POLICY: u32 = 1; +pub const _GLIBCXX_HAVE_AT_QUICK_EXIT: u32 = 1; +pub const _GLIBCXX_HAVE_CEILF: u32 = 1; +pub const _GLIBCXX_HAVE_CEILL: u32 = 1; +pub const _GLIBCXX_HAVE_COMPLEX_H: u32 = 1; +pub const _GLIBCXX_HAVE_COSF: u32 = 1; +pub const _GLIBCXX_HAVE_COSHF: u32 = 1; +pub const _GLIBCXX_HAVE_COSHL: u32 = 1; +pub const _GLIBCXX_HAVE_COSL: u32 = 1; +pub const _GLIBCXX_HAVE_DIRENT_H: u32 = 1; +pub const _GLIBCXX_HAVE_DLFCN_H: u32 = 1; +pub const _GLIBCXX_HAVE_EBADMSG: u32 = 1; +pub const _GLIBCXX_HAVE_ECANCELED: u32 = 1; +pub const _GLIBCXX_HAVE_ECHILD: u32 = 1; +pub const _GLIBCXX_HAVE_EIDRM: u32 = 1; +pub const _GLIBCXX_HAVE_ENDIAN_H: u32 = 1; +pub const _GLIBCXX_HAVE_ENODATA: u32 = 1; +pub const _GLIBCXX_HAVE_ENOLINK: u32 = 1; +pub const _GLIBCXX_HAVE_ENOSPC: u32 = 1; +pub const _GLIBCXX_HAVE_ENOSR: u32 = 1; +pub const _GLIBCXX_HAVE_ENOSTR: u32 = 1; +pub const _GLIBCXX_HAVE_ENOTRECOVERABLE: u32 = 1; +pub const _GLIBCXX_HAVE_ENOTSUP: u32 = 1; +pub const _GLIBCXX_HAVE_EOVERFLOW: u32 = 1; +pub const _GLIBCXX_HAVE_EOWNERDEAD: u32 = 1; +pub const _GLIBCXX_HAVE_EPERM: u32 = 1; +pub const _GLIBCXX_HAVE_EPROTO: u32 = 1; +pub const _GLIBCXX_HAVE_ETIME: u32 = 1; +pub const _GLIBCXX_HAVE_ETIMEDOUT: u32 = 1; +pub const _GLIBCXX_HAVE_ETXTBSY: u32 = 1; +pub const _GLIBCXX_HAVE_EWOULDBLOCK: u32 = 1; +pub const _GLIBCXX_HAVE_EXCEPTION_PTR_SINCE_GCC46: u32 = 1; +pub const _GLIBCXX_HAVE_EXECINFO_H: u32 = 1; +pub const _GLIBCXX_HAVE_EXPF: u32 = 1; +pub const _GLIBCXX_HAVE_EXPL: u32 = 1; +pub const _GLIBCXX_HAVE_FABSF: u32 = 1; +pub const _GLIBCXX_HAVE_FABSL: u32 = 1; +pub const _GLIBCXX_HAVE_FCNTL_H: u32 = 1; +pub const _GLIBCXX_HAVE_FENV_H: u32 = 1; +pub const _GLIBCXX_HAVE_FINITE: u32 = 1; +pub const _GLIBCXX_HAVE_FINITEF: u32 = 1; +pub const _GLIBCXX_HAVE_FINITEL: u32 = 1; +pub const _GLIBCXX_HAVE_FLOAT_H: u32 = 1; +pub const _GLIBCXX_HAVE_FLOORF: u32 = 1; +pub const _GLIBCXX_HAVE_FLOORL: u32 = 1; +pub const _GLIBCXX_HAVE_FMODF: u32 = 1; +pub const _GLIBCXX_HAVE_FMODL: u32 = 1; +pub const _GLIBCXX_HAVE_FREXPF: u32 = 1; +pub const _GLIBCXX_HAVE_FREXPL: u32 = 1; +pub const _GLIBCXX_HAVE_GETIPINFO: u32 = 1; +pub const _GLIBCXX_HAVE_GETS: u32 = 1; +pub const _GLIBCXX_HAVE_HYPOT: u32 = 1; +pub const _GLIBCXX_HAVE_HYPOTF: u32 = 1; +pub const _GLIBCXX_HAVE_HYPOTL: u32 = 1; +pub const _GLIBCXX_HAVE_ICONV: u32 = 1; +pub const _GLIBCXX_HAVE_INT64_T: u32 = 1; +pub const _GLIBCXX_HAVE_INT64_T_LONG: u32 = 1; +pub const _GLIBCXX_HAVE_INTTYPES_H: u32 = 1; +pub const _GLIBCXX_HAVE_ISINFF: u32 = 1; +pub const _GLIBCXX_HAVE_ISINFL: u32 = 1; +pub const _GLIBCXX_HAVE_ISNANF: u32 = 1; +pub const _GLIBCXX_HAVE_ISNANL: u32 = 1; +pub const _GLIBCXX_HAVE_ISWBLANK: u32 = 1; +pub const _GLIBCXX_HAVE_LC_MESSAGES: u32 = 1; +pub const _GLIBCXX_HAVE_LDEXPF: u32 = 1; +pub const _GLIBCXX_HAVE_LDEXPL: u32 = 1; +pub const _GLIBCXX_HAVE_LIBINTL_H: u32 = 1; +pub const _GLIBCXX_HAVE_LIMIT_AS: u32 = 1; +pub const _GLIBCXX_HAVE_LIMIT_DATA: u32 = 1; +pub const _GLIBCXX_HAVE_LIMIT_FSIZE: u32 = 1; +pub const _GLIBCXX_HAVE_LIMIT_RSS: u32 = 1; +pub const _GLIBCXX_HAVE_LIMIT_VMEM: u32 = 0; +pub const _GLIBCXX_HAVE_LINK: u32 = 1; +pub const _GLIBCXX_HAVE_LINUX_FUTEX: u32 = 1; +pub const _GLIBCXX_HAVE_LINUX_RANDOM_H: u32 = 1; +pub const _GLIBCXX_HAVE_LINUX_TYPES_H: u32 = 1; +pub const _GLIBCXX_HAVE_LOCALE_H: u32 = 1; +pub const _GLIBCXX_HAVE_LOG10F: u32 = 1; +pub const _GLIBCXX_HAVE_LOG10L: u32 = 1; +pub const _GLIBCXX_HAVE_LOGF: u32 = 1; +pub const _GLIBCXX_HAVE_LOGL: u32 = 1; +pub const _GLIBCXX_HAVE_MBSTATE_T: u32 = 1; +pub const _GLIBCXX_HAVE_MEMALIGN: u32 = 1; +pub const _GLIBCXX_HAVE_MEMORY_H: u32 = 1; +pub const _GLIBCXX_HAVE_MODF: u32 = 1; +pub const _GLIBCXX_HAVE_MODFF: u32 = 1; +pub const _GLIBCXX_HAVE_MODFL: u32 = 1; +pub const _GLIBCXX_HAVE_NETDB_H: u32 = 1; +pub const _GLIBCXX_HAVE_NETINET_IN_H: u32 = 1; +pub const _GLIBCXX_HAVE_NETINET_TCP_H: u32 = 1; +pub const _GLIBCXX_HAVE_POLL: u32 = 1; +pub const _GLIBCXX_HAVE_POLL_H: u32 = 1; +pub const _GLIBCXX_HAVE_POSIX_MEMALIGN: u32 = 1; +pub const _GLIBCXX_HAVE_POWF: u32 = 1; +pub const _GLIBCXX_HAVE_POWL: u32 = 1; +pub const _GLIBCXX_HAVE_QUICK_EXIT: u32 = 1; +pub const _GLIBCXX_HAVE_READLINK: u32 = 1; +pub const _GLIBCXX_HAVE_SETENV: u32 = 1; +pub const _GLIBCXX_HAVE_SINCOS: u32 = 1; +pub const _GLIBCXX_HAVE_SINCOSF: u32 = 1; +pub const _GLIBCXX_HAVE_SINCOSL: u32 = 1; +pub const _GLIBCXX_HAVE_SINF: u32 = 1; +pub const _GLIBCXX_HAVE_SINHF: u32 = 1; +pub const _GLIBCXX_HAVE_SINHL: u32 = 1; +pub const _GLIBCXX_HAVE_SINL: u32 = 1; +pub const _GLIBCXX_HAVE_SOCKATMARK: u32 = 1; +pub const _GLIBCXX_HAVE_SQRTF: u32 = 1; +pub const _GLIBCXX_HAVE_SQRTL: u32 = 1; +pub const _GLIBCXX_HAVE_STDALIGN_H: u32 = 1; +pub const _GLIBCXX_HAVE_STDBOOL_H: u32 = 1; +pub const _GLIBCXX_HAVE_STDINT_H: u32 = 1; +pub const _GLIBCXX_HAVE_STDLIB_H: u32 = 1; +pub const _GLIBCXX_HAVE_STRERROR_L: u32 = 1; +pub const _GLIBCXX_HAVE_STRERROR_R: u32 = 1; +pub const _GLIBCXX_HAVE_STRINGS_H: u32 = 1; +pub const _GLIBCXX_HAVE_STRING_H: u32 = 1; +pub const _GLIBCXX_HAVE_STRTOF: u32 = 1; +pub const _GLIBCXX_HAVE_STRTOLD: u32 = 1; +pub const _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE: u32 = 1; +pub const _GLIBCXX_HAVE_STRXFRM_L: u32 = 1; +pub const _GLIBCXX_HAVE_SYMLINK: u32 = 1; +pub const _GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_IOCTL_H: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_IPC_H: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_PARAM_H: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_RESOURCE_H: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_SDT_H: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_SEM_H: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_SOCKET_H: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_STATVFS_H: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_STAT_H: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_SYSINFO_H: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_TIME_H: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_TYPES_H: u32 = 1; +pub const _GLIBCXX_HAVE_SYS_UIO_H: u32 = 1; +pub const _GLIBCXX_HAVE_S_ISREG: u32 = 1; +pub const _GLIBCXX_HAVE_TANF: u32 = 1; +pub const _GLIBCXX_HAVE_TANHF: u32 = 1; +pub const _GLIBCXX_HAVE_TANHL: u32 = 1; +pub const _GLIBCXX_HAVE_TANL: u32 = 1; +pub const _GLIBCXX_HAVE_TGMATH_H: u32 = 1; +pub const _GLIBCXX_HAVE_TIMESPEC_GET: u32 = 1; +pub const _GLIBCXX_HAVE_TLS: u32 = 1; +pub const _GLIBCXX_HAVE_TRUNCATE: u32 = 1; +pub const _GLIBCXX_HAVE_UCHAR_H: u32 = 1; +pub const _GLIBCXX_HAVE_UNISTD_H: u32 = 1; +pub const _GLIBCXX_HAVE_UTIME_H: u32 = 1; +pub const _GLIBCXX_HAVE_VFWSCANF: u32 = 1; +pub const _GLIBCXX_HAVE_VSWSCANF: u32 = 1; +pub const _GLIBCXX_HAVE_VWSCANF: u32 = 1; +pub const _GLIBCXX_HAVE_WCHAR_H: u32 = 1; +pub const _GLIBCXX_HAVE_WCSTOF: u32 = 1; +pub const _GLIBCXX_HAVE_WCTYPE_H: u32 = 1; +pub const _GLIBCXX_HAVE_WRITEV: u32 = 1; +pub const _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL: u32 = 1; +pub const LT_OBJDIR: &'static [u8; 7usize] = b".libs/\0"; +pub const _GLIBCXX_PACKAGE_BUGREPORT: &'static [u8; 1usize] = b"\0"; +pub const _GLIBCXX_PACKAGE_NAME: &'static [u8; 15usize] = b"package-unused\0"; +pub const _GLIBCXX_PACKAGE_STRING: &'static [u8; 30usize] = + b"package-unused version-unused\0"; +pub const _GLIBCXX_PACKAGE_TARNAME: &'static [u8; 10usize] = b"libstdc++\0"; +pub const _GLIBCXX_PACKAGE_URL: &'static [u8; 1usize] = b"\0"; +pub const _GLIBCXX_PACKAGE__GLIBCXX_VERSION: &'static [u8; 15usize] = + b"version-unused\0"; +pub const STDC_HEADERS: u32 = 1; +pub const _GLIBCXX_DARWIN_USE_64_BIT_INODE: u32 = 1; +pub const _GLIBCXX11_USE_C99_COMPLEX: u32 = 1; +pub const _GLIBCXX11_USE_C99_MATH: u32 = 1; +pub const _GLIBCXX11_USE_C99_STDIO: u32 = 1; +pub const _GLIBCXX11_USE_C99_STDLIB: u32 = 1; +pub const _GLIBCXX11_USE_C99_WCHAR: u32 = 1; +pub const _GLIBCXX98_USE_C99_COMPLEX: u32 = 1; +pub const _GLIBCXX98_USE_C99_MATH: u32 = 1; +pub const _GLIBCXX98_USE_C99_STDIO: u32 = 1; +pub const _GLIBCXX98_USE_C99_STDLIB: u32 = 1; +pub const _GLIBCXX98_USE_C99_WCHAR: u32 = 1; +pub const _GLIBCXX_ATOMIC_BUILTINS: u32 = 1; +pub const _GLIBCXX_FULLY_DYNAMIC_STRING: u32 = 0; +pub const _GLIBCXX_HAS_GTHREADS: u32 = 1; +pub const _GLIBCXX_HOSTED: u32 = 1; +pub const _GLIBCXX_RES_LIMITS: u32 = 1; +pub const _GLIBCXX_STDIO_EOF: i32 = -1; +pub const _GLIBCXX_STDIO_SEEK_CUR: u32 = 1; +pub const _GLIBCXX_STDIO_SEEK_END: u32 = 2; +pub const _GLIBCXX_SYMVER: u32 = 1; +pub const _GLIBCXX_SYMVER_GNU: u32 = 1; +pub const _GLIBCXX_USE_C11_UCHAR_CXX11: u32 = 1; +pub const _GLIBCXX_USE_C99: u32 = 1; +pub const _GLIBCXX_USE_C99_COMPLEX_TR1: u32 = 1; +pub const _GLIBCXX_USE_C99_CTYPE_TR1: u32 = 1; +pub const _GLIBCXX_USE_C99_FENV_TR1: u32 = 1; +pub const _GLIBCXX_USE_C99_INTTYPES_TR1: u32 = 1; +pub const _GLIBCXX_USE_C99_INTTYPES_WCHAR_T_TR1: u32 = 1; +pub const _GLIBCXX_USE_C99_MATH_TR1: u32 = 1; +pub const _GLIBCXX_USE_C99_STDINT_TR1: u32 = 1; +pub const _GLIBCXX_USE_CLOCK_MONOTONIC: u32 = 1; +pub const _GLIBCXX_USE_CLOCK_REALTIME: u32 = 1; +pub const _GLIBCXX_USE_DECIMAL_FLOAT: u32 = 1; +pub const _GLIBCXX_USE_DEV_RANDOM: u32 = 1; +pub const _GLIBCXX_USE_FCHMOD: u32 = 1; +pub const _GLIBCXX_USE_FCHMODAT: u32 = 1; +pub const _GLIBCXX_USE_GETTIMEOFDAY: u32 = 1; +pub const _GLIBCXX_USE_GET_NPROCS: u32 = 1; +pub const _GLIBCXX_USE_INT128: u32 = 1; +pub const _GLIBCXX_USE_LFS: u32 = 1; +pub const _GLIBCXX_USE_LONG_LONG: u32 = 1; +pub const _GLIBCXX_USE_LSTAT: u32 = 1; +pub const _GLIBCXX_USE_NANOSLEEP: u32 = 1; +pub const _GLIBCXX_USE_NLS: u32 = 1; +pub const _GLIBCXX_USE_PTHREAD_RWLOCK_T: u32 = 1; +pub const _GLIBCXX_USE_RANDOM_TR1: u32 = 1; +pub const _GLIBCXX_USE_REALPATH: u32 = 1; +pub const _GLIBCXX_USE_SCHED_YIELD: u32 = 1; +pub const _GLIBCXX_USE_SC_NPROCESSORS_ONLN: u32 = 1; +pub const _GLIBCXX_USE_SENDFILE: u32 = 1; +pub const _GLIBCXX_USE_ST_MTIM: u32 = 1; +pub const _GLIBCXX_USE_TMPNAM: u32 = 1; +pub const _GLIBCXX_USE_UTIME: u32 = 1; +pub const _GLIBCXX_USE_UTIMENSAT: u32 = 1; +pub const _GLIBCXX_USE_WCHAR_T: u32 = 1; +pub const _GLIBCXX_VERBOSE: u32 = 1; +pub const _GLIBCXX_X86_RDRAND: u32 = 1; +pub const _GTHREAD_USE_MUTEX_TIMEDLOCK: u32 = 1; +pub const _STDINT_H: u32 = 1; +pub const __GLIBC_USE_LIB_EXT2: u32 = 1; +pub const __GLIBC_USE_IEC_60559_BFP_EXT: u32 = 1; +pub const __GLIBC_USE_IEC_60559_BFP_EXT_C2X: u32 = 1; +pub const __GLIBC_USE_IEC_60559_FUNCS_EXT: u32 = 1; +pub const __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X: u32 = 1; +pub const __GLIBC_USE_IEC_60559_TYPES_EXT: u32 = 1; pub const _BITS_TYPES_H: u32 = 1; pub const __TIMESIZE: u32 = 64; pub const _BITS_TYPESIZES_H: u32 = 1; @@ -149,6 +408,81 @@ pub const __RLIM_T_MATCHES_RLIM64_T: u32 = 1; pub const __STATFS_MATCHES_STATFS64: u32 = 1; pub const __FD_SETSIZE: u32 = 1024; pub const _BITS_TIME64_H: u32 = 1; +pub const _BITS_WCHAR_H: u32 = 1; +pub const _BITS_STDINT_INTN_H: u32 = 1; +pub const _BITS_STDINT_UINTN_H: u32 = 1; +pub const INT8_MIN: i32 = -128; +pub const INT16_MIN: i32 = -32768; +pub const INT32_MIN: i32 = -2147483648; +pub const INT8_MAX: u32 = 127; +pub const INT16_MAX: u32 = 32767; +pub const INT32_MAX: u32 = 2147483647; +pub const UINT8_MAX: u32 = 255; +pub const UINT16_MAX: u32 = 65535; +pub const UINT32_MAX: u32 = 4294967295; +pub const INT_LEAST8_MIN: i32 = -128; +pub const INT_LEAST16_MIN: i32 = -32768; +pub const INT_LEAST32_MIN: i32 = -2147483648; +pub const INT_LEAST8_MAX: u32 = 127; +pub const INT_LEAST16_MAX: u32 = 32767; +pub const INT_LEAST32_MAX: u32 = 2147483647; +pub const UINT_LEAST8_MAX: u32 = 255; +pub const UINT_LEAST16_MAX: u32 = 65535; +pub const UINT_LEAST32_MAX: u32 = 4294967295; +pub const INT_FAST8_MIN: i32 = -128; +pub const INT_FAST16_MIN: i64 = -9223372036854775808; +pub const INT_FAST32_MIN: i64 = -9223372036854775808; +pub const INT_FAST8_MAX: u32 = 127; +pub const INT_FAST16_MAX: u64 = 9223372036854775807; +pub const INT_FAST32_MAX: u64 = 9223372036854775807; +pub const UINT_FAST8_MAX: u32 = 255; +pub const UINT_FAST16_MAX: i32 = -1; +pub const UINT_FAST32_MAX: i32 = -1; +pub const INTPTR_MIN: i64 = -9223372036854775808; +pub const INTPTR_MAX: u64 = 9223372036854775807; +pub const UINTPTR_MAX: i32 = -1; +pub const PTRDIFF_MIN: i64 = -9223372036854775808; +pub const PTRDIFF_MAX: u64 = 9223372036854775807; +pub const SIG_ATOMIC_MIN: i32 = -2147483648; +pub const SIG_ATOMIC_MAX: u32 = 2147483647; +pub const SIZE_MAX: i32 = -1; +pub const WINT_MIN: u32 = 0; +pub const WINT_MAX: u32 = 4294967295; +pub const INT8_WIDTH: u32 = 8; +pub const UINT8_WIDTH: u32 = 8; +pub const INT16_WIDTH: u32 = 16; +pub const UINT16_WIDTH: u32 = 16; +pub const INT32_WIDTH: u32 = 32; +pub const UINT32_WIDTH: u32 = 32; +pub const INT64_WIDTH: u32 = 64; +pub const UINT64_WIDTH: u32 = 64; +pub const INT_LEAST8_WIDTH: u32 = 8; +pub const UINT_LEAST8_WIDTH: u32 = 8; +pub const INT_LEAST16_WIDTH: u32 = 16; +pub const UINT_LEAST16_WIDTH: u32 = 16; +pub const INT_LEAST32_WIDTH: u32 = 32; +pub const UINT_LEAST32_WIDTH: u32 = 32; +pub const INT_LEAST64_WIDTH: u32 = 64; +pub const UINT_LEAST64_WIDTH: u32 = 64; +pub const INT_FAST8_WIDTH: u32 = 8; +pub const UINT_FAST8_WIDTH: u32 = 8; +pub const INT_FAST16_WIDTH: u32 = 64; +pub const UINT_FAST16_WIDTH: u32 = 64; +pub const INT_FAST32_WIDTH: u32 = 64; +pub const UINT_FAST32_WIDTH: u32 = 64; +pub const INT_FAST64_WIDTH: u32 = 64; +pub const UINT_FAST64_WIDTH: u32 = 64; +pub const INTPTR_WIDTH: u32 = 64; +pub const UINTPTR_WIDTH: u32 = 64; +pub const INTMAX_WIDTH: u32 = 64; +pub const UINTMAX_WIDTH: u32 = 64; +pub const PTRDIFF_WIDTH: u32 = 64; +pub const SIG_ATOMIC_WIDTH: u32 = 32; +pub const SIZE_WIDTH: u32 = 64; +pub const WCHAR_WIDTH: u32 = 32; +pub const WINT_WIDTH: u32 = 32; +pub const _TIME_H: u32 = 1; +pub const _BITS_TIME_H: u32 = 1; pub const CLOCK_REALTIME: u32 = 0; pub const CLOCK_MONOTONIC: u32 = 1; pub const CLOCK_PROCESS_CPUTIME_ID: u32 = 2; @@ -223,7 +557,8 @@ pub const _BITS_TYPES___LOCALE_T_H: u32 = 1; pub const TIME_UTC: u32 = 1; pub const CINDEX_VERSION_MAJOR: u32 = 0; pub const CINDEX_VERSION_MINOR: u32 = 59; -pub type size_t = ::std::os::raw::c_ulong; +pub type std_size_t = ::std::os::raw::c_ulong; +pub type std_nullptr_t = *const ::std::os::raw::c_void; pub type __u_char = ::std::os::raw::c_uchar; pub type __u_short = ::std::os::raw::c_ushort; pub type __u_int = ::std::os::raw::c_uint; @@ -315,6 +650,25 @@ pub type __caddr_t = *mut ::std::os::raw::c_char; pub type __intptr_t = ::std::os::raw::c_long; pub type __socklen_t = ::std::os::raw::c_uint; pub type __sig_atomic_t = ::std::os::raw::c_int; +pub type int_least8_t = __int_least8_t; +pub type int_least16_t = __int_least16_t; +pub type int_least32_t = __int_least32_t; +pub type int_least64_t = __int_least64_t; +pub type uint_least8_t = __uint_least8_t; +pub type uint_least16_t = __uint_least16_t; +pub type uint_least32_t = __uint_least32_t; +pub type uint_least64_t = __uint_least64_t; +pub type int_fast8_t = ::std::os::raw::c_schar; +pub type int_fast16_t = ::std::os::raw::c_long; +pub type int_fast32_t = ::std::os::raw::c_long; +pub type int_fast64_t = ::std::os::raw::c_long; +pub type uint_fast8_t = ::std::os::raw::c_uchar; +pub type uint_fast16_t = ::std::os::raw::c_ulong; +pub type uint_fast32_t = ::std::os::raw::c_ulong; +pub type uint_fast64_t = ::std::os::raw::c_ulong; +pub type intmax_t = __intmax_t; +pub type uintmax_t = __uintmax_t; +pub type size_t = ::std::os::raw::c_ulong; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct timeval { From 79f75683ebf3b3c11a73e456307c90c690eeb9f2 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 18 Mar 2020 17:04:51 -0700 Subject: [PATCH 80/88] Make clang interface C only to avoid C++ mangling issues Platforms don't mangle C++ the same, so we should avoid depending on C++ mangling if we're going to embed a bindings file. --- src/clang/clang_interface.cpp | 18 +++-- src/clang/clang_interface.hpp | 18 +++-- src/clang/clang_interface.rs | 145 ---------------------------------- src/clang/libclang_compat.cpp | 2 +- 4 files changed, 22 insertions(+), 161 deletions(-) diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index ab53573625..533d4b2ee8 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -52,9 +52,11 @@ BindgenStringRef stringref(llvm::StringRef S) { return ref; } -BindgenSourceRange::BindgenSourceRange(const SourceRange &range) { - B = new SourceLocation(range.getBegin()); - E = new SourceLocation(range.getEnd()); +BindgenSourceRange make_sourcerange(const SourceRange &range) { + BindgenSourceRange out; + out.B = new SourceLocation(range.getBegin()); + out.E = new SourceLocation(range.getEnd()); + return out; } BindgenStringRefSet make_stringrefset(std::vector &string_vec) { @@ -471,7 +473,7 @@ long long Decl_getOffsetOfField(const Decl *D, ASTContext *Ctx) { } BindgenSourceRange Decl_getSourceRange(const Decl *D) { - return BindgenSourceRange(D->getSourceRange()); + return make_sourcerange(D->getSourceRange()); } QualType Decl_getTypedefDeclUnderlyingType(const Decl *D) { @@ -926,7 +928,7 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { QualType Expr_getType(const Expr *E) { return make_type_compatible(E->getType()); } BindgenSourceRange Expr_getSourceRange(const Expr *E) { - return BindgenSourceRange(E->getSourceRange()); + return make_sourcerange(E->getSourceRange()); } class BindgenVisitor : public RecursiveASTVisitor { @@ -1676,15 +1678,15 @@ SourceLocation *PreprocessedEntity_getLocation(const PreprocessedEntity *PPE) { } BindgenSourceRange CXXBaseSpecifier_getSourceRange(const CXXBaseSpecifier *B) { - return BindgenSourceRange(B->getSourceRange()); + return make_sourcerange(B->getSourceRange()); } BindgenSourceRange Attr_getSourceRange(const Attr *A) { - return BindgenSourceRange(A->getRange()); + return make_sourcerange(A->getRange()); } BindgenSourceRange PreprocessedEntity_getSourceRange(const PreprocessedEntity *PPE) { - return BindgenSourceRange(PPE->getSourceRange()); + return make_sourcerange(PPE->getSourceRange()); } BindgenStringRef PreprocessedEntity_getSpelling(const PreprocessedEntity *PPE) { diff --git a/src/clang/clang_interface.hpp b/src/clang/clang_interface.hpp index 6efcd76133..f72d237430 100644 --- a/src/clang/clang_interface.hpp +++ b/src/clang/clang_interface.hpp @@ -30,10 +30,12 @@ struct FullComment; } // namespace clang -struct EvalResult; - using namespace clang; +extern "C" { + +struct EvalResult; + struct BindgenStringRef { char *s; size_t len; @@ -51,7 +53,7 @@ struct BindgenStringRefSet { BindgenStringRef *strings; size_t len; - BindgenStringRefSet() : strings(nullptr), len(0) {} + // BindgenStringRefSet() : strings(nullptr), len(0) {} }; @@ -59,10 +61,10 @@ struct BindgenSourceRange { SourceLocation *B; SourceLocation *E; - BindgenSourceRange(const SourceRange &range); - operator bool() const { - return B && E; - } + // BindgenSourceRange(const SourceRange &range); + // operator bool() const { + // return B && E; + // } }; @@ -266,4 +268,6 @@ CX_CXXAccessSpecifier CXXBaseSpecifier_getAccess(const CXXBaseSpecifier *); BindgenSourceRange Attr_getSourceRange(const Attr *); BindgenSourceRange PreprocessedEntity_getSourceRange(const PreprocessedEntity *); +} // extern "C" + #endif // BINDGEN_CLANG_AST_H diff --git a/src/clang/clang_interface.rs b/src/clang/clang_interface.rs index c9032f49ba..aebe45fcfc 100644 --- a/src/clang/clang_interface.rs +++ b/src/clang/clang_interface.rs @@ -6821,55 +6821,29 @@ fn bindgen_test_layout_BindgenSourceRange() { ); } extern "C" { - #[link_name = "\u{1}_ZN18BindgenSourceRangeC1ERKN5clang11SourceRangeE"] - pub fn BindgenSourceRange_BindgenSourceRange( - this: *mut BindgenSourceRange, - range: *const clang_SourceRange, - ); -} -impl BindgenSourceRange { - #[inline] - pub unsafe fn new(range: *const clang_SourceRange) -> Self { - let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); - BindgenSourceRange_BindgenSourceRange( - __bindgen_tmp.as_mut_ptr(), - range, - ); - __bindgen_tmp.assume_init() - } -} -extern "C" { - #[link_name = "\u{1}_Z12deleteStringP16BindgenStringRef"] pub fn deleteString(s: *mut BindgenStringRef); } extern "C" { - #[link_name = "\u{1}_Z7cStringP16BindgenStringRef"] pub fn cString(s: *mut BindgenStringRef) -> *mut ::std::os::raw::c_char; } extern "C" { - #[link_name = "\u{1}_Z15deleteStringSetP19BindgenStringRefSet"] pub fn deleteStringSet(s: *mut BindgenStringRefSet); } extern "C" { - #[link_name = "\u{1}_Z20deleteSourceLocationPN5clang14SourceLocationE"] pub fn deleteSourceLocation(s: *mut clang_SourceLocation); } extern "C" { - #[link_name = "\u{1}_Z17deleteSourceRangeP18BindgenSourceRange"] pub fn deleteSourceRange(s: *mut BindgenSourceRange); } extern "C" { - #[link_name = "\u{1}_Z16deleteEvalResultP10EvalResult"] pub fn deleteEvalResult(e: *mut EvalResult); } extern "C" { - #[link_name = "\u{1}_Z18ASTUnit_getContextPN5clang7ASTUnitE"] pub fn ASTUnit_getContext( arg1: *mut clang_ASTUnit, ) -> *mut clang_ASTContext; } extern "C" { - #[link_name = "\u{1}_Z20parseTranslationUnitPKcPKS0_ijP13CXUnsavedFilej"] pub fn parseTranslationUnit( source_filename: *const ::std::os::raw::c_char, command_line_args: *const *const ::std::os::raw::c_char, @@ -6880,357 +6854,286 @@ extern "C" { ) -> *mut clang_ASTUnit; } extern "C" { - #[link_name = "\u{1}_Z14disposeASTUnitPN5clang7ASTUnitE"] pub fn disposeASTUnit(AU: *mut clang_ASTUnit); } extern "C" { - #[link_name = "\u{1}_Z25ASTUnit_getNumDiagnosticsPKN5clang7ASTUnitE"] pub fn ASTUnit_getNumDiagnostics( AU: *const clang_ASTUnit, ) -> ::std::os::raw::c_uint; } extern "C" { - #[link_name = "\u{1}_Z21ASTUnit_getDiagnosticPKN5clang7ASTUnitEj"] pub fn ASTUnit_getDiagnostic( AU: *const clang_ASTUnit, i: ::std::os::raw::c_uint, ) -> *const clang_StoredDiagnostic; } extern "C" { - #[link_name = "\u{1}_Z21ASTUnit_getTargetInfoPN5clang7ASTUnitE"] pub fn ASTUnit_getTargetInfo( AU: *mut clang_ASTUnit, ) -> *const clang_TargetInfo; } extern "C" { - #[link_name = "\u{1}_Z26TargetInfo_getPointerWidthPKN5clang10TargetInfoE"] pub fn TargetInfo_getPointerWidth( TI: *const clang_TargetInfo, ) -> ::std::os::raw::c_int; } extern "C" { - #[link_name = "\u{1}_Z20TargetInfo_getTriplePKN5clang10TargetInfoE"] pub fn TargetInfo_getTriple( TI: *const clang_TargetInfo, ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z13Expr_EvaluatePKN5clang4ExprEPNS_10ASTContextE"] pub fn Expr_Evaluate( E: *const clang_Expr, Ctx: *mut clang_ASTContext, ) -> *mut EvalResult; } extern "C" { - #[link_name = "\u{1}_Z13Decl_EvaluatePKN5clang4DeclEPNS_10ASTContextE"] pub fn Decl_Evaluate( D: *const clang_Decl, Ctx: *mut clang_ASTContext, ) -> *mut EvalResult; } extern "C" { - #[link_name = "\u{1}_Z18EvalResult_getKindP10EvalResult"] pub fn EvalResult_getKind(arg1: *mut EvalResult) -> CXEvalResultKind::Type; } extern "C" { - #[link_name = "\u{1}_Z22EvalResult_getAsDoubleP10EvalResult"] pub fn EvalResult_getAsDouble(arg1: *mut EvalResult) -> f64; } extern "C" { - #[link_name = "\u{1}_Z24EvalResult_isUnsignedIntP10EvalResult"] pub fn EvalResult_isUnsignedInt(arg1: *mut EvalResult) -> bool; } extern "C" { - #[link_name = "\u{1}_Z24EvalResult_getAsUnsignedP10EvalResult"] pub fn EvalResult_getAsUnsigned( arg1: *mut EvalResult, ) -> ::std::os::raw::c_ulonglong; } extern "C" { - #[link_name = "\u{1}_Z24EvalResult_getAsLongLongP10EvalResult"] pub fn EvalResult_getAsLongLong( arg1: *mut EvalResult, ) -> ::std::os::raw::c_longlong; } extern "C" { - #[link_name = "\u{1}_Z19EvalResult_getAsStrP10EvalResult"] pub fn EvalResult_getAsStr(arg1: *mut EvalResult) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z17Diagnostic_formatPKN5clang16StoredDiagnosticE"] pub fn Diagnostic_format( arg1: *const clang_StoredDiagnostic, ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z22Diagnostic_getSeverityPKN5clang16StoredDiagnosticE"] pub fn Diagnostic_getSeverity( arg1: *const clang_StoredDiagnostic, ) -> CXDiagnosticSeverity::Type; } extern "C" { - #[link_name = "\u{1}_Z22getTranslationUnitDeclPN5clang7ASTUnitE"] pub fn getTranslationUnitDecl( arg1: *mut clang_ASTUnit, ) -> *const clang_Decl; } extern "C" { - #[link_name = "\u{1}_Z20CursorKind_isInvalid12CXCursorKind"] pub fn CursorKind_isInvalid(kind: CXCursorKind::Type) -> bool; } extern "C" { - #[link_name = "\u{1}_Z21Decl_getLexicalParentPKN5clang4DeclE"] pub fn Decl_getLexicalParent(D: *const clang_Decl) -> *const clang_Decl; } extern "C" { - #[link_name = "\u{1}_Z22Decl_getSemanticParentPKN5clang4DeclE"] pub fn Decl_getSemanticParent(D: *const clang_Decl) -> *const clang_Decl; } extern "C" { - #[link_name = "\u{1}_Z18Decl_getDefinitionPKN5clang4DeclEb"] pub fn Decl_getDefinition( D: *const clang_Decl, isReference: bool, ) -> *const clang_Decl; } extern "C" { - #[link_name = "\u{1}_Z18Decl_getReferencedPKN5clang4DeclE"] pub fn Decl_getReferenced(D: *const clang_Decl) -> *const clang_Decl; } extern "C" { - #[link_name = "\u{1}_Z17Decl_getCanonicalPKN5clang4DeclE"] pub fn Decl_getCanonical(D: *const clang_Decl) -> *const clang_Decl; } extern "C" { - #[link_name = "\u{1}_Z27Decl_getSpecializedTemplatePKN5clang4DeclE"] pub fn Decl_getSpecializedTemplate( D: *const clang_Decl, ) -> *const clang_Decl; } extern "C" { - #[link_name = "\u{1}_Z26Decl_getTemplateCursorKindPKN5clang4DeclE"] pub fn Decl_getTemplateCursorKind( D: *const clang_Decl, ) -> CXCursorKind::Type; } extern "C" { - #[link_name = "\u{1}_Z16Decl_getArgumentPKN5clang4DeclEj"] pub fn Decl_getArgument( D: *const clang_Decl, i: ::std::os::raw::c_uint, ) -> *const clang_Decl; } extern "C" { - #[link_name = "\u{1}_Z20Decl_getNumArgumentsPKN5clang4DeclE"] pub fn Decl_getNumArguments(D: *const clang_Decl) -> ::std::os::raw::c_int; } extern "C" { - #[link_name = "\u{1}_Z11Decl_getUSRPKN5clang4DeclE"] pub fn Decl_getUSR(D: *const clang_Decl) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z16Decl_getSpellingPKN5clang4DeclE"] pub fn Decl_getSpelling(D: *const clang_Decl) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z19Decl_getDisplayNamePKN5clang4DeclE"] pub fn Decl_getDisplayName(D: *const clang_Decl) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z16Decl_getManglingPKN5clang4DeclEPNS_10ASTContextE"] pub fn Decl_getMangling( D: *const clang_Decl, arg1: *mut clang_ASTContext, ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z20Decl_getCXXManglingsPKN5clang4DeclEPNS_10ASTContextE"] pub fn Decl_getCXXManglings( D: *const clang_Decl, arg1: *mut clang_ASTContext, ) -> BindgenStringRefSet; } extern "C" { - #[link_name = "\u{1}_Z28Decl_getNumTemplateArgumentsPKN5clang4DeclE"] pub fn Decl_getNumTemplateArguments( D: *const clang_Decl, ) -> ::std::os::raw::c_int; } extern "C" { - #[link_name = "\u{1}_Z20Decl_getCXCursorKindPKN5clang4DeclE"] pub fn Decl_getCXCursorKind(D: *const clang_Decl) -> CXCursorKind::Type; } extern "C" { - #[link_name = "\u{1}_Z17Decl_isDefinitionPKN5clang4DeclE"] pub fn Decl_isDefinition(D: *const clang_Decl) -> bool; } extern "C" { - #[link_name = "\u{1}_Z16Decl_getLocationPKN5clang4DeclE"] pub fn Decl_getLocation(D: *const clang_Decl) -> *mut clang_SourceLocation; } extern "C" { - #[link_name = "\u{1}_Z22Decl_getRawCommentTextPKN5clang4DeclEPNS_10ASTContextE"] pub fn Decl_getRawCommentText( D: *const clang_Decl, arg1: *mut clang_ASTContext, ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z21Decl_getParsedCommentPKN5clang4DeclEPNS_10ASTContextE"] pub fn Decl_getParsedComment( D: *const clang_Decl, arg1: *mut clang_ASTContext, ) -> *mut clang_comments_Comment; } extern "C" { - #[link_name = "\u{1}_Z12Decl_getTypePKN5clang4DeclEPNS_10ASTContextE"] pub fn Decl_getType( D: *const clang_Decl, arg1: *mut clang_ASTContext, ) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z22Decl_isFunctionInlinedPKN5clang4DeclE"] pub fn Decl_isFunctionInlined(D: *const clang_Decl) -> bool; } extern "C" { - #[link_name = "\u{1}_Z25Decl_getFieldDeclBitWidthPKN5clang4DeclEPNS_10ASTContextE"] pub fn Decl_getFieldDeclBitWidth( D: *const clang_Decl, arg1: *mut clang_ASTContext, ) -> ::std::os::raw::c_int; } extern "C" { - #[link_name = "\u{1}_Z27Decl_getEnumDeclIntegerTypePKN5clang4DeclE"] pub fn Decl_getEnumDeclIntegerType(D: *const clang_Decl) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z25Decl_getEnumConstantValuePKN5clang4DeclE"] pub fn Decl_getEnumConstantValue(D: *const clang_Decl) -> i64; } extern "C" { - #[link_name = "\u{1}_Z33Decl_getEnumConstantUnsignedValuePKN5clang4DeclE"] pub fn Decl_getEnumConstantUnsignedValue(D: *const clang_Decl) -> u64; } extern "C" { - #[link_name = "\u{1}_Z21Decl_getOffsetOfFieldPKN5clang4DeclEPNS_10ASTContextE"] pub fn Decl_getOffsetOfField( D: *const clang_Decl, arg1: *mut clang_ASTContext, ) -> ::std::os::raw::c_longlong; } extern "C" { - #[link_name = "\u{1}_Z19Decl_getSourceRangePKN5clang4DeclE"] pub fn Decl_getSourceRange(D: *const clang_Decl) -> BindgenSourceRange; } extern "C" { - #[link_name = "\u{1}_Z33Decl_getTypedefDeclUnderlyingTypePKN5clang4DeclE"] pub fn Decl_getTypedefDeclUnderlyingType( D: *const clang_Decl, ) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z15Decl_getLinkagePKN5clang4DeclE"] pub fn Decl_getLinkage(D: *const clang_Decl) -> CXLinkageKind::Type; } extern "C" { - #[link_name = "\u{1}_Z18Decl_getVisibilityPKN5clang4DeclE"] pub fn Decl_getVisibility(D: *const clang_Decl) -> CXVisibilityKind::Type; } extern "C" { - #[link_name = "\u{1}_Z14Decl_getAccessPKN5clang4DeclE"] pub fn Decl_getAccess(D: *const clang_Decl) -> CX_CXXAccessSpecifier::Type; } extern "C" { - #[link_name = "\u{1}_Z18CXXField_isMutablePKN5clang4DeclE"] pub fn CXXField_isMutable(D: *const clang_Decl) -> bool; } extern "C" { - #[link_name = "\u{1}_Z18CXXMethod_isStaticPKN5clang4DeclE"] pub fn CXXMethod_isStatic(D: *const clang_Decl) -> bool; } extern "C" { - #[link_name = "\u{1}_Z17CXXMethod_isConstPKN5clang4DeclE"] pub fn CXXMethod_isConst(D: *const clang_Decl) -> bool; } extern "C" { - #[link_name = "\u{1}_Z19CXXMethod_isVirtualPKN5clang4DeclE"] pub fn CXXMethod_isVirtual(D: *const clang_Decl) -> bool; } extern "C" { - #[link_name = "\u{1}_Z23CXXMethod_isPureVirtualPKN5clang4DeclE"] pub fn CXXMethod_isPureVirtual(D: *const clang_Decl) -> bool; } extern "C" { - #[link_name = "\u{1}_Z18Decl_getResultTypePKN5clang4DeclEPNS_10ASTContextE"] pub fn Decl_getResultType( D: *const clang_Decl, arg1: *mut clang_ASTContext, ) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z16Expr_getArgumentPKN5clang4ExprEj"] pub fn Expr_getArgument( E: *const clang_Expr, i: ::std::os::raw::c_uint, ) -> *const clang_Expr; } extern "C" { - #[link_name = "\u{1}_Z20Expr_getNumArgumentsPKN5clang4ExprE"] pub fn Expr_getNumArguments(E: *const clang_Expr) -> ::std::os::raw::c_int; } extern "C" { - #[link_name = "\u{1}_Z11Expr_getUSRPKN5clang4ExprE"] pub fn Expr_getUSR(E: *const clang_Expr) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z16Expr_getSpellingPKN5clang4ExprE"] pub fn Expr_getSpelling(E: *const clang_Expr) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z19Expr_getDisplayNamePKN5clang4ExprE"] pub fn Expr_getDisplayName(E: *const clang_Expr) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z16Expr_getManglingPKN5clang4ExprE"] pub fn Expr_getMangling(E: *const clang_Expr) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z20Expr_getCXXManglingsPKN5clang4ExprE"] pub fn Expr_getCXXManglings(E: *const clang_Expr) -> BindgenStringRefSet; } extern "C" { - #[link_name = "\u{1}_Z20Expr_getCXCursorKindPKN5clang4ExprE"] pub fn Expr_getCXCursorKind(E: *const clang_Expr) -> CXCursorKind::Type; } extern "C" { - #[link_name = "\u{1}_Z16Expr_getLocationPKN5clang4ExprE"] pub fn Expr_getLocation(E: *const clang_Expr) -> *mut clang_SourceLocation; } extern "C" { - #[link_name = "\u{1}_Z22Expr_getRawCommentTextPKN5clang4ExprE"] pub fn Expr_getRawCommentText(E: *const clang_Expr) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z21Expr_getParsedCommentPKN5clang4ExprE"] pub fn Expr_getParsedComment( E: *const clang_Expr, ) -> *mut clang_comments_FullComment; } extern "C" { - #[link_name = "\u{1}_Z12Expr_getTypePKN5clang4ExprE"] pub fn Expr_getType(E: *const clang_Expr) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z19Expr_getSourceRangePKN5clang4ExprE"] pub fn Expr_getSourceRange(E: *const clang_Expr) -> BindgenSourceRange; } extern "C" { - #[link_name = "\u{1}_Z19Type_getDeclarationN5clang8QualTypeE"] pub fn Type_getDeclaration(arg1: clang_QualType) -> *const clang_Decl; } extern "C" { - #[link_name = "\u{1}_Z20Attr_getCXCursorKindPKN5clang4AttrE"] pub fn Attr_getCXCursorKind(arg1: *const clang_Attr) -> CXCursorKind::Type; } #[repr(C)] @@ -7364,7 +7267,6 @@ pub type Visitor = ::std::option::Option< ) -> CXChildVisitResult::Type, >; extern "C" { - #[link_name = "\u{1}_Z18Decl_visitChildrenPKN5clang4DeclE12CXCursorKindPF18CXChildVisitResult4NodeS5_PNS_7ASTUnitEPvES7_S8_"] pub fn Decl_visitChildren( Parent: *const clang_Decl, kind: CXCursorKind::Type, @@ -7374,7 +7276,6 @@ extern "C" { ); } extern "C" { - #[link_name = "\u{1}_Z18Expr_visitChildrenPKN5clang4ExprE12CXCursorKindPF18CXChildVisitResult4NodeS5_PNS_7ASTUnitEPvES7_S8_"] pub fn Expr_visitChildren( Parent: *const clang_Expr, kind: CXCursorKind::Type, @@ -7384,7 +7285,6 @@ extern "C" { ); } extern "C" { - #[link_name = "\u{1}_Z30CXXBaseSpecifier_visitChildrenPKN5clang16CXXBaseSpecifierE12CXCursorKindPF18CXChildVisitResult4NodeS5_PNS_7ASTUnitEPvES7_S8_"] pub fn CXXBaseSpecifier_visitChildren( Parent: *const clang_CXXBaseSpecifier, kind: CXCursorKind::Type, @@ -7394,7 +7294,6 @@ extern "C" { ); } extern "C" { - #[link_name = "\u{1}_Z8tokenizePN5clang7ASTUnitE18BindgenSourceRangePP7CXTokenPj"] pub fn tokenize( TU: *mut clang_ASTUnit, Range: BindgenSourceRange, @@ -7403,7 +7302,6 @@ extern "C" { ); } extern "C" { - #[link_name = "\u{1}_Z13disposeTokensPKN5clang7ASTUnitEP7CXTokenj"] pub fn disposeTokens( TU: *const clang_ASTUnit, Tokens: *mut CXToken, @@ -7411,111 +7309,91 @@ extern "C" { ); } extern "C" { - #[link_name = "\u{1}_Z12getTokenKind7CXToken"] pub fn getTokenKind(token: CXToken) -> CXTokenKind::Type; } extern "C" { - #[link_name = "\u{1}_Z16getTokenSpellingPN5clang7ASTUnitE7CXToken"] pub fn getTokenSpelling( TU: *mut clang_ASTUnit, token: CXToken, ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z9Type_kindN5clang8QualTypeEPNS_10ASTContextE"] pub fn Type_kind( arg1: clang_QualType, arg2: *mut clang_ASTContext, ) -> CXTypeKind::Type; } extern "C" { - #[link_name = "\u{1}_Z20Type_getTypeSpellingN5clang8QualTypeEPNS_10ASTContextE"] pub fn Type_getTypeSpelling( arg1: clang_QualType, arg2: *mut clang_ASTContext, ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z25Type_isConstQualifiedTypeN5clang8QualTypeE"] pub fn Type_isConstQualifiedType(arg1: clang_QualType) -> bool; } extern "C" { - #[link_name = "\u{1}_Z14Type_getSizeOfN5clang8QualTypeEPNS_10ASTContextE"] pub fn Type_getSizeOf( arg1: clang_QualType, arg2: *mut clang_ASTContext, ) -> ::std::os::raw::c_longlong; } extern "C" { - #[link_name = "\u{1}_Z15Type_getAlignOfN5clang8QualTypeEPNS_10ASTContextE"] pub fn Type_getAlignOf( arg1: clang_QualType, arg2: *mut clang_ASTContext, ) -> ::std::os::raw::c_longlong; } extern "C" { - #[link_name = "\u{1}_Z28Type_getNumTemplateArgumentsN5clang8QualTypeE"] pub fn Type_getNumTemplateArguments( arg1: clang_QualType, ) -> ::std::os::raw::c_int; } extern "C" { - #[link_name = "\u{1}_Z15Type_getArgTypeN5clang8QualTypeEj"] pub fn Type_getArgType( T: clang_QualType, index: ::std::os::raw::c_uint, ) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z19Type_getNumArgTypesN5clang8QualTypeE"] pub fn Type_getNumArgTypes(arg1: clang_QualType) -> ::std::os::raw::c_int; } extern "C" { - #[link_name = "\u{1}_Z19Type_getPointeeTypeN5clang8QualTypeE"] pub fn Type_getPointeeType(arg1: clang_QualType) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z19Type_getElementTypeN5clang8QualTypeE"] pub fn Type_getElementType(arg1: clang_QualType) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z19Type_getNumElementsN5clang8QualTypeE"] pub fn Type_getNumElements(arg1: clang_QualType) -> ::std::os::raw::c_int; } extern "C" { - #[link_name = "\u{1}_Z21Type_getCanonicalTypeN5clang8QualTypeEPNS_10ASTContextE"] pub fn Type_getCanonicalType( arg1: clang_QualType, arg2: *mut clang_ASTContext, ) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z27Type_isFunctionTypeVariadicN5clang8QualTypeE"] pub fn Type_isFunctionTypeVariadic(arg1: clang_QualType) -> bool; } extern "C" { - #[link_name = "\u{1}_Z18Type_getResultTypeN5clang8QualTypeE"] pub fn Type_getResultType(arg1: clang_QualType) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z31Type_getFunctionTypeCallingConvN5clang8QualTypeE"] pub fn Type_getFunctionTypeCallingConv( arg1: clang_QualType, ) -> CXCallingConv::Type; } extern "C" { - #[link_name = "\u{1}_Z17Type_getNamedTypeN5clang8QualTypeE"] pub fn Type_getNamedType(arg1: clang_QualType) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z30Type_getTemplateArgumentAsTypeN5clang8QualTypeEj"] pub fn Type_getTemplateArgumentAsType( T: clang_QualType, index: ::std::os::raw::c_uint, ) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z19getSpellingLocationPN5clang7ASTUnitEPKNS_14SourceLocationEPPNS_9FileEntryEPiS8_S8_"] pub fn getSpellingLocation( AST: *mut clang_ASTUnit, T: *const clang_SourceLocation, @@ -7526,133 +7404,110 @@ extern "C" { ); } extern "C" { - #[link_name = "\u{1}_Z15Comment_getKindPKN5clang8comments7CommentE"] pub fn Comment_getKind( arg1: *const clang_comments_Comment, ) -> CXCommentKind::Type; } extern "C" { - #[link_name = "\u{1}_Z22Comment_getNumChildrenPKN5clang8comments7CommentE"] pub fn Comment_getNumChildren( arg1: *const clang_comments_Comment, ) -> ::std::os::raw::c_uint; } extern "C" { - #[link_name = "\u{1}_Z16Comment_getChildPKN5clang8comments7CommentEj"] pub fn Comment_getChild( arg1: *const clang_comments_Comment, index: ::std::os::raw::c_uint, ) -> *mut clang_comments_Comment; } extern "C" { - #[link_name = "\u{1}_Z25HTMLTagComment_getTagNamePKN5clang8comments7CommentE"] pub fn HTMLTagComment_getTagName( arg1: *const clang_comments_Comment, ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z24HTMLStartTag_getNumAttrsPKN5clang8comments7CommentE"] pub fn HTMLStartTag_getNumAttrs( arg1: *const clang_comments_Comment, ) -> ::std::os::raw::c_uint; } extern "C" { - #[link_name = "\u{1}_Z24HTMLStartTag_getAttrNamePKN5clang8comments7CommentEj"] pub fn HTMLStartTag_getAttrName( arg1: *const clang_comments_Comment, arg2: ::std::os::raw::c_uint, ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z25HTMLStartTag_getAttrValuePKN5clang8comments7CommentEj"] pub fn HTMLStartTag_getAttrValue( arg1: *const clang_comments_Comment, arg2: ::std::os::raw::c_uint, ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z22CursorKind_getSpelling12CXCursorKind"] pub fn CursorKind_getSpelling(arg1: CXCursorKind::Type) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z20TypeKind_getSpelling10CXTypeKind"] pub fn TypeKind_getSpelling(arg1: CXTypeKind::Type) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z30PreprocessedEntity_getSpellingPKN5clang18PreprocessedEntityE"] pub fn PreprocessedEntity_getSpelling( arg1: *const clang_PreprocessedEntity, ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z17FileEntry_getNamePKN5clang9FileEntryE"] pub fn FileEntry_getName(arg1: *const clang_FileEntry) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z15getClangVersionv"] pub fn getClangVersion() -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z30CXXBaseSpecifier_isVirtualBasePKN5clang16CXXBaseSpecifierE"] pub fn CXXBaseSpecifier_isVirtualBase( arg1: *const clang_CXXBaseSpecifier, ) -> bool; } extern "C" { - #[link_name = "\u{1}_Z24CXXBaseSpecifier_getTypePKN5clang16CXXBaseSpecifierE"] pub fn CXXBaseSpecifier_getType( arg1: *const clang_CXXBaseSpecifier, ) -> clang_QualType; } extern "C" { - #[link_name = "\u{1}_Z28CXXBaseSpecifier_getSpellingPKN5clang16CXXBaseSpecifierE"] pub fn CXXBaseSpecifier_getSpelling( arg1: *const clang_CXXBaseSpecifier, ) -> BindgenStringRef; } extern "C" { - #[link_name = "\u{1}_Z28CXXBaseSpecifier_getLocationPKN5clang16CXXBaseSpecifierE"] pub fn CXXBaseSpecifier_getLocation( arg1: *const clang_CXXBaseSpecifier, ) -> *mut clang_SourceLocation; } extern "C" { - #[link_name = "\u{1}_Z16Attr_getLocationPKN5clang4AttrE"] pub fn Attr_getLocation( arg1: *const clang_Attr, ) -> *mut clang_SourceLocation; } extern "C" { - #[link_name = "\u{1}_Z30PreprocessedEntity_getLocationPKN5clang18PreprocessedEntityE"] pub fn PreprocessedEntity_getLocation( arg1: *const clang_PreprocessedEntity, ) -> *mut clang_SourceLocation; } extern "C" { - #[link_name = "\u{1}_Z34PreprocessedEntity_getIncludedFilePKN5clang18PreprocessedEntityE"] pub fn PreprocessedEntity_getIncludedFile( arg1: *const clang_PreprocessedEntity, ) -> *const clang_FileEntry; } extern "C" { - #[link_name = "\u{1}_Z31CXXBaseSpecifier_getSourceRangePKN5clang16CXXBaseSpecifierE"] pub fn CXXBaseSpecifier_getSourceRange( arg1: *const clang_CXXBaseSpecifier, ) -> BindgenSourceRange; } extern "C" { - #[link_name = "\u{1}_Z26CXXBaseSpecifier_getAccessPKN5clang16CXXBaseSpecifierE"] pub fn CXXBaseSpecifier_getAccess( arg1: *const clang_CXXBaseSpecifier, ) -> CX_CXXAccessSpecifier::Type; } extern "C" { - #[link_name = "\u{1}_Z19Attr_getSourceRangePKN5clang4AttrE"] pub fn Attr_getSourceRange(arg1: *const clang_Attr) -> BindgenSourceRange; } extern "C" { - #[link_name = "\u{1}_Z33PreprocessedEntity_getSourceRangePKN5clang18PreprocessedEntityE"] pub fn PreprocessedEntity_getSourceRange( arg1: *const clang_PreprocessedEntity, ) -> BindgenSourceRange; diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 9d584c29dd..80d7096a4e 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -1610,7 +1610,7 @@ const Decl *Type_getDeclaration(QualType T) { // Adapted from getTokens and others in CIndex.cpp void tokenize(ASTUnit *TU, BindgenSourceRange Range, CXToken **Tokens, unsigned *NumTokens) { - if (!Tokens || !NumTokens || !Range) + if (!Tokens || !NumTokens || !Range.B || !Range.E) return; // Translate the Range end location to after the last token, instead of From bd1d72a36d932467a1cadb38bda919138caf2ebf Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 18 Mar 2020 17:19:45 -0700 Subject: [PATCH 81/88] Remove old CXXFLAG --- src/clang/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/clang/CMakeLists.txt b/src/clang/CMakeLists.txt index b4afda5a32..665669f412 100644 --- a/src/clang/CMakeLists.txt +++ b/src/clang/CMakeLists.txt @@ -44,9 +44,6 @@ else() add_library(BindgenClangInterface STATIC ${SRCS}) endif() -# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") - - add_definitions(-DCLANG_LIBDIR_SUFFIX="${LLVM_LIBDIR_SUFFIX}") set_target_properties(BindgenClangInterface PROPERTIES From 8a5d6d1e8a17bba27486e34aa6bd685ebe686bbf Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 18 Mar 2020 17:19:56 -0700 Subject: [PATCH 82/88] Silence warning and add static asserts to validate assumptions --- src/clang/clang_interface.hpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/clang/clang_interface.hpp b/src/clang/clang_interface.hpp index f72d237430..f1d52cd8cf 100644 --- a/src/clang/clang_interface.hpp +++ b/src/clang/clang_interface.hpp @@ -47,6 +47,20 @@ struct QualType { void *ptr; }; } +#else +namespace { +struct ExpectedQualType { + void *ptr; +}; + +// We want to return QualType from API functions, but it is incompatible with C +// linkage. We verify that its size and alignment is correct below. +#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" +static_assert(sizeof(struct ExpectedQualType) == sizeof(clang::QualType), + "QualType has unexpected size"); +static_assert(alignof(struct ExpectedQualType) == alignof(clang::QualType), + "QualType has unexpected alignment"); +} #endif struct BindgenStringRefSet { From d7dacc3c448d135b6e81ad9337d42efa7f4c1da5 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 19 Mar 2020 10:57:29 -0700 Subject: [PATCH 83/88] Support building on Windows --- build.rs | 82 +++++++++++++++++++++++----------------- src/clang/CMakeLists.txt | 5 +++ 2 files changed, 52 insertions(+), 35 deletions(-) diff --git a/build.rs b/build.rs index c26974e090..6571798e6b 100644 --- a/build.rs +++ b/build.rs @@ -95,15 +95,25 @@ mod clang_ast { fn build_native(llvm_info: &LLVMInfo) { // Find where the (already built) LLVM lib dir is let llvm_lib_dir = &llvm_info.lib_dir; - let mut llvm_cmake_dir = format!("{}/cmake/llvm", llvm_lib_dir); - let mut clang_cmake_dir = format!("{}/cmake/clang", llvm_lib_dir); + let mut llvm_cmake_dir: PathBuf = llvm_lib_dir.into(); + llvm_cmake_dir.push("cmake"); + llvm_cmake_dir.push("llvm"); + let mut clang_cmake_dir: PathBuf = llvm_lib_dir.into(); + clang_cmake_dir.push("cmake"); + clang_cmake_dir.push("clang"); if let Some((major_version, minor_version)) = llvm_info.version { if (major_version == 3 && minor_version <= 8) || major_version < 3 { - llvm_cmake_dir = - format!("{}/../share/llvm/cmake", llvm_lib_dir); - clang_cmake_dir = - format!("{}/../share/clang/cmake", llvm_lib_dir); + llvm_cmake_dir = PathBuf::from(llvm_lib_dir); + llvm_cmake_dir.pop(); + llvm_cmake_dir.push("share"); + llvm_cmake_dir.push("llvm"); + llvm_cmake_dir.push("cmake"); + clang_cmake_dir = PathBuf::from(llvm_lib_dir); + clang_cmake_dir.pop(); + clang_cmake_dir.push("share"); + clang_cmake_dir.push("clang"); + clang_cmake_dir.push("cmake"); } } @@ -113,16 +123,14 @@ mod clang_ast { println!("cargo:rerun-if-changed=src/clang/libclang_compat.cpp"); // Build libBindgenClangInterface.a with cmake let dst = cmake::Config::new("src/clang") - .define("LLVM_DIR", &llvm_cmake_dir) - .define("Clang_DIR", &clang_cmake_dir) - .build_target("BindgenClangInterface") + .define("LLVM_DIR", llvm_cmake_dir.as_os_str()) + .define("Clang_DIR", clang_cmake_dir.as_os_str()) .build(); - let out_dir = dst.display(); - // Set up search path for newly built libBindgenClangInterface.a - println!("cargo:rustc-link-search=native={}/build/lib", out_dir); - println!("cargo:rustc-link-search=native={}/build", out_dir); + let mut out_dir = dst; + out_dir.push("lib"); + println!("cargo:rustc-link-search=native={}", out_dir.display()); // Statically link against our library, 'BindgenClangInterface' println!("cargo:rustc-link-lib=static=BindgenClangInterface"); @@ -158,7 +166,7 @@ mod clang_ast { // Link against the C++ std library. if cfg!(target_os = "macos") { println!("cargo:rustc-link-lib=c++"); - } else { + } else if cfg!(not(target_os = "windows")) { println!("cargo:rustc-link-lib=stdc++"); } } @@ -245,6 +253,25 @@ mod clang_ast { }) } + /// Strip full path from library if provided. rustc expects us to + /// pass just the library name in `-l` arguments. + fn clean_lib_path(lib: &str) -> String { + if lib.starts_with("-l") { + lib[2..].to_string() + } else { + // Sometimes llvm-config gives us an absolute path + // to the library, and I can't figure out a way to + // give an absolute path of a library to rustc. + Path::new(lib) + .file_stem() + .unwrap() + .to_str() + .unwrap() + .trim_start_matches("lib") + .into() + } + } + let llvm_config = find_llvm_config(); let lib_dir = { let path_str = build_var("LLVM_LIB_DIR") @@ -383,11 +410,11 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: args.insert(1, link_mode); } let mut libs: Vec = - invoke_command(llvm_config.as_ref(), &args) - .unwrap_or("-lLLVM".to_string()) - .split_whitespace() - .map(|lib| String::from(lib.trim_start_matches("-l"))) - .collect(); + invoke_command(llvm_config.as_ref(), &args) + .unwrap_or("-lLLVM".to_string()) + .split_whitespace() + .map(clean_lib_path) + .collect(); libs.extend( build_var("LLVM_SYSTEM_LIBS") @@ -400,22 +427,7 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: }) .unwrap_or(String::new()) .split_whitespace() - .map(|lib| { - if lib.starts_with("-l") { - lib[2..].to_string() - } else { - // Sometimes llvm-config gives us an absolute path - // to the library, and I can't figure out a way to - // give an absolute path of a library to rustc. - Path::new(lib) - .file_stem() - .unwrap() - .to_str() - .unwrap() - .trim_start_matches("lib") - .into() - } - }), + .map(clean_lib_path) ); Self { diff --git a/src/clang/CMakeLists.txt b/src/clang/CMakeLists.txt index 665669f412..0d89fca23e 100644 --- a/src/clang/CMakeLists.txt +++ b/src/clang/CMakeLists.txt @@ -61,3 +61,8 @@ target_link_libraries(BindgenClangInterface PRIVATE clangTooling clangBasic ) + +install(TARGETS BindgenClangInterface DESTINATION lib) + +# get_target_property(OUT BindgenClangInterface LINK_LIBRARIES) +# message(STATUS "test:" ${OUT}) \ No newline at end of file From 86c6cc57bcf951ea1c1a414991c7357bf6e9a732 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 19 Mar 2020 14:16:56 -0700 Subject: [PATCH 84/88] Build list of libraries to link against in cmake --- build.rs | 104 ++++++++++++++++++++++++--------------- src/clang/CMakeLists.txt | 42 +++++++++++++++- 2 files changed, 104 insertions(+), 42 deletions(-) diff --git a/build.rs b/build.rs index 6571798e6b..8927ed5f8f 100644 --- a/build.rs +++ b/build.rs @@ -73,6 +73,7 @@ mod testgen { mod clang_ast { use std::env; use std::ffi::OsStr; + use std::fs; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -122,52 +123,75 @@ mod clang_ast { println!("cargo:rerun-if-changed=src/clang/clang_interface.cpp"); println!("cargo:rerun-if-changed=src/clang/libclang_compat.cpp"); // Build libBindgenClangInterface.a with cmake - let dst = cmake::Config::new("src/clang") + let out_dir = cmake::Config::new("src/clang") .define("LLVM_DIR", llvm_cmake_dir.as_os_str()) .define("Clang_DIR", clang_cmake_dir.as_os_str()) .build(); // Set up search path for newly built libBindgenClangInterface.a - let mut out_dir = dst; - out_dir.push("lib"); - println!("cargo:rustc-link-search=native={}", out_dir.display()); + let lib_dir = out_dir.join("lib"); + println!("cargo:rustc-link-search=native={}", lib_dir.display()); // Statically link against our library, 'BindgenClangInterface' println!("cargo:rustc-link-lib=static=BindgenClangInterface"); - // Link against these Clang libs. The ordering here is important! Libraries - // must be listed before their dependencies when statically linking. + let deps_filepath = out_dir.join("BindgenClangInterface.deps"); println!("cargo:rustc-link-search=native={}", llvm_lib_dir); - for lib in &[ - "clangIndex", - "clangFrontend", - "clangParse", - "clangSerialization", - "clangSema", - "clangEdit", - "clangAnalysis", - "clangDriver", - "clangFormat", - "clangToolingCore", - "clangAST", - "clangLex", - "clangBasic", - ] { - println!("cargo:rustc-link-lib={}", lib); - } + if deps_filepath.is_file() { + // Our CMake script was able to generate a list of dependencies for + // us. This should be more accurate than what we build here. + let deps_file = fs::read_to_string(deps_filepath) + .expect("Could not read deps file"); + let deps = deps_file + .split(";") + .filter(|dep| { + // We're skipping any dependencies with delayLoad, because + // rustc doesn't know how to handle these. We don't seem to + // need them anyway. + !dep.starts_with("-delayload") + }); + for lib in deps { + println!("cargo:rustc-link-lib={}", lib); + } + } else { + // Link against these Clang libs. The ordering here is important! Libraries + // must be listed before their dependencies when statically linking. + for lib in &[ + "clangIndex", + "clangFrontend", + "clangParse", + "clangSerialization", + "clangSema", + "clangEdit", + "clangAnalysis", + "clangDriver", + "clangFormat", + "clangToolingCore", + "clangAST", + "clangLex", + "clangBasic", + ] { + println!("cargo:rustc-link-lib={}", lib); + } - for lib in &llvm_info.libs { - // IMPORTANT: We cannot specify static= or dylib= here because rustc - // will reorder those libs before the clang libs above which don't have - // static or dylib. - println!("cargo:rustc-link-lib={}", lib); - } + for lib in &llvm_info.libs { + // IMPORTANT: We cannot specify static= or dylib= here because rustc + // will reorder those libs before the clang libs above which don't have + // static or dylib. + println!("cargo:rustc-link-lib={}", lib); + } + + // Link against the C++ std library. + if cfg!(target_os = "macos") { + println!("cargo:rustc-link-lib=c++"); + } else if cfg!(not(target_os = "windows")) { + println!("cargo:rustc-link-lib=stdc++"); + } - // Link against the C++ std library. - if cfg!(target_os = "macos") { - println!("cargo:rustc-link-lib=c++"); - } else if cfg!(not(target_os = "windows")) { - println!("cargo:rustc-link-lib=stdc++"); + // clangDriver links against system version.lib on windows + if cfg!(target_os = "windows") { + println!("cargo:rustc-link-lib=version") + } } } @@ -410,11 +434,11 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: args.insert(1, link_mode); } let mut libs: Vec = - invoke_command(llvm_config.as_ref(), &args) - .unwrap_or("-lLLVM".to_string()) - .split_whitespace() - .map(clean_lib_path) - .collect(); + invoke_command(llvm_config.as_ref(), &args) + .unwrap_or("-lLLVM".to_string()) + .split_whitespace() + .map(clean_lib_path) + .collect(); libs.extend( build_var("LLVM_SYSTEM_LIBS") @@ -427,7 +451,7 @@ variable or make sure `llvm-config` is on $PATH then re-build. For example: }) .unwrap_or(String::new()) .split_whitespace() - .map(clean_lib_path) + .map(clean_lib_path), ); Self { diff --git a/src/clang/CMakeLists.txt b/src/clang/CMakeLists.txt index 0d89fca23e..70bdbf992b 100644 --- a/src/clang/CMakeLists.txt +++ b/src/clang/CMakeLists.txt @@ -64,5 +64,43 @@ target_link_libraries(BindgenClangInterface PRIVATE install(TARGETS BindgenClangInterface DESTINATION lib) -# get_target_property(OUT BindgenClangInterface LINK_LIBRARIES) -# message(STATUS "test:" ${OUT}) \ No newline at end of file +# Gather dependencies for all libraries required by our target, recursively +function(target_link_libs_recursive out_libs target) + get_target_property(imported ${target} IMPORTED) + if (imported) + get_target_property(target_link_libs ${target} INTERFACE_LINK_LIBRARIES) + else() + get_target_property(target_link_libs ${target} LINK_LIBRARIES) + endif() + if (target_link_libs) + set(libs "") + foreach(dep IN LISTS target_link_libs) + list(FIND visited_targets ${dep} visited) + if (${visited} EQUAL -1) + list(APPEND visited_targets ${dep}) + list(APPEND libs ${dep}) + if (TARGET ${dep}) + set(dependencies "") + target_link_libs_recursive(dependencies ${dep}) + list(APPEND libs ${dependencies}) + endif() + endif() + endforeach(dep) + set(visited_targets ${visited_targets} PARENT_SCOPE) + set(${out_libs} ${libs} PARENT_SCOPE) + endif() +endfunction() + +if (Clang_FOUND) + target_link_libs_recursive(link_libs BindgenClangInterface) + foreach(lib IN LISTS link_libs) + string(REGEX MATCH "^-delayload" delayload ${lib}) + if (NOT delayload) + message(STATUS "\ncargo:rustc-link-lib=" ${lib}) + endif() + endforeach(lib) + + file(WRITE "${CMAKE_INSTALL_PREFIX}/BindgenClangInterface.deps" "${link_libs}") +else() # we didn't find clang cmake files + file(REMOVE "${CMAKE_INSTALL_PREFIX}/BindgenClangInterface.deps") +endif() \ No newline at end of file From ff7f76f25db723fc518f9784c4367490c6f20abe Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 19 Mar 2020 17:45:47 -0700 Subject: [PATCH 85/88] Generate dependency list from cmake for clang shared libraries --- src/clang/CMakeLists.txt | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/clang/CMakeLists.txt b/src/clang/CMakeLists.txt index 70bdbf992b..69e514fe89 100644 --- a/src/clang/CMakeLists.txt +++ b/src/clang/CMakeLists.txt @@ -51,8 +51,9 @@ set_target_properties(BindgenClangInterface PROPERTIES CXX_EXTENSIONS OFF ) -# PRIVATE was added to make BindgenClangInterface build with LLVM 6.0. Keyword -# description: https://cmake.org/pipermail/cmake/2016-May/063400.html +# Any changes to this list must be kept in sync with ../../build.rs in case +# cmake cannot find the clang cmake config files to generate a useful dependency +# list. target_link_libraries(BindgenClangInterface PRIVATE clangAST clangFrontend @@ -60,8 +61,17 @@ target_link_libraries(BindgenClangInterface PRIVATE clangSema clangTooling clangBasic + clangLex ) +# rustc links with CC, so we need to explicitly include the C++ standard library +if (APPLE) + target_link_libraries(BindgenClangInterface PRIVATE c++) +elseif(UNIX) + target_link_libraries(BindgenClangInterface PRIVATE stdc++) +endif() + + install(TARGETS BindgenClangInterface DESTINATION lib) # Gather dependencies for all libraries required by our target, recursively @@ -69,6 +79,10 @@ function(target_link_libs_recursive out_libs target) get_target_property(imported ${target} IMPORTED) if (imported) get_target_property(target_link_libs ${target} INTERFACE_LINK_LIBRARIES) + if (NOT target_link_libs) + get_target_property(target_config ${target} IMPORTED_CONFIGURATIONS) + get_target_property(target_link_libs ${target} IMPORTED_LINK_DEPENDENT_LIBRARIES_${target_config}) + endif() else() get_target_property(target_link_libs ${target} LINK_LIBRARIES) endif() @@ -93,14 +107,8 @@ endfunction() if (Clang_FOUND) target_link_libs_recursive(link_libs BindgenClangInterface) - foreach(lib IN LISTS link_libs) - string(REGEX MATCH "^-delayload" delayload ${lib}) - if (NOT delayload) - message(STATUS "\ncargo:rustc-link-lib=" ${lib}) - endif() - endforeach(lib) file(WRITE "${CMAKE_INSTALL_PREFIX}/BindgenClangInterface.deps" "${link_libs}") else() # we didn't find clang cmake files file(REMOVE "${CMAKE_INSTALL_PREFIX}/BindgenClangInterface.deps") -endif() \ No newline at end of file +endif() From e1748a7511394ec5510712f9fe4a821b19d63b56 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 19 Mar 2020 17:46:12 -0700 Subject: [PATCH 86/88] Switch to C++11 (we don't use any C++14) --- src/clang/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clang/CMakeLists.txt b/src/clang/CMakeLists.txt index 69e514fe89..b91806c91d 100644 --- a/src/clang/CMakeLists.txt +++ b/src/clang/CMakeLists.txt @@ -47,7 +47,7 @@ endif() add_definitions(-DCLANG_LIBDIR_SUFFIX="${LLVM_LIBDIR_SUFFIX}") set_target_properties(BindgenClangInterface PROPERTIES - CXX_STANDARD 14 + CXX_STANDARD 11 CXX_EXTENSIONS OFF ) From 6dae2408f04a307f6c8ad4643beb6bcaf89cb562 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 20 Mar 2020 10:09:17 -0700 Subject: [PATCH 87/88] Default to linking against LLVM and clang-cpp shared libs if available --- build.rs | 41 ++++++++++++++++++++-------------------- src/clang/CMakeLists.txt | 15 +++++++++++---- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/build.rs b/build.rs index 8927ed5f8f..f00c9c26de 100644 --- a/build.rs +++ b/build.rs @@ -87,6 +87,25 @@ mod clang_ast { env::var(name).ok() } + /// Strip full path from library if provided. rustc expects us to + /// pass just the library name in `-l` arguments. + fn clean_lib_path(lib: &str) -> String { + if lib.starts_with("-l") { + lib[2..].to_string() + } else { + // Sometimes llvm-config gives us an absolute path + // to the library, and I can't figure out a way to + // give an absolute path of a library to rustc. + Path::new(lib) + .file_stem() + .unwrap() + .to_str() + .unwrap() + .trim_start_matches("lib") + .into() + } + } + /// Call out to CMake, build the clang ast library, and tell cargo where to look /// for it. Note that `CMAKE_BUILD_TYPE` gets implicitly determined by the /// cmake crate according to the following: @@ -149,7 +168,8 @@ mod clang_ast { // rustc doesn't know how to handle these. We don't seem to // need them anyway. !dep.starts_with("-delayload") - }); + }) + .map(clean_lib_path); for lib in deps { println!("cargo:rustc-link-lib={}", lib); } @@ -277,25 +297,6 @@ mod clang_ast { }) } - /// Strip full path from library if provided. rustc expects us to - /// pass just the library name in `-l` arguments. - fn clean_lib_path(lib: &str) -> String { - if lib.starts_with("-l") { - lib[2..].to_string() - } else { - // Sometimes llvm-config gives us an absolute path - // to the library, and I can't figure out a way to - // give an absolute path of a library to rustc. - Path::new(lib) - .file_stem() - .unwrap() - .to_str() - .unwrap() - .trim_start_matches("lib") - .into() - } - } - let llvm_config = find_llvm_config(); let lib_dir = { let path_str = build_var("LLVM_LIB_DIR") diff --git a/src/clang/CMakeLists.txt b/src/clang/CMakeLists.txt index b91806c91d..391a270414 100644 --- a/src/clang/CMakeLists.txt +++ b/src/clang/CMakeLists.txt @@ -51,10 +51,11 @@ set_target_properties(BindgenClangInterface PROPERTIES CXX_EXTENSIONS OFF ) + # Any changes to this list must be kept in sync with ../../build.rs in case -# cmake cannot find the clang cmake config files to generate a useful dependency -# list. -target_link_libraries(BindgenClangInterface PRIVATE +# cmake cannot find the clang cmake config files to generate a useful +# dependency list. +set(clang_libs clangAST clangFrontend clangIndex @@ -64,6 +65,12 @@ target_link_libraries(BindgenClangInterface PRIVATE clangLex ) +if (TARGET clang-cpp AND TARGET LLVM) + target_link_libraries(BindgenClangInterface PRIVATE LLVM clang-cpp) +else() + target_link_libraries(BindgenClangInterface PRIVATE ${clang_libs}) +endif() + # rustc links with CC, so we need to explicitly include the C++ standard library if (APPLE) target_link_libraries(BindgenClangInterface PRIVATE c++) @@ -92,12 +99,12 @@ function(target_link_libs_recursive out_libs target) list(FIND visited_targets ${dep} visited) if (${visited} EQUAL -1) list(APPEND visited_targets ${dep}) - list(APPEND libs ${dep}) if (TARGET ${dep}) set(dependencies "") target_link_libs_recursive(dependencies ${dep}) list(APPEND libs ${dependencies}) endif() + list(APPEND libs ${dep}) endif() endforeach(dep) set(visited_targets ${visited_targets} PARENT_SCOPE) From 1a5821fb0452f2a1c387cbd210d8a953d038d014 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 23 Mar 2020 12:25:29 -0700 Subject: [PATCH 88/88] Pass QualTypes to Rust as void* to avoid ABI issues We can't pass C++ objects by value from C++ to Rust. QualType has an interface for converting back and forth to void*, so we can use that instead. --- src/clang.rs | 14 +--- src/clang/clang_interface.cpp | 118 ++++++++++++++++------------- src/clang/clang_interface.hpp | 72 +++++++----------- src/clang/clang_interface.rs | 86 +++++++-------------- src/clang/clang_interface_impl.hpp | 2 +- src/clang/libclang_compat.cpp | 56 ++++++++------ 6 files changed, 156 insertions(+), 192 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index 341e91d010..292ed7835c 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -754,7 +754,7 @@ impl Cursor { _ => mem::zeroed(), } }; - if x.ptr.is_null() { + if x.is_null() { None } else { Some(Type { x, unit: self.unit }) @@ -1251,18 +1251,10 @@ where /// The type of a node in clang's AST. #[derive(Clone, Copy, PartialEq, Eq)] pub struct Type { - x: clang_interface::clang_QualType, + x: clang_interface::BindgenQualType, unit: *mut clang_interface::clang_ASTUnit, } -impl PartialEq for clang_interface::clang_QualType { - fn eq(&self, other: &Self) -> bool { - ptr::eq(self.ptr, other.ptr) - } -} - -impl Eq for clang_interface::clang_QualType {} - impl fmt::Debug for Type { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!( @@ -1701,7 +1693,7 @@ impl CanonicalTypeDeclaration { /// An iterator for a type's template arguments. pub struct TypeTemplateArgIterator { - x: clang_interface::clang_QualType, + x: clang_interface::BindgenQualType, unit: *mut clang_interface::clang_ASTUnit, length: u32, index: u32, diff --git a/src/clang/clang_interface.cpp b/src/clang/clang_interface.cpp index 533d4b2ee8..baebf15a83 100644 --- a/src/clang/clang_interface.cpp +++ b/src/clang/clang_interface.cpp @@ -378,9 +378,9 @@ comments::Comment *Decl_getParsedComment(const Decl *D, ASTContext *Ctx) { return Ctx->getCommentForDecl(&*D, nullptr); } -QualType make_type_compatible(QualType QT) { +BindgenQualType make_type_compatible(QualType QT) { if (QT.isNull()) - return QT; + return nullptr; // libclang does not return AttributedTypes if // CXTranslationUnit_IncludeAttributedTypes is not set, and bindgen assumes it @@ -396,13 +396,13 @@ QualType make_type_compatible(QualType QT) { if (auto *DT = QT->getAs()) return make_type_compatible(DT->getOriginalType()); - return QT; + return QT.getAsOpaquePtr(); } -QualType Decl_getType(const Decl *D, ASTContext *Ctx) { +BindgenQualType Decl_getType(const Decl *D, ASTContext *Ctx) { auto ty = QualType(); if (!D) - return ty; + return nullptr; if (auto *TD = dyn_cast(&*D)) ty = Ctx->getTypeDeclType(TD); @@ -417,7 +417,7 @@ QualType Decl_getType(const Decl *D, ASTContext *Ctx) { else if (auto *FTD = dyn_cast(&*D)) ty = FTD->getTemplatedDecl()->getType(); else - return QualType(); + return nullptr; return make_type_compatible(ty); } @@ -437,11 +437,11 @@ int Decl_getFieldDeclBitWidth(const Decl *D, ASTContext *Ctx) { return -1; } -QualType Decl_getEnumDeclIntegerType(const Decl *D) { +BindgenQualType Decl_getEnumDeclIntegerType(const Decl *D) { if (auto *TD = dyn_cast_or_null(&*D)) return make_type_compatible(TD->getIntegerType()); else - return QualType(); + return nullptr; } int64_t Decl_getEnumConstantValue(const Decl *D) { @@ -476,11 +476,11 @@ BindgenSourceRange Decl_getSourceRange(const Decl *D) { return make_sourcerange(D->getSourceRange()); } -QualType Decl_getTypedefDeclUnderlyingType(const Decl *D) { +BindgenQualType Decl_getTypedefDeclUnderlyingType(const Decl *D) { if (auto *TD = dyn_cast_or_null(&*D)) return make_type_compatible(TD->getUnderlyingType()); else - return QualType(); + return nullptr; } bool CXXField_isMutable(const Decl *D) { @@ -522,7 +522,7 @@ bool CXXMethod_isPureVirtual(const Decl *D) { return Method && Method->isVirtual() && Method->isPure(); } -QualType Decl_getResultType(const Decl *D, ASTContext *Ctx) { +BindgenQualType Decl_getResultType(const Decl *D, ASTContext *Ctx) { if (auto *MD = dyn_cast_or_null(D)) return make_type_compatible(MD->getReturnType()); @@ -925,7 +925,7 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E) { } } -QualType Expr_getType(const Expr *E) { return make_type_compatible(E->getType()); } +BindgenQualType Expr_getType(const Expr *E) { return make_type_compatible(E->getType()); } BindgenSourceRange Expr_getSourceRange(const Expr *E) { return make_sourcerange(E->getSourceRange()); @@ -1488,107 +1488,117 @@ void disposeTokens(const ASTUnit *TU, CXToken *Tokens, unsigned NumTokens) { delete[] Tokens; } -BindgenStringRef Type_getTypeSpelling(QualType T, ASTContext *Context) { +BindgenStringRef Type_getTypeSpelling(BindgenQualType T, ASTContext *Context) { + auto QT = QualType::getFromOpaquePtr(T); SmallString<64> Str; llvm::raw_svector_ostream OS(Str); PrintingPolicy PP(Context->getLangOpts()); - T.print(OS, PP); + QT.print(OS, PP); return stringref(OS.str()); } -bool Type_isConstQualifiedType(QualType T) { - return T.isLocalConstQualified(); +bool Type_isConstQualifiedType(BindgenQualType T) { + auto QT = QualType::getFromOpaquePtr(T); + return QT.isLocalConstQualified(); } -int Type_getNumTemplateArguments(QualType T) { - if (T.isNull()) +int Type_getNumTemplateArguments(BindgenQualType T) { + auto QT = QualType::getFromOpaquePtr(T); + if (QT.isNull()) return -1; - auto TA = GetTemplateArguments(T); + auto TA = GetTemplateArguments(QT); if (!TA) return -1; return GetTemplateArgumentArraySize(TA.getValue()); } -QualType Type_getArgType(QualType T, unsigned i) { - if (T.isNull()) - return QualType(); +BindgenQualType Type_getArgType(BindgenQualType T, unsigned i) { + auto QT = QualType::getFromOpaquePtr(T); + if (QT.isNull()) + return nullptr;; - if (const FunctionProtoType *FD = T->getAs()) { + if (const FunctionProtoType *FD = QT->getAs()) { unsigned numParams = FD->getNumParams(); if (i >= numParams) - return QualType(); + return nullptr; return make_type_compatible(FD->getParamType(i)); } - return QualType(); + return nullptr; } -int Type_getNumArgTypes(QualType T) { - if (T.isNull()) +int Type_getNumArgTypes(BindgenQualType T) { + auto QT = QualType::getFromOpaquePtr(T); + if (QT.isNull()) return -1; - if (const FunctionProtoType *FD = T->getAs()) { + if (const FunctionProtoType *FD = QT->getAs()) { return FD->getNumParams(); } - if (T->getAs()) { + if (QT->getAs()) { return 0; } return -1; } -QualType Type_getCanonicalType(QualType T, ASTContext *Context) { - if (T.isNull()) - return QualType(); +BindgenQualType Type_getCanonicalType(BindgenQualType T, ASTContext *Context) { + auto QT = QualType::getFromOpaquePtr(T); + if (QT.isNull()) + return nullptr; - return make_type_compatible(Context->getCanonicalType(T)); + return make_type_compatible(Context->getCanonicalType(QT)); } -bool Type_isFunctionTypeVariadic(QualType T) { - if (T.isNull()) +bool Type_isFunctionTypeVariadic(BindgenQualType T) { + auto QT = QualType::getFromOpaquePtr(T); + if (QT.isNull()) return false; - if (const FunctionProtoType *FD = T->getAs()) + if (const FunctionProtoType *FD = QT->getAs()) return (unsigned)FD->isVariadic(); - if (T->getAs()) + if (QT->getAs()) return true; return false; } -QualType Type_getResultType(QualType T) { - if (T.isNull()) - return QualType(); +BindgenQualType Type_getResultType(BindgenQualType T) { + auto QT = QualType::getFromOpaquePtr(T); + if (QT.isNull()) + return nullptr; - if (const FunctionType *FD = T->getAs()) + if (const FunctionType *FD = QT->getAs()) return make_type_compatible(FD->getReturnType()); - return QualType(); + return nullptr; } -QualType Type_getNamedType(QualType T) { - const Type *TP = T.getTypePtrOrNull(); +BindgenQualType Type_getNamedType(BindgenQualType T) { + auto QT = QualType::getFromOpaquePtr(T); + const Type *TP = QT.getTypePtrOrNull(); if (TP && TP->getTypeClass() == Type::Elaborated) return make_type_compatible(cast(TP)->getNamedType()); - return QualType(); + return nullptr; } -QualType Type_getTemplateArgumentAsType(QualType T, unsigned index) { - if (T.isNull()) - return QualType(); +BindgenQualType Type_getTemplateArgumentAsType(BindgenQualType T, unsigned index) { + auto QT = QualType::getFromOpaquePtr(T); + if (QT.isNull()) + return nullptr; - auto TA = GetTemplateArguments(T); + auto TA = GetTemplateArguments(QT); if (!TA) - return QualType(); + return nullptr; - Optional QT = FindTemplateArgumentTypeAt(TA.getValue(), index); - return make_type_compatible(QT.getValueOr(QualType())); + Optional ArgQT = FindTemplateArgumentTypeAt(TA.getValue(), index); + return make_type_compatible(ArgQT.getValueOr(QualType())); } unsigned Comment_getNumChildren(const comments::Comment *C) { @@ -1651,9 +1661,9 @@ bool CXXBaseSpecifier_isVirtualBase(const CXXBaseSpecifier *B) { return B && B->isVirtual(); } -QualType CXXBaseSpecifier_getType(const CXXBaseSpecifier *B) { +BindgenQualType CXXBaseSpecifier_getType(const CXXBaseSpecifier *B) { if (!B) - return QualType(); + return nullptr; return make_type_compatible(B->getType()); } diff --git a/src/clang/clang_interface.hpp b/src/clang/clang_interface.hpp index f1d52cd8cf..688c58f683 100644 --- a/src/clang/clang_interface.hpp +++ b/src/clang/clang_interface.hpp @@ -41,27 +41,9 @@ struct BindgenStringRef { size_t len; }; -#ifndef BINDGEN_IMPLEMENTATION -namespace clang { -struct QualType { - void *ptr; -}; -} -#else -namespace { -struct ExpectedQualType { - void *ptr; -}; - -// We want to return QualType from API functions, but it is incompatible with C -// linkage. We verify that its size and alignment is correct below. -#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" -static_assert(sizeof(struct ExpectedQualType) == sizeof(clang::QualType), - "QualType has unexpected size"); -static_assert(alignof(struct ExpectedQualType) == alignof(clang::QualType), - "QualType has unexpected alignment"); -} -#endif +// We export QualTypes back and forth to Rust as opaque pointers because we +// can't pass a C++ class by value. +typedef void* BindgenQualType; struct BindgenStringRefSet { BindgenStringRef *strings; @@ -144,15 +126,15 @@ bool Decl_isDefinition(const Decl *D); SourceLocation *Decl_getLocation(const Decl *D); BindgenStringRef Decl_getRawCommentText(const Decl *D, ASTContext *); comments::Comment *Decl_getParsedComment(const Decl *D, ASTContext *); -QualType Decl_getType(const Decl *D, ASTContext *); +BindgenQualType Decl_getType(const Decl *D, ASTContext *); bool Decl_isFunctionInlined(const Decl *D); int Decl_getFieldDeclBitWidth(const Decl *D, ASTContext *); -QualType Decl_getEnumDeclIntegerType(const Decl *D); +BindgenQualType Decl_getEnumDeclIntegerType(const Decl *D); int64_t Decl_getEnumConstantValue(const Decl *D); uint64_t Decl_getEnumConstantUnsignedValue(const Decl *D); long long Decl_getOffsetOfField(const Decl *D, ASTContext *); BindgenSourceRange Decl_getSourceRange(const Decl *D); -QualType Decl_getTypedefDeclUnderlyingType(const Decl *D); +BindgenQualType Decl_getTypedefDeclUnderlyingType(const Decl *D); CXLinkageKind Decl_getLinkage(const Decl *D); CXVisibilityKind Decl_getVisibility(const Decl *D); CX_CXXAccessSpecifier Decl_getAccess(const Decl *D); @@ -161,7 +143,7 @@ bool CXXMethod_isStatic(const Decl *D); bool CXXMethod_isConst(const Decl *D); bool CXXMethod_isVirtual(const Decl *D); bool CXXMethod_isPureVirtual(const Decl *D); -QualType Decl_getResultType(const Decl *D, ASTContext *); +BindgenQualType Decl_getResultType(const Decl *D, ASTContext *); const Expr *Expr_getArgument(const Expr *E, unsigned i); @@ -176,10 +158,10 @@ CXCursorKind Expr_getCXCursorKind(const Expr *E); SourceLocation *Expr_getLocation(const Expr *E); BindgenStringRef Expr_getRawCommentText(const Expr *E); comments::FullComment *Expr_getParsedComment(const Expr *E); -QualType Expr_getType(const Expr *E); +BindgenQualType Expr_getType(const Expr *E); BindgenSourceRange Expr_getSourceRange(const Expr *E); -const Decl *Type_getDeclaration(QualType); +const Decl *Type_getDeclaration(BindgenQualType); CXCursorKind Attr_getCXCursorKind(const Attr *); @@ -234,23 +216,23 @@ void disposeTokens(const ASTUnit *TU, CXToken *Tokens, unsigned NumTokens); CXTokenKind getTokenKind(CXToken token); BindgenStringRef getTokenSpelling(ASTUnit *TU, CXToken token); -CXTypeKind Type_kind(QualType, ASTContext *); -BindgenStringRef Type_getTypeSpelling(QualType, ASTContext *); -bool Type_isConstQualifiedType(QualType); -long long Type_getSizeOf(QualType, ASTContext *); -long long Type_getAlignOf(QualType, ASTContext *); -int Type_getNumTemplateArguments(QualType); -QualType Type_getArgType(QualType T, unsigned index); -int Type_getNumArgTypes(QualType); -QualType Type_getPointeeType(QualType); -QualType Type_getElementType(QualType); -int Type_getNumElements(QualType); -QualType Type_getCanonicalType(QualType, ASTContext *); -bool Type_isFunctionTypeVariadic(QualType); -QualType Type_getResultType(QualType); -CXCallingConv Type_getFunctionTypeCallingConv(QualType); -QualType Type_getNamedType(QualType); -QualType Type_getTemplateArgumentAsType(QualType T, unsigned index); +CXTypeKind Type_kind(BindgenQualType, ASTContext *); +BindgenStringRef Type_getTypeSpelling(BindgenQualType, ASTContext *); +bool Type_isConstQualifiedType(BindgenQualType); +long long Type_getSizeOf(BindgenQualType, ASTContext *); +long long Type_getAlignOf(BindgenQualType, ASTContext *); +int Type_getNumTemplateArguments(BindgenQualType); +BindgenQualType Type_getArgType(BindgenQualType T, unsigned index); +int Type_getNumArgTypes(BindgenQualType); +BindgenQualType Type_getPointeeType(BindgenQualType); +BindgenQualType Type_getElementType(BindgenQualType); +int Type_getNumElements(BindgenQualType); +BindgenQualType Type_getCanonicalType(BindgenQualType, ASTContext *); +bool Type_isFunctionTypeVariadic(BindgenQualType); +BindgenQualType Type_getResultType(BindgenQualType); +CXCallingConv Type_getFunctionTypeCallingConv(BindgenQualType); +BindgenQualType Type_getNamedType(BindgenQualType); +BindgenQualType Type_getTemplateArgumentAsType(BindgenQualType T, unsigned index); void getSpellingLocation(ASTUnit *AST, const SourceLocation *T, FileEntry **file, int *line, int *col, int *off); @@ -271,7 +253,7 @@ BindgenStringRef FileEntry_getName(const FileEntry *); BindgenStringRef getClangVersion(); bool CXXBaseSpecifier_isVirtualBase(const CXXBaseSpecifier *); -QualType CXXBaseSpecifier_getType(const CXXBaseSpecifier *); +BindgenQualType CXXBaseSpecifier_getType(const CXXBaseSpecifier *); BindgenStringRef CXXBaseSpecifier_getSpelling(const CXXBaseSpecifier *); SourceLocation *CXXBaseSpecifier_getLocation(const CXXBaseSpecifier *); SourceLocation *Attr_getLocation(const Attr *); diff --git a/src/clang/clang_interface.rs b/src/clang/clang_interface.rs index aebe45fcfc..7b3f330fb5 100644 --- a/src/clang/clang_interface.rs +++ b/src/clang/clang_interface.rs @@ -6653,36 +6653,6 @@ pub struct clang_comments_FullComment { } #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct clang_QualType { - pub ptr: *mut ::std::os::raw::c_void, -} -#[test] -fn bindgen_test_layout_clang_QualType() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(clang_QualType)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(clang_QualType)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).ptr as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(clang_QualType), - "::", - stringify!(ptr) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct EvalResult { _unused: [u8; 0], } @@ -6730,6 +6700,7 @@ fn bindgen_test_layout_BindgenStringRef() { ) ); } +pub type BindgenQualType = *mut ::std::os::raw::c_void; #[repr(C)] #[derive(Debug)] pub struct BindgenStringRefSet { @@ -7022,7 +6993,7 @@ extern "C" { pub fn Decl_getType( D: *const clang_Decl, arg1: *mut clang_ASTContext, - ) -> clang_QualType; + ) -> BindgenQualType; } extern "C" { pub fn Decl_isFunctionInlined(D: *const clang_Decl) -> bool; @@ -7034,7 +7005,8 @@ extern "C" { ) -> ::std::os::raw::c_int; } extern "C" { - pub fn Decl_getEnumDeclIntegerType(D: *const clang_Decl) -> clang_QualType; + pub fn Decl_getEnumDeclIntegerType(D: *const clang_Decl) + -> BindgenQualType; } extern "C" { pub fn Decl_getEnumConstantValue(D: *const clang_Decl) -> i64; @@ -7054,7 +7026,7 @@ extern "C" { extern "C" { pub fn Decl_getTypedefDeclUnderlyingType( D: *const clang_Decl, - ) -> clang_QualType; + ) -> BindgenQualType; } extern "C" { pub fn Decl_getLinkage(D: *const clang_Decl) -> CXLinkageKind::Type; @@ -7084,7 +7056,7 @@ extern "C" { pub fn Decl_getResultType( D: *const clang_Decl, arg1: *mut clang_ASTContext, - ) -> clang_QualType; + ) -> BindgenQualType; } extern "C" { pub fn Expr_getArgument( @@ -7125,13 +7097,13 @@ extern "C" { ) -> *mut clang_comments_FullComment; } extern "C" { - pub fn Expr_getType(E: *const clang_Expr) -> clang_QualType; + pub fn Expr_getType(E: *const clang_Expr) -> BindgenQualType; } extern "C" { pub fn Expr_getSourceRange(E: *const clang_Expr) -> BindgenSourceRange; } extern "C" { - pub fn Type_getDeclaration(arg1: clang_QualType) -> *const clang_Decl; + pub fn Type_getDeclaration(arg1: BindgenQualType) -> *const clang_Decl; } extern "C" { pub fn Attr_getCXCursorKind(arg1: *const clang_Attr) -> CXCursorKind::Type; @@ -7319,79 +7291,79 @@ extern "C" { } extern "C" { pub fn Type_kind( - arg1: clang_QualType, + arg1: BindgenQualType, arg2: *mut clang_ASTContext, ) -> CXTypeKind::Type; } extern "C" { pub fn Type_getTypeSpelling( - arg1: clang_QualType, + arg1: BindgenQualType, arg2: *mut clang_ASTContext, ) -> BindgenStringRef; } extern "C" { - pub fn Type_isConstQualifiedType(arg1: clang_QualType) -> bool; + pub fn Type_isConstQualifiedType(arg1: BindgenQualType) -> bool; } extern "C" { pub fn Type_getSizeOf( - arg1: clang_QualType, + arg1: BindgenQualType, arg2: *mut clang_ASTContext, ) -> ::std::os::raw::c_longlong; } extern "C" { pub fn Type_getAlignOf( - arg1: clang_QualType, + arg1: BindgenQualType, arg2: *mut clang_ASTContext, ) -> ::std::os::raw::c_longlong; } extern "C" { pub fn Type_getNumTemplateArguments( - arg1: clang_QualType, + arg1: BindgenQualType, ) -> ::std::os::raw::c_int; } extern "C" { pub fn Type_getArgType( - T: clang_QualType, + T: BindgenQualType, index: ::std::os::raw::c_uint, - ) -> clang_QualType; + ) -> BindgenQualType; } extern "C" { - pub fn Type_getNumArgTypes(arg1: clang_QualType) -> ::std::os::raw::c_int; + pub fn Type_getNumArgTypes(arg1: BindgenQualType) -> ::std::os::raw::c_int; } extern "C" { - pub fn Type_getPointeeType(arg1: clang_QualType) -> clang_QualType; + pub fn Type_getPointeeType(arg1: BindgenQualType) -> BindgenQualType; } extern "C" { - pub fn Type_getElementType(arg1: clang_QualType) -> clang_QualType; + pub fn Type_getElementType(arg1: BindgenQualType) -> BindgenQualType; } extern "C" { - pub fn Type_getNumElements(arg1: clang_QualType) -> ::std::os::raw::c_int; + pub fn Type_getNumElements(arg1: BindgenQualType) -> ::std::os::raw::c_int; } extern "C" { pub fn Type_getCanonicalType( - arg1: clang_QualType, + arg1: BindgenQualType, arg2: *mut clang_ASTContext, - ) -> clang_QualType; + ) -> BindgenQualType; } extern "C" { - pub fn Type_isFunctionTypeVariadic(arg1: clang_QualType) -> bool; + pub fn Type_isFunctionTypeVariadic(arg1: BindgenQualType) -> bool; } extern "C" { - pub fn Type_getResultType(arg1: clang_QualType) -> clang_QualType; + pub fn Type_getResultType(arg1: BindgenQualType) -> BindgenQualType; } extern "C" { pub fn Type_getFunctionTypeCallingConv( - arg1: clang_QualType, + arg1: BindgenQualType, ) -> CXCallingConv::Type; } extern "C" { - pub fn Type_getNamedType(arg1: clang_QualType) -> clang_QualType; + pub fn Type_getNamedType(arg1: BindgenQualType) -> BindgenQualType; } extern "C" { pub fn Type_getTemplateArgumentAsType( - T: clang_QualType, + T: BindgenQualType, index: ::std::os::raw::c_uint, - ) -> clang_QualType; + ) -> BindgenQualType; } extern "C" { pub fn getSpellingLocation( @@ -7467,7 +7439,7 @@ extern "C" { extern "C" { pub fn CXXBaseSpecifier_getType( arg1: *const clang_CXXBaseSpecifier, - ) -> clang_QualType; + ) -> BindgenQualType; } extern "C" { pub fn CXXBaseSpecifier_getSpelling( diff --git a/src/clang/clang_interface_impl.hpp b/src/clang/clang_interface_impl.hpp index 1c5076994f..4fd5919162 100644 --- a/src/clang/clang_interface_impl.hpp +++ b/src/clang/clang_interface_impl.hpp @@ -36,7 +36,7 @@ BindgenStringRef stringref(const char *newStr); BindgenStringRef stringref(const std::string &s); BindgenStringRef stringref(llvm::StringRef S); BindgenStringRefSet make_stringrefset(std::vector &string_vec); -QualType make_type_compatible(QualType QT); +BindgenQualType make_type_compatible(QualType QT); // Functions defined in libclang_compat.cpp const Decl *getDeclFromExpr(const Stmt *E); diff --git a/src/clang/libclang_compat.cpp b/src/clang/libclang_compat.cpp index 80d7096a4e..3bf907330d 100644 --- a/src/clang/libclang_compat.cpp +++ b/src/clang/libclang_compat.cpp @@ -197,8 +197,9 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { } // Adapted from GetTypeKind in CXType.cpp -CXTypeKind Type_kind(QualType T, ASTContext *Context) { - const Type *TP = T.getTypePtrOrNull(); +CXTypeKind Type_kind(BindgenQualType T, ASTContext *Context) { + auto QT = QualType::getFromOpaquePtr(T); + const Type *TP = QT.getTypePtrOrNull(); if (!TP) return CXType_Invalid; @@ -210,7 +211,7 @@ CXTypeKind Type_kind(QualType T, ASTContext *Context) { bool isObjc = Context->getLangOpts().ObjC1; #endif // CLANG_VERSION_MAJOR if (isObjc) { - QualType UT = T.getUnqualifiedType(); + QualType UT = QT.getUnqualifiedType(); if (Context->isObjCIdType(UT)) return CXType_ObjCId; if (Context->isObjCClassType(UT)) @@ -1545,8 +1546,9 @@ SourceLocation *Expr_getLocation(const Expr *E) { } // Adapted from clang_getTypeDeclaration in CXType.cpp -const Decl *Type_getDeclaration(QualType T) { - const Type *TP = T.getTypePtrOrNull(); +const Decl *Type_getDeclaration(BindgenQualType T) { + auto QT = QualType::getFromOpaquePtr(T); + const Type *TP = QT.getTypePtrOrNull(); if (!TP) return nullptr; @@ -1755,7 +1757,8 @@ BindgenStringRef getTokenSpelling(ASTUnit *CXXUnit, CXToken CXTok) { } // Adapted from clang_Type_getSizeOf in CXType.cpp -long long Type_getSizeOf(QualType QT, ASTContext *Context) { +long long Type_getSizeOf(BindgenQualType T, ASTContext *Context) { + auto QT = QualType::getFromOpaquePtr(T); if (QT.isNull()) return CXTypeLayoutError_Invalid; // [expr.sizeof] p2: if reference type, return size of referenced type @@ -1787,7 +1790,8 @@ long long Type_getSizeOf(QualType QT, ASTContext *Context) { } // Adapted from clang_Type_getAlignOf in CXType.cpp -long long Type_getAlignOf(QualType QT, ASTContext *Context) { +long long Type_getAlignOf(BindgenQualType T, ASTContext *Context) { + auto QT = QualType::getFromOpaquePtr(T); if (QT.isNull()) return CXTypeLayoutError_Invalid; // [expr.alignof] p1: return size_t value for complete object type, reference @@ -1811,29 +1815,30 @@ long long Type_getAlignOf(QualType QT, ASTContext *Context) { } // Adapted from clang_getPointeeType in CXType.cpp -QualType Type_getPointeeType(QualType T) { - const Type *TP = T.getTypePtrOrNull(); +BindgenQualType Type_getPointeeType(BindgenQualType T) { + auto QT = QualType::getFromOpaquePtr(T); + const Type *TP = QT.getTypePtrOrNull(); if (!TP) - return QualType(); + return nullptr; try_again: switch (TP->getTypeClass()) { case Type::Pointer: - T = cast(TP)->getPointeeType(); + QT = cast(TP)->getPointeeType(); break; case Type::BlockPointer: - T = cast(TP)->getPointeeType(); + QT = cast(TP)->getPointeeType(); break; case Type::LValueReference: case Type::RValueReference: - T = cast(TP)->getPointeeType(); + QT = cast(TP)->getPointeeType(); break; case Type::ObjCObjectPointer: - T = cast(TP)->getPointeeType(); + QT = cast(TP)->getPointeeType(); break; case Type::MemberPointer: - T = cast(TP)->getPointeeType(); + QT = cast(TP)->getPointeeType(); break; case Type::Auto: #if CLANG_VERSION_MAJOR > 4 @@ -1846,16 +1851,17 @@ QualType Type_getPointeeType(QualType T) { goto try_again; break; default: - T = QualType(); + QT = QualType(); break; } - return make_type_compatible(T); + return make_type_compatible(QT); } // Adapted from clang_getElementType in CXType.cpp -QualType Type_getElementType(QualType T) { +BindgenQualType Type_getElementType(BindgenQualType T) { + auto QT = QualType::getFromOpaquePtr(T); QualType ET = QualType(); - const Type *TP = T.getTypePtrOrNull(); + const Type *TP = QT.getTypePtrOrNull(); if (TP) { switch (TP->getTypeClass()) { @@ -1888,9 +1894,10 @@ QualType Type_getElementType(QualType T) { } // Adapted from clang_getNumElements in CXType.cpp -int Type_getNumElements(QualType T) { +int Type_getNumElements(BindgenQualType T) { + auto QT = QualType::getFromOpaquePtr(T); long long result = -1; - const Type *TP = T.getTypePtrOrNull(); + const Type *TP = QT.getTypePtrOrNull(); if (TP) { switch (TP->getTypeClass()) { @@ -1911,11 +1918,12 @@ int Type_getNumElements(QualType T) { } // Adapted from clang_getFunctionTypeCallingConv in CXType.cpp -CXCallingConv Type_getFunctionTypeCallingConv(QualType T) { - if (T.isNull()) +CXCallingConv Type_getFunctionTypeCallingConv(BindgenQualType T) { + auto QT = QualType::getFromOpaquePtr(T); + if (QT.isNull()) return CXCallingConv_Invalid; - if (const FunctionType *FD = T->getAs()) { + if (const FunctionType *FD = QT->getAs()) { #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X switch (FD->getCallConv()) { TCALLINGCONV(C);