xref: /freebsd/contrib/llvm-project/clang/include/clang/Frontend/CompilerInvocation.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- CompilerInvocation.h - Compiler Invocation Helper Data ---*- 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_COMPILERINVOCATION_H
10 #define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
11 
12 #include "clang/APINotes/APINotesOptions.h"
13 #include "clang/Basic/CodeGenOptions.h"
14 #include "clang/Basic/DiagnosticOptions.h"
15 #include "clang/Basic/FileSystemOptions.h"
16 #include "clang/Basic/LLVM.h"
17 #include "clang/Basic/LangOptions.h"
18 #include "clang/Basic/LangStandard.h"
19 #include "clang/Frontend/DependencyOutputOptions.h"
20 #include "clang/Frontend/FrontendOptions.h"
21 #include "clang/Frontend/MigratorOptions.h"
22 #include "clang/Frontend/PreprocessorOutputOptions.h"
23 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
24 #include "llvm/ADT/IntrusiveRefCntPtr.h"
25 #include "llvm/ADT/ArrayRef.h"
26 #include <memory>
27 #include <string>
28 
29 namespace llvm {
30 
31 class Triple;
32 
33 namespace opt {
34 
35 class ArgList;
36 
37 } // namespace opt
38 
39 namespace vfs {
40 
41 class FileSystem;
42 
43 } // namespace vfs
44 
45 } // namespace llvm
46 
47 namespace clang {
48 
49 class DiagnosticsEngine;
50 class HeaderSearchOptions;
51 class PreprocessorOptions;
52 class TargetOptions;
53 
54 // This lets us create the DiagnosticsEngine with a properly-filled-out
55 // DiagnosticOptions instance.
56 std::unique_ptr<DiagnosticOptions>
57 CreateAndPopulateDiagOpts(ArrayRef<const char *> Argv);
58 
59 /// Fill out Opts based on the options given in Args.
60 ///
61 /// Args must have been created from the OptTable returned by
62 /// createCC1OptTable().
63 ///
64 /// When errors are encountered, return false and, if Diags is non-null,
65 /// report the error(s).
66 bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args,
67                          DiagnosticsEngine *Diags = nullptr,
68                          bool DefaultDiagColor = true);
69 
70 /// The base class of CompilerInvocation. It keeps individual option objects
71 /// behind reference-counted pointers, which is useful for clients that want to
72 /// keep select option objects alive (even after CompilerInvocation gets
73 /// destroyed) without making a copy.
74 class CompilerInvocationBase {
75 protected:
76   /// Options controlling the language variant.
77   std::shared_ptr<LangOptions> LangOpts;
78 
79   /// Options controlling the target.
80   std::shared_ptr<TargetOptions> TargetOpts;
81 
82   /// Options controlling the diagnostic engine.
83   std::shared_ptr<DiagnosticOptions> DiagnosticOpts;
84 
85   /// Options controlling the \#include directive.
86   std::shared_ptr<HeaderSearchOptions> HSOpts;
87 
88   /// Options controlling the preprocessor (aside from \#include handling).
89   std::shared_ptr<PreprocessorOptions> PPOpts;
90 
91   /// Options controlling the static analyzer.
92   std::shared_ptr<AnalyzerOptions> AnalyzerOpts;
93 
94   std::shared_ptr<MigratorOptions> MigratorOpts;
95 
96   /// Options controlling API notes.
97   std::shared_ptr<APINotesOptions> APINotesOpts;
98 
99   /// Options controlling IRgen and the backend.
100   std::shared_ptr<CodeGenOptions> CodeGenOpts;
101 
102   /// Options controlling file system operations.
103   std::shared_ptr<FileSystemOptions> FSOpts;
104 
105   /// Options controlling the frontend itself.
106   std::shared_ptr<FrontendOptions> FrontendOpts;
107 
108   /// Options controlling dependency output.
109   std::shared_ptr<DependencyOutputOptions> DependencyOutputOpts;
110 
111   /// Options controlling preprocessed output.
112   std::shared_ptr<PreprocessorOutputOptions> PreprocessorOutputOpts;
113 
114   /// Dummy tag type whose instance can be passed into the constructor to
115   /// prevent creation of the reference-counted option objects.
116   struct EmptyConstructor {};
117 
118   CompilerInvocationBase();
CompilerInvocationBase(EmptyConstructor)119   CompilerInvocationBase(EmptyConstructor) {}
120   CompilerInvocationBase(const CompilerInvocationBase &X) = delete;
121   CompilerInvocationBase(CompilerInvocationBase &&X) = default;
122   CompilerInvocationBase &operator=(const CompilerInvocationBase &X) = delete;
123   CompilerInvocationBase &deep_copy_assign(const CompilerInvocationBase &X);
124   CompilerInvocationBase &shallow_copy_assign(const CompilerInvocationBase &X);
125   CompilerInvocationBase &operator=(CompilerInvocationBase &&X) = default;
126   ~CompilerInvocationBase() = default;
127 
128 public:
129   /// Const getters.
130   /// @{
getLangOpts()131   const LangOptions &getLangOpts() const { return *LangOpts; }
getTargetOpts()132   const TargetOptions &getTargetOpts() const { return *TargetOpts; }
getDiagnosticOpts()133   const DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; }
getHeaderSearchOpts()134   const HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; }
getPreprocessorOpts()135   const PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; }
getAnalyzerOpts()136   const AnalyzerOptions &getAnalyzerOpts() const { return *AnalyzerOpts; }
getMigratorOpts()137   const MigratorOptions &getMigratorOpts() const { return *MigratorOpts; }
getAPINotesOpts()138   const APINotesOptions &getAPINotesOpts() const { return *APINotesOpts; }
getCodeGenOpts()139   const CodeGenOptions &getCodeGenOpts() const { return *CodeGenOpts; }
getFileSystemOpts()140   const FileSystemOptions &getFileSystemOpts() const { return *FSOpts; }
getFrontendOpts()141   const FrontendOptions &getFrontendOpts() const { return *FrontendOpts; }
getDependencyOutputOpts()142   const DependencyOutputOptions &getDependencyOutputOpts() const {
143     return *DependencyOutputOpts;
144   }
getPreprocessorOutputOpts()145   const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
146     return *PreprocessorOutputOpts;
147   }
148   /// @}
149 
150   /// Command line generation.
151   /// @{
152   using StringAllocator = llvm::function_ref<const char *(const Twine &)>;
153   /// Generate cc1-compatible command line arguments from this instance.
154   ///
155   /// \param [out] Args - The generated arguments. Note that the caller is
156   /// responsible for inserting the path to the clang executable and "-cc1" if
157   /// desired.
158   /// \param SA - A function that given a Twine can allocate storage for a given
159   /// command line argument and return a pointer to the newly allocated string.
160   /// The returned pointer is what gets appended to Args.
generateCC1CommandLine(llvm::SmallVectorImpl<const char * > & Args,StringAllocator SA)161   void generateCC1CommandLine(llvm::SmallVectorImpl<const char *> &Args,
162                               StringAllocator SA) const {
163     generateCC1CommandLine([&](const Twine &Arg) {
164       // No need to allocate static string literals.
165       Args.push_back(Arg.isSingleStringLiteral()
166                          ? Arg.getSingleStringRef().data()
167                          : SA(Arg));
168     });
169   }
170 
171   using ArgumentConsumer = llvm::function_ref<void(const Twine &)>;
172   /// Generate cc1-compatible command line arguments from this instance.
173   ///
174   /// \param Consumer - Callback that gets invoked for every single generated
175   /// command line argument.
176   void generateCC1CommandLine(ArgumentConsumer Consumer) const;
177 
178   /// Generate cc1-compatible command line arguments from this instance,
179   /// wrapping the result as a std::vector<std::string>.
180   ///
181   /// This is a (less-efficient) wrapper over generateCC1CommandLine().
182   std::vector<std::string> getCC1CommandLine() const;
183 
184 private:
185   /// Generate command line options from DiagnosticOptions.
186   static void GenerateDiagnosticArgs(const DiagnosticOptions &Opts,
187                                      ArgumentConsumer Consumer,
188                                      bool DefaultDiagColor);
189 
190   /// Generate command line options from LangOptions.
191   static void GenerateLangArgs(const LangOptions &Opts,
192                                ArgumentConsumer Consumer, const llvm::Triple &T,
193                                InputKind IK);
194 
195   // Generate command line options from CodeGenOptions.
196   static void GenerateCodeGenArgs(const CodeGenOptions &Opts,
197                                   ArgumentConsumer Consumer,
198                                   const llvm::Triple &T,
199                                   const std::string &OutputFile,
200                                   const LangOptions *LangOpts);
201   /// @}
202 };
203 
204 class CowCompilerInvocation;
205 
206 /// Helper class for holding the data necessary to invoke the compiler.
207 ///
208 /// This class is designed to represent an abstract "invocation" of the
209 /// compiler, including data such as the include paths, the code generation
210 /// options, the warning flags, and so on.
211 class CompilerInvocation : public CompilerInvocationBase {
212 public:
213   CompilerInvocation() = default;
CompilerInvocation(const CompilerInvocation & X)214   CompilerInvocation(const CompilerInvocation &X)
215       : CompilerInvocationBase(EmptyConstructor{}) {
216     deep_copy_assign(X);
217   }
218   CompilerInvocation(CompilerInvocation &&) = default;
219   CompilerInvocation &operator=(const CompilerInvocation &X) {
220     deep_copy_assign(X);
221     return *this;
222   }
223   ~CompilerInvocation() = default;
224 
225   explicit CompilerInvocation(const CowCompilerInvocation &X);
226   CompilerInvocation &operator=(const CowCompilerInvocation &X);
227 
228   /// Const getters.
229   /// @{
230   // Note: These need to be pulled in manually. Otherwise, they get hidden by
231   // the mutable getters with the same names.
232   using CompilerInvocationBase::getLangOpts;
233   using CompilerInvocationBase::getTargetOpts;
234   using CompilerInvocationBase::getDiagnosticOpts;
235   using CompilerInvocationBase::getHeaderSearchOpts;
236   using CompilerInvocationBase::getPreprocessorOpts;
237   using CompilerInvocationBase::getAnalyzerOpts;
238   using CompilerInvocationBase::getMigratorOpts;
239   using CompilerInvocationBase::getAPINotesOpts;
240   using CompilerInvocationBase::getCodeGenOpts;
241   using CompilerInvocationBase::getFileSystemOpts;
242   using CompilerInvocationBase::getFrontendOpts;
243   using CompilerInvocationBase::getDependencyOutputOpts;
244   using CompilerInvocationBase::getPreprocessorOutputOpts;
245   /// @}
246 
247   /// Mutable getters.
248   /// @{
getLangOpts()249   LangOptions &getLangOpts() { return *LangOpts; }
getTargetOpts()250   TargetOptions &getTargetOpts() { return *TargetOpts; }
getDiagnosticOpts()251   DiagnosticOptions &getDiagnosticOpts() { return *DiagnosticOpts; }
getHeaderSearchOpts()252   HeaderSearchOptions &getHeaderSearchOpts() { return *HSOpts; }
getPreprocessorOpts()253   PreprocessorOptions &getPreprocessorOpts() { return *PPOpts; }
getAnalyzerOpts()254   AnalyzerOptions &getAnalyzerOpts() { return *AnalyzerOpts; }
getMigratorOpts()255   MigratorOptions &getMigratorOpts() { return *MigratorOpts; }
getAPINotesOpts()256   APINotesOptions &getAPINotesOpts() { return *APINotesOpts; }
getCodeGenOpts()257   CodeGenOptions &getCodeGenOpts() { return *CodeGenOpts; }
getFileSystemOpts()258   FileSystemOptions &getFileSystemOpts() { return *FSOpts; }
getFrontendOpts()259   FrontendOptions &getFrontendOpts() { return *FrontendOpts; }
getDependencyOutputOpts()260   DependencyOutputOptions &getDependencyOutputOpts() {
261     return *DependencyOutputOpts;
262   }
getPreprocessorOutputOpts()263   PreprocessorOutputOptions &getPreprocessorOutputOpts() {
264     return *PreprocessorOutputOpts;
265   }
266   /// @}
267 
268   /// Create a compiler invocation from a list of input options.
269   /// \returns true on success.
270   ///
271   /// \returns false if an error was encountered while parsing the arguments
272   /// and attempts to recover and continue parsing the rest of the arguments.
273   /// The recovery is best-effort and only guarantees that \p Res will end up in
274   /// one of the vaild-to-access (albeit arbitrary) states.
275   ///
276   /// \param [out] Res - The resulting invocation.
277   /// \param [in] CommandLineArgs - Array of argument strings, this must not
278   /// contain "-cc1".
279   static bool CreateFromArgs(CompilerInvocation &Res,
280                              ArrayRef<const char *> CommandLineArgs,
281                              DiagnosticsEngine &Diags,
282                              const char *Argv0 = nullptr);
283 
284   /// Get the directory where the compiler headers
285   /// reside, relative to the compiler binary (found by the passed in
286   /// arguments).
287   ///
288   /// \param Argv0 - The program path (from argv[0]), for finding the builtin
289   /// compiler path.
290   /// \param MainAddr - The address of main (or some other function in the main
291   /// executable), for finding the builtin compiler path.
292   static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
293 
294   /// Populate \p Opts with the default set of pointer authentication-related
295   /// options given \p LangOpts and \p Triple.
296   ///
297   /// Note: This is intended to be used by tools which must be aware of
298   /// pointer authentication-related code generation, e.g. lldb.
299   static void setDefaultPointerAuthOptions(PointerAuthOptions &Opts,
300                                            const LangOptions &LangOpts,
301                                            const llvm::Triple &Triple);
302 
303   /// Retrieve a module hash string that is suitable for uniquely
304   /// identifying the conditions under which the module was built.
305   std::string getModuleHash() const;
306 
307   /// Check that \p Args can be parsed and re-serialized without change,
308   /// emiting diagnostics for any differences.
309   ///
310   /// This check is only suitable for command-lines that are expected to already
311   /// be canonical.
312   ///
313   /// \return false if there are any errors.
314   static bool checkCC1RoundTrip(ArrayRef<const char *> Args,
315                                 DiagnosticsEngine &Diags,
316                                 const char *Argv0 = nullptr);
317 
318   /// Reset all of the options that are not considered when building a
319   /// module.
320   void resetNonModularOptions();
321 
322   /// Disable implicit modules and canonicalize options that are only used by
323   /// implicit modules.
324   void clearImplicitModuleBuildOptions();
325 
326 private:
327   static bool CreateFromArgsImpl(CompilerInvocation &Res,
328                                  ArrayRef<const char *> CommandLineArgs,
329                                  DiagnosticsEngine &Diags, const char *Argv0);
330 
331   /// Parse command line options that map to LangOptions.
332   static bool ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args,
333                             InputKind IK, const llvm::Triple &T,
334                             std::vector<std::string> &Includes,
335                             DiagnosticsEngine &Diags);
336 
337   /// Parse command line options that map to CodeGenOptions.
338   static bool ParseCodeGenArgs(CodeGenOptions &Opts, llvm::opt::ArgList &Args,
339                                InputKind IK, DiagnosticsEngine &Diags,
340                                const llvm::Triple &T,
341                                const std::string &OutputFile,
342                                const LangOptions &LangOptsRef);
343 };
344 
345 /// Same as \c CompilerInvocation, but with copy-on-write optimization.
346 class CowCompilerInvocation : public CompilerInvocationBase {
347 public:
348   CowCompilerInvocation() = default;
CowCompilerInvocation(const CowCompilerInvocation & X)349   CowCompilerInvocation(const CowCompilerInvocation &X)
350       : CompilerInvocationBase(EmptyConstructor{}) {
351     shallow_copy_assign(X);
352   }
353   CowCompilerInvocation(CowCompilerInvocation &&) = default;
354   CowCompilerInvocation &operator=(const CowCompilerInvocation &X) {
355     shallow_copy_assign(X);
356     return *this;
357   }
358   ~CowCompilerInvocation() = default;
359 
CowCompilerInvocation(const CompilerInvocation & X)360   CowCompilerInvocation(const CompilerInvocation &X)
361       : CompilerInvocationBase(EmptyConstructor{}) {
362     deep_copy_assign(X);
363   }
364 
CowCompilerInvocation(CompilerInvocation && X)365   CowCompilerInvocation(CompilerInvocation &&X)
366       : CompilerInvocationBase(std::move(X)) {}
367 
368   // Const getters are inherited from the base class.
369 
370   /// Mutable getters.
371   /// @{
372   LangOptions &getMutLangOpts();
373   TargetOptions &getMutTargetOpts();
374   DiagnosticOptions &getMutDiagnosticOpts();
375   HeaderSearchOptions &getMutHeaderSearchOpts();
376   PreprocessorOptions &getMutPreprocessorOpts();
377   AnalyzerOptions &getMutAnalyzerOpts();
378   MigratorOptions &getMutMigratorOpts();
379   APINotesOptions &getMutAPINotesOpts();
380   CodeGenOptions &getMutCodeGenOpts();
381   FileSystemOptions &getMutFileSystemOpts();
382   FrontendOptions &getMutFrontendOpts();
383   DependencyOutputOptions &getMutDependencyOutputOpts();
384   PreprocessorOutputOptions &getMutPreprocessorOutputOpts();
385   /// @}
386 };
387 
388 IntrusiveRefCntPtr<llvm::vfs::FileSystem>
389 createVFSFromCompilerInvocation(const CompilerInvocation &CI,
390                                 DiagnosticsEngine &Diags);
391 
392 IntrusiveRefCntPtr<llvm::vfs::FileSystem> createVFSFromCompilerInvocation(
393     const CompilerInvocation &CI, DiagnosticsEngine &Diags,
394     IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);
395 
396 IntrusiveRefCntPtr<llvm::vfs::FileSystem>
397 createVFSFromOverlayFiles(ArrayRef<std::string> VFSOverlayFiles,
398                           DiagnosticsEngine &Diags,
399                           IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);
400 
401 } // namespace clang
402 
403 #endif // LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
404