Repository: JuliaLang/julia
File: src/pipeline.cpp (C++)

Code before:
                AA.registerFunctionAnalysis<ScopedNoAliasAA>();
                AA.registerFunctionAnalysis<TypeBasedAA>();
            }
            TM.registerDefaultAliasAnalyses(AA);
            return AA;
        });
        // Register our TargetLibraryInfoImpl.
        FAM.registerPass([&] JL_NOTSAFEPOINT { return llvm::TargetIRAnalysis(TM.getTargetIRAnalysis()); });
        FAM.registerPass([&] JL_NOTSAFEPOINT { return llvm::TargetLibraryAnalysis(llvm::TargetLibraryInfoImpl(TM.getTargetTriple())); });
        return FAM;
    }

    ModulePassManager createMPM(PassBuilder &PB, OptimizationLevel O, OptimizationOptions options) JL_NOTSAFEPOINT {
        ModulePassManager MPM;
        buildPipeline(MPM, &PB, O, options);
        return MPM;
    }
}

// Parse LLVM-style option string into PrintOptions
void parseLLVMOptions(const char *options, PrintOptions &out) {
    if (!options || options[0] == '\0')
        return;

    std::string opts(options);
    // Simple parser for common options
    if (opts.find("-print-after-all") != std::string::npos)
        out.print_after_all = true;
    if (opts.find("-print-before-all") != std::string::npos)
        out.print_before_all = true;
    if (opts.find("-print-module-scope") != std::string::npos)
        out.print_module_scope = true;
    if (opts.find("-print-changed") != std::string::npos)
        out.print_changed = true;

    // Parse -print-after=PASSNAME
    auto pos = opts.find("-print-after=");
    if (pos != std::string::npos) {
        auto start = pos + 13;
        auto end = opts.find_first_of(" \t\n", start);
        if (end == std::string::npos)
            end = opts.size();
        out.print_after = opts.substr(start, end - start);
    }

    // Parse -print-before=PASSNAME
    pos = opts.find("-print-before=");
    if (pos != std::string::npos) {
        auto start = pos + 14;
        auto end = opts.find_first_of(" \t\n", start);
        if (end == std::string::npos)

Review comment (suggestion):
Please use a real parser (even if it is just getopt) and not this claude garbage. If we want to act like LLVM, it should use the function structure here: https://llvm.org/doxygen/CommandLine_8cpp_source.html#l01462

e.g. tokenization by [TokenizeGNUCommandLine](https://llvm.org/doxygen/namespacellvm_1_1cl.html#aff28c3d477d3a7870ec643381f186ed4)

and then preferably make a custom CommandLineParser instance, although you could iterate them manually, it is kinda painful to implement correctly. You could potentially steal the option definitions from the GlobalParser (we do that elsewhere in codegen.cpp to forcibly set/clear some manually), but that isn't as important.

Code after:
                AA.registerFunctionAnalysis<BasicAA>();
                AA.registerFunctionAnalysis<ScopedNoAliasAA>();
                AA.registerFunctionAnalysis<TypeBasedAA>();
            }
            TM.registerDefaultAliasAnalyses(AA);
            return AA;
        });
        // Register our TargetLibraryInfoImpl.
        FAM.registerPass([&] JL_NOTSAFEPOINT { return llvm::TargetIRAnalysis(TM.getTargetIRAnalysis()); });
        FAM.registerPass([&] JL_NOTSAFEPOINT { return llvm::TargetLibraryAnalysis(llvm::TargetLibraryInfoImpl(TM.getTargetTriple())); });
        return FAM;
    }

    ModulePassManager createMPM(PassBuilder &PB, OptimizationLevel O, OptimizationOptions options) JL_NOTSAFEPOINT {
        ModulePassManager MPM;
        buildPipeline(MPM, &PB, O, options);
        return MPM;
    }
}

// Parse LLVM-style option string into PrintOptions using LLVM's tokenizer
void parseLLVMOptions(const char *options, PrintOptions &out) JL_NOTSAFEPOINT {
    if (!options || options[0] == '\0')
        return;

    // Tokenize the options string using LLVM's GNU command line tokenizer
    BumpPtrAllocator Alloc;
    StringSaver Saver(Alloc);
    SmallVector<const char *, 16> Argv;
    cl::TokenizeGNUCommandLine(options, Saver, Argv);

    // Helper to match an option and get its value
    // option should include trailing "=" (e.g., "-print-after=")
    // Returns the value if matched, empty StringRef if no match
    // Supports both "-option=value" and "-option value" syntax
    auto getNextValue = [&](size_t &idx, StringRef Arg, StringRef option) JL_NOTSAFEPOINT -> StringRef {
        StringRef optionName = option.drop_back(); // remove trailing "="
        // Check for "-option=value" syntax
        if (Arg.starts_with(option)) {
            return Arg.substr(option.size());
        }
        // Check for "-option value" syntax (exact match on option name)
        if (Arg == optionName) {
            if (idx + 1 < Argv.size()) {
                return StringRef(Argv[++idx]);
            }
            raw_string_ostream err_stream(out.error);
            err_stream << "Warning: " << optionName << " requires a value\n";
        }
        return StringRef();
    };