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/Basic/CodeGenOptions.h"
13 #include "clang/Basic/DiagnosticOptions.h"
14 #include "clang/Basic/FileSystemOptions.h"
15 #include "clang/Basic/LLVM.h"
16 #include "clang/Basic/LangOptions.h"
17 #include "clang/Basic/LangStandard.h"
18 #include "clang/Frontend/DependencyOutputOptions.h"
19 #include "clang/Frontend/FrontendOptions.h"
20 #include "clang/Frontend/MigratorOptions.h"
21 #include "clang/Frontend/PreprocessorOutputOptions.h"
22 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
23 #include "llvm/ADT/IntrusiveRefCntPtr.h"
24 #include "llvm/ADT/ArrayRef.h"
25 #include <memory>
26 #include <string>
27 
28 namespace llvm {
29 
30 class Triple;
31 
32 namespace opt {
33 
34 class ArgList;
35 
36 } // namespace opt
37 
38 namespace vfs {
39 
40 class FileSystem;
41 
42 } // namespace vfs
43 
44 } // namespace llvm
45 
46 namespace clang {
47 
48 class DiagnosticsEngine;
49 class HeaderSearchOptions;
50 class PreprocessorOptions;
51 class TargetOptions;
52 
53 /// Fill out Opts based on the options given in Args.
54 ///
55 /// Args must have been created from the OptTable returned by
56 /// createCC1OptTable().
57 ///
58 /// When errors are encountered, return false and, if Diags is non-null,
59 /// report the error(s).
60 bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args,
61                          DiagnosticsEngine *Diags = nullptr,
62                          bool DefaultDiagColor = true);
63 
64 /// The base class of CompilerInvocation with reference semantics.
65 ///
66 /// This class stores option objects behind reference-counted pointers. This is
67 /// useful for clients that want to keep some option object around even after
68 /// CompilerInvocation gets destroyed, without making a copy.
69 ///
70 /// This is a separate class so that we can implement the copy constructor and
71 /// assignment here and leave them defaulted in the rest of CompilerInvocation.
72 class CompilerInvocationRefBase {
73 public:
74   /// Options controlling the language variant.
75   std::shared_ptr<LangOptions> LangOpts;
76 
77   /// Options controlling the target.
78   std::shared_ptr<TargetOptions> TargetOpts;
79 
80   /// Options controlling the diagnostic engine.
81   IntrusiveRefCntPtr<DiagnosticOptions> DiagnosticOpts;
82 
83   /// Options controlling the \#include directive.
84   std::shared_ptr<HeaderSearchOptions> HeaderSearchOpts;
85 
86   /// Options controlling the preprocessor (aside from \#include handling).
87   std::shared_ptr<PreprocessorOptions> PreprocessorOpts;
88 
89   /// Options controlling the static analyzer.
90   AnalyzerOptionsRef AnalyzerOpts;
91 
92   CompilerInvocationRefBase();
93   CompilerInvocationRefBase(const CompilerInvocationRefBase &X);
94   CompilerInvocationRefBase(CompilerInvocationRefBase &&X);
95   CompilerInvocationRefBase &operator=(CompilerInvocationRefBase X);
96   CompilerInvocationRefBase &operator=(CompilerInvocationRefBase &&X);
97   ~CompilerInvocationRefBase();
98 
getLangOpts()99   LangOptions *getLangOpts() { return LangOpts.get(); }
getLangOpts()100   const LangOptions *getLangOpts() const { return LangOpts.get(); }
101 
getTargetOpts()102   TargetOptions &getTargetOpts() { return *TargetOpts.get(); }
getTargetOpts()103   const TargetOptions &getTargetOpts() const { return *TargetOpts.get(); }
104 
getDiagnosticOpts()105   DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; }
106 
getHeaderSearchOpts()107   HeaderSearchOptions &getHeaderSearchOpts() { return *HeaderSearchOpts; }
108 
getHeaderSearchOpts()109   const HeaderSearchOptions &getHeaderSearchOpts() const {
110     return *HeaderSearchOpts;
111   }
112 
getHeaderSearchOptsPtr()113   std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() const {
114     return HeaderSearchOpts;
115   }
116 
getPreprocessorOptsPtr()117   std::shared_ptr<PreprocessorOptions> getPreprocessorOptsPtr() {
118     return PreprocessorOpts;
119   }
120 
getPreprocessorOpts()121   PreprocessorOptions &getPreprocessorOpts() { return *PreprocessorOpts; }
122 
getPreprocessorOpts()123   const PreprocessorOptions &getPreprocessorOpts() const {
124     return *PreprocessorOpts;
125   }
126 
getAnalyzerOpts()127   AnalyzerOptionsRef getAnalyzerOpts() const { return AnalyzerOpts; }
128 };
129 
130 /// The base class of CompilerInvocation with value semantics.
131 class CompilerInvocationValueBase {
132 protected:
133   MigratorOptions MigratorOpts;
134 
135   /// Options controlling IRgen and the backend.
136   CodeGenOptions CodeGenOpts;
137 
138   /// Options controlling dependency output.
139   DependencyOutputOptions DependencyOutputOpts;
140 
141   /// Options controlling file system operations.
142   FileSystemOptions FileSystemOpts;
143 
144   /// Options controlling the frontend itself.
145   FrontendOptions FrontendOpts;
146 
147   /// Options controlling preprocessed output.
148   PreprocessorOutputOptions PreprocessorOutputOpts;
149 
150 public:
getMigratorOpts()151   MigratorOptions &getMigratorOpts() { return MigratorOpts; }
getMigratorOpts()152   const MigratorOptions &getMigratorOpts() const { return MigratorOpts; }
153 
getCodeGenOpts()154   CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
getCodeGenOpts()155   const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }
156 
getDependencyOutputOpts()157   DependencyOutputOptions &getDependencyOutputOpts() {
158     return DependencyOutputOpts;
159   }
160 
getDependencyOutputOpts()161   const DependencyOutputOptions &getDependencyOutputOpts() const {
162     return DependencyOutputOpts;
163   }
164 
getFileSystemOpts()165   FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
166 
getFileSystemOpts()167   const FileSystemOptions &getFileSystemOpts() const {
168     return FileSystemOpts;
169   }
170 
getFrontendOpts()171   FrontendOptions &getFrontendOpts() { return FrontendOpts; }
getFrontendOpts()172   const FrontendOptions &getFrontendOpts() const { return FrontendOpts; }
173 
getPreprocessorOutputOpts()174   PreprocessorOutputOptions &getPreprocessorOutputOpts() {
175     return PreprocessorOutputOpts;
176   }
177 
getPreprocessorOutputOpts()178   const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
179     return PreprocessorOutputOpts;
180   }
181 };
182 
183 /// Helper class for holding the data necessary to invoke the compiler.
184 ///
185 /// This class is designed to represent an abstract "invocation" of the
186 /// compiler, including data such as the include paths, the code generation
187 /// options, the warning flags, and so on.
188 class CompilerInvocation : public CompilerInvocationRefBase,
189                            public CompilerInvocationValueBase {
190 public:
191   /// Create a compiler invocation from a list of input options.
192   /// \returns true on success.
193   ///
194   /// \returns false if an error was encountered while parsing the arguments
195   /// and attempts to recover and continue parsing the rest of the arguments.
196   /// The recovery is best-effort and only guarantees that \p Res will end up in
197   /// one of the vaild-to-access (albeit arbitrary) states.
198   ///
199   /// \param [out] Res - The resulting invocation.
200   /// \param [in] CommandLineArgs - Array of argument strings, this must not
201   /// contain "-cc1".
202   static bool CreateFromArgs(CompilerInvocation &Res,
203                              ArrayRef<const char *> CommandLineArgs,
204                              DiagnosticsEngine &Diags,
205                              const char *Argv0 = nullptr);
206 
207   /// Get the directory where the compiler headers
208   /// reside, relative to the compiler binary (found by the passed in
209   /// arguments).
210   ///
211   /// \param Argv0 - The program path (from argv[0]), for finding the builtin
212   /// compiler path.
213   /// \param MainAddr - The address of main (or some other function in the main
214   /// executable), for finding the builtin compiler path.
215   static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
216 
217   /// Set language defaults for the given input language and
218   /// language standard in the given LangOptions object.
219   ///
220   /// \param Opts - The LangOptions object to set up.
221   /// \param IK - The input language.
222   /// \param T - The target triple.
223   /// \param Includes - The affected list of included files.
224   /// \param LangStd - The input language standard.
225   static void
226   setLangDefaults(LangOptions &Opts, InputKind IK, const llvm::Triple &T,
227                   std::vector<std::string> &Includes,
228                   LangStandard::Kind LangStd = LangStandard::lang_unspecified);
229 
230   /// Retrieve a module hash string that is suitable for uniquely
231   /// identifying the conditions under which the module was built.
232   std::string getModuleHash() const;
233 
234   using StringAllocator = llvm::function_ref<const char *(const llvm::Twine &)>;
235   /// Generate a cc1-compatible command line arguments from this instance.
236   ///
237   /// \param [out] Args - The generated arguments. Note that the caller is
238   /// responsible for inserting the path to the clang executable and "-cc1" if
239   /// desired.
240   /// \param SA - A function that given a Twine can allocate storage for a given
241   /// command line argument and return a pointer to the newly allocated string.
242   /// The returned pointer is what gets appended to Args.
243   void generateCC1CommandLine(llvm::SmallVectorImpl<const char *> &Args,
244                               StringAllocator SA) const;
245 
246 private:
247   static bool CreateFromArgsImpl(CompilerInvocation &Res,
248                                  ArrayRef<const char *> CommandLineArgs,
249                                  DiagnosticsEngine &Diags, const char *Argv0);
250 
251   /// Generate command line options from DiagnosticOptions.
252   static void GenerateDiagnosticArgs(const DiagnosticOptions &Opts,
253                                      SmallVectorImpl<const char *> &Args,
254                                      StringAllocator SA, bool DefaultDiagColor);
255 
256   /// Parse command line options that map to LangOptions.
257   static bool ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args,
258                             InputKind IK, const llvm::Triple &T,
259                             std::vector<std::string> &Includes,
260                             DiagnosticsEngine &Diags);
261 
262   /// Generate command line options from LangOptions.
263   static void GenerateLangArgs(const LangOptions &Opts,
264                                SmallVectorImpl<const char *> &Args,
265                                StringAllocator SA, const llvm::Triple &T,
266                                InputKind IK);
267 
268   /// Parse command line options that map to CodeGenOptions.
269   static bool ParseCodeGenArgs(CodeGenOptions &Opts, llvm::opt::ArgList &Args,
270                                InputKind IK, DiagnosticsEngine &Diags,
271                                const llvm::Triple &T,
272                                const std::string &OutputFile,
273                                const LangOptions &LangOptsRef);
274 
275   // Generate command line options from CodeGenOptions.
276   static void GenerateCodeGenArgs(const CodeGenOptions &Opts,
277                                   SmallVectorImpl<const char *> &Args,
278                                   StringAllocator SA, const llvm::Triple &T,
279                                   const std::string &OutputFile,
280                                   const LangOptions *LangOpts);
281 };
282 
283 IntrusiveRefCntPtr<llvm::vfs::FileSystem>
284 createVFSFromCompilerInvocation(const CompilerInvocation &CI,
285                                 DiagnosticsEngine &Diags);
286 
287 IntrusiveRefCntPtr<llvm::vfs::FileSystem> createVFSFromCompilerInvocation(
288     const CompilerInvocation &CI, DiagnosticsEngine &Diags,
289     IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);
290 
291 } // namespace clang
292 
293 #endif // LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
294