| author | |
| committer | |
| log | cf7a5b7a4a77181a4c90fc9a92df496cfb48c3cd |
| tree | c8614c7c0d818c2e787068498984792d7b70be00 |
| parent | e65b9e8f7bcc38943f48ed44560a22c62ca222ce |
| signature | Commit is signed but in an unrecognized format. |
4 files changed, 154 insertions(+), 105 deletions(-)
src-self-hosted/c_tokenizer.zig+55-53| ... | ... | @@ -27,6 +27,7 @@ pub const CToken = struct { |
| 27 | 27 | Lt, |
| 28 | 28 | Comma, |
| 29 | 29 | Fn, |
| 30 | Arrow, | |
| 30 | 31 | }; |
| 31 | 32 | |
| 32 | 33 | pub const NumLitSuffix = enum { |
| ... | ... | @@ -164,6 +165,8 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 164 | 165 | NumLitIntSuffixL, |
| 165 | 166 | NumLitIntSuffixLL, |
| 166 | 167 | NumLitIntSuffixUL, |
| 168 | Minus, | |
| 169 | Done, | |
| 167 | 170 | } = .Start; |
| 168 | 171 | |
| 169 | 172 | var result = CToken{ |
| ... | ... | @@ -178,9 +181,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 178 | 181 | const c = chars[i.*]; |
| 179 | 182 | if (c == 0) { |
| 180 | 183 | switch (state) { |
| 181 | .Start => { | |
| 182 | return result; | |
| 183 | }, | |
| 184 | 184 | .Identifier, |
| 185 | 185 | .Decimal, |
| 186 | 186 | .Hex, |
| ... | ... | @@ -193,6 +193,9 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 193 | 193 | result.bytes = chars[begin_index..i.*]; |
| 194 | 194 | return result; |
| 195 | 195 | }, |
| 196 | .Start, | |
| 197 | .Minus, | |
| 198 | .Done, | |
| 196 | 199 | .NumLitIntSuffixU, |
| 197 | 200 | .NumLitIntSuffixL, |
| 198 | 201 | .NumLitIntSuffixUL, |
| ... | ... | @@ -212,7 +215,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 212 | 215 | => return error.TokenizingFailed, |
| 213 | 216 | } |
| 214 | 217 | } |
| 215 | i.* += 1; | |
| 216 | 218 | switch (state) { |
| 217 | 219 | .Start => { |
| 218 | 220 | switch (c) { |
| ... | ... | @@ -220,12 +222,12 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 220 | 222 | '\'' => { |
| 221 | 223 | state = .CharLit; |
| 222 | 224 | result.id = .CharLit; |
| 223 | begin_index = i.* - 1; | |
| 225 | begin_index = i.*; | |
| 224 | 226 | }, |
| 225 | 227 | '\"' => { |
| 226 | 228 | state = .String; |
| 227 | 229 | result.id = .StrLit; |
| 228 | begin_index = i.* - 1; | |
| 230 | begin_index = i.*; | |
| 229 | 231 | }, |
| 230 | 232 | '/' => { |
| 231 | 233 | state = .OpenComment; |
| ... | ... | @@ -239,21 +241,21 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 239 | 241 | 'a'...'z', 'A'...'Z', '_' => { |
| 240 | 242 | state = .Identifier; |
| 241 | 243 | result.id = .Identifier; |
| 242 | begin_index = i.* - 1; | |
| 244 | begin_index = i.*; | |
| 243 | 245 | }, |
| 244 | 246 | '1'...'9' => { |
| 245 | 247 | state = .Decimal; |
| 246 | 248 | result.id = .NumLitInt; |
| 247 | begin_index = i.* - 1; | |
| 249 | begin_index = i.*; | |
| 248 | 250 | }, |
| 249 | 251 | '0' => { |
| 250 | 252 | state = .GotZero; |
| 251 | 253 | result.id = .NumLitInt; |
| 252 | begin_index = i.* - 1; | |
| 254 | begin_index = i.*; | |
| 253 | 255 | }, |
| 254 | 256 | '.' => { |
| 255 | 257 | result.id = .Dot; |
| 256 | return result; | |
| 258 | state = .Done; | |
| 257 | 259 | }, |
| 258 | 260 | '<' => { |
| 259 | 261 | result.id = .Lt; |
| ... | ... | @@ -261,40 +263,52 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 261 | 263 | }, |
| 262 | 264 | '(' => { |
| 263 | 265 | result.id = .LParen; |
| 264 | return result; | |
| 266 | state = .Done; | |
| 265 | 267 | }, |
| 266 | 268 | ')' => { |
| 267 | 269 | result.id = .RParen; |
| 268 | return result; | |
| 270 | state = .Done; | |
| 269 | 271 | }, |
| 270 | 272 | '*' => { |
| 271 | 273 | result.id = .Asterisk; |
| 272 | return result; | |
| 274 | state = .Done; | |
| 273 | 275 | }, |
| 274 | 276 | '-' => { |
| 277 | state = .Minus; | |
| 275 | 278 | result.id = .Minus; |
| 276 | return result; | |
| 277 | 279 | }, |
| 278 | 280 | '!' => { |
| 279 | 281 | result.id = .Bang; |
| 280 | return result; | |
| 282 | state = .Done; | |
| 281 | 283 | }, |
| 282 | 284 | '~' => { |
| 283 | 285 | result.id = .Tilde; |
| 284 | return result; | |
| 286 | state = .Done; | |
| 285 | 287 | }, |
| 286 | 288 | ',' => { |
| 287 | 289 | result.id = .Comma; |
| 288 | return result; | |
| 290 | state = .Done; | |
| 289 | 291 | }, |
| 290 | 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 | 307 | .GotLt => { |
| 294 | 308 | switch (c) { |
| 295 | 309 | '<' => { |
| 296 | 310 | result.id = .Shl; |
| 297 | return result; | |
| 311 | state = .Done; | |
| 298 | 312 | }, |
| 299 | 313 | else => { |
| 300 | 314 | return result; |
| ... | ... | @@ -310,19 +324,16 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 310 | 324 | 'f', |
| 311 | 325 | 'F', |
| 312 | 326 | => { |
| 313 | i.* -= 1; | |
| 314 | 327 | result.num_lit_suffix = .F; |
| 315 | 328 | result.bytes = chars[begin_index..i.*]; |
| 316 | return result; | |
| 329 | state = .Done; | |
| 317 | 330 | }, |
| 318 | 331 | 'l', 'L' => { |
| 319 | i.* -= 1; | |
| 320 | 332 | result.num_lit_suffix = .L; |
| 321 | 333 | result.bytes = chars[begin_index..i.*]; |
| 322 | return result; | |
| 334 | state = .Done; | |
| 323 | 335 | }, |
| 324 | 336 | else => { |
| 325 | i.* -= 1; | |
| 326 | 337 | result.bytes = chars[begin_index..i.*]; |
| 327 | 338 | return result; |
| 328 | 339 | }, |
| ... | ... | @@ -352,16 +363,15 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 352 | 363 | '0'...'9' => {}, |
| 353 | 364 | 'f', 'F' => { |
| 354 | 365 | result.num_lit_suffix = .F; |
| 355 | result.bytes = chars[begin_index .. i.* - 1]; | |
| 356 | return result; | |
| 366 | result.bytes = chars[begin_index..i.*]; | |
| 367 | state = .Done; | |
| 357 | 368 | }, |
| 358 | 369 | 'l', 'L' => { |
| 359 | 370 | result.num_lit_suffix = .L; |
| 360 | result.bytes = chars[begin_index .. i.* - 1]; | |
| 361 | return result; | |
| 371 | result.bytes = chars[begin_index..i.*]; | |
| 372 | state = .Done; | |
| 362 | 373 | }, |
| 363 | 374 | else => { |
| 364 | i.* -= 1; | |
| 365 | 375 | result.bytes = chars[begin_index..i.*]; |
| 366 | 376 | return result; |
| 367 | 377 | }, |
| ... | ... | @@ -374,19 +384,18 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 374 | 384 | 'u', 'U' => { |
| 375 | 385 | state = .NumLitIntSuffixU; |
| 376 | 386 | result.num_lit_suffix = .U; |
| 377 | result.bytes = chars[begin_index .. i.* - 1]; | |
| 387 | result.bytes = chars[begin_index..i.*]; | |
| 378 | 388 | }, |
| 379 | 389 | 'l', 'L' => { |
| 380 | 390 | state = .NumLitIntSuffixL; |
| 381 | 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 | 395 | result.id = .NumLitFloat; |
| 386 | 396 | state = .Float; |
| 387 | 397 | }, |
| 388 | 398 | else => { |
| 389 | i.* -= 1; | |
| 390 | 399 | result.bytes = chars[begin_index..i.*]; |
| 391 | 400 | return result; |
| 392 | 401 | }, |
| ... | ... | @@ -407,12 +416,12 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 407 | 416 | 'u', 'U' => { |
| 408 | 417 | state = .NumLitIntSuffixU; |
| 409 | 418 | result.num_lit_suffix = .U; |
| 410 | result.bytes = chars[begin_index .. i.* - 1]; | |
| 419 | result.bytes = chars[begin_index..i.*]; | |
| 411 | 420 | }, |
| 412 | 421 | 'l', 'L' => { |
| 413 | 422 | state = .NumLitIntSuffixL; |
| 414 | 423 | result.num_lit_suffix = .L; |
| 415 | result.bytes = chars[begin_index .. i.* - 1]; | |
| 424 | result.bytes = chars[begin_index..i.*]; | |
| 416 | 425 | }, |
| 417 | 426 | else => { |
| 418 | 427 | i.* -= 1; |
| ... | ... | @@ -425,7 +434,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 425 | 434 | '0'...'7' => {}, |
| 426 | 435 | '8', '9' => return error.TokenizingFailed, |
| 427 | 436 | else => { |
| 428 | i.* -= 1; | |
| 429 | 437 | result.bytes = chars[begin_index..i.*]; |
| 430 | 438 | return result; |
| 431 | 439 | }, |
| ... | ... | @@ -438,16 +446,15 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 438 | 446 | // marks the number literal as unsigned |
| 439 | 447 | state = .NumLitIntSuffixU; |
| 440 | 448 | result.num_lit_suffix = .U; |
| 441 | result.bytes = chars[begin_index .. i.* - 1]; | |
| 449 | result.bytes = chars[begin_index..i.*]; | |
| 442 | 450 | }, |
| 443 | 451 | 'l', 'L' => { |
| 444 | 452 | // marks the number literal as long |
| 445 | 453 | state = .NumLitIntSuffixL; |
| 446 | 454 | result.num_lit_suffix = .L; |
| 447 | result.bytes = chars[begin_index .. i.* - 1]; | |
| 455 | result.bytes = chars[begin_index..i.*]; | |
| 448 | 456 | }, |
| 449 | 457 | else => { |
| 450 | i.* -= 1; | |
| 451 | 458 | result.bytes = chars[begin_index..i.*]; |
| 452 | 459 | return result; |
| 453 | 460 | }, |
| ... | ... | @@ -461,16 +468,15 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 461 | 468 | // marks the number literal as unsigned |
| 462 | 469 | state = .NumLitIntSuffixU; |
| 463 | 470 | result.num_lit_suffix = .U; |
| 464 | result.bytes = chars[begin_index .. i.* - 1]; | |
| 471 | result.bytes = chars[begin_index..i.*]; | |
| 465 | 472 | }, |
| 466 | 473 | 'l', 'L' => { |
| 467 | 474 | // marks the number literal as long |
| 468 | 475 | state = .NumLitIntSuffixL; |
| 469 | 476 | result.num_lit_suffix = .L; |
| 470 | result.bytes = chars[begin_index .. i.* - 1]; | |
| 477 | result.bytes = chars[begin_index..i.*]; | |
| 471 | 478 | }, |
| 472 | 479 | else => { |
| 473 | i.* -= 1; | |
| 474 | 480 | result.bytes = chars[begin_index..i.*]; |
| 475 | 481 | return result; |
| 476 | 482 | }, |
| ... | ... | @@ -483,7 +489,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 483 | 489 | state = .NumLitIntSuffixUL; |
| 484 | 490 | }, |
| 485 | 491 | else => { |
| 486 | i.* -= 1; | |
| 487 | 492 | return result; |
| 488 | 493 | }, |
| 489 | 494 | } |
| ... | ... | @@ -496,10 +501,9 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 496 | 501 | }, |
| 497 | 502 | 'u', 'U' => { |
| 498 | 503 | result.num_lit_suffix = .LU; |
| 499 | return result; | |
| 504 | state = .Done; | |
| 500 | 505 | }, |
| 501 | 506 | else => { |
| 502 | i.* -= 1; | |
| 503 | 507 | return result; |
| 504 | 508 | }, |
| 505 | 509 | } |
| ... | ... | @@ -508,10 +512,9 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 508 | 512 | switch (c) { |
| 509 | 513 | 'u', 'U' => { |
| 510 | 514 | result.num_lit_suffix = .LLU; |
| 511 | return result; | |
| 515 | state = .Done; | |
| 512 | 516 | }, |
| 513 | 517 | else => { |
| 514 | i.* -= 1; | |
| 515 | 518 | return result; |
| 516 | 519 | }, |
| 517 | 520 | } |
| ... | ... | @@ -523,7 +526,6 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 523 | 526 | return result; |
| 524 | 527 | }, |
| 525 | 528 | else => { |
| 526 | i.* -= 1; | |
| 527 | 529 | return result; |
| 528 | 530 | }, |
| 529 | 531 | } |
| ... | ... | @@ -532,17 +534,16 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 532 | 534 | switch (c) { |
| 533 | 535 | '_', 'a'...'z', 'A'...'Z', '0'...'9' => {}, |
| 534 | 536 | else => { |
| 535 | i.* -= 1; | |
| 536 | 537 | result.bytes = chars[begin_index..i.*]; |
| 537 | 538 | return result; |
| 538 | 539 | }, |
| 539 | 540 | } |
| 540 | 541 | }, |
| 541 | .String => { // TODO char escapes | |
| 542 | .String => { | |
| 542 | 543 | switch (c) { |
| 543 | 544 | '\"' => { |
| 544 | result.bytes = chars[begin_index..i.*]; | |
| 545 | return result; | |
| 545 | result.bytes = chars[begin_index .. i.* + 1]; | |
| 546 | state = .Done; | |
| 546 | 547 | }, |
| 547 | 548 | else => {}, |
| 548 | 549 | } |
| ... | ... | @@ -550,8 +551,8 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 550 | 551 | .CharLit => { |
| 551 | 552 | switch (c) { |
| 552 | 553 | '\'' => { |
| 553 | result.bytes = chars[begin_index..i.*]; | |
| 554 | return result; | |
| 554 | result.bytes = chars[begin_index .. i.* + 1]; | |
| 555 | state = .Done; | |
| 555 | 556 | }, |
| 556 | 557 | else => {}, |
| 557 | 558 | } |
| ... | ... | @@ -566,7 +567,7 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken { |
| 566 | 567 | }, |
| 567 | 568 | else => { |
| 568 | 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 | 599 | } |
| 599 | 600 | }, |
| 600 | 601 | } |
| 602 | i.* += 1; | |
| 601 | 603 | } |
| 602 | 604 | unreachable; |
| 603 | 605 | } |
src-self-hosted/clang.zig+5-1| ... | ... | @@ -1096,5 +1096,9 @@ pub extern fn ZigClangCharacterLiteral_getBeginLoc(*const ZigClangCharacterLiter |
| 1096 | 1096 | pub extern fn ZigClangCharacterLiteral_getKind(*const ZigClangCharacterLiteral) ZigClangCharacterLiteral_CharacterKind; |
| 1097 | 1097 | pub extern fn ZigClangCharacterLiteral_getValue(*const ZigClangCharacterLiteral) c_uint; |
| 1098 | 1098 | |
| 1099 | pub extern fn ZigClangStmtExpr_getSubStmt( *const ZigClangStmtExpr) *const ZigClangCompoundStmt; | |
| 1099 | pub extern fn ZigClangStmtExpr_getSubStmt(*const ZigClangStmtExpr) *const ZigClangCompoundStmt; | |
| 1100 | ||
| 1101 | pub extern fn ZigClangMemberExpr_getBase(*const ZigClangMemberExpr) *const ZigClangExpr; | |
| 1102 | pub extern fn ZigClangMemberExpr_isArrow(*const ZigClangMemberExpr) bool; | |
| 1103 | pub extern fn ZigClangMemberExpr_getMemberDecl(*const ZigClangMemberExpr) *const ZigClangValueDecl; | |
| 1100 | 1104 |
src-self-hosted/translate_c.zig+49-35| ... | ... | @@ -49,9 +49,6 @@ const Scope = struct { |
| 49 | 49 | Root, |
| 50 | 50 | Condition, |
| 51 | 51 | FnDef, |
| 52 | ||
| 53 | /// used when getting a member `a.b` | |
| 54 | Ref, | |
| 55 | 52 | Loop, |
| 56 | 53 | }; |
| 57 | 54 | |
| ... | ... | @@ -181,7 +178,6 @@ const Scope = struct { |
| 181 | 178 | fn getAlias(scope: *Scope, name: []const u8) ?[]const u8 { |
| 182 | 179 | return switch (scope.id) { |
| 183 | 180 | .Root => null, |
| 184 | .Ref => null, | |
| 185 | 181 | .FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name), |
| 186 | 182 | .Block => @fieldParentPtr(Block, "base", scope).getAlias(name), |
| 187 | 183 | .Switch, .Loop, .Condition => scope.parent.?.getAlias(name), |
| ... | ... | @@ -190,7 +186,6 @@ const Scope = struct { |
| 190 | 186 | |
| 191 | 187 | fn contains(scope: *Scope, name: []const u8) bool { |
| 192 | 188 | return switch (scope.id) { |
| 193 | .Ref => false, | |
| 194 | 189 | .Root => @fieldParentPtr(Root, "base", scope).contains(name), |
| 195 | 190 | .FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name), |
| 196 | 191 | .Block => @fieldParentPtr(Block, "base", scope).contains(name), |
| ... | ... | @@ -230,7 +225,6 @@ const Context = struct { |
| 230 | 225 | decl_table: DeclTable, |
| 231 | 226 | alias_list: AliasList, |
| 232 | 227 | global_scope: *Scope.Root, |
| 233 | ptr_params: std.BufSet, | |
| 234 | 228 | clang_context: *ZigClangASTContext, |
| 235 | 229 | mangle_count: u64 = 0, |
| 236 | 230 | |
| ... | ... | @@ -316,7 +310,6 @@ pub fn translate( |
| 316 | 310 | .decl_table = DeclTable.init(arena), |
| 317 | 311 | .alias_list = AliasList.init(arena), |
| 318 | 312 | .global_scope = try arena.create(Scope.Root), |
| 319 | .ptr_params = std.BufSet.init(arena), | |
| 320 | 313 | .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?, |
| 321 | 314 | }; |
| 322 | 315 | context.global_scope.* = Scope.Root.init(&context); |
| ... | ... | @@ -856,6 +849,7 @@ fn transStmt( |
| 856 | 849 | .PredefinedExprClass => return transPredefinedExpr(rp, scope, @ptrCast(*const ZigClangPredefinedExpr, stmt), result_used), |
| 857 | 850 | .CharacterLiteralClass => return transCharLiteral(rp, scope, @ptrCast(*const ZigClangCharacterLiteral, stmt), result_used), |
| 858 | 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 | 853 | else => { |
| 860 | 854 | return revertAndWarn( |
| 861 | 855 | rp, |
| ... | ... | @@ -1147,7 +1141,6 @@ fn transDeclRefExpr( |
| 1147 | 1141 | const value_decl = ZigClangDeclRefExpr_getDecl(expr); |
| 1148 | 1142 | const name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, value_decl))); |
| 1149 | 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 | 1144 | return transCreateNodeIdentifier(rp.c, checked_name); |
| 1152 | 1145 | } |
| 1153 | 1146 | |
| ... | ... | @@ -1990,6 +1983,18 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr, |
| 1990 | 1983 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); |
| 1991 | 1984 | } |
| 1992 | 1985 | |
| 1986 | fn 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 | ||
| 1993 | 1998 | fn transCPtrCast( |
| 1994 | 1999 | rp: RestorePoint, |
| 1995 | 2000 | loc: ZigClangSourceLocation, |
| ... | ... | @@ -2213,8 +2218,8 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC |
| 2213 | 2218 | import_fn_call.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 2214 | 2219 | |
| 2215 | 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"); | |
| 2217 | const log2int_fn_call = try transCreateNodeFnCall(rp.c, &outer_field_access.base); | |
| 2221 | const outer_field_access = try transCreateNodeFieldAccess(rp.c, inner_field_access, "Log2Int"); | |
| 2222 | const log2int_fn_call = try transCreateNodeFnCall(rp.c, outer_field_access); | |
| 2218 | 2223 | try @ptrCast(*ast.Node.SuffixOp.Op.Call, &log2int_fn_call.op).params.push(zig_type_node); |
| 2219 | 2224 | log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")"); |
| 2220 | 2225 | |
| ... | ... | @@ -2446,7 +2451,7 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp { |
| 2446 | 2451 | return node; |
| 2447 | 2452 | } |
| 2448 | 2453 | |
| 2449 | fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node.InfixOp { | |
| 2454 | fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node { | |
| 2450 | 2455 | const field_access_node = try c.a().create(ast.Node.InfixOp); |
| 2451 | 2456 | field_access_node.* = .{ |
| 2452 | 2457 | .op_token = try appendToken(c, .Period, "."), |
| ... | ... | @@ -2454,7 +2459,7 @@ fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []c |
| 2454 | 2459 | .op = .Period, |
| 2455 | 2460 | .rhs = try transCreateNodeIdentifier(c, field_name), |
| 2456 | 2461 | }; |
| 2457 | return field_access_node; | |
| 2462 | return &field_access_node.base; | |
| 2458 | 2463 | } |
| 2459 | 2464 | |
| 2460 | 2465 | fn transCreateNodePrefixOp( |
| ... | ... | @@ -2924,9 +2929,9 @@ fn transCreateNodeShiftOp( |
| 2924 | 2929 | rp: RestorePoint, |
| 2925 | 2930 | scope: *Scope, |
| 2926 | 2931 | stmt: *const ZigClangBinaryOperator, |
| 2927 | comptime op: ast.Node.InfixOp.Op, | |
| 2928 | comptime op_tok_id: std.zig.Token.Id, | |
| 2929 | comptime bytes: []const u8, | |
| 2932 | op: ast.Node.InfixOp.Op, | |
| 2933 | op_tok_id: std.zig.Token.Id, | |
| 2934 | bytes: []const u8, | |
| 2930 | 2935 | ) !*ast.Node { |
| 2931 | 2936 | std.debug.assert(op == .BitShiftLeft or op == .BitShiftRight); |
| 2932 | 2937 | |
| ... | ... | @@ -2957,6 +2962,16 @@ fn transCreateNodeShiftOp( |
| 2957 | 2962 | return &node.base; |
| 2958 | 2963 | } |
| 2959 | 2964 | |
| 2965 | fn 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 | ||
| 2960 | 2975 | const RestorePoint = struct { |
| 2961 | 2976 | c: *Context, |
| 2962 | 2977 | token_index: ast.TokenIndex, |
| ... | ... | @@ -3862,16 +3877,21 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 3862 | 3877 | .{}, |
| 3863 | 3878 | ); |
| 3864 | 3879 | |
| 3865 | const op_token = try appendToken(rp.c, .Period, "."); | |
| 3866 | const rhs = try transCreateNodeIdentifier(rp.c, name_tok.bytes); | |
| 3867 | const access_node = try rp.c.a().create(ast.Node.InfixOp); | |
| 3868 | access_node.* = .{ | |
| 3869 | .op_token = op_token, | |
| 3870 | .lhs = node, | |
| 3871 | .op = .Period, | |
| 3872 | .rhs = rhs, | |
| 3873 | }; | |
| 3874 | node = &access_node.base; | |
| 3880 | node = try transCreateNodeFieldAccess(rp.c, node, name_tok.bytes); | |
| 3881 | }, | |
| 3882 | .Arrow => { | |
| 3883 | const name_tok = it.next().?; | |
| 3884 | if (name_tok.id != .Identifier) | |
| 3885 | return revertAndWarn( | |
| 3886 | rp, | |
| 3887 | error.ParseError, | |
| 3888 | source_loc, | |
| 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 | 3896 | .Asterisk => { |
| 3877 | 3897 | if (it.peek().?.id == .RParen) { |
| ... | ... | @@ -3887,14 +3907,14 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 3887 | 3907 | // expr * expr |
| 3888 | 3908 | const op_token = try appendToken(rp.c, .Asterisk, "*"); |
| 3889 | 3909 | const rhs = try parseCPrimaryExpr(rp, it, source_loc, scope); |
| 3890 | const bitshift_node = try rp.c.a().create(ast.Node.InfixOp); | |
| 3891 | bitshift_node.* = .{ | |
| 3910 | const mul_node = try rp.c.a().create(ast.Node.InfixOp); | |
| 3911 | mul_node.* = .{ | |
| 3892 | 3912 | .op_token = op_token, |
| 3893 | 3913 | .lhs = node, |
| 3894 | 3914 | .op = .BitShiftLeft, |
| 3895 | 3915 | .rhs = rhs, |
| 3896 | 3916 | }; |
| 3897 | node = &bitshift_node.base; | |
| 3917 | node = &mul_node.base; | |
| 3898 | 3918 | } |
| 3899 | 3919 | }, |
| 3900 | 3920 | .Shl => { |
| ... | ... | @@ -3938,13 +3958,7 @@ fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 3938 | 3958 | }, |
| 3939 | 3959 | .Asterisk => { |
| 3940 | 3960 | const prefix_op_expr = try parseCPrefixOpExpr(rp, it, source_loc, scope); |
| 3941 | const node = try rp.c.a().create(ast.Node.SuffixOp); | |
| 3942 | node.* = .{ | |
| 3943 | .lhs = .{ .node = prefix_op_expr }, | |
| 3944 | .op = .Deref, | |
| 3945 | .rtoken = try appendToken(rp.c, .PeriodAsterisk, ".*"), | |
| 3946 | }; | |
| 3947 | return &node.base; | |
| 3961 | return try transCreateNodePtrDeref(rp.c, prefix_op_expr); | |
| 3948 | 3962 | }, |
| 3949 | 3963 | else => { |
| 3950 | 3964 | _ = it.prev(); |
test/translate_c.zig+45-16| ... | ... | @@ -1494,6 +1494,35 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1494 | 1494 | \\} |
| 1495 | 1495 | }); |
| 1496 | 1496 | |
| 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 | 1526 | /////////////// Cases for only stage1 which are TODO items for stage2 //////////////// |
| 1498 | 1527 | |
| 1499 | 1528 | cases.addAllowWarnings("simple data types", |
| ... | ... | @@ -1702,22 +1731,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1702 | 1731 | \\} |
| 1703 | 1732 | }); |
| 1704 | 1733 | |
| 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 | 1734 | cases.addC("array access", |
| 1722 | 1735 | \\int array[100]; |
| 1723 | 1736 | \\int foo(int index) { |
| ... | ... | @@ -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 | } |