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 ; |
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 &() 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(Consumer: [&](const Twine &Arg) { |
164 | // No need to allocate static string literals. |
165 | Args.push_back(Elt: 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; |
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 | /// @{ |
249 | LangOptions &getLangOpts() { return *LangOpts; } |
250 | TargetOptions &getTargetOpts() { return *TargetOpts; } |
251 | DiagnosticOptions &getDiagnosticOpts() { return *DiagnosticOpts; } |
252 | HeaderSearchOptions &() { return *HSOpts; } |
253 | PreprocessorOptions &getPreprocessorOpts() { return *PPOpts; } |
254 | AnalyzerOptions &getAnalyzerOpts() { return *AnalyzerOpts; } |
255 | MigratorOptions &getMigratorOpts() { return *MigratorOpts; } |
256 | APINotesOptions &getAPINotesOpts() { return *APINotesOpts; } |
257 | CodeGenOptions &getCodeGenOpts() { return *CodeGenOpts; } |
258 | FileSystemOptions &getFileSystemOpts() { return *FSOpts; } |
259 | FrontendOptions &getFrontendOpts() { return *FrontendOpts; } |
260 | DependencyOutputOptions &getDependencyOutputOpts() { |
261 | return *DependencyOutputOpts; |
262 | } |
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; |
273 | std::shared_ptr<HeaderSearchOptions> () { |
274 | return HSOpts; |
275 | } |
276 | std::shared_ptr<PreprocessorOptions> getPreprocessorOptsPtr() { |
277 | return PPOpts; |
278 | } |
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 | /// Retrieve a module hash string that is suitable for uniquely |
309 | /// identifying the conditions under which the module was built. |
310 | std::string getModuleHash() const; |
311 | |
312 | /// Check that \p Args can be parsed and re-serialized without change, |
313 | /// emiting diagnostics for any differences. |
314 | /// |
315 | /// This check is only suitable for command-lines that are expected to already |
316 | /// be canonical. |
317 | /// |
318 | /// \return false if there are any errors. |
319 | static bool checkCC1RoundTrip(ArrayRef<const char *> Args, |
320 | DiagnosticsEngine &Diags, |
321 | const char *Argv0 = nullptr); |
322 | |
323 | /// Reset all of the options that are not considered when building a |
324 | /// module. |
325 | void resetNonModularOptions(); |
326 | |
327 | /// Disable implicit modules and canonicalize options that are only used by |
328 | /// implicit modules. |
329 | void clearImplicitModuleBuildOptions(); |
330 | |
331 | private: |
332 | static bool CreateFromArgsImpl(CompilerInvocation &Res, |
333 | ArrayRef<const char *> CommandLineArgs, |
334 | DiagnosticsEngine &Diags, const char *Argv0); |
335 | |
336 | /// Parse command line options that map to LangOptions. |
337 | static bool ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args, |
338 | InputKind IK, const llvm::Triple &T, |
339 | std::vector<std::string> &Includes, |
340 | DiagnosticsEngine &Diags); |
341 | |
342 | /// Parse command line options that map to CodeGenOptions. |
343 | static bool ParseCodeGenArgs(CodeGenOptions &Opts, llvm::opt::ArgList &Args, |
344 | InputKind IK, DiagnosticsEngine &Diags, |
345 | const llvm::Triple &T, |
346 | const std::string &OutputFile, |
347 | const LangOptions &LangOptsRef); |
348 | }; |
349 | |
350 | /// Same as \c CompilerInvocation, but with copy-on-write optimization. |
351 | class CowCompilerInvocation : public CompilerInvocationBase { |
352 | public: |
353 | CowCompilerInvocation() = default; |
354 | CowCompilerInvocation(const CowCompilerInvocation &X) |
355 | : CompilerInvocationBase(EmptyConstructor{}) { |
356 | shallow_copy_assign(X); |
357 | } |
358 | CowCompilerInvocation(CowCompilerInvocation &&) = default; |
359 | CowCompilerInvocation &operator=(const CowCompilerInvocation &X) { |
360 | shallow_copy_assign(X); |
361 | return *this; |
362 | } |
363 | ~CowCompilerInvocation() = default; |
364 | |
365 | CowCompilerInvocation(const CompilerInvocation &X) |
366 | : CompilerInvocationBase(EmptyConstructor{}) { |
367 | deep_copy_assign(X); |
368 | } |
369 | |
370 | CowCompilerInvocation(CompilerInvocation &&X) |
371 | : CompilerInvocationBase(std::move(X)) {} |
372 | |
373 | // Const getters are inherited from the base class. |
374 | |
375 | /// Mutable getters. |
376 | /// @{ |
377 | LangOptions &getMutLangOpts(); |
378 | TargetOptions &getMutTargetOpts(); |
379 | DiagnosticOptions &getMutDiagnosticOpts(); |
380 | HeaderSearchOptions &(); |
381 | PreprocessorOptions &getMutPreprocessorOpts(); |
382 | AnalyzerOptions &getMutAnalyzerOpts(); |
383 | MigratorOptions &getMutMigratorOpts(); |
384 | APINotesOptions &getMutAPINotesOpts(); |
385 | CodeGenOptions &getMutCodeGenOpts(); |
386 | FileSystemOptions &getMutFileSystemOpts(); |
387 | FrontendOptions &getMutFrontendOpts(); |
388 | DependencyOutputOptions &getMutDependencyOutputOpts(); |
389 | PreprocessorOutputOptions &getMutPreprocessorOutputOpts(); |
390 | /// @} |
391 | }; |
392 | |
393 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> |
394 | createVFSFromCompilerInvocation(const CompilerInvocation &CI, |
395 | DiagnosticsEngine &Diags); |
396 | |
397 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> createVFSFromCompilerInvocation( |
398 | const CompilerInvocation &CI, DiagnosticsEngine &Diags, |
399 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS); |
400 | |
401 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> |
402 | createVFSFromOverlayFiles(ArrayRef<std::string> VFSOverlayFiles, |
403 | DiagnosticsEngine &Diags, |
404 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS); |
405 | |
406 | } // namespace clang |
407 | |
408 | #endif // LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H |
409 | |