From 519fc96c475680de2cc49e7811dbbfadb912cbcc Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 23 Oct 2019 17:52:09 +0000 Subject: Vendor import of stripped clang trunk r375505, the last commit before the upstream Subversion repository was made read-only, and the LLVM project migrated to GitHub: https://llvm.org/svn/llvm-project/cfe/trunk@375505 --- include/clang/CrossTU/CrossTranslationUnit.h | 143 ++++++++++++++++++++++++--- 1 file changed, 127 insertions(+), 16 deletions(-) (limited to 'include/clang/CrossTU') diff --git a/include/clang/CrossTU/CrossTranslationUnit.h b/include/clang/CrossTU/CrossTranslationUnit.h index d64329cdff3e..4d2b7109c62a 100644 --- a/include/clang/CrossTU/CrossTranslationUnit.h +++ b/include/clang/CrossTU/CrossTranslationUnit.h @@ -17,6 +17,7 @@ #include "clang/AST/ASTImporterSharedState.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/Error.h" @@ -153,18 +154,34 @@ public: /// was passed to the constructor. /// /// \return Returns the resulting definition or an error. - llvm::Expected importDefinition(const FunctionDecl *FD); - llvm::Expected importDefinition(const VarDecl *VD); + llvm::Expected importDefinition(const FunctionDecl *FD, + ASTUnit *Unit); + llvm::Expected importDefinition(const VarDecl *VD, + ASTUnit *Unit); /// Get a name to identify a named decl. - static std::string getLookupName(const NamedDecl *ND); + static llvm::Optional getLookupName(const NamedDecl *ND); /// Emit diagnostics for the user for potential configuration errors. void emitCrossTUDiagnostics(const IndexError &IE); + /// Determine the original source location in the original TU for an + /// imported source location. + /// \p ToLoc Source location in the imported-to AST. + /// \return Source location in the imported-from AST and the corresponding + /// ASTUnit object (the AST was loaded from a file using an internal ASTUnit + /// object that is returned here). + /// If any error happens (ToLoc is a non-imported source location) empty is + /// returned. + llvm::Optional> + getImportedFromSourceLocation(const clang::SourceLocation &ToLoc) const; + private: + using ImportedFileIDMap = + llvm::DenseMap>; + void lazyInitImporterSharedSt(TranslationUnitDecl *ToTU); - ASTImporter &getOrCreateASTImporter(ASTContext &From); + ASTImporter &getOrCreateASTImporter(ASTUnit *Unit); template llvm::Expected getCrossTUDefinitionImpl(const T *D, StringRef CrossTUDir, @@ -174,20 +191,114 @@ private: const T *findDefInDeclContext(const DeclContext *DC, StringRef LookupName); template - llvm::Expected importDefinitionImpl(const T *D); - - llvm::StringMap> FileASTUnitMap; - llvm::StringMap NameASTUnitMap; - llvm::StringMap NameFileMap; - llvm::DenseMap> - ASTUnitImporterMap; - CompilerInstance &CI; + llvm::Expected importDefinitionImpl(const T *D, ASTUnit *Unit); + + using ImporterMapTy = + llvm::DenseMap>; + + ImporterMapTy ASTUnitImporterMap; + ASTContext &Context; std::shared_ptr ImporterSharedSt; - /// \p CTULoadTreshold should serve as an upper limit to the number of TUs - /// imported in order to reduce the memory footprint of CTU analysis. - const unsigned CTULoadThreshold; - unsigned NumASTLoaded{0u}; + /// Map of imported FileID's (in "To" context) to FileID in "From" context + /// and the ASTUnit for the From context. + /// This map is used by getImportedFromSourceLocation to lookup a FileID and + /// its Preprocessor when knowing only the FileID in the 'To' context. The + /// FileID could be imported by any of multiple 'From' ASTImporter objects. + /// we do not want to loop over all ASTImporter's to find the one that + /// imported the FileID. + ImportedFileIDMap ImportedFileIDs; + + /// Functor for loading ASTUnits from AST-dump files. + class ASTFileLoader { + public: + ASTFileLoader(const CompilerInstance &CI); + std::unique_ptr operator()(StringRef ASTFilePath); + + private: + const CompilerInstance &CI; + }; + + /// Maintain number of AST loads and check for reaching the load limit. + class ASTLoadGuard { + public: + ASTLoadGuard(unsigned Limit) : Limit(Limit) {} + + /// Indicates, whether a new load operation is permitted, it is within the + /// threshold. + operator bool() const { return Count < Limit; } + + /// Tell that a new AST was loaded successfully. + void indicateLoadSuccess() { ++Count; } + + private: + /// The number of ASTs actually imported. + unsigned Count{0u}; + /// The limit (threshold) value for number of loaded ASTs. + const unsigned Limit; + }; + + /// Storage and load of ASTUnits, cached access, and providing searchability + /// are the concerns of ASTUnitStorage class. + class ASTUnitStorage { + public: + ASTUnitStorage(const CompilerInstance &CI); + /// Loads an ASTUnit for a function. + /// + /// \param FunctionName USR name of the function. + /// \param CrossTUDir Path to the directory used to store CTU related files. + /// \param IndexName Name of the file inside \p CrossTUDir which maps + /// function USR names to file paths. These files contain the corresponding + /// AST-dumps. + /// \param DisplayCTUProgress Display a message about loading new ASTs. + /// + /// \return An Expected instance which contains the ASTUnit pointer or the + /// error occured during the load. + llvm::Expected getASTUnitForFunction(StringRef FunctionName, + StringRef CrossTUDir, + StringRef IndexName, + bool DisplayCTUProgress); + /// Identifies the path of the file which can be used to load the ASTUnit + /// for a given function. + /// + /// \param FunctionName USR name of the function. + /// \param CrossTUDir Path to the directory used to store CTU related files. + /// \param IndexName Name of the file inside \p CrossTUDir which maps + /// function USR names to file paths. These files contain the corresponding + /// AST-dumps. + /// + /// \return An Expected instance containing the filepath. + llvm::Expected getFileForFunction(StringRef FunctionName, + StringRef CrossTUDir, + StringRef IndexName); + + private: + llvm::Error ensureCTUIndexLoaded(StringRef CrossTUDir, StringRef IndexName); + llvm::Expected getASTUnitForFile(StringRef FileName, + bool DisplayCTUProgress); + + template using BaseMapTy = llvm::StringMap; + using OwningMapTy = BaseMapTy>; + using NonOwningMapTy = BaseMapTy; + + OwningMapTy FileASTUnitMap; + NonOwningMapTy NameASTUnitMap; + + using IndexMapTy = BaseMapTy; + IndexMapTy NameFileMap; + + ASTFileLoader FileAccessor; + + /// Limit the number of loaded ASTs. Used to limit the memory usage of the + /// CrossTranslationUnitContext. + /// The ASTUnitStorage has the knowledge about if the AST to load is + /// actually loaded or returned from cache. This information is needed to + /// maintain the counter. + ASTLoadGuard LoadGuard; + }; + + ASTUnitStorage ASTStorage; + }; } // namespace cross_tu -- cgit v1.2.3