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