Skip to content

Commit d5f2c3e

Browse files
committed
transpile: Compute and store override_tys ahead of time
1 parent 389e85c commit d5f2c3e

3 files changed

Lines changed: 429 additions & 2 deletions

File tree

c2rust-transpile/src/c_ast/c_expr.rs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::c_ast::c_decl::{CDeclId, CDeclKind, CFieldId};
2-
use crate::c_ast::c_stmt::CStmtId;
2+
use crate::c_ast::c_stmt::{CStmtId, CStmtKind};
33
use crate::c_ast::c_type::{CQualTypeId, CTypeId, CTypeKind};
44
use crate::c_ast::{Located, SomeId, TypedAstContext};
55
use c2rust_ast_exporter::clang_ast::LRValue;
@@ -698,6 +698,18 @@ impl TypedAstContext {
698698
}
699699
}
700700

701+
/// Same as the `Index` trait, but doesn't bypass `Paren`.
702+
pub fn index_expr_raw(&self, index: CExprId) -> &CExpr {
703+
static BADEXPR: CExpr = Located {
704+
loc: None,
705+
kind: CExprKind::BadExpr,
706+
};
707+
match self.c_exprs.get(&index) {
708+
None => &BADEXPR,
709+
Some(e) => e,
710+
}
711+
}
712+
701713
pub fn is_null_expr(&self, expr_id: CExprId) -> bool {
702714
use CExprKind::*;
703715
match self[expr_id].kind {
@@ -953,6 +965,53 @@ impl TypedAstContext {
953965
BadExpr => false,
954966
}
955967
}
968+
969+
/// Returns whether `expr` is within a conditional context, meaning that it is in a context
970+
/// where a Rust `bool` will be expected.
971+
pub fn expr_is_condition(&self, expr: CExprId) -> bool {
972+
let parent = match self.parent(expr) {
973+
Some(parent) => parent,
974+
None => return false,
975+
};
976+
977+
match parent {
978+
SomeId::Stmt(parent_stmt) => match self.c_stmts[&parent_stmt].kind {
979+
CStmtKind::If {
980+
scrutinee: condition,
981+
..
982+
}
983+
| CStmtKind::While { condition, .. }
984+
| CStmtKind::DoWhile { condition, .. }
985+
| CStmtKind::ForLoop {
986+
condition: Some(condition),
987+
..
988+
} => expr == condition,
989+
_ => false,
990+
},
991+
992+
SomeId::Expr(parent_expr) => match self.c_exprs[&parent_expr].kind {
993+
CExprKind::Paren(..) => self.expr_is_condition(parent_expr),
994+
CExprKind::Unary(_, CUnOp::Not, arg, _) => expr == arg,
995+
CExprKind::Binary(_, CBinOp::And | CBinOp::Or, lhs, rhs, _, _) => {
996+
expr == lhs || expr == rhs
997+
}
998+
CExprKind::Conditional(_, condition, _, _)
999+
| CExprKind::BinaryConditional(_, condition, _) => expr == condition,
1000+
CExprKind::ImplicitCast(_, arg, kind, _, _)
1001+
| CExprKind::ExplicitCast(_, arg, kind, _, _) => {
1002+
matches!(
1003+
kind,
1004+
CastKind::IntegralToBoolean
1005+
| CastKind::FloatingToBoolean
1006+
| CastKind::PointerToBoolean
1007+
) && expr == arg
1008+
}
1009+
_ => false,
1010+
},
1011+
1012+
_ => false,
1013+
}
1014+
}
9561015
}
9571016

9581017
impl Index<CExprId> for TypedAstContext {

c2rust-transpile/src/c_ast/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,18 @@ impl TypedAstContext {
243243
.and_then(|parent| T::try_from(parent).ok())
244244
}
245245

246+
/// If `child` is inside a function, returns its `CDeclId`.
247+
pub fn parent_function(&self, child: impl Into<SomeId>) -> Option<CDeclId> {
248+
match self.parent(child)? {
249+
SomeId::Stmt(stmt) => self.parent_function(stmt),
250+
SomeId::Expr(expr) => self.parent_function(expr),
251+
SomeId::Decl(decl) => {
252+
matches!(self[decl].kind, CDeclKind::Function { .. }).then_some(decl)
253+
}
254+
SomeId::Type(ty) => self.parent_function(ty),
255+
}
256+
}
257+
246258
pub fn display_loc(&self, loc: &Option<SrcSpan>) -> Option<DisplaySrcSpan> {
247259
loc.as_ref().map(|loc| DisplaySrcSpan {
248260
file: self.files[self.file_map[loc.fileid as usize]].path.clone(),

0 commit comments

Comments
 (0)