-
Notifications
You must be signed in to change notification settings - Fork 742
Constant variable improvements. #260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
239d62b
f9422a4
d516168
91faa76
824f99a
b348e73
9380ed5
2468fb2
19d36d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -264,7 +264,7 @@ impl Cursor { | |
|
||
/// Given that this cursor's referent is reference type, get the cursor | ||
/// pointing to the referenced type. | ||
pub fn referenced(&self) -> Option<Cursor> { | ||
pub fn referenced(&self) -> Option<Cursor> { | ||
unsafe { | ||
let ret = Cursor { | ||
x: clang_getCursorReferenced(self.x), | ||
|
@@ -475,6 +475,11 @@ impl Cursor { | |
pub fn is_virtual_base(&self) -> bool { | ||
unsafe { clang_isVirtualBase(self.x) != 0 } | ||
} | ||
|
||
/// Try to evaluate this cursor. | ||
pub fn evaluate(&self) -> EvalResult { | ||
EvalResult::new(*self) | ||
} | ||
} | ||
|
||
extern "C" fn visit_children<Visitor>(cur: CXCursor, | ||
|
@@ -933,7 +938,9 @@ impl Into<String> for CXString { | |
} | ||
unsafe { | ||
let c_str = CStr::from_ptr(clang_getCString(self) as *const _); | ||
c_str.to_string_lossy().into_owned() | ||
let ret = c_str.to_string_lossy().into_owned(); | ||
clang_disposeString(self); | ||
ret | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... lol ... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not a big deal because they're refcounted, but still... |
||
} | ||
} | ||
} | ||
|
@@ -1259,3 +1266,70 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> Enum_CXVisitorResult { | |
pub fn extract_clang_version() -> String { | ||
unsafe { clang_getClangVersion().into() } | ||
} | ||
|
||
/// A wrapper for the result of evaluating an expression. | ||
#[derive(Debug)] | ||
pub struct EvalResult { | ||
x: CXEvalResult, | ||
} | ||
|
||
#[cfg(feature = "llvm_stable")] | ||
impl EvalResult { | ||
/// Create a dummy EvalResult. | ||
pub fn new(_: Cursor) -> Self { | ||
EvalResult { | ||
x: ::std::ptr::null_mut(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
} | ||
|
||
/// Not useful in llvm 3.8. | ||
pub fn as_double(&self) -> Option<f64> { | ||
None | ||
} | ||
|
||
/// Not useful in llvm 3.8. | ||
pub fn as_int(&self) -> Option<i32> { | ||
None | ||
} | ||
} | ||
|
||
#[cfg(not(feature = "llvm_stable"))] | ||
impl EvalResult { | ||
/// Evaluate `cursor` and return the result. | ||
pub fn new(cursor: Cursor) -> Self { | ||
EvalResult { | ||
x: unsafe { clang_Cursor_Evaluate(cursor.x) }, | ||
} | ||
} | ||
|
||
fn kind(&self) -> Enum_CXEvalResultKind { | ||
unsafe { clang_EvalResult_getKind(self.x) } | ||
} | ||
|
||
/// Try to get back the result as a double. | ||
pub fn as_double(&self) -> Option<f64> { | ||
match self.kind() { | ||
CXEval_Float => { | ||
Some(unsafe { clang_EvalResult_getAsDouble(self.x) } as f64) | ||
} | ||
_ => None, | ||
} | ||
} | ||
|
||
/// Try to get back the result as an integer. | ||
pub fn as_int(&self) -> Option<i32> { | ||
match self.kind() { | ||
CXEval_Int => { | ||
Some(unsafe { clang_EvalResult_getAsInt(self.x) } as i32) | ||
} | ||
_ => None, | ||
} | ||
} | ||
} | ||
|
||
#[cfg(not(feature = "llvm_stable"))] | ||
impl Drop for EvalResult { | ||
fn drop(&mut self) { | ||
unsafe { clang_EvalResult_dispose(self.x) }; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -304,6 +304,7 @@ impl CodeGenerator for Var { | |
ctx: &BindgenContext, | ||
result: &mut CodegenResult, | ||
item: &Item) { | ||
use ir::var::VarType; | ||
debug!("<Var as CodeGenerator>::codegen: item = {:?}", item); | ||
|
||
let canonical_name = item.canonical_name(ctx); | ||
|
@@ -320,10 +321,44 @@ impl CodeGenerator for Var { | |
.item() | ||
.pub_() | ||
.const_(canonical_name) | ||
.expr() | ||
.build(helpers::ast_ty::int_expr(val)) | ||
.build(ty); | ||
result.push(const_item) | ||
.expr(); | ||
let item = match *val { | ||
VarType::Int(val) => { | ||
const_item.build(helpers::ast_ty::int_expr(val)) | ||
.build(ty) | ||
} | ||
VarType::String(ref bytes) => { | ||
// Account the trailing zero. | ||
// | ||
// TODO: Here we ignore the type we just made up, probably | ||
// we should refactor how the variable type and ty id work. | ||
let len = bytes.len() + 1; | ||
let ty = quote_ty!(ctx.ext_cx(), [u8; $len]); | ||
|
||
match String::from_utf8(bytes.clone()) { | ||
Ok(string) => { | ||
const_item.build(helpers::ast_ty::cstr_expr(string)) | ||
.build(quote_ty!(ctx.ext_cx(), &'static $ty)) | ||
} | ||
Err(..) => { | ||
const_item | ||
.build(helpers::ast_ty::byte_array_expr(bytes)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we should always make C strings a byte array... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's just because the bytestring reads better, but should be effectively equivalent. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
actually bindgen generates i8 byte arrays for literal strings in processor definitions. u8 arrays would IMHO be a more useful resp. *const c_char compatible representation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you file an issue with a test-case? Thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you file an issue with a test-case? Thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i wrote an issue ticket in the meanwhile: #1401 but i think it's more an issue, which rather needs contemplation than any example, where it leads to unpleasant results. |
||
.build(ty) | ||
} | ||
} | ||
} | ||
VarType::Float(f) => { | ||
const_item.build(helpers::ast_ty::float_expr(f)) | ||
.build(ty) | ||
} | ||
VarType::Char(c) => { | ||
const_item | ||
.build(aster::AstBuilder::new().expr().lit().byte(c)) | ||
.build(ty) | ||
} | ||
}; | ||
|
||
result.push(item); | ||
} else { | ||
let mut attrs = vec![]; | ||
if let Some(mangled) = self.mangled_name() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -123,6 +123,14 @@ impl Type { | |
Self::new(Some(name), None, kind, false) | ||
} | ||
|
||
/// Is this an floating point type? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "an" -> "a" |
||
pub fn is_float(&self) -> bool { | ||
match self.kind { | ||
TypeKind::Float(..) => true, | ||
_ => false, | ||
} | ||
} | ||
|
||
/// Is this an integer type? | ||
pub fn is_integer(&self) -> bool { | ||
match self.kind { | ||
|
@@ -667,7 +675,7 @@ impl Type { | |
TypeKind::TemplateAlias(inner.unwrap(), args) | ||
} | ||
CXCursor_TemplateRef => { | ||
let referenced = location.referenced().expect("expected value, got none"); | ||
let referenced = location.referenced().unwrap(); | ||
let referenced_ty = referenced.cur_type(); | ||
let referenced_declaration = | ||
Some(referenced_ty.declaration()); | ||
|
@@ -679,7 +687,7 @@ impl Type { | |
ctx); | ||
} | ||
CXCursor_TypeRef => { | ||
let referenced = location.referenced().expect("expected value, got none"); | ||
let referenced = location.referenced().unwrap(); | ||
let referenced_ty = referenced.cur_type(); | ||
let referenced_declaration = | ||
Some(referenced_ty.declaration()); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you rustfmt this? I'd think it would put each parameter on its own line if they are too long to fit on one line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't because
cargo fmt
doesn't detect the build.rs file apparently. Probably worth making it recognise it as a followup.