//===-- COFFDirectiveParser.cpp - JITLink coff directive parser --*- C++ -*===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // MSVC COFF directive parser // //===----------------------------------------------------------------------===// #include "COFFDirectiveParser.h" #include using namespace llvm; using namespace jitlink; #define DEBUG_TYPE "jitlink" // Create prefix string literals used in Options.td #define PREFIX(NAME, VALUE) \ static constexpr StringLiteral NAME##_init[] = VALUE; \ static constexpr ArrayRef NAME(NAME##_init, \ std::size(NAME##_init) - 1); #include "COFFOptions.inc" #undef PREFIX static constexpr const StringLiteral PrefixTable_init[] = #define PREFIX_UNION(VALUES) VALUES #include "COFFOptions.inc" #undef PREFIX_UNION ; static constexpr const ArrayRef PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); // Create table mapping all options defined in COFFOptions.td using namespace llvm::opt; static constexpr opt::OptTable::Info infoTable[] = { #define OPTION(...) \ LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(COFF_OPT_, __VA_ARGS__), #include "COFFOptions.inc" #undef OPTION }; class COFFOptTable : public opt::PrecomputedOptTable { public: COFFOptTable() : PrecomputedOptTable(infoTable, PrefixTable, true) {} }; static COFFOptTable optTable; Expected COFFDirectiveParser::parse(StringRef Str) { SmallVector Tokens; SmallVector Buffer; cl::TokenizeWindowsCommandLineNoCopy(Str, saver, Tokens); for (StringRef Tok : Tokens) { bool HasNul = Tok.end() != Str.end() && Tok.data()[Tok.size()] == '\0'; Buffer.push_back(HasNul ? Tok.data() : saver.save(Tok).data()); } unsigned missingIndex; unsigned missingCount; auto Result = optTable.ParseArgs(Buffer, missingIndex, missingCount); if (missingCount) return make_error(Twine("COFF directive parsing failed: ") + Result.getArgString(missingIndex) + " missing argument"); LLVM_DEBUG({ for (auto *arg : Result.filtered(COFF_OPT_UNKNOWN)) dbgs() << "Unknown coff option argument: " << arg->getAsString(Result) << "\n"; }); return std::move(Result); }