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