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