Skip to content

Commit 89964e1

Browse files
committed
transpile: Add AST node parent information
1 parent c8d84fa commit 89964e1

7 files changed

Lines changed: 406 additions & 24 deletions

File tree

c2rust-transpile/src/c_ast/c_decl.rs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,77 @@ pub struct CDeclSrcRange {
148148
}
149149

150150
impl TypedAstContext {
151+
pub(super) fn add_decl_parents(&mut self, id: CDeclId, kind: &CDeclKind) {
152+
use CDeclKind::*;
153+
let parent = SomeId::Decl(id);
154+
155+
match *kind {
156+
Function {
157+
ref parameters,
158+
body,
159+
..
160+
} => {
161+
for &parameter in parameters {
162+
self.add_parent(parameter, parent);
163+
}
164+
165+
if let Some(body) = body {
166+
self.add_parent(body, parent);
167+
}
168+
}
169+
170+
Variable { initializer, .. } => {
171+
if let Some(initializer) = initializer {
172+
self.add_parent(initializer, parent);
173+
}
174+
}
175+
176+
Enum {
177+
ref variants,
178+
integral_type,
179+
..
180+
} => {
181+
if integral_type.is_some() {
182+
for &variant in variants {
183+
self.add_parent(variant, parent);
184+
}
185+
}
186+
}
187+
188+
EnumConstant { .. } => (),
189+
190+
Typedef { .. } => (),
191+
192+
Struct { ref fields, .. } => {
193+
if let Some(fields) = fields {
194+
for &field in fields {
195+
self.add_parent(field, parent);
196+
}
197+
}
198+
}
199+
200+
Union { ref fields, .. } => {
201+
if let Some(fields) = fields {
202+
for &field in fields {
203+
self.add_parent(field, parent);
204+
}
205+
}
206+
}
207+
208+
Field { .. } => (),
209+
210+
MacroObject { .. } => (),
211+
212+
MacroFunction { .. } => (),
213+
214+
NonCanonicalDecl { .. } => (),
215+
216+
StaticAssert { assert_expr, .. } => {
217+
self.add_parent(assert_expr, parent);
218+
}
219+
}
220+
}
221+
151222
/// Construct a map from top-level decls in the main file to their source ranges.
152223
pub fn top_decl_locs(&self) -> IndexMap<CDeclId, CDeclSrcRange> {
153224
let mut name_loc_map = IndexMap::new();
@@ -388,7 +459,9 @@ impl TypedAstContext {
388459
if let CDeclKind::EnumConstant { .. } = self.c_decls[&decl_id].kind {
389460
// Special case for enums. The enum constant is used, so the whole
390461
// enum is also used.
391-
let parent_id = self.parents[&decl_id];
462+
let parent_id = self
463+
.parent_with_type(decl_id)
464+
.expect("Enum constant does not have a parent Enum");
392465
if wanted.insert(parent_id) {
393466
to_walk.push(parent_id);
394467
}

c2rust-transpile/src/c_ast/c_expr.rs

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,164 @@ pub enum Designator {
541541
}
542542

543543
impl TypedAstContext {
544+
pub(super) fn add_expr_parents(&mut self, id: CExprId, kind: &CExprKind) {
545+
use CExprKind::*;
546+
let parent = SomeId::Expr(id);
547+
548+
match *kind {
549+
Literal(..) => (),
550+
551+
Unary(_, _, expr, _) => {
552+
self.add_parent(expr, parent);
553+
}
554+
555+
UnaryType(_, _, expr, _) => {
556+
if let Some(expr) = expr {
557+
self.add_parent(expr, parent);
558+
}
559+
}
560+
561+
OffsetOf(_, ref kind) => match *kind {
562+
OffsetOfKind::Constant(..) => (),
563+
OffsetOfKind::Variable(_, _, expr) => {
564+
self.add_parent(expr, parent);
565+
}
566+
},
567+
568+
Binary(_, _, lhs, rhs, _, _) => {
569+
self.add_parent(lhs, parent);
570+
self.add_parent(rhs, parent);
571+
}
572+
573+
ImplicitCast(_, expr, _, _, _) => {
574+
self.add_parent(expr, parent);
575+
}
576+
577+
ExplicitCast(_, expr, _, _, _) => {
578+
self.add_parent(expr, parent);
579+
}
580+
581+
ConstantExpr(_, expr, _) => {
582+
self.add_parent(expr, parent);
583+
}
584+
585+
DeclRef(..) => (),
586+
587+
Call(_, func, ref args) => {
588+
self.add_parent(func, parent);
589+
590+
for &arg in args {
591+
self.add_parent(arg, parent);
592+
}
593+
}
594+
595+
Member(_, expr, _, _, _) => {
596+
self.add_parent(expr, parent);
597+
}
598+
599+
ArraySubscript(_, lhs, rhs, _) => {
600+
self.add_parent(lhs, parent);
601+
self.add_parent(rhs, parent);
602+
}
603+
604+
Conditional(_, cond, lhs, rhs) => {
605+
self.add_parent(cond, parent);
606+
self.add_parent(lhs, parent);
607+
self.add_parent(rhs, parent);
608+
}
609+
610+
BinaryConditional(_, cond, rhs) => {
611+
self.add_parent(cond, parent);
612+
self.add_parent(rhs, parent);
613+
}
614+
615+
InitList(_, ref exprs, _, syntactic_form) => {
616+
for &expr in exprs {
617+
self.add_parent(expr, parent);
618+
}
619+
620+
if let Some(syntactic_form) = syntactic_form {
621+
self.add_parent(syntactic_form, parent);
622+
}
623+
}
624+
625+
ImplicitValueInit(..) => (),
626+
627+
Paren(_, expr) => {
628+
self.add_parent(expr, parent);
629+
}
630+
631+
CompoundLiteral(_, expr) => {
632+
self.add_parent(expr, parent);
633+
}
634+
635+
Predefined(_, expr) => {
636+
self.add_parent(expr, parent);
637+
}
638+
639+
Statements(_, stmt) => {
640+
self.add_parent(stmt, parent);
641+
}
642+
643+
VAArg(_, expr) => {
644+
self.add_parent(expr, parent);
645+
}
646+
647+
ShuffleVector(_, ref exprs) => {
648+
for &expr in exprs {
649+
self.add_parent(expr, parent);
650+
}
651+
}
652+
653+
ConvertVector(_, ref exprs) => {
654+
for &expr in exprs {
655+
self.add_parent(expr, parent);
656+
}
657+
}
658+
659+
DesignatedInitExpr(_, _, expr) => {
660+
self.add_parent(expr, parent);
661+
}
662+
663+
Choose(_, cond, lhs, rhs, _) => {
664+
self.add_parent(cond, parent);
665+
self.add_parent(lhs, parent);
666+
self.add_parent(rhs, parent);
667+
}
668+
669+
Atomic {
670+
ptr,
671+
order,
672+
val1,
673+
order_fail,
674+
val2,
675+
weak,
676+
..
677+
} => {
678+
self.add_parent(ptr, parent);
679+
self.add_parent(order, parent);
680+
681+
if let Some(val1) = val1 {
682+
self.add_parent(val1, parent);
683+
}
684+
685+
if let Some(order_fail) = order_fail {
686+
self.add_parent(order_fail, parent);
687+
}
688+
689+
if let Some(val2) = val2 {
690+
self.add_parent(val2, parent);
691+
}
692+
693+
if let Some(weak) = weak {
694+
self.add_parent(weak, parent);
695+
}
696+
}
697+
698+
BadExpr => (),
699+
}
700+
}
701+
544702
pub fn is_null_expr(&self, expr_id: CExprId) -> bool {
545703
use CExprKind::*;
546704
match self[expr_id].kind {

c2rust-transpile/src/c_ast/c_stmt.rs

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::c_ast::c_decl::CDeclId;
22
use crate::c_ast::c_expr::{CExprId, ConstIntExpr};
3-
use crate::c_ast::{Attribute, Located, TypedAstContext};
3+
use crate::c_ast::{Attribute, Located, SomeId, TypedAstContext};
44
use std::fmt::Debug;
55
use std::ops::Index;
66

@@ -92,6 +92,111 @@ pub struct AsmOperand {
9292
}
9393

9494
impl TypedAstContext {
95+
pub(super) fn add_stmt_parents(&mut self, id: CStmtId, kind: &CStmtKind) {
96+
use CStmtKind::*;
97+
let parent = SomeId::Stmt(id);
98+
99+
match *kind {
100+
Label(stmt) => {
101+
self.add_parent(stmt, parent);
102+
}
103+
104+
Case(expr, stmt, _) => {
105+
self.add_parent(expr, parent);
106+
self.add_parent(stmt, parent);
107+
}
108+
109+
Default(stmt) => {
110+
self.add_parent(stmt, parent);
111+
}
112+
113+
Compound(ref stmts) => {
114+
for &stmt in stmts {
115+
self.add_parent(stmt, parent);
116+
}
117+
}
118+
119+
Expr(expr) => {
120+
self.add_parent(expr, parent);
121+
}
122+
123+
Empty => (),
124+
125+
If {
126+
scrutinee,
127+
true_variant,
128+
false_variant,
129+
} => {
130+
self.add_parent(scrutinee, parent);
131+
self.add_parent(true_variant, parent);
132+
133+
if let Some(false_variant) = false_variant {
134+
self.add_parent(false_variant, parent);
135+
}
136+
}
137+
Switch { scrutinee, body } => {
138+
self.add_parent(scrutinee, parent);
139+
self.add_parent(body, parent);
140+
}
141+
142+
While { condition, body } => {
143+
self.add_parent(condition, parent);
144+
self.add_parent(body, parent);
145+
}
146+
147+
DoWhile { body, condition } => {
148+
self.add_parent(body, parent);
149+
self.add_parent(condition, parent);
150+
}
151+
152+
ForLoop {
153+
init,
154+
condition,
155+
increment,
156+
body,
157+
} => {
158+
if let Some(init) = init {
159+
self.add_parent(init, parent);
160+
}
161+
162+
if let Some(condition) = condition {
163+
self.add_parent(condition, parent);
164+
}
165+
166+
if let Some(increment) = increment {
167+
self.add_parent(increment, parent);
168+
}
169+
170+
self.add_parent(body, parent);
171+
}
172+
173+
Goto(..) => (),
174+
Break => (),
175+
Continue => (),
176+
177+
Return(expr) => {
178+
if let Some(expr) = expr {
179+
self.add_parent(expr, parent);
180+
}
181+
}
182+
183+
Decls(ref decls) => {
184+
for &decl in decls {
185+
self.add_parent(decl, parent);
186+
}
187+
}
188+
189+
Asm { .. } => (),
190+
191+
Attributed {
192+
attributes: _,
193+
substatement,
194+
} => {
195+
self.add_parent(substatement, parent);
196+
}
197+
}
198+
}
199+
95200
pub fn is_const_stmt(&self, stmt: CStmtId) -> bool {
96201
let is_const = |stmt| self.is_const_stmt(stmt);
97202
let is_const_expr = |expr| self.is_const_expr(expr);

0 commit comments

Comments
 (0)