COFFDirectiveParser.cpp 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. #include "COFFDirectiveParser.h"
  13. #include <array>
  14. using namespace llvm;
  15. using namespace jitlink;
  16. #define DEBUG_TYPE "jitlink"
  17. // Create prefix string literals used in Options.td
  18. #define PREFIX(NAME, VALUE) \
  19. static constexpr StringLiteral NAME##_init[] = VALUE; \
  20. static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
  21. std::size(NAME##_init) - 1);
  22. #include "COFFOptions.inc"
  23. #undef PREFIX
  24. static constexpr const StringLiteral PrefixTable_init[] =
  25. #define PREFIX_UNION(VALUES) VALUES
  26. #include "COFFOptions.inc"
  27. #undef PREFIX_UNION
  28. ;
  29. static constexpr const ArrayRef<StringLiteral>
  30. PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1);
  31. // Create table mapping all options defined in COFFOptions.td
  32. static constexpr opt::OptTable::Info infoTable[] = {
  33. #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
  34. {X1, \
  35. X2, \
  36. X10, \
  37. X11, \
  38. COFF_OPT_##ID, \
  39. opt::Option::KIND##Class, \
  40. X9, \
  41. X8, \
  42. COFF_OPT_##GROUP, \
  43. COFF_OPT_##ALIAS, \
  44. X7, \
  45. X12},
  46. #include "COFFOptions.inc"
  47. #undef OPTION
  48. };
  49. class COFFOptTable : public opt::PrecomputedOptTable {
  50. public:
  51. COFFOptTable() : PrecomputedOptTable(infoTable, PrefixTable, true) {}
  52. };
  53. static COFFOptTable optTable;
  54. Expected<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. unsigned missingIndex;
  63. unsigned missingCount;
  64. auto Result = optTable.ParseArgs(Buffer, missingIndex, missingCount);
  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. }