Skip to content

Commit be5a0e0

Browse files
committed
ast-exporter: In VisitExpr, handle when Begin and End start off in different macros
1 parent 9864d0c commit be5a0e0

3 files changed

Lines changed: 167 additions & 226 deletions

File tree

c2rust-ast-exporter/src/AstExporter.cpp

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,9 +1411,7 @@ class TranslateASTVisitor final
14111411
auto Begin = ExprRange.getBegin();
14121412
auto End = ExprRange.getEnd();
14131413

1414-
// Check that we are only expanding a single macro call.
1415-
if (!Begin.isMacroID() || !End.isMacroID() ||
1416-
Mgr.getImmediateMacroCallerLoc(Begin) != Mgr.getImmediateMacroCallerLoc(End)) {
1414+
if (!Begin.isMacroID() || !End.isMacroID()) {
14171415
return true;
14181416
}
14191417

@@ -1427,10 +1425,35 @@ class TranslateASTVisitor final
14271425
Begin = ExpansionRange.getBegin();
14281426
} while (Begin.isMacroID());
14291427

1428+
// Find the point at which Begin and End converge on the same expansion range.
1429+
// This is where the expression E first corresponds to a single macro call.
1430+
// Any subsequent expansions will be single macro calls as well.
1431+
auto ConvergencePoint = ExpansionStack.end();
1432+
1433+
do {
1434+
auto ExpansionRange = Mgr.getImmediateExpansionRange(End);
1435+
ConvergencePoint = std::find_if(
1436+
ExpansionStack.begin(),
1437+
ExpansionStack.end(),
1438+
[ExpansionRange](auto &R) {
1439+
return R.getAsRange() == ExpansionRange.getAsRange() &&
1440+
R.isTokenRange() == ExpansionRange.isTokenRange();
1441+
}
1442+
);
1443+
End = ExpansionRange.getEnd();
1444+
} while (End.isMacroID() && ConvergencePoint == ExpansionStack.end());
1445+
1446+
// Remove all elements before the convergence point.
1447+
ExpansionStack.erase(ExpansionStack.begin(), ConvergencePoint);
1448+
1449+
// The expression has no single call point.
1450+
if (ExpansionStack.empty()) {
1451+
return true;
1452+
}
1453+
14301454
curMacroExpansionSource =
14311455
Lexer::getSourceText(ExpansionStack[0], Mgr, Context->getLangOpts());
14321456

1433-
auto Range = ExprRange;
14341457
for (auto ExpansionRange : ExpansionStack) {
14351458
StringRef name;
14361459
MacroInfo *mac = getMacroInfo(ExpansionRange.getBegin(), name);
@@ -1439,21 +1462,9 @@ class TranslateASTVisitor final
14391462
return true;
14401463
}
14411464

1442-
auto ReplacementBegin = mac->getReplacementToken(0).getLocation();
1443-
auto ReplacementEnd = mac->getDefinitionEndLoc();
1444-
// Verify that this expansion covers the entire macro replacement
1445-
// definition, i.e. E is not a subexpression of the macro
1446-
// replacement.
1447-
if (Mgr.getSpellingLoc(Range.getBegin()) != ReplacementBegin ||
1448-
Mgr.getSpellingLoc(Range.getEnd()) != ReplacementEnd) {
1449-
return true;
1450-
}
1451-
14521465
if (VisitMacro(name, ExpansionRange.getBegin(), mac, E)) {
14531466
curMacroExpansionStack.push_back(mac);
14541467
}
1455-
1456-
Range = ExpansionRange.getAsRange();
14571468
}
14581469

14591470
return true;

c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap

Lines changed: 70 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ pub const NESTED_FLOAT: ::core::ffi::c_double = LITERAL_FLOAT;
5252
pub const NESTED_CHAR: ::core::ffi::c_int = LITERAL_CHAR;
5353
pub const NESTED_STR: [::core::ffi::c_char; 6] = LITERAL_STR;
5454
pub const NESTED_STRUCT: S = LITERAL_STRUCT;
55+
pub const NEGATIVE_INT: ::core::ffi::c_int = -LITERAL_INT;
56+
pub const INT_ARITHMETIC: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int;
57+
pub const MIXED_ARITHMETIC: ::core::ffi::c_double = LITERAL_INT as ::core::ffi::c_double
58+
+ NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double
59+
- true_0 as ::core::ffi::c_double;
5560
pub const PARENS: ::core::ffi::c_int = NESTED_INT * (LITERAL_CHAR + true_0);
5661
pub const PTR_ARITHMETIC: *const ::core::ffi::c_char = unsafe {
5762
LITERAL_STR
@@ -60,7 +65,24 @@ pub const PTR_ARITHMETIC: *const ::core::ffi::c_char = unsafe {
6065
.offset(-(3 as ::core::ffi::c_int as isize))
6166
};
6267
pub const WIDENING_CAST: ::core::ffi::c_ulonglong = LITERAL_INT as ::core::ffi::c_ulonglong;
68+
pub const NARROWING_CAST: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char;
6369
pub const CONVERSION_CAST: ::core::ffi::c_double = LITERAL_INT as ::core::ffi::c_double;
70+
pub const INDEXING: ::core::ffi::c_char = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize];
71+
pub const STR_CONCATENATION: [::core::ffi::c_char; 18] = unsafe {
72+
::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0")
73+
};
74+
pub const REF_MACRO: *const ::core::ffi::c_char = unsafe {
75+
NESTED_STR
76+
.as_ptr()
77+
.offset(LITERAL_FLOAT as ::core::ffi::c_int as isize) as *const ::core::ffi::c_char
78+
};
79+
pub const REF_LITERAL: *mut S = &LITERAL_STRUCT as *const S as *mut S;
80+
pub const TERNARY: ::core::ffi::c_int = if LITERAL_BOOL != 0 {
81+
1 as ::core::ffi::c_int
82+
} else {
83+
2 as ::core::ffi::c_int
84+
};
85+
pub const MEMBER: ::core::ffi::c_int = LITERAL_STRUCT.i;
6486
#[no_mangle]
6587
pub unsafe extern "C" fn local_muts() {
6688
let mut literal_int: ::core::ffi::c_int = LITERAL_INT;
@@ -87,45 +109,28 @@ pub unsafe extern "C" fn local_muts() {
87109
3 as ::core::ffi::c_int,
88110
];
89111
let mut nested_struct: S = NESTED_STRUCT;
90-
let mut negative_int: ::core::ffi::c_int = -LITERAL_INT;
91-
let mut int_arithmetic: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int;
92-
let mut mixed_arithmetic: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double
93-
+ NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double
94-
- true_0 as ::core::ffi::c_double)
95-
as ::core::ffi::c_float;
112+
let mut negative_int: ::core::ffi::c_int = NEGATIVE_INT;
113+
let mut int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC;
114+
let mut mixed_arithmetic: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float;
96115
let mut parens: ::core::ffi::c_int = PARENS;
97116
let mut ptr_arithmetic: *const ::core::ffi::c_char = PTR_ARITHMETIC;
98117
let mut widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST;
99-
let mut narrowing_cast: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char;
118+
let mut narrowing_cast: ::core::ffi::c_char = NARROWING_CAST;
100119
let mut conversion_cast: ::core::ffi::c_double = CONVERSION_CAST;
101-
let mut indexing: ::core::ffi::c_char =
102-
NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize];
103-
let mut str_concatenation_ptr: *const ::core::ffi::c_char =
104-
b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char;
105-
let mut str_concatenation: [::core::ffi::c_char; 18] =
106-
::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0");
120+
let mut indexing: ::core::ffi::c_char = INDEXING;
121+
let mut str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr();
122+
let mut str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION;
107123
let mut builtin: ::core::ffi::c_int =
108124
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
109-
let mut ref_indexing: *const ::core::ffi::c_char = NESTED_STR
110-
.as_ptr()
111-
.offset(LITERAL_FLOAT as ::core::ffi::c_int as isize)
112-
as *const ::core::ffi::c_char;
113-
let mut ref_struct: *const S = &mut LITERAL_STRUCT as *mut S;
114-
let mut ternary: ::core::ffi::c_int = if LITERAL_BOOL != 0 {
115-
1 as ::core::ffi::c_int
116-
} else {
117-
2 as ::core::ffi::c_int
118-
};
119-
let mut member: ::core::ffi::c_int = LITERAL_STRUCT.i;
125+
let mut ref_indexing: *const ::core::ffi::c_char = REF_MACRO;
126+
let mut ref_struct: *const S = REF_LITERAL;
127+
let mut ternary: ::core::ffi::c_int = TERNARY;
128+
let mut member: ::core::ffi::c_int = MEMBER;
120129
let mut stmt_expr: ::core::ffi::c_float = ({
121130
let mut builtin_0: ::core::ffi::c_int =
122131
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
123-
let mut indexing_0: ::core::ffi::c_char =
124-
NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize];
125-
let mut mixed: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double
126-
+ NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double
127-
- true_0 as ::core::ffi::c_double)
128-
as ::core::ffi::c_float;
132+
let mut indexing_0: ::core::ffi::c_char = INDEXING;
133+
let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float;
129134
let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int;
130135
while i < builtin_0 {
131136
mixed += indexing_0 as ::core::ffi::c_float;
@@ -160,43 +165,27 @@ pub unsafe extern "C" fn local_consts() {
160165
3 as ::core::ffi::c_int,
161166
];
162167
let nested_struct: S = NESTED_STRUCT;
163-
let negative_int: ::core::ffi::c_int = -LITERAL_INT;
164-
let int_arithmetic: ::core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int;
165-
let mixed_arithmetic: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double
166-
+ NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double
167-
- true_0 as ::core::ffi::c_double)
168-
as ::core::ffi::c_float;
168+
let negative_int: ::core::ffi::c_int = NEGATIVE_INT;
169+
let int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC;
170+
let mixed_arithmetic: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float;
169171
let parens: ::core::ffi::c_int = PARENS;
170172
let ptr_arithmetic: *const ::core::ffi::c_char = PTR_ARITHMETIC;
171173
let widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST;
172-
let narrowing_cast: ::core::ffi::c_char = LITERAL_INT as ::core::ffi::c_char;
174+
let narrowing_cast: ::core::ffi::c_char = NARROWING_CAST;
173175
let conversion_cast: ::core::ffi::c_double = CONVERSION_CAST;
174-
let indexing: ::core::ffi::c_char = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize];
175-
let str_concatenation_ptr: *const ::core::ffi::c_char =
176-
b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char;
177-
let str_concatenation: [::core::ffi::c_char; 18] =
178-
::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0");
176+
let indexing: ::core::ffi::c_char = INDEXING;
177+
let str_concatenation_ptr: *const ::core::ffi::c_char = STR_CONCATENATION.as_ptr();
178+
let str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION;
179179
let builtin: ::core::ffi::c_int = (LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
180-
let ref_indexing: *const ::core::ffi::c_char = NESTED_STR
181-
.as_ptr()
182-
.offset(LITERAL_FLOAT as ::core::ffi::c_int as isize)
183-
as *const ::core::ffi::c_char;
184-
let ref_struct: *const S = &mut LITERAL_STRUCT as *mut S;
185-
let ternary: ::core::ffi::c_int = if LITERAL_BOOL != 0 {
186-
1 as ::core::ffi::c_int
187-
} else {
188-
2 as ::core::ffi::c_int
189-
};
190-
let member: ::core::ffi::c_int = LITERAL_STRUCT.i;
180+
let ref_indexing: *const ::core::ffi::c_char = REF_MACRO;
181+
let ref_struct: *const S = REF_LITERAL;
182+
let ternary: ::core::ffi::c_int = TERNARY;
183+
let member: ::core::ffi::c_int = MEMBER;
191184
let stmt_expr: ::core::ffi::c_float = ({
192185
let mut builtin_0: ::core::ffi::c_int =
193186
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
194-
let mut indexing_0: ::core::ffi::c_char =
195-
NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize];
196-
let mut mixed: ::core::ffi::c_float = (LITERAL_INT as ::core::ffi::c_double
197-
+ NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double
198-
- true_0 as ::core::ffi::c_double)
199-
as ::core::ffi::c_float;
187+
let mut indexing_0: ::core::ffi::c_char = INDEXING;
188+
let mut mixed: ::core::ffi::c_float = MIXED_ARITHMETIC as ::core::ffi::c_float;
200189
let mut i: ::core::ffi::c_int = 0 as ::core::ffi::c_int;
201190
while i < builtin_0 {
202191
mixed += indexing_0 as ::core::ffi::c_float;
@@ -233,30 +222,25 @@ static mut global_static_const_nested_array: [::core::ffi::c_int; 3] = [
233222
3 as ::core::ffi::c_int,
234223
];
235224
static mut global_static_const_nested_struct: S = NESTED_STRUCT;
236-
static mut global_static_const_negative_int: ::core::ffi::c_int = -LITERAL_INT;
237-
static mut global_static_const_int_arithmetic: ::core::ffi::c_int =
238-
NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int;
225+
static mut global_static_const_negative_int: ::core::ffi::c_int = NEGATIVE_INT;
226+
static mut global_static_const_int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC;
239227
static mut global_static_const_mixed_arithmetic: ::core::ffi::c_float =
240-
(LITERAL_INT as ::core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double
241-
- true_0 as ::core::ffi::c_double) as ::core::ffi::c_float;
228+
MIXED_ARITHMETIC as ::core::ffi::c_float;
242229
static mut global_static_const_parens: ::core::ffi::c_int = PARENS;
243230
static mut global_static_const_ptr_arithmetic: *const ::core::ffi::c_char =
244231
::core::ptr::null::<::core::ffi::c_char>();
245232
static mut global_static_const_widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST;
246-
static mut global_static_const_narrowing_cast: ::core::ffi::c_char =
247-
LITERAL_INT as ::core::ffi::c_char;
233+
static mut global_static_const_narrowing_cast: ::core::ffi::c_char = NARROWING_CAST;
248234
static mut global_static_const_conversion_cast: ::core::ffi::c_double = CONVERSION_CAST;
249235
static mut global_static_const_indexing: ::core::ffi::c_char = 0;
250236
static mut global_static_const_str_concatenation_ptr: *const ::core::ffi::c_char =
251-
b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char;
252-
static mut global_static_const_str_concatenation: [::core::ffi::c_char; 18] = unsafe {
253-
::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0")
254-
};
237+
STR_CONCATENATION.as_ptr();
238+
static mut global_static_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION;
255239
static mut global_static_const_builtin: ::core::ffi::c_int =
256240
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
257241
static mut global_static_const_ref_indexing: *const ::core::ffi::c_char =
258242
::core::ptr::null::<::core::ffi::c_char>();
259-
static mut global_static_const_ref_struct: *const S = &LITERAL_STRUCT as *const S as *mut S;
243+
static mut global_static_const_ref_struct: *const S = REF_LITERAL;
260244
static mut global_static_const_ternary: ::core::ffi::c_int = 0;
261245
static mut global_static_const_member: ::core::ffi::c_int = 0;
262246
#[no_mangle]
@@ -304,14 +288,12 @@ pub static mut global_const_nested_array: [::core::ffi::c_int; 3] = [
304288
#[no_mangle]
305289
pub static mut global_const_nested_struct: S = NESTED_STRUCT;
306290
#[no_mangle]
307-
pub static mut global_const_negative_int: ::core::ffi::c_int = -LITERAL_INT;
291+
pub static mut global_const_negative_int: ::core::ffi::c_int = NEGATIVE_INT;
308292
#[no_mangle]
309-
pub static mut global_const_int_arithmetic: ::core::ffi::c_int =
310-
NESTED_INT + LITERAL_INT + 1 as ::core::ffi::c_int;
293+
pub static mut global_const_int_arithmetic: ::core::ffi::c_int = INT_ARITHMETIC;
311294
#[no_mangle]
312295
pub static mut global_const_mixed_arithmetic: ::core::ffi::c_float =
313-
(LITERAL_INT as ::core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as ::core::ffi::c_double
314-
- true_0 as ::core::ffi::c_double) as ::core::ffi::c_float;
296+
MIXED_ARITHMETIC as ::core::ffi::c_float;
315297
#[no_mangle]
316298
pub static mut global_const_parens: ::core::ffi::c_int = PARENS;
317299
#[no_mangle]
@@ -320,27 +302,24 @@ pub static mut global_const_ptr_arithmetic: *const ::core::ffi::c_char =
320302
#[no_mangle]
321303
pub static mut global_const_widening_cast: ::core::ffi::c_ulonglong = WIDENING_CAST;
322304
#[no_mangle]
323-
pub static mut global_const_narrowing_cast: ::core::ffi::c_char =
324-
LITERAL_INT as ::core::ffi::c_char;
305+
pub static mut global_const_narrowing_cast: ::core::ffi::c_char = NARROWING_CAST;
325306
#[no_mangle]
326307
pub static mut global_const_conversion_cast: ::core::ffi::c_double = CONVERSION_CAST;
327308
#[no_mangle]
328309
pub static mut global_const_indexing: ::core::ffi::c_char = 0;
329310
#[no_mangle]
330311
pub static mut global_const_str_concatenation_ptr: *const ::core::ffi::c_char =
331-
b"hello hello world\0".as_ptr() as *const ::core::ffi::c_char;
312+
STR_CONCATENATION.as_ptr();
332313
#[no_mangle]
333-
pub static mut global_const_str_concatenation: [::core::ffi::c_char; 18] = unsafe {
334-
::core::mem::transmute::<[u8; 18], [::core::ffi::c_char; 18]>(*b"hello hello world\0")
335-
};
314+
pub static mut global_const_str_concatenation: [::core::ffi::c_char; 18] = STR_CONCATENATION;
336315
#[no_mangle]
337316
pub static mut global_const_builtin: ::core::ffi::c_int =
338317
(LITERAL_INT as ::core::ffi::c_uint).leading_zeros() as i32;
339318
#[no_mangle]
340319
pub static mut global_const_ref_indexing: *const ::core::ffi::c_char =
341320
::core::ptr::null::<::core::ffi::c_char>();
342321
#[no_mangle]
343-
pub static mut global_const_ref_struct: *const S = &LITERAL_STRUCT as *const S as *mut S;
322+
pub static mut global_const_ref_struct: *const S = REF_LITERAL;
344323
#[no_mangle]
345324
pub static mut global_const_ternary: ::core::ffi::c_int = 0;
346325
#[no_mangle]
@@ -446,29 +425,15 @@ pub unsafe extern "C" fn late_init_var() -> ::core::ffi::c_int {
446425
}
447426
unsafe extern "C" fn c2rust_run_static_initializers() {
448427
global_static_const_ptr_arithmetic = PTR_ARITHMETIC;
449-
global_static_const_indexing = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize];
450-
global_static_const_ref_indexing = NESTED_STR
451-
.as_ptr()
452-
.offset(LITERAL_FLOAT as ::core::ffi::c_int as isize)
453-
as *const ::core::ffi::c_char;
454-
global_static_const_ternary = if LITERAL_BOOL != 0 {
455-
1 as ::core::ffi::c_int
456-
} else {
457-
2 as ::core::ffi::c_int
458-
};
459-
global_static_const_member = LITERAL_STRUCT.i;
428+
global_static_const_indexing = INDEXING;
429+
global_static_const_ref_indexing = REF_MACRO;
430+
global_static_const_ternary = TERNARY;
431+
global_static_const_member = MEMBER;
460432
global_const_ptr_arithmetic = PTR_ARITHMETIC;
461-
global_const_indexing = NESTED_STR[LITERAL_FLOAT as ::core::ffi::c_int as usize];
462-
global_const_ref_indexing = NESTED_STR
463-
.as_ptr()
464-
.offset(LITERAL_FLOAT as ::core::ffi::c_int as isize)
465-
as *const ::core::ffi::c_char;
466-
global_const_ternary = if LITERAL_BOOL != 0 {
467-
1 as ::core::ffi::c_int
468-
} else {
469-
2 as ::core::ffi::c_int
470-
};
471-
global_const_member = LITERAL_STRUCT.i;
433+
global_const_indexing = INDEXING;
434+
global_const_ref_indexing = REF_MACRO;
435+
global_const_ternary = TERNARY;
436+
global_const_member = MEMBER;
472437
}
473438
#[used]
474439
#[cfg_attr(target_os = "linux", link_section = ".init_array")]

0 commit comments

Comments
 (0)