llvm-project
107 строк · 3.5 Кб
1//===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===//
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#include "Common/OptEmitter.h"10#include "llvm/ADT/STLExtras.h"11#include "llvm/ADT/StringMap.h"12#include "llvm/TableGen/Record.h"13#include "llvm/TableGen/TableGenBackend.h"14
15using namespace llvm;16
17/// OptParserEmitter - This tablegen backend takes an input .td file
18/// describing a list of options and emits a RST man page.
19static void EmitOptRST(RecordKeeper &Records, raw_ostream &OS) {20llvm::StringMap<std::vector<Record *>> OptionsByGroup;21std::vector<Record *> OptionsWithoutGroup;22
23// Get the options.24std::vector<Record *> Opts = Records.getAllDerivedDefinitions("Option");25array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords);26
27// Get the option groups.28const std::vector<Record *> &Groups =29Records.getAllDerivedDefinitions("OptionGroup");30for (unsigned i = 0, e = Groups.size(); i != e; ++i) {31const Record &R = *Groups[i];32OptionsByGroup.try_emplace(R.getValueAsString("Name"));33}34
35// Map options to their group.36for (unsigned i = 0, e = Opts.size(); i != e; ++i) {37const Record &R = *Opts[i];38if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) {39OptionsByGroup[DI->getDef()->getValueAsString("Name")].push_back(Opts[i]);40} else {41OptionsByGroup["options"].push_back(Opts[i]);42}43}44
45// Print options under their group.46for (const auto &KV : OptionsByGroup) {47std::string GroupName = KV.getKey().upper();48OS << GroupName << '\n';49OS << std::string(GroupName.size(), '-') << '\n';50OS << '\n';51
52for (Record *R : KV.getValue()) {53OS << ".. option:: ";54
55// Print the prefix.56std::vector<StringRef> Prefixes = R->getValueAsListOfStrings("Prefixes");57if (!Prefixes.empty())58OS << Prefixes[0];59
60// Print the option name.61OS << R->getValueAsString("Name");62
63StringRef MetaVarName;64// Print the meta-variable.65if (!isa<UnsetInit>(R->getValueInit("MetaVarName"))) {66MetaVarName = R->getValueAsString("MetaVarName");67} else if (!isa<UnsetInit>(R->getValueInit("Values")))68MetaVarName = "<value>";69
70if (!MetaVarName.empty()) {71OS << '=';72OS.write_escaped(MetaVarName);73}74
75OS << "\n\n";76
77std::string HelpText;78// The option help text.79if (!isa<UnsetInit>(R->getValueInit("HelpText"))) {80HelpText = R->getValueAsString("HelpText").trim().str();81if (!HelpText.empty() && HelpText.back() != '.')82HelpText.push_back('.');83}84
85if (!isa<UnsetInit>(R->getValueInit("Values"))) {86SmallVector<StringRef> Values;87SplitString(R->getValueAsString("Values"), Values, ",");88HelpText += (" " + MetaVarName + " must be '").str();89
90if (Values.size() > 1) {91HelpText += join(Values.begin(), Values.end() - 1, "', '");92HelpText += "' or '";93}94HelpText += (Values.back() + "'.").str();95}96
97if (!HelpText.empty()) {98OS << ' ';99OS.write_escaped(HelpText);100OS << "\n\n";101}102}103}104}
105
106static TableGen::Emitter::Opt X("gen-opt-rst", EmitOptRST,107"Generate option RST");108