Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:55

0001 //===- ASTUnit.h - ASTUnit utility ------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // ASTUnit utility class.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H
0014 #define LLVM_CLANG_FRONTEND_ASTUNIT_H
0015 
0016 #include "clang-c/Index.h"
0017 #include "clang/AST/ASTContext.h"
0018 #include "clang/Basic/Diagnostic.h"
0019 #include "clang/Basic/FileSystemOptions.h"
0020 #include "clang/Basic/LLVM.h"
0021 #include "clang/Basic/LangOptions.h"
0022 #include "clang/Basic/SourceLocation.h"
0023 #include "clang/Basic/SourceManager.h"
0024 #include "clang/Basic/TargetOptions.h"
0025 #include "clang/Lex/HeaderSearchOptions.h"
0026 #include "clang/Lex/ModuleLoader.h"
0027 #include "clang/Lex/PreprocessingRecord.h"
0028 #include "clang/Sema/CodeCompleteConsumer.h"
0029 #include "clang/Serialization/ASTBitCodes.h"
0030 #include "clang/Frontend/PrecompiledPreamble.h"
0031 #include "llvm/ADT/ArrayRef.h"
0032 #include "llvm/ADT/DenseMap.h"
0033 #include "llvm/ADT/IntrusiveRefCntPtr.h"
0034 #include "llvm/ADT/STLExtras.h"
0035 #include "llvm/ADT/SmallVector.h"
0036 #include "llvm/ADT/StringMap.h"
0037 #include "llvm/ADT/StringRef.h"
0038 #include "llvm/ADT/iterator_range.h"
0039 #include <cassert>
0040 #include <cstddef>
0041 #include <cstdint>
0042 #include <memory>
0043 #include <optional>
0044 #include <string>
0045 #include <utility>
0046 #include <vector>
0047 
0048 namespace llvm {
0049 
0050 class MemoryBuffer;
0051 
0052 namespace vfs {
0053 
0054 class FileSystem;
0055 
0056 } // namespace vfs
0057 } // namespace llvm
0058 
0059 namespace clang {
0060 
0061 class ASTContext;
0062 class ASTDeserializationListener;
0063 class ASTMutationListener;
0064 class ASTReader;
0065 class CompilerInstance;
0066 class CompilerInvocation;
0067 class Decl;
0068 class FileEntry;
0069 class FileManager;
0070 class FrontendAction;
0071 class HeaderSearch;
0072 class InputKind;
0073 class InMemoryModuleCache;
0074 class PCHContainerOperations;
0075 class PCHContainerReader;
0076 class Preprocessor;
0077 class PreprocessorOptions;
0078 class Sema;
0079 class TargetInfo;
0080 class SyntaxOnlyAction;
0081 
0082 /// \brief Enumerates the available scopes for skipping function bodies.
0083 enum class SkipFunctionBodiesScope { None, Preamble, PreambleAndMainFile };
0084 
0085 /// \brief Enumerates the available kinds for capturing diagnostics.
0086 enum class CaptureDiagsKind { None, All, AllWithoutNonErrorsFromIncludes };
0087 
0088 /// Utility class for loading a ASTContext from an AST file.
0089 class ASTUnit {
0090 public:
0091   struct StandaloneFixIt {
0092     std::pair<unsigned, unsigned> RemoveRange;
0093     std::pair<unsigned, unsigned> InsertFromRange;
0094     std::string CodeToInsert;
0095     bool BeforePreviousInsertions;
0096   };
0097 
0098   struct StandaloneDiagnostic {
0099     unsigned ID;
0100     DiagnosticsEngine::Level Level;
0101     std::string Message;
0102     std::string Filename;
0103     unsigned LocOffset;
0104     std::vector<std::pair<unsigned, unsigned>> Ranges;
0105     std::vector<StandaloneFixIt> FixIts;
0106   };
0107 
0108 private:
0109   std::shared_ptr<LangOptions>            LangOpts;
0110   IntrusiveRefCntPtr<DiagnosticsEngine>   Diagnostics;
0111   IntrusiveRefCntPtr<FileManager>         FileMgr;
0112   IntrusiveRefCntPtr<SourceManager>       SourceMgr;
0113   IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
0114   std::unique_ptr<HeaderSearch>           HeaderInfo;
0115   IntrusiveRefCntPtr<TargetInfo>          Target;
0116   std::shared_ptr<Preprocessor>           PP;
0117   IntrusiveRefCntPtr<ASTContext>          Ctx;
0118   std::shared_ptr<TargetOptions>          TargetOpts;
0119   std::shared_ptr<HeaderSearchOptions>    HSOpts;
0120   std::shared_ptr<PreprocessorOptions>    PPOpts;
0121   IntrusiveRefCntPtr<ASTReader> Reader;
0122   bool HadModuleLoaderFatalFailure = false;
0123   bool StorePreamblesInMemory = false;
0124 
0125   struct ASTWriterData;
0126   std::unique_ptr<ASTWriterData> WriterData;
0127 
0128   FileSystemOptions FileSystemOpts;
0129   std::string PreambleStoragePath;
0130 
0131   /// The AST consumer that received information about the translation
0132   /// unit as it was parsed or loaded.
0133   std::unique_ptr<ASTConsumer> Consumer;
0134 
0135   /// The semantic analysis object used to type-check the translation
0136   /// unit.
0137   std::unique_ptr<Sema> TheSema;
0138 
0139   /// Optional owned invocation, just used to make the invocation used in
0140   /// LoadFromCommandLine available.
0141   std::shared_ptr<CompilerInvocation> Invocation;
0142 
0143   /// Fake module loader: the AST unit doesn't need to load any modules.
0144   TrivialModuleLoader ModuleLoader;
0145 
0146   // OnlyLocalDecls - when true, walking this AST should only visit declarations
0147   // that come from the AST itself, not from included precompiled headers.
0148   // FIXME: This is temporary; eventually, CIndex will always do this.
0149   bool OnlyLocalDecls = false;
0150 
0151   /// Whether to capture any diagnostics produced.
0152   CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None;
0153 
0154   /// Track whether the main file was loaded from an AST or not.
0155   bool MainFileIsAST;
0156 
0157   /// What kind of translation unit this AST represents.
0158   TranslationUnitKind TUKind = TU_Complete;
0159 
0160   /// Whether we should time each operation.
0161   bool WantTiming;
0162 
0163   /// Whether the ASTUnit should delete the remapped buffers.
0164   bool OwnsRemappedFileBuffers = true;
0165 
0166   /// Track the top-level decls which appeared in an ASTUnit which was loaded
0167   /// from a source file.
0168   //
0169   // FIXME: This is just an optimization hack to avoid deserializing large parts
0170   // of a PCH file when using the Index library on an ASTUnit loaded from
0171   // source. In the long term we should make the Index library use efficient and
0172   // more scalable search mechanisms.
0173   std::vector<Decl*> TopLevelDecls;
0174 
0175   /// Sorted (by file offset) vector of pairs of file offset/Decl.
0176   using LocDeclsTy = SmallVector<std::pair<unsigned, Decl *>, 64>;
0177   using FileDeclsTy = llvm::DenseMap<FileID, std::unique_ptr<LocDeclsTy>>;
0178 
0179   /// Map from FileID to the file-level declarations that it contains.
0180   /// The files and decls are only local (and non-preamble) ones.
0181   FileDeclsTy FileDecls;
0182 
0183   /// The name of the original source file used to generate this ASTUnit.
0184   std::string OriginalSourceFile;
0185 
0186   /// The set of diagnostics produced when creating the preamble.
0187   SmallVector<StandaloneDiagnostic, 4> PreambleDiagnostics;
0188 
0189   /// The set of diagnostics produced when creating this
0190   /// translation unit.
0191   SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
0192 
0193   /// The set of diagnostics produced when failing to parse, e.g. due
0194   /// to failure to load the PCH.
0195   SmallVector<StoredDiagnostic, 4> FailedParseDiagnostics;
0196 
0197   /// The number of stored diagnostics that come from the driver
0198   /// itself.
0199   ///
0200   /// Diagnostics that come from the driver are retained from one parse to
0201   /// the next.
0202   unsigned NumStoredDiagnosticsFromDriver = 0;
0203 
0204   /// Counter that determines when we want to try building a
0205   /// precompiled preamble.
0206   ///
0207   /// If zero, we will never build a precompiled preamble. Otherwise,
0208   /// it's treated as a counter that decrements each time we reparse
0209   /// without the benefit of a precompiled preamble. When it hits 1,
0210   /// we'll attempt to rebuild the precompiled header. This way, if
0211   /// building the precompiled preamble fails, we won't try again for
0212   /// some number of calls.
0213   unsigned PreambleRebuildCountdown = 0;
0214 
0215   /// Counter indicating how often the preamble was build in total.
0216   unsigned PreambleCounter = 0;
0217 
0218   /// Cache pairs "filename - source location"
0219   ///
0220   /// Cache contains only source locations from preamble so it is
0221   /// guaranteed that they stay valid when the SourceManager is recreated.
0222   /// This cache is used when loading preamble to increase performance
0223   /// of that loading. It must be cleared when preamble is recreated.
0224   llvm::StringMap<SourceLocation> PreambleSrcLocCache;
0225 
0226   /// The contents of the preamble.
0227   std::optional<PrecompiledPreamble> Preamble;
0228 
0229   /// When non-NULL, this is the buffer used to store the contents of
0230   /// the main file when it has been padded for use with the precompiled
0231   /// preamble.
0232   std::unique_ptr<llvm::MemoryBuffer> SavedMainFileBuffer;
0233 
0234   /// The number of warnings that occurred while parsing the preamble.
0235   ///
0236   /// This value will be used to restore the state of the \c DiagnosticsEngine
0237   /// object when re-using the precompiled preamble. Note that only the
0238   /// number of warnings matters, since we will not save the preamble
0239   /// when any errors are present.
0240   unsigned NumWarningsInPreamble = 0;
0241 
0242   /// A list of the serialization ID numbers for each of the top-level
0243   /// declarations parsed within the precompiled preamble.
0244   std::vector<LocalDeclID> TopLevelDeclsInPreamble;
0245 
0246   /// Whether we should be caching code-completion results.
0247   bool ShouldCacheCodeCompletionResults : 1;
0248 
0249   /// Whether to include brief documentation within the set of code
0250   /// completions cached.
0251   bool IncludeBriefCommentsInCodeCompletion : 1;
0252 
0253   /// True if non-system source files should be treated as volatile
0254   /// (likely to change while trying to use them).
0255   bool UserFilesAreVolatile : 1;
0256 
0257   static void ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
0258                              ASTUnit &AST, CaptureDiagsKind CaptureDiagnostics);
0259 
0260   void TranslateStoredDiagnostics(FileManager &FileMgr,
0261                                   SourceManager &SrcMan,
0262                       const SmallVectorImpl<StandaloneDiagnostic> &Diags,
0263                             SmallVectorImpl<StoredDiagnostic> &Out);
0264 
0265   void clearFileLevelDecls();
0266 
0267 public:
0268   /// A cached code-completion result, which may be introduced in one of
0269   /// many different contexts.
0270   struct CachedCodeCompletionResult {
0271     /// The code-completion string corresponding to this completion
0272     /// result.
0273     CodeCompletionString *Completion;
0274 
0275     /// A bitmask that indicates which code-completion contexts should
0276     /// contain this completion result.
0277     ///
0278     /// The bits in the bitmask correspond to the values of
0279     /// CodeCompleteContext::Kind. To map from a completion context kind to a
0280     /// bit, shift 1 by that number of bits. Many completions can occur in
0281     /// several different contexts.
0282     uint64_t ShowInContexts;
0283 
0284     /// The priority given to this code-completion result.
0285     unsigned Priority;
0286 
0287     /// The libclang cursor kind corresponding to this code-completion
0288     /// result.
0289     CXCursorKind Kind;
0290 
0291     /// The availability of this code-completion result.
0292     CXAvailabilityKind Availability;
0293 
0294     /// The simplified type class for a non-macro completion result.
0295     SimplifiedTypeClass TypeClass;
0296 
0297     /// The type of a non-macro completion result, stored as a unique
0298     /// integer used by the string map of cached completion types.
0299     ///
0300     /// This value will be zero if the type is not known, or a unique value
0301     /// determined by the formatted type string. Se \c CachedCompletionTypes
0302     /// for more information.
0303     unsigned Type;
0304   };
0305 
0306   /// Retrieve the mapping from formatted type names to unique type
0307   /// identifiers.
0308   llvm::StringMap<unsigned> &getCachedCompletionTypes() {
0309     return CachedCompletionTypes;
0310   }
0311 
0312   /// Retrieve the allocator used to cache global code completions.
0313   std::shared_ptr<GlobalCodeCompletionAllocator>
0314   getCachedCompletionAllocator() {
0315     return CachedCompletionAllocator;
0316   }
0317 
0318   CodeCompletionTUInfo &getCodeCompletionTUInfo() {
0319     if (!CCTUInfo)
0320       CCTUInfo = std::make_unique<CodeCompletionTUInfo>(
0321           std::make_shared<GlobalCodeCompletionAllocator>());
0322     return *CCTUInfo;
0323   }
0324 
0325 private:
0326   /// Allocator used to store cached code completions.
0327   std::shared_ptr<GlobalCodeCompletionAllocator> CachedCompletionAllocator;
0328 
0329   std::unique_ptr<CodeCompletionTUInfo> CCTUInfo;
0330 
0331   /// The set of cached code-completion results.
0332   std::vector<CachedCodeCompletionResult> CachedCompletionResults;
0333 
0334   /// A mapping from the formatted type name to a unique number for that
0335   /// type, which is used for type equality comparisons.
0336   llvm::StringMap<unsigned> CachedCompletionTypes;
0337 
0338   /// A string hash of the top-level declaration and macro definition
0339   /// names processed the last time that we reparsed the file.
0340   ///
0341   /// This hash value is used to determine when we need to refresh the
0342   /// global code-completion cache.
0343   unsigned CompletionCacheTopLevelHashValue = 0;
0344 
0345   /// A string hash of the top-level declaration and macro definition
0346   /// names processed the last time that we reparsed the precompiled preamble.
0347   ///
0348   /// This hash value is used to determine when we need to refresh the
0349   /// global code-completion cache after a rebuild of the precompiled preamble.
0350   unsigned PreambleTopLevelHashValue = 0;
0351 
0352   /// The current hash value for the top-level declaration and macro
0353   /// definition names
0354   unsigned CurrentTopLevelHashValue = 0;
0355 
0356   /// Bit used by CIndex to mark when a translation unit may be in an
0357   /// inconsistent state, and is not safe to free.
0358   LLVM_PREFERRED_TYPE(bool)
0359   unsigned UnsafeToFree : 1;
0360 
0361   /// \brief Enumerator specifying the scope for skipping function bodies.
0362   SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
0363 
0364   /// Cache any "global" code-completion results, so that we can avoid
0365   /// recomputing them with each completion.
0366   void CacheCodeCompletionResults();
0367 
0368   /// Clear out and deallocate
0369   void ClearCachedCompletionResults();
0370 
0371   explicit ASTUnit(bool MainFileIsAST);
0372 
0373   bool Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
0374              std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,
0375              IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS);
0376 
0377   std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble(
0378       std::shared_ptr<PCHContainerOperations> PCHContainerOps,
0379       CompilerInvocation &PreambleInvocationIn,
0380       IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, bool AllowRebuild = true,
0381       unsigned MaxLines = 0);
0382   void RealizeTopLevelDeclsFromPreamble();
0383 
0384   /// Transfers ownership of the objects (like SourceManager) from
0385   /// \param CI to this ASTUnit.
0386   void transferASTDataFromCompilerInstance(CompilerInstance &CI);
0387 
0388   /// Allows us to assert that ASTUnit is not being used concurrently,
0389   /// which is not supported.
0390   ///
0391   /// Clients should create instances of the ConcurrencyCheck class whenever
0392   /// using the ASTUnit in a way that isn't intended to be concurrent, which is
0393   /// just about any usage.
0394   /// Becomes a noop in release mode; only useful for debug mode checking.
0395   class ConcurrencyState {
0396     void *Mutex; // a std::recursive_mutex in debug;
0397 
0398   public:
0399     ConcurrencyState();
0400     ~ConcurrencyState();
0401 
0402     void start();
0403     void finish();
0404   };
0405   ConcurrencyState ConcurrencyCheckValue;
0406 
0407 public:
0408   friend class ConcurrencyCheck;
0409 
0410   class ConcurrencyCheck {
0411     ASTUnit &Self;
0412 
0413   public:
0414     explicit ConcurrencyCheck(ASTUnit &Self) : Self(Self) {
0415       Self.ConcurrencyCheckValue.start();
0416     }
0417 
0418     ~ConcurrencyCheck() {
0419       Self.ConcurrencyCheckValue.finish();
0420     }
0421   };
0422 
0423   ASTUnit(const ASTUnit &) = delete;
0424   ASTUnit &operator=(const ASTUnit &) = delete;
0425   ~ASTUnit();
0426 
0427   bool isMainFileAST() const { return MainFileIsAST; }
0428 
0429   bool isUnsafeToFree() const { return UnsafeToFree; }
0430   void setUnsafeToFree(bool Value) { UnsafeToFree = Value; }
0431 
0432   const DiagnosticsEngine &getDiagnostics() const { return *Diagnostics; }
0433   DiagnosticsEngine &getDiagnostics() { return *Diagnostics; }
0434 
0435   const SourceManager &getSourceManager() const { return *SourceMgr; }
0436   SourceManager &getSourceManager() { return *SourceMgr; }
0437 
0438   const Preprocessor &getPreprocessor() const { return *PP; }
0439   Preprocessor &getPreprocessor() { return *PP; }
0440   std::shared_ptr<Preprocessor> getPreprocessorPtr() const { return PP; }
0441 
0442   const ASTContext &getASTContext() const { return *Ctx; }
0443   ASTContext &getASTContext() { return *Ctx; }
0444 
0445   void setASTContext(ASTContext *ctx) { Ctx = ctx; }
0446   void setPreprocessor(std::shared_ptr<Preprocessor> pp);
0447 
0448   /// Enable source-range based diagnostic messages.
0449   ///
0450   /// If diagnostic messages with source-range information are to be expected
0451   /// and AST comes not from file (e.g. after LoadFromCompilerInvocation) this
0452   /// function has to be called.
0453   /// The function is to be called only once and the AST should be associated
0454   /// with the same source file afterwards.
0455   void enableSourceFileDiagnostics();
0456 
0457   bool hasSema() const { return (bool)TheSema; }
0458 
0459   Sema &getSema() const {
0460     assert(TheSema && "ASTUnit does not have a Sema object!");
0461     return *TheSema;
0462   }
0463 
0464   const LangOptions &getLangOpts() const {
0465     assert(LangOpts && "ASTUnit does not have language options");
0466     return *LangOpts;
0467   }
0468 
0469   const HeaderSearchOptions &getHeaderSearchOpts() const {
0470     assert(HSOpts && "ASTUnit does not have header search options");
0471     return *HSOpts;
0472   }
0473 
0474   const PreprocessorOptions &getPreprocessorOpts() const {
0475     assert(PPOpts && "ASTUnit does not have preprocessor options");
0476     return *PPOpts;
0477   }
0478 
0479   const FileManager &getFileManager() const { return *FileMgr; }
0480   FileManager &getFileManager() { return *FileMgr; }
0481 
0482   const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
0483 
0484   IntrusiveRefCntPtr<ASTReader> getASTReader() const;
0485 
0486   StringRef getOriginalSourceFileName() const {
0487     return OriginalSourceFile;
0488   }
0489 
0490   ASTMutationListener *getASTMutationListener();
0491   ASTDeserializationListener *getDeserializationListener();
0492 
0493   bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
0494 
0495   bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; }
0496   void setOwnsRemappedFileBuffers(bool val) { OwnsRemappedFileBuffers = val; }
0497 
0498   StringRef getMainFileName() const;
0499 
0500   /// If this ASTUnit came from an AST file, returns the filename for it.
0501   StringRef getASTFileName() const;
0502 
0503   using top_level_iterator = std::vector<Decl *>::iterator;
0504 
0505   top_level_iterator top_level_begin() {
0506     assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
0507     if (!TopLevelDeclsInPreamble.empty())
0508       RealizeTopLevelDeclsFromPreamble();
0509     return TopLevelDecls.begin();
0510   }
0511 
0512   top_level_iterator top_level_end() {
0513     assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
0514     if (!TopLevelDeclsInPreamble.empty())
0515       RealizeTopLevelDeclsFromPreamble();
0516     return TopLevelDecls.end();
0517   }
0518 
0519   std::size_t top_level_size() const {
0520     assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
0521     return TopLevelDeclsInPreamble.size() + TopLevelDecls.size();
0522   }
0523 
0524   bool top_level_empty() const {
0525     assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
0526     return TopLevelDeclsInPreamble.empty() && TopLevelDecls.empty();
0527   }
0528 
0529   /// Add a new top-level declaration.
0530   void addTopLevelDecl(Decl *D) {
0531     TopLevelDecls.push_back(D);
0532   }
0533 
0534   /// Add a new local file-level declaration.
0535   void addFileLevelDecl(Decl *D);
0536 
0537   /// Get the decls that are contained in a file in the Offset/Length
0538   /// range. \p Length can be 0 to indicate a point at \p Offset instead of
0539   /// a range.
0540   void findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
0541                            SmallVectorImpl<Decl *> &Decls);
0542 
0543   /// Retrieve a reference to the current top-level name hash value.
0544   ///
0545   /// Note: This is used internally by the top-level tracking action
0546   unsigned &getCurrentTopLevelHashValue() { return CurrentTopLevelHashValue; }
0547 
0548   /// Get the source location for the given file:line:col triplet.
0549   ///
0550   /// The difference with SourceManager::getLocation is that this method checks
0551   /// whether the requested location points inside the precompiled preamble
0552   /// in which case the returned source location will be a "loaded" one.
0553   SourceLocation getLocation(const FileEntry *File,
0554                              unsigned Line, unsigned Col) const;
0555 
0556   /// Get the source location for the given file:offset pair.
0557   SourceLocation getLocation(const FileEntry *File, unsigned Offset) const;
0558 
0559   /// If \p Loc is a loaded location from the preamble, returns
0560   /// the corresponding local location of the main file, otherwise it returns
0561   /// \p Loc.
0562   SourceLocation mapLocationFromPreamble(SourceLocation Loc) const;
0563 
0564   /// If \p Loc is a local location of the main file but inside the
0565   /// preamble chunk, returns the corresponding loaded location from the
0566   /// preamble, otherwise it returns \p Loc.
0567   SourceLocation mapLocationToPreamble(SourceLocation Loc) const;
0568 
0569   bool isInPreambleFileID(SourceLocation Loc) const;
0570   bool isInMainFileID(SourceLocation Loc) const;
0571   SourceLocation getStartOfMainFileID() const;
0572   SourceLocation getEndOfPreambleFileID() const;
0573 
0574   /// \see mapLocationFromPreamble.
0575   SourceRange mapRangeFromPreamble(SourceRange R) const {
0576     return SourceRange(mapLocationFromPreamble(R.getBegin()),
0577                        mapLocationFromPreamble(R.getEnd()));
0578   }
0579 
0580   /// \see mapLocationToPreamble.
0581   SourceRange mapRangeToPreamble(SourceRange R) const {
0582     return SourceRange(mapLocationToPreamble(R.getBegin()),
0583                        mapLocationToPreamble(R.getEnd()));
0584   }
0585 
0586   unsigned getPreambleCounterForTests() const { return PreambleCounter; }
0587 
0588   // Retrieve the diagnostics associated with this AST
0589   using stored_diag_iterator = StoredDiagnostic *;
0590   using stored_diag_const_iterator = const StoredDiagnostic *;
0591 
0592   stored_diag_const_iterator stored_diag_begin() const {
0593     return StoredDiagnostics.begin();
0594   }
0595 
0596   stored_diag_iterator stored_diag_begin() {
0597     return StoredDiagnostics.begin();
0598   }
0599 
0600   stored_diag_const_iterator stored_diag_end() const {
0601     return StoredDiagnostics.end();
0602   }
0603 
0604   stored_diag_iterator stored_diag_end() {
0605     return StoredDiagnostics.end();
0606   }
0607 
0608   unsigned stored_diag_size() const { return StoredDiagnostics.size(); }
0609 
0610   stored_diag_iterator stored_diag_afterDriver_begin() {
0611     if (NumStoredDiagnosticsFromDriver > StoredDiagnostics.size())
0612       NumStoredDiagnosticsFromDriver = 0;
0613     return StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver;
0614   }
0615 
0616   using cached_completion_iterator =
0617       std::vector<CachedCodeCompletionResult>::iterator;
0618 
0619   cached_completion_iterator cached_completion_begin() {
0620     return CachedCompletionResults.begin();
0621   }
0622 
0623   cached_completion_iterator cached_completion_end() {
0624     return CachedCompletionResults.end();
0625   }
0626 
0627   unsigned cached_completion_size() const {
0628     return CachedCompletionResults.size();
0629   }
0630 
0631   /// Returns an iterator range for the local preprocessing entities
0632   /// of the local Preprocessor, if this is a parsed source file, or the loaded
0633   /// preprocessing entities of the primary module if this is an AST file.
0634   llvm::iterator_range<PreprocessingRecord::iterator>
0635   getLocalPreprocessingEntities() const;
0636 
0637   /// Type for a function iterating over a number of declarations.
0638   /// \returns true to continue iteration and false to abort.
0639   using DeclVisitorFn = bool (*)(void *context, const Decl *D);
0640 
0641   /// Iterate over local declarations (locally parsed if this is a parsed
0642   /// source file or the loaded declarations of the primary module if this is an
0643   /// AST file).
0644   /// \returns true if the iteration was complete or false if it was aborted.
0645   bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn);
0646 
0647   /// Get the PCH file if one was included.
0648   OptionalFileEntryRef getPCHFile();
0649 
0650   /// Returns true if the ASTUnit was constructed from a serialized
0651   /// module file.
0652   bool isModuleFile() const;
0653 
0654   std::unique_ptr<llvm::MemoryBuffer>
0655   getBufferForFile(StringRef Filename, std::string *ErrorStr = nullptr);
0656 
0657   /// Determine what kind of translation unit this AST represents.
0658   TranslationUnitKind getTranslationUnitKind() const { return TUKind; }
0659 
0660   /// Determine the input kind this AST unit represents.
0661   InputKind getInputKind() const;
0662 
0663   /// A mapping from a file name to the memory buffer that stores the
0664   /// remapped contents of that file.
0665   using RemappedFile = std::pair<std::string, llvm::MemoryBuffer *>;
0666 
0667   /// Create a ASTUnit. Gets ownership of the passed CompilerInvocation.
0668   static std::unique_ptr<ASTUnit>
0669   create(std::shared_ptr<CompilerInvocation> CI,
0670          IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
0671          CaptureDiagsKind CaptureDiagnostics, bool UserFilesAreVolatile);
0672 
0673   enum WhatToLoad {
0674     /// Load options and the preprocessor state.
0675     LoadPreprocessorOnly,
0676 
0677     /// Load the AST, but do not restore Sema state.
0678     LoadASTOnly,
0679 
0680     /// Load everything, including Sema.
0681     LoadEverything
0682   };
0683 
0684   /// Create a ASTUnit from an AST file.
0685   ///
0686   /// \param Filename - The AST file to load.
0687   ///
0688   /// \param PCHContainerRdr - The PCHContainerOperations to use for loading and
0689   /// creating modules.
0690   /// \param Diags - The diagnostics engine to use for reporting errors; its
0691   /// lifetime is expected to extend past that of the returned ASTUnit.
0692   ///
0693   /// \returns - The initialized ASTUnit or null if the AST failed to load.
0694   static std::unique_ptr<ASTUnit>
0695   LoadFromASTFile(StringRef Filename, const PCHContainerReader &PCHContainerRdr,
0696                   WhatToLoad ToLoad,
0697                   IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
0698                   const FileSystemOptions &FileSystemOpts,
0699                   std::shared_ptr<HeaderSearchOptions> HSOpts,
0700                   std::shared_ptr<LangOptions> LangOpts = nullptr,
0701                   bool OnlyLocalDecls = false,
0702                   CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
0703                   bool AllowASTWithCompilerErrors = false,
0704                   bool UserFilesAreVolatile = false,
0705                   IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
0706                       llvm::vfs::getRealFileSystem());
0707 
0708 private:
0709   /// Helper function for \c LoadFromCompilerInvocation() and
0710   /// \c LoadFromCommandLine(), which loads an AST from a compiler invocation.
0711   ///
0712   /// \param PrecompilePreambleAfterNParses After how many parses the preamble
0713   /// of this translation unit should be precompiled, to improve the performance
0714   /// of reparsing. Set to zero to disable preambles.
0715   ///
0716   /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
0717   /// Note that preamble is saved to a temporary directory on a RealFileSystem,
0718   /// so in order for it to be loaded correctly, VFS should have access to
0719   /// it(i.e., be an overlay over RealFileSystem).
0720   ///
0721   /// \returns \c true if a catastrophic failure occurred (which means that the
0722   /// \c ASTUnit itself is invalid), or \c false otherwise.
0723   bool LoadFromCompilerInvocation(
0724       std::shared_ptr<PCHContainerOperations> PCHContainerOps,
0725       unsigned PrecompilePreambleAfterNParses,
0726       IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS);
0727 
0728 public:
0729   /// Create an ASTUnit from a source file, via a CompilerInvocation
0730   /// object, by invoking the optionally provided ASTFrontendAction.
0731   ///
0732   /// \param CI - The compiler invocation to use; it must have exactly one input
0733   /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
0734   ///
0735   /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
0736   /// creating modules.
0737   ///
0738   /// \param Diags - The diagnostics engine to use for reporting errors; its
0739   /// lifetime is expected to extend past that of the returned ASTUnit.
0740   ///
0741   /// \param Action - The ASTFrontendAction to invoke. Its ownership is not
0742   /// transferred.
0743   ///
0744   /// \param Unit - optionally an already created ASTUnit. Its ownership is not
0745   /// transferred.
0746   ///
0747   /// \param Persistent - if true the returned ASTUnit will be complete.
0748   /// false means the caller is only interested in getting info through the
0749   /// provided \see Action.
0750   ///
0751   /// \param ErrAST - If non-null and parsing failed without any AST to return
0752   /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
0753   /// mainly to allow the caller to see the diagnostics.
0754   /// This will only receive an ASTUnit if a new one was created. If an already
0755   /// created ASTUnit was passed in \p Unit then the caller can check that.
0756   ///
0757   static ASTUnit *LoadFromCompilerInvocationAction(
0758       std::shared_ptr<CompilerInvocation> CI,
0759       std::shared_ptr<PCHContainerOperations> PCHContainerOps,
0760       IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
0761       FrontendAction *Action = nullptr, ASTUnit *Unit = nullptr,
0762       bool Persistent = true, StringRef ResourceFilesPath = StringRef(),
0763       bool OnlyLocalDecls = false,
0764       CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
0765       unsigned PrecompilePreambleAfterNParses = 0,
0766       bool CacheCodeCompletionResults = false,
0767       bool UserFilesAreVolatile = false,
0768       std::unique_ptr<ASTUnit> *ErrAST = nullptr);
0769 
0770   /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
0771   /// CompilerInvocation object.
0772   ///
0773   /// \param CI - The compiler invocation to use; it must have exactly one input
0774   /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
0775   ///
0776   /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
0777   /// creating modules.
0778   ///
0779   /// \param Diags - The diagnostics engine to use for reporting errors; its
0780   /// lifetime is expected to extend past that of the returned ASTUnit.
0781   //
0782   // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
0783   // shouldn't need to specify them at construction time.
0784   static std::unique_ptr<ASTUnit> LoadFromCompilerInvocation(
0785       std::shared_ptr<CompilerInvocation> CI,
0786       std::shared_ptr<PCHContainerOperations> PCHContainerOps,
0787       IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr,
0788       bool OnlyLocalDecls = false,
0789       CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
0790       unsigned PrecompilePreambleAfterNParses = 0,
0791       TranslationUnitKind TUKind = TU_Complete,
0792       bool CacheCodeCompletionResults = false,
0793       bool IncludeBriefCommentsInCodeCompletion = false,
0794       bool UserFilesAreVolatile = false);
0795 
0796   /// LoadFromCommandLine - Create an ASTUnit from a vector of command line
0797   /// arguments, which must specify exactly one source file.
0798   ///
0799   /// \param ArgBegin - The beginning of the argument vector.
0800   ///
0801   /// \param ArgEnd - The end of the argument vector.
0802   ///
0803   /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
0804   /// creating modules.
0805   ///
0806   /// \param Diags - The diagnostics engine to use for reporting errors; its
0807   /// lifetime is expected to extend past that of the returned ASTUnit.
0808   ///
0809   /// \param ResourceFilesPath - The path to the compiler resource files.
0810   ///
0811   /// \param StorePreamblesInMemory - Whether to store PCH in memory. If false,
0812   /// PCH are stored in temporary files.
0813   ///
0814   /// \param PreambleStoragePath - The path to a directory, in which to create
0815   /// temporary PCH files. If empty, the default system temporary directory is
0816   /// used. This parameter is ignored if \p StorePreamblesInMemory is true.
0817   ///
0818   /// \param ModuleFormat - If provided, uses the specific module format.
0819   ///
0820   /// \param ErrAST - If non-null and parsing failed without any AST to return
0821   /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
0822   /// mainly to allow the caller to see the diagnostics.
0823   ///
0824   /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
0825   /// Note that preamble is saved to a temporary directory on a RealFileSystem,
0826   /// so in order for it to be loaded correctly, VFS should have access to
0827   /// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used
0828   /// if \p VFS is nullptr.
0829   ///
0830   // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
0831   // shouldn't need to specify them at construction time.
0832   static std::unique_ptr<ASTUnit> LoadFromCommandLine(
0833       const char **ArgBegin, const char **ArgEnd,
0834       std::shared_ptr<PCHContainerOperations> PCHContainerOps,
0835       IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
0836       bool StorePreamblesInMemory = false,
0837       StringRef PreambleStoragePath = StringRef(), bool OnlyLocalDecls = false,
0838       CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
0839       ArrayRef<RemappedFile> RemappedFiles = {},
0840       bool RemappedFilesKeepOriginalName = true,
0841       unsigned PrecompilePreambleAfterNParses = 0,
0842       TranslationUnitKind TUKind = TU_Complete,
0843       bool CacheCodeCompletionResults = false,
0844       bool IncludeBriefCommentsInCodeCompletion = false,
0845       bool AllowPCHWithCompilerErrors = false,
0846       SkipFunctionBodiesScope SkipFunctionBodies =
0847           SkipFunctionBodiesScope::None,
0848       bool SingleFileParse = false, bool UserFilesAreVolatile = false,
0849       bool ForSerialization = false,
0850       bool RetainExcludedConditionalBlocks = false,
0851       std::optional<StringRef> ModuleFormat = std::nullopt,
0852       std::unique_ptr<ASTUnit> *ErrAST = nullptr,
0853       IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
0854 
0855   /// Reparse the source files using the same command-line options that
0856   /// were originally used to produce this translation unit.
0857   ///
0858   /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
0859   /// Note that preamble is saved to a temporary directory on a RealFileSystem,
0860   /// so in order for it to be loaded correctly, VFS should give an access to
0861   /// this(i.e. be an overlay over RealFileSystem).
0862   /// FileMgr->getVirtualFileSystem() will be used if \p VFS is nullptr.
0863   ///
0864   /// \returns True if a failure occurred that causes the ASTUnit not to
0865   /// contain any translation-unit information, false otherwise.
0866   bool Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
0867                ArrayRef<RemappedFile> RemappedFiles = {},
0868                IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
0869 
0870   /// Free data that will be re-generated on the next parse.
0871   ///
0872   /// Preamble-related data is not affected.
0873   void ResetForParse();
0874 
0875   /// Perform code completion at the given file, line, and
0876   /// column within this translation unit.
0877   ///
0878   /// \param File The file in which code completion will occur.
0879   ///
0880   /// \param Line The line at which code completion will occur.
0881   ///
0882   /// \param Column The column at which code completion will occur.
0883   ///
0884   /// \param IncludeMacros Whether to include macros in the code-completion
0885   /// results.
0886   ///
0887   /// \param IncludeCodePatterns Whether to include code patterns (such as a
0888   /// for loop) in the code-completion results.
0889   ///
0890   /// \param IncludeBriefComments Whether to include brief documentation within
0891   /// the set of code completions returned.
0892   ///
0893   /// \param Act If supplied, this argument is used to parse the input file,
0894   /// allowing customized parsing by overriding SyntaxOnlyAction lifecycle
0895   /// methods.
0896   ///
0897   /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and
0898   /// OwnedBuffers parameters are all disgusting hacks. They will go away.
0899   void CodeComplete(StringRef File, unsigned Line, unsigned Column,
0900                     ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,
0901                     bool IncludeCodePatterns, bool IncludeBriefComments,
0902                     CodeCompleteConsumer &Consumer,
0903                     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
0904                     DiagnosticsEngine &Diag, LangOptions &LangOpts,
0905                     SourceManager &SourceMgr, FileManager &FileMgr,
0906                     SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
0907                     SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers,
0908                     std::unique_ptr<SyntaxOnlyAction> Act);
0909 
0910   /// Save this translation unit to a file with the given name.
0911   ///
0912   /// \returns true if there was a file error or false if the save was
0913   /// successful.
0914   bool Save(StringRef File);
0915 
0916   /// Serialize this translation unit with the given output stream.
0917   ///
0918   /// \returns True if an error occurred, false otherwise.
0919   bool serialize(raw_ostream &OS);
0920 };
0921 
0922 } // namespace clang
0923 
0924 #endif // LLVM_CLANG_FRONTEND_ASTUNIT_H