1 //===- FrontendOptions.h ----------------------------------------*- 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_FRONTENDOPTIONS_H 10 #define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H 11 12 #include "clang/AST/ASTDumperUtils.h" 13 #include "clang/Basic/LangStandard.h" 14 #include "clang/Frontend/CommandLineSourceLoc.h" 15 #include "clang/Sema/CodeCompleteOptions.h" 16 #include "clang/Serialization/ModuleFileExtension.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/Support/MemoryBuffer.h" 19 #include <cassert> 20 #include <map> 21 #include <memory> 22 #include <optional> 23 #include <string> 24 #include <vector> 25 26 namespace llvm { 27 28 class MemoryBuffer; 29 30 } // namespace llvm 31 32 namespace clang { 33 34 namespace frontend { 35 36 enum ActionKind { 37 /// Parse ASTs and list Decl nodes. 38 ASTDeclList, 39 40 /// Parse ASTs and dump them. 41 ASTDump, 42 43 /// Parse ASTs and print them. 44 ASTPrint, 45 46 /// Parse ASTs and view them in Graphviz. 47 ASTView, 48 49 /// Dump the compiler configuration. 50 DumpCompilerOptions, 51 52 /// Dump out raw tokens. 53 DumpRawTokens, 54 55 /// Dump out preprocessed tokens. 56 DumpTokens, 57 58 /// Emit a .s file. 59 EmitAssembly, 60 61 /// Emit a .bc file. 62 EmitBC, 63 64 /// Translate input source into HTML. 65 EmitHTML, 66 67 /// Emit a .ll file. 68 EmitLLVM, 69 70 /// Generate LLVM IR, but do not emit anything. 71 EmitLLVMOnly, 72 73 /// Generate machine code, but don't emit anything. 74 EmitCodeGenOnly, 75 76 /// Emit a .o file. 77 EmitObj, 78 79 // Extract API information 80 ExtractAPI, 81 82 /// Parse and apply any fixits to the source. 83 FixIt, 84 85 /// Generate pre-compiled module from a module map. 86 GenerateModule, 87 88 /// Generate pre-compiled module from a standard C++ module interface unit. 89 GenerateModuleInterface, 90 91 /// Generate reduced module interface for a standard C++ module interface 92 /// unit. 93 GenerateReducedModuleInterface, 94 95 /// Generate a C++20 header unit module from a header file. 96 GenerateHeaderUnit, 97 98 /// Generate pre-compiled header. 99 GeneratePCH, 100 101 /// Generate Interface Stub Files. 102 GenerateInterfaceStubs, 103 104 /// Only execute frontend initialization. 105 InitOnly, 106 107 /// Dump information about a module file. 108 ModuleFileInfo, 109 110 /// Load and verify that a PCH file is usable. 111 VerifyPCH, 112 113 /// Parse and perform semantic analysis. 114 ParseSyntaxOnly, 115 116 /// Run a plugin action, \see ActionName. 117 PluginAction, 118 119 /// Print the "preamble" of the input file 120 PrintPreamble, 121 122 /// -E mode. 123 PrintPreprocessedInput, 124 125 /// Expand macros but not \#includes. 126 RewriteMacros, 127 128 /// ObjC->C Rewriter. 129 RewriteObjC, 130 131 /// Rewriter playground 132 RewriteTest, 133 134 /// Run one or more source code analyses. 135 RunAnalysis, 136 137 /// Dump template instantiations 138 TemplightDump, 139 140 /// Run migrator. 141 MigrateSource, 142 143 /// Just lex, no output. 144 RunPreprocessorOnly, 145 146 /// Print the output of the dependency directives source minimizer. 147 PrintDependencyDirectivesSourceMinimizerOutput 148 }; 149 150 } // namespace frontend 151 152 /// The kind of a file that we've been handed as an input. 153 class InputKind { 154 public: 155 /// The input file format. 156 enum Format { 157 Source, 158 ModuleMap, 159 Precompiled 160 }; 161 162 // If we are building a header unit, what kind it is; this affects whether 163 // we look for the file in the user or system include search paths before 164 // flagging a missing input. 165 enum HeaderUnitKind { 166 HeaderUnit_None, 167 HeaderUnit_User, 168 HeaderUnit_System, 169 HeaderUnit_Abs 170 }; 171 172 private: 173 Language Lang; 174 LLVM_PREFERRED_TYPE(Format) 175 unsigned Fmt : 3; 176 LLVM_PREFERRED_TYPE(bool) 177 unsigned Preprocessed : 1; 178 LLVM_PREFERRED_TYPE(HeaderUnitKind) 179 unsigned HeaderUnit : 3; 180 LLVM_PREFERRED_TYPE(bool) 181 unsigned IsHeader : 1; 182 183 public: 184 constexpr InputKind(Language L = Language::Unknown, Format F = Source, 185 bool PP = false, HeaderUnitKind HU = HeaderUnit_None, 186 bool HD = false) Lang(L)187 : Lang(L), Fmt(F), Preprocessed(PP), HeaderUnit(HU), IsHeader(HD) {} 188 getLanguage()189 Language getLanguage() const { return static_cast<Language>(Lang); } getFormat()190 Format getFormat() const { return static_cast<Format>(Fmt); } getHeaderUnitKind()191 HeaderUnitKind getHeaderUnitKind() const { 192 return static_cast<HeaderUnitKind>(HeaderUnit); 193 } isPreprocessed()194 bool isPreprocessed() const { return Preprocessed; } isHeader()195 bool isHeader() const { return IsHeader; } isHeaderUnit()196 bool isHeaderUnit() const { return HeaderUnit != HeaderUnit_None; } 197 198 /// Is the input kind fully-unknown? isUnknown()199 bool isUnknown() const { return Lang == Language::Unknown && Fmt == Source; } 200 201 /// Is the language of the input some dialect of Objective-C? isObjectiveC()202 bool isObjectiveC() const { 203 return Lang == Language::ObjC || Lang == Language::ObjCXX; 204 } 205 getPreprocessed()206 InputKind getPreprocessed() const { 207 return InputKind(getLanguage(), getFormat(), true, getHeaderUnitKind(), 208 isHeader()); 209 } 210 getHeader()211 InputKind getHeader() const { 212 return InputKind(getLanguage(), getFormat(), isPreprocessed(), 213 getHeaderUnitKind(), true); 214 } 215 withHeaderUnit(HeaderUnitKind HU)216 InputKind withHeaderUnit(HeaderUnitKind HU) const { 217 return InputKind(getLanguage(), getFormat(), isPreprocessed(), HU, 218 isHeader()); 219 } 220 withFormat(Format F)221 InputKind withFormat(Format F) const { 222 return InputKind(getLanguage(), F, isPreprocessed(), getHeaderUnitKind(), 223 isHeader()); 224 } 225 }; 226 227 /// An input file for the front end. 228 class FrontendInputFile { 229 /// The file name, or "-" to read from standard input. 230 std::string File; 231 232 /// The input, if it comes from a buffer rather than a file. This object 233 /// does not own the buffer, and the caller is responsible for ensuring 234 /// that it outlives any users. 235 std::optional<llvm::MemoryBufferRef> Buffer; 236 237 /// The kind of input, e.g., C source, AST file, LLVM IR. 238 InputKind Kind; 239 240 /// Whether we're dealing with a 'system' input (vs. a 'user' input). 241 bool IsSystem = false; 242 243 public: 244 FrontendInputFile() = default; 245 FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false) 246 : File(File.str()), Kind(Kind), IsSystem(IsSystem) {} 247 FrontendInputFile(llvm::MemoryBufferRef Buffer, InputKind Kind, 248 bool IsSystem = false) Buffer(Buffer)249 : Buffer(Buffer), Kind(Kind), IsSystem(IsSystem) {} 250 getKind()251 InputKind getKind() const { return Kind; } isSystem()252 bool isSystem() const { return IsSystem; } 253 isEmpty()254 bool isEmpty() const { return File.empty() && Buffer == std::nullopt; } isFile()255 bool isFile() const { return !isBuffer(); } isBuffer()256 bool isBuffer() const { return Buffer != std::nullopt; } isPreprocessed()257 bool isPreprocessed() const { return Kind.isPreprocessed(); } isHeader()258 bool isHeader() const { return Kind.isHeader(); } getHeaderUnitKind()259 InputKind::HeaderUnitKind getHeaderUnitKind() const { 260 return Kind.getHeaderUnitKind(); 261 } 262 getFile()263 StringRef getFile() const { 264 assert(isFile()); 265 return File; 266 } 267 getBuffer()268 llvm::MemoryBufferRef getBuffer() const { 269 assert(isBuffer()); 270 return *Buffer; 271 } 272 }; 273 274 /// FrontendOptions - Options for controlling the behavior of the frontend. 275 class FrontendOptions { 276 public: 277 /// Disable memory freeing on exit. 278 LLVM_PREFERRED_TYPE(bool) 279 unsigned DisableFree : 1; 280 281 /// When generating PCH files, instruct the AST writer to create relocatable 282 /// PCH files. 283 LLVM_PREFERRED_TYPE(bool) 284 unsigned RelocatablePCH : 1; 285 286 /// Show the -help text. 287 LLVM_PREFERRED_TYPE(bool) 288 unsigned ShowHelp : 1; 289 290 /// Show frontend performance metrics and statistics. 291 LLVM_PREFERRED_TYPE(bool) 292 unsigned ShowStats : 1; 293 294 LLVM_PREFERRED_TYPE(bool) 295 unsigned AppendStats : 1; 296 297 /// print the supported cpus for the current target 298 LLVM_PREFERRED_TYPE(bool) 299 unsigned PrintSupportedCPUs : 1; 300 301 /// Print the supported extensions for the current target. 302 LLVM_PREFERRED_TYPE(bool) 303 unsigned PrintSupportedExtensions : 1; 304 305 /// Show the -version text. 306 LLVM_PREFERRED_TYPE(bool) 307 unsigned ShowVersion : 1; 308 309 /// Apply fixes even if there are unfixable errors. 310 LLVM_PREFERRED_TYPE(bool) 311 unsigned FixWhatYouCan : 1; 312 313 /// Apply fixes only for warnings. 314 LLVM_PREFERRED_TYPE(bool) 315 unsigned FixOnlyWarnings : 1; 316 317 /// Apply fixes and recompile. 318 LLVM_PREFERRED_TYPE(bool) 319 unsigned FixAndRecompile : 1; 320 321 /// Apply fixes to temporary files. 322 LLVM_PREFERRED_TYPE(bool) 323 unsigned FixToTemporaries : 1; 324 325 /// Emit ARC errors even if the migrator can fix them. 326 LLVM_PREFERRED_TYPE(bool) 327 unsigned ARCMTMigrateEmitARCErrors : 1; 328 329 /// Skip over function bodies to speed up parsing in cases you do not need 330 /// them (e.g. with code completion). 331 LLVM_PREFERRED_TYPE(bool) 332 unsigned SkipFunctionBodies : 1; 333 334 /// Whether we can use the global module index if available. 335 LLVM_PREFERRED_TYPE(bool) 336 unsigned UseGlobalModuleIndex : 1; 337 338 /// Whether we can generate the global module index if needed. 339 LLVM_PREFERRED_TYPE(bool) 340 unsigned GenerateGlobalModuleIndex : 1; 341 342 /// Whether we include declaration dumps in AST dumps. 343 LLVM_PREFERRED_TYPE(bool) 344 unsigned ASTDumpDecls : 1; 345 346 /// Whether we deserialize all decls when forming AST dumps. 347 LLVM_PREFERRED_TYPE(bool) 348 unsigned ASTDumpAll : 1; 349 350 /// Whether we include lookup table dumps in AST dumps. 351 LLVM_PREFERRED_TYPE(bool) 352 unsigned ASTDumpLookups : 1; 353 354 /// Whether we include declaration type dumps in AST dumps. 355 LLVM_PREFERRED_TYPE(bool) 356 unsigned ASTDumpDeclTypes : 1; 357 358 /// Whether we are performing an implicit module build. 359 LLVM_PREFERRED_TYPE(bool) 360 unsigned BuildingImplicitModule : 1; 361 362 /// Whether to use a filesystem lock when building implicit modules. 363 LLVM_PREFERRED_TYPE(bool) 364 unsigned BuildingImplicitModuleUsesLock : 1; 365 366 /// Whether we should embed all used files into the PCM file. 367 LLVM_PREFERRED_TYPE(bool) 368 unsigned ModulesEmbedAllFiles : 1; 369 370 /// Whether timestamps should be written to the produced PCH file. 371 LLVM_PREFERRED_TYPE(bool) 372 unsigned IncludeTimestamps : 1; 373 374 /// Should a temporary file be used during compilation. 375 LLVM_PREFERRED_TYPE(bool) 376 unsigned UseTemporary : 1; 377 378 /// When using -emit-module, treat the modulemap as a system module. 379 LLVM_PREFERRED_TYPE(bool) 380 unsigned IsSystemModule : 1; 381 382 /// Output (and read) PCM files regardless of compiler errors. 383 LLVM_PREFERRED_TYPE(bool) 384 unsigned AllowPCMWithCompilerErrors : 1; 385 386 /// Whether to share the FileManager when building modules. 387 LLVM_PREFERRED_TYPE(bool) 388 unsigned ModulesShareFileManager : 1; 389 390 CodeCompleteOptions CodeCompleteOpts; 391 392 /// Specifies the output format of the AST. 393 ASTDumpOutputFormat ASTDumpFormat = ADOF_Default; 394 395 enum { 396 ARCMT_None, 397 ARCMT_Check, 398 ARCMT_Modify, 399 ARCMT_Migrate 400 } ARCMTAction = ARCMT_None; 401 402 enum { 403 ObjCMT_None = 0, 404 405 /// Enable migration to modern ObjC literals. 406 ObjCMT_Literals = 0x1, 407 408 /// Enable migration to modern ObjC subscripting. 409 ObjCMT_Subscripting = 0x2, 410 411 /// Enable migration to modern ObjC readonly property. 412 ObjCMT_ReadonlyProperty = 0x4, 413 414 /// Enable migration to modern ObjC readwrite property. 415 ObjCMT_ReadwriteProperty = 0x8, 416 417 /// Enable migration to modern ObjC property. 418 ObjCMT_Property = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty), 419 420 /// Enable annotation of ObjCMethods of all kinds. 421 ObjCMT_Annotation = 0x10, 422 423 /// Enable migration of ObjC methods to 'instancetype'. 424 ObjCMT_Instancetype = 0x20, 425 426 /// Enable migration to NS_ENUM/NS_OPTIONS macros. 427 ObjCMT_NsMacros = 0x40, 428 429 /// Enable migration to add conforming protocols. 430 ObjCMT_ProtocolConformance = 0x80, 431 432 /// prefer 'atomic' property over 'nonatomic'. 433 ObjCMT_AtomicProperty = 0x100, 434 435 /// annotate property with NS_RETURNS_INNER_POINTER 436 ObjCMT_ReturnsInnerPointerProperty = 0x200, 437 438 /// use NS_NONATOMIC_IOSONLY for property 'atomic' attribute 439 ObjCMT_NsAtomicIOSOnlyProperty = 0x400, 440 441 /// Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods. 442 ObjCMT_DesignatedInitializer = 0x800, 443 444 /// Enable converting setter/getter expressions to property-dot syntx. 445 ObjCMT_PropertyDotSyntax = 0x1000, 446 447 ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty | 448 ObjCMT_Annotation | ObjCMT_Instancetype | 449 ObjCMT_NsMacros | ObjCMT_ProtocolConformance | 450 ObjCMT_NsAtomicIOSOnlyProperty | 451 ObjCMT_DesignatedInitializer), 452 ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | 453 ObjCMT_MigrateDecls | ObjCMT_PropertyDotSyntax) 454 }; 455 unsigned ObjCMTAction = ObjCMT_None; 456 std::string ObjCMTAllowListPath; 457 458 std::string MTMigrateDir; 459 std::string ARCMTMigrateReportOut; 460 461 /// The input kind, either specified via -x argument or deduced from the input 462 /// file name. 463 InputKind DashX; 464 465 /// The input files and their types. 466 SmallVector<FrontendInputFile, 0> Inputs; 467 468 /// When the input is a module map, the original module map file from which 469 /// that map was inferred, if any (for umbrella modules). 470 std::string OriginalModuleMap; 471 472 /// The output file, if any. 473 std::string OutputFile; 474 475 /// If given, the new suffix for fix-it rewritten files. 476 std::string FixItSuffix; 477 478 /// If given, filter dumped AST Decl nodes by this substring. 479 std::string ASTDumpFilter; 480 481 /// If given, enable code completion at the provided location. 482 ParsedSourceLocation CodeCompletionAt; 483 484 /// The frontend action to perform. 485 frontend::ActionKind ProgramAction = frontend::ParseSyntaxOnly; 486 487 /// The name of the action to run when using a plugin action. 488 std::string ActionName; 489 490 // Currently this is only used as part of the `-extract-api` action. 491 /// The name of the product the input files belong too. 492 std::string ProductName; 493 494 // Currently this is only used as part of the `-extract-api` action. 495 // A comma seperated list of files providing a list of APIs to 496 // ignore when extracting documentation. 497 std::vector<std::string> ExtractAPIIgnoresFileList; 498 499 // Currently this is only used as part of the `-emit-symbol-graph` 500 // action. 501 // Location of output directory where symbol graph information would 502 // be dumped 503 std::string SymbolGraphOutputDir; 504 505 /// Args to pass to the plugins 506 std::map<std::string, std::vector<std::string>> PluginArgs; 507 508 /// The list of plugin actions to run in addition to the normal action. 509 std::vector<std::string> AddPluginActions; 510 511 /// The list of plugins to load. 512 std::vector<std::string> Plugins; 513 514 /// The list of module file extensions. 515 std::vector<std::shared_ptr<ModuleFileExtension>> ModuleFileExtensions; 516 517 /// The list of module map files to load before processing the input. 518 std::vector<std::string> ModuleMapFiles; 519 520 /// The list of additional prebuilt module files to load before 521 /// processing the input. 522 std::vector<std::string> ModuleFiles; 523 524 /// The list of files to embed into the compiled module file. 525 std::vector<std::string> ModulesEmbedFiles; 526 527 /// The list of AST files to merge. 528 std::vector<std::string> ASTMergeFiles; 529 530 /// A list of arguments to forward to LLVM's option processing; this 531 /// should only be used for debugging and experimental features. 532 std::vector<std::string> LLVMArgs; 533 534 /// File name of the file that will provide record layouts 535 /// (in the format produced by -fdump-record-layouts). 536 std::string OverrideRecordLayoutsFile; 537 538 /// Auxiliary triple for CUDA/HIP compilation. 539 std::string AuxTriple; 540 541 /// Auxiliary target CPU for CUDA/HIP compilation. 542 std::optional<std::string> AuxTargetCPU; 543 544 /// Auxiliary target features for CUDA/HIP compilation. 545 std::optional<std::vector<std::string>> AuxTargetFeatures; 546 547 /// Filename to write statistics to. 548 std::string StatsFile; 549 550 /// Minimum time granularity (in microseconds) traced by time profiler. 551 unsigned TimeTraceGranularity; 552 553 /// Path which stores the output files for -ftime-trace 554 std::string TimeTracePath; 555 556 public: FrontendOptions()557 FrontendOptions() 558 : DisableFree(false), RelocatablePCH(false), ShowHelp(false), 559 ShowStats(false), AppendStats(false), ShowVersion(false), 560 FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false), 561 FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false), 562 SkipFunctionBodies(false), UseGlobalModuleIndex(true), 563 GenerateGlobalModuleIndex(true), ASTDumpDecls(false), 564 ASTDumpLookups(false), BuildingImplicitModule(false), 565 BuildingImplicitModuleUsesLock(true), ModulesEmbedAllFiles(false), 566 IncludeTimestamps(true), UseTemporary(true), 567 AllowPCMWithCompilerErrors(false), ModulesShareFileManager(true), 568 TimeTraceGranularity(500) {} 569 570 /// getInputKindForExtension - Return the appropriate input kind for a file 571 /// extension. For example, "c" would return Language::C. 572 /// 573 /// \return The input kind for the extension, or Language::Unknown if the 574 /// extension is not recognized. 575 static InputKind getInputKindForExtension(StringRef Extension); 576 }; 577 578 } // namespace clang 579 580 #endif // LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H 581