1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include "llvm/TableGen/Record.h" |
15 | #include "llvm/TableGen/StringMatcher.h" |
16 | #include "llvm/TableGen/TableGenBackend.h" |
17 | #include <vector> |
18 | |
19 | using namespace llvm; |
20 | |
21 | namespace clang { |
22 | void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) { |
23 | emitSourceFileHeader("A list of commands useable in documentation " |
24 | "comments", OS); |
25 | |
26 | OS << "namespace {\n" |
27 | "const CommandInfo Commands[] = {\n"; |
28 | std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Command"); |
29 | for (size_t i = 0, e = Tags.size(); i != e; ++i) { |
30 | Record &Tag = *Tags[i]; |
31 | OS << " { " |
32 | << "\"" << Tag.getValueAsString("Name") << "\", " |
33 | << "\"" << Tag.getValueAsString("EndCommandName") << "\", " |
34 | << i << ", " |
35 | << Tag.getValueAsInt("NumArgs") << ", " |
36 | << Tag.getValueAsBit("IsInlineCommand") << ", " |
37 | << Tag.getValueAsBit("IsBlockCommand") << ", " |
38 | << Tag.getValueAsBit("IsBriefCommand") << ", " |
39 | << Tag.getValueAsBit("IsReturnsCommand") << ", " |
40 | << Tag.getValueAsBit("IsParamCommand") << ", " |
41 | << Tag.getValueAsBit("IsTParamCommand") << ", " |
42 | << Tag.getValueAsBit("IsThrowsCommand") << ", " |
43 | << Tag.getValueAsBit("IsDeprecatedCommand") << ", " |
44 | << Tag.getValueAsBit("IsHeaderfileCommand") << ", " |
45 | << Tag.getValueAsBit("IsEmptyParagraphAllowed") << ", " |
46 | << Tag.getValueAsBit("IsVerbatimBlockCommand") << ", " |
47 | << Tag.getValueAsBit("IsVerbatimBlockEndCommand") << ", " |
48 | << Tag.getValueAsBit("IsVerbatimLineCommand") << ", " |
49 | << Tag.getValueAsBit("IsDeclarationCommand") << ", " |
50 | << Tag.getValueAsBit("IsFunctionDeclarationCommand") << ", " |
51 | << Tag.getValueAsBit("IsRecordLikeDetailCommand") << ", " |
52 | << Tag.getValueAsBit("IsRecordLikeDeclarationCommand") << ", " |
53 | << "0" |
54 | << " }"; |
55 | if (i + 1 != e) |
56 | OS << ","; |
57 | OS << "\n"; |
58 | } |
59 | OS << "};\n" |
60 | "} // unnamed namespace\n\n"; |
61 | |
62 | std::vector<StringMatcher::StringPair> Matches; |
63 | for (size_t i = 0, e = Tags.size(); i != e; ++i) { |
64 | Record &Tag = *Tags[i]; |
65 | std::string Name = Tag.getValueAsString("Name"); |
66 | std::string Return; |
67 | raw_string_ostream(Return) << "return &Commands[" << i << "];"; |
68 | Matches.emplace_back(std::move(Name), std::move(Return)); |
69 | } |
70 | |
71 | OS << "const CommandInfo *CommandTraits::getBuiltinCommandInfo(\n" |
72 | << " StringRef Name) {\n"; |
73 | StringMatcher("Name", Matches, OS).Emit(); |
74 | OS << " return nullptr;\n" |
75 | << "}\n\n"; |
76 | } |
77 | |
78 | static std::string MangleName(StringRef Str) { |
79 | std::string Mangled; |
80 | for (unsigned i = 0, e = Str.size(); i != e; ++i) { |
81 | switch (Str[i]) { |
82 | default: |
83 | Mangled += Str[i]; |
84 | break; |
85 | case '[': |
86 | Mangled += "lsquare"; |
87 | break; |
88 | case ']': |
89 | Mangled += "rsquare"; |
90 | break; |
91 | case '{': |
92 | Mangled += "lbrace"; |
93 | break; |
94 | case '}': |
95 | Mangled += "rbrace"; |
96 | break; |
97 | case '$': |
98 | Mangled += "dollar"; |
99 | break; |
100 | case '/': |
101 | Mangled += "slash"; |
102 | break; |
103 | } |
104 | } |
105 | return Mangled; |
106 | } |
107 | |
108 | void EmitClangCommentCommandList(RecordKeeper &Records, raw_ostream &OS) { |
109 | emitSourceFileHeader("A list of commands useable in documentation " |
110 | "comments", OS); |
111 | |
112 | OS << "#ifndef COMMENT_COMMAND\n" |
113 | << "# define COMMENT_COMMAND(NAME)\n" |
114 | << "#endif\n"; |
115 | |
116 | std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Command"); |
117 | for (size_t i = 0, e = Tags.size(); i != e; ++i) { |
118 | Record &Tag = *Tags[i]; |
119 | std::string MangledName = MangleName(Tag.getValueAsString("Name")); |
120 | |
121 | OS << "COMMENT_COMMAND(" << MangledName << ")\n"; |
122 | } |
123 | } |
124 | } |
125 | |