authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-18 22:29:42+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-18 22:29:42+02:00
logcf7a5b7a4a77181a4c90fc9a92df496cfb48c3cd
treec8614c7c0d818c2e787068498984792d7b70be00
parente65b9e8f7bcc38943f48ed44560a22c62ca222ce
signature Commit is signed but in an unrecognized format.

translate-c-2 member access


4 files changed, 154 insertions(+), 105 deletions(-)

src-self-hosted/c_tokenizer.zig+55-53
...@@ -27,6 +27,7 @@ pub const CToken = struct {...@@ -27,6 +27,7 @@ pub const CToken = struct {
27 Lt,27 Lt,
28 Comma,28 Comma,
29 Fn,29 Fn,
30 Arrow,
30 };31 };
3132
32 pub const NumLitSuffix = enum {33 pub const NumLitSuffix = enum {
...@@ -164,6 +165,8 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -164,6 +165,8 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
164 NumLitIntSuffixL,165 NumLitIntSuffixL,
165 NumLitIntSuffixLL,166 NumLitIntSuffixLL,
166 NumLitIntSuffixUL,167 NumLitIntSuffixUL,
168 Minus,
169 Done,
167 } = .Start;170 } = .Start;
168171
169 var result = CToken{172 var result = CToken{
...@@ -178,9 +181,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -178,9 +181,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
178 const c = chars[i.*];181 const c = chars[i.*];
179 if (c == 0) {182 if (c == 0) {
180 switch (state) {183 switch (state) {
181 .Start => {
182 return result;
183 },
184 .Identifier,184 .Identifier,
185 .Decimal,185 .Decimal,
186 .Hex,186 .Hex,
...@@ -193,6 +193,9 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -193,6 +193,9 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
193 result.bytes = chars[begin_index..i.*];193 result.bytes = chars[begin_index..i.*];
194 return result;194 return result;
195 },195 },
196 .Start,
197 .Minus,
198 .Done,
196 .NumLitIntSuffixU,199 .NumLitIntSuffixU,
197 .NumLitIntSuffixL,200 .NumLitIntSuffixL,
198 .NumLitIntSuffixUL,201 .NumLitIntSuffixUL,
...@@ -212,7 +215,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -212,7 +215,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
212 => return error.TokenizingFailed,215 => return error.TokenizingFailed,
213 }216 }
214 }217 }
215 i.* += 1;
216 switch (state) {218 switch (state) {
217 .Start => {219 .Start => {
218 switch (c) {220 switch (c) {
...@@ -220,12 +222,12 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -220,12 +222,12 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
220 '\'' => {222 '\'' => {
221 state = .CharLit;223 state = .CharLit;
222 result.id = .CharLit;224 result.id = .CharLit;
223 begin_index = i.* - 1;225 begin_index = i.*;
224 },226 },
225 '\"' => {227 '\"' => {
226 state = .String;228 state = .String;
227 result.id = .StrLit;229 result.id = .StrLit;
228 begin_index = i.* - 1;230 begin_index = i.*;
229 },231 },
230 '/' => {232 '/' => {
231 state = .OpenComment;233 state = .OpenComment;
...@@ -239,21 +241,21 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -239,21 +241,21 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
239 'a'...'z', 'A'...'Z', '_' => {241 'a'...'z', 'A'...'Z', '_' => {
240 state = .Identifier;242 state = .Identifier;
241 result.id = .Identifier;243 result.id = .Identifier;
242 begin_index = i.* - 1;244 begin_index = i.*;
243 },245 },
244 '1'...'9' => {246 '1'...'9' => {
245 state = .Decimal;247 state = .Decimal;
246 result.id = .NumLitInt;248 result.id = .NumLitInt;
247 begin_index = i.* - 1;249 begin_index = i.*;
248 },250 },
249 '0' => {251 '0' => {
250 state = .GotZero;252 state = .GotZero;
251 result.id = .NumLitInt;253 result.id = .NumLitInt;
252 begin_index = i.* - 1;254 begin_index = i.*;
253 },255 },
254 '.' => {256 '.' => {
255 result.id = .Dot;257 result.id = .Dot;
256 return result;258 state = .Done;
257 },259 },
258 '<' => {260 '<' => {
259 result.id = .Lt;261 result.id = .Lt;
...@@ -261,40 +263,52 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -261,40 +263,52 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
261 },263 },
262 '(' => {264 '(' => {
263 result.id = .LParen;265 result.id = .LParen;
264 return result;266 state = .Done;
265 },267 },
266 ')' => {268 ')' => {
267 result.id = .RParen;269 result.id = .RParen;
268 return result;270 state = .Done;
269 },271 },
270 '*' => {272 '*' => {
271 result.id = .Asterisk;273 result.id = .Asterisk;
272 return result;274 state = .Done;
273 },275 },
274 '-' => {276 '-' => {
277 state = .Minus;
275 result.id = .Minus;278 result.id = .Minus;
276 return result;
277 },279 },
278 '!' => {280 '!' => {
279 result.id = .Bang;281 result.id = .Bang;
280 return result;282 state = .Done;
281 },283 },
282 '~' => {284 '~' => {
283 result.id = .Tilde;285 result.id = .Tilde;
284 return result;286 state = .Done;
285 },287 },
286 ',' => {288 ',' => {
287 result.id = .Comma;289 result.id = .Comma;
288 return result;290 state = .Done;
289 },291 },
290 else => return error.TokenizingFailed,292 else => return error.TokenizingFailed,
291 }293 }
292 },294 },
295 .Done => return result,
296 .Minus => {
297 switch (c) {
298 '>' => {
299 result.id = .Arrow;
300 state = .Done;
301 },
302 else => {
303 return result;
304 },
305 }
306 },
293 .GotLt => {307 .GotLt => {
294 switch (c) {308 switch (c) {
295 '<' => {309 '<' => {
296 result.id = .Shl;310 result.id = .Shl;
297 return result;311 state = .Done;
298 },312 },
299 else => {313 else => {
300 return result;314 return result;
...@@ -310,19 +324,16 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -310,19 +324,16 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
310 'f',324 'f',
311 'F',325 'F',
312 => {326 => {
313 i.* -= 1;
314 result.num_lit_suffix = .F;327 result.num_lit_suffix = .F;
315 result.bytes = chars[begin_index..i.*];328 result.bytes = chars[begin_index..i.*];
316 return result;329 state = .Done;
317 },330 },
318 'l', 'L' => {331 'l', 'L' => {
319 i.* -= 1;
320 result.num_lit_suffix = .L;332 result.num_lit_suffix = .L;
321 result.bytes = chars[begin_index..i.*];333 result.bytes = chars[begin_index..i.*];
322 return result;334 state = .Done;
323 },335 },
324 else => {336 else => {
325 i.* -= 1;
326 result.bytes = chars[begin_index..i.*];337 result.bytes = chars[begin_index..i.*];
327 return result;338 return result;
328 },339 },
...@@ -352,16 +363,15 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -352,16 +363,15 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
352 '0'...'9' => {},363 '0'...'9' => {},
353 'f', 'F' => {364 'f', 'F' => {
354 result.num_lit_suffix = .F;365 result.num_lit_suffix = .F;
355 result.bytes = chars[begin_index .. i.* - 1];366 result.bytes = chars[begin_index..i.*];
356 return result;367 state = .Done;
357 },368 },
358 'l', 'L' => {369 'l', 'L' => {
359 result.num_lit_suffix = .L;370 result.num_lit_suffix = .L;
360 result.bytes = chars[begin_index .. i.* - 1];371 result.bytes = chars[begin_index..i.*];
361 return result;372 state = .Done;
362 },373 },
363 else => {374 else => {
364 i.* -= 1;
365 result.bytes = chars[begin_index..i.*];375 result.bytes = chars[begin_index..i.*];
366 return result;376 return result;
367 },377 },
...@@ -374,19 +384,18 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -374,19 +384,18 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
374 'u', 'U' => {384 'u', 'U' => {
375 state = .NumLitIntSuffixU;385 state = .NumLitIntSuffixU;
376 result.num_lit_suffix = .U;386 result.num_lit_suffix = .U;
377 result.bytes = chars[begin_index .. i.* - 1];387 result.bytes = chars[begin_index..i.*];
378 },388 },
379 'l', 'L' => {389 'l', 'L' => {
380 state = .NumLitIntSuffixL;390 state = .NumLitIntSuffixL;
381 result.num_lit_suffix = .L;391 result.num_lit_suffix = .L;
382 result.bytes = chars[begin_index .. i.* - 1];392 result.bytes = chars[begin_index..i.*];
383 },393 },
384 '.' => {394 '.' => {
385 result.id = .NumLitFloat;395 result.id = .NumLitFloat;
386 state = .Float;396 state = .Float;
387 },397 },
388 else => {398 else => {
389 i.* -= 1;
390 result.bytes = chars[begin_index..i.*];399 result.bytes = chars[begin_index..i.*];
391 return result;400 return result;
392 },401 },
...@@ -407,12 +416,12 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -407,12 +416,12 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
407 'u', 'U' => {416 'u', 'U' => {
408 state = .NumLitIntSuffixU;417 state = .NumLitIntSuffixU;
409 result.num_lit_suffix = .U;418 result.num_lit_suffix = .U;
410 result.bytes = chars[begin_index .. i.* - 1];419 result.bytes = chars[begin_index..i.*];
411 },420 },
412 'l', 'L' => {421 'l', 'L' => {
413 state = .NumLitIntSuffixL;422 state = .NumLitIntSuffixL;
414 result.num_lit_suffix = .L;423 result.num_lit_suffix = .L;
415 result.bytes = chars[begin_index .. i.* - 1];424 result.bytes = chars[begin_index..i.*];
416 },425 },
417 else => {426 else => {
418 i.* -= 1;427 i.* -= 1;
...@@ -425,7 +434,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -425,7 +434,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
425 '0'...'7' => {},434 '0'...'7' => {},
426 '8', '9' => return error.TokenizingFailed,435 '8', '9' => return error.TokenizingFailed,
427 else => {436 else => {
428 i.* -= 1;
429 result.bytes = chars[begin_index..i.*];437 result.bytes = chars[begin_index..i.*];
430 return result;438 return result;
431 },439 },
...@@ -438,16 +446,15 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -438,16 +446,15 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
438 // marks the number literal as unsigned446 // marks the number literal as unsigned
439 state = .NumLitIntSuffixU;447 state = .NumLitIntSuffixU;
440 result.num_lit_suffix = .U;448 result.num_lit_suffix = .U;
441 result.bytes = chars[begin_index .. i.* - 1];449 result.bytes = chars[begin_index..i.*];
442 },450 },
443 'l', 'L' => {451 'l', 'L' => {
444 // marks the number literal as long452 // marks the number literal as long
445 state = .NumLitIntSuffixL;453 state = .NumLitIntSuffixL;
446 result.num_lit_suffix = .L;454 result.num_lit_suffix = .L;
447 result.bytes = chars[begin_index .. i.* - 1];455 result.bytes = chars[begin_index..i.*];
448 },456 },
449 else => {457 else => {
450 i.* -= 1;
451 result.bytes = chars[begin_index..i.*];458 result.bytes = chars[begin_index..i.*];
452 return result;459 return result;
453 },460 },
...@@ -461,16 +468,15 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -461,16 +468,15 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
461 // marks the number literal as unsigned468 // marks the number literal as unsigned
462 state = .NumLitIntSuffixU;469 state = .NumLitIntSuffixU;
463 result.num_lit_suffix = .U;470 result.num_lit_suffix = .U;
464 result.bytes = chars[begin_index .. i.* - 1];471 result.bytes = chars[begin_index..i.*];
465 },472 },
466 'l', 'L' => {473 'l', 'L' => {
467 // marks the number literal as long474 // marks the number literal as long
468 state = .NumLitIntSuffixL;475 state = .NumLitIntSuffixL;
469 result.num_lit_suffix = .L;476 result.num_lit_suffix = .L;
470 result.bytes = chars[begin_index .. i.* - 1];477 result.bytes = chars[begin_index..i.*];
471 },478 },
472 else => {479 else => {
473 i.* -= 1;
474 result.bytes = chars[begin_index..i.*];480 result.bytes = chars[begin_index..i.*];
475 return result;481 return result;
476 },482 },
...@@ -483,7 +489,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -483,7 +489,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
483 state = .NumLitIntSuffixUL;489 state = .NumLitIntSuffixUL;
484 },490 },
485 else => {491 else => {
486 i.* -= 1;
487 return result;492 return result;
488 },493 },
489 }494 }
...@@ -496,10 +501,9 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -496,10 +501,9 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
496 },501 },
497 'u', 'U' => {502 'u', 'U' => {
498 result.num_lit_suffix = .LU;503 result.num_lit_suffix = .LU;
499 return result;504 state = .Done;
500 },505 },
501 else => {506 else => {
502 i.* -= 1;
503 return result;507 return result;
504 },508 },
505 }509 }
...@@ -508,10 +512,9 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -508,10 +512,9 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
508 switch (c) {512 switch (c) {
509 'u', 'U' => {513 'u', 'U' => {
510 result.num_lit_suffix = .LLU;514 result.num_lit_suffix = .LLU;
511 return result;515 state = .Done;
512 },516 },
513 else => {517 else => {
514 i.* -= 1;
515 return result;518 return result;
516 },519 },
517 }520 }
...@@ -523,7 +526,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -523,7 +526,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
523 return result;526 return result;
524 },527 },
525 else => {528 else => {
526 i.* -= 1;
527 return result;529 return result;
528 },530 },
529 }531 }
...@@ -532,17 +534,16 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -532,17 +534,16 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
532 switch (c) {534 switch (c) {
533 '_', 'a'...'z', 'A'...'Z', '0'...'9' => {},535 '_', 'a'...'z', 'A'...'Z', '0'...'9' => {},
534 else => {536 else => {
535 i.* -= 1;
536 result.bytes = chars[begin_index..i.*];537 result.bytes = chars[begin_index..i.*];
537 return result;538 return result;
538 },539 },
539 }540 }
540 },541 },
541 .String => { // TODO char escapes542 .String => {
542 switch (c) {543 switch (c) {
543 '\"' => {544 '\"' => {
544 result.bytes = chars[begin_index..i.*];545 result.bytes = chars[begin_index .. i.* + 1];
545 return result;546 state = .Done;
546 },547 },
547 else => {},548 else => {},
548 }549 }
...@@ -550,8 +551,8 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -550,8 +551,8 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
550 .CharLit => {551 .CharLit => {
551 switch (c) {552 switch (c) {
552 '\'' => {553 '\'' => {
553 result.bytes = chars[begin_index..i.*];554 result.bytes = chars[begin_index .. i.* + 1];
554 return result;555 state = .Done;
555 },556 },
556 else => {},557 else => {},
557 }558 }
...@@ -566,7 +567,7 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -566,7 +567,7 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
566 },567 },
567 else => {568 else => {
568 result.id = .Slash;569 result.id = .Slash;
569 return result;570 state = .Done;
570 },571 },
571 }572 }
572 },573 },
...@@ -598,6 +599,7 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {...@@ -598,6 +599,7 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
598 }599 }
599 },600 },
600 }601 }
602 i.* += 1;
601 }603 }
602 unreachable;604 unreachable;
603}605}
src-self-hosted/clang.zig+5-1
...@@ -1096,5 +1096,9 @@ pub extern fn ZigClangCharacterLiteral_getBeginLoc(*const ZigClangCharacterLiter...@@ -1096,5 +1096,9 @@ pub extern fn ZigClangCharacterLiteral_getBeginLoc(*const ZigClangCharacterLiter
1096pub extern fn ZigClangCharacterLiteral_getKind(*const ZigClangCharacterLiteral) ZigClangCharacterLiteral_CharacterKind;1096pub extern fn ZigClangCharacterLiteral_getKind(*const ZigClangCharacterLiteral) ZigClangCharacterLiteral_CharacterKind;
1097pub extern fn ZigClangCharacterLiteral_getValue(*const ZigClangCharacterLiteral) c_uint;1097pub extern fn ZigClangCharacterLiteral_getValue(*const ZigClangCharacterLiteral) c_uint;
10981098
1099pub extern fn ZigClangStmtExpr_getSubStmt( *const ZigClangStmtExpr) *const ZigClangCompoundStmt;1099pub extern fn ZigClangStmtExpr_getSubStmt(*const ZigClangStmtExpr) *const ZigClangCompoundStmt;
1100
1101pub extern fn ZigClangMemberExpr_getBase(*const ZigClangMemberExpr) *const ZigClangExpr;
1102pub extern fn ZigClangMemberExpr_isArrow(*const ZigClangMemberExpr) bool;
1103pub extern fn ZigClangMemberExpr_getMemberDecl(*const ZigClangMemberExpr) *const ZigClangValueDecl;
11001104
src-self-hosted/translate_c.zig+49-35
...@@ -49,9 +49,6 @@ const Scope = struct {...@@ -49,9 +49,6 @@ const Scope = struct {
49 Root,49 Root,
50 Condition,50 Condition,
51 FnDef,51 FnDef,
52
53 /// used when getting a member `a.b`
54 Ref,
55 Loop,52 Loop,
56 };53 };
5754
...@@ -181,7 +178,6 @@ const Scope = struct {...@@ -181,7 +178,6 @@ const Scope = struct {
181 fn getAlias(scope: *Scope, name: []const u8) ?[]const u8 {178 fn getAlias(scope: *Scope, name: []const u8) ?[]const u8 {
182 return switch (scope.id) {179 return switch (scope.id) {
183 .Root => null,180 .Root => null,
184 .Ref => null,
185 .FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name),181 .FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name),
186 .Block => @fieldParentPtr(Block, "base", scope).getAlias(name),182 .Block => @fieldParentPtr(Block, "base", scope).getAlias(name),
187 .Switch, .Loop, .Condition => scope.parent.?.getAlias(name),183 .Switch, .Loop, .Condition => scope.parent.?.getAlias(name),
...@@ -190,7 +186,6 @@ const Scope = struct {...@@ -190,7 +186,6 @@ const Scope = struct {
190186
191 fn contains(scope: *Scope, name: []const u8) bool {187 fn contains(scope: *Scope, name: []const u8) bool {
192 return switch (scope.id) {188 return switch (scope.id) {
193 .Ref => false,
194 .Root => @fieldParentPtr(Root, "base", scope).contains(name),189 .Root => @fieldParentPtr(Root, "base", scope).contains(name),
195 .FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name),190 .FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name),
196 .Block => @fieldParentPtr(Block, "base", scope).contains(name),191 .Block => @fieldParentPtr(Block, "base", scope).contains(name),
...@@ -230,7 +225,6 @@ const Context = struct {...@@ -230,7 +225,6 @@ const Context = struct {
230 decl_table: DeclTable,225 decl_table: DeclTable,
231 alias_list: AliasList,226 alias_list: AliasList,
232 global_scope: *Scope.Root,227 global_scope: *Scope.Root,
233 ptr_params: std.BufSet,
234 clang_context: *ZigClangASTContext,228 clang_context: *ZigClangASTContext,
235 mangle_count: u64 = 0,229 mangle_count: u64 = 0,
236230
...@@ -316,7 +310,6 @@ pub fn translate(...@@ -316,7 +310,6 @@ pub fn translate(
316 .decl_table = DeclTable.init(arena),310 .decl_table = DeclTable.init(arena),
317 .alias_list = AliasList.init(arena),311 .alias_list = AliasList.init(arena),
318 .global_scope = try arena.create(Scope.Root),312 .global_scope = try arena.create(Scope.Root),
319 .ptr_params = std.BufSet.init(arena),
320 .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,313 .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
321 };314 };
322 context.global_scope.* = Scope.Root.init(&context);315 context.global_scope.* = Scope.Root.init(&context);
...@@ -856,6 +849,7 @@ fn transStmt(...@@ -856,6 +849,7 @@ fn transStmt(
856 .PredefinedExprClass => return transPredefinedExpr(rp, scope, @ptrCast(*const ZigClangPredefinedExpr, stmt), result_used),849 .PredefinedExprClass => return transPredefinedExpr(rp, scope, @ptrCast(*const ZigClangPredefinedExpr, stmt), result_used),
857 .CharacterLiteralClass => return transCharLiteral(rp, scope, @ptrCast(*const ZigClangCharacterLiteral, stmt), result_used),850 .CharacterLiteralClass => return transCharLiteral(rp, scope, @ptrCast(*const ZigClangCharacterLiteral, stmt), result_used),
858 .StmtExprClass => return transStmtExpr(rp, scope, @ptrCast(*const ZigClangStmtExpr, stmt), result_used),851 .StmtExprClass => return transStmtExpr(rp, scope, @ptrCast(*const ZigClangStmtExpr, stmt), result_used),
852 .MemberExprClass => return transMemberExpr(rp, scope, @ptrCast(*const ZigClangMemberExpr, stmt), result_used),
859 else => {853 else => {
860 return revertAndWarn(854 return revertAndWarn(
861 rp,855 rp,
...@@ -1147,7 +1141,6 @@ fn transDeclRefExpr(...@@ -1147,7 +1141,6 @@ fn transDeclRefExpr(
1147 const value_decl = ZigClangDeclRefExpr_getDecl(expr);1141 const value_decl = ZigClangDeclRefExpr_getDecl(expr);
1148 const name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, value_decl)));1142 const name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, value_decl)));
1149 const checked_name = if (scope.getAlias(name)) |a| a else name;1143 const checked_name = if (scope.getAlias(name)) |a| a else name;
1150 if (lrvalue == .l_value) try rp.c.ptr_params.put(checked_name);
1151 return transCreateNodeIdentifier(rp.c, checked_name);1144 return transCreateNodeIdentifier(rp.c, checked_name);
1152}1145}
11531146
...@@ -1990,6 +1983,18 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr,...@@ -1990,6 +1983,18 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr,
1990 return maybeSuppressResult(rp, scope, used, &grouped_expr.base);1983 return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
1991}1984}
19921985
1986fn transMemberExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangMemberExpr, result_used: ResultUsed) TransError!*ast.Node {
1987 var container_node = try transExpr(rp, scope, ZigClangMemberExpr_getBase(stmt), .used, .r_value);
1988
1989 if (ZigClangMemberExpr_isArrow(stmt)) {
1990 container_node = try transCreateNodePtrDeref(rp.c, container_node);
1991 }
1992
1993 const name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, ZigClangMemberExpr_getMemberDecl(stmt))));
1994 const node = try transCreateNodeFieldAccess(rp.c, container_node, name);
1995 return maybeSuppressResult(rp, scope, result_used, node);
1996}
1997
1993fn transCPtrCast(1998fn transCPtrCast(
1994 rp: RestorePoint,1999 rp: RestorePoint,
1995 loc: ZigClangSourceLocation,2000 loc: ZigClangSourceLocation,
...@@ -2213,8 +2218,8 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC...@@ -2213,8 +2218,8 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC
2213 import_fn_call.rparen_token = try appendToken(rp.c, .RParen, ")");2218 import_fn_call.rparen_token = try appendToken(rp.c, .RParen, ")");
22142219
2215 const inner_field_access = try transCreateNodeFieldAccess(rp.c, &import_fn_call.base, "math");2220 const inner_field_access = try transCreateNodeFieldAccess(rp.c, &import_fn_call.base, "math");
2216 const outer_field_access = try transCreateNodeFieldAccess(rp.c, &inner_field_access.base, "Log2Int");2221 const outer_field_access = try transCreateNodeFieldAccess(rp.c, inner_field_access, "Log2Int");
2217 const log2int_fn_call = try transCreateNodeFnCall(rp.c, &outer_field_access.base);2222 const log2int_fn_call = try transCreateNodeFnCall(rp.c, outer_field_access);
2218 try @ptrCast(*ast.Node.SuffixOp.Op.Call, &log2int_fn_call.op).params.push(zig_type_node);2223 try @ptrCast(*ast.Node.SuffixOp.Op.Call, &log2int_fn_call.op).params.push(zig_type_node);
2219 log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")");2224 log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")");
22202225
...@@ -2446,7 +2451,7 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp {...@@ -2446,7 +2451,7 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp {
2446 return node;2451 return node;
2447}2452}
24482453
2449fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node.InfixOp {2454fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node {
2450 const field_access_node = try c.a().create(ast.Node.InfixOp);2455 const field_access_node = try c.a().create(ast.Node.InfixOp);
2451 field_access_node.* = .{2456 field_access_node.* = .{
2452 .op_token = try appendToken(c, .Period, "."),2457 .op_token = try appendToken(c, .Period, "."),
...@@ -2454,7 +2459,7 @@ fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []c...@@ -2454,7 +2459,7 @@ fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []c
2454 .op = .Period,2459 .op = .Period,
2455 .rhs = try transCreateNodeIdentifier(c, field_name),2460 .rhs = try transCreateNodeIdentifier(c, field_name),
2456 };2461 };
2457 return field_access_node;2462 return &field_access_node.base;
2458}2463}
24592464
2460fn transCreateNodePrefixOp(2465fn transCreateNodePrefixOp(
...@@ -2924,9 +2929,9 @@ fn transCreateNodeShiftOp(...@@ -2924,9 +2929,9 @@ fn transCreateNodeShiftOp(
2924 rp: RestorePoint,2929 rp: RestorePoint,
2925 scope: *Scope,2930 scope: *Scope,
2926 stmt: *const ZigClangBinaryOperator,2931 stmt: *const ZigClangBinaryOperator,
2927 comptime op: ast.Node.InfixOp.Op,2932 op: ast.Node.InfixOp.Op,
2928 comptime op_tok_id: std.zig.Token.Id,2933 op_tok_id: std.zig.Token.Id,
2929 comptime bytes: []const u8,2934 bytes: []const u8,
2930) !*ast.Node {2935) !*ast.Node {
2931 std.debug.assert(op == .BitShiftLeft or op == .BitShiftRight);2936 std.debug.assert(op == .BitShiftLeft or op == .BitShiftRight);
29322937
...@@ -2957,6 +2962,16 @@ fn transCreateNodeShiftOp(...@@ -2957,6 +2962,16 @@ fn transCreateNodeShiftOp(
2957 return &node.base;2962 return &node.base;
2958}2963}
29592964
2965fn transCreateNodePtrDeref(c: *Context, lhs: *ast.Node) !*ast.Node {
2966 const node = try c.a().create(ast.Node.SuffixOp);
2967 node.* = .{
2968 .lhs = .{ .node = lhs },
2969 .op = .Deref,
2970 .rtoken = try appendToken(c, .PeriodAsterisk, ".*"),
2971 };
2972 return &node.base;
2973}
2974
2960const RestorePoint = struct {2975const RestorePoint = struct {
2961 c: *Context,2976 c: *Context,
2962 token_index: ast.TokenIndex,2977 token_index: ast.TokenIndex,
...@@ -3862,16 +3877,21 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc...@@ -3862,16 +3877,21 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
3862 .{},3877 .{},
3863 );3878 );
38643879
3865 const op_token = try appendToken(rp.c, .Period, ".");3880 node = try transCreateNodeFieldAccess(rp.c, node, name_tok.bytes);
3866 const rhs = try transCreateNodeIdentifier(rp.c, name_tok.bytes);3881 },
3867 const access_node = try rp.c.a().create(ast.Node.InfixOp);3882 .Arrow => {
3868 access_node.* = .{3883 const name_tok = it.next().?;
3869 .op_token = op_token,3884 if (name_tok.id != .Identifier)
3870 .lhs = node,3885 return revertAndWarn(
3871 .op = .Period,3886 rp,
3872 .rhs = rhs,3887 error.ParseError,
3873 };3888 source_loc,
3874 node = &access_node.base;3889 "unable to translate C expr",
3890 .{},
3891 );
3892
3893 const deref = try transCreateNodePtrDeref(rp.c, node);
3894 node = try transCreateNodeFieldAccess(rp.c, deref, name_tok.bytes);
3875 },3895 },
3876 .Asterisk => {3896 .Asterisk => {
3877 if (it.peek().?.id == .RParen) {3897 if (it.peek().?.id == .RParen) {
...@@ -3887,14 +3907,14 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc...@@ -3887,14 +3907,14 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
3887 // expr * expr3907 // expr * expr
3888 const op_token = try appendToken(rp.c, .Asterisk, "*");3908 const op_token = try appendToken(rp.c, .Asterisk, "*");
3889 const rhs = try parseCPrimaryExpr(rp, it, source_loc, scope);3909 const rhs = try parseCPrimaryExpr(rp, it, source_loc, scope);
3890 const bitshift_node = try rp.c.a().create(ast.Node.InfixOp);3910 const mul_node = try rp.c.a().create(ast.Node.InfixOp);
3891 bitshift_node.* = .{3911 mul_node.* = .{
3892 .op_token = op_token,3912 .op_token = op_token,
3893 .lhs = node,3913 .lhs = node,
3894 .op = .BitShiftLeft,3914 .op = .BitShiftLeft,
3895 .rhs = rhs,3915 .rhs = rhs,
3896 };3916 };
3897 node = &bitshift_node.base;3917 node = &mul_node.base;
3898 }3918 }
3899 },3919 },
3900 .Shl => {3920 .Shl => {
...@@ -3938,13 +3958,7 @@ fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc...@@ -3938,13 +3958,7 @@ fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
3938 },3958 },
3939 .Asterisk => {3959 .Asterisk => {
3940 const prefix_op_expr = try parseCPrefixOpExpr(rp, it, source_loc, scope);3960 const prefix_op_expr = try parseCPrefixOpExpr(rp, it, source_loc, scope);
3941 const node = try rp.c.a().create(ast.Node.SuffixOp);3961 return try transCreateNodePtrDeref(rp.c, prefix_op_expr);
3942 node.* = .{
3943 .lhs = .{ .node = prefix_op_expr },
3944 .op = .Deref,
3945 .rtoken = try appendToken(rp.c, .PeriodAsterisk, ".*"),
3946 };
3947 return &node.base;
3948 },3962 },
3949 else => {3963 else => {
3950 _ = it.prev();3964 _ = it.prev();
test/translate_c.zig+45-16
...@@ -1494,6 +1494,35 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1494,6 +1494,35 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1494 \\}1494 \\}
1495 });1495 });
14961496
1497 cases.add_2("field access expression",
1498 \\#define ARROW a->b
1499 \\#define DOT a.b
1500 \\extern struct Foo {
1501 \\ int b;
1502 \\}a;
1503 \\float b = 2.0f;
1504 \\int foo(void) {
1505 \\ struct Foo *c;
1506 \\ a.b;
1507 \\ c->b;
1508 \\}
1509 , &[_][]const u8{
1510 \\pub const struct_Foo = extern struct {
1511 \\ b: c_int,
1512 \\};
1513 \\pub extern var a: struct_Foo;
1514 \\pub export var b: f32 = 2;
1515 \\pub export fn foo() c_int {
1516 \\ var c: [*c]struct_Foo = undefined;
1517 \\ _ = a.b;
1518 \\ _ = c.*.b;
1519 \\}
1520 ,
1521 \\pub const DOT = a.b;
1522 ,
1523 \\pub const ARROW = a.*.b;
1524 });
1525
1497 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////1526 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
14981527
1499 cases.addAllowWarnings("simple data types",1528 cases.addAllowWarnings("simple data types",
...@@ -1702,22 +1731,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1702,22 +1731,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1702 \\}1731 \\}
1703 });1732 });
17041733
1705 cases.addC("field access expression",
1706 \\struct Foo {
1707 \\ int field;
1708 \\};
1709 \\int read_field(struct Foo *foo) {
1710 \\ return foo->field;
1711 \\}
1712 , &[_][]const u8{
1713 \\pub const struct_Foo = extern struct {
1714 \\ field: c_int,
1715 \\};
1716 \\pub export fn read_field(foo: [*c]struct_Foo) c_int {
1717 \\ return foo.*.field;
1718 \\}
1719 });
1720
1721 cases.addC("array access",1734 cases.addC("array access",
1722 \\int array[100];1735 \\int array[100];
1723 \\int foo(int index) {1736 \\int foo(int index) {
...@@ -2627,4 +2640,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2627,4 +2640,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2627 \\ };2640 \\ };
2628 \\}2641 \\}
2629 });2642 });
2643
2644 cases.addC("field access expression",
2645 \\struct Foo {
2646 \\ int field;
2647 \\};
2648 \\int read_field(struct Foo *foo) {
2649 \\ return foo->field;
2650 \\}
2651 , &[_][]const u8{
2652 \\pub const struct_Foo = extern struct {
2653 \\ field: c_int,
2654 \\};
2655 \\pub export fn read_field(foo: [*c]struct_Foo) c_int {
2656 \\ return foo.*.field;
2657 \\}
2658 });
2630}2659}