1 //===- TableGen.cpp - Top-Level TableGen implementation for Clang ---------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the main function for Clang's TableGen.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "ClangASTEmitters.h"
14 #include "TableGenBackends.h" // Declares all backends.
15 #include "llvm/Support/CommandLine.h"
16 #include "llvm/Support/InitLLVM.h"
17 #include "llvm/Support/PrettyStackTrace.h"
18 #include "llvm/Support/Signals.h"
19 #include "llvm/TableGen/Error.h"
20 #include "llvm/TableGen/Main.h"
21 #include "llvm/TableGen/Record.h"
22 
23 using namespace llvm;
24 using namespace clang;
25 
26 enum ActionType {
27   PrintRecords,
28   DumpJSON,
29   GenClangAttrClasses,
30   GenClangAttrParserStringSwitches,
31   GenClangAttrSubjectMatchRulesParserStringSwitches,
32   GenClangAttrImpl,
33   GenClangAttrList,
34   GenClangAttrSubjectMatchRuleList,
35   GenClangAttrPCHRead,
36   GenClangAttrPCHWrite,
37   GenClangAttrHasAttributeImpl,
38   GenClangAttrSpellingListIndex,
39   GenClangAttrASTVisitor,
40   GenClangAttrTemplateInstantiate,
41   GenClangAttrParsedAttrList,
42   GenClangAttrParsedAttrImpl,
43   GenClangAttrParsedAttrKinds,
44   GenClangAttrTextNodeDump,
45   GenClangAttrNodeTraverse,
46   GenClangDiagsDefs,
47   GenClangDiagGroups,
48   GenClangDiagsIndexName,
49   GenClangCommentNodes,
50   GenClangDeclNodes,
51   GenClangStmtNodes,
52   GenClangTypeNodes,
53   GenClangOpcodes,
54   GenClangSACheckers,
55   GenClangCommentHTMLTags,
56   GenClangCommentHTMLTagsProperties,
57   GenClangCommentHTMLNamedCharacterReferences,
58   GenClangCommentCommandInfo,
59   GenClangCommentCommandList,
60   GenClangOpenCLBuiltins,
61   GenArmNeon,
62   GenArmFP16,
63   GenArmNeonSema,
64   GenArmNeonTest,
65   GenArmMveHeader,
66   GenArmMveBuiltinDef,
67   GenArmMveBuiltinSema,
68   GenArmMveBuiltinCG,
69   GenArmMveBuiltinAliases,
70   GenAttrDocs,
71   GenDiagDocs,
72   GenOptDocs,
73   GenDataCollectors,
74   GenTestPragmaAttributeSupportedAttributes
75 };
76 
77 namespace {
78 cl::opt<ActionType> Action(
79     cl::desc("Action to perform:"),
80     cl::values(
81         clEnumValN(PrintRecords, "print-records",
82                    "Print all records to stdout (default)"),
83         clEnumValN(DumpJSON, "dump-json",
84                    "Dump all records as machine-readable JSON"),
85         clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes",
86                    "Generate clang attribute clases"),
87         clEnumValN(GenClangAttrParserStringSwitches,
88                    "gen-clang-attr-parser-string-switches",
89                    "Generate all parser-related attribute string switches"),
90         clEnumValN(GenClangAttrSubjectMatchRulesParserStringSwitches,
91                    "gen-clang-attr-subject-match-rules-parser-string-switches",
92                    "Generate all parser-related attribute subject match rule"
93                    "string switches"),
94         clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl",
95                    "Generate clang attribute implementations"),
96         clEnumValN(GenClangAttrList, "gen-clang-attr-list",
97                    "Generate a clang attribute list"),
98         clEnumValN(GenClangAttrSubjectMatchRuleList,
99                    "gen-clang-attr-subject-match-rule-list",
100                    "Generate a clang attribute subject match rule list"),
101         clEnumValN(GenClangAttrPCHRead, "gen-clang-attr-pch-read",
102                    "Generate clang PCH attribute reader"),
103         clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write",
104                    "Generate clang PCH attribute writer"),
105         clEnumValN(GenClangAttrHasAttributeImpl,
106                    "gen-clang-attr-has-attribute-impl",
107                    "Generate a clang attribute spelling list"),
108         clEnumValN(GenClangAttrSpellingListIndex,
109                    "gen-clang-attr-spelling-index",
110                    "Generate a clang attribute spelling index"),
111         clEnumValN(GenClangAttrASTVisitor, "gen-clang-attr-ast-visitor",
112                    "Generate a recursive AST visitor for clang attributes"),
113         clEnumValN(GenClangAttrTemplateInstantiate,
114                    "gen-clang-attr-template-instantiate",
115                    "Generate a clang template instantiate code"),
116         clEnumValN(GenClangAttrParsedAttrList,
117                    "gen-clang-attr-parsed-attr-list",
118                    "Generate a clang parsed attribute list"),
119         clEnumValN(GenClangAttrParsedAttrImpl,
120                    "gen-clang-attr-parsed-attr-impl",
121                    "Generate the clang parsed attribute helpers"),
122         clEnumValN(GenClangAttrParsedAttrKinds,
123                    "gen-clang-attr-parsed-attr-kinds",
124                    "Generate a clang parsed attribute kinds"),
125         clEnumValN(GenClangAttrTextNodeDump, "gen-clang-attr-text-node-dump",
126                    "Generate clang attribute text node dumper"),
127         clEnumValN(GenClangAttrNodeTraverse, "gen-clang-attr-node-traverse",
128                    "Generate clang attribute traverser"),
129         clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs",
130                    "Generate Clang diagnostics definitions"),
131         clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups",
132                    "Generate Clang diagnostic groups"),
133         clEnumValN(GenClangDiagsIndexName, "gen-clang-diags-index-name",
134                    "Generate Clang diagnostic name index"),
135         clEnumValN(GenClangCommentNodes, "gen-clang-comment-nodes",
136                    "Generate Clang AST comment nodes"),
137         clEnumValN(GenClangDeclNodes, "gen-clang-decl-nodes",
138                    "Generate Clang AST declaration nodes"),
139         clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes",
140                    "Generate Clang AST statement nodes"),
141         clEnumValN(GenClangTypeNodes, "gen-clang-type-nodes",
142                    "Generate Clang AST type nodes"),
143         clEnumValN(GenClangOpcodes, "gen-clang-opcodes",
144                    "Generate Clang constexpr interpreter opcodes"),
145         clEnumValN(GenClangSACheckers, "gen-clang-sa-checkers",
146                    "Generate Clang Static Analyzer checkers"),
147         clEnumValN(GenClangCommentHTMLTags, "gen-clang-comment-html-tags",
148                    "Generate efficient matchers for HTML tag "
149                    "names that are used in documentation comments"),
150         clEnumValN(GenClangCommentHTMLTagsProperties,
151                    "gen-clang-comment-html-tags-properties",
152                    "Generate efficient matchers for HTML tag "
153                    "properties"),
154         clEnumValN(GenClangCommentHTMLNamedCharacterReferences,
155                    "gen-clang-comment-html-named-character-references",
156                    "Generate function to translate named character "
157                    "references to UTF-8 sequences"),
158         clEnumValN(GenClangCommentCommandInfo, "gen-clang-comment-command-info",
159                    "Generate command properties for commands that "
160                    "are used in documentation comments"),
161         clEnumValN(GenClangCommentCommandList, "gen-clang-comment-command-list",
162                    "Generate list of commands that are used in "
163                    "documentation comments"),
164         clEnumValN(GenClangOpenCLBuiltins, "gen-clang-opencl-builtins",
165                    "Generate OpenCL builtin declaration handlers"),
166         clEnumValN(GenArmNeon, "gen-arm-neon", "Generate arm_neon.h for clang"),
167         clEnumValN(GenArmFP16, "gen-arm-fp16", "Generate arm_fp16.h for clang"),
168         clEnumValN(GenArmNeonSema, "gen-arm-neon-sema",
169                    "Generate ARM NEON sema support for clang"),
170         clEnumValN(GenArmNeonTest, "gen-arm-neon-test",
171                    "Generate ARM NEON tests for clang"),
172         clEnumValN(GenArmMveHeader, "gen-arm-mve-header",
173                    "Generate arm_mve.h for clang"),
174         clEnumValN(GenArmMveBuiltinDef, "gen-arm-mve-builtin-def",
175                    "Generate ARM MVE builtin definitions for clang"),
176         clEnumValN(GenArmMveBuiltinSema, "gen-arm-mve-builtin-sema",
177                    "Generate ARM MVE builtin sema checks for clang"),
178         clEnumValN(GenArmMveBuiltinCG, "gen-arm-mve-builtin-codegen",
179                    "Generate ARM MVE builtin code-generator for clang"),
180         clEnumValN(GenArmMveBuiltinAliases, "gen-arm-mve-builtin-aliases",
181                    "Generate list of valid ARM MVE builtin aliases for clang"),
182         clEnumValN(GenAttrDocs, "gen-attr-docs",
183                    "Generate attribute documentation"),
184         clEnumValN(GenDiagDocs, "gen-diag-docs",
185                    "Generate diagnostic documentation"),
186         clEnumValN(GenOptDocs, "gen-opt-docs", "Generate option documentation"),
187         clEnumValN(GenDataCollectors, "gen-clang-data-collectors",
188                    "Generate data collectors for AST nodes"),
189         clEnumValN(GenTestPragmaAttributeSupportedAttributes,
190                    "gen-clang-test-pragma-attribute-supported-attributes",
191                    "Generate a list of attributes supported by #pragma clang "
192                    "attribute for testing purposes")));
193 
194 cl::opt<std::string>
195 ClangComponent("clang-component",
196                cl::desc("Only use warnings from specified component"),
197                cl::value_desc("component"), cl::Hidden);
198 
199 bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
200   switch (Action) {
201   case PrintRecords:
202     OS << Records;           // No argument, dump all contents
203     break;
204   case DumpJSON:
205     EmitJSON(Records, OS);
206     break;
207   case GenClangAttrClasses:
208     EmitClangAttrClass(Records, OS);
209     break;
210   case GenClangAttrParserStringSwitches:
211     EmitClangAttrParserStringSwitches(Records, OS);
212     break;
213   case GenClangAttrSubjectMatchRulesParserStringSwitches:
214     EmitClangAttrSubjectMatchRulesParserStringSwitches(Records, OS);
215     break;
216   case GenClangAttrImpl:
217     EmitClangAttrImpl(Records, OS);
218     break;
219   case GenClangAttrList:
220     EmitClangAttrList(Records, OS);
221     break;
222   case GenClangAttrSubjectMatchRuleList:
223     EmitClangAttrSubjectMatchRuleList(Records, OS);
224     break;
225   case GenClangAttrPCHRead:
226     EmitClangAttrPCHRead(Records, OS);
227     break;
228   case GenClangAttrPCHWrite:
229     EmitClangAttrPCHWrite(Records, OS);
230     break;
231   case GenClangAttrHasAttributeImpl:
232     EmitClangAttrHasAttrImpl(Records, OS);
233     break;
234   case GenClangAttrSpellingListIndex:
235     EmitClangAttrSpellingListIndex(Records, OS);
236     break;
237   case GenClangAttrASTVisitor:
238     EmitClangAttrASTVisitor(Records, OS);
239     break;
240   case GenClangAttrTemplateInstantiate:
241     EmitClangAttrTemplateInstantiate(Records, OS);
242     break;
243   case GenClangAttrParsedAttrList:
244     EmitClangAttrParsedAttrList(Records, OS);
245     break;
246   case GenClangAttrParsedAttrImpl:
247     EmitClangAttrParsedAttrImpl(Records, OS);
248     break;
249   case GenClangAttrParsedAttrKinds:
250     EmitClangAttrParsedAttrKinds(Records, OS);
251     break;
252   case GenClangAttrTextNodeDump:
253     EmitClangAttrTextNodeDump(Records, OS);
254     break;
255   case GenClangAttrNodeTraverse:
256     EmitClangAttrNodeTraverse(Records, OS);
257     break;
258   case GenClangDiagsDefs:
259     EmitClangDiagsDefs(Records, OS, ClangComponent);
260     break;
261   case GenClangDiagGroups:
262     EmitClangDiagGroups(Records, OS);
263     break;
264   case GenClangDiagsIndexName:
265     EmitClangDiagsIndexName(Records, OS);
266     break;
267   case GenClangCommentNodes:
268     EmitClangASTNodes(Records, OS, CommentNodeClassName, "");
269     break;
270   case GenClangDeclNodes:
271     EmitClangASTNodes(Records, OS, DeclNodeClassName, "Decl");
272     EmitClangDeclContext(Records, OS);
273     break;
274   case GenClangStmtNodes:
275     EmitClangASTNodes(Records, OS, StmtNodeClassName, "");
276     break;
277   case GenClangTypeNodes:
278     EmitClangTypeNodes(Records, OS);
279     break;
280   case GenClangOpcodes:
281     EmitClangOpcodes(Records, OS);
282     break;
283   case GenClangSACheckers:
284     EmitClangSACheckers(Records, OS);
285     break;
286   case GenClangCommentHTMLTags:
287     EmitClangCommentHTMLTags(Records, OS);
288     break;
289   case GenClangCommentHTMLTagsProperties:
290     EmitClangCommentHTMLTagsProperties(Records, OS);
291     break;
292   case GenClangCommentHTMLNamedCharacterReferences:
293     EmitClangCommentHTMLNamedCharacterReferences(Records, OS);
294     break;
295   case GenClangCommentCommandInfo:
296     EmitClangCommentCommandInfo(Records, OS);
297     break;
298   case GenClangCommentCommandList:
299     EmitClangCommentCommandList(Records, OS);
300     break;
301   case GenClangOpenCLBuiltins:
302     EmitClangOpenCLBuiltins(Records, OS);
303     break;
304   case GenArmNeon:
305     EmitNeon(Records, OS);
306     break;
307   case GenArmFP16:
308     EmitFP16(Records, OS);
309     break;
310   case GenArmNeonSema:
311     EmitNeonSema(Records, OS);
312     break;
313   case GenArmNeonTest:
314     EmitNeonTest(Records, OS);
315     break;
316   case GenArmMveHeader:
317     EmitMveHeader(Records, OS);
318     break;
319   case GenArmMveBuiltinDef:
320     EmitMveBuiltinDef(Records, OS);
321     break;
322   case GenArmMveBuiltinSema:
323     EmitMveBuiltinSema(Records, OS);
324     break;
325   case GenArmMveBuiltinCG:
326     EmitMveBuiltinCG(Records, OS);
327     break;
328   case GenArmMveBuiltinAliases:
329     EmitMveBuiltinAliases(Records, OS);
330     break;
331   case GenAttrDocs:
332     EmitClangAttrDocs(Records, OS);
333     break;
334   case GenDiagDocs:
335     EmitClangDiagDocs(Records, OS);
336     break;
337   case GenOptDocs:
338     EmitClangOptDocs(Records, OS);
339     break;
340   case GenDataCollectors:
341     EmitClangDataCollectors(Records, OS);
342     break;
343   case GenTestPragmaAttributeSupportedAttributes:
344     EmitTestPragmaAttributeSupportedAttributes(Records, OS);
345     break;
346   }
347 
348   return false;
349 }
350 }
351 
352 int main(int argc, char **argv) {
353   llvm::InitLLVM X(argc, argv);
354   cl::ParseCommandLineOptions(argc, argv);
355 
356   llvm_shutdown_obj Y;
357 
358   return TableGenMain(argv[0], &ClangTableGenMain);
359 }
360 
361 #ifdef __has_feature
362 #if __has_feature(address_sanitizer)
363 #include <sanitizer/lsan_interface.h>
364 // Disable LeakSanitizer for this binary as it has too many leaks that are not
365 // very interesting to fix. See compiler-rt/include/sanitizer/lsan_interface.h .
366 int __lsan_is_turned_off() { return 1; }
367 #endif  // __has_feature(address_sanitizer)
368 #endif  // defined(__has_feature)
369