1 //===--- ClangCommentCommandInfoEmitter.cpp - Generate command lists -----====//
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 // This tablegen backend emits command lists and efficient matchers for command
10 // names that are used in documentation comments.
12 //===----------------------------------------------------------------------===//
14 #include "TableGenBackends.h"
16 #include "llvm/TableGen/Record.h"
17 #include "llvm/TableGen/StringMatcher.h"
18 #include "llvm/TableGen/TableGenBackend.h"
23 void clang::EmitClangCommentCommandInfo(RecordKeeper
&Records
, raw_ostream
&OS
) {
24 emitSourceFileHeader("A list of commands useable in documentation "
28 "const CommandInfo Commands[] = {\n";
29 std::vector
<Record
*> Tags
= Records
.getAllDerivedDefinitions("Command");
30 for (size_t i
= 0, e
= Tags
.size(); i
!= e
; ++i
) {
31 Record
&Tag
= *Tags
[i
];
33 << "\"" << Tag
.getValueAsString("Name") << "\", "
34 << "\"" << Tag
.getValueAsString("EndCommandName") << "\", "
36 << Tag
.getValueAsInt("NumArgs") << ", "
37 << Tag
.getValueAsBit("IsInlineCommand") << ", "
38 << Tag
.getValueAsBit("IsBlockCommand") << ", "
39 << Tag
.getValueAsBit("IsBriefCommand") << ", "
40 << Tag
.getValueAsBit("IsReturnsCommand") << ", "
41 << Tag
.getValueAsBit("IsParamCommand") << ", "
42 << Tag
.getValueAsBit("IsTParamCommand") << ", "
43 << Tag
.getValueAsBit("IsThrowsCommand") << ", "
44 << Tag
.getValueAsBit("IsDeprecatedCommand") << ", "
45 << Tag
.getValueAsBit("IsHeaderfileCommand") << ", "
46 << Tag
.getValueAsBit("IsEmptyParagraphAllowed") << ", "
47 << Tag
.getValueAsBit("IsVerbatimBlockCommand") << ", "
48 << Tag
.getValueAsBit("IsVerbatimBlockEndCommand") << ", "
49 << Tag
.getValueAsBit("IsVerbatimLineCommand") << ", "
50 << Tag
.getValueAsBit("IsDeclarationCommand") << ", "
51 << Tag
.getValueAsBit("IsFunctionDeclarationCommand") << ", "
52 << Tag
.getValueAsBit("IsRecordLikeDetailCommand") << ", "
53 << Tag
.getValueAsBit("IsRecordLikeDeclarationCommand") << ", "
54 << /* IsUnknownCommand = */ "0"
61 "} // unnamed namespace\n\n";
63 std::vector
<StringMatcher::StringPair
> Matches
;
64 for (size_t i
= 0, e
= Tags
.size(); i
!= e
; ++i
) {
65 Record
&Tag
= *Tags
[i
];
66 std::string Name
= std::string(Tag
.getValueAsString("Name"));
68 raw_string_ostream(Return
) << "return &Commands[" << i
<< "];";
69 Matches
.emplace_back(std::move(Name
), std::move(Return
));
72 OS
<< "const CommandInfo *CommandTraits::getBuiltinCommandInfo(\n"
73 << " StringRef Name) {\n";
74 StringMatcher("Name", Matches
, OS
).Emit();
75 OS
<< " return nullptr;\n"
79 static std::string
MangleName(StringRef Str
) {
81 for (unsigned i
= 0, e
= Str
.size(); i
!= e
; ++i
) {
115 void clang::EmitClangCommentCommandList(RecordKeeper
&Records
, raw_ostream
&OS
) {
116 emitSourceFileHeader("A list of commands useable in documentation "
119 OS
<< "#ifndef COMMENT_COMMAND\n"
120 << "# define COMMENT_COMMAND(NAME)\n"
123 std::vector
<Record
*> Tags
= Records
.getAllDerivedDefinitions("Command");
124 for (size_t i
= 0, e
= Tags
.size(); i
!= e
; ++i
) {
125 Record
&Tag
= *Tags
[i
];
126 std::string MangledName
= MangleName(Tag
.getValueAsString("Name"));
128 OS
<< "COMMENT_COMMAND(" << MangledName
<< ")\n";