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