1//===-- COFFDirectiveParser.cpp - JITLink coff directive parser --*- C++ -*===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// MSVC COFF directive parser 10// 11//===----------------------------------------------------------------------===// 12 13#include "COFFDirectiveParser.h" 14 15#include <array> 16 17using namespace llvm; 18using namespace jitlink; 19 20#define DEBUG_TYPE "jitlink" 21 22// Create prefix string literals used in Options.td 23#define PREFIX(NAME, VALUE) \ 24 static constexpr StringLiteral NAME##_init[] = VALUE; \ 25 static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ 26 std::size(NAME##_init) - 1); 27#include "COFFOptions.inc" 28#undef PREFIX 29 30static constexpr const StringLiteral PrefixTable_init[] = 31#define PREFIX_UNION(VALUES) VALUES 32#include "COFFOptions.inc" 33#undef PREFIX_UNION 34 ; 35static constexpr const ArrayRef<StringLiteral> 36 PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); 37 38// Create table mapping all options defined in COFFOptions.td 39using namespace llvm::opt; 40static constexpr opt::OptTable::Info infoTable[] = { 41#define OPTION(...) \ 42 LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(COFF_OPT_, __VA_ARGS__), 43#include "COFFOptions.inc" 44#undef OPTION 45}; 46 47class COFFOptTable : public opt::PrecomputedOptTable { 48public: 49 COFFOptTable() : PrecomputedOptTable(infoTable, PrefixTable, true) {} 50}; 51 52static COFFOptTable optTable; 53 54Expected<opt::InputArgList> COFFDirectiveParser::parse(StringRef Str) { 55 SmallVector<StringRef, 16> Tokens; 56 SmallVector<const char *, 16> Buffer; 57 cl::TokenizeWindowsCommandLineNoCopy(Str, saver, Tokens); 58 for (StringRef Tok : Tokens) { 59 bool HasNul = Tok.end() != Str.end() && Tok.data()[Tok.size()] == '\0'; 60 Buffer.push_back(HasNul ? Tok.data() : saver.save(Tok).data()); 61 } 62 63 unsigned missingIndex; 64 unsigned missingCount; 65 66 auto Result = optTable.ParseArgs(Buffer, missingIndex, missingCount); 67 68 if (missingCount) 69 return make_error<JITLinkError>(Twine("COFF directive parsing failed: ") + 70 Result.getArgString(missingIndex) + 71 " missing argument"); 72 LLVM_DEBUG({ 73 for (auto *arg : Result.filtered(COFF_OPT_UNKNOWN)) 74 dbgs() << "Unknown coff option argument: " << arg->getAsString(Result) 75 << "\n"; 76 }); 77 return std::move(Result); 78} 79