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(const RecordKeeper
&Records
,
25 emitSourceFileHeader("A list of commands useable in documentation comments",
29 "const CommandInfo Commands[] = {\n";
30 ArrayRef
<const Record
*> Tags
= Records
.getAllDerivedDefinitions("Command");
31 for (size_t i
= 0, e
= Tags
.size(); i
!= e
; ++i
) {
32 const Record
&Tag
= *Tags
[i
];
34 << "\"" << Tag
.getValueAsString("Name") << "\", "
35 << "\"" << Tag
.getValueAsString("EndCommandName") << "\", " << i
<< ", "
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("IsParCommand") << ", "
47 << Tag
.getValueAsBit("IsEmptyParagraphAllowed") << ", "
48 << Tag
.getValueAsBit("IsVerbatimBlockCommand") << ", "
49 << Tag
.getValueAsBit("IsVerbatimBlockEndCommand") << ", "
50 << Tag
.getValueAsBit("IsVerbatimLineCommand") << ", "
51 << Tag
.getValueAsBit("IsDeclarationCommand") << ", "
52 << Tag
.getValueAsBit("IsFunctionDeclarationCommand") << ", "
53 << Tag
.getValueAsBit("IsRecordLikeDetailCommand") << ", "
54 << Tag
.getValueAsBit("IsRecordLikeDeclarationCommand") << ", "
55 << /* 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 const Record
&Tag
= *Tags
[i
];
66 std::string Name
= Tag
.getValueAsString("Name").str();
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(const RecordKeeper
&Records
,
117 emitSourceFileHeader("A list of commands useable in documentation comments",
120 OS
<< "#ifndef COMMENT_COMMAND\n"
121 << "# define COMMENT_COMMAND(NAME)\n"
124 ArrayRef
<const Record
*> Tags
= Records
.getAllDerivedDefinitions("Command");
125 for (size_t i
= 0, e
= Tags
.size(); i
!= e
; ++i
) {
126 const Record
&Tag
= *Tags
[i
];
127 std::string MangledName
= MangleName(Tag
.getValueAsString("Name"));
129 OS
<< "COMMENT_COMMAND(" << MangledName
<< ")\n";