| 377 | } |
| 378 | |
| 379 | void TransformVarDecl(Parser *parser, Str *storage_class, |
| 380 | bool is_class, bool is_toplevel, DeclType decl_type) { |
| 381 | // We rewrite: VAR type a, b = init, c; |
| 382 | // as: |
| 383 | // storage_class type a; |
| 384 | // storage_class type b; |
| 385 | // static type b__INIT__; |
| 386 | // storage_class type c; |
| 387 | // Init(b, init); |
| 388 | State saved = parser->save(); |
| 389 | Int special_pos = parser->current_pos(); |
| 390 | parser->current().str = storage_class; // rewrite contents |
| 391 | parser->advance(); // skip past special token |
| 392 | parser->skip_while(SymsWS); |
| 393 | Int type_start = parser->current_pos(); |
| 394 | parser->advance(); |
| 395 | parser->skip_while(SymIdent | SymColonColon | SymsWS); |
| 396 | Int type_end = parser->current_pos(); |
| 397 | for(;;) { |
| 398 | Int var_pos = -1, var_start = -1, var_end = -1; |
| 399 | var_start = parser->current_pos(); |
| 400 | parser->skip_while(SymsTypePrefix | BIT(SymWS) | BIT(SymClass)); |
| 401 | if (TEST(SymsEndDecl | BIT(SymLBrkt), parser->current_sym())) { |
| 402 | // We are one symbol past the initial variable identifier. |
| 403 | var_pos = parser->find_back_until(BIT(SymIdent)); |
| 404 | var_end = var_pos + 1; |
| 405 | } else { |
| 406 | // We have a function pointer declaration |
| 407 | State tmp = parser->save(); |
| 408 | var_start = parser->current_pos(); |
| 409 | parser->skip_until(BIT(SymIdent)); |
| 410 | if (parser->current_sym() == SymIdent) |
| 411 | var_pos = parser->current_pos(); |
| 412 | parser->restore(tmp); |
| 413 | parser->safe_skip_until(SymsEndDecl); |
| 414 | var_end = parser->current_pos(); |
| 415 | } |
| 416 | Int init_start = -1, init_end = -1; |
| 417 | if (parser->current_sym() == SymEqual) { |
| 418 | init_start = parser->current_pos(); |
| 419 | parser->advance(); |
| 420 | parser->safe_skip_until(BIT(SymComma) | BIT(SymSemicolon)); |
| 421 | init_end = parser->current_pos(); |
| 422 | } |
| 423 | switch (parser->current_sym()) { |
| 424 | case SymComma: |
| 425 | EmitDecl(parser, storage_class, |
| 426 | type_start, type_end, var_start, var_end, |
| 427 | init_start, init_end, var_pos, is_class, is_toplevel, decl_type); |
| 428 | parser->advance(); |
| 429 | break; |
| 430 | case SymSemicolon: |
| 431 | EmitDecl(parser, storage_class, |
| 432 | type_start, type_end, var_start, var_end, |
| 433 | init_start, init_end, var_pos, is_class, is_toplevel, decl_type); |
| 434 | parser->advance(); |
| 435 | parser->mark(); |
| 436 | return; |
no test coverage detected