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