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 17 using namespace llvm; 18 using namespace jitlink; 19 20 #define DEBUG_TYPE "jitlink" 21 22 #define OPTTABLE_STR_TABLE_CODE 23 #include "COFFOptions.inc" 24 #undef OPTTABLE_STR_TABLE_CODE 25 26 #define OPTTABLE_PREFIXES_TABLE_CODE 27 #include "COFFOptions.inc" 28 #undef OPTTABLE_PREFIXES_TABLE_CODE 29 30 #define OPTTABLE_PREFIXES_UNION_CODE 31 #include "COFFOptions.inc" 32 #undef OPTTABLE_PREFIXES_UNION_CODE 33 34 // Create table mapping all options defined in COFFOptions.td 35 using namespace llvm::opt; 36 static constexpr opt::OptTable::Info infoTable[] = { 37 #define OPTION(...) \ 38 LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(COFF_OPT_, __VA_ARGS__), 39 #include "COFFOptions.inc" 40 #undef OPTION 41 }; 42 43 class COFFOptTable : public opt::PrecomputedOptTable { 44 public: 45 COFFOptTable() 46 : PrecomputedOptTable(OptionStrTable, OptionPrefixesTable, infoTable, 47 OptionPrefixesUnion, true) {} 48 }; 49 50 static COFFOptTable optTable; 51 52 Expected<opt::InputArgList> COFFDirectiveParser::parse(StringRef Str) { 53 SmallVector<StringRef, 16> Tokens; 54 SmallVector<const char *, 16> Buffer; 55 cl::TokenizeWindowsCommandLineNoCopy(Str, saver, Tokens); 56 for (StringRef Tok : Tokens) { 57 bool HasNul = Tok.end() != Str.end() && Tok.data()[Tok.size()] == '\0'; 58 Buffer.push_back(HasNul ? Tok.data() : saver.save(Tok).data()); 59 } 60 61 unsigned missingIndex; 62 unsigned missingCount; 63 64 auto Result = optTable.ParseArgs(Buffer, missingIndex, missingCount); 65 66 if (missingCount) 67 return make_error<JITLinkError>(Twine("COFF directive parsing failed: ") + 68 Result.getArgString(missingIndex) + 69 " missing argument"); 70 LLVM_DEBUG({ 71 for (auto *arg : Result.filtered(COFF_OPT_UNKNOWN)) 72 dbgs() << "Unknown coff option argument: " << arg->getAsString(Result) 73 << "\n"; 74 }); 75 return std::move(Result); 76 } 77