1 | //===- FrontendOptions.h ----------------------------------------*- C++ -*-===// |
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 | #ifndef LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H |
10 | #define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H |
11 | |
12 | #include "clang/AST/ASTDumperUtils.h" |
13 | #include "clang/Basic/LangStandard.h" |
14 | #include "clang/Frontend/CommandLineSourceLoc.h" |
15 | #include "clang/Sema/CodeCompleteOptions.h" |
16 | #include "clang/Serialization/ModuleFileExtension.h" |
17 | #include "llvm/ADT/StringRef.h" |
18 | #include "llvm/Support/Compiler.h" |
19 | #include "llvm/Support/MemoryBuffer.h" |
20 | #include <cassert> |
21 | #include <map> |
22 | #include <memory> |
23 | #include <optional> |
24 | #include <string> |
25 | #include <vector> |
26 | |
27 | namespace llvm { |
28 | |
29 | class MemoryBuffer; |
30 | |
31 | } // namespace llvm |
32 | |
33 | namespace clang { |
34 | |
35 | namespace frontend { |
36 | |
37 | enum ActionKind { |
38 | /// Parse ASTs and list Decl nodes. |
39 | ASTDeclList, |
40 | |
41 | /// Parse ASTs and dump them. |
42 | ASTDump, |
43 | |
44 | /// Parse ASTs and print them. |
45 | ASTPrint, |
46 | |
47 | /// Parse ASTs and view them in Graphviz. |
48 | ASTView, |
49 | |
50 | /// Dump the compiler configuration. |
51 | DumpCompilerOptions, |
52 | |
53 | /// Dump out raw tokens. |
54 | DumpRawTokens, |
55 | |
56 | /// Dump out preprocessed tokens. |
57 | DumpTokens, |
58 | |
59 | /// Emit a .s file. |
60 | EmitAssembly, |
61 | |
62 | /// Emit a .bc file. |
63 | EmitBC, |
64 | |
65 | /// Translate input source into HTML. |
66 | EmitHTML, |
67 | |
68 | /// Emit a .cir file |
69 | EmitCIR, |
70 | |
71 | /// Emit a .ll file. |
72 | EmitLLVM, |
73 | |
74 | /// Generate LLVM IR, but do not emit anything. |
75 | EmitLLVMOnly, |
76 | |
77 | /// Generate machine code, but don't emit anything. |
78 | EmitCodeGenOnly, |
79 | |
80 | /// Emit a .o file. |
81 | EmitObj, |
82 | |
83 | // Extract API information |
84 | , |
85 | |
86 | /// Parse and apply any fixits to the source. |
87 | FixIt, |
88 | |
89 | /// Generate pre-compiled module from a module map. |
90 | GenerateModule, |
91 | |
92 | /// Generate pre-compiled module from a standard C++ module interface unit. |
93 | GenerateModuleInterface, |
94 | |
95 | /// Generate reduced module interface for a standard C++ module interface |
96 | /// unit. |
97 | GenerateReducedModuleInterface, |
98 | |
99 | /// Generate a C++20 header unit module from a header file. |
100 | , |
101 | |
102 | /// Generate pre-compiled header. |
103 | GeneratePCH, |
104 | |
105 | /// Generate Interface Stub Files. |
106 | GenerateInterfaceStubs, |
107 | |
108 | /// Only execute frontend initialization. |
109 | InitOnly, |
110 | |
111 | /// Dump information about a module file. |
112 | ModuleFileInfo, |
113 | |
114 | /// Load and verify that a PCH file is usable. |
115 | VerifyPCH, |
116 | |
117 | /// Parse and perform semantic analysis. |
118 | ParseSyntaxOnly, |
119 | |
120 | /// Run a plugin action, \see ActionName. |
121 | PluginAction, |
122 | |
123 | /// Print the "preamble" of the input file |
124 | PrintPreamble, |
125 | |
126 | /// -E mode. |
127 | PrintPreprocessedInput, |
128 | |
129 | /// Expand macros but not \#includes. |
130 | RewriteMacros, |
131 | |
132 | /// ObjC->C Rewriter. |
133 | RewriteObjC, |
134 | |
135 | /// Rewriter playground |
136 | RewriteTest, |
137 | |
138 | /// Run one or more source code analyses. |
139 | RunAnalysis, |
140 | |
141 | /// Dump template instantiations |
142 | TemplightDump, |
143 | |
144 | /// Just lex, no output. |
145 | RunPreprocessorOnly, |
146 | |
147 | /// Print the output of the dependency directives source minimizer. |
148 | PrintDependencyDirectivesSourceMinimizerOutput |
149 | }; |
150 | |
151 | } // namespace frontend |
152 | |
153 | /// The kind of a file that we've been handed as an input. |
154 | class InputKind { |
155 | public: |
156 | /// The input file format. |
157 | enum Format { |
158 | Source, |
159 | ModuleMap, |
160 | Precompiled |
161 | }; |
162 | |
163 | // If we are building a header unit, what kind it is; this affects whether |
164 | // we look for the file in the user or system include search paths before |
165 | // flagging a missing input. |
166 | enum { |
167 | , |
168 | , |
169 | , |
170 | |
171 | }; |
172 | |
173 | private: |
174 | Language Lang; |
175 | LLVM_PREFERRED_TYPE(Format) |
176 | unsigned Fmt : 3; |
177 | LLVM_PREFERRED_TYPE(bool) |
178 | unsigned Preprocessed : 1; |
179 | LLVM_PREFERRED_TYPE(HeaderUnitKind) |
180 | unsigned : 3; |
181 | LLVM_PREFERRED_TYPE(bool) |
182 | unsigned : 1; |
183 | |
184 | public: |
185 | constexpr (Language L = Language::Unknown, Format F = Source, |
186 | bool PP = false, HeaderUnitKind HU = HeaderUnit_None, |
187 | bool HD = false) |
188 | : Lang(L), Fmt(F), Preprocessed(PP), HeaderUnit(HU), IsHeader(HD) {} |
189 | |
190 | Language getLanguage() const { return static_cast<Language>(Lang); } |
191 | Format getFormat() const { return static_cast<Format>(Fmt); } |
192 | HeaderUnitKind () const { |
193 | return static_cast<HeaderUnitKind>(HeaderUnit); |
194 | } |
195 | bool isPreprocessed() const { return Preprocessed; } |
196 | bool () const { return IsHeader; } |
197 | bool () const { return HeaderUnit != HeaderUnit_None; } |
198 | |
199 | /// Is the input kind fully-unknown? |
200 | bool isUnknown() const { return Lang == Language::Unknown && Fmt == Source; } |
201 | |
202 | /// Is the language of the input some dialect of Objective-C? |
203 | bool isObjectiveC() const { |
204 | return Lang == Language::ObjC || Lang == Language::ObjCXX; |
205 | } |
206 | |
207 | InputKind getPreprocessed() const { |
208 | return InputKind(getLanguage(), getFormat(), true, getHeaderUnitKind(), |
209 | isHeader()); |
210 | } |
211 | |
212 | InputKind () const { |
213 | return InputKind(getLanguage(), getFormat(), isPreprocessed(), |
214 | getHeaderUnitKind(), true); |
215 | } |
216 | |
217 | InputKind (HeaderUnitKind HU) const { |
218 | return InputKind(getLanguage(), getFormat(), isPreprocessed(), HU, |
219 | isHeader()); |
220 | } |
221 | |
222 | InputKind withFormat(Format F) const { |
223 | return InputKind(getLanguage(), F, isPreprocessed(), getHeaderUnitKind(), |
224 | isHeader()); |
225 | } |
226 | }; |
227 | |
228 | /// An input file for the front end. |
229 | class FrontendInputFile { |
230 | /// The file name, or "-" to read from standard input. |
231 | std::string File; |
232 | |
233 | /// The input, if it comes from a buffer rather than a file. This object |
234 | /// does not own the buffer, and the caller is responsible for ensuring |
235 | /// that it outlives any users. |
236 | std::optional<llvm::MemoryBufferRef> Buffer; |
237 | |
238 | /// The kind of input, e.g., C source, AST file, LLVM IR. |
239 | InputKind Kind; |
240 | |
241 | /// Whether we're dealing with a 'system' input (vs. a 'user' input). |
242 | bool IsSystem = false; |
243 | |
244 | public: |
245 | FrontendInputFile() = default; |
246 | FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false) |
247 | : File(File.str()), Kind(Kind), IsSystem(IsSystem) {} |
248 | FrontendInputFile(llvm::MemoryBufferRef Buffer, InputKind Kind, |
249 | bool IsSystem = false) |
250 | : Buffer(Buffer), Kind(Kind), IsSystem(IsSystem) {} |
251 | |
252 | InputKind getKind() const { return Kind; } |
253 | bool isSystem() const { return IsSystem; } |
254 | |
255 | bool isEmpty() const { return File.empty() && Buffer == std::nullopt; } |
256 | bool isFile() const { return !isBuffer(); } |
257 | bool isBuffer() const { return Buffer != std::nullopt; } |
258 | bool isPreprocessed() const { return Kind.isPreprocessed(); } |
259 | bool () const { return Kind.isHeader(); } |
260 | InputKind::HeaderUnitKind () const { |
261 | return Kind.getHeaderUnitKind(); |
262 | } |
263 | |
264 | StringRef getFile() const { |
265 | assert(isFile()); |
266 | return File; |
267 | } |
268 | |
269 | llvm::MemoryBufferRef getBuffer() const { |
270 | assert(isBuffer()); |
271 | return *Buffer; |
272 | } |
273 | }; |
274 | |
275 | /// FrontendOptions - Options for controlling the behavior of the frontend. |
276 | class FrontendOptions { |
277 | public: |
278 | /// Disable memory freeing on exit. |
279 | LLVM_PREFERRED_TYPE(bool) |
280 | unsigned DisableFree : 1; |
281 | |
282 | /// When generating PCH files, instruct the AST writer to create relocatable |
283 | /// PCH files. |
284 | LLVM_PREFERRED_TYPE(bool) |
285 | unsigned RelocatablePCH : 1; |
286 | |
287 | /// Show the -help text. |
288 | LLVM_PREFERRED_TYPE(bool) |
289 | unsigned ShowHelp : 1; |
290 | |
291 | /// Show frontend performance metrics and statistics. |
292 | LLVM_PREFERRED_TYPE(bool) |
293 | unsigned ShowStats : 1; |
294 | |
295 | LLVM_PREFERRED_TYPE(bool) |
296 | unsigned AppendStats : 1; |
297 | |
298 | /// print the supported cpus for the current target |
299 | LLVM_PREFERRED_TYPE(bool) |
300 | unsigned PrintSupportedCPUs : 1; |
301 | |
302 | /// Print the supported extensions for the current target. |
303 | LLVM_PREFERRED_TYPE(bool) |
304 | unsigned PrintSupportedExtensions : 1; |
305 | |
306 | /// Print the extensions enabled for the current target. |
307 | LLVM_PREFERRED_TYPE(bool) |
308 | unsigned PrintEnabledExtensions : 1; |
309 | |
310 | /// Show the -version text. |
311 | LLVM_PREFERRED_TYPE(bool) |
312 | unsigned ShowVersion : 1; |
313 | |
314 | /// Apply fixes even if there are unfixable errors. |
315 | LLVM_PREFERRED_TYPE(bool) |
316 | unsigned FixWhatYouCan : 1; |
317 | |
318 | /// Apply fixes only for warnings. |
319 | LLVM_PREFERRED_TYPE(bool) |
320 | unsigned FixOnlyWarnings : 1; |
321 | |
322 | /// Apply fixes and recompile. |
323 | LLVM_PREFERRED_TYPE(bool) |
324 | unsigned FixAndRecompile : 1; |
325 | |
326 | /// Apply fixes to temporary files. |
327 | LLVM_PREFERRED_TYPE(bool) |
328 | unsigned FixToTemporaries : 1; |
329 | |
330 | /// Skip over function bodies to speed up parsing in cases you do not need |
331 | /// them (e.g. with code completion). |
332 | LLVM_PREFERRED_TYPE(bool) |
333 | unsigned SkipFunctionBodies : 1; |
334 | |
335 | /// Whether we can use the global module index if available. |
336 | LLVM_PREFERRED_TYPE(bool) |
337 | unsigned UseGlobalModuleIndex : 1; |
338 | |
339 | /// Whether we can generate the global module index if needed. |
340 | LLVM_PREFERRED_TYPE(bool) |
341 | unsigned GenerateGlobalModuleIndex : 1; |
342 | |
343 | /// Whether we include declaration dumps in AST dumps. |
344 | LLVM_PREFERRED_TYPE(bool) |
345 | unsigned ASTDumpDecls : 1; |
346 | |
347 | /// Whether we deserialize all decls when forming AST dumps. |
348 | LLVM_PREFERRED_TYPE(bool) |
349 | unsigned ASTDumpAll : 1; |
350 | |
351 | /// Whether we include lookup table dumps in AST dumps. |
352 | LLVM_PREFERRED_TYPE(bool) |
353 | unsigned ASTDumpLookups : 1; |
354 | |
355 | /// Whether we include declaration type dumps in AST dumps. |
356 | LLVM_PREFERRED_TYPE(bool) |
357 | unsigned ASTDumpDeclTypes : 1; |
358 | |
359 | /// Whether we are performing an implicit module build. |
360 | LLVM_PREFERRED_TYPE(bool) |
361 | unsigned BuildingImplicitModule : 1; |
362 | |
363 | /// Whether to use a filesystem lock when building implicit modules. |
364 | LLVM_PREFERRED_TYPE(bool) |
365 | unsigned BuildingImplicitModuleUsesLock : 1; |
366 | |
367 | /// Whether we should embed all used files into the PCM file. |
368 | LLVM_PREFERRED_TYPE(bool) |
369 | unsigned ModulesEmbedAllFiles : 1; |
370 | |
371 | /// Whether timestamps should be written to the produced PCH file. |
372 | LLVM_PREFERRED_TYPE(bool) |
373 | unsigned IncludeTimestamps : 1; |
374 | |
375 | /// Should a temporary file be used during compilation. |
376 | LLVM_PREFERRED_TYPE(bool) |
377 | unsigned UseTemporary : 1; |
378 | |
379 | /// When using -emit-module, treat the modulemap as a system module. |
380 | LLVM_PREFERRED_TYPE(bool) |
381 | unsigned IsSystemModule : 1; |
382 | |
383 | /// Output (and read) PCM files regardless of compiler errors. |
384 | LLVM_PREFERRED_TYPE(bool) |
385 | unsigned AllowPCMWithCompilerErrors : 1; |
386 | |
387 | /// Whether to share the FileManager when building modules. |
388 | LLVM_PREFERRED_TYPE(bool) |
389 | unsigned ModulesShareFileManager : 1; |
390 | |
391 | /// Whether to emit symbol graph files as a side effect of compilation. |
392 | LLVM_PREFERRED_TYPE(bool) |
393 | unsigned EmitSymbolGraph : 1; |
394 | |
395 | /// Whether to emit additional symbol graphs for extended modules. |
396 | LLVM_PREFERRED_TYPE(bool) |
397 | unsigned EmitExtensionSymbolGraphs : 1; |
398 | |
399 | /// Whether to emit symbol labels for testing in generated symbol graphs |
400 | LLVM_PREFERRED_TYPE(bool) |
401 | unsigned EmitSymbolGraphSymbolLabelsForTesting : 1; |
402 | |
403 | /// Whether to emit symbol labels for testing in generated symbol graphs |
404 | LLVM_PREFERRED_TYPE(bool) |
405 | unsigned EmitPrettySymbolGraphs : 1; |
406 | |
407 | /// Whether to generate reduced BMI for C++20 named modules. |
408 | LLVM_PREFERRED_TYPE(bool) |
409 | unsigned GenReducedBMI : 1; |
410 | |
411 | /// Use Clang IR pipeline to emit code |
412 | LLVM_PREFERRED_TYPE(bool) |
413 | unsigned UseClangIRPipeline : 1; |
414 | |
415 | CodeCompleteOptions CodeCompleteOpts; |
416 | |
417 | /// Specifies the output format of the AST. |
418 | ASTDumpOutputFormat ASTDumpFormat = ADOF_Default; |
419 | |
420 | /// The input kind, either specified via -x argument or deduced from the input |
421 | /// file name. |
422 | InputKind DashX; |
423 | |
424 | /// The input files and their types. |
425 | SmallVector<FrontendInputFile, 0> Inputs; |
426 | |
427 | /// When the input is a module map, the original module map file from which |
428 | /// that map was inferred, if any (for umbrella modules). |
429 | std::string OriginalModuleMap; |
430 | |
431 | /// The output file, if any. |
432 | std::string OutputFile; |
433 | |
434 | /// If given, the new suffix for fix-it rewritten files. |
435 | std::string FixItSuffix; |
436 | |
437 | /// If given, filter dumped AST Decl nodes by this substring. |
438 | std::string ASTDumpFilter; |
439 | |
440 | /// If given, enable code completion at the provided location. |
441 | ParsedSourceLocation CodeCompletionAt; |
442 | |
443 | /// The frontend action to perform. |
444 | frontend::ActionKind ProgramAction = frontend::ParseSyntaxOnly; |
445 | |
446 | /// The name of the action to run when using a plugin action. |
447 | std::string ActionName; |
448 | |
449 | // Currently this is only used as part of the `-extract-api` action. |
450 | /// The name of the product the input files belong too. |
451 | std::string ProductName; |
452 | |
453 | // Currently this is only used as part of the `-extract-api` action. |
454 | // A comma separated list of files providing a list of APIs to |
455 | // ignore when extracting documentation. |
456 | std::vector<std::string> ; |
457 | |
458 | // Location of output directory where symbol graph information would |
459 | // be dumped. This overrides regular -o output file specification |
460 | std::string SymbolGraphOutputDir; |
461 | |
462 | /// Args to pass to the plugins |
463 | std::map<std::string, std::vector<std::string>> PluginArgs; |
464 | |
465 | /// The list of plugin actions to run in addition to the normal action. |
466 | std::vector<std::string> AddPluginActions; |
467 | |
468 | /// The list of plugins to load. |
469 | std::vector<std::string> Plugins; |
470 | |
471 | /// The list of module file extensions. |
472 | std::vector<std::shared_ptr<ModuleFileExtension>> ModuleFileExtensions; |
473 | |
474 | /// The list of module map files to load before processing the input. |
475 | std::vector<std::string> ModuleMapFiles; |
476 | |
477 | /// The list of additional prebuilt module files to load before |
478 | /// processing the input. |
479 | std::vector<std::string> ModuleFiles; |
480 | |
481 | /// The list of files to embed into the compiled module file. |
482 | std::vector<std::string> ModulesEmbedFiles; |
483 | |
484 | /// The list of AST files to merge. |
485 | std::vector<std::string> ASTMergeFiles; |
486 | |
487 | /// A list of arguments to forward to LLVM's option processing; this |
488 | /// should only be used for debugging and experimental features. |
489 | std::vector<std::string> LLVMArgs; |
490 | |
491 | /// File name of the file that will provide record layouts |
492 | /// (in the format produced by -fdump-record-layouts). |
493 | std::string OverrideRecordLayoutsFile; |
494 | |
495 | /// Auxiliary triple for CUDA/HIP compilation. |
496 | std::string AuxTriple; |
497 | |
498 | /// Auxiliary target CPU for CUDA/HIP compilation. |
499 | std::optional<std::string> AuxTargetCPU; |
500 | |
501 | /// Auxiliary target features for CUDA/HIP compilation. |
502 | std::optional<std::vector<std::string>> AuxTargetFeatures; |
503 | |
504 | /// Filename to write statistics to. |
505 | std::string StatsFile; |
506 | |
507 | /// Minimum time granularity (in microseconds) traced by time profiler. |
508 | unsigned TimeTraceGranularity; |
509 | |
510 | /// Make time trace capture verbose event details (e.g. source filenames). |
511 | /// This can increase the size of the output by 2-3 times. |
512 | LLVM_PREFERRED_TYPE(bool) |
513 | unsigned TimeTraceVerbose : 1; |
514 | |
515 | /// Path which stores the output files for -ftime-trace |
516 | std::string TimeTracePath; |
517 | |
518 | /// Output Path for module output file. |
519 | std::string ModuleOutputPath; |
520 | |
521 | public: |
522 | FrontendOptions() |
523 | : DisableFree(false), RelocatablePCH(false), ShowHelp(false), |
524 | ShowStats(false), AppendStats(false), ShowVersion(false), |
525 | FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false), |
526 | FixToTemporaries(false), SkipFunctionBodies(false), |
527 | UseGlobalModuleIndex(true), GenerateGlobalModuleIndex(true), |
528 | ASTDumpDecls(false), ASTDumpLookups(false), |
529 | BuildingImplicitModule(false), BuildingImplicitModuleUsesLock(true), |
530 | ModulesEmbedAllFiles(false), IncludeTimestamps(true), |
531 | UseTemporary(true), AllowPCMWithCompilerErrors(false), |
532 | ModulesShareFileManager(true), EmitSymbolGraph(false), |
533 | EmitExtensionSymbolGraphs(false), |
534 | EmitSymbolGraphSymbolLabelsForTesting(false), |
535 | EmitPrettySymbolGraphs(false), GenReducedBMI(false), |
536 | UseClangIRPipeline(false), TimeTraceGranularity(500), |
537 | TimeTraceVerbose(false) {} |
538 | |
539 | /// getInputKindForExtension - Return the appropriate input kind for a file |
540 | /// extension. For example, "c" would return Language::C. |
541 | /// |
542 | /// \return The input kind for the extension, or Language::Unknown if the |
543 | /// extension is not recognized. |
544 | static InputKind getInputKindForExtension(StringRef Extension); |
545 | }; |
546 | |
547 | } // namespace clang |
548 | |
549 | #endif // LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H |
550 | |