Skip to content

Commit

Permalink
Remove unnecessary clone of macro definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
jyn514 committed May 21, 2020
1 parent 73013e1 commit 9283496
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 43 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 8 additions & 7 deletions src/ir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::BindgenOptions;
use crate::{Entry, HashMap, HashSet};
use clang_sys;
use proc_macro2::{Ident, Span};
use rcc::InternedStr;
use std::borrow::Cow;
use std::cell::Cell;
use std::collections::HashMap as StdHashMap;
Expand Down Expand Up @@ -350,8 +351,8 @@ pub struct BindgenContext {
/// hard errors while parsing duplicated macros, as well to allow macro
/// expression parsing.
///
/// This needs to be an std::HashMap because the cexpr API requires it.
parsed_macros: StdHashMap<Vec<u8>, rcc::Literal>,
/// This needs to be an std::HashMap because the rcc API requires it.
parsed_macros: StdHashMap<rcc::InternedStr, rcc::Definition>,

/// The active replacements collected from replaces="xxx" annotations.
replacements: HashMap<Vec<String>, ItemId>,
Expand Down Expand Up @@ -2033,25 +2034,25 @@ If you encounter an error missing from this list, please file an issue or a PR!"
}

/// Have we parsed the macro named `macro_name` already?
pub fn parsed_macro(&self, macro_name: &[u8]) -> bool {
self.parsed_macros.contains_key(macro_name)
pub fn parsed_macro(&self, macro_name: InternedStr) -> bool {
self.parsed_macros.contains_key(&macro_name)
}

/// Get the currently parsed macros.
pub fn parsed_macros(
&self,
) -> &StdHashMap<Vec<u8>, rcc::Literal> {
) -> &StdHashMap<InternedStr, rcc::Definition> {
debug_assert!(!self.in_codegen_phase());
&self.parsed_macros
}

/// Mark the macro named `macro_name` as parsed.
pub fn note_parsed_macro(
&mut self,
id: Vec<u8>,
id: InternedStr,
value: rcc::Literal,
) {
self.parsed_macros.insert(id, value);
self.parsed_macros.insert(id, rcc::Definition::Object(vec![rcc::Token::Literal(value)]));
}

/// Are we in the codegen phase?
Expand Down
48 changes: 13 additions & 35 deletions src/ir/var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::parse::{
};
use std::io;
use std::collections::HashMap;
use rcc::{InternedStr, Literal};

/// The type for a constant variable.
#[derive(Debug)]
Expand Down Expand Up @@ -134,7 +135,6 @@ impl ClangSubItemParser for Var {
cursor: clang::Cursor,
ctx: &mut BindgenContext,
) -> Result<ParseResult<Self>, ParseError> {
use rcc::Literal;
use clang_sys::*;
match cursor.kind() {
CXCursor_MacroDefinition => {
Expand All @@ -156,29 +156,22 @@ impl ClangSubItemParser for Var {

assert!(!id.is_empty(), "Empty macro name?");

let previously_defined = ctx.parsed_macro(&id);
let previously_defined = ctx.parsed_macro(id);

// NB: It's important to "note" the macro even if the result is
// not an integer, otherwise we might lose other kind of
// derived macros.
ctx.note_parsed_macro(id.clone(), value.clone());
ctx.note_parsed_macro(id, value.clone());

if previously_defined {
let name = String::from_utf8(id).unwrap();
warn!("Duplicated macro definition: {}", name);
warn!("Duplicated macro definition: {}", id);
return Err(ParseError::Continue);
}

// NOTE: Unwrapping, here and above, is safe, because the
// identifier of a token comes straight from clang, and we
// enforce utf8 there, so we should have already panicked at
// this point.
let name = String::from_utf8(id).unwrap();

let parse_int = |value| {
let kind = ctx
.parse_callbacks()
.and_then(|c| c.int_macro(&name, value))
.and_then(|c| c.int_macro(rcc::get_str!(id), value))
.unwrap_or_else(|| {
default_macro_constant_type(value)
});
Expand All @@ -200,7 +193,7 @@ impl ClangSubItemParser for Var {
ctx,
);
if let Some(callbacks) = ctx.parse_callbacks() {
callbacks.str_macro(&name, &val);
callbacks.str_macro(rcc::get_str!(id), &val);
}
(TypeKind::Pointer(char_ty), VarType::String(val))
}
Expand All @@ -211,7 +204,7 @@ impl ClangSubItemParser for Var {
let ty = Item::builtin_type(type_kind, true, ctx);

Ok(ParseResult::New(
Var::new(name, None, ty, Some(val), true),
Var::new(id.resolve_and_clone(), None, ty, Some(val), true),
Some(cursor),
))
}
Expand Down Expand Up @@ -309,7 +302,7 @@ impl ClangSubItemParser for Var {
fn parse_macro(
ctx: &BindgenContext,
cursor: &clang::Cursor,
) -> Option<(Vec<u8>, rcc::Literal)> {
) -> Option<(InternedStr, Literal)> {
use rcc::Token;

// TODO: pass this in to rcc somehow
Expand All @@ -318,15 +311,15 @@ fn parse_macro(
// TODO: remove(0) is expensive
let ident = rcc_tokens.remove(0);
let ident_str = match ident.data {
Token::Id(id) => id.resolve_and_clone().into_bytes(),
Token::Id(id) => id,
_ => return None,
};
if ident_str.is_empty() {
return None;
}

// TODO: remove this clone (will need changes in rcc)
if let Some(literal) = rcc_expr(rcc_tokens.clone().into_iter(), &parsed_macros) {
if let Some(literal) = rcc_expr(rcc_tokens.clone().into_iter(), parsed_macros) {
return Some((ident_str, literal));
}

Expand All @@ -337,37 +330,22 @@ fn parse_macro(
// https://bugs.llvm.org//show_bug.cgi?id=9069
// https://reviews.llvm.org/D26446
rcc_tokens.pop()?;
if let Some(literal) = rcc_expr(rcc_tokens.into_iter(), &parsed_macros) {
if let Some(literal) = rcc_expr(rcc_tokens.into_iter(), parsed_macros) {
Some((ident_str, literal))
} else {
None
}
}

fn rcc_expr(rcc_tokens: impl Iterator<Item = rcc::Locatable<rcc::Token>>, definitions: &HashMap<Vec<u8>, rcc::Literal>) -> Option<rcc::Literal> {
fn rcc_expr(rcc_tokens: impl Iterator<Item = rcc::Locatable<rcc::Token>>, definitions: &HashMap<InternedStr, rcc::Definition>) -> Option<Literal> {
use rcc::PreProcessor;

//let mut replacer = MacroReplacer::with_definitions(std::iter::empty().peekable(), &definitions);
let mut rcc_tokens = rcc_tokens.peekable();
let location = rcc_tokens.peek()?.location;
let map = definitions.iter().map(|(k, v)| {
(String::from_utf8_lossy(k).to_string().into(), rcc::Definition::Object(vec![rcc::Token::Literal(v.clone())]))
}).collect();
PreProcessor::cpp_expr(&map, rcc_tokens, location).ok()?.const_fold().ok()?.into_literal().ok()
/*
let first = rcc_tokens.next()?;
let mut parser = Parser::new(first, rcc_tokens.map(Result::<_, CompileError>::Ok), false);
let expr = parser.expr().ok()?;
let mut analyzer = PureAnalyzer::new();
analyzer.expr(expr).const_fold().ok()?.into_literal().ok()
*/
PreProcessor::cpp_expr(definitions, rcc_tokens, location).ok()?.const_fold().ok()?.into_literal().ok()
}

fn parse_int_literal_tokens(cursor: &clang::Cursor) -> Option<i64> {
use rcc::Literal;

let rcc_tokens = cursor.rcc_tokens().into_iter();

// TODO(emilio): We can try to parse other kinds of literals.
Expand Down

0 comments on commit 9283496

Please sign in to comment.