Skip to content

Commit 505b826

Browse files
committed
transpile: Add AST node parent information
1 parent f4268be commit 505b826

7 files changed

Lines changed: 408 additions & 26 deletions

File tree

c2rust-transpile/src/c_ast/c_decl.rs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::c_ast::c_expr::{CExprId, ConstIntExpr};
22
use crate::c_ast::c_stmt::CStmtId;
33
use crate::c_ast::c_type::{CFuncTypeId, CQualTypeId, CTypeKind};
4-
use crate::c_ast::{Attribute, Located, SrcLoc, TypedAstContext};
4+
use crate::c_ast::{Attribute, Located, SomeId, SrcLoc, TypedAstContext};
55
use indexmap::{IndexMap, IndexSet};
66
use std::fmt::Debug;
77
use std::ops::Index;
@@ -145,6 +145,77 @@ pub struct CDeclSrcRange {
145145
}
146146

147147
impl TypedAstContext {
148+
pub(super) fn add_decl_parents(&mut self, id: CDeclId, kind: &CDeclKind) {
149+
use CDeclKind::*;
150+
let parent = SomeId::Decl(id);
151+
152+
match *kind {
153+
Function {
154+
ref parameters,
155+
body,
156+
..
157+
} => {
158+
for &parameter in parameters {
159+
self.add_parent(parameter, parent);
160+
}
161+
162+
if let Some(body) = body {
163+
self.add_parent(body, parent);
164+
}
165+
}
166+
167+
Variable { initializer, .. } => {
168+
if let Some(initializer) = initializer {
169+
self.add_parent(initializer, parent);
170+
}
171+
}
172+
173+
Enum {
174+
ref variants,
175+
integral_type,
176+
..
177+
} => {
178+
if integral_type.is_some() {
179+
for &variant in variants {
180+
self.add_parent(variant, parent);
181+
}
182+
}
183+
}
184+
185+
EnumConstant { .. } => {}
186+
187+
Typedef { .. } => {}
188+
189+
Struct { ref fields, .. } => {
190+
if let Some(fields) = fields {
191+
for &field in fields {
192+
self.add_parent(field, parent);
193+
}
194+
}
195+
}
196+
197+
Union { ref fields, .. } => {
198+
if let Some(fields) = fields {
199+
for &field in fields {
200+
self.add_parent(field, parent);
201+
}
202+
}
203+
}
204+
205+
Field { .. } => {}
206+
207+
MacroObject { .. } => {}
208+
209+
MacroFunction { .. } => {}
210+
211+
NonCanonicalDecl { .. } => {}
212+
213+
StaticAssert { assert_expr, .. } => {
214+
self.add_parent(assert_expr, parent);
215+
}
216+
}
217+
}
218+
148219
/// Construct a map from top-level decls in the main file to their source ranges.
149220
pub fn top_decl_locs(&self) -> IndexMap<CDeclId, CDeclSrcRange> {
150221
let mut name_loc_map = IndexMap::new();

c2rust-transpile/src/c_ast/c_expr.rs

Lines changed: 159 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::c_ast::c_decl::{CDeclId, CDeclKind, CFieldId};
22
use crate::c_ast::c_stmt::CStmtId;
33
use crate::c_ast::c_type::{CQualTypeId, CTypeId, CTypeKind};
4-
use crate::c_ast::{Located, TypedAstContext};
4+
use crate::c_ast::{Located, SomeId, TypedAstContext};
55
use c2rust_ast_exporter::clang_ast::LRValue;
66
use std::fmt::{self, Debug, Display};
77
use std::ops::Index;
@@ -540,6 +540,164 @@ pub enum Designator {
540540
}
541541

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