[cfe-commits] r138582 - in /cfe/trunk: include/clang/Serialization/ASTReader.h include/clang/Serialization/Module.h include/clang/Serialization/ModuleManager.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderInternals.h lib/Serialization/CMakeLists.txt lib/Serialization/Module.cpp lib/Serialization/ModuleManager.cpp
Douglas Gregor
dgregor at apple.com
Thu Aug 25 13:47:51 PDT 2011
Author: dgregor
Date: Thu Aug 25 15:47:51 2011
New Revision: 138582
URL: http://llvm.org/viewvc/llvm-project?rev=138582&view=rev
Log:
Factor the Module and ModuleManager classes out into separate headers
and .cpp files, since ASTReader.cpp was getting way too large. No
functionality change.
Added:
cfe/trunk/include/clang/Serialization/Module.h
cfe/trunk/include/clang/Serialization/ModuleManager.h
cfe/trunk/lib/Serialization/ASTReaderInternals.h
cfe/trunk/lib/Serialization/Module.cpp
cfe/trunk/lib/Serialization/ModuleManager.cpp
Modified:
cfe/trunk/include/clang/Serialization/ASTReader.h
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/CMakeLists.txt
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=138582&r1=138581&r2=138582&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Thu Aug 25 15:47:51 2011
@@ -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 ASTReader;
class ASTDeclReader;
class ASTStmtReader;
-class ASTIdentifierLookupTrait;
class TypeLocReader;
struct HeaderFileInfo;
class VersionTuple;
@@ -161,421 +161,14 @@
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 @@
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.
Added: cfe/trunk/include/clang/Serialization/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Module.h?rev=138582&view=auto
==============================================================================
--- cfe/trunk/include/clang/Serialization/Module.h (added)
+++ cfe/trunk/include/clang/Serialization/Module.h Thu Aug 25 15:47:51 2011
@@ -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
Added: cfe/trunk/include/clang/Serialization/ModuleManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ModuleManager.h?rev=138582&view=auto
==============================================================================
--- cfe/trunk/include/clang/Serialization/ModuleManager.h (added)
+++ cfe/trunk/include/clang/Serialization/ModuleManager.h Thu Aug 25 15:47:51 2011
@@ -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 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);
+};
+
+} } // end namespace clang::serialization
+
+#endif
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=138582&r1=138581&r2=138582&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Aug 25 15:47:51 2011
@@ -13,7 +13,9 @@
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTDeserializationListener.h"
+#include "clang/Serialization/ModuleManager.h"
#include "ASTCommon.h"
+#include "ASTReaderInternals.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/Utils.h"
#include "clang/Sema/Sema.h"
@@ -52,6 +54,7 @@
using namespace clang;
using namespace clang::serialization;
+using namespace clang::serialization::reader;
//===----------------------------------------------------------------------===//
// PCH validator implementation
@@ -479,425 +482,321 @@
}
-namespace {
-class ASTSelectorLookupTrait {
- ASTReader &Reader;
- Module &F;
-
-public:
- struct data_type {
- SelectorID ID;
- llvm::SmallVector<ObjCMethodDecl *, 2> Instance;
- llvm::SmallVector<ObjCMethodDecl *, 2> Factory;
- };
-
- typedef Selector external_key_type;
- typedef external_key_type internal_key_type;
-
- ASTSelectorLookupTrait(ASTReader &Reader, Module &F)
- : Reader(Reader), F(F) { }
-
- static bool EqualKey(const internal_key_type& a,
- const internal_key_type& b) {
- return a == b;
- }
-
- static unsigned ComputeHash(Selector Sel) {
- return serialization::ComputeHash(Sel);
- }
-
- // This hopefully will just get inlined and removed by the optimizer.
- static const internal_key_type&
- GetInternalKey(const external_key_type& x) { return x; }
-
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char*& d) {
- using namespace clang::io;
- unsigned KeyLen = ReadUnalignedLE16(d);
- unsigned DataLen = ReadUnalignedLE16(d);
- return std::make_pair(KeyLen, DataLen);
- }
-
- internal_key_type ReadKey(const unsigned char* d, unsigned) {
- using namespace clang::io;
- SelectorTable &SelTable = Reader.getContext()->Selectors;
- unsigned N = ReadUnalignedLE16(d);
- IdentifierInfo *FirstII
- = Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
- if (N == 0)
- return SelTable.getNullarySelector(FirstII);
- else if (N == 1)
- return SelTable.getUnarySelector(FirstII);
-
- SmallVector<IdentifierInfo *, 16> Args;
- Args.push_back(FirstII);
- for (unsigned I = 1; I != N; ++I)
- Args.push_back(Reader.getLocalIdentifier(F, ReadUnalignedLE32(d)));
-
- return SelTable.getSelector(N, Args.data());
- }
-
- data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) {
- using namespace clang::io;
-
- data_type Result;
-
- Result.ID = Reader.getGlobalSelectorID(F, ReadUnalignedLE32(d));
- unsigned NumInstanceMethods = ReadUnalignedLE16(d);
- unsigned NumFactoryMethods = ReadUnalignedLE16(d);
-
- // Load instance methods
- ObjCMethodList *Prev = 0;
- for (unsigned I = 0; I != NumInstanceMethods; ++I) {
- if (ObjCMethodDecl *Method
- = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))
- Result.Instance.push_back(Method);
- }
-
- // Load factory methods
- Prev = 0;
- for (unsigned I = 0; I != NumFactoryMethods; ++I) {
- if (ObjCMethodDecl *Method
- = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))
- Result.Factory.push_back(Method);
- }
-
- return Result;
- }
-};
-
-} // end anonymous namespace
-
-/// \brief The on-disk hash table used for the global method pool.
-typedef OnDiskChainedHashTable<ASTSelectorLookupTrait>
- ASTSelectorLookupTable;
-namespace clang {
-class ASTIdentifierLookupTrait {
- ASTReader &Reader;
- Module &F;
-
- // If we know the IdentifierInfo in advance, it is here and we will
- // not build a new one. Used when deserializing information about an
- // identifier that was constructed before the AST file was read.
- IdentifierInfo *KnownII;
-
-public:
- typedef IdentifierInfo * data_type;
-
- typedef const std::pair<const char*, unsigned> external_key_type;
-
- typedef external_key_type internal_key_type;
-
- ASTIdentifierLookupTrait(ASTReader &Reader, Module &F,
- IdentifierInfo *II = 0)
- : Reader(Reader), F(F), KnownII(II) { }
-
- static bool EqualKey(const internal_key_type& a,
- const internal_key_type& b) {
- return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
- : false;
- }
-
- static unsigned ComputeHash(const internal_key_type& a) {
- return llvm::HashString(StringRef(a.first, a.second));
- }
-
- // This hopefully will just get inlined and removed by the optimizer.
- static const internal_key_type&
- GetInternalKey(const external_key_type& x) { return x; }
-
- // This hopefully will just get inlined and removed by the optimizer.
- static const external_key_type&
- GetExternalKey(const internal_key_type& x) { return x; }
+unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) {
+ return serialization::ComputeHash(Sel);
+}
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char*& d) {
- using namespace clang::io;
- unsigned DataLen = ReadUnalignedLE16(d);
- unsigned KeyLen = ReadUnalignedLE16(d);
- return std::make_pair(KeyLen, DataLen);
- }
- static std::pair<const char*, unsigned>
- ReadKey(const unsigned char* d, unsigned n) {
- assert(n >= 2 && d[n-1] == '\0');
- return std::make_pair((const char*) d, n-1);
+std::pair<unsigned, unsigned>
+ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
+ using namespace clang::io;
+ unsigned KeyLen = ReadUnalignedLE16(d);
+ unsigned DataLen = ReadUnalignedLE16(d);
+ return std::make_pair(KeyLen, DataLen);
+}
+
+ASTSelectorLookupTrait::internal_key_type
+ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) {
+ using namespace clang::io;
+ SelectorTable &SelTable = Reader.getContext()->Selectors;
+ unsigned N = ReadUnalignedLE16(d);
+ IdentifierInfo *FirstII
+ = Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
+ if (N == 0)
+ return SelTable.getNullarySelector(FirstII);
+ else if (N == 1)
+ return SelTable.getUnarySelector(FirstII);
+
+ SmallVector<IdentifierInfo *, 16> Args;
+ Args.push_back(FirstII);
+ for (unsigned I = 1; I != N; ++I)
+ Args.push_back(Reader.getLocalIdentifier(F, ReadUnalignedLE32(d)));
+
+ return SelTable.getSelector(N, Args.data());
+}
+
+ASTSelectorLookupTrait::data_type
+ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d,
+ unsigned DataLen) {
+ using namespace clang::io;
+
+ data_type Result;
+
+ Result.ID = Reader.getGlobalSelectorID(F, ReadUnalignedLE32(d));
+ unsigned NumInstanceMethods = ReadUnalignedLE16(d);
+ unsigned NumFactoryMethods = ReadUnalignedLE16(d);
+
+ // Load instance methods
+ ObjCMethodList *Prev = 0;
+ for (unsigned I = 0; I != NumInstanceMethods; ++I) {
+ if (ObjCMethodDecl *Method
+ = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))
+ Result.Instance.push_back(Method);
+ }
+
+ // Load factory methods
+ Prev = 0;
+ for (unsigned I = 0; I != NumFactoryMethods; ++I) {
+ if (ObjCMethodDecl *Method
+ = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))
+ Result.Factory.push_back(Method);
}
- IdentifierInfo *ReadData(const internal_key_type& k,
- const unsigned char* d,
- unsigned DataLen) {
- using namespace clang::io;
- unsigned RawID = ReadUnalignedLE32(d);
- bool IsInteresting = RawID & 0x01;
-
- // Wipe out the "is interesting" bit.
- RawID = RawID >> 1;
-
- IdentID ID = Reader.getGlobalIdentifierID(F, RawID);
- if (!IsInteresting) {
- // For uninteresting identifiers, just build the IdentifierInfo
- // and associate it with the persistent ID.
- IdentifierInfo *II = KnownII;
- if (!II)
- II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second));
- Reader.SetIdentifierInfo(ID, II);
- II->setIsFromAST();
- return II;
- }
-
- unsigned Bits = ReadUnalignedLE16(d);
- bool CPlusPlusOperatorKeyword = Bits & 0x01;
- Bits >>= 1;
- bool HasRevertedTokenIDToIdentifier = Bits & 0x01;
- Bits >>= 1;
- bool Poisoned = Bits & 0x01;
- Bits >>= 1;
- bool ExtensionToken = Bits & 0x01;
- Bits >>= 1;
- bool hasMacroDefinition = Bits & 0x01;
- Bits >>= 1;
- unsigned ObjCOrBuiltinID = Bits & 0x3FF;
- Bits >>= 10;
+ return Result;
+}
- assert(Bits == 0 && "Extra bits in the identifier?");
- DataLen -= 6;
+unsigned ASTIdentifierLookupTrait::ComputeHash(const internal_key_type& a) {
+ return llvm::HashString(StringRef(a.first, a.second));
+}
- // Build the IdentifierInfo itself and link the identifier ID with
- // the new IdentifierInfo.
+std::pair<unsigned, unsigned>
+ASTIdentifierLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
+ using namespace clang::io;
+ unsigned DataLen = ReadUnalignedLE16(d);
+ unsigned KeyLen = ReadUnalignedLE16(d);
+ return std::make_pair(KeyLen, DataLen);
+}
+
+std::pair<const char*, unsigned>
+ASTIdentifierLookupTrait::ReadKey(const unsigned char* d, unsigned n) {
+ assert(n >= 2 && d[n-1] == '\0');
+ return std::make_pair((const char*) d, n-1);
+}
+
+IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
+ const unsigned char* d,
+ unsigned DataLen) {
+ using namespace clang::io;
+ unsigned RawID = ReadUnalignedLE32(d);
+ bool IsInteresting = RawID & 0x01;
+
+ // Wipe out the "is interesting" bit.
+ RawID = RawID >> 1;
+
+ IdentID ID = Reader.getGlobalIdentifierID(F, RawID);
+ if (!IsInteresting) {
+ // For uninteresting identifiers, just build the IdentifierInfo
+ // and associate it with the persistent ID.
IdentifierInfo *II = KnownII;
if (!II)
II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second));
Reader.SetIdentifierInfo(ID, II);
-
- // Set or check the various bits in the IdentifierInfo structure.
- // Token IDs are read-only.
- if (HasRevertedTokenIDToIdentifier)
- II->RevertTokenIDToIdentifier();
- II->setObjCOrBuiltinID(ObjCOrBuiltinID);
- assert(II->isExtensionToken() == ExtensionToken &&
- "Incorrect extension token flag");
- (void)ExtensionToken;
- if (Poisoned)
- II->setIsPoisoned(true);
- assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
- "Incorrect C++ operator keyword flag");
- (void)CPlusPlusOperatorKeyword;
-
- // If this identifier is a macro, deserialize the macro
- // definition.
- if (hasMacroDefinition) {
- // FIXME: Check for conflicts?
- uint32_t Offset = ReadUnalignedLE32(d);
- Reader.SetIdentifierIsMacro(II, F, Offset);
- DataLen -= 4;
- }
-
- // Read all of the declarations visible at global scope with this
- // name.
- if (Reader.getContext() == 0) return II;
- if (DataLen > 0) {
- SmallVector<uint32_t, 4> DeclIDs;
- for (; DataLen > 0; DataLen -= 4)
- DeclIDs.push_back(Reader.getGlobalDeclID(F, ReadUnalignedLE32(d)));
- Reader.SetGloballyVisibleDecls(II, DeclIDs);
- }
-
II->setIsFromAST();
return II;
}
-};
-
-} // end anonymous namespace
-/// \brief The on-disk hash table used to contain information about
-/// all of the identifiers in the program.
-typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
- ASTIdentifierLookupTable;
+ unsigned Bits = ReadUnalignedLE16(d);
+ bool CPlusPlusOperatorKeyword = Bits & 0x01;
+ Bits >>= 1;
+ bool HasRevertedTokenIDToIdentifier = Bits & 0x01;
+ Bits >>= 1;
+ bool Poisoned = Bits & 0x01;
+ Bits >>= 1;
+ bool ExtensionToken = Bits & 0x01;
+ Bits >>= 1;
+ bool hasMacroDefinition = Bits & 0x01;
+ Bits >>= 1;
+ unsigned ObjCOrBuiltinID = Bits & 0x3FF;
+ Bits >>= 10;
+
+ assert(Bits == 0 && "Extra bits in the identifier?");
+ DataLen -= 6;
+
+ // Build the IdentifierInfo itself and link the identifier ID with
+ // the new IdentifierInfo.
+ IdentifierInfo *II = KnownII;
+ if (!II)
+ II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second));
+ Reader.SetIdentifierInfo(ID, II);
+
+ // Set or check the various bits in the IdentifierInfo structure.
+ // Token IDs are read-only.
+ if (HasRevertedTokenIDToIdentifier)
+ II->RevertTokenIDToIdentifier();
+ II->setObjCOrBuiltinID(ObjCOrBuiltinID);
+ assert(II->isExtensionToken() == ExtensionToken &&
+ "Incorrect extension token flag");
+ (void)ExtensionToken;
+ if (Poisoned)
+ II->setIsPoisoned(true);
+ assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
+ "Incorrect C++ operator keyword flag");
+ (void)CPlusPlusOperatorKeyword;
+
+ // If this identifier is a macro, deserialize the macro
+ // definition.
+ if (hasMacroDefinition) {
+ // FIXME: Check for conflicts?
+ uint32_t Offset = ReadUnalignedLE32(d);
+ Reader.SetIdentifierIsMacro(II, F, Offset);
+ DataLen -= 4;
+ }
+
+ // Read all of the declarations visible at global scope with this
+ // name.
+ if (Reader.getContext() == 0) return II;
+ if (DataLen > 0) {
+ SmallVector<uint32_t, 4> DeclIDs;
+ for (; DataLen > 0; DataLen -= 4)
+ DeclIDs.push_back(Reader.getGlobalDeclID(F, ReadUnalignedLE32(d)));
+ Reader.SetGloballyVisibleDecls(II, DeclIDs);
+ }
+
+ II->setIsFromAST();
+ return II;
+}
+
+unsigned
+ASTDeclContextNameLookupTrait::ComputeHash(const DeclNameKey &Key) const {
+ llvm::FoldingSetNodeID ID;
+ ID.AddInteger(Key.Kind);
-namespace {
-class ASTDeclContextNameLookupTrait {
- ASTReader &Reader;
- Module &F;
-
-public:
- /// \brief Pair of begin/end iterators for DeclIDs.
- ///
- /// Note that these declaration IDs are local to the module that contains this
- /// particular lookup t
- typedef std::pair<DeclID *, DeclID *> data_type;
-
- /// \brief Special internal key for declaration names.
- /// The hash table creates keys for comparison; we do not create
- /// a DeclarationName for the internal key to avoid deserializing types.
- struct DeclNameKey {
- DeclarationName::NameKind Kind;
- uint64_t Data;
- DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { }
- };
-
- typedef DeclarationName external_key_type;
- typedef DeclNameKey internal_key_type;
-
- explicit ASTDeclContextNameLookupTrait(ASTReader &Reader,
- Module &F)
- : Reader(Reader), F(F) { }
-
- static bool EqualKey(const internal_key_type& a,
- const internal_key_type& b) {
- return a.Kind == b.Kind && a.Data == b.Data;
- }
-
- unsigned ComputeHash(const DeclNameKey &Key) const {
- llvm::FoldingSetNodeID ID;
- ID.AddInteger(Key.Kind);
-
- switch (Key.Kind) {
- case DeclarationName::Identifier:
- case DeclarationName::CXXLiteralOperatorName:
- ID.AddString(((IdentifierInfo*)Key.Data)->getName());
- break;
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));
- break;
- case DeclarationName::CXXOperatorName:
- ID.AddInteger((OverloadedOperatorKind)Key.Data);
- break;
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- case DeclarationName::CXXUsingDirective:
- break;
- }
-
- return ID.ComputeHash();
+ switch (Key.Kind) {
+ case DeclarationName::Identifier:
+ case DeclarationName::CXXLiteralOperatorName:
+ ID.AddString(((IdentifierInfo*)Key.Data)->getName());
+ break;
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));
+ break;
+ case DeclarationName::CXXOperatorName:
+ ID.AddInteger((OverloadedOperatorKind)Key.Data);
+ break;
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ case DeclarationName::CXXUsingDirective:
+ break;
}
- internal_key_type GetInternalKey(const external_key_type& Name) const {
- DeclNameKey Key;
- Key.Kind = Name.getNameKind();
- switch (Name.getNameKind()) {
- case DeclarationName::Identifier:
- Key.Data = (uint64_t)Name.getAsIdentifierInfo();
- break;
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
- break;
- case DeclarationName::CXXOperatorName:
- Key.Data = Name.getCXXOverloadedOperator();
- break;
- case DeclarationName::CXXLiteralOperatorName:
- Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();
- break;
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- case DeclarationName::CXXUsingDirective:
- Key.Data = 0;
- break;
- }
+ return ID.ComputeHash();
+}
- return Key;
+ASTDeclContextNameLookupTrait::internal_key_type
+ASTDeclContextNameLookupTrait::GetInternalKey(
+ const external_key_type& Name) const {
+ DeclNameKey Key;
+ Key.Kind = Name.getNameKind();
+ switch (Name.getNameKind()) {
+ case DeclarationName::Identifier:
+ Key.Data = (uint64_t)Name.getAsIdentifierInfo();
+ break;
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
+ break;
+ case DeclarationName::CXXOperatorName:
+ Key.Data = Name.getCXXOverloadedOperator();
+ break;
+ case DeclarationName::CXXLiteralOperatorName:
+ Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();
+ break;
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ case DeclarationName::CXXUsingDirective:
+ Key.Data = 0;
+ break;
}
- external_key_type GetExternalKey(const internal_key_type& Key) const {
- ASTContext *Context = Reader.getContext();
- switch (Key.Kind) {
- case DeclarationName::Identifier:
- return DeclarationName((IdentifierInfo*)Key.Data);
-
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- return DeclarationName(Selector(Key.Data));
+ return Key;
+}
- case DeclarationName::CXXConstructorName:
- return Context->DeclarationNames.getCXXConstructorName(
- Context->getCanonicalType(Reader.getLocalType(F, Key.Data)));
+ASTDeclContextNameLookupTrait::external_key_type
+ASTDeclContextNameLookupTrait::GetExternalKey(
+ const internal_key_type& Key) const {
+ ASTContext *Context = Reader.getContext();
+ switch (Key.Kind) {
+ case DeclarationName::Identifier:
+ return DeclarationName((IdentifierInfo*)Key.Data);
- case DeclarationName::CXXDestructorName:
- return Context->DeclarationNames.getCXXDestructorName(
- Context->getCanonicalType(Reader.getLocalType(F, Key.Data)));
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ return DeclarationName(Selector(Key.Data));
- case DeclarationName::CXXConversionFunctionName:
- return Context->DeclarationNames.getCXXConversionFunctionName(
- Context->getCanonicalType(Reader.getLocalType(F, Key.Data)));
+ case DeclarationName::CXXConstructorName:
+ return Context->DeclarationNames.getCXXConstructorName(
+ Context->getCanonicalType(Reader.getLocalType(F, Key.Data)));
- case DeclarationName::CXXOperatorName:
- return Context->DeclarationNames.getCXXOperatorName(
- (OverloadedOperatorKind)Key.Data);
+ case DeclarationName::CXXDestructorName:
+ return Context->DeclarationNames.getCXXDestructorName(
+ Context->getCanonicalType(Reader.getLocalType(F, Key.Data)));
- case DeclarationName::CXXLiteralOperatorName:
- return Context->DeclarationNames.getCXXLiteralOperatorName(
- (IdentifierInfo*)Key.Data);
+ case DeclarationName::CXXConversionFunctionName:
+ return Context->DeclarationNames.getCXXConversionFunctionName(
+ Context->getCanonicalType(Reader.getLocalType(F, Key.Data)));
- case DeclarationName::CXXUsingDirective:
- return DeclarationName::getUsingDirectiveName();
- }
+ case DeclarationName::CXXOperatorName:
+ return Context->DeclarationNames.getCXXOperatorName(
+ (OverloadedOperatorKind)Key.Data);
- llvm_unreachable("Invalid Name Kind ?");
- }
+ case DeclarationName::CXXLiteralOperatorName:
+ return Context->DeclarationNames.getCXXLiteralOperatorName(
+ (IdentifierInfo*)Key.Data);
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char*& d) {
- using namespace clang::io;
- unsigned KeyLen = ReadUnalignedLE16(d);
- unsigned DataLen = ReadUnalignedLE16(d);
- return std::make_pair(KeyLen, DataLen);
+ case DeclarationName::CXXUsingDirective:
+ return DeclarationName::getUsingDirectiveName();
}
- internal_key_type ReadKey(const unsigned char* d, unsigned) {
- using namespace clang::io;
+ llvm_unreachable("Invalid Name Kind ?");
+}
- DeclNameKey Key;
- Key.Kind = (DeclarationName::NameKind)*d++;
- switch (Key.Kind) {
- case DeclarationName::Identifier:
- Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
- break;
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- Key.Data =
- (uint64_t)Reader.getLocalSelector(F, ReadUnalignedLE32(d))
- .getAsOpaquePtr();
- break;
- case DeclarationName::CXXOperatorName:
- Key.Data = *d++; // OverloadedOperatorKind
- break;
- case DeclarationName::CXXLiteralOperatorName:
- Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
- break;
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- case DeclarationName::CXXUsingDirective:
- Key.Data = 0;
- break;
- }
+std::pair<unsigned, unsigned>
+ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
+ using namespace clang::io;
+ unsigned KeyLen = ReadUnalignedLE16(d);
+ unsigned DataLen = ReadUnalignedLE16(d);
+ return std::make_pair(KeyLen, DataLen);
+}
- return Key;
- }
+ASTDeclContextNameLookupTrait::internal_key_type
+ASTDeclContextNameLookupTrait::ReadKey(const unsigned char* d, unsigned) {
+ using namespace clang::io;
- data_type ReadData(internal_key_type, const unsigned char* d,
- unsigned DataLen) {
- using namespace clang::io;
- unsigned NumDecls = ReadUnalignedLE16(d);
- DeclID *Start = (DeclID *)d;
- return std::make_pair(Start, Start + NumDecls);
+ DeclNameKey Key;
+ Key.Kind = (DeclarationName::NameKind)*d++;
+ switch (Key.Kind) {
+ case DeclarationName::Identifier:
+ Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
+ break;
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ Key.Data =
+ (uint64_t)Reader.getLocalSelector(F, ReadUnalignedLE32(d))
+ .getAsOpaquePtr();
+ break;
+ case DeclarationName::CXXOperatorName:
+ Key.Data = *d++; // OverloadedOperatorKind
+ break;
+ case DeclarationName::CXXLiteralOperatorName:
+ Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
+ break;
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ case DeclarationName::CXXUsingDirective:
+ Key.Data = 0;
+ break;
}
-};
-} // end anonymous namespace
+ return Key;
+}
-/// \brief The on-disk hash table used for the DeclContext's Name lookup table.
-typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
- ASTDeclContextNameLookupTable;
+ASTDeclContextNameLookupTrait::data_type
+ASTDeclContextNameLookupTrait::ReadData(internal_key_type,
+ const unsigned char* d,
+ unsigned DataLen) {
+ using namespace clang::io;
+ unsigned NumDecls = ReadUnalignedLE16(d);
+ DeclID *Start = (DeclID *)d;
+ return std::make_pair(Start, Start + NumDecls);
+}
bool ASTReader::ReadDeclContextStorage(Module &M,
llvm::BitstreamCursor &Cursor,
@@ -1631,116 +1530,65 @@
return LocalID + I->second;
}
-namespace {
- /// \brief Trait class used to search the on-disk hash table containing all of
- /// the header search information.
- ///
- /// The on-disk hash table contains a mapping from each header path to
- /// information about that header (how many times it has been included, its
- /// controlling macro, etc.). Note that we actually hash based on the
- /// filename, and support "deep" comparisons of file names based on current
- /// inode numbers, so that the search can cope with non-normalized path names
- /// and symlinks.
- class HeaderFileInfoTrait {
- ASTReader &Reader;
- Module &M;
- HeaderSearch *HS;
- const char *FrameworkStrings;
- const char *SearchPath;
- struct stat SearchPathStatBuf;
- llvm::Optional<int> SearchPathStatResult;
-
- int StatSimpleCache(const char *Path, struct stat *StatBuf) {
- if (Path == SearchPath) {
- if (!SearchPathStatResult)
- SearchPathStatResult = stat(Path, &SearchPathStatBuf);
-
- *StatBuf = SearchPathStatBuf;
- return *SearchPathStatResult;
- }
-
- return stat(Path, StatBuf);
- }
-
- public:
- typedef const char *external_key_type;
- typedef const char *internal_key_type;
-
- typedef HeaderFileInfo data_type;
-
- HeaderFileInfoTrait(ASTReader &Reader, Module &M, HeaderSearch *HS,
- const char *FrameworkStrings,
- const char *SearchPath = 0)
- : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings),
- SearchPath(SearchPath) { }
-
- static unsigned ComputeHash(const char *path) {
- return llvm::HashString(llvm::sys::path::filename(path));
- }
+unsigned HeaderFileInfoTrait::ComputeHash(const char *path) {
+ return llvm::HashString(llvm::sys::path::filename(path));
+}
- static internal_key_type GetInternalKey(const char *path) { return path; }
+HeaderFileInfoTrait::internal_key_type
+HeaderFileInfoTrait::GetInternalKey(const char *path) { return path; }
- bool EqualKey(internal_key_type a, internal_key_type b) {
- if (strcmp(a, b) == 0)
- return true;
-
- if (llvm::sys::path::filename(a) != llvm::sys::path::filename(b))
- return false;
-
- // The file names match, but the path names don't. stat() the files to
- // see if they are the same.
- struct stat StatBufA, StatBufB;
- if (StatSimpleCache(a, &StatBufA) || StatSimpleCache(b, &StatBufB))
- return false;
-
- return StatBufA.st_ino == StatBufB.st_ino;
- }
-
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char*& d) {
- unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
- unsigned DataLen = (unsigned) *d++;
- return std::make_pair(KeyLen + 1, DataLen);
- }
+bool HeaderFileInfoTrait::EqualKey(internal_key_type a, internal_key_type b) {
+ if (strcmp(a, b) == 0)
+ return true;
+
+ if (llvm::sys::path::filename(a) != llvm::sys::path::filename(b))
+ return false;
+
+ // The file names match, but the path names don't. stat() the files to
+ // see if they are the same.
+ struct stat StatBufA, StatBufB;
+ if (StatSimpleCache(a, &StatBufA) || StatSimpleCache(b, &StatBufB))
+ return false;
+
+ return StatBufA.st_ino == StatBufB.st_ino;
+}
- static internal_key_type ReadKey(const unsigned char *d, unsigned) {
- return (const char *)d;
- }
+std::pair<unsigned, unsigned>
+HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) {
+ unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
+ unsigned DataLen = (unsigned) *d++;
+ return std::make_pair(KeyLen + 1, DataLen);
+}
- data_type ReadData(const internal_key_type, const unsigned char *d,
- unsigned DataLen) {
- const unsigned char *End = d + DataLen;
- using namespace clang::io;
- HeaderFileInfo HFI;
- unsigned Flags = *d++;
- HFI.isImport = (Flags >> 5) & 0x01;
- HFI.isPragmaOnce = (Flags >> 4) & 0x01;
- HFI.DirInfo = (Flags >> 2) & 0x03;
- HFI.Resolved = (Flags >> 1) & 0x01;
- HFI.IndexHeaderMapHeader = Flags & 0x01;
- HFI.NumIncludes = ReadUnalignedLE16(d);
- HFI.ControllingMacroID = Reader.getGlobalDeclID(M, ReadUnalignedLE32(d));
- if (unsigned FrameworkOffset = ReadUnalignedLE32(d)) {
- // The framework offset is 1 greater than the actual offset,
- // since 0 is used as an indicator for "no framework name".
- StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1);
- HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
- }
-
- assert(End == d && "Wrong data length in HeaderFileInfo deserialization");
- (void)End;
-
- // This HeaderFileInfo was externally loaded.
- HFI.External = true;
- return HFI;
- }
- };
+HeaderFileInfoTrait::data_type
+HeaderFileInfoTrait::ReadData(const internal_key_type, const unsigned char *d,
+ unsigned DataLen) {
+ const unsigned char *End = d + DataLen;
+ using namespace clang::io;
+ HeaderFileInfo HFI;
+ unsigned Flags = *d++;
+ HFI.isImport = (Flags >> 5) & 0x01;
+ HFI.isPragmaOnce = (Flags >> 4) & 0x01;
+ HFI.DirInfo = (Flags >> 2) & 0x03;
+ HFI.Resolved = (Flags >> 1) & 0x01;
+ HFI.IndexHeaderMapHeader = Flags & 0x01;
+ HFI.NumIncludes = ReadUnalignedLE16(d);
+ HFI.ControllingMacroID = Reader.getGlobalDeclID(M, ReadUnalignedLE32(d));
+ if (unsigned FrameworkOffset = ReadUnalignedLE32(d)) {
+ // The framework offset is 1 greater than the actual offset,
+ // since 0 is used as an indicator for "no framework name".
+ StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1);
+ HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
+ }
+
+ assert(End == d && "Wrong data length in HeaderFileInfo deserialization");
+ (void)End;
+
+ // This HeaderFileInfo was externally loaded.
+ HFI.External = true;
+ return HFI;
}
-/// \brief The on-disk hash table used for the global method pool.
-typedef OnDiskChainedHashTable<HeaderFileInfoTrait>
- HeaderFileInfoLookupTable;
-
void ASTReader::SetIdentifierIsMacro(IdentifierInfo *II, Module &F,
uint64_t LocalOffset) {
// Note that this identifier has a macro definition.
@@ -5718,291 +5566,3 @@
delete static_cast<ASTDeclContextNameLookupTable*>(J->first);
}
}
-
-//===----------------------------------------------------------------------===//
-// Module implementation
-//===----------------------------------------------------------------------===//
-Module::Module(ModuleKind Kind)
- : Kind(Kind), DirectlyImported(false), SizeInBits(0),
- LocalNumSLocEntries(0), SLocEntryBaseID(0),
- SLocEntryBaseOffset(0), SLocEntryOffsets(0),
- SLocFileOffsets(0), LocalNumIdentifiers(0),
- IdentifierOffsets(0), BaseIdentifierID(0), IdentifierTableData(0),
- IdentifierLookupTable(0), BasePreprocessedEntityID(0),
- LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0),
- BaseMacroDefinitionID(0), LocalNumHeaderFileInfos(0),
- HeaderFileInfoTableData(0), HeaderFileInfoTable(0),
- HeaderFileFrameworkStrings(0),
- LocalNumSelectors(0), SelectorOffsets(0), BaseSelectorID(0),
- SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0),
- DeclOffsets(0), BaseDeclID(0),
- LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(0),
- LocalNumTypes(0), TypeOffsets(0), BaseTypeIndex(0), StatCache(0),
- NumPreallocatedPreprocessingEntities(0)
-{}
-
-Module::~Module() {
- for (DeclContextInfosMap::iterator I = DeclContextInfos.begin(),
- E = DeclContextInfos.end();
- I != E; ++I) {
- if (I->second.NameLookupTableData)
- delete static_cast<ASTDeclContextNameLookupTable*>(
- I->second.NameLookupTableData);
- }
-
- delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
- delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable);
- delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
-}
-
-template<typename Key, typename Offset, unsigned InitialCapacity>
-static void
-dumpLocalRemap(StringRef Name,
- const ContinuousRangeMap<Key, Offset, InitialCapacity> &Map) {
- if (Map.begin() == Map.end())
- return;
-
- typedef ContinuousRangeMap<Key, Offset, InitialCapacity> MapType;
- llvm::errs() << " " << Name << ":\n";
- for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end();
- I != IEnd; ++I) {
- llvm::errs() << " " << I->first << " -> " << I->second
- << "\n";
- }
-}
-
-void Module::dump() {
- llvm::errs() << "\nModule: " << FileName << "\n";
- if (!Imports.empty()) {
- llvm::errs() << " Imports: ";
- for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
- if (I)
- llvm::errs() << ", ";
- llvm::errs() << Imports[I]->FileName;
- }
- llvm::errs() << "\n";
- }
-
- // Remapping tables.
- llvm::errs() << " Base source location offset: " << SLocEntryBaseOffset
- << '\n';
- dumpLocalRemap("Source location offset local -> global map", SLocRemap);
-
- llvm::errs() << " Base identifier ID: " << BaseIdentifierID << '\n'
- << " Number of identifiers: " << LocalNumIdentifiers << '\n';
- dumpLocalRemap("Identifier ID local -> global map", IdentifierRemap);
-
- llvm::errs() << " Base selector ID: " << BaseSelectorID << '\n'
- << " Number of selectors: " << LocalNumSelectors << '\n';
- dumpLocalRemap("Selector ID local -> global map", SelectorRemap);
-
- llvm::errs() << " Base preprocessed entity ID: " << BasePreprocessedEntityID
- << '\n'
- << " Number of preprocessed entities: "
- << NumPreallocatedPreprocessingEntities << '\n';
- dumpLocalRemap("Preprocessed entity ID local -> global map",
- PreprocessedEntityRemap);
-
- llvm::errs() << " Base macro definition ID: " << BaseMacroDefinitionID
- << '\n'
- << " Number of macro definitions: " << LocalNumMacroDefinitions
- << '\n';
- dumpLocalRemap("Macro definition ID local -> global map",
- MacroDefinitionRemap);
-
- llvm::errs() << " Base type index: " << BaseTypeIndex << '\n'
- << " Number of types: " << LocalNumTypes << '\n';
- dumpLocalRemap("Type index local -> global map", TypeRemap);
-
- llvm::errs() << " Base decl ID: " << BaseDeclID << '\n'
- << " Number of decls: " << LocalNumDecls << '\n';
- dumpLocalRemap("Decl ID local -> global map", DeclRemap);
-}
-
-//===----------------------------------------------------------------------===//
-// Module manager implementation
-//===----------------------------------------------------------------------===//
-
-Module *ModuleManager::lookup(StringRef Name) {
- const FileEntry *Entry = FileMgr.getFile(Name);
- return Modules[Entry];
-}
-
-llvm::MemoryBuffer *ModuleManager::lookupBuffer(StringRef Name) {
- const FileEntry *Entry = FileMgr.getFile(Name);
- return InMemoryBuffers[Entry];
-}
-
-std::pair<Module *, bool>
-ModuleManager::addModule(StringRef FileName, ModuleKind Type,
- Module *ImportedBy, std::string &ErrorStr) {
- const FileEntry *Entry = FileMgr.getFile(FileName);
- if (!Entry && FileName != "-") {
- ErrorStr = "file not found";
- return std::make_pair(static_cast<Module*>(0), false);
- }
-
- // Check whether we already loaded this module, before
- Module *&ModuleEntry = Modules[Entry];
- bool NewModule = false;
- if (!ModuleEntry) {
- // Allocate a new module.
- Module *New = new Module(Type);
- New->FileName = FileName.str();
- Chain.push_back(New);
- NewModule = true;
- ModuleEntry = New;
-
- // Load the contents of the module
- if (llvm::MemoryBuffer *Buffer = lookupBuffer(FileName)) {
- // The buffer was already provided for us.
- assert(Buffer && "Passed null buffer");
- New->Buffer.reset(Buffer);
- } else {
- // Open the AST file.
- llvm::error_code ec;
- if (FileName == "-") {
- ec = llvm::MemoryBuffer::getSTDIN(New->Buffer);
- if (ec)
- ErrorStr = ec.message();
- } else
- New->Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrorStr));
-
- if (!New->Buffer)
- return std::make_pair(static_cast<Module*>(0), false);
- }
-
- // Initialize the stream
- New->StreamFile.init((const unsigned char *)New->Buffer->getBufferStart(),
- (const unsigned char *)New->Buffer->getBufferEnd()); }
-
- if (ImportedBy) {
- ModuleEntry->ImportedBy.insert(ImportedBy);
- ImportedBy->Imports.insert(ModuleEntry);
- } else {
- ModuleEntry->DirectlyImported = true;
- }
-
- return std::make_pair(ModuleEntry, NewModule);
-}
-
-void ModuleManager::addInMemoryBuffer(StringRef FileName,
- llvm::MemoryBuffer *Buffer) {
-
- const FileEntry *Entry = FileMgr.getVirtualFile(FileName,
- Buffer->getBufferSize(), 0);
- InMemoryBuffers[Entry] = Buffer;
-}
-
-ModuleManager::ModuleManager(const FileSystemOptions &FSO) : FileMgr(FSO) { }
-
-ModuleManager::~ModuleManager() {
- for (unsigned i = 0, e = Chain.size(); i != e; ++i)
- delete Chain[e - i - 1];
-}
-
-void ModuleManager::visit(bool (*Visitor)(Module &M, void *UserData),
- void *UserData) {
- unsigned N = size();
-
- // Record the number of incoming edges for each module. When we
- // encounter a module with no incoming edges, push it into the queue
- // to seed the queue.
- SmallVector<Module *, 4> Queue;
- Queue.reserve(N);
- llvm::DenseMap<Module *, unsigned> UnusedIncomingEdges;
- for (ModuleIterator M = begin(), MEnd = end(); M != MEnd; ++M) {
- if (unsigned Size = (*M)->ImportedBy.size())
- UnusedIncomingEdges[*M] = Size;
- else
- Queue.push_back(*M);
- }
-
- llvm::SmallPtrSet<Module *, 4> Skipped;
- unsigned QueueStart = 0;
- while (QueueStart < Queue.size()) {
- Module *CurrentModule = Queue[QueueStart++];
-
- // Check whether this module should be skipped.
- if (Skipped.count(CurrentModule))
- continue;
-
- if (Visitor(*CurrentModule, UserData)) {
- // The visitor has requested that cut off visitation of any
- // module that the current module depends on. To indicate this
- // behavior, we mark all of the reachable modules as having N
- // incoming edges (which is impossible otherwise).
- SmallVector<Module *, 4> Stack;
- Stack.push_back(CurrentModule);
- Skipped.insert(CurrentModule);
- while (!Stack.empty()) {
- Module *NextModule = Stack.back();
- Stack.pop_back();
-
- // For any module that this module depends on, push it on the
- // stack (if it hasn't already been marked as visited).
- for (llvm::SetVector<Module *>::iterator
- M = NextModule->Imports.begin(),
- MEnd = NextModule->Imports.end();
- M != MEnd; ++M) {
- if (Skipped.insert(*M))
- Stack.push_back(*M);
- }
- }
- continue;
- }
-
- // For any module that this module depends on, push it on the
- // stack (if it hasn't already been marked as visited).
- for (llvm::SetVector<Module *>::iterator M = CurrentModule->Imports.begin(),
- MEnd = CurrentModule->Imports.end();
- M != MEnd; ++M) {
-
- // Remove our current module as an impediment to visiting the
- // module we depend on. If we were the last unvisited module
- // that depends on this particular module, push it into the
- // queue to be visited.
- unsigned &NumUnusedEdges = UnusedIncomingEdges[*M];
- if (NumUnusedEdges && (--NumUnusedEdges == 0))
- Queue.push_back(*M);
- }
- }
-}
-
-/// \brief Perform a depth-first visit of the current module.
-static bool visitDepthFirst(Module &M,
- bool (*Visitor)(Module &M, bool Preorder,
- void *UserData),
- void *UserData,
- llvm::SmallPtrSet<Module *, 4> &Visited) {
- // Preorder visitation
- if (Visitor(M, /*Preorder=*/true, UserData))
- return true;
-
- // Visit children
- for (llvm::SetVector<Module *>::iterator IM = M.Imports.begin(),
- IMEnd = M.Imports.end();
- IM != IMEnd; ++IM) {
- if (!Visited.insert(*IM))
- continue;
-
- if (visitDepthFirst(**IM, Visitor, UserData, Visited))
- return true;
- }
-
- // Postorder visitation
- return Visitor(M, /*Preorder=*/false, UserData);
-}
-
-void ModuleManager::visitDepthFirst(bool (*Visitor)(Module &M, bool Preorder,
- void *UserData),
- void *UserData) {
- llvm::SmallPtrSet<Module *, 4> Visited;
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- if (!Visited.insert(Chain[I]))
- continue;
-
- if (::visitDepthFirst(*Chain[I], Visitor, UserData, Visited))
- return;
- }
-}
Added: cfe/trunk/lib/Serialization/ASTReaderInternals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderInternals.h?rev=138582&view=auto
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderInternals.h (added)
+++ cfe/trunk/lib/Serialization/ASTReaderInternals.h Thu Aug 25 15:47:51 2011
@@ -0,0 +1,243 @@
+//===--- ASTReaderInternals.h - AST Reader Internals ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides internal definitions used in the AST reader.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_INTERNALS_H
+#define LLVM_CLANG_SERIALIZATION_ASTREADER_INTERNALS_H
+
+#include "clang/Basic/OnDiskHashTable.h"
+#include "clang/AST/DeclarationName.h"
+#include <utility>
+#include <sys/stat.h>
+
+namespace clang {
+
+class ASTReader;
+class HeaderSearch;
+struct HeaderFileInfo;
+
+namespace serialization {
+
+class Module;
+
+namespace reader {
+
+/// \brief Class that performs name lookup into a DeclContext stored
+/// in an AST file.
+class ASTDeclContextNameLookupTrait {
+ ASTReader &Reader;
+ Module &F;
+
+public:
+ /// \brief Pair of begin/end iterators for DeclIDs.
+ ///
+ /// Note that these declaration IDs are local to the module that contains this
+ /// particular lookup t
+ typedef std::pair<DeclID *, DeclID *> data_type;
+
+ /// \brief Special internal key for declaration names.
+ /// The hash table creates keys for comparison; we do not create
+ /// a DeclarationName for the internal key to avoid deserializing types.
+ struct DeclNameKey {
+ DeclarationName::NameKind Kind;
+ uint64_t Data;
+ DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { }
+ };
+
+ typedef DeclarationName external_key_type;
+ typedef DeclNameKey internal_key_type;
+
+ explicit ASTDeclContextNameLookupTrait(ASTReader &Reader,
+ Module &F)
+ : Reader(Reader), F(F) { }
+
+ static bool EqualKey(const internal_key_type& a,
+ const internal_key_type& b) {
+ return a.Kind == b.Kind && a.Data == b.Data;
+ }
+
+ unsigned ComputeHash(const DeclNameKey &Key) const;
+ internal_key_type GetInternalKey(const external_key_type& Name) const;
+ external_key_type GetExternalKey(const internal_key_type& Key) const;
+
+ static std::pair<unsigned, unsigned>
+ ReadKeyDataLength(const unsigned char*& d);
+
+ internal_key_type ReadKey(const unsigned char* d, unsigned);
+
+ data_type ReadData(internal_key_type, const unsigned char* d,
+ unsigned DataLen);
+};
+
+/// \brief The on-disk hash table used for the DeclContext's Name lookup table.
+typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
+ ASTDeclContextNameLookupTable;
+
+/// \brief Class that performs lookup for an identifier stored in an AST file.
+class ASTIdentifierLookupTrait {
+ ASTReader &Reader;
+ Module &F;
+
+ // If we know the IdentifierInfo in advance, it is here and we will
+ // not build a new one. Used when deserializing information about an
+ // identifier that was constructed before the AST file was read.
+ IdentifierInfo *KnownII;
+
+public:
+ typedef IdentifierInfo * data_type;
+
+ typedef const std::pair<const char*, unsigned> external_key_type;
+
+ typedef external_key_type internal_key_type;
+
+ ASTIdentifierLookupTrait(ASTReader &Reader, Module &F,
+ IdentifierInfo *II = 0)
+ : Reader(Reader), F(F), KnownII(II) { }
+
+ static bool EqualKey(const internal_key_type& a,
+ const internal_key_type& b) {
+ return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
+ : false;
+ }
+
+ static unsigned ComputeHash(const internal_key_type& a);
+
+ // This hopefully will just get inlined and removed by the optimizer.
+ static const internal_key_type&
+ GetInternalKey(const external_key_type& x) { return x; }
+
+ // This hopefully will just get inlined and removed by the optimizer.
+ static const external_key_type&
+ GetExternalKey(const internal_key_type& x) { return x; }
+
+ static std::pair<unsigned, unsigned>
+ ReadKeyDataLength(const unsigned char*& d);
+
+ static std::pair<const char*, unsigned>
+ ReadKey(const unsigned char* d, unsigned n);
+
+ IdentifierInfo *ReadData(const internal_key_type& k,
+ const unsigned char* d,
+ unsigned DataLen);
+};
+
+/// \brief The on-disk hash table used to contain information about
+/// all of the identifiers in the program.
+typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
+ ASTIdentifierLookupTable;
+
+/// \brief Class that performs lookup for a selector's entries in the global
+/// method pool stored in an AST file.
+class ASTSelectorLookupTrait {
+ ASTReader &Reader;
+ Module &F;
+
+public:
+ struct data_type {
+ SelectorID ID;
+ llvm::SmallVector<ObjCMethodDecl *, 2> Instance;
+ llvm::SmallVector<ObjCMethodDecl *, 2> Factory;
+ };
+
+ typedef Selector external_key_type;
+ typedef external_key_type internal_key_type;
+
+ ASTSelectorLookupTrait(ASTReader &Reader, Module &F)
+ : Reader(Reader), F(F) { }
+
+ static bool EqualKey(const internal_key_type& a,
+ const internal_key_type& b) {
+ return a == b;
+ }
+
+ static unsigned ComputeHash(Selector Sel);
+
+ static const internal_key_type&
+ GetInternalKey(const external_key_type& x) { return x; };
+
+ static std::pair<unsigned, unsigned>
+ ReadKeyDataLength(const unsigned char*& d);
+
+ internal_key_type ReadKey(const unsigned char* d, unsigned);
+ data_type ReadData(Selector, const unsigned char* d, unsigned DataLen);
+};
+
+/// \brief The on-disk hash table used for the global method pool.
+typedef OnDiskChainedHashTable<ASTSelectorLookupTrait>
+ ASTSelectorLookupTable;
+
+/// \brief Trait class used to search the on-disk hash table containing all of
+/// the header search information.
+///
+/// The on-disk hash table contains a mapping from each header path to
+/// information about that header (how many times it has been included, its
+/// controlling macro, etc.). Note that we actually hash based on the
+/// filename, and support "deep" comparisons of file names based on current
+/// inode numbers, so that the search can cope with non-normalized path names
+/// and symlinks.
+class HeaderFileInfoTrait {
+ ASTReader &Reader;
+ Module &M;
+ HeaderSearch *HS;
+ const char *FrameworkStrings;
+ const char *SearchPath;
+ struct stat SearchPathStatBuf;
+ llvm::Optional<int> SearchPathStatResult;
+
+ int StatSimpleCache(const char *Path, struct stat *StatBuf) {
+ if (Path == SearchPath) {
+ if (!SearchPathStatResult)
+ SearchPathStatResult = stat(Path, &SearchPathStatBuf);
+
+ *StatBuf = SearchPathStatBuf;
+ return *SearchPathStatResult;
+ }
+
+ return stat(Path, StatBuf);
+ }
+
+public:
+ typedef const char *external_key_type;
+ typedef const char *internal_key_type;
+
+ typedef HeaderFileInfo data_type;
+
+ HeaderFileInfoTrait(ASTReader &Reader, Module &M, HeaderSearch *HS,
+ const char *FrameworkStrings,
+ const char *SearchPath = 0)
+ : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings),
+ SearchPath(SearchPath) { }
+
+ static unsigned ComputeHash(const char *path);
+ static internal_key_type GetInternalKey(const char *path);
+ bool EqualKey(internal_key_type a, internal_key_type b);
+
+ static std::pair<unsigned, unsigned>
+ ReadKeyDataLength(const unsigned char*& d);
+
+ static internal_key_type ReadKey(const unsigned char *d, unsigned) {
+ return (const char *)d;
+ }
+
+ data_type ReadData(const internal_key_type, const unsigned char *d,
+ unsigned DataLen);
+};
+
+/// \brief The on-disk hash table used for known header files.
+typedef OnDiskChainedHashTable<HeaderFileInfoTrait>
+ HeaderFileInfoLookupTable;
+
+} // end namespace clang::serialization::reader
+} // end namespace clang::serialization
+} // end namespace clang
+
+
+#endif
Modified: cfe/trunk/lib/Serialization/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/CMakeLists.txt?rev=138582&r1=138581&r2=138582&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/CMakeLists.txt (original)
+++ cfe/trunk/lib/Serialization/CMakeLists.txt Thu Aug 25 15:47:51 2011
@@ -2,6 +2,8 @@
#set(LLVM_USED_LIBS ???)
add_clang_library(clangSerialization
+ ASTCommon.h
+ ASTReaderInternals.h
ASTCommon.cpp
ASTReader.cpp
ASTReaderDecl.cpp
@@ -11,6 +13,8 @@
ASTWriterStmt.cpp
ChainedIncludesSource.cpp
GeneratePCH.cpp
+ Module.cpp
+ ModuleManager.cpp
)
add_dependencies(clangSerialization
Added: cfe/trunk/lib/Serialization/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/Module.cpp?rev=138582&view=auto
==============================================================================
--- cfe/trunk/lib/Serialization/Module.cpp (added)
+++ cfe/trunk/lib/Serialization/Module.cpp Thu Aug 25 15:47:51 2011
@@ -0,0 +1,117 @@
+//===--- Module.cpp - 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 implements the Module class, which describes a module that has
+// been loaded from an AST file.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Serialization/Module.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "ASTReaderInternals.h"
+
+using namespace clang;
+using namespace serialization;
+using namespace reader;
+
+Module::Module(ModuleKind Kind)
+ : Kind(Kind), DirectlyImported(false), SizeInBits(0),
+ LocalNumSLocEntries(0), SLocEntryBaseID(0),
+ SLocEntryBaseOffset(0), SLocEntryOffsets(0),
+ SLocFileOffsets(0), LocalNumIdentifiers(0),
+ IdentifierOffsets(0), BaseIdentifierID(0), IdentifierTableData(0),
+ IdentifierLookupTable(0), BasePreprocessedEntityID(0),
+ LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0),
+ BaseMacroDefinitionID(0), LocalNumHeaderFileInfos(0),
+ HeaderFileInfoTableData(0), HeaderFileInfoTable(0),
+ HeaderFileFrameworkStrings(0),
+ LocalNumSelectors(0), SelectorOffsets(0), BaseSelectorID(0),
+ SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0),
+ DeclOffsets(0), BaseDeclID(0),
+ LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(0),
+ LocalNumTypes(0), TypeOffsets(0), BaseTypeIndex(0), StatCache(0),
+ NumPreallocatedPreprocessingEntities(0)
+{}
+
+Module::~Module() {
+ for (DeclContextInfosMap::iterator I = DeclContextInfos.begin(),
+ E = DeclContextInfos.end();
+ I != E; ++I) {
+ if (I->second.NameLookupTableData)
+ delete static_cast<ASTDeclContextNameLookupTable*>(
+ I->second.NameLookupTableData);
+ }
+
+ delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
+ delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable);
+ delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
+}
+
+template<typename Key, typename Offset, unsigned InitialCapacity>
+static void
+dumpLocalRemap(StringRef Name,
+ const ContinuousRangeMap<Key, Offset, InitialCapacity> &Map) {
+ if (Map.begin() == Map.end())
+ return;
+
+ typedef ContinuousRangeMap<Key, Offset, InitialCapacity> MapType;
+ llvm::errs() << " " << Name << ":\n";
+ for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end();
+ I != IEnd; ++I) {
+ llvm::errs() << " " << I->first << " -> " << I->second << "\n";
+ }
+}
+
+void Module::dump() {
+ llvm::errs() << "\nModule: " << FileName << "\n";
+ if (!Imports.empty()) {
+ llvm::errs() << " Imports: ";
+ for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
+ if (I)
+ llvm::errs() << ", ";
+ llvm::errs() << Imports[I]->FileName;
+ }
+ llvm::errs() << "\n";
+ }
+
+ // Remapping tables.
+ llvm::errs() << " Base source location offset: " << SLocEntryBaseOffset
+ << '\n';
+ dumpLocalRemap("Source location offset local -> global map", SLocRemap);
+
+ llvm::errs() << " Base identifier ID: " << BaseIdentifierID << '\n'
+ << " Number of identifiers: " << LocalNumIdentifiers << '\n';
+ dumpLocalRemap("Identifier ID local -> global map", IdentifierRemap);
+
+ llvm::errs() << " Base selector ID: " << BaseSelectorID << '\n'
+ << " Number of selectors: " << LocalNumSelectors << '\n';
+ dumpLocalRemap("Selector ID local -> global map", SelectorRemap);
+
+ llvm::errs() << " Base preprocessed entity ID: " << BasePreprocessedEntityID
+ << '\n'
+ << " Number of preprocessed entities: "
+ << NumPreallocatedPreprocessingEntities << '\n';
+ dumpLocalRemap("Preprocessed entity ID local -> global map",
+ PreprocessedEntityRemap);
+
+ llvm::errs() << " Base macro definition ID: " << BaseMacroDefinitionID
+ << '\n'
+ << " Number of macro definitions: " << LocalNumMacroDefinitions
+ << '\n';
+ dumpLocalRemap("Macro definition ID local -> global map",
+ MacroDefinitionRemap);
+
+ llvm::errs() << " Base type index: " << BaseTypeIndex << '\n'
+ << " Number of types: " << LocalNumTypes << '\n';
+ dumpLocalRemap("Type index local -> global map", TypeRemap);
+
+ llvm::errs() << " Base decl ID: " << BaseDeclID << '\n'
+ << " Number of decls: " << LocalNumDecls << '\n';
+ dumpLocalRemap("Decl ID local -> global map", DeclRemap);
+}
Added: cfe/trunk/lib/Serialization/ModuleManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ModuleManager.cpp?rev=138582&view=auto
==============================================================================
--- cfe/trunk/lib/Serialization/ModuleManager.cpp (added)
+++ cfe/trunk/lib/Serialization/ModuleManager.cpp Thu Aug 25 15:47:51 2011
@@ -0,0 +1,204 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Serialization/ModuleManager.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+
+using namespace clang;
+using namespace serialization;
+
+Module *ModuleManager::lookup(StringRef Name) {
+ const FileEntry *Entry = FileMgr.getFile(Name);
+ return Modules[Entry];
+}
+
+llvm::MemoryBuffer *ModuleManager::lookupBuffer(StringRef Name) {
+ const FileEntry *Entry = FileMgr.getFile(Name);
+ return InMemoryBuffers[Entry];
+}
+
+std::pair<Module *, bool>
+ModuleManager::addModule(StringRef FileName, ModuleKind Type,
+ Module *ImportedBy, std::string &ErrorStr) {
+ const FileEntry *Entry = FileMgr.getFile(FileName);
+ if (!Entry && FileName != "-") {
+ ErrorStr = "file not found";
+ return std::make_pair(static_cast<Module*>(0), false);
+ }
+
+ // Check whether we already loaded this module, before
+ Module *&ModuleEntry = Modules[Entry];
+ bool NewModule = false;
+ if (!ModuleEntry) {
+ // Allocate a new module.
+ Module *New = new Module(Type);
+ New->FileName = FileName.str();
+ Chain.push_back(New);
+ NewModule = true;
+ ModuleEntry = New;
+
+ // Load the contents of the module
+ if (llvm::MemoryBuffer *Buffer = lookupBuffer(FileName)) {
+ // The buffer was already provided for us.
+ assert(Buffer && "Passed null buffer");
+ New->Buffer.reset(Buffer);
+ } else {
+ // Open the AST file.
+ llvm::error_code ec;
+ if (FileName == "-") {
+ ec = llvm::MemoryBuffer::getSTDIN(New->Buffer);
+ if (ec)
+ ErrorStr = ec.message();
+ } else
+ New->Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrorStr));
+
+ if (!New->Buffer)
+ return std::make_pair(static_cast<Module*>(0), false);
+ }
+
+ // Initialize the stream
+ New->StreamFile.init((const unsigned char *)New->Buffer->getBufferStart(),
+ (const unsigned char *)New->Buffer->getBufferEnd()); }
+
+ if (ImportedBy) {
+ ModuleEntry->ImportedBy.insert(ImportedBy);
+ ImportedBy->Imports.insert(ModuleEntry);
+ } else {
+ ModuleEntry->DirectlyImported = true;
+ }
+
+ return std::make_pair(ModuleEntry, NewModule);
+}
+
+void ModuleManager::addInMemoryBuffer(StringRef FileName,
+ llvm::MemoryBuffer *Buffer) {
+
+ const FileEntry *Entry = FileMgr.getVirtualFile(FileName,
+ Buffer->getBufferSize(), 0);
+ InMemoryBuffers[Entry] = Buffer;
+}
+
+ModuleManager::ModuleManager(const FileSystemOptions &FSO) : FileMgr(FSO) { }
+
+ModuleManager::~ModuleManager() {
+ for (unsigned i = 0, e = Chain.size(); i != e; ++i)
+ delete Chain[e - i - 1];
+}
+
+void ModuleManager::visit(bool (*Visitor)(Module &M, void *UserData),
+ void *UserData) {
+ unsigned N = size();
+
+ // Record the number of incoming edges for each module. When we
+ // encounter a module with no incoming edges, push it into the queue
+ // to seed the queue.
+ SmallVector<Module *, 4> Queue;
+ Queue.reserve(N);
+ llvm::DenseMap<Module *, unsigned> UnusedIncomingEdges;
+ for (ModuleIterator M = begin(), MEnd = end(); M != MEnd; ++M) {
+ if (unsigned Size = (*M)->ImportedBy.size())
+ UnusedIncomingEdges[*M] = Size;
+ else
+ Queue.push_back(*M);
+ }
+
+ llvm::SmallPtrSet<Module *, 4> Skipped;
+ unsigned QueueStart = 0;
+ while (QueueStart < Queue.size()) {
+ Module *CurrentModule = Queue[QueueStart++];
+
+ // Check whether this module should be skipped.
+ if (Skipped.count(CurrentModule))
+ continue;
+
+ if (Visitor(*CurrentModule, UserData)) {
+ // The visitor has requested that cut off visitation of any
+ // module that the current module depends on. To indicate this
+ // behavior, we mark all of the reachable modules as having N
+ // incoming edges (which is impossible otherwise).
+ SmallVector<Module *, 4> Stack;
+ Stack.push_back(CurrentModule);
+ Skipped.insert(CurrentModule);
+ while (!Stack.empty()) {
+ Module *NextModule = Stack.back();
+ Stack.pop_back();
+
+ // For any module that this module depends on, push it on the
+ // stack (if it hasn't already been marked as visited).
+ for (llvm::SetVector<Module *>::iterator
+ M = NextModule->Imports.begin(),
+ MEnd = NextModule->Imports.end();
+ M != MEnd; ++M) {
+ if (Skipped.insert(*M))
+ Stack.push_back(*M);
+ }
+ }
+ continue;
+ }
+
+ // For any module that this module depends on, push it on the
+ // stack (if it hasn't already been marked as visited).
+ for (llvm::SetVector<Module *>::iterator M = CurrentModule->Imports.begin(),
+ MEnd = CurrentModule->Imports.end();
+ M != MEnd; ++M) {
+
+ // Remove our current module as an impediment to visiting the
+ // module we depend on. If we were the last unvisited module
+ // that depends on this particular module, push it into the
+ // queue to be visited.
+ unsigned &NumUnusedEdges = UnusedIncomingEdges[*M];
+ if (NumUnusedEdges && (--NumUnusedEdges == 0))
+ Queue.push_back(*M);
+ }
+ }
+}
+
+/// \brief Perform a depth-first visit of the current module.
+static bool visitDepthFirst(Module &M,
+ bool (*Visitor)(Module &M, bool Preorder,
+ void *UserData),
+ void *UserData,
+ llvm::SmallPtrSet<Module *, 4> &Visited) {
+ // Preorder visitation
+ if (Visitor(M, /*Preorder=*/true, UserData))
+ return true;
+
+ // Visit children
+ for (llvm::SetVector<Module *>::iterator IM = M.Imports.begin(),
+ IMEnd = M.Imports.end();
+ IM != IMEnd; ++IM) {
+ if (!Visited.insert(*IM))
+ continue;
+
+ if (visitDepthFirst(**IM, Visitor, UserData, Visited))
+ return true;
+ }
+
+ // Postorder visitation
+ return Visitor(M, /*Preorder=*/false, UserData);
+}
+
+void ModuleManager::visitDepthFirst(bool (*Visitor)(Module &M, bool Preorder,
+ void *UserData),
+ void *UserData) {
+ llvm::SmallPtrSet<Module *, 4> Visited;
+ for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+ if (!Visited.insert(Chain[I]))
+ continue;
+
+ if (::visitDepthFirst(*Chain[I], Visitor, UserData, Visited))
+ return;
+ }
+}
More information about the cfe-commits
mailing list