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