| 1468 | } // namespace |
| 1469 | |
| 1470 | tl::expected<ProcessArgsResult, core::Statistic> |
| 1471 | process_args(Context& ctx) |
| 1472 | { |
| 1473 | ASSERT(!ctx.orig_args.empty()); |
| 1474 | |
| 1475 | ArgsInfo& args_info = ctx.args_info; |
| 1476 | Config& config = ctx.config; |
| 1477 | |
| 1478 | ArgumentProcessingState state; |
| 1479 | |
| 1480 | std::optional<Statistic> argument_error; |
| 1481 | while (true) { |
| 1482 | // args is a copy of the original arguments given to the compiler but where |
| 1483 | // arguments from @file and similar constructs will be expanded. It's only |
| 1484 | // used as a temporary data structure to loop over. |
| 1485 | util::Args args = ctx.orig_args; |
| 1486 | args_info = {}; |
| 1487 | state = {}; |
| 1488 | argument_error = std::nullopt; |
| 1489 | |
| 1490 | state.add_common_arg(args[0]); // Compiler |
| 1491 | |
| 1492 | bool restart = false; |
| 1493 | for (size_t i = 1; i < args.size(); i++) { |
| 1494 | const auto statistic = |
| 1495 | process_arg(ctx, args_info, ctx.config, args, i, state, restart); |
| 1496 | if (restart) { |
| 1497 | break; |
| 1498 | } |
| 1499 | if (statistic != Statistic::none && !argument_error) { |
| 1500 | argument_error = statistic; |
| 1501 | } |
| 1502 | } |
| 1503 | |
| 1504 | if (!restart) { |
| 1505 | break; |
| 1506 | } |
| 1507 | } |
| 1508 | |
| 1509 | std::reverse(args_info.debug_prefix_maps.begin(), |
| 1510 | args_info.debug_prefix_maps.end()); |
| 1511 | std::reverse(args_info.coverage_prefix_maps.begin(), |
| 1512 | args_info.coverage_prefix_maps.end()); |
| 1513 | |
| 1514 | const bool is_link = |
| 1515 | !(state.found_c_opt || state.found_dc_opt || state.found_S_opt |
| 1516 | || state.found_syntax_only || state.found_analyze_opt); |
| 1517 | |
| 1518 | if (state.input_files.empty()) { |
| 1519 | LOG("No input file found"); |
| 1520 | return tl::unexpected(Statistic::no_input_file); |
| 1521 | } |
| 1522 | if (state.input_files.size() > 1) { |
| 1523 | if (is_link) { |
| 1524 | LOG("Called for link"); |
| 1525 | return tl::unexpected( |
| 1526 | util::pstr(state.input_files.front()).str().find("conftest.") |
| 1527 | != std::string::npos |
no test coverage detected