1480093f4SDimitry Andric //===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===// 2480093f4SDimitry Andric // 3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric // 7480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8480093f4SDimitry Andric 9480093f4SDimitry Andric #include "OptEmitter.h" 10480093f4SDimitry Andric #include "llvm/ADT/STLExtras.h" 11480093f4SDimitry Andric #include "llvm/ADT/SmallString.h" 12*5ffd83dbSDimitry Andric #include "llvm/ADT/StringMap.h" 13480093f4SDimitry Andric #include "llvm/ADT/Twine.h" 14480093f4SDimitry Andric #include "llvm/TableGen/Error.h" 15480093f4SDimitry Andric #include "llvm/TableGen/Record.h" 16480093f4SDimitry Andric #include "llvm/TableGen/TableGenBackend.h" 17480093f4SDimitry Andric #include <cctype> 18480093f4SDimitry Andric #include <cstring> 19480093f4SDimitry Andric #include <map> 20480093f4SDimitry Andric 21480093f4SDimitry Andric using namespace llvm; 22480093f4SDimitry Andric 23480093f4SDimitry Andric /// OptParserEmitter - This tablegen backend takes an input .td file 24480093f4SDimitry Andric /// describing a list of options and emits a RST man page. 25480093f4SDimitry Andric namespace llvm { 26480093f4SDimitry Andric void EmitOptRST(RecordKeeper &Records, raw_ostream &OS) { 27480093f4SDimitry Andric llvm::StringMap<std::vector<Record *>> OptionsByGroup; 28480093f4SDimitry Andric std::vector<Record *> OptionsWithoutGroup; 29480093f4SDimitry Andric 30480093f4SDimitry Andric // Get the options. 31480093f4SDimitry Andric std::vector<Record *> Opts = Records.getAllDerivedDefinitions("Option"); 32480093f4SDimitry Andric array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords); 33480093f4SDimitry Andric 34480093f4SDimitry Andric // Get the option groups. 35480093f4SDimitry Andric const std::vector<Record *> &Groups = 36480093f4SDimitry Andric Records.getAllDerivedDefinitions("OptionGroup"); 37480093f4SDimitry Andric for (unsigned i = 0, e = Groups.size(); i != e; ++i) { 38480093f4SDimitry Andric const Record &R = *Groups[i]; 39480093f4SDimitry Andric OptionsByGroup.try_emplace(R.getValueAsString("Name")); 40480093f4SDimitry Andric } 41480093f4SDimitry Andric 42480093f4SDimitry Andric // Map options to their group. 43480093f4SDimitry Andric for (unsigned i = 0, e = Opts.size(); i != e; ++i) { 44480093f4SDimitry Andric const Record &R = *Opts[i]; 45480093f4SDimitry Andric if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) { 46480093f4SDimitry Andric OptionsByGroup[DI->getDef()->getValueAsString("Name")].push_back(Opts[i]); 47480093f4SDimitry Andric } else { 48480093f4SDimitry Andric OptionsByGroup["options"].push_back(Opts[i]); 49480093f4SDimitry Andric } 50480093f4SDimitry Andric } 51480093f4SDimitry Andric 52480093f4SDimitry Andric // Print options under their group. 53480093f4SDimitry Andric for (const auto &KV : OptionsByGroup) { 54480093f4SDimitry Andric std::string GroupName = KV.getKey().upper(); 55480093f4SDimitry Andric OS << GroupName << '\n'; 56480093f4SDimitry Andric OS << std::string(GroupName.size(), '-') << '\n'; 57480093f4SDimitry Andric OS << '\n'; 58480093f4SDimitry Andric 59480093f4SDimitry Andric for (Record *R : KV.getValue()) { 60480093f4SDimitry Andric OS << ".. option:: "; 61480093f4SDimitry Andric 62480093f4SDimitry Andric // Print the prefix. 63480093f4SDimitry Andric std::vector<StringRef> Prefixes = R->getValueAsListOfStrings("Prefixes"); 64480093f4SDimitry Andric if (!Prefixes.empty()) 65480093f4SDimitry Andric OS << Prefixes[0]; 66480093f4SDimitry Andric 67480093f4SDimitry Andric // Print the option name. 68480093f4SDimitry Andric OS << R->getValueAsString("Name"); 69480093f4SDimitry Andric 70480093f4SDimitry Andric // Print the meta-variable. 71480093f4SDimitry Andric if (!isa<UnsetInit>(R->getValueInit("MetaVarName"))) { 72480093f4SDimitry Andric OS << '='; 73480093f4SDimitry Andric OS.write_escaped(R->getValueAsString("MetaVarName")); 74480093f4SDimitry Andric } 75480093f4SDimitry Andric 76480093f4SDimitry Andric OS << "\n\n"; 77480093f4SDimitry Andric 78480093f4SDimitry Andric // The option help text. 79480093f4SDimitry Andric if (!isa<UnsetInit>(R->getValueInit("HelpText"))) { 80480093f4SDimitry Andric OS << ' '; 81480093f4SDimitry Andric OS.write_escaped(R->getValueAsString("HelpText")); 82480093f4SDimitry Andric OS << "\n\n"; 83480093f4SDimitry Andric } 84480093f4SDimitry Andric } 85480093f4SDimitry Andric } 86480093f4SDimitry Andric } 87480093f4SDimitry Andric } // end namespace llvm 88