diff options
Diffstat (limited to 'llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp')
| -rw-r--r-- | llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp b/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp new file mode 100644 index 000000000000..30c1579a1ba0 --- /dev/null +++ b/llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp @@ -0,0 +1,88 @@ +//===-- 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 <array> + +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<StringLiteral> 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<StringLiteral> + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + +// Create table mapping all options defined in COFFOptions.td +static constexpr opt::OptTable::Info infoTable[] = { +#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ + {X1, \ + X2, \ + X10, \ + X11, \ + COFF_OPT_##ID, \ + opt::Option::KIND##Class, \ + X9, \ + X8, \ + COFF_OPT_##GROUP, \ + COFF_OPT_##ALIAS, \ + X7, \ + X12}, +#include "COFFOptions.inc" +#undef OPTION +}; + +class COFFOptTable : public opt::PrecomputedOptTable { +public: + COFFOptTable() : PrecomputedOptTable(infoTable, PrefixTable, true) {} +}; + +static COFFOptTable optTable; + +Expected<opt::InputArgList> COFFDirectiveParser::parse(StringRef Str) { + SmallVector<StringRef, 16> Tokens; + SmallVector<const char *, 16> 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<JITLinkError>(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); +} |
