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   /// print the supported cpus for the current target
282   unsigned PrintSupportedCPUs : 1;
283 
284   /// Output time trace profile.
285   unsigned TimeTrace : 1;
286 
287   /// Show the -version text.
288   unsigned ShowVersion : 1;
289 
290   /// Apply fixes even if there are unfixable errors.
291   unsigned FixWhatYouCan : 1;
292 
293   /// Apply fixes only for warnings.
294   unsigned FixOnlyWarnings : 1;
295 
296   /// Apply fixes and recompile.
297   unsigned FixAndRecompile : 1;
298 
299   /// Apply fixes to temporary files.
300   unsigned FixToTemporaries : 1;
301 
302   /// Emit ARC errors even if the migrator can fix them.
303   unsigned ARCMTMigrateEmitARCErrors : 1;
304 
305   /// Skip over function bodies to speed up parsing in cases you do not need
306   /// them (e.g. with code completion).
307   unsigned SkipFunctionBodies : 1;
308 
309   /// Whether we can use the global module index if available.
310   unsigned UseGlobalModuleIndex : 1;
311 
312   /// Whether we can generate the global module index if needed.
313   unsigned GenerateGlobalModuleIndex : 1;
314 
315   /// Whether we include declaration dumps in AST dumps.
316   unsigned ASTDumpDecls : 1;
317 
318   /// Whether we deserialize all decls when forming AST dumps.
319   unsigned ASTDumpAll : 1;
320 
321   /// Whether we include lookup table dumps in AST dumps.
322   unsigned ASTDumpLookups : 1;
323 
324   /// Whether we include declaration type dumps in AST dumps.
325   unsigned ASTDumpDeclTypes : 1;
326 
327   /// Whether we are performing an implicit module build.
328   unsigned BuildingImplicitModule : 1;
329 
330   /// Whether to use a filesystem lock when building implicit modules.
331   unsigned BuildingImplicitModuleUsesLock : 1;
332 
333   /// Whether we should embed all used files into the PCM file.
334   unsigned ModulesEmbedAllFiles : 1;
335 
336   /// Whether timestamps should be written to the produced PCH file.
337   unsigned IncludeTimestamps : 1;
338 
339   /// Should a temporary file be used during compilation.
340   unsigned UseTemporary : 1;
341 
342   /// When using -emit-module, treat the modulemap as a system module.
343   unsigned IsSystemModule : 1;
344 
345   /// Output (and read) PCM files regardless of compiler errors.
346   unsigned AllowPCMWithCompilerErrors : 1;
347 
348   /// Whether to share the FileManager when building modules.
349   unsigned ModulesShareFileManager : 1;
350 
351   CodeCompleteOptions CodeCompleteOpts;
352 
353   /// Specifies the output format of the AST.
354   ASTDumpOutputFormat ASTDumpFormat = ADOF_Default;
355 
356   enum {
357     ARCMT_None,
358     ARCMT_Check,
359     ARCMT_Modify,
360     ARCMT_Migrate
361   } ARCMTAction = ARCMT_None;
362 
363   enum {
364     ObjCMT_None = 0,
365 
366     /// Enable migration to modern ObjC literals.
367     ObjCMT_Literals = 0x1,
368 
369     /// Enable migration to modern ObjC subscripting.
370     ObjCMT_Subscripting = 0x2,
371 
372     /// Enable migration to modern ObjC readonly property.
373     ObjCMT_ReadonlyProperty = 0x4,
374 
375     /// Enable migration to modern ObjC readwrite property.
376     ObjCMT_ReadwriteProperty = 0x8,
377 
378     /// Enable migration to modern ObjC property.
379     ObjCMT_Property = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty),
380 
381     /// Enable annotation of ObjCMethods of all kinds.
382     ObjCMT_Annotation = 0x10,
383 
384     /// Enable migration of ObjC methods to 'instancetype'.
385     ObjCMT_Instancetype = 0x20,
386 
387     /// Enable migration to NS_ENUM/NS_OPTIONS macros.
388     ObjCMT_NsMacros = 0x40,
389 
390     /// Enable migration to add conforming protocols.
391     ObjCMT_ProtocolConformance = 0x80,
392 
393     /// prefer 'atomic' property over 'nonatomic'.
394     ObjCMT_AtomicProperty = 0x100,
395 
396     /// annotate property with NS_RETURNS_INNER_POINTER
397     ObjCMT_ReturnsInnerPointerProperty = 0x200,
398 
399     /// use NS_NONATOMIC_IOSONLY for property 'atomic' attribute
400     ObjCMT_NsAtomicIOSOnlyProperty = 0x400,
401 
402     /// Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods.
403     ObjCMT_DesignatedInitializer = 0x800,
404 
405     /// Enable converting setter/getter expressions to property-dot syntx.
406     ObjCMT_PropertyDotSyntax = 0x1000,
407 
408     ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty |
409                            ObjCMT_Annotation | ObjCMT_Instancetype |
410                            ObjCMT_NsMacros | ObjCMT_ProtocolConformance |
411                            ObjCMT_NsAtomicIOSOnlyProperty |
412                            ObjCMT_DesignatedInitializer),
413     ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting |
414                          ObjCMT_MigrateDecls | ObjCMT_PropertyDotSyntax)
415   };
416   unsigned ObjCMTAction = ObjCMT_None;
417   std::string ObjCMTAllowListPath;
418 
419   std::string MTMigrateDir;
420   std::string ARCMTMigrateReportOut;
421 
422   /// The input kind, either specified via -x argument or deduced from the input
423   /// file name.
424   InputKind DashX;
425 
426   /// The input files and their types.
427   SmallVector<FrontendInputFile, 0> Inputs;
428 
429   /// When the input is a module map, the original module map file from which
430   /// that map was inferred, if any (for umbrella modules).
431   std::string OriginalModuleMap;
432 
433   /// The output file, if any.
434   std::string OutputFile;
435 
436   /// If given, the new suffix for fix-it rewritten files.
437   std::string FixItSuffix;
438 
439   /// If given, filter dumped AST Decl nodes by this substring.
440   std::string ASTDumpFilter;
441 
442   /// If given, enable code completion at the provided location.
443   ParsedSourceLocation CodeCompletionAt;
444 
445   /// The frontend action to perform.
446   frontend::ActionKind ProgramAction = frontend::ParseSyntaxOnly;
447 
448   /// The name of the action to run when using a plugin action.
449   std::string ActionName;
450 
451   // Currently this is only used as part of the `-extract-api` action.
452   /// The name of the product the input files belong too.
453   std::string ProductName;
454 
455   // Currently this is only used as part of the `-extract-api` action.
456   /// The file providing a list of APIs to ignore when extracting documentation
457   std::string ExtractAPIIgnoresFile;
458 
459   /// Args to pass to the plugins
460   std::map<std::string, std::vector<std::string>> PluginArgs;
461 
462   /// The list of plugin actions to run in addition to the normal action.
463   std::vector<std::string> AddPluginActions;
464 
465   /// The list of plugins to load.
466   std::vector<std::string> Plugins;
467 
468   /// The list of module file extensions.
469   std::vector<std::shared_ptr<ModuleFileExtension>> ModuleFileExtensions;
470 
471   /// The list of module map files to load before processing the input.
472   std::vector<std::string> ModuleMapFiles;
473 
474   /// The list of additional prebuilt module files to load before
475   /// processing the input.
476   std::vector<std::string> ModuleFiles;
477 
478   /// The list of files to embed into the compiled module file.
479   std::vector<std::string> ModulesEmbedFiles;
480 
481   /// The list of AST files to merge.
482   std::vector<std::string> ASTMergeFiles;
483 
484   /// A list of arguments to forward to LLVM's option processing; this
485   /// should only be used for debugging and experimental features.
486   std::vector<std::string> LLVMArgs;
487 
488   /// File name of the file that will provide record layouts
489   /// (in the format produced by -fdump-record-layouts).
490   std::string OverrideRecordLayoutsFile;
491 
492   /// Auxiliary triple for CUDA/HIP compilation.
493   std::string AuxTriple;
494 
495   /// Auxiliary target CPU for CUDA/HIP compilation.
496   std::optional<std::string> AuxTargetCPU;
497 
498   /// Auxiliary target features for CUDA/HIP compilation.
499   std::optional<std::vector<std::string>> AuxTargetFeatures;
500 
501   /// Filename to write statistics to.
502   std::string StatsFile;
503 
504   /// Minimum time granularity (in microseconds) traced by time profiler.
505   unsigned TimeTraceGranularity;
506 
507   /// Path which stores the output files for -ftime-trace
508   std::string TimeTracePath;
509 
510 public:
511   FrontendOptions()
512       : DisableFree(false), RelocatablePCH(false), ShowHelp(false),
513         ShowStats(false), TimeTrace(false), ShowVersion(false),
514         FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false),
515         FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false),
516         SkipFunctionBodies(false), UseGlobalModuleIndex(true),
517         GenerateGlobalModuleIndex(true), ASTDumpDecls(false),
518         ASTDumpLookups(false), BuildingImplicitModule(false),
519         BuildingImplicitModuleUsesLock(true), ModulesEmbedAllFiles(false),
520         IncludeTimestamps(true), UseTemporary(true),
521         AllowPCMWithCompilerErrors(false), ModulesShareFileManager(true),
522         TimeTraceGranularity(500) {}
523 
524   /// getInputKindForExtension - Return the appropriate input kind for a file
525   /// extension. For example, "c" would return Language::C.
526   ///
527   /// \return The input kind for the extension, or Language::Unknown if the
528   /// extension is not recognized.
529   static InputKind getInputKindForExtension(StringRef Extension);
530 };
531 
532 } // namespace clang
533 
534 #endif // LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
535