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();
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   /// @{
131   const LangOptions &getLangOpts() const { return *LangOpts; }
132   const TargetOptions &getTargetOpts() const { return *TargetOpts; }
133   const DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; }
134   const HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; }
135   const PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; }
136   const AnalyzerOptions &getAnalyzerOpts() const { return *AnalyzerOpts; }
137   const MigratorOptions &getMigratorOpts() const { return *MigratorOpts; }
138   const APINotesOptions &getAPINotesOpts() const { return *APINotesOpts; }
139   const CodeGenOptions &getCodeGenOpts() const { return *CodeGenOpts; }
140   const FileSystemOptions &getFileSystemOpts() const { return *FSOpts; }
141   const FrontendOptions &getFrontendOpts() const { return *FrontendOpts; }
142   const DependencyOutputOptions &getDependencyOutputOpts() const {
143     return *DependencyOutputOpts;
144   }
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.
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 /// Helper class for holding the data necessary to invoke the compiler.
205 ///
206 /// This class is designed to represent an abstract "invocation" of the
207 /// compiler, including data such as the include paths, the code generation
208 /// options, the warning flags, and so on.
209 class CompilerInvocation : public CompilerInvocationBase {
210 public:
211   CompilerInvocation() = default;
212   CompilerInvocation(const CompilerInvocation &X)
213       : CompilerInvocationBase(EmptyConstructor{}) {
214     deep_copy_assign(X);
215   }
216   CompilerInvocation(CompilerInvocation &&) = default;
217   CompilerInvocation &operator=(const CompilerInvocation &X) {
218     deep_copy_assign(X);
219     return *this;
220   }
221   ~CompilerInvocation() = default;
222 
223   /// Const getters.
224   /// @{
225   // Note: These need to be pulled in manually. Otherwise, they get hidden by
226   // the mutable getters with the same names.
227   using CompilerInvocationBase::getLangOpts;
228   using CompilerInvocationBase::getTargetOpts;
229   using CompilerInvocationBase::getDiagnosticOpts;
230   using CompilerInvocationBase::getHeaderSearchOpts;
231   using CompilerInvocationBase::getPreprocessorOpts;
232   using CompilerInvocationBase::getAnalyzerOpts;
233   using CompilerInvocationBase::getMigratorOpts;
234   using CompilerInvocationBase::getAPINotesOpts;
235   using CompilerInvocationBase::getCodeGenOpts;
236   using CompilerInvocationBase::getFileSystemOpts;
237   using CompilerInvocationBase::getFrontendOpts;
238   using CompilerInvocationBase::getDependencyOutputOpts;
239   using CompilerInvocationBase::getPreprocessorOutputOpts;
240   /// @}
241 
242   /// Mutable getters.
243   /// @{
244   LangOptions &getLangOpts() { return *LangOpts; }
245   TargetOptions &getTargetOpts() { return *TargetOpts; }
246   DiagnosticOptions &getDiagnosticOpts() { return *DiagnosticOpts; }
247   HeaderSearchOptions &getHeaderSearchOpts() { return *HSOpts; }
248   PreprocessorOptions &getPreprocessorOpts() { return *PPOpts; }
249   AnalyzerOptions &getAnalyzerOpts() { return *AnalyzerOpts; }
250   MigratorOptions &getMigratorOpts() { return *MigratorOpts; }
251   APINotesOptions &getAPINotesOpts() { return *APINotesOpts; }
252   CodeGenOptions &getCodeGenOpts() { return *CodeGenOpts; }
253   FileSystemOptions &getFileSystemOpts() { return *FSOpts; }
254   FrontendOptions &getFrontendOpts() { return *FrontendOpts; }
255   DependencyOutputOptions &getDependencyOutputOpts() {
256     return *DependencyOutputOpts;
257   }
258   PreprocessorOutputOptions &getPreprocessorOutputOpts() {
259     return *PreprocessorOutputOpts;
260   }
261   /// @}
262 
263   /// Base class internals.
264   /// @{
265   using CompilerInvocationBase::LangOpts;
266   using CompilerInvocationBase::TargetOpts;
267   using CompilerInvocationBase::DiagnosticOpts;
268   std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() {
269     return HSOpts;
270   }
271   std::shared_ptr<PreprocessorOptions> getPreprocessorOptsPtr() {
272     return PPOpts;
273   }
274   /// @}
275 
276   /// Create a compiler invocation from a list of input options.
277   /// \returns true on success.
278   ///
279   /// \returns false if an error was encountered while parsing the arguments
280   /// and attempts to recover and continue parsing the rest of the arguments.
281   /// The recovery is best-effort and only guarantees that \p Res will end up in
282   /// one of the vaild-to-access (albeit arbitrary) states.
283   ///
284   /// \param [out] Res - The resulting invocation.
285   /// \param [in] CommandLineArgs - Array of argument strings, this must not
286   /// contain "-cc1".
287   static bool CreateFromArgs(CompilerInvocation &Res,
288                              ArrayRef<const char *> CommandLineArgs,
289                              DiagnosticsEngine &Diags,
290                              const char *Argv0 = nullptr);
291 
292   /// Get the directory where the compiler headers
293   /// reside, relative to the compiler binary (found by the passed in
294   /// arguments).
295   ///
296   /// \param Argv0 - The program path (from argv[0]), for finding the builtin
297   /// compiler path.
298   /// \param MainAddr - The address of main (or some other function in the main
299   /// executable), for finding the builtin compiler path.
300   static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
301 
302   /// Retrieve a module hash string that is suitable for uniquely
303   /// identifying the conditions under which the module was built.
304   std::string getModuleHash() const;
305 
306   /// Check that \p Args can be parsed and re-serialized without change,
307   /// emiting diagnostics for any differences.
308   ///
309   /// This check is only suitable for command-lines that are expected to already
310   /// be canonical.
311   ///
312   /// \return false if there are any errors.
313   static bool checkCC1RoundTrip(ArrayRef<const char *> Args,
314                                 DiagnosticsEngine &Diags,
315                                 const char *Argv0 = nullptr);
316 
317   /// Reset all of the options that are not considered when building a
318   /// module.
319   void resetNonModularOptions();
320 
321   /// Disable implicit modules and canonicalize options that are only used by
322   /// implicit modules.
323   void clearImplicitModuleBuildOptions();
324 
325 private:
326   static bool CreateFromArgsImpl(CompilerInvocation &Res,
327                                  ArrayRef<const char *> CommandLineArgs,
328                                  DiagnosticsEngine &Diags, const char *Argv0);
329 
330   /// Parse command line options that map to LangOptions.
331   static bool ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args,
332                             InputKind IK, const llvm::Triple &T,
333                             std::vector<std::string> &Includes,
334                             DiagnosticsEngine &Diags);
335 
336   /// Parse command line options that map to CodeGenOptions.
337   static bool ParseCodeGenArgs(CodeGenOptions &Opts, llvm::opt::ArgList &Args,
338                                InputKind IK, DiagnosticsEngine &Diags,
339                                const llvm::Triple &T,
340                                const std::string &OutputFile,
341                                const LangOptions &LangOptsRef);
342 };
343 
344 /// Same as \c CompilerInvocation, but with copy-on-write optimization.
345 class CowCompilerInvocation : public CompilerInvocationBase {
346 public:
347   CowCompilerInvocation() = default;
348   CowCompilerInvocation(const CowCompilerInvocation &X)
349       : CompilerInvocationBase(EmptyConstructor{}) {
350     shallow_copy_assign(X);
351   }
352   CowCompilerInvocation(CowCompilerInvocation &&) = default;
353   CowCompilerInvocation &operator=(const CowCompilerInvocation &X) {
354     shallow_copy_assign(X);
355     return *this;
356   }
357   ~CowCompilerInvocation() = default;
358 
359   CowCompilerInvocation(const CompilerInvocation &X)
360       : CompilerInvocationBase(EmptyConstructor{}) {
361     deep_copy_assign(X);
362   }
363 
364   CowCompilerInvocation(CompilerInvocation &&X)
365       : CompilerInvocationBase(std::move(X)) {}
366 
367   // Const getters are inherited from the base class.
368 
369   /// Mutable getters.
370   /// @{
371   LangOptions &getMutLangOpts();
372   TargetOptions &getMutTargetOpts();
373   DiagnosticOptions &getMutDiagnosticOpts();
374   HeaderSearchOptions &getMutHeaderSearchOpts();
375   PreprocessorOptions &getMutPreprocessorOpts();
376   AnalyzerOptions &getMutAnalyzerOpts();
377   MigratorOptions &getMutMigratorOpts();
378   APINotesOptions &getMutAPINotesOpts();
379   CodeGenOptions &getMutCodeGenOpts();
380   FileSystemOptions &getMutFileSystemOpts();
381   FrontendOptions &getMutFrontendOpts();
382   DependencyOutputOptions &getMutDependencyOutputOpts();
383   PreprocessorOutputOptions &getMutPreprocessorOutputOpts();
384   /// @}
385 };
386 
387 IntrusiveRefCntPtr<llvm::vfs::FileSystem>
388 createVFSFromCompilerInvocation(const CompilerInvocation &CI,
389                                 DiagnosticsEngine &Diags);
390 
391 IntrusiveRefCntPtr<llvm::vfs::FileSystem> createVFSFromCompilerInvocation(
392     const CompilerInvocation &CI, DiagnosticsEngine &Diags,
393     IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);
394 
395 IntrusiveRefCntPtr<llvm::vfs::FileSystem>
396 createVFSFromOverlayFiles(ArrayRef<std::string> VFSOverlayFiles,
397                           DiagnosticsEngine &Diags,
398                           IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);
399 
400 } // namespace clang
401 
402 #endif // LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
403