diff --git a/llvm/tools/llvm-ml/Opts.td b/llvm/tools/llvm-ml/Opts.td --- a/llvm/tools/llvm-ml/Opts.td +++ b/llvm/tools/llvm-ml/Opts.td @@ -45,6 +45,7 @@ def assembly_file : MLJoinedOrSeparate<"Ta">, HelpText<"Assemble source file with name not ending with " "the .asm extension">; +def parse_only : MLFlag<"Zs">, HelpText<"Run a syntax-check only">; def bitness : LLVMJoined<"m">, Values<"32,64">, HelpText<"Target platform (x86 or x86-64)">; @@ -107,4 +108,3 @@ def codeview_info : UnsupportedFlag<"Zi">, HelpText<"">; def enable_m510_option : UnsupportedFlag<"Zm">, HelpText<"">; def structure_packing : UnsupportedJoined<"Zp">, HelpText<"">; -def parse_only : UnsupportedFlag<"Zs">, HelpText<"">; diff --git a/llvm/tools/llvm-ml/llvm-ml.cpp b/llvm/tools/llvm-ml/llvm-ml.cpp --- a/llvm/tools/llvm-ml/llvm-ml.cpp +++ b/llvm/tools/llvm-ml/llvm-ml.cpp @@ -78,7 +78,7 @@ }; } // namespace -static Triple GetTriple(StringRef ProgName, opt::InputArgList &Args) { +static Triple GetTriple(StringRef ProgName, opt::ArgList &Args) { // Figure out the target triple. StringRef DefaultBitness = "32"; SmallString<255> Program = ProgName; @@ -128,7 +128,7 @@ SourceMgr &SrcMgr, MCContext &Ctx, MCStreamer &Str, MCAsmInfo &MAI, MCSubtargetInfo &STI, MCInstrInfo &MCII, MCTargetOptions &MCOptions, - const opt::ArgList &InputArgs) { + const opt::ArgList &Args) { std::unique_ptr Parser( createMCMasmParser(SrcMgr, Ctx, Str, MAI, 0)); std::unique_ptr TAP( @@ -140,14 +140,14 @@ return 1; } - Parser->setShowParsedOperands(InputArgs.hasArg(OPT_show_inst_operands)); + Parser->setShowParsedOperands(Args.hasArg(OPT_show_inst_operands)); Parser->setTargetParser(*TAP); Parser->getLexer().setLexMasmIntegers(true); Parser->getLexer().useMasmDefaultRadix(true); Parser->getLexer().setLexMasmHexFloats(true); Parser->getLexer().setLexMasmStrings(true); - auto Defines = InputArgs.getAllArgValues(OPT_define); + auto Defines = Args.getAllArgValues(OPT_define); for (StringRef Define : Defines) { const auto NameValue = Define.split('='); StringRef Name = NameValue.first, Value = NameValue.second; @@ -179,9 +179,14 @@ opt::InputArgList InputArgs = T.ParseArgs(ArgsArr, MissingArgIndex, MissingArgCount); + opt::DerivedArgList Args(InputArgs); + for (auto *Arg : InputArgs) { + Args.append(Arg); + } + std::string InputFilename; - for (auto *Arg : InputArgs.filtered(OPT_INPUT)) { - std::string ArgString = Arg->getAsString(InputArgs); + for (auto *Arg : Args.filtered(OPT_INPUT)) { + std::string ArgString = Arg->getAsString(Args); if (ArgString == "-" || StringRef(ArgString).endswith(".asm")) { if (!InputFilename.empty()) { WithColor::warning(errs(), ProgName) @@ -202,22 +207,22 @@ exit(1); } } - for (auto *Arg : InputArgs.filtered(OPT_assembly_file)) { + for (auto *Arg : Args.filtered(OPT_assembly_file)) { if (!InputFilename.empty()) { WithColor::warning(errs(), ProgName) << "does not support multiple assembly files in one command; " << "ignoring '" << InputFilename << "'\n"; } - InputFilename = Arg->getAsString(InputArgs); + InputFilename = Arg->getAsString(Args); } - for (auto *Arg : InputArgs.filtered(OPT_unsupported_Group)) { + for (auto *Arg : Args.filtered(OPT_unsupported_Group)) { WithColor::warning(errs(), ProgName) << "ignoring unsupported '" << Arg->getOption().getName() << "' option\n"; } - if (InputArgs.hasArg(OPT_help)) { + if (Args.hasArg(OPT_help)) { std::string Usage = llvm::formatv("{0} [ /options ] file", ProgName).str(); T.PrintHelp(outs(), Usage.c_str(), "LLVM MASM Assembler", /*ShowHidden=*/false); @@ -229,10 +234,13 @@ return 0; } + if (Args.hasArg(OPT_parse_only)) + Args.AddJoinedArg(nullptr, T.getOption(OPT_filetype), "null"); + MCTargetOptions MCOptions; MCOptions.AssemblyLanguage = "masm"; - Triple TheTriple = GetTriple(ProgName, InputArgs); + Triple TheTriple = GetTriple(ProgName, Args); std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget("", TheTriple, Error); if (!TheTarget) { @@ -241,7 +249,7 @@ } const std::string &TripleName = TheTriple.getTriple(); - bool SafeSEH = InputArgs.hasArg(OPT_safeseh); + bool SafeSEH = Args.hasArg(OPT_safeseh); if (SafeSEH && !(TheTriple.isArch32Bit() && TheTriple.isX86())) { WithColor::warning() << "/safeseh applies only to 32-bit X86 platforms; ignoring.\n"; @@ -263,7 +271,7 @@ // Record the location of the include directories so that the lexer can find // it later. - SrcMgr.setIncludeDirs(InputArgs.getAllArgValues(OPT_include_path)); + SrcMgr.setIncludeDirs(Args.getAllArgValues(OPT_include_path)); std::unique_ptr MRI(TheTarget->createMCRegInfo(TripleName)); assert(MRI && "Unable to create target register info!"); @@ -272,7 +280,7 @@ TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); assert(MAI && "Unable to create target asm info!"); - MAI->setPreserveAsmComments(InputArgs.hasArg(OPT_preserve_comments)); + MAI->setPreserveAsmComments(Args.hasArg(OPT_preserve_comments)); // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and // MCObjectFileInfo needs a MCContext reference in order to initialize itself. @@ -281,7 +289,7 @@ MOFI.InitMCObjectFileInfo(TheTriple, /*PIC=*/false, Ctx, /*LargeCodeModel=*/true); - if (InputArgs.hasArg(OPT_save_temp_labels)) + if (Args.hasArg(OPT_save_temp_labels)) Ctx.setAllowTemporaryLabels(false); // Set compilation information. @@ -290,16 +298,16 @@ Ctx.setCompilationDir(CWD); Ctx.setMainFileName(InputFilename); - StringRef FileType = InputArgs.getLastArgValue(OPT_filetype, "obj"); + StringRef FileType = Args.getLastArgValue(OPT_filetype, "obj"); SmallString<255> DefaultOutputFilename; - if (InputArgs.hasArg(OPT_as_lex)) { + if (Args.hasArg(OPT_as_lex)) { DefaultOutputFilename = "-"; } else { DefaultOutputFilename = InputFilename; sys::path::replace_extension(DefaultOutputFilename, FileType); } const StringRef OutputFilename = - InputArgs.getLastArgValue(OPT_output_file, DefaultOutputFilename); + Args.getLastArgValue(OPT_output_file, DefaultOutputFilename); std::unique_ptr Out = GetOutputStream(OutputFilename); if (!Out) return 1; @@ -317,7 +325,7 @@ MCInstPrinter *IP = nullptr; if (FileType == "s") { - const bool OutputATTAsm = InputArgs.hasArg(OPT_output_att_asm); + const bool OutputATTAsm = Args.hasArg(OPT_output_att_asm); const unsigned OutputAsmVariant = OutputATTAsm ? 0U // ATT dialect : 1U; // Intel dialect IP = TheTarget->createMCInstPrinter(TheTriple, OutputAsmVariant, *MAI, @@ -332,11 +340,11 @@ } // Set the display preference for hex vs. decimal immediates. - IP->setPrintImmHex(InputArgs.hasArg(OPT_print_imm_hex)); + IP->setPrintImmHex(Args.hasArg(OPT_print_imm_hex)); // Set up the AsmStreamer. std::unique_ptr CE; - if (InputArgs.hasArg(OPT_show_encoding)) + if (Args.hasArg(OPT_show_encoding)) CE.reset(TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx)); std::unique_ptr MAB( @@ -345,7 +353,7 @@ Str.reset(TheTarget->createAsmStreamer( Ctx, std::move(FOut), /*asmverbose*/ true, /*useDwarfDirectory*/ true, IP, std::move(CE), std::move(MAB), - InputArgs.hasArg(OPT_show_inst))); + Args.hasArg(OPT_show_inst))); } else if (FileType == "null") { Str.reset(TheTarget->createNullStreamer(Ctx)); @@ -387,12 +395,12 @@ Str->setUseAssemblerInfoForParsing(true); int Res = 1; - if (InputArgs.hasArg(OPT_as_lex)) { + if (Args.hasArg(OPT_as_lex)) { // -as-lex; Lex only, and output a stream of tokens Res = AsLexInput(SrcMgr, *MAI, Out->os()); } else { Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, - *MCII, MCOptions, InputArgs); + *MCII, MCOptions, Args); } // Keep output if no errors.