1 //===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "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"
17 /// OptParserEmitter - This tablegen backend takes an input .td file
18 /// describing a list of options and emits a RST man page.
19 static void EmitOptRST(RecordKeeper
&Records
, raw_ostream
&OS
) {
20 llvm::StringMap
<std::vector
<Record
*>> OptionsByGroup
;
21 std::vector
<Record
*> OptionsWithoutGroup
;
24 std::vector
<Record
*> Opts
= Records
.getAllDerivedDefinitions("Option");
25 array_pod_sort(Opts
.begin(), Opts
.end(), CompareOptionRecords
);
27 // Get the option groups.
28 const std::vector
<Record
*> &Groups
=
29 Records
.getAllDerivedDefinitions("OptionGroup");
30 for (unsigned i
= 0, e
= Groups
.size(); i
!= e
; ++i
) {
31 const Record
&R
= *Groups
[i
];
32 OptionsByGroup
.try_emplace(R
.getValueAsString("Name"));
35 // Map options to their group.
36 for (unsigned i
= 0, e
= Opts
.size(); i
!= e
; ++i
) {
37 const Record
&R
= *Opts
[i
];
38 if (const DefInit
*DI
= dyn_cast
<DefInit
>(R
.getValueInit("Group"))) {
39 OptionsByGroup
[DI
->getDef()->getValueAsString("Name")].push_back(Opts
[i
]);
41 OptionsByGroup
["options"].push_back(Opts
[i
]);
45 // Print options under their group.
46 for (const auto &KV
: OptionsByGroup
) {
47 std::string GroupName
= KV
.getKey().upper();
48 OS
<< GroupName
<< '\n';
49 OS
<< std::string(GroupName
.size(), '-') << '\n';
52 for (Record
*R
: KV
.getValue()) {
56 std::vector
<StringRef
> Prefixes
= R
->getValueAsListOfStrings("Prefixes");
57 if (!Prefixes
.empty())
60 // Print the option name.
61 OS
<< R
->getValueAsString("Name");
63 StringRef MetaVarName
;
64 // Print the meta-variable.
65 if (!isa
<UnsetInit
>(R
->getValueInit("MetaVarName"))) {
66 MetaVarName
= R
->getValueAsString("MetaVarName");
67 } else if (!isa
<UnsetInit
>(R
->getValueInit("Values")))
68 MetaVarName
= "<value>";
70 if (!MetaVarName
.empty()) {
72 OS
.write_escaped(MetaVarName
);
78 // The option help text.
79 if (!isa
<UnsetInit
>(R
->getValueInit("HelpText"))) {
80 HelpText
= R
->getValueAsString("HelpText").trim().str();
81 if (!HelpText
.empty() && HelpText
.back() != '.')
82 HelpText
.push_back('.');
85 if (!isa
<UnsetInit
>(R
->getValueInit("Values"))) {
86 SmallVector
<StringRef
> Values
;
87 SplitString(R
->getValueAsString("Values"), Values
, ",");
88 HelpText
+= (" " + MetaVarName
+ " must be '").str();
90 if (Values
.size() > 1) {
91 HelpText
+= join(Values
.begin(), Values
.end() - 1, "', '");
94 HelpText
+= (Values
.front() + "'.").str();
97 if (!HelpText
.empty()) {
99 OS
.write_escaped(HelpText
);
106 static TableGen::Emitter::Opt
X("gen-opt-rst", EmitOptRST
,
107 "Generate option RST");