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 <string>
23 #include <vector>
24 
25 namespace llvm {
26 
27 class MemoryBuffer;
28 
29 } // namespace llvm
30 
31 namespace clang {
32 
33 namespace frontend {
34 
35 enum ActionKind {
36   /// Parse ASTs and list Decl nodes.
37   ASTDeclList,
38 
39   /// Parse ASTs and dump them.
40   ASTDump,
41 
42   /// Parse ASTs and print them.
43   ASTPrint,
44 
45   /// Parse ASTs and view them in Graphviz.
46   ASTView,
47 
48   /// Dump the compiler configuration.
49   DumpCompilerOptions,
50 
51   /// Dump out raw tokens.
52   DumpRawTokens,
53 
54   /// Dump out preprocessed tokens.
55   DumpTokens,
56 
57   /// Emit a .s file.
58   EmitAssembly,
59 
60   /// Emit a .bc file.
61   EmitBC,
62 
63   /// Translate input source into HTML.
64   EmitHTML,
65 
66   /// Emit a .ll file.
67   EmitLLVM,
68 
69   /// Generate LLVM IR, but do not emit anything.
70   EmitLLVMOnly,
71 
72   /// Generate machine code, but don't emit anything.
73   EmitCodeGenOnly,
74 
75   /// Emit a .o file.
76   EmitObj,
77 
78   // Extract API information
79   ExtractAPI,
80 
81   /// Parse and apply any fixits to the source.
82   FixIt,
83 
84   /// Generate pre-compiled module from a module map.
85   GenerateModule,
86 
87   /// Generate pre-compiled module from a C++ module interface file.
88   GenerateModuleInterface,
89 
90   /// Generate pre-compiled module from a set of header files.
91   GenerateHeaderModule,
92 
93   /// Generate a C++20 header unit module from a header file.
94   GenerateHeaderUnit,
95 
96   /// Generate pre-compiled header.
97   GeneratePCH,
98 
99   /// Generate Interface Stub Files.
100   GenerateInterfaceStubs,
101 
102   /// Only execute frontend initialization.
103   InitOnly,
104 
105   /// Dump information about a module file.
106   ModuleFileInfo,
107 
108   /// Load and verify that a PCH file is usable.
109   VerifyPCH,
110 
111   /// Parse and perform semantic analysis.
112   ParseSyntaxOnly,
113 
114   /// Run a plugin action, \see ActionName.
115   PluginAction,
116 
117   /// Print the "preamble" of the input file
118   PrintPreamble,
119 
120   /// -E mode.
121   PrintPreprocessedInput,
122 
123   /// Expand macros but not \#includes.
124   RewriteMacros,
125 
126   /// ObjC->C Rewriter.
127   RewriteObjC,
128 
129   /// Rewriter playground
130   RewriteTest,
131 
132   /// Run one or more source code analyses.
133   RunAnalysis,
134 
135   /// Dump template instantiations
136   TemplightDump,
137 
138   /// Run migrator.
139   MigrateSource,
140 
141   /// Just lex, no output.
142   RunPreprocessorOnly,
143 
144   /// Print the output of the dependency directives source minimizer.
145   PrintDependencyDirectivesSourceMinimizerOutput
146 };
147 
148 } // namespace frontend
149 
150 /// The kind of a file that we've been handed as an input.
151 class InputKind {
152 private:
153   Language Lang;
154   unsigned Fmt : 3;
155   unsigned Preprocessed : 1;
156   unsigned HeaderUnit : 3;
157   unsigned IsHeader : 1;
158 
159 public:
160   /// The input file format.
161   enum Format {
162     Source,
163     ModuleMap,
164     Precompiled
165   };
166 
167   // If we are building a header unit, what kind it is; this affects whether
168   // we look for the file in the user or system include search paths before
169   // flagging a missing input.
170   enum HeaderUnitKind {
171     HeaderUnit_None,
172     HeaderUnit_User,
173     HeaderUnit_System,
174     HeaderUnit_Abs
175   };
176 
177   constexpr InputKind(Language L = Language::Unknown, Format F = Source,
178                       bool PP = false, HeaderUnitKind HU = HeaderUnit_None,
179                       bool HD = false)
180       : Lang(L), Fmt(F), Preprocessed(PP), HeaderUnit(HU), IsHeader(HD) {}
181 
182   Language getLanguage() const { return static_cast<Language>(Lang); }
183   Format getFormat() const { return static_cast<Format>(Fmt); }
184   HeaderUnitKind getHeaderUnitKind() const {
185     return static_cast<HeaderUnitKind>(HeaderUnit);
186   }
187   bool isPreprocessed() const { return Preprocessed; }
188   bool isHeader() const { return IsHeader; }
189   bool isHeaderUnit() const { return HeaderUnit != HeaderUnit_None; }
190 
191   /// Is the input kind fully-unknown?
192   bool isUnknown() const { return Lang == Language::Unknown && Fmt == Source; }
193 
194   /// Is the language of the input some dialect of Objective-C?
195   bool isObjectiveC() const {
196     return Lang == Language::ObjC || Lang == Language::ObjCXX;
197   }
198 
199   InputKind getPreprocessed() const {
200     return InputKind(getLanguage(), getFormat(), true, getHeaderUnitKind(),
201                      isHeader());
202   }
203 
204   InputKind getHeader() const {
205     return InputKind(getLanguage(), getFormat(), isPreprocessed(),
206                      getHeaderUnitKind(), true);
207   }
208 
209   InputKind withHeaderUnit(HeaderUnitKind HU) const {
210     return InputKind(getLanguage(), getFormat(), isPreprocessed(), HU,
211                      isHeader());
212   }
213 
214   InputKind withFormat(Format F) const {
215     return InputKind(getLanguage(), F, isPreprocessed(), getHeaderUnitKind(),
216                      isHeader());
217   }
218 };
219 
220 /// An input file for the front end.
221 class FrontendInputFile {
222   /// The file name, or "-" to read from standard input.
223   std::string File;
224 
225   /// The input, if it comes from a buffer rather than a file. This object
226   /// does not own the buffer, and the caller is responsible for ensuring
227   /// that it outlives any users.
228   llvm::Optional<llvm::MemoryBufferRef> Buffer;
229 
230   /// The kind of input, e.g., C source, AST file, LLVM IR.
231   InputKind Kind;
232 
233   /// Whether we're dealing with a 'system' input (vs. a 'user' input).
234   bool IsSystem = false;
235 
236 public:
237   FrontendInputFile() = default;
238   FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)
239       : File(File.str()), Kind(Kind), IsSystem(IsSystem) {}
240   FrontendInputFile(llvm::MemoryBufferRef Buffer, InputKind Kind,
241                     bool IsSystem = false)
242       : Buffer(Buffer), Kind(Kind), IsSystem(IsSystem) {}
243 
244   InputKind getKind() const { return Kind; }
245   bool isSystem() const { return IsSystem; }
246 
247   bool isEmpty() const { return File.empty() && Buffer == None; }
248   bool isFile() const { return !isBuffer(); }
249   bool isBuffer() const { return Buffer != None; }
250   bool isPreprocessed() const { return Kind.isPreprocessed(); }
251   bool isHeader() const { return Kind.isHeader(); }
252   InputKind::HeaderUnitKind getHeaderUnitKind() const {
253     return Kind.getHeaderUnitKind();
254   }
255 
256   StringRef getFile() const {
257     assert(isFile());
258     return File;
259   }
260 
261   llvm::MemoryBufferRef getBuffer() const {
262     assert(isBuffer());
263     return *Buffer;
264   }
265 };
266 
267 /// FrontendOptions - Options for controlling the behavior of the frontend.
268 class FrontendOptions {
269 public:
270   /// Disable memory freeing on exit.
271   unsigned DisableFree : 1;
272 
273   /// When generating PCH files, instruct the AST writer to create relocatable
274   /// PCH files.
275   unsigned RelocatablePCH : 1;
276 
277   /// Show the -help text.
278   unsigned ShowHelp : 1;
279 
280   /// Show frontend performance metrics and statistics.
281   unsigned ShowStats : 1;
282 
283   /// print the supported cpus for the current target
284   unsigned PrintSupportedCPUs : 1;
285 
286   /// Output time trace profile.
287   unsigned TimeTrace : 1;
288 
289   /// Show the -version text.
290   unsigned ShowVersion : 1;
291 
292   /// Apply fixes even if there are unfixable errors.
293   unsigned FixWhatYouCan : 1;
294 
295   /// Apply fixes only for warnings.
296   unsigned FixOnlyWarnings : 1;
297 
298   /// Apply fixes and recompile.
299   unsigned FixAndRecompile : 1;
300 
301   /// Apply fixes to temporary files.
302   unsigned FixToTemporaries : 1;
303 
304   /// Emit ARC errors even if the migrator can fix them.
305   unsigned ARCMTMigrateEmitARCErrors : 1;
306 
307   /// Skip over function bodies to speed up parsing in cases you do not need
308   /// them (e.g. with code completion).
309   unsigned SkipFunctionBodies : 1;
310 
311   /// Whether we can use the global module index if available.
312   unsigned UseGlobalModuleIndex : 1;
313 
314   /// Whether we can generate the global module index if needed.
315   unsigned GenerateGlobalModuleIndex : 1;
316 
317   /// Whether we include declaration dumps in AST dumps.
318   unsigned ASTDumpDecls : 1;
319 
320   /// Whether we deserialize all decls when forming AST dumps.
321   unsigned ASTDumpAll : 1;
322 
323   /// Whether we include lookup table dumps in AST dumps.
324   unsigned ASTDumpLookups : 1;
325 
326   /// Whether we include declaration type dumps in AST dumps.
327   unsigned ASTDumpDeclTypes : 1;
328 
329   /// Whether we are performing an implicit module build.
330   unsigned BuildingImplicitModule : 1;
331 
332   /// Whether to use a filesystem lock when building implicit modules.
333   unsigned BuildingImplicitModuleUsesLock : 1;
334 
335   /// Whether we should embed all used files into the PCM file.
336   unsigned ModulesEmbedAllFiles : 1;
337 
338   /// Whether timestamps should be written to the produced PCH file.
339   unsigned IncludeTimestamps : 1;
340 
341   /// Should a temporary file be used during compilation.
342   unsigned UseTemporary : 1;
343 
344   /// When using -emit-module, treat the modulemap as a system module.
345   unsigned IsSystemModule : 1;
346 
347   /// Output (and read) PCM files regardless of compiler errors.
348   unsigned AllowPCMWithCompilerErrors : 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   /// Args to pass to the plugins
455   std::map<std::string, std::vector<std::string>> PluginArgs;
456 
457   /// The list of plugin actions to run in addition to the normal action.
458   std::vector<std::string> AddPluginActions;
459 
460   /// The list of plugins to load.
461   std::vector<std::string> Plugins;
462 
463   /// The list of module file extensions.
464   std::vector<std::shared_ptr<ModuleFileExtension>> ModuleFileExtensions;
465 
466   /// The list of module map files to load before processing the input.
467   std::vector<std::string> ModuleMapFiles;
468 
469   /// The list of additional prebuilt module files to load before
470   /// processing the input.
471   std::vector<std::string> ModuleFiles;
472 
473   /// The list of files to embed into the compiled module file.
474   std::vector<std::string> ModulesEmbedFiles;
475 
476   /// The list of AST files to merge.
477   std::vector<std::string> ASTMergeFiles;
478 
479   /// A list of arguments to forward to LLVM's option processing; this
480   /// should only be used for debugging and experimental features.
481   std::vector<std::string> LLVMArgs;
482 
483   /// File name of the file that will provide record layouts
484   /// (in the format produced by -fdump-record-layouts).
485   std::string OverrideRecordLayoutsFile;
486 
487   /// Auxiliary triple for CUDA/HIP compilation.
488   std::string AuxTriple;
489 
490   /// Auxiliary target CPU for CUDA/HIP compilation.
491   Optional<std::string> AuxTargetCPU;
492 
493   /// Auxiliary target features for CUDA/HIP compilation.
494   Optional<std::vector<std::string>> AuxTargetFeatures;
495 
496   /// Filename to write statistics to.
497   std::string StatsFile;
498 
499   /// Minimum time granularity (in microseconds) traced by time profiler.
500   unsigned TimeTraceGranularity;
501 
502   /// Path which stores the output files for -ftime-trace
503   std::string TimeTracePath;
504 
505 public:
506   FrontendOptions()
507       : DisableFree(false), RelocatablePCH(false), ShowHelp(false),
508         ShowStats(false), TimeTrace(false), ShowVersion(false),
509         FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false),
510         FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false),
511         SkipFunctionBodies(false), UseGlobalModuleIndex(true),
512         GenerateGlobalModuleIndex(true), ASTDumpDecls(false),
513         ASTDumpLookups(false), BuildingImplicitModule(false),
514         BuildingImplicitModuleUsesLock(true), ModulesEmbedAllFiles(false),
515         IncludeTimestamps(true), UseTemporary(true),
516         AllowPCMWithCompilerErrors(false), TimeTraceGranularity(500) {}
517 
518   /// getInputKindForExtension - Return the appropriate input kind for a file
519   /// extension. For example, "c" would return Language::C.
520   ///
521   /// \return The input kind for the extension, or Language::Unknown if the
522   /// extension is not recognized.
523   static InputKind getInputKindForExtension(StringRef Extension);
524 };
525 
526 } // namespace clang
527 
528 #endif // LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
529