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 std::shared_ptr<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 std::shared_ptr<AnalyzerOptions> 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 /// Create a compiler invocation from a list of input options. 269 /// \returns true on success. 270 /// 271 /// \returns false if an error was encountered while parsing the arguments 272 /// and attempts to recover and continue parsing the rest of the arguments. 273 /// The recovery is best-effort and only guarantees that \p Res will end up in 274 /// one of the vaild-to-access (albeit arbitrary) states. 275 /// 276 /// \param [out] Res - The resulting invocation. 277 /// \param [in] CommandLineArgs - Array of argument strings, this must not 278 /// contain "-cc1". 279 static bool CreateFromArgs(CompilerInvocation &Res, 280 ArrayRef<const char *> CommandLineArgs, 281 DiagnosticsEngine &Diags, 282 const char *Argv0 = nullptr); 283 284 /// Get the directory where the compiler headers 285 /// reside, relative to the compiler binary (found by the passed in 286 /// arguments). 287 /// 288 /// \param Argv0 - The program path (from argv[0]), for finding the builtin 289 /// compiler path. 290 /// \param MainAddr - The address of main (or some other function in the main 291 /// executable), for finding the builtin compiler path. 292 static std::string GetResourcesPath(const char *Argv0, void *MainAddr); 293 294 /// Populate \p Opts with the default set of pointer authentication-related 295 /// options given \p LangOpts and \p Triple. 296 /// 297 /// Note: This is intended to be used by tools which must be aware of 298 /// pointer authentication-related code generation, e.g. lldb. 299 static void setDefaultPointerAuthOptions(PointerAuthOptions &Opts, 300 const LangOptions &LangOpts, 301 const llvm::Triple &Triple); 302 303 /// Retrieve a module hash string that is suitable for uniquely 304 /// identifying the conditions under which the module was built. 305 std::string getModuleHash() const; 306 307 /// Check that \p Args can be parsed and re-serialized without change, 308 /// emiting diagnostics for any differences. 309 /// 310 /// This check is only suitable for command-lines that are expected to already 311 /// be canonical. 312 /// 313 /// \return false if there are any errors. 314 static bool checkCC1RoundTrip(ArrayRef<const char *> Args, 315 DiagnosticsEngine &Diags, 316 const char *Argv0 = nullptr); 317 318 /// Reset all of the options that are not considered when building a 319 /// module. 320 void resetNonModularOptions(); 321 322 /// Disable implicit modules and canonicalize options that are only used by 323 /// implicit modules. 324 void clearImplicitModuleBuildOptions(); 325 326 private: 327 static bool CreateFromArgsImpl(CompilerInvocation &Res, 328 ArrayRef<const char *> CommandLineArgs, 329 DiagnosticsEngine &Diags, const char *Argv0); 330 331 /// Parse command line options that map to LangOptions. 332 static bool ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args, 333 InputKind IK, const llvm::Triple &T, 334 std::vector<std::string> &Includes, 335 DiagnosticsEngine &Diags); 336 337 /// Parse command line options that map to CodeGenOptions. 338 static bool ParseCodeGenArgs(CodeGenOptions &Opts, llvm::opt::ArgList &Args, 339 InputKind IK, DiagnosticsEngine &Diags, 340 const llvm::Triple &T, 341 const std::string &OutputFile, 342 const LangOptions &LangOptsRef); 343 }; 344 345 /// Same as \c CompilerInvocation, but with copy-on-write optimization. 346 class CowCompilerInvocation : public CompilerInvocationBase { 347 public: 348 CowCompilerInvocation() = default; CowCompilerInvocation(const CowCompilerInvocation & X)349 CowCompilerInvocation(const CowCompilerInvocation &X) 350 : CompilerInvocationBase(EmptyConstructor{}) { 351 shallow_copy_assign(X); 352 } 353 CowCompilerInvocation(CowCompilerInvocation &&) = default; 354 CowCompilerInvocation &operator=(const CowCompilerInvocation &X) { 355 shallow_copy_assign(X); 356 return *this; 357 } 358 ~CowCompilerInvocation() = default; 359 CowCompilerInvocation(const CompilerInvocation & X)360 CowCompilerInvocation(const CompilerInvocation &X) 361 : CompilerInvocationBase(EmptyConstructor{}) { 362 deep_copy_assign(X); 363 } 364 CowCompilerInvocation(CompilerInvocation && X)365 CowCompilerInvocation(CompilerInvocation &&X) 366 : CompilerInvocationBase(std::move(X)) {} 367 368 // Const getters are inherited from the base class. 369 370 /// Mutable getters. 371 /// @{ 372 LangOptions &getMutLangOpts(); 373 TargetOptions &getMutTargetOpts(); 374 DiagnosticOptions &getMutDiagnosticOpts(); 375 HeaderSearchOptions &getMutHeaderSearchOpts(); 376 PreprocessorOptions &getMutPreprocessorOpts(); 377 AnalyzerOptions &getMutAnalyzerOpts(); 378 MigratorOptions &getMutMigratorOpts(); 379 APINotesOptions &getMutAPINotesOpts(); 380 CodeGenOptions &getMutCodeGenOpts(); 381 FileSystemOptions &getMutFileSystemOpts(); 382 FrontendOptions &getMutFrontendOpts(); 383 DependencyOutputOptions &getMutDependencyOutputOpts(); 384 PreprocessorOutputOptions &getMutPreprocessorOutputOpts(); 385 /// @} 386 }; 387 388 IntrusiveRefCntPtr<llvm::vfs::FileSystem> 389 createVFSFromCompilerInvocation(const CompilerInvocation &CI, 390 DiagnosticsEngine &Diags); 391 392 IntrusiveRefCntPtr<llvm::vfs::FileSystem> createVFSFromCompilerInvocation( 393 const CompilerInvocation &CI, DiagnosticsEngine &Diags, 394 IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS); 395 396 IntrusiveRefCntPtr<llvm::vfs::FileSystem> 397 createVFSFromOverlayFiles(ArrayRef<std::string> VFSOverlayFiles, 398 DiagnosticsEngine &Diags, 399 IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS); 400 401 } // namespace clang 402 403 #endif // LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H 404