diff options
Diffstat (limited to 'include/clang/Serialization/ASTReader.h')
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 544 |
1 files changed, 381 insertions, 163 deletions
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 996a134..9baaf4b 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -34,6 +34,8 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/DenseSet.h" @@ -162,16 +164,16 @@ private: void Error(const char *Msg); }; -namespace serialization { +namespace serialization { class ReadMethodPoolVisitor; - + namespace reader { class ASTIdentifierLookupTrait; } - + } // end namespace serialization - + /// \brief Reads an AST files chain containing the contents of a translation /// unit. /// @@ -191,7 +193,7 @@ class ASTReader public ExternalSemaSource, public IdentifierInfoLookup, public ExternalIdentifierLookup, - public ExternalSLocEntrySource + public ExternalSLocEntrySource { public: enum ASTReadResult { Success, Failure, IgnorePCH }; @@ -205,18 +207,18 @@ public: friend class ASTWriter; friend class ASTUnit; // ASTUnit needs to remap source locations. friend class serialization::ReadMethodPoolVisitor; - - typedef serialization::Module Module; + + typedef serialization::ModuleFile ModuleFile; typedef serialization::ModuleKind ModuleKind; typedef serialization::ModuleManager ModuleManager; - + typedef ModuleManager::ModuleIterator ModuleIterator; typedef ModuleManager::ModuleConstIterator ModuleConstIterator; typedef ModuleManager::ModuleReverseIterator ModuleReverseIterator; private: /// \brief The receiver of some callbacks invoked by ASTReader. - llvm::OwningPtr<ASTReaderListener> Listener; + OwningPtr<ASTReaderListener> Listener; /// \brief The receiver of deserialization events. ASTDeserializationListener *DeserializationListener; @@ -224,7 +226,7 @@ private: SourceManager &SourceMgr; FileManager &FileMgr; DiagnosticsEngine &Diags; - + /// \brief The semantic analysis object that will be processing the /// AST files and the translation unit that uses it. Sema *SemaObj; @@ -234,7 +236,7 @@ private: /// \brief The AST context into which we'll read the AST files. ASTContext &Context; - + /// \brief The AST consumer. ASTConsumer *Consumer; @@ -243,24 +245,24 @@ private: /// \brief A map of global bit offsets to the module that stores entities /// at those bit offsets. - ContinuousRangeMap<uint64_t, Module*, 4> GlobalBitOffsetsMap; + ContinuousRangeMap<uint64_t, ModuleFile*, 4> GlobalBitOffsetsMap; /// \brief A map of negated SLocEntryIDs to the modules containing them. - ContinuousRangeMap<unsigned, Module*, 64> GlobalSLocEntryMap; + ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocEntryMap; + + typedef ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocOffsetMapType; - typedef ContinuousRangeMap<unsigned, Module*, 64> GlobalSLocOffsetMapType; - /// \brief A map of reversed (SourceManager::MaxLoadedOffset - SLocOffset) /// SourceLocation offsets to the modules containing them. GlobalSLocOffsetMapType GlobalSLocOffsetMap; - + /// \brief Types that have already been loaded from the chain. /// /// When the pointer at index I is non-NULL, the type with /// ID = (I + 1) << FastQual::Width has already been loaded std::vector<QualType> TypesLoaded; - typedef ContinuousRangeMap<serialization::TypeID, Module *, 4> + typedef ContinuousRangeMap<serialization::TypeID, ModuleFile *, 4> GlobalTypeMapType; /// \brief Mapping from global type IDs to the module in which the @@ -274,60 +276,67 @@ private: /// = I + 1 has already been loaded. std::vector<Decl *> DeclsLoaded; - typedef ContinuousRangeMap<serialization::DeclID, Module *, 4> + typedef ContinuousRangeMap<serialization::DeclID, ModuleFile *, 4> GlobalDeclMapType; - + /// \brief Mapping from global declaration IDs to the module in which the /// declaration resides. GlobalDeclMapType GlobalDeclMap; - - typedef std::pair<Module *, uint64_t> FileOffset; + + typedef std::pair<ModuleFile *, uint64_t> FileOffset; typedef SmallVector<FileOffset, 2> FileOffsetsTy; typedef llvm::DenseMap<serialization::DeclID, FileOffsetsTy> DeclUpdateOffsetsMap; - + /// \brief Declarations that have modifications residing in a later file /// in the chain. DeclUpdateOffsetsMap DeclUpdateOffsets; - typedef llvm::DenseMap<serialization::DeclID, - std::pair<Module *, uint64_t> > + struct ReplacedDeclInfo { + ModuleFile *Mod; + uint64_t Offset; + unsigned RawLoc; + + ReplacedDeclInfo() : Mod(0), Offset(0), RawLoc(0) {} + ReplacedDeclInfo(ModuleFile *Mod, uint64_t Offset, unsigned RawLoc) + : Mod(Mod), Offset(Offset), RawLoc(RawLoc) {} + }; + + typedef llvm::DenseMap<serialization::DeclID, ReplacedDeclInfo> DeclReplacementMap; /// \brief Declarations that have been replaced in a later file in the chain. DeclReplacementMap ReplacedDecls; + struct FileDeclsInfo { + ModuleFile *Mod; + ArrayRef<serialization::LocalDeclID> Decls; + + FileDeclsInfo() : Mod(0) {} + FileDeclsInfo(ModuleFile *Mod, ArrayRef<serialization::LocalDeclID> Decls) + : Mod(Mod), Decls(Decls) {} + }; + + /// \brief Map from a FileID to the file-level declarations that it contains. + llvm::DenseMap<FileID, FileDeclsInfo> FileDeclIDs; + // Updates for visible decls can occur for other contexts than just the // TU, and when we read those update records, the actual context will not // be available yet (unless it's the TU), so have this pending map using the // ID as a key. It will be realized when the context is actually loaded. - typedef SmallVector<std::pair<void *, Module*>, 1> DeclContextVisibleUpdates; + typedef SmallVector<std::pair<void *, ModuleFile*>, 1> DeclContextVisibleUpdates; typedef llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates> DeclContextVisibleUpdatesPending; /// \brief Updates to the visible declarations of declaration contexts that /// haven't been loaded yet. DeclContextVisibleUpdatesPending PendingVisibleUpdates; - - typedef SmallVector<CXXRecordDecl *, 4> ForwardRefs; - typedef llvm::DenseMap<const CXXRecordDecl *, ForwardRefs> - PendingForwardRefsMap; - /// \brief Forward references that have a definition but the definition decl - /// is still initializing. When the definition gets read it will update - /// the DefinitionData pointer of all pending references. - PendingForwardRefsMap PendingForwardRefs; - - typedef llvm::DenseMap<serialization::DeclID, serialization::DeclID> - FirstLatestDeclIDMap; - /// \brief Map of first declarations from a chained PCH that point to the - /// most recent declarations in another AST file. - FirstLatestDeclIDMap FirstLatestDeclIDs; - - /// \brief Set of ObjC interfaces that have categories chained to them in - /// other modules. - llvm::DenseSet<serialization::GlobalDeclID> ObjCChainedCategoriesInterfaces; - + + /// \brief The set of C++ or Objective-C classes that have forward + /// declarations that have not yet been linked to their definitions. + llvm::SmallPtrSet<Decl *, 4> PendingDefinitions; + /// \brief Read the records that describe the contents of declcontexts. - bool ReadDeclContextStorage(Module &M, + bool ReadDeclContextStorage(ModuleFile &M, llvm::BitstreamCursor &Cursor, const std::pair<uint64_t, uint64_t> &Offsets, serialization::DeclContextInfo &Info); @@ -340,14 +349,62 @@ private: /// been loaded. std::vector<IdentifierInfo *> IdentifiersLoaded; - typedef ContinuousRangeMap<serialization::IdentID, Module *, 4> + typedef ContinuousRangeMap<serialization::IdentID, ModuleFile *, 4> GlobalIdentifierMapType; - + /// \brief Mapping from global identifer IDs to the module in which the /// identifier resides along with the offset that should be added to the /// global identifier ID to produce a local ID. GlobalIdentifierMapType GlobalIdentifierMap; + /// \brief A vector containing submodules that have already been loaded. + /// + /// This vector is indexed by the Submodule ID (-1). NULL submodule entries + /// indicate that the particular submodule ID has not yet been loaded. + SmallVector<Module *, 2> SubmodulesLoaded; + + typedef ContinuousRangeMap<serialization::SubmoduleID, ModuleFile *, 4> + GlobalSubmoduleMapType; + + /// \brief Mapping from global submodule IDs to the module file in which the + /// submodule resides along with the offset that should be added to the + /// global submodule ID to produce a local ID. + GlobalSubmoduleMapType GlobalSubmoduleMap; + + /// \brief A set of hidden declarations. + typedef llvm::SmallVector<llvm::PointerUnion<Decl *, IdentifierInfo *>, 2> + HiddenNames; + + typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType; + + /// \brief A mapping from each of the hidden submodules to the deserialized + /// declarations in that submodule that could be made visible. + HiddenNamesMapType HiddenNamesMap; + + + /// \brief A module import or export that hasn't yet been resolved. + struct UnresolvedModuleImportExport { + /// \brief The file in which this module resides. + ModuleFile *File; + + /// \brief The module that is importing or exporting. + Module *Mod; + + /// \brief The local ID of the module that is being exported. + unsigned ID; + + /// \brief Whether this is an import (vs. an export). + unsigned IsImport : 1; + + /// \brief Whether this is a wildcard export. + unsigned IsWildcard : 1; + }; + + /// \brief The set of module imports and exports that still need to be + /// resolved. + llvm::SmallVector<UnresolvedModuleImportExport, 2> + UnresolvedModuleImportExports; + /// \brief A vector containing selectors that have already been loaded. /// /// This vector is indexed by the Selector ID (-1). NULL selector @@ -355,27 +412,31 @@ private: /// been loaded. SmallVector<Selector, 16> SelectorsLoaded; - typedef ContinuousRangeMap<serialization::SelectorID, Module *, 4> + typedef ContinuousRangeMap<serialization::SelectorID, ModuleFile *, 4> GlobalSelectorMapType; - + /// \brief Mapping from global selector IDs to the module in which the /// selector resides along with the offset that should be added to the /// global selector ID to produce a local ID. GlobalSelectorMapType GlobalSelectorMap; + /// \brief The generation number of the last time we loaded data from the + /// global method pool for this selector. + llvm::DenseMap<Selector, unsigned> SelectorGeneration; + /// \brief Mapping from identifiers that represent macros whose definitions /// have not yet been deserialized to the global offset where the macro /// record resides. llvm::DenseMap<IdentifierInfo *, uint64_t> UnreadMacroRecordOffsets; - typedef ContinuousRangeMap<unsigned, Module *, 4> + typedef ContinuousRangeMap<unsigned, ModuleFile *, 4> GlobalPreprocessedEntityMapType; - + /// \brief Mapping from global preprocessing entity IDs to the module in /// which the preprocessed entity resides along with the offset that should be /// added to the global preprocessing entitiy ID to produce a local ID. GlobalPreprocessedEntityMapType GlobalPreprocessedEntityMap; - + /// \name CodeGen-relevant special data /// \brief Fields containing data that is relevant to CodeGen. //@{ @@ -423,7 +484,7 @@ private: /// \brief A list of all the delegating constructors we've seen, to diagnose /// cycles. SmallVector<uint64_t, 4> DelegatingCtorDecls; - + /// \brief Method selectors used in a @selector expression. Used for /// implementation of -Wselector. SmallVector<uint64_t, 64> ReferencedSelectorsData; @@ -480,6 +541,9 @@ private: /// \brief A list of the namespaces we've seen. SmallVector<uint64_t, 4> KnownNamespaces; + /// \brief A list of modules that were imported by precompiled headers or + /// any other non-module AST file. + SmallVector<serialization::SubmoduleID, 2> ImportedModules; //@} /// \brief The original file name that was used to build the primary AST file, @@ -493,7 +557,7 @@ private: /// \brief The file ID for the original file that was used to build the /// primary AST file. FileID OriginalFileID; - + /// \brief The directory that the PCH was originally created in. Used to /// allow resolving headers even after headers+PCH was moved to a new path. std::string OriginalDir; @@ -511,19 +575,23 @@ private: /// \brief Whether to disable the normal validation performed on precompiled /// headers when they are loaded. bool DisableValidation; - + /// \brief Whether to disable the use of stat caches in AST files. bool DisableStatCache; + /// \brief Whether to accept an AST file with compiler errors. + bool AllowASTWithCompilerErrors; + + /// \brief The current "generation" of the module file import stack, which + /// indicates how many separate module file load operations have occurred. + unsigned CurrentGeneration; + /// \brief Mapping from switch-case IDs in the chain to switch-case statements /// /// Statements usually don't have IDs, but switch cases need them, so that the /// switch statement can refer to them. std::map<unsigned, SwitchCase *> SwitchCaseStmts; - /// \brief Mapping from opaque value IDs to OpaqueValueExprs. - std::map<unsigned, OpaqueValueExpr*> OpaqueValueExprs; - /// \brief The number of stat() calls that hit/missed the stat /// cache. unsigned NumStatHits, NumStatMisses; @@ -567,13 +635,19 @@ private: /// Number of visible decl contexts read/total. unsigned NumVisibleDeclContextsRead, TotalVisibleDeclContexts; - + /// Total size of modules, in bits, currently loaded uint64_t TotalModulesSizeInBits; /// \brief Number of Decl/types that are currently deserializing. unsigned NumCurrentElementsDeserializing; + /// \brief Set true while we are in the process of passing deserialized + /// "interesting" decls to consumer inside FinishedDeserializing(). + /// This is used as a guard to avoid recursively repeating the process of + /// passing decls to consumer. + bool PassingDeclsToConsumer; + /// Number of CXX base specifiers currently loaded unsigned NumCXXBaseSpecifiersLoaded; @@ -591,6 +665,10 @@ private: /// loaded once the recursive loading has completed. std::deque<PendingIdentifierInfo> PendingIdentifierInfos; + /// \brief The generation number of each identifier, which keeps track of + /// the last time we loaded information about this identifier. + llvm::DenseMap<IdentifierInfo *, unsigned> IdentifierGeneration; + /// \brief Contains declarations and definitions that will be /// "interesting" to the ASTConsumer, when we get that AST consumer. /// @@ -599,10 +677,58 @@ private: /// Objective-C protocols. std::deque<Decl *> InterestingDecls; - /// \brief We delay loading of the previous declaration chain to avoid - /// deeply nested calls when there are many redeclarations. - std::deque<std::pair<Decl *, serialization::DeclID> > PendingPreviousDecls; - + /// \brief The set of redeclarable declaraations that have been deserialized + /// since the last time the declaration chains were linked. + llvm::SmallPtrSet<Decl *, 16> RedeclsDeserialized; + + /// \brief The list of redeclaration chains that still need to be + /// reconstructed. + /// + /// Each element is the global declaration ID of the first declaration in + /// the chain. Elements in this vector should be unique; use + /// PendingDeclChainsKnown to ensure uniqueness. + llvm::SmallVector<serialization::DeclID, 16> PendingDeclChains; + + /// \brief Keeps track of the elements added to PendingDeclChains. + llvm::SmallSet<serialization::DeclID, 16> PendingDeclChainsKnown; + + /// \brief The set of Objective-C categories that have been deserialized + /// since the last time the declaration chains were linked. + llvm::SmallPtrSet<ObjCCategoryDecl *, 16> CategoriesDeserialized; + + /// \brief The set of Objective-C class definitions that have already been + /// loaded, for which we will need to check for categories whenever a new + /// module is loaded. + llvm::SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded; + + typedef llvm::DenseMap<Decl *, llvm::SmallVector<serialization::DeclID, 2> > + MergedDeclsMap; + + /// \brief A mapping from canonical declarations to the set of additional + /// (global, previously-canonical) declaration IDs that have been merged with + /// that canonical declaration. + MergedDeclsMap MergedDecls; + + typedef llvm::DenseMap<serialization::GlobalDeclID, + llvm::SmallVector<serialization::DeclID, 2> > + StoredMergedDeclsMap; + + /// \brief A mapping from canonical declaration IDs to the set of additional + /// declaration IDs that have been merged with that canonical declaration. + /// + /// This is the deserialized representation of the entries in MergedDecls. + /// When we query entries in MergedDecls, they will be augmented with entries + /// from StoredMergedDecls. + StoredMergedDeclsMap StoredMergedDecls; + + /// \brief Combine the stored merged declarations for the given canonical + /// declaration into the set of merged declarations. + /// + /// \returns An iterator into MergedDecls that corresponds to the position of + /// the given canonical declaration. + MergedDeclsMap::iterator + combineStoredMergedDecls(Decl *Canon, serialization::GlobalDeclID CanonID); + /// \brief Ready to load the previous declaration of the given Decl. void loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID); @@ -614,7 +740,7 @@ private: Read_Decl, Read_Type, Read_Stmt }; - /// \brief What kind of records we are reading. + /// \brief What kind of records we are reading. ReadingKind ReadingKind; /// \brief RAII object to change the reading kind. @@ -649,7 +775,7 @@ private: std::string SuggestedPredefines; /// \brief Reads a statement from the specified cursor. - Stmt *ReadStmtFromStream(Module &F); + Stmt *ReadStmtFromStream(ModuleFile &F); /// \brief Get a FileEntry out of stored-in-PCH filename, making sure we take /// into account all the necessary relocations. @@ -658,20 +784,21 @@ private: void MaybeAddSystemRootToFilename(std::string &Filename); ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type, - Module *ImportedBy); - ASTReadResult ReadASTBlock(Module &F); + ModuleFile *ImportedBy); + ASTReadResult ReadASTBlock(ModuleFile &F); bool CheckPredefinesBuffers(); - bool ParseLineTable(Module &F, SmallVectorImpl<uint64_t> &Record); - ASTReadResult ReadSourceManagerBlock(Module &F); + bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &Record); + ASTReadResult ReadSourceManagerBlock(ModuleFile &F); ASTReadResult ReadSLocEntryRecord(int ID); llvm::BitstreamCursor &SLocCursorForID(int ID); - SourceLocation getImportLocation(Module *F); + SourceLocation getImportLocation(ModuleFile *F); + ASTReadResult ReadSubmoduleBlock(ModuleFile &F); bool ParseLanguageOptions(const SmallVectorImpl<uint64_t> &Record); - + struct RecordLocation { - RecordLocation(Module *M, uint64_t O) + RecordLocation(ModuleFile *M, uint64_t O) : F(M), Offset(O) {} - Module *F; + ModuleFile *F; uint64_t Offset; }; @@ -679,19 +806,22 @@ private: RecordLocation TypeCursorForIndex(unsigned Index); void LoadedDecl(unsigned Index, Decl *D); Decl *ReadDeclRecord(serialization::DeclID ID); - RecordLocation DeclCursorForID(serialization::DeclID ID); + RecordLocation DeclCursorForID(serialization::DeclID ID, + unsigned &RawLocation); void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D); - void loadObjCChainedCategories(serialization::GlobalDeclID ID, - ObjCInterfaceDecl *D); - + void loadPendingDeclChain(serialization::GlobalDeclID ID); + void loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D, + unsigned PreviousGeneration = 0); + RecordLocation getLocalBitOffset(uint64_t GlobalOffset); - uint64_t getGlobalBitOffset(Module &M, uint32_t LocalOffset); + uint64_t getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset); /// \brief Returns the first preprocessed entity ID that ends after \arg BLoc. serialization::PreprocessedEntityID findBeginPreprocessedEntity(SourceLocation BLoc) const; - /// \brief Returns the first preprocessed entity ID that begins after \arg ELoc. + /// \brief Returns the first preprocessed entity ID that begins after \arg + /// ELoc. serialization::PreprocessedEntityID findEndPreprocessedEntity(SourceLocation ELoc) const; @@ -703,7 +833,15 @@ private: findNextPreprocessedEntity( GlobalSLocOffsetMapType::const_iterator SLocMapI) const; + /// \brief Returns (ModuleFile, Local index) pair for \arg GlobalIndex of a + /// preprocessed entity. + std::pair<ModuleFile *, unsigned> + getModulePreprocessedEntity(unsigned GlobalIndex); + void PassInterestingDeclsToConsumer(); + void PassInterestingDeclToConsumer(Decl *D); + + void finishPendingActions(); /// \brief Produce an error diagnostic and return true. /// @@ -740,20 +878,38 @@ public: /// help when an AST file is being used in cases where the /// underlying files in the file system may have changed, but /// parsing should still continue. + /// + /// \param AllowASTWithCompilerErrors If true, the AST reader will accept an + /// AST file the was created out of an AST with compiler errors, + /// otherwise it will reject it. ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "", - bool DisableValidation = false, bool DisableStatCache = false); + bool DisableValidation = false, bool DisableStatCache = false, + bool AllowASTWithCompilerErrors = false); ~ASTReader(); SourceManager &getSourceManager() const { return SourceMgr; } - + /// \brief Load the AST file designated by the given file name. ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type); /// \brief Checks that no file that is stored in PCH is out-of-sync with /// the actual file in the file system. - ASTReadResult validateFileEntries(Module &M); + ASTReadResult validateFileEntries(ModuleFile &M); + /// \brief Make the entities in the given module and any of its (non-explicit) + /// submodules visible to name lookup. + /// + /// \param Mod The module whose names should be made visible. + /// + /// \param Visibility The level of visibility to give the names in the module. + /// Visibility can only be increased over time. + void makeModuleVisible(Module *Mod, + Module::NameVisibilityKind NameVisibility); + + /// \brief Make the names within this set of hidden names visible. + void makeNamesVisible(const HiddenNames &Names); + /// \brief Set the AST callbacks listener. void setListener(ASTReaderListener *listener) { Listener.reset(listener); @@ -770,12 +926,19 @@ public: ModuleMgr.addInMemoryBuffer(FileName, Buffer); } + /// \brief Finalizes the AST reader's state before writing an AST file to + /// disk. + /// + /// This operation may undo temporary state in the AST that should not be + /// emitted. + void finalizeForWriting(); + /// \brief Retrieve the module manager. ModuleManager &getModuleManager() { return ModuleMgr; } /// \brief Retrieve the preprocessor. Preprocessor &getPreprocessor() const { return PP; } - + /// \brief Retrieve the name of the original source file name const std::string &getOriginalSourceFile() { return OriginalFileName; } @@ -801,6 +964,11 @@ public: virtual std::pair<unsigned, unsigned> findPreprocessedEntitiesInRange(SourceRange Range); + /// \brief Optionally returns true or false if the preallocated preprocessed + /// entity with index \arg Index came from file \arg FID. + virtual llvm::Optional<bool> isPreprocessedEntityInFileID(unsigned Index, + FileID FID); + /// \brief Read the header file information for the given file entry. virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE); @@ -826,6 +994,11 @@ public: return static_cast<unsigned>(DeclsLoaded.size()); } + /// \brief Returns the number of submodules known. + unsigned getTotalNumSubmodules() const { + return static_cast<unsigned>(SubmodulesLoaded.size()); + } + /// \brief Returns the number of selectors found in the chain. unsigned getTotalNumSelectors() const { return static_cast<unsigned>(SelectorsLoaded.size()); @@ -839,28 +1012,28 @@ public: E = ModuleMgr.end(); I != E; ++I) { Result += (*I)->NumPreprocessedEntities; } - + return Result; } - + /// \brief Returns the number of C++ base specifiers found in the chain. unsigned getTotalNumCXXBaseSpecifiers() const { return NumCXXBaseSpecifiersLoaded; } - + /// \brief Reads a TemplateArgumentLocInfo appropriate for the /// given TemplateArgument kind. TemplateArgumentLocInfo - GetTemplateArgumentLocInfo(Module &F, TemplateArgument::ArgKind Kind, + GetTemplateArgumentLocInfo(ModuleFile &F, TemplateArgument::ArgKind Kind, const RecordData &Record, unsigned &Idx); /// \brief Reads a TemplateArgumentLoc. TemplateArgumentLoc - ReadTemplateArgumentLoc(Module &F, + ReadTemplateArgumentLoc(ModuleFile &F, const RecordData &Record, unsigned &Idx); /// \brief Reads a declarator info from the given record. - TypeSourceInfo *GetTypeSourceInfo(Module &F, + TypeSourceInfo *GetTypeSourceInfo(ModuleFile &F, const RecordData &Record, unsigned &Idx); /// \brief Resolve a type ID into a type, potentially building a new @@ -868,35 +1041,42 @@ public: QualType GetType(serialization::TypeID ID); /// \brief Resolve a local type ID within a given AST file into a type. - QualType getLocalType(Module &F, unsigned LocalID); - + QualType getLocalType(ModuleFile &F, unsigned LocalID); + /// \brief Map a local type ID within a given AST file into a global type ID. - serialization::TypeID getGlobalTypeID(Module &F, unsigned LocalID) const; - - /// \brief Read a type from the current position in the given record, which + serialization::TypeID getGlobalTypeID(ModuleFile &F, unsigned LocalID) const; + + /// \brief Read a type from the current position in the given record, which /// was read from the given AST file. - QualType readType(Module &F, const RecordData &Record, unsigned &Idx) { + QualType readType(ModuleFile &F, const RecordData &Record, unsigned &Idx) { if (Idx >= Record.size()) return QualType(); - + return getLocalType(F, Record[Idx++]); } - - /// \brief Map from a local declaration ID within a given module to a + + /// \brief Map from a local declaration ID within a given module to a /// global declaration ID. - serialization::DeclID getGlobalDeclID(Module &F, unsigned LocalID) const; + serialization::DeclID getGlobalDeclID(ModuleFile &F, unsigned LocalID) const; /// \brief Returns true if global DeclID \arg ID originated from module /// \arg M. - bool isDeclIDFromModule(serialization::GlobalDeclID ID, Module &M) const; + bool isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const; + + /// \brief Retrieve the module file that owns the given declaration, or NULL + /// if the declaration is not from a module file. + ModuleFile *getOwningModuleFile(Decl *D); + /// \brief Returns the source location for the decl \arg ID. + SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID); + /// \brief Resolve a declaration ID into a declaration, potentially /// building a new declaration. Decl *GetDecl(serialization::DeclID ID); virtual Decl *GetExternalDecl(uint32_t ID); /// \brief Reads a declaration with the given local ID in the given module. - Decl *GetLocalDecl(Module &F, uint32_t LocalID) { + Decl *GetLocalDecl(ModuleFile &F, uint32_t LocalID) { return GetDecl(getGlobalDeclID(F, LocalID)); } @@ -904,40 +1084,49 @@ public: /// /// \returns The requested declaration, casted to the given return type. template<typename T> - T *GetLocalDeclAs(Module &F, uint32_t LocalID) { + T *GetLocalDeclAs(ModuleFile &F, uint32_t LocalID) { return cast_or_null<T>(GetLocalDecl(F, LocalID)); } - /// \brief Reads a declaration ID from the given position in a record in the + /// \brief Map a global declaration ID into the declaration ID used to + /// refer to this declaration within the given module fule. + /// + /// \returns the global ID of the given declaration as known in the given + /// module file. + serialization::DeclID + mapGlobalIDToModuleFileGlobalID(ModuleFile &M, + serialization::DeclID GlobalID); + + /// \brief Reads a declaration ID from the given position in a record in the /// given module. /// /// \returns The declaration ID read from the record, adjusted to a global ID. - serialization::DeclID ReadDeclID(Module &F, const RecordData &Record, + serialization::DeclID ReadDeclID(ModuleFile &F, const RecordData &Record, unsigned &Idx); - + /// \brief Reads a declaration from the given position in a record in the /// given module. - Decl *ReadDecl(Module &F, const RecordData &R, unsigned &I) { + Decl *ReadDecl(ModuleFile &F, const RecordData &R, unsigned &I) { return GetDecl(ReadDeclID(F, R, I)); } - + /// \brief Reads a declaration from the given position in a record in the /// given module. /// /// \returns The declaration read from this location, casted to the given /// result type. template<typename T> - T *ReadDeclAs(Module &F, const RecordData &R, unsigned &I) { + T *ReadDeclAs(ModuleFile &F, const RecordData &R, unsigned &I) { return cast_or_null<T>(GetDecl(ReadDeclID(F, R, I))); } /// \brief Read a CXXBaseSpecifiers ID form the given record and /// return its global bit offset. - uint64_t readCXXBaseSpecifiers(Module &M, const RecordData &Record, + uint64_t readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record, unsigned &Idx); - + virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset); - + /// \brief Resolve the offset of a statement into a statement. /// /// This operation will read a new statement from the external @@ -974,6 +1163,12 @@ public: bool (*isKindWeWant)(Decl::Kind), SmallVectorImpl<Decl*> &Decls); + /// \brief Get the decls that are contained in a file in the Offset/Length + /// range. \arg Length can be 0 to indicate a point at \arg Offset instead of + /// a range. + virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length, + SmallVectorImpl<Decl *> &Decls); + /// \brief Notify ASTReader that we started deserialization of /// a decl or type so until FinishedDeserializing is called there may be /// decls that are initializing. Must be paired with FinishedDeserializing. @@ -995,7 +1190,7 @@ public: /// \brief Dump information about the AST reader to standard error. void dump(); - + /// Return the amount of memory used by memory buffers, breaking down /// by heap-backed versus mmap'ed memory. virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const; @@ -1025,11 +1220,7 @@ public: /// \brief Load the contents of the global method pool for a given /// selector. - /// - /// \returns a pair of Objective-C methods lists containing the - /// instance and factory methods, respectively, with this selector. - virtual std::pair<ObjCMethodList, ObjCMethodList> - ReadMethodPool(Selector Sel); + virtual void ReadMethodPool(Selector Sel); /// \brief Load the set of namespaces that are known to the external source, /// which will be used during typo correction. @@ -1051,7 +1242,7 @@ public: virtual void ReadLocallyScopedExternalDecls( SmallVectorImpl<NamedDecl *> &Decls); - + virtual void ReadReferencedSelectors( SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels); @@ -1061,7 +1252,7 @@ public: virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables); virtual void ReadPendingInstantiations( - SmallVectorImpl<std::pair<ValueDecl *, + SmallVectorImpl<std::pair<ValueDecl *, SourceLocation> > &Pending); /// \brief Load a selector from disk, registering its ID if it exists. @@ -1080,7 +1271,7 @@ public: IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID); - IdentifierInfo *GetIdentifierInfo(Module &M, const RecordData &Record, + IdentifierInfo *GetIdentifierInfo(ModuleFile &M, const RecordData &Record, unsigned &Idx) { return DecodeIdentifierInfo(getGlobalIdentifierID(M, Record[Idx++])); } @@ -1089,101 +1280,110 @@ public: return DecodeIdentifierInfo(ID); } - IdentifierInfo *getLocalIdentifier(Module &M, unsigned LocalID); - - serialization::IdentifierID getGlobalIdentifierID(Module &M, + IdentifierInfo *getLocalIdentifier(ModuleFile &M, unsigned LocalID); + + serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M, unsigned LocalID); - + /// \brief Read the source location entry with index ID. virtual bool ReadSLocEntry(int ID); + /// \brief Retrieve the global submodule ID given a module and its local ID + /// number. + serialization::SubmoduleID + getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID); + + /// \brief Retrieve the submodule that corresponds to a global submodule ID. + /// + Module *getSubmodule(serialization::SubmoduleID GlobalID); + /// \brief Retrieve a selector from the given module with its local ID /// number. - Selector getLocalSelector(Module &M, unsigned LocalID); + Selector getLocalSelector(ModuleFile &M, unsigned LocalID); Selector DecodeSelector(serialization::SelectorID Idx); virtual Selector GetExternalSelector(serialization::SelectorID ID); uint32_t GetNumExternalSelectors(); - Selector ReadSelector(Module &M, const RecordData &Record, unsigned &Idx) { + Selector ReadSelector(ModuleFile &M, const RecordData &Record, unsigned &Idx) { return getLocalSelector(M, Record[Idx++]); } - + /// \brief Retrieve the global selector ID that corresponds to this /// the local selector ID in a given module. - serialization::SelectorID getGlobalSelectorID(Module &F, + serialization::SelectorID getGlobalSelectorID(ModuleFile &F, unsigned LocalID) const; /// \brief Read a declaration name. - DeclarationName ReadDeclarationName(Module &F, + DeclarationName ReadDeclarationName(ModuleFile &F, const RecordData &Record, unsigned &Idx); - void ReadDeclarationNameLoc(Module &F, + void ReadDeclarationNameLoc(ModuleFile &F, DeclarationNameLoc &DNLoc, DeclarationName Name, const RecordData &Record, unsigned &Idx); - void ReadDeclarationNameInfo(Module &F, DeclarationNameInfo &NameInfo, + void ReadDeclarationNameInfo(ModuleFile &F, DeclarationNameInfo &NameInfo, const RecordData &Record, unsigned &Idx); - void ReadQualifierInfo(Module &F, QualifierInfo &Info, + void ReadQualifierInfo(ModuleFile &F, QualifierInfo &Info, const RecordData &Record, unsigned &Idx); - NestedNameSpecifier *ReadNestedNameSpecifier(Module &F, + NestedNameSpecifier *ReadNestedNameSpecifier(ModuleFile &F, const RecordData &Record, unsigned &Idx); - NestedNameSpecifierLoc ReadNestedNameSpecifierLoc(Module &F, + NestedNameSpecifierLoc ReadNestedNameSpecifierLoc(ModuleFile &F, const RecordData &Record, unsigned &Idx); /// \brief Read a template name. - TemplateName ReadTemplateName(Module &F, const RecordData &Record, + TemplateName ReadTemplateName(ModuleFile &F, const RecordData &Record, unsigned &Idx); /// \brief Read a template argument. - TemplateArgument ReadTemplateArgument(Module &F, + TemplateArgument ReadTemplateArgument(ModuleFile &F, const RecordData &Record,unsigned &Idx); - + /// \brief Read a template parameter list. - TemplateParameterList *ReadTemplateParameterList(Module &F, + TemplateParameterList *ReadTemplateParameterList(ModuleFile &F, const RecordData &Record, unsigned &Idx); - + /// \brief Read a template argument array. void ReadTemplateArgumentList(SmallVector<TemplateArgument, 8> &TemplArgs, - Module &F, const RecordData &Record, + ModuleFile &F, const RecordData &Record, unsigned &Idx); /// \brief Read a UnresolvedSet structure. - void ReadUnresolvedSet(Module &F, UnresolvedSetImpl &Set, + void ReadUnresolvedSet(ModuleFile &F, UnresolvedSetImpl &Set, const RecordData &Record, unsigned &Idx); /// \brief Read a C++ base specifier. - CXXBaseSpecifier ReadCXXBaseSpecifier(Module &F, + CXXBaseSpecifier ReadCXXBaseSpecifier(ModuleFile &F, const RecordData &Record,unsigned &Idx); /// \brief Read a CXXCtorInitializer array. std::pair<CXXCtorInitializer **, unsigned> - ReadCXXCtorInitializers(Module &F, const RecordData &Record, + ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record, unsigned &Idx); /// \brief Read a source location from raw form. - SourceLocation ReadSourceLocation(Module &Module, unsigned Raw) const { + SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, unsigned Raw) const { SourceLocation Loc = SourceLocation::getFromRawEncoding(Raw); - assert(Module.SLocRemap.find(Loc.getOffset()) != Module.SLocRemap.end() && + assert(ModuleFile.SLocRemap.find(Loc.getOffset()) != ModuleFile.SLocRemap.end() && "Cannot find offset to remap."); - int Remap = Module.SLocRemap.find(Loc.getOffset())->second; + int Remap = ModuleFile.SLocRemap.find(Loc.getOffset())->second; return Loc.getLocWithOffset(Remap); } /// \brief Read a source location. - SourceLocation ReadSourceLocation(Module &Module, + SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, const RecordData &Record, unsigned& Idx) { - return ReadSourceLocation(Module, Record[Idx++]); + return ReadSourceLocation(ModuleFile, Record[Idx++]); } /// \brief Read a source range. - SourceRange ReadSourceRange(Module &F, + SourceRange ReadSourceRange(ModuleFile &F, const RecordData &Record, unsigned& Idx); /// \brief Read an integral value @@ -1201,18 +1401,18 @@ public: /// \brief Read a version tuple. VersionTuple ReadVersionTuple(const RecordData &Record, unsigned &Idx); - CXXTemporary *ReadCXXTemporary(Module &F, const RecordData &Record, + CXXTemporary *ReadCXXTemporary(ModuleFile &F, const RecordData &Record, unsigned &Idx); - + /// \brief Reads attributes from the current stream position. - void ReadAttributes(Module &F, AttrVec &Attrs, + void ReadAttributes(ModuleFile &F, AttrVec &Attrs, const RecordData &Record, unsigned &Idx); /// \brief Reads a statement. - Stmt *ReadStmt(Module &F); + Stmt *ReadStmt(ModuleFile &F); /// \brief Reads an expression. - Expr *ReadExpr(Module &F); + Expr *ReadExpr(ModuleFile &F); /// \brief Reads a sub-statement operand during statement reading. Stmt *ReadSubStmt() { @@ -1228,29 +1428,47 @@ public: Expr *ReadSubExpr(); /// \brief Reads the macro record located at the given offset. - void ReadMacroRecord(Module &F, uint64_t Offset); - + void ReadMacroRecord(ModuleFile &F, uint64_t Offset); + /// \brief Determine the global preprocessed entity ID that corresponds to /// the given local ID within the given module. - serialization::PreprocessedEntityID - getGlobalPreprocessedEntityID(Module &M, unsigned LocalID) const; - + serialization::PreprocessedEntityID + getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const; + /// \brief Note that the identifier is a macro whose record will be loaded /// from the given AST file at the given (file-local) offset. - void SetIdentifierIsMacro(IdentifierInfo *II, Module &F, - uint64_t Offset); - + /// + /// \param II The name of the macro. + /// + /// \param F The module file from which the macro definition was deserialized. + /// + /// \param Offset The offset into the module file at which the macro + /// definition is located. + /// + /// \param Visible Whether the macro should be made visible. + void setIdentifierIsMacro(IdentifierInfo *II, ModuleFile &F, + uint64_t Offset, bool Visible); + /// \brief Read the set of macros defined by this external macro source. virtual void ReadDefinedMacros(); /// \brief Read the macro definition for this identifier. virtual void LoadMacroDefinition(IdentifierInfo *II); + /// \brief Update an out-of-date identifier. + virtual void updateOutOfDateIdentifier(IdentifierInfo &II); + + /// \brief Note that this identifier is up-to-date. + void markIdentifierUpToDate(IdentifierInfo *II); + /// \brief Read the macro definition corresponding to this iterator /// into the unread macro record offsets table. void LoadMacroDefinition( llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos); - + + /// \brief Load all external visible decls in the given DeclContext. + void completeVisibleDeclsMap(DeclContext *DC); + /// \brief Retrieve the AST context that this AST reader supplements. ASTContext &getContext() { return Context; } |