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