Skip to content

Commit ce16c3c

Browse files
committed
[Clang][Docs] Consolidate option hiding in ClangOptionDocEmitter
Update the `hasFlag` check to account for an Option's groups to better match how the option parsing logic works, and instead of checking if a group has include/exclude flags just check if there are any visible options in it. This cleans up some the empty sections that are currently emitted in clang's option docs. Differential Revision: https://reviews.llvm.org/D157146
1 parent 32870da commit ce16c3c

File tree

1 file changed

+36
-52
lines changed

1 file changed

+36
-52
lines changed

clang/utils/TableGen/ClangOptionDocEmitter.cpp

Lines changed: 36 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,41 @@ struct DocumentedGroup;
3131
struct Documentation {
3232
std::vector<DocumentedGroup> Groups;
3333
std::vector<DocumentedOption> Options;
34+
35+
bool empty() {
36+
return Groups.empty() && Options.empty();
37+
}
3438
};
3539
struct DocumentedGroup : Documentation {
3640
Record *Group;
3741
};
3842

43+
static bool hasFlag(const Record *Option, StringRef OptionFlag) {
44+
for (const Record *Flag : Option->getValueAsListOfDefs("Flags"))
45+
if (Flag->getName() == OptionFlag)
46+
return true;
47+
if (const DefInit *DI = dyn_cast<DefInit>(Option->getValueInit("Group")))
48+
for (const Record *Flag : DI->getDef()->getValueAsListOfDefs("Flags"))
49+
if (Flag->getName() == OptionFlag)
50+
return true;
51+
return false;
52+
}
53+
54+
static bool isOptionVisible(const Record *Option, const Record *DocInfo) {
55+
for (StringRef Exclusion : DocInfo->getValueAsListOfStrings("ExcludedFlags"))
56+
if (hasFlag(Option, Exclusion))
57+
return false;
58+
if (!DocInfo->getValue("IncludedFlags"))
59+
return true;
60+
for (StringRef Inclusion : DocInfo->getValueAsListOfStrings("IncludedFlags"))
61+
if (hasFlag(Option, Inclusion))
62+
return true;
63+
return false;
64+
}
65+
3966
// Reorganize the records into a suitable form for emitting documentation.
40-
Documentation extractDocumentation(RecordKeeper &Records) {
67+
Documentation extractDocumentation(RecordKeeper &Records,
68+
const Record *DocInfo) {
4169
Documentation Result;
4270

4371
// Build the tree of groups. The root in the tree is the fake option group
@@ -124,12 +152,15 @@ Documentation extractDocumentation(RecordKeeper &Records) {
124152
D.Groups.back().Group = G;
125153
Documentation &Base = D.Groups.back();
126154
Base = DocumentationForGroup(G);
155+
if (Base.empty())
156+
D.Groups.pop_back();
127157
}
128158

129159
auto &Options = OptionsInGroup[R];
130160
llvm::sort(Options, CompareByName);
131161
for (Record *O : Options)
132-
D.Options.push_back(DocumentationForOption(O));
162+
if (isOptionVisible(O, DocInfo))
163+
D.Options.push_back(DocumentationForOption(O));
133164

134165
return D;
135166
};
@@ -161,44 +192,6 @@ unsigned getNumArgsForKind(Record *OptionKind, const Record *Option) {
161192
.Default(0);
162193
}
163194

164-
bool hasFlag(const Record *OptionOrGroup, StringRef OptionFlag) {
165-
for (const Record *Flag : OptionOrGroup->getValueAsListOfDefs("Flags"))
166-
if (Flag->getName() == OptionFlag)
167-
return true;
168-
return false;
169-
}
170-
171-
bool isIncluded(const Record *OptionOrGroup, const Record *DocInfo) {
172-
assert(DocInfo->getValue("IncludedFlags") && "Missing includeFlags");
173-
for (StringRef Inclusion : DocInfo->getValueAsListOfStrings("IncludedFlags"))
174-
if (hasFlag(OptionOrGroup, Inclusion))
175-
return true;
176-
return false;
177-
}
178-
179-
bool isGroupIncluded(const DocumentedGroup &Group, const Record *DocInfo) {
180-
if (isIncluded(Group.Group, DocInfo))
181-
return true;
182-
for (auto &O : Group.Options)
183-
if (isIncluded(O.Option, DocInfo))
184-
return true;
185-
for (auto &G : Group.Groups) {
186-
if (isIncluded(G.Group, DocInfo))
187-
return true;
188-
if (isGroupIncluded(G, DocInfo))
189-
return true;
190-
}
191-
return false;
192-
}
193-
194-
bool isExcluded(const Record *OptionOrGroup, const Record *DocInfo) {
195-
// FIXME: Provide a flag to specify the set of exclusions.
196-
for (StringRef Exclusion : DocInfo->getValueAsListOfStrings("ExcludedFlags"))
197-
if (hasFlag(OptionOrGroup, Exclusion))
198-
return true;
199-
return false;
200-
}
201-
202195
std::string escapeRST(StringRef Str) {
203196
std::string Out;
204197
for (auto K : Str) {
@@ -319,16 +312,13 @@ void forEachOptionName(const DocumentedOption &Option, const Record *DocInfo,
319312
F(Option.Option);
320313

321314
for (auto *Alias : Option.Aliases)
322-
if (!isExcluded(Alias, DocInfo) && canSphinxCopeWithOption(Option.Option))
315+
if (isOptionVisible(Alias, DocInfo) &&
316+
canSphinxCopeWithOption(Option.Option))
323317
F(Alias);
324318
}
325319

326320
void emitOption(const DocumentedOption &Option, const Record *DocInfo,
327321
raw_ostream &OS) {
328-
if (isExcluded(Option.Option, DocInfo))
329-
return;
330-
if (DocInfo->getValue("IncludedFlags") && !isIncluded(Option.Option, DocInfo))
331-
return;
332322
if (Option.Option->getValueAsDef("Kind")->getName() == "KIND_UNKNOWN" ||
333323
Option.Option->getValueAsDef("Kind")->getName() == "KIND_INPUT")
334324
return;
@@ -401,12 +391,6 @@ void emitDocumentation(int Depth, const Documentation &Doc,
401391

402392
void emitGroup(int Depth, const DocumentedGroup &Group, const Record *DocInfo,
403393
raw_ostream &OS) {
404-
if (isExcluded(Group.Group, DocInfo))
405-
return;
406-
407-
if (DocInfo->getValue("IncludedFlags") && !isGroupIncluded(Group, DocInfo))
408-
return;
409-
410394
emitHeading(Depth,
411395
getRSTStringWithTextFallback(Group.Group, "DocName", "Name"), OS);
412396

@@ -440,5 +424,5 @@ void clang::EmitClangOptDocs(RecordKeeper &Records, raw_ostream &OS) {
440424
OS << DocInfo->getValueAsString("Intro") << "\n";
441425
OS << ".. program:: " << DocInfo->getValueAsString("Program") << "\n";
442426

443-
emitDocumentation(0, extractDocumentation(Records), DocInfo, OS);
427+
emitDocumentation(0, extractDocumentation(Records, DocInfo), DocInfo, OS);
444428
}

0 commit comments

Comments
 (0)