diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-08-25 20:47:51 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-08-25 20:47:51 +0000 |
commit | 98339b96a8089a6da715487e432c5abfca0ca0df (patch) | |
tree | b3562746710d09e2287a2fa7eb67fb28e7e3c4ba | |
parent | 7c2349be2d11143a2e59a167fd43362a3bf4585e (diff) |
Factor the Module and ModuleManager classes out into separate headers
and .cpp files, since ASTReader.cpp was getting way too large. No
functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138582 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 423 | ||||
-rw-r--r-- | include/clang/Serialization/Module.h | 322 | ||||
-rw-r--r-- | include/clang/Serialization/ModuleManager.h | 153 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 1084 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderInternals.h | 243 | ||||
-rw-r--r-- | lib/Serialization/CMakeLists.txt | 4 | ||||
-rw-r--r-- | lib/Serialization/Module.cpp | 117 | ||||
-rw-r--r-- | lib/Serialization/ModuleManager.cpp | 204 |
8 files changed, 1373 insertions, 1177 deletions
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 9eb4320d55..c8a72551be 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -16,6 +16,8 @@ #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ContinuousRangeMap.h" +#include "clang/Serialization/Module.h" +#include "clang/Serialization/ModuleManager.h" #include "clang/Sema/ExternalSemaSource.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/DeclObjC.h" @@ -32,7 +34,6 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Bitcode/BitstreamReader.h" @@ -73,7 +74,6 @@ class ASTWriter; class ASTReader; class ASTDeclReader; class ASTStmtReader; -class ASTIdentifierLookupTrait; class TypeLocReader; struct HeaderFileInfo; class VersionTuple; @@ -161,421 +161,14 @@ private: void Error(const char *Msg); }; -namespace serialization { - -/// \brief Specifies the kind of module that has been loaded. -enum ModuleKind { - MK_Module, ///< File is a module proper. - MK_PCH, ///< File is a PCH file treated as such. - MK_Preamble, ///< File is a PCH file treated as the preamble. - MK_MainFile ///< File is a PCH file treated as the actual main file. -}; - -/// \brief Information about the contents of a DeclContext. -struct DeclContextInfo { - DeclContextInfo() - : NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {} - - void *NameLookupTableData; // an ASTDeclContextNameLookupTable. - const KindDeclIDPair *LexicalDecls; - unsigned NumLexicalDecls; -}; - -/// \brief Information about a module that has been loaded by the ASTReader. -/// -/// Each instance of the Module class corresponds to a single AST file, which -/// may be a precompiled header, precompiled preamble, or an AST file of some -/// sort loaded as the main file, all of which are specific formulations of -/// the general notion of a "module". A module may depend on another module. -class Module { -public: - Module(ModuleKind Kind); - ~Module(); - - // === General information === - - /// \brief The type of this module. - ModuleKind Kind; - - /// \brief The file name of the module file. - std::string FileName; - - /// \brief Whether this module has been directly imported by the - /// user. - bool DirectlyImported; - - /// \brief The memory buffer that stores the data associated with - /// this AST file. - llvm::OwningPtr<llvm::MemoryBuffer> Buffer; - - /// \brief The size of this file, in bits. - uint64_t SizeInBits; - - /// \brief The global bit offset (or base) of this module - uint64_t GlobalBitOffset; - - /// \brief The bitstream reader from which we'll read the AST file. - llvm::BitstreamReader StreamFile; - - /// \brief The main bitstream cursor for the main block. - llvm::BitstreamCursor Stream; - - /// \brief The source location where this module was first imported. - SourceLocation ImportLoc; - - /// \brief The first source location in this module. - SourceLocation FirstLoc; - - // === Source Locations === - - /// \brief Cursor used to read source location entries. - llvm::BitstreamCursor SLocEntryCursor; - - /// \brief The number of source location entries in this AST file. - unsigned LocalNumSLocEntries; - - /// \brief The base ID in the source manager's view of this module. - int SLocEntryBaseID; - - /// \brief The base offset in the source manager's view of this module. - unsigned SLocEntryBaseOffset; - - /// \brief Offsets for all of the source location entries in the - /// AST file. - const uint32_t *SLocEntryOffsets; - - /// \brief The number of source location file entries in this AST file. - unsigned LocalNumSLocFileEntries; - - /// \brief Offsets for all of the source location file entries in the - /// AST file. - const uint32_t *SLocFileOffsets; - - /// \brief Remapping table for source locations in this module. - ContinuousRangeMap<uint32_t, int, 2> SLocRemap; - - // === Identifiers === - - /// \brief The number of identifiers in this AST file. - unsigned LocalNumIdentifiers; - - /// \brief Offsets into the identifier table data. - /// - /// This array is indexed by the identifier ID (-1), and provides - /// the offset into IdentifierTableData where the string data is - /// stored. - const uint32_t *IdentifierOffsets; - - /// \brief Base identifier ID for identifiers local to this module. - serialization::IdentID BaseIdentifierID; - - /// \brief Remapping table for identifier IDs in this module. - ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap; - - /// \brief Actual data for the on-disk hash table of identifiers. - /// - /// This pointer points into a memory buffer, where the on-disk hash - /// table for identifiers actually lives. - const char *IdentifierTableData; - - /// \brief A pointer to an on-disk hash table of opaque type - /// IdentifierHashTable. - void *IdentifierLookupTable; - - // === Macros === - - /// \brief The cursor to the start of the preprocessor block, which stores - /// all of the macro definitions. - llvm::BitstreamCursor MacroCursor; - - /// \brief The offset of the start of the set of defined macros. - uint64_t MacroStartOffset; - - // === Detailed PreprocessingRecord === - - /// \brief The cursor to the start of the (optional) detailed preprocessing - /// record block. - llvm::BitstreamCursor PreprocessorDetailCursor; - - /// \brief The offset of the start of the preprocessor detail cursor. - uint64_t PreprocessorDetailStartOffset; - - /// \brief Base preprocessed entity ID for preprocessed entities local to - /// this module. - serialization::PreprocessedEntityID BasePreprocessedEntityID; - - /// \brief Remapping table for preprocessed entity IDs in this module. - ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap; - - /// \brief The number of macro definitions in this file. - unsigned LocalNumMacroDefinitions; - - /// \brief Offsets of all of the macro definitions in the preprocessing - /// record in the AST file. - const uint32_t *MacroDefinitionOffsets; - - /// \brief Base macro definition ID for macro definitions local to this - /// module. - serialization::MacroID BaseMacroDefinitionID; - - /// \brief Remapping table for macro definition IDs in this module. - ContinuousRangeMap<uint32_t, int, 2> MacroDefinitionRemap; - - // === Header search information === - - /// \brief The number of local HeaderFileInfo structures. - unsigned LocalNumHeaderFileInfos; - - /// \brief Actual data for the on-disk hash table of header file - /// information. - /// - /// This pointer points into a memory buffer, where the on-disk hash - /// table for header file information actually lives. - const char *HeaderFileInfoTableData; - - /// \brief The on-disk hash table that contains information about each of - /// the header files. - void *HeaderFileInfoTable; - - /// \brief Actual data for the list of framework names used in the header - /// search information. - const char *HeaderFileFrameworkStrings; - - // === Selectors === - - /// \brief The number of selectors new to this file. - /// - /// This is the number of entries in SelectorOffsets. - unsigned LocalNumSelectors; - - /// \brief Offsets into the selector lookup table's data array - /// where each selector resides. - const uint32_t *SelectorOffsets; - - /// \brief Base selector ID for selectors local to this module. - serialization::SelectorID BaseSelectorID; - - /// \brief Remapping table for selector IDs in this module. - ContinuousRangeMap<uint32_t, int, 2> SelectorRemap; - - /// \brief A pointer to the character data that comprises the selector table - /// - /// The SelectorOffsets table refers into this memory. - const unsigned char *SelectorLookupTableData; - - /// \brief A pointer to an on-disk hash table of opaque type - /// ASTSelectorLookupTable. - /// - /// This hash table provides the IDs of all selectors, and the associated - /// instance and factory methods. - void *SelectorLookupTable; - - // === Declarations === - - /// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block. It - /// has read all the abbreviations at the start of the block and is ready to - /// jump around with these in context. - llvm::BitstreamCursor DeclsCursor; - - /// \brief The number of declarations in this AST file. - unsigned LocalNumDecls; - - /// \brief Offset of each declaration within the bitstream, indexed - /// by the declaration ID (-1). - const uint32_t *DeclOffsets; - - /// \brief Base declaration ID for declarations local to this module. - serialization::DeclID BaseDeclID; - - /// \brief Remapping table for declaration IDs in this module. - ContinuousRangeMap<uint32_t, int, 2> DeclRemap; - - /// \brief The number of C++ base specifier sets in this AST file. - unsigned LocalNumCXXBaseSpecifiers; - - /// \brief Offset of each C++ base specifier set within the bitstream, - /// indexed by the C++ base specifier set ID (-1). - const uint32_t *CXXBaseSpecifiersOffsets; - - typedef llvm::DenseMap<const DeclContext *, DeclContextInfo> - DeclContextInfosMap; - - /// \brief Information about the lexical and visible declarations - /// for each DeclContext. - DeclContextInfosMap DeclContextInfos; - - // === Types === - - /// \brief The number of types in this AST file. - unsigned LocalNumTypes; - - /// \brief Offset of each type within the bitstream, indexed by the - /// type ID, or the representation of a Type*. - const uint32_t *TypeOffsets; - - /// \brief Base type ID for types local to this module as represented in - /// the global type ID space. - serialization::TypeID BaseTypeIndex; - - /// \brief Remapping table for type IDs in this module. - ContinuousRangeMap<uint32_t, int, 2> TypeRemap; - - // === Miscellaneous === - - /// \brief Diagnostic IDs and their mappings that the user changed. - SmallVector<uint64_t, 8> PragmaDiagMappings; - - /// \brief The AST stat cache installed for this file, if any. - /// - /// The dynamic type of this stat cache is always ASTStatCache - void *StatCache; - - /// \brief The number of preallocated preprocessing entities in the - /// preprocessing record. - unsigned NumPreallocatedPreprocessingEntities; - - /// \brief List of modules which depend on this module - llvm::SetVector<Module *> ImportedBy; - - /// \brief List of modules which this module depends on - llvm::SetVector<Module *> Imports; - - /// \brief Determine whether this module was directly imported at - /// any point during translation. - bool isDirectlyImported() const { return DirectlyImported; } - - /// \brief Dump debugging output for this module. - void dump(); -}; - -/// \brief The manager for modules loaded by the ASTReader. -class ModuleManager { - /// \brief The chain of AST files. The first entry is the one named by the - /// user, the last one is the one that doesn't depend on anything further. - SmallVector<Module*, 2> Chain; - - /// \brief All loaded modules, indexed by name. - llvm::DenseMap<const FileEntry *, Module *> Modules; - - /// \brief FileManager that handles translating between filenames and - /// FileEntry *. - FileManager FileMgr; - - /// \brief A lookup of in-memory (virtual file) buffers - llvm::DenseMap<const FileEntry *, llvm::MemoryBuffer *> InMemoryBuffers; - -public: - typedef SmallVector<Module*, 2>::iterator ModuleIterator; - typedef SmallVector<Module*, 2>::const_iterator ModuleConstIterator; - typedef SmallVector<Module*, 2>::reverse_iterator ModuleReverseIterator; - typedef std::pair<uint32_t, StringRef> ModuleOffset; - - ModuleManager(const FileSystemOptions &FSO); - ~ModuleManager(); - - /// \brief Forward iterator to traverse all loaded modules. This is reverse - /// source-order. - ModuleIterator begin() { return Chain.begin(); } - /// \brief Forward iterator end-point to traverse all loaded modules - ModuleIterator end() { return Chain.end(); } - - /// \brief Const forward iterator to traverse all loaded modules. This is - /// in reverse source-order. - ModuleConstIterator begin() const { return Chain.begin(); } - /// \brief Const forward iterator end-point to traverse all loaded modules - ModuleConstIterator end() const { return Chain.end(); } - - /// \brief Reverse iterator to traverse all loaded modules. This is in - /// source order. - ModuleReverseIterator rbegin() { return Chain.rbegin(); } - /// \brief Reverse iterator end-point to traverse all loaded modules. - ModuleReverseIterator rend() { return Chain.rend(); } - - /// \brief Returns the primary module associated with the manager, that is, - /// the first module loaded - Module &getPrimaryModule() { return *Chain[0]; } - - /// \brief Returns the primary module associated with the manager, that is, - /// the first module loaded. - Module &getPrimaryModule() const { return *Chain[0]; } - - /// \brief Returns the module associated with the given index - Module &operator[](unsigned Index) const { return *Chain[Index]; } - - /// \brief Returns the module associated with the given name - Module *lookup(StringRef Name); - - /// \brief Returns the in-memory (virtual file) buffer with the given name - llvm::MemoryBuffer *lookupBuffer(StringRef Name); - - /// \brief Number of modules loaded - unsigned size() const { return Chain.size(); } - - /// \brief Attempts to create a new module and add it to the list of known - /// modules. - /// - /// \param FileName The file name of the module to be loaded. - /// - /// \param Type The kind of module being loaded. - /// - /// \param ImportedBy The module that is importing this module, or NULL if - /// this module is imported directly by the user. - /// - /// \param ErrorStr Will be set to a non-empty string if any errors occurred - /// while trying to load the module. - /// - /// \return A pointer to the module that corresponds to this file name, - /// and a boolean indicating whether the module was newly added. - std::pair<Module *, bool> - addModule(StringRef FileName, ModuleKind Type, Module *ImportedBy, - std::string &ErrorStr); - - /// \brief Add an in-memory buffer the list of known buffers - void addInMemoryBuffer(StringRef FileName, llvm::MemoryBuffer *Buffer); - - /// \brief Visit each of the modules. - /// - /// This routine visits each of the modules, starting with the - /// "root" modules that no other loaded modules depend on, and - /// proceeding to the leaf modules, visiting each module only once - /// during the traversal. - /// - /// This traversal is intended to support various "lookup" - /// operations that can find data in any of the loaded modules. - /// - /// \param Visitor A visitor function that will be invoked with each - /// module and the given user data pointer. The return value must be - /// convertible to bool; when false, the visitation continues to - /// modules that the current module depends on. When true, the - /// visitation skips any modules that the current module depends on. - /// - /// \param UserData User data associated with the visitor object, which - /// will be passed along to the visitor. - void visit(bool (*Visitor)(Module &M, void *UserData), void *UserData); - - /// \brief Visit each of the modules with a depth-first traversal. - /// - /// This routine visits each of the modules known to the module - /// manager using a depth-first search, starting with the first - /// loaded module. The traversal invokes the callback both before - /// traversing the children (preorder traversal) and after - /// traversing the children (postorder traversal). - /// - /// \param Visitor A visitor function that will be invoked with each - /// module and given a \c Preorder flag that indicates whether we're - /// visiting the module before or after visiting its children. The - /// visitor may return true at any time to abort the depth-first - /// visitation. - /// - /// \param UserData User data ssociated with the visitor object, - /// which will be passed along to the user. - void visitDepthFirst(bool (*Visitor)(Module &M, bool Preorder, - void *UserData), - void *UserData); -}; +namespace serialization { class ReadMethodPoolVisitor; +namespace reader { + class ASTIdentifierLookupTrait; +} + } // end namespace serialization /// \brief Reads an AST files chain containing the contents of a translation @@ -606,7 +199,7 @@ public: friend class ASTDeclReader; friend class ASTStmtReader; friend class ASTIdentifierIterator; - friend class ASTIdentifierLookupTrait; + friend class serialization::reader::ASTIdentifierLookupTrait; friend class TypeLocReader; friend class ASTWriter; friend class ASTUnit; // ASTUnit needs to remap source locations. diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h new file mode 100644 index 0000000000..a6a7da4fbd --- /dev/null +++ b/include/clang/Serialization/Module.h @@ -0,0 +1,322 @@ +//===--- Module.h - Module description --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the Module class, which describes a module that has +// been loaded from an AST file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_MODULE_H +#define LLVM_CLANG_SERIALIZATION_MODULE_H + +#include "clang/Serialization/ASTBitCodes.h" +#include "clang/Serialization/ContinuousRangeMap.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/Bitcode/BitstreamReader.h" +#include <string> + +namespace clang { + +class DeclContext; + +namespace serialization { + +/// \brief Specifies the kind of module that has been loaded. +enum ModuleKind { + MK_Module, ///< File is a module proper. + MK_PCH, ///< File is a PCH file treated as such. + MK_Preamble, ///< File is a PCH file treated as the preamble. + MK_MainFile ///< File is a PCH file treated as the actual main file. +}; + +/// \brief Information about the contents of a DeclContext. +struct DeclContextInfo { + DeclContextInfo() + : NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {} + + void *NameLookupTableData; // an ASTDeclContextNameLookupTable. + const KindDeclIDPair *LexicalDecls; + unsigned NumLexicalDecls; +}; + +/// \brief Information about a module that has been loaded by the ASTReader. +/// +/// Each instance of the Module class corresponds to a single AST file, which +/// may be a precompiled header, precompiled preamble, a module, or an AST file +/// of some sort loaded as the main file, all of which are specific formulations of +/// the general notion of a "module". A module may depend on any number of +/// other modules. +class Module { +public: + Module(ModuleKind Kind); + ~Module(); + + // === General information === + + /// \brief The type of this module. + ModuleKind Kind; + + /// \brief The file name of the module file. + std::string FileName; + + /// \brief Whether this module has been directly imported by the + /// user. + bool DirectlyImported; + + /// \brief The memory buffer that stores the data associated with + /// this AST file. + llvm::OwningPtr<llvm::MemoryBuffer> Buffer; + + /// \brief The size of this file, in bits. + uint64_t SizeInBits; + + /// \brief The global bit offset (or base) of this module + uint64_t GlobalBitOffset; + + /// \brief The bitstream reader from which we'll read the AST file. + llvm::BitstreamReader StreamFile; + + /// \brief The main bitstream cursor for the main block. + llvm::BitstreamCursor Stream; + + /// \brief The source location where this module was first imported. + SourceLocation ImportLoc; + + /// \brief The first source location in this module. + SourceLocation FirstLoc; + + // === Source Locations === + + /// \brief Cursor used to read source location entries. + llvm::BitstreamCursor SLocEntryCursor; + + /// \brief The number of source location entries in this AST file. + unsigned LocalNumSLocEntries; + + /// \brief The base ID in the source manager's view of this module. + int SLocEntryBaseID; + + /// \brief The base offset in the source manager's view of this module. + unsigned SLocEntryBaseOffset; + + /// \brief Offsets for all of the source location entries in the + /// AST file. + const uint32_t *SLocEntryOffsets; + + /// \brief The number of source location file entries in this AST file. + unsigned LocalNumSLocFileEntries; + + /// \brief Offsets for all of the source location file entries in the + /// AST file. + const uint32_t *SLocFileOffsets; + + /// \brief Remapping table for source locations in this module. + ContinuousRangeMap<uint32_t, int, 2> SLocRemap; + + // === Identifiers === + + /// \brief The number of identifiers in this AST file. + unsigned LocalNumIdentifiers; + + /// \brief Offsets into the identifier table data. + /// + /// This array is indexed by the identifier ID (-1), and provides + /// the offset into IdentifierTableData where the string data is + /// stored. + const uint32_t *IdentifierOffsets; + + /// \brief Base identifier ID for identifiers local to this module. + serialization::IdentID BaseIdentifierID; + + /// \brief Remapping table for identifier IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap; + + /// \brief Actual data for the on-disk hash table of identifiers. + /// + /// This pointer points into a memory buffer, where the on-disk hash + /// table for identifiers actually lives. + const char *IdentifierTableData; + + /// \brief A pointer to an on-disk hash table of opaque type + /// IdentifierHashTable. + void *IdentifierLookupTable; + + // === Macros === + + /// \brief The cursor to the start of the preprocessor block, which stores + /// all of the macro definitions. + llvm::BitstreamCursor MacroCursor; + + /// \brief The offset of the start of the set of defined macros. + uint64_t MacroStartOffset; + + // === Detailed PreprocessingRecord === + + /// \brief The cursor to the start of the (optional) detailed preprocessing + /// record block. + llvm::BitstreamCursor PreprocessorDetailCursor; + + /// \brief The offset of the start of the preprocessor detail cursor. + uint64_t PreprocessorDetailStartOffset; + + /// \brief Base preprocessed entity ID for preprocessed entities local to + /// this module. + serialization::PreprocessedEntityID BasePreprocessedEntityID; + + /// \brief Remapping table for preprocessed entity IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap; + + /// \brief The number of macro definitions in this file. + unsigned LocalNumMacroDefinitions; + + /// \brief Offsets of all of the macro definitions in the preprocessing + /// record in the AST file. + const uint32_t *MacroDefinitionOffsets; + + /// \brief Base macro definition ID for macro definitions local to this + /// module. + serialization::MacroID BaseMacroDefinitionID; + + /// \brief Remapping table for macro definition IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> MacroDefinitionRemap; + + // === Header search information === + + /// \brief The number of local HeaderFileInfo structures. + unsigned LocalNumHeaderFileInfos; + + /// \brief Actual data for the on-disk hash table of header file + /// information. + /// + /// This pointer points into a memory buffer, where the on-disk hash + /// table for header file information actually lives. + const char *HeaderFileInfoTableData; + + /// \brief The on-disk hash table that contains information about each of + /// the header files. + void *HeaderFileInfoTable; + + /// \brief Actual data for the list of framework names used in the header + /// search information. + const char *HeaderFileFrameworkStrings; + + // === Selectors === + + /// \brief The number of selectors new to this file. + /// + /// This is the number of entries in SelectorOffsets. + unsigned LocalNumSelectors; + + /// \brief Offsets into the selector lookup table's data array + /// where each selector resides. + const uint32_t *SelectorOffsets; + + /// \brief Base selector ID for selectors local to this module. + serialization::SelectorID BaseSelectorID; + + /// \brief Remapping table for selector IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> SelectorRemap; + + /// \brief A pointer to the character data that comprises the selector table + /// + /// The SelectorOffsets table refers into this memory. + const unsigned char *SelectorLookupTableData; + + /// \brief A pointer to an on-disk hash table of opaque type + /// ASTSelectorLookupTable. + /// + /// This hash table provides the IDs of all selectors, and the associated + /// instance and factory methods. + void *SelectorLookupTable; + + // === Declarations === + + /// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block. It + /// has read all the abbreviations at the start of the block and is ready to + /// jump around with these in context. + llvm::BitstreamCursor DeclsCursor; + + /// \brief The number of declarations in this AST file. + unsigned LocalNumDecls; + + /// \brief Offset of each declaration within the bitstream, indexed + /// by the declaration ID (-1). + const uint32_t *DeclOffsets; + + /// \brief Base declaration ID for declarations local to this module. + serialization::DeclID BaseDeclID; + + /// \brief Remapping table for declaration IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> DeclRemap; + + /// \brief The number of C++ base specifier sets in this AST file. + unsigned LocalNumCXXBaseSpecifiers; + + /// \brief Offset of each C++ base specifier set within the bitstream, + /// indexed by the C++ base specifier set ID (-1). + const uint32_t *CXXBaseSpecifiersOffsets; + + typedef llvm::DenseMap<const DeclContext *, DeclContextInfo> + DeclContextInfosMap; + + /// \brief Information about the lexical and visible declarations + /// for each DeclContext. + DeclContextInfosMap DeclContextInfos; + + // === Types === + + /// \brief The number of types in this AST file. + unsigned LocalNumTypes; + + /// \brief Offset of each type within the bitstream, indexed by the + /// type ID, or the representation of a Type*. + const uint32_t *TypeOffsets; + + /// \brief Base type ID for types local to this module as represented in + /// the global type ID space. + serialization::TypeID BaseTypeIndex; + + /// \brief Remapping table for type IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> TypeRemap; + + // === Miscellaneous === + + /// \brief Diagnostic IDs and their mappings that the user changed. + SmallVector<uint64_t, 8> PragmaDiagMappings; + + /// \brief The AST stat cache installed for this file, if any. + /// + /// The dynamic type of this stat cache is always ASTStatCache + void *StatCache; + + /// \brief The number of preallocated preprocessing entities in the + /// preprocessing record. + unsigned NumPreallocatedPreprocessingEntities; + + /// \brief List of modules which depend on this module + llvm::SetVector<Module *> ImportedBy; + + /// \brief List of modules which this module depends on + llvm::SetVector<Module *> Imports; + + /// \brief Determine whether this module was directly imported at + /// any point during translation. + bool isDirectlyImported() const { return DirectlyImported; } + + /// \brief Dump debugging output for this module. + void dump(); +}; + +} // end namespace serialization + +} // end namespace clang + +#endif diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h new file mode 100644 index 0000000000..65a5d5e2ec --- /dev/null +++ b/include/clang/Serialization/ModuleManager.h @@ -0,0 +1,153 @@ +//===--- ModuleManager.cpp - Module Manager ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ModuleManager class, which manages a set of loaded +// modules for the ASTReader. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H +#define LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H + +#include "clang/Serialization/Module.h" +#include "clang/Basic/FileManager.h" +#include "llvm/ADT/DenseMap.h" + +namespace clang { + +namespace serialization { + +/// \brief Manages the set of modules loaded by an AST reader. +class ModuleManager { + /// \brief The chain of AST files. The first entry is the one named by the + /// user, the last one is the one that doesn't depend on anything further. + llvm::SmallVector<Module*, 2> Chain; + + /// \brief All loaded modules, indexed by name. + llvm::DenseMap<const FileEntry *, Module *> Modules; + + /// \brief FileManager that handles translating between filenames and + /// FileEntry *. + FileManager FileMgr; + + /// \brief A lookup of in-memory (virtual file) buffers + llvm::DenseMap<const FileEntry *, llvm::MemoryBuffer *> InMemoryBuffers; + +public: + typedef SmallVector<Module*, 2>::iterator ModuleIterator; + typedef SmallVector<Module*, 2>::const_iterator ModuleConstIterator; + typedef SmallVector<Module*, 2>::reverse_iterator ModuleReverseIterator; + typedef std::pair<uint32_t, StringRef> ModuleOffset; + + ModuleManager(const FileSystemOptions &FSO); + ~ModuleManager(); + + /// \brief Forward iterator to traverse all loaded modules. This is reverse + /// source-order. + ModuleIterator begin() { return Chain.begin(); } + /// \brief Forward iterator end-point to traverse all loaded modules + ModuleIterator end() { return Chain.end(); } + + /// \brief Const forward iterator to traverse all loaded modules. This is + /// in reverse source-order. + ModuleConstIterator begin() const { return Chain.begin(); } + /// \brief Const forward iterator end-point to traverse all loaded modules + ModuleConstIterator end() const { return Chain.end(); } + + /// \brief Reverse iterator to traverse all loaded modules. This is in + /// source order. + ModuleReverseIterator rbegin() { return Chain.rbegin(); } + /// \brief Reverse iterator end-point to traverse all loaded modules. + ModuleReverseIterator rend() { return Chain.rend(); } + + /// \brief Returns the primary module associated with the manager, that is, + /// the first module loaded + Module &getPrimaryModule() { return *Chain[0]; } + + /// \brief Returns the primary module associated with the manager, that is, + /// the first module loaded. + Module &getPrimaryModule() const { return *Chain[0]; } + + /// \brief Returns the module associated with the given index + Module &operator[](unsigned Index) const { return *Chain[Index]; } + + /// \brief Returns the module associated with the given name + Module *lookup(StringRef Name); + + /// \brief Returns the in-memory (virtual file) buffer with the given name + llvm::MemoryBuffer *lookupBuffer(StringRef Name); + + /// \brief Number of modules loaded + unsigned size() const { return Chain.size(); } + /// \brief Attempts to create a new module and add it to the list of known + /// modules. + /// + /// \param FileName The file name of the module to be loaded. + /// + /// \param Type The kind of module being loaded. + /// + /// \param ImportedBy The module that is importing this module, or NULL if + /// this module is imported directly by the user. + /// + /// \param ErrorStr Will be set to a non-empty string if any errors occurred + /// while trying to load the module. + /// + /// \return A pointer to the module that corresponds to this file name, + /// and a boolean indicating whether the module was newly added. + std::pair<Module *, bool> + addModule(StringRef FileName, ModuleKind Type, Module *ImportedBy, + std::string &ErrorStr); + + /// \brief Add an in-memory buffer the list of known buffers + void addInMemoryBuffer(StringRef FileName, llvm::MemoryBuffer *Buffer); + + /// \brief Visit each of the modules. + /// + /// This routine visits each of the modules, starting with the + /// "root" modules that no other loaded modules depend on, and + /// proceeding to the leaf modules, visiting each module only once + /// during the traversal. + /// + /// This traversal is intended to support various "lookup" + /// operations that can find data in any of the loaded modules. + /// + /// \param Visitor A visitor function that will be invoked with each + /// module and the given user data pointer. The return value must be + /// convertible to bool; when false, the visitation continues to + /// modules that the current module depends on. When true, the + /// visitation skips any modules that the current module depends on. + /// + /// \param UserData User data associated with the visitor object, which + /// will be passed along to the visitor. + void visit(bool (*Visitor)(Module &M, void *UserData), void *UserData); + + /// \brief Visit each of the modules with a depth-first traversal. + /// + /// This routine visits each of the modules known to the module + /// manager using a depth-first search, starting with the first + /// loaded module. The traversal invokes the callback both before + /// traversing the children (preorder traversal) and after + /// traversing the children (postorder traversal). + /// + /// \param Visitor A visitor function that will be invoked with each + /// module and given a \c Preorder flag that indicates whether we're + /// visiting the module before or after visiting it |