xref: /freebsd/contrib/llvm-project/clang/include/clang/Frontend/CompilerInvocation.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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   IntrusiveRefCntPtr<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   AnalyzerOptionsRef 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   /// Base class internals.
269   /// @{
270   using CompilerInvocationBase::LangOpts;
271   using CompilerInvocationBase::TargetOpts;
272   using CompilerInvocationBase::DiagnosticOpts;
getHeaderSearchOptsPtr()273   std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() {
274     return HSOpts;
275   }
getPreprocessorOptsPtr()276   std::shared_ptr<PreprocessorOptions> getPreprocessorOptsPtr() {
277     return PPOpts;
278   }
getLangOptsPtr()279   std::shared_ptr<LangOptions> getLangOptsPtr() { return LangOpts; }
280   /// @}
281 
282   /// Create a compiler invocation from a list of input options.
283   /// \returns true on success.
284   ///
285   /// \returns false if an error was encountered while parsing the arguments
286   /// and attempts to recover and continue parsing the rest of the arguments.
287   /// The recovery is best-effort and only guarantees that \p Res will end up in
288   /// one of the vaild-to-access (albeit arbitrary) states.
289   ///
290   /// \param [out] Res - The resulting invocation.
291   /// \param [in] CommandLineArgs - Array of argument strings, this must not
292   /// contain "-cc1".
293   static bool CreateFromArgs(CompilerInvocation &Res,
294                              ArrayRef<const char *> CommandLineArgs,
295                              DiagnosticsEngine &Diags,
296                              const char *Argv0 = nullptr);
297 
298   /// Get the directory where the compiler headers
299   /// reside, relative to the compiler binary (found by the passed in
300   /// arguments).
301   ///
302   /// \param Argv0 - The program path (from argv[0]), for finding the builtin
303   /// compiler path.
304   /// \param MainAddr - The address of main (or some other function in the main
305   /// executable), for finding the builtin compiler path.
306   static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
307 
308   /// Populate \p Opts with the default set of pointer authentication-related
309   /// options given \p LangOpts and \p Triple.
310   ///
311   /// Note: This is intended to be used by tools which must be aware of
312   /// pointer authentication-related code generation, e.g. lldb.
313   static void setDefaultPointerAuthOptions(PointerAuthOptions &Opts,
314                                            const LangOptions &LangOpts,
315                                            const llvm::Triple &Triple);
316 
317   /// Retrieve a module hash string that is suitable for uniquely
318   /// identifying the conditions under which the module was built.
319   std::string getModuleHash() const;
320 
321   /// Check that \p Args can be parsed and re-serialized without change,
322   /// emiting diagnostics for any differences.
323   ///
324   /// This check is only suitable for command-lines that are expected to already
325   /// be canonical.
326   ///
327   /// \return false if there are any errors.
328   static bool checkCC1RoundTrip(ArrayRef<const char *> Args,
329                                 DiagnosticsEngine &Diags,
330                                 const char *Argv0 = nullptr);
331 
332   /// Reset all of the options that are not considered when building a
333   /// module.
334   void resetNonModularOptions();
335 
336   /// Disable implicit modules and canonicalize options that are only used by
337   /// implicit modules.
338   void clearImplicitModuleBuildOptions();
339 
340 private:
341   static bool CreateFromArgsImpl(CompilerInvocation &Res,
342                                  ArrayRef<const char *> CommandLineArgs,
343                                  DiagnosticsEngine &Diags, const char *Argv0);
344 
345   /// Parse command line options that map to LangOptions.
346   static bool ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args,
347                             InputKind IK, const llvm::Triple &T,
348                             std::vector<std::string> &Includes,
349                             DiagnosticsEngine &Diags);
350 
351   /// Parse command line options that map to CodeGenOptions.
352   static bool ParseCodeGenArgs(CodeGenOptions &Opts, llvm::opt::ArgList &Args,
353                                InputKind IK, DiagnosticsEngine &Diags,
354                                const llvm::Triple &T,
355                                const std::string &OutputFile,
356                                const LangOptions &LangOptsRef);
357 };
358 
359 /// Same as \c CompilerInvocation, but with copy-on-write optimization.
360 class CowCompilerInvocation : public CompilerInvocationBase {
361 public:
362   CowCompilerInvocation() = default;
CowCompilerInvocation(const CowCompilerInvocation & X)363   CowCompilerInvocation(const CowCompilerInvocation &X)
364       : CompilerInvocationBase(EmptyConstructor{}) {
365     shallow_copy_assign(X);
366   }
367   CowCompilerInvocation(CowCompilerInvocation &&) = default;
368   CowCompilerInvocation &operator=(const CowCompilerInvocation &X) {
369     shallow_copy_assign(X);
370     return *this;
371   }
372   ~CowCompilerInvocation() = default;
373 
CowCompilerInvocation(const CompilerInvocation & X)374   CowCompilerInvocation(const CompilerInvocation &X)
375       : CompilerInvocationBase(EmptyConstructor{}) {
376     deep_copy_assign(X);
377   }
378 
CowCompilerInvocation(CompilerInvocation && X)379   CowCompilerInvocation(CompilerInvocation &&X)
380       : CompilerInvocationBase(std::move(X)) {}
381 
382   // Const getters are inherited from the base class.
383 
384   /// Mutable getters.
385   /// @{
386   LangOptions &getMutLangOpts();
387   TargetOptions &getMutTargetOpts();
388   DiagnosticOptions &getMutDiagnosticOpts();
389   HeaderSearchOptions &getMutHeaderSearchOpts();
390   PreprocessorOptions &getMutPreprocessorOpts();
391   AnalyzerOptions &getMutAnalyzerOpts();
392   MigratorOptions &getMutMigratorOpts();
393   APINotesOptions &getMutAPINotesOpts();
394   CodeGenOptions &getMutCodeGenOpts();
395   FileSystemOptions &getMutFileSystemOpts();
396   FrontendOptions &getMutFrontendOpts();
397   DependencyOutputOptions &getMutDependencyOutputOpts();
398   PreprocessorOutputOptions &getMutPreprocessorOutputOpts();
399   /// @}
400 };
401 
402 IntrusiveRefCntPtr<llvm::vfs::FileSystem>
403 createVFSFromCompilerInvocation(const CompilerInvocation &CI,
404                                 DiagnosticsEngine &Diags);
405 
406 IntrusiveRefCntPtr<llvm::vfs::FileSystem> createVFSFromCompilerInvocation(
407     const CompilerInvocation &CI, DiagnosticsEngine &Diags,
408     IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);
409 
410 IntrusiveRefCntPtr<llvm::vfs::FileSystem>
411 createVFSFromOverlayFiles(ArrayRef<std::string> VFSOverlayFiles,
412                           DiagnosticsEngine &Diags,
413                           IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);
414 
415 } // namespace clang
416 
417 #endif // LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
418