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