| 1362 | } |
| 1363 | |
| 1364 | static void parse_fn(Function &f) { |
| 1365 | fn = &f; |
| 1366 | bb = &f.getBB(""); |
| 1367 | bool has_return = false; |
| 1368 | |
| 1369 | while (true) { |
| 1370 | switch (auto t = *tokenizer) { |
| 1371 | case ASSUME: |
| 1372 | bb->addInstr(parse_assume()); |
| 1373 | break; |
| 1374 | case LABEL: |
| 1375 | bb = &f.getBB(yylval.str); |
| 1376 | break; |
| 1377 | case RETURN: { |
| 1378 | auto instr = parse_return(); |
| 1379 | f.setType(instr->getType()); |
| 1380 | bb->addInstr(std::move(instr)); |
| 1381 | has_return = true; |
| 1382 | break; |
| 1383 | } |
| 1384 | case UNREACH: |
| 1385 | bb->addInstr(make_unique<Assume>(get_constant(0, *int_types[1].get()), |
| 1386 | Assume::AndNonPoison)); |
| 1387 | break; |
| 1388 | default: |
| 1389 | string_view name; |
| 1390 | if (t == REGISTER) { |
| 1391 | name = yylval.str; |
| 1392 | tokenizer.ensure(EQUALS); |
| 1393 | } else |
| 1394 | tokenizer.unget(t); |
| 1395 | |
| 1396 | auto i = parse_instr(name); |
| 1397 | if (!i) { |
| 1398 | if (name.empty()) |
| 1399 | goto exit; |
| 1400 | error("Instruction expected", *tokenizer); |
| 1401 | } |
| 1402 | |
| 1403 | if (!name.empty()) { |
| 1404 | if (!identifiers.emplace(name, i.get()).second) |
| 1405 | error("Duplicated assignment to " + string(name)); |
| 1406 | } |
| 1407 | bb->addInstr(std::move(i)); |
| 1408 | break; |
| 1409 | } |
| 1410 | } |
| 1411 | |
| 1412 | exit: |
| 1413 | if (!has_return) { |
| 1414 | if (bb->empty()) |
| 1415 | error("Block cannot be empty"); |
| 1416 | |
| 1417 | auto &val = bb->back(); |
| 1418 | bb->addInstr(make_unique<Return>(val.getType(), val)); |
| 1419 | f.setType(val.getType()); |
| 1420 | } |
| 1421 | } |
no test coverage detected