1 //===- ASTUnit.h - ASTUnit utility ------------------------------*- 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 // ASTUnit utility class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H 14 #define LLVM_CLANG_FRONTEND_ASTUNIT_H 15 16 #include "clang-c/Index.h" 17 #include "clang/AST/ASTContext.h" 18 #include "clang/Basic/Diagnostic.h" 19 #include "clang/Basic/FileSystemOptions.h" 20 #include "clang/Basic/LLVM.h" 21 #include "clang/Basic/LangOptions.h" 22 #include "clang/Basic/SourceLocation.h" 23 #include "clang/Basic/SourceManager.h" 24 #include "clang/Basic/TargetOptions.h" 25 #include "clang/Lex/HeaderSearchOptions.h" 26 #include "clang/Lex/ModuleLoader.h" 27 #include "clang/Lex/PreprocessingRecord.h" 28 #include "clang/Sema/CodeCompleteConsumer.h" 29 #include "clang/Serialization/ASTBitCodes.h" 30 #include "clang/Frontend/PrecompiledPreamble.h" 31 #include "llvm/ADT/ArrayRef.h" 32 #include "llvm/ADT/DenseMap.h" 33 #include "llvm/ADT/IntrusiveRefCntPtr.h" 34 #include "llvm/ADT/STLExtras.h" 35 #include "llvm/ADT/SmallVector.h" 36 #include "llvm/ADT/StringMap.h" 37 #include "llvm/ADT/StringRef.h" 38 #include "llvm/ADT/iterator_range.h" 39 #include <cassert> 40 #include <cstddef> 41 #include <cstdint> 42 #include <memory> 43 #include <optional> 44 #include <string> 45 #include <utility> 46 #include <vector> 47 48 namespace llvm { 49 50 class MemoryBuffer; 51 52 namespace vfs { 53 54 class FileSystem; 55 56 } // namespace vfs 57 } // namespace llvm 58 59 namespace clang { 60 61 class ASTContext; 62 class ASTDeserializationListener; 63 class ASTMutationListener; 64 class ASTReader; 65 class CompilerInstance; 66 class CompilerInvocation; 67 class Decl; 68 class FileEntry; 69 class FileManager; 70 class FrontendAction; 71 class HeaderSearch; 72 class InputKind; 73 class InMemoryModuleCache; 74 class PCHContainerOperations; 75 class PCHContainerReader; 76 class Preprocessor; 77 class PreprocessorOptions; 78 class Sema; 79 class TargetInfo; 80 81 /// \brief Enumerates the available scopes for skipping function bodies. 82 enum class SkipFunctionBodiesScope { None, Preamble, PreambleAndMainFile }; 83 84 /// \brief Enumerates the available kinds for capturing diagnostics. 85 enum class CaptureDiagsKind { None, All, AllWithoutNonErrorsFromIncludes }; 86 87 /// Utility class for loading a ASTContext from an AST file. 88 class ASTUnit { 89 public: 90 struct StandaloneFixIt { 91 std::pair<unsigned, unsigned> RemoveRange; 92 std::pair<unsigned, unsigned> InsertFromRange; 93 std::string CodeToInsert; 94 bool BeforePreviousInsertions; 95 }; 96 97 struct StandaloneDiagnostic { 98 unsigned ID; 99 DiagnosticsEngine::Level Level; 100 std::string Message; 101 std::string Filename; 102 unsigned LocOffset; 103 std::vector<std::pair<unsigned, unsigned>> Ranges; 104 std::vector<StandaloneFixIt> FixIts; 105 }; 106 107 private: 108 std::shared_ptr<LangOptions> LangOpts; 109 IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics; 110 IntrusiveRefCntPtr<FileManager> FileMgr; 111 IntrusiveRefCntPtr<SourceManager> SourceMgr; 112 IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache; 113 std::unique_ptr<HeaderSearch> HeaderInfo; 114 IntrusiveRefCntPtr<TargetInfo> Target; 115 std::shared_ptr<Preprocessor> PP; 116 IntrusiveRefCntPtr<ASTContext> Ctx; 117 std::shared_ptr<TargetOptions> TargetOpts; 118 std::shared_ptr<HeaderSearchOptions> HSOpts; 119 std::shared_ptr<PreprocessorOptions> PPOpts; 120 IntrusiveRefCntPtr<ASTReader> Reader; 121 bool HadModuleLoaderFatalFailure = false; 122 bool StorePreamblesInMemory = false; 123 124 struct ASTWriterData; 125 std::unique_ptr<ASTWriterData> WriterData; 126 127 FileSystemOptions FileSystemOpts; 128 std::string PreambleStoragePath; 129 130 /// The AST consumer that received information about the translation 131 /// unit as it was parsed or loaded. 132 std::unique_ptr<ASTConsumer> Consumer; 133 134 /// The semantic analysis object used to type-check the translation 135 /// unit. 136 std::unique_ptr<Sema> TheSema; 137 138 /// Optional owned invocation, just used to make the invocation used in 139 /// LoadFromCommandLine available. 140 std::shared_ptr<CompilerInvocation> Invocation; 141 142 /// Fake module loader: the AST unit doesn't need to load any modules. 143 TrivialModuleLoader ModuleLoader; 144 145 // OnlyLocalDecls - when true, walking this AST should only visit declarations 146 // that come from the AST itself, not from included precompiled headers. 147 // FIXME: This is temporary; eventually, CIndex will always do this. 148 bool OnlyLocalDecls = false; 149 150 /// Whether to capture any diagnostics produced. 151 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None; 152 153 /// Track whether the main file was loaded from an AST or not. 154 bool MainFileIsAST; 155 156 /// What kind of translation unit this AST represents. 157 TranslationUnitKind TUKind = TU_Complete; 158 159 /// Whether we should time each operation. 160 bool WantTiming; 161 162 /// Whether the ASTUnit should delete the remapped buffers. 163 bool OwnsRemappedFileBuffers = true; 164 165 /// Track the top-level decls which appeared in an ASTUnit which was loaded 166 /// from a source file. 167 // 168 // FIXME: This is just an optimization hack to avoid deserializing large parts 169 // of a PCH file when using the Index library on an ASTUnit loaded from 170 // source. In the long term we should make the Index library use efficient and 171 // more scalable search mechanisms. 172 std::vector<Decl*> TopLevelDecls; 173 174 /// Sorted (by file offset) vector of pairs of file offset/Decl. 175 using LocDeclsTy = SmallVector<std::pair<unsigned, Decl *>, 64>; 176 using FileDeclsTy = llvm::DenseMap<FileID, std::unique_ptr<LocDeclsTy>>; 177 178 /// Map from FileID to the file-level declarations that it contains. 179 /// The files and decls are only local (and non-preamble) ones. 180 FileDeclsTy FileDecls; 181 182 /// The name of the original source file used to generate this ASTUnit. 183 std::string OriginalSourceFile; 184 185 /// The set of diagnostics produced when creating the preamble. 186 SmallVector<StandaloneDiagnostic, 4> PreambleDiagnostics; 187 188 /// The set of diagnostics produced when creating this 189 /// translation unit. 190 SmallVector<StoredDiagnostic, 4> StoredDiagnostics; 191 192 /// The set of diagnostics produced when failing to parse, e.g. due 193 /// to failure to load the PCH. 194 SmallVector<StoredDiagnostic, 4> FailedParseDiagnostics; 195 196 /// The number of stored diagnostics that come from the driver 197 /// itself. 198 /// 199 /// Diagnostics that come from the driver are retained from one parse to 200 /// the next. 201 unsigned NumStoredDiagnosticsFromDriver = 0; 202 203 /// Counter that determines when we want to try building a 204 /// precompiled preamble. 205 /// 206 /// If zero, we will never build a precompiled preamble. Otherwise, 207 /// it's treated as a counter that decrements each time we reparse 208 /// without the benefit of a precompiled preamble. When it hits 1, 209 /// we'll attempt to rebuild the precompiled header. This way, if 210 /// building the precompiled preamble fails, we won't try again for 211 /// some number of calls. 212 unsigned PreambleRebuildCountdown = 0; 213 214 /// Counter indicating how often the preamble was build in total. 215 unsigned PreambleCounter = 0; 216 217 /// Cache pairs "filename - source location" 218 /// 219 /// Cache contains only source locations from preamble so it is 220 /// guaranteed that they stay valid when the SourceManager is recreated. 221 /// This cache is used when loading preamble to increase performance 222 /// of that loading. It must be cleared when preamble is recreated. 223 llvm::StringMap<SourceLocation> PreambleSrcLocCache; 224 225 /// The contents of the preamble. 226 std::optional<PrecompiledPreamble> Preamble; 227 228 /// When non-NULL, this is the buffer used to store the contents of 229 /// the main file when it has been padded for use with the precompiled 230 /// preamble. 231 std::unique_ptr<llvm::MemoryBuffer> SavedMainFileBuffer; 232 233 /// The number of warnings that occurred while parsing the preamble. 234 /// 235 /// This value will be used to restore the state of the \c DiagnosticsEngine 236 /// object when re-using the precompiled preamble. Note that only the 237 /// number of warnings matters, since we will not save the preamble 238 /// when any errors are present. 239 unsigned NumWarningsInPreamble = 0; 240 241 /// A list of the serialization ID numbers for each of the top-level 242 /// declarations parsed within the precompiled preamble. 243 std::vector<serialization::DeclID> TopLevelDeclsInPreamble; 244 245 /// Whether we should be caching code-completion results. 246 bool ShouldCacheCodeCompletionResults : 1; 247 248 /// Whether to include brief documentation within the set of code 249 /// completions cached. 250 bool IncludeBriefCommentsInCodeCompletion : 1; 251 252 /// True if non-system source files should be treated as volatile 253 /// (likely to change while trying to use them). 254 bool UserFilesAreVolatile : 1; 255 256 static void ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 257 ASTUnit &AST, CaptureDiagsKind CaptureDiagnostics); 258 259 void TranslateStoredDiagnostics(FileManager &FileMgr, 260 SourceManager &SrcMan, 261 const SmallVectorImpl<StandaloneDiagnostic> &Diags, 262 SmallVectorImpl<StoredDiagnostic> &Out); 263 264 void clearFileLevelDecls(); 265 266 public: 267 /// A cached code-completion result, which may be introduced in one of 268 /// many different contexts. 269 struct CachedCodeCompletionResult { 270 /// The code-completion string corresponding to this completion 271 /// result. 272 CodeCompletionString *Completion; 273 274 /// A bitmask that indicates which code-completion contexts should 275 /// contain this completion result. 276 /// 277 /// The bits in the bitmask correspond to the values of 278 /// CodeCompleteContext::Kind. To map from a completion context kind to a 279 /// bit, shift 1 by that number of bits. Many completions can occur in 280 /// several different contexts. 281 uint64_t ShowInContexts; 282 283 /// The priority given to this code-completion result. 284 unsigned Priority; 285 286 /// The libclang cursor kind corresponding to this code-completion 287 /// result. 288 CXCursorKind Kind; 289 290 /// The availability of this code-completion result. 291 CXAvailabilityKind Availability; 292 293 /// The simplified type class for a non-macro completion result. 294 SimplifiedTypeClass TypeClass; 295 296 /// The type of a non-macro completion result, stored as a unique 297 /// integer used by the string map of cached completion types. 298 /// 299 /// This value will be zero if the type is not known, or a unique value 300 /// determined by the formatted type string. Se \c CachedCompletionTypes 301 /// for more information. 302 unsigned Type; 303 }; 304 305 /// Retrieve the mapping from formatted type names to unique type 306 /// identifiers. 307 llvm::StringMap<unsigned> &getCachedCompletionTypes() { 308 return CachedCompletionTypes; 309 } 310 311 /// Retrieve the allocator used to cache global code completions. 312 std::shared_ptr<GlobalCodeCompletionAllocator> 313 getCachedCompletionAllocator() { 314 return CachedCompletionAllocator; 315 } 316 317 CodeCompletionTUInfo &getCodeCompletionTUInfo() { 318 if (!CCTUInfo) 319 CCTUInfo = std::make_unique<CodeCompletionTUInfo>( 320 std::make_shared<GlobalCodeCompletionAllocator>()); 321 return *CCTUInfo; 322 } 323 324 private: 325 /// Allocator used to store cached code completions. 326 std::shared_ptr<GlobalCodeCompletionAllocator> CachedCompletionAllocator; 327 328 std::unique_ptr<CodeCompletionTUInfo> CCTUInfo; 329 330 /// The set of cached code-completion results. 331 std::vector<CachedCodeCompletionResult> CachedCompletionResults; 332 333 /// A mapping from the formatted type name to a unique number for that 334 /// type, which is used for type equality comparisons. 335 llvm::StringMap<unsigned> CachedCompletionTypes; 336 337 /// A string hash of the top-level declaration and macro definition 338 /// names processed the last time that we reparsed the file. 339 /// 340 /// This hash value is used to determine when we need to refresh the 341 /// global code-completion cache. 342 unsigned CompletionCacheTopLevelHashValue = 0; 343 344 /// A string hash of the top-level declaration and macro definition 345 /// names processed the last time that we reparsed the precompiled preamble. 346 /// 347 /// This hash value is used to determine when we need to refresh the 348 /// global code-completion cache after a rebuild of the precompiled preamble. 349 unsigned PreambleTopLevelHashValue = 0; 350 351 /// The current hash value for the top-level declaration and macro 352 /// definition names 353 unsigned CurrentTopLevelHashValue = 0; 354 355 /// Bit used by CIndex to mark when a translation unit may be in an 356 /// inconsistent state, and is not safe to free. 357 unsigned UnsafeToFree : 1; 358 359 /// \brief Enumerator specifying the scope for skipping function bodies. 360 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None; 361 362 /// Cache any "global" code-completion results, so that we can avoid 363 /// recomputing them with each completion. 364 void CacheCodeCompletionResults(); 365 366 /// Clear out and deallocate 367 void ClearCachedCompletionResults(); 368 369 explicit ASTUnit(bool MainFileIsAST); 370 371 bool Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, 372 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer, 373 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS); 374 375 std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble( 376 std::shared_ptr<PCHContainerOperations> PCHContainerOps, 377 CompilerInvocation &PreambleInvocationIn, 378 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, bool AllowRebuild = true, 379 unsigned MaxLines = 0); 380 void RealizeTopLevelDeclsFromPreamble(); 381 382 /// Transfers ownership of the objects (like SourceManager) from 383 /// \param CI to this ASTUnit. 384 void transferASTDataFromCompilerInstance(CompilerInstance &CI); 385 386 /// Allows us to assert that ASTUnit is not being used concurrently, 387 /// which is not supported. 388 /// 389 /// Clients should create instances of the ConcurrencyCheck class whenever 390 /// using the ASTUnit in a way that isn't intended to be concurrent, which is 391 /// just about any usage. 392 /// Becomes a noop in release mode; only useful for debug mode checking. 393 class ConcurrencyState { 394 void *Mutex; // a std::recursive_mutex in debug; 395 396 public: 397 ConcurrencyState(); 398 ~ConcurrencyState(); 399 400 void start(); 401 void finish(); 402 }; 403 ConcurrencyState ConcurrencyCheckValue; 404 405 public: 406 friend class ConcurrencyCheck; 407 408 class ConcurrencyCheck { 409 ASTUnit &Self; 410 411 public: 412 explicit ConcurrencyCheck(ASTUnit &Self) : Self(Self) { 413 Self.ConcurrencyCheckValue.start(); 414 } 415 416 ~ConcurrencyCheck() { 417 Self.ConcurrencyCheckValue.finish(); 418 } 419 }; 420 421 ASTUnit(const ASTUnit &) = delete; 422 ASTUnit &operator=(const ASTUnit &) = delete; 423 ~ASTUnit(); 424 425 bool isMainFileAST() const { return MainFileIsAST; } 426 427 bool isUnsafeToFree() const { return UnsafeToFree; } 428 void setUnsafeToFree(bool Value) { UnsafeToFree = Value; } 429 430 const DiagnosticsEngine &getDiagnostics() const { return *Diagnostics; } 431 DiagnosticsEngine &getDiagnostics() { return *Diagnostics; } 432 433 const SourceManager &getSourceManager() const { return *SourceMgr; } 434 SourceManager &getSourceManager() { return *SourceMgr; } 435 436 const Preprocessor &getPreprocessor() const { return *PP; } 437 Preprocessor &getPreprocessor() { return *PP; } 438 std::shared_ptr<Preprocessor> getPreprocessorPtr() const { return PP; } 439 440 const ASTContext &getASTContext() const { return *Ctx; } 441 ASTContext &getASTContext() { return *Ctx; } 442 443 void setASTContext(ASTContext *ctx) { Ctx = ctx; } 444 void setPreprocessor(std::shared_ptr<Preprocessor> pp); 445 446 /// Enable source-range based diagnostic messages. 447 /// 448 /// If diagnostic messages with source-range information are to be expected 449 /// and AST comes not from file (e.g. after LoadFromCompilerInvocation) this 450 /// function has to be called. 451 /// The function is to be called only once and the AST should be associated 452 /// with the same source file afterwards. 453 void enableSourceFileDiagnostics(); 454 455 bool hasSema() const { return (bool)TheSema; } 456 457 Sema &getSema() const { 458 assert(TheSema && "ASTUnit does not have a Sema object!"); 459 return *TheSema; 460 } 461 462 const LangOptions &getLangOpts() const { 463 assert(LangOpts && "ASTUnit does not have language options"); 464 return *LangOpts; 465 } 466 467 const HeaderSearchOptions &getHeaderSearchOpts() const { 468 assert(HSOpts && "ASTUnit does not have header search options"); 469 return *HSOpts; 470 } 471 472 const PreprocessorOptions &getPreprocessorOpts() const { 473 assert(PPOpts && "ASTUnit does not have preprocessor options"); 474 return *PPOpts; 475 } 476 477 const FileManager &getFileManager() const { return *FileMgr; } 478 FileManager &getFileManager() { return *FileMgr; } 479 480 const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; } 481 482 IntrusiveRefCntPtr<ASTReader> getASTReader() const; 483 484 StringRef getOriginalSourceFileName() const { 485 return OriginalSourceFile; 486 } 487 488 ASTMutationListener *getASTMutationListener(); 489 ASTDeserializationListener *getDeserializationListener(); 490 491 bool getOnlyLocalDecls() const { return OnlyLocalDecls; } 492 493 bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; } 494 void setOwnsRemappedFileBuffers(bool val) { OwnsRemappedFileBuffers = val; } 495 496 StringRef getMainFileName() const; 497 498 /// If this ASTUnit came from an AST file, returns the filename for it. 499 StringRef getASTFileName() const; 500 501 using top_level_iterator = std::vector<Decl *>::iterator; 502 503 top_level_iterator top_level_begin() { 504 assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); 505 if (!TopLevelDeclsInPreamble.empty()) 506 RealizeTopLevelDeclsFromPreamble(); 507 return TopLevelDecls.begin(); 508 } 509 510 top_level_iterator top_level_end() { 511 assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); 512 if (!TopLevelDeclsInPreamble.empty()) 513 RealizeTopLevelDeclsFromPreamble(); 514 return TopLevelDecls.end(); 515 } 516 517 std::size_t top_level_size() const { 518 assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); 519 return TopLevelDeclsInPreamble.size() + TopLevelDecls.size(); 520 } 521 522 bool top_level_empty() const { 523 assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); 524 return TopLevelDeclsInPreamble.empty() && TopLevelDecls.empty(); 525 } 526 527 /// Add a new top-level declaration. 528 void addTopLevelDecl(Decl *D) { 529 TopLevelDecls.push_back(D); 530 } 531 532 /// Add a new local file-level declaration. 533 void addFileLevelDecl(Decl *D); 534 535 /// Get the decls that are contained in a file in the Offset/Length 536 /// range. \p Length can be 0 to indicate a point at \p Offset instead of 537 /// a range. 538 void findFileRegionDecls(FileID File, unsigned Offset, unsigned Length, 539 SmallVectorImpl<Decl *> &Decls); 540 541 /// Retrieve a reference to the current top-level name hash value. 542 /// 543 /// Note: This is used internally by the top-level tracking action 544 unsigned &getCurrentTopLevelHashValue() { return CurrentTopLevelHashValue; } 545 546 /// Get the source location for the given file:line:col triplet. 547 /// 548 /// The difference with SourceManager::getLocation is that this method checks 549 /// whether the requested location points inside the precompiled preamble 550 /// in which case the returned source location will be a "loaded" one. 551 SourceLocation getLocation(const FileEntry *File, 552 unsigned Line, unsigned Col) const; 553 554 /// Get the source location for the given file:offset pair. 555 SourceLocation getLocation(const FileEntry *File, unsigned Offset) const; 556 557 /// If \p Loc is a loaded location from the preamble, returns 558 /// the corresponding local location of the main file, otherwise it returns 559 /// \p Loc. 560 SourceLocation mapLocationFromPreamble(SourceLocation Loc) const; 561 562 /// If \p Loc is a local location of the main file but inside the 563 /// preamble chunk, returns the corresponding loaded location from the 564 /// preamble, otherwise it returns \p Loc. 565 SourceLocation mapLocationToPreamble(SourceLocation Loc) const; 566 567 bool isInPreambleFileID(SourceLocation Loc) const; 568 bool isInMainFileID(SourceLocation Loc) const; 569 SourceLocation getStartOfMainFileID() const; 570 SourceLocation getEndOfPreambleFileID() const; 571 572 /// \see mapLocationFromPreamble. 573 SourceRange mapRangeFromPreamble(SourceRange R) const { 574 return SourceRange(mapLocationFromPreamble(R.getBegin()), 575 mapLocationFromPreamble(R.getEnd())); 576 } 577 578 /// \see mapLocationToPreamble. 579 SourceRange mapRangeToPreamble(SourceRange R) const { 580 return SourceRange(mapLocationToPreamble(R.getBegin()), 581 mapLocationToPreamble(R.getEnd())); 582 } 583 584 unsigned getPreambleCounterForTests() const { return PreambleCounter; } 585 586 // Retrieve the diagnostics associated with this AST 587 using stored_diag_iterator = StoredDiagnostic *; 588 using stored_diag_const_iterator = const StoredDiagnostic *; 589 590 stored_diag_const_iterator stored_diag_begin() const { 591 return StoredDiagnostics.begin(); 592 } 593 594 stored_diag_iterator stored_diag_begin() { 595 return StoredDiagnostics.begin(); 596 } 597 598 stored_diag_const_iterator stored_diag_end() const { 599 return StoredDiagnostics.end(); 600 } 601 602 stored_diag_iterator stored_diag_end() { 603 return StoredDiagnostics.end(); 604 } 605 606 unsigned stored_diag_size() const { return StoredDiagnostics.size(); } 607 608 stored_diag_iterator stored_diag_afterDriver_begin() { 609 if (NumStoredDiagnosticsFromDriver > StoredDiagnostics.size()) 610 NumStoredDiagnosticsFromDriver = 0; 611 return StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver; 612 } 613 614 using cached_completion_iterator = 615 std::vector<CachedCodeCompletionResult>::iterator; 616 617 cached_completion_iterator cached_completion_begin() { 618 return CachedCompletionResults.begin(); 619 } 620 621 cached_completion_iterator cached_completion_end() { 622 return CachedCompletionResults.end(); 623 } 624 625 unsigned cached_completion_size() const { 626 return CachedCompletionResults.size(); 627 } 628 629 /// Returns an iterator range for the local preprocessing entities 630 /// of the local Preprocessor, if this is a parsed source file, or the loaded 631 /// preprocessing entities of the primary module if this is an AST file. 632 llvm::iterator_range<PreprocessingRecord::iterator> 633 getLocalPreprocessingEntities() const; 634 635 /// Type for a function iterating over a number of declarations. 636 /// \returns true to continue iteration and false to abort. 637 using DeclVisitorFn = bool (*)(void *context, const Decl *D); 638 639 /// Iterate over local declarations (locally parsed if this is a parsed 640 /// source file or the loaded declarations of the primary module if this is an 641 /// AST file). 642 /// \returns true if the iteration was complete or false if it was aborted. 643 bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn); 644 645 /// Get the PCH file if one was included. 646 OptionalFileEntryRef getPCHFile(); 647 648 /// Returns true if the ASTUnit was constructed from a serialized 649 /// module file. 650 bool isModuleFile() const; 651 652 std::unique_ptr<llvm::MemoryBuffer> 653 getBufferForFile(StringRef Filename, std::string *ErrorStr = nullptr); 654 655 /// Determine what kind of translation unit this AST represents. 656 TranslationUnitKind getTranslationUnitKind() const { return TUKind; } 657 658 /// Determine the input kind this AST unit represents. 659 InputKind getInputKind() const; 660 661 /// A mapping from a file name to the memory buffer that stores the 662 /// remapped contents of that file. 663 using RemappedFile = std::pair<std::string, llvm::MemoryBuffer *>; 664 665 /// Create a ASTUnit. Gets ownership of the passed CompilerInvocation. 666 static std::unique_ptr<ASTUnit> 667 create(std::shared_ptr<CompilerInvocation> CI, 668 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 669 CaptureDiagsKind CaptureDiagnostics, bool UserFilesAreVolatile); 670 671 enum WhatToLoad { 672 /// Load options and the preprocessor state. 673 LoadPreprocessorOnly, 674 675 /// Load the AST, but do not restore Sema state. 676 LoadASTOnly, 677 678 /// Load everything, including Sema. 679 LoadEverything 680 }; 681 682 /// Create a ASTUnit from an AST file. 683 /// 684 /// \param Filename - The AST file to load. 685 /// 686 /// \param PCHContainerRdr - The PCHContainerOperations to use for loading and 687 /// creating modules. 688 /// \param Diags - The diagnostics engine to use for reporting errors; its 689 /// lifetime is expected to extend past that of the returned ASTUnit. 690 /// 691 /// \returns - The initialized ASTUnit or null if the AST failed to load. 692 static std::unique_ptr<ASTUnit> 693 LoadFromASTFile(const std::string &Filename, 694 const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, 695 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 696 const FileSystemOptions &FileSystemOpts, 697 std::shared_ptr<HeaderSearchOptions> HSOpts, 698 bool UseDebugInfo = false, bool OnlyLocalDecls = false, 699 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, 700 bool AllowASTWithCompilerErrors = false, 701 bool UserFilesAreVolatile = false, 702 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = 703 llvm::vfs::getRealFileSystem()); 704 705 private: 706 /// Helper function for \c LoadFromCompilerInvocation() and 707 /// \c LoadFromCommandLine(), which loads an AST from a compiler invocation. 708 /// 709 /// \param PrecompilePreambleAfterNParses After how many parses the preamble 710 /// of this translation unit should be precompiled, to improve the performance 711 /// of reparsing. Set to zero to disable preambles. 712 /// 713 /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses. 714 /// Note that preamble is saved to a temporary directory on a RealFileSystem, 715 /// so in order for it to be loaded correctly, VFS should have access to 716 /// it(i.e., be an overlay over RealFileSystem). 717 /// 718 /// \returns \c true if a catastrophic failure occurred (which means that the 719 /// \c ASTUnit itself is invalid), or \c false otherwise. 720 bool LoadFromCompilerInvocation( 721 std::shared_ptr<PCHContainerOperations> PCHContainerOps, 722 unsigned PrecompilePreambleAfterNParses, 723 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS); 724 725 public: 726 /// Create an ASTUnit from a source file, via a CompilerInvocation 727 /// object, by invoking the optionally provided ASTFrontendAction. 728 /// 729 /// \param CI - The compiler invocation to use; it must have exactly one input 730 /// source file. The ASTUnit takes ownership of the CompilerInvocation object. 731 /// 732 /// \param PCHContainerOps - The PCHContainerOperations to use for loading and 733 /// creating modules. 734 /// 735 /// \param Diags - The diagnostics engine to use for reporting errors; its 736 /// lifetime is expected to extend past that of the returned ASTUnit. 737 /// 738 /// \param Action - The ASTFrontendAction to invoke. Its ownership is not 739 /// transferred. 740 /// 741 /// \param Unit - optionally an already created ASTUnit. Its ownership is not 742 /// transferred. 743 /// 744 /// \param Persistent - if true the returned ASTUnit will be complete. 745 /// false means the caller is only interested in getting info through the 746 /// provided \see Action. 747 /// 748 /// \param ErrAST - If non-null and parsing failed without any AST to return 749 /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit 750 /// mainly to allow the caller to see the diagnostics. 751 /// This will only receive an ASTUnit if a new one was created. If an already 752 /// created ASTUnit was passed in \p Unit then the caller can check that. 753 /// 754 static ASTUnit *LoadFromCompilerInvocationAction( 755 std::shared_ptr<CompilerInvocation> CI, 756 std::shared_ptr<PCHContainerOperations> PCHContainerOps, 757 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 758 FrontendAction *Action = nullptr, ASTUnit *Unit = nullptr, 759 bool Persistent = true, StringRef ResourceFilesPath = StringRef(), 760 bool OnlyLocalDecls = false, 761 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, 762 unsigned PrecompilePreambleAfterNParses = 0, 763 bool CacheCodeCompletionResults = false, 764 bool UserFilesAreVolatile = false, 765 std::unique_ptr<ASTUnit> *ErrAST = nullptr); 766 767 /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a 768 /// CompilerInvocation object. 769 /// 770 /// \param CI - The compiler invocation to use; it must have exactly one input 771 /// source file. The ASTUnit takes ownership of the CompilerInvocation object. 772 /// 773 /// \param PCHContainerOps - The PCHContainerOperations to use for loading and 774 /// creating modules. 775 /// 776 /// \param Diags - The diagnostics engine to use for reporting errors; its 777 /// lifetime is expected to extend past that of the returned ASTUnit. 778 // 779 // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we 780 // shouldn't need to specify them at construction time. 781 static std::unique_ptr<ASTUnit> LoadFromCompilerInvocation( 782 std::shared_ptr<CompilerInvocation> CI, 783 std::shared_ptr<PCHContainerOperations> PCHContainerOps, 784 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr, 785 bool OnlyLocalDecls = false, 786 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, 787 unsigned PrecompilePreambleAfterNParses = 0, 788 TranslationUnitKind TUKind = TU_Complete, 789 bool CacheCodeCompletionResults = false, 790 bool IncludeBriefCommentsInCodeCompletion = false, 791 bool UserFilesAreVolatile = false); 792 793 /// LoadFromCommandLine - Create an ASTUnit from a vector of command line 794 /// arguments, which must specify exactly one source file. 795 /// 796 /// \param ArgBegin - The beginning of the argument vector. 797 /// 798 /// \param ArgEnd - The end of the argument vector. 799 /// 800 /// \param PCHContainerOps - The PCHContainerOperations to use for loading and 801 /// creating modules. 802 /// 803 /// \param Diags - The diagnostics engine to use for reporting errors; its 804 /// lifetime is expected to extend past that of the returned ASTUnit. 805 /// 806 /// \param ResourceFilesPath - The path to the compiler resource files. 807 /// 808 /// \param StorePreamblesInMemory - Whether to store PCH in memory. If false, 809 /// PCH are stored in temporary files. 810 /// 811 /// \param PreambleStoragePath - The path to a directory, in which to create 812 /// temporary PCH files. If empty, the default system temporary directory is 813 /// used. This parameter is ignored if \p StorePreamblesInMemory is true. 814 /// 815 /// \param ModuleFormat - If provided, uses the specific module format. 816 /// 817 /// \param ErrAST - If non-null and parsing failed without any AST to return 818 /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit 819 /// mainly to allow the caller to see the diagnostics. 820 /// 821 /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses. 822 /// Note that preamble is saved to a temporary directory on a RealFileSystem, 823 /// so in order for it to be loaded correctly, VFS should have access to 824 /// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used 825 /// if \p VFS is nullptr. 826 /// 827 // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we 828 // shouldn't need to specify them at construction time. 829 static std::unique_ptr<ASTUnit> LoadFromCommandLine( 830 const char **ArgBegin, const char **ArgEnd, 831 std::shared_ptr<PCHContainerOperations> PCHContainerOps, 832 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath, 833 bool StorePreamblesInMemory = false, 834 StringRef PreambleStoragePath = StringRef(), bool OnlyLocalDecls = false, 835 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, 836 ArrayRef<RemappedFile> RemappedFiles = std::nullopt, 837 bool RemappedFilesKeepOriginalName = true, 838 unsigned PrecompilePreambleAfterNParses = 0, 839 TranslationUnitKind TUKind = TU_Complete, 840 bool CacheCodeCompletionResults = false, 841 bool IncludeBriefCommentsInCodeCompletion = false, 842 bool AllowPCHWithCompilerErrors = false, 843 SkipFunctionBodiesScope SkipFunctionBodies = 844 SkipFunctionBodiesScope::None, 845 bool SingleFileParse = false, bool UserFilesAreVolatile = false, 846 bool ForSerialization = false, 847 bool RetainExcludedConditionalBlocks = false, 848 std::optional<StringRef> ModuleFormat = std::nullopt, 849 std::unique_ptr<ASTUnit> *ErrAST = nullptr, 850 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr); 851 852 /// Reparse the source files using the same command-line options that 853 /// were originally used to produce this translation unit. 854 /// 855 /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses. 856 /// Note that preamble is saved to a temporary directory on a RealFileSystem, 857 /// so in order for it to be loaded correctly, VFS should give an access to 858 /// this(i.e. be an overlay over RealFileSystem). 859 /// FileMgr->getVirtualFileSystem() will be used if \p VFS is nullptr. 860 /// 861 /// \returns True if a failure occurred that causes the ASTUnit not to 862 /// contain any translation-unit information, false otherwise. 863 bool Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, 864 ArrayRef<RemappedFile> RemappedFiles = std::nullopt, 865 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr); 866 867 /// Free data that will be re-generated on the next parse. 868 /// 869 /// Preamble-related data is not affected. 870 void ResetForParse(); 871 872 /// Perform code completion at the given file, line, and 873 /// column within this translation unit. 874 /// 875 /// \param File The file in which code completion will occur. 876 /// 877 /// \param Line The line at which code completion will occur. 878 /// 879 /// \param Column The column at which code completion will occur. 880 /// 881 /// \param IncludeMacros Whether to include macros in the code-completion 882 /// results. 883 /// 884 /// \param IncludeCodePatterns Whether to include code patterns (such as a 885 /// for loop) in the code-completion results. 886 /// 887 /// \param IncludeBriefComments Whether to include brief documentation within 888 /// the set of code completions returned. 889 /// 890 /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and 891 /// OwnedBuffers parameters are all disgusting hacks. They will go away. 892 void CodeComplete(StringRef File, unsigned Line, unsigned Column, 893 ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros, 894 bool IncludeCodePatterns, bool IncludeBriefComments, 895 CodeCompleteConsumer &Consumer, 896 std::shared_ptr<PCHContainerOperations> PCHContainerOps, 897 DiagnosticsEngine &Diag, LangOptions &LangOpts, 898 SourceManager &SourceMgr, FileManager &FileMgr, 899 SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, 900 SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers); 901 902 /// Save this translation unit to a file with the given name. 903 /// 904 /// \returns true if there was a file error or false if the save was 905 /// successful. 906 bool Save(StringRef File); 907 908 /// Serialize this translation unit with the given output stream. 909 /// 910 /// \returns True if an error occurred, false otherwise. 911 bool serialize(raw_ostream &OS); 912 }; 913 914 } // namespace clang 915 916 #endif // LLVM_CLANG_FRONTEND_ASTUNIT_H 917