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