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