diff options
Diffstat (limited to 'clang/include/clang/Frontend/PCHReader.h')
-rw-r--r-- | clang/include/clang/Frontend/PCHReader.h | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/clang/include/clang/Frontend/PCHReader.h b/clang/include/clang/Frontend/PCHReader.h new file mode 100644 index 00000000000..1338d3c03b6 --- /dev/null +++ b/clang/include/clang/Frontend/PCHReader.h @@ -0,0 +1,169 @@ +//===--- PCHReader.h - Precompiled Headers Reader ---------------*- 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 PCHReader class, which reads a precompiled header. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_FRONTEND_PCH_READER_H +#define LLVM_CLANG_FRONTEND_PCH_READER_H + +#include "clang/AST/DeclarationName.h" +#include "clang/AST/ExternalASTSource.h" +#include "clang/AST/Type.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Support/DataTypes.h" +#include <string> +#include <utility> +#include <vector> + +namespace llvm { + class MemoryBuffer; +} + +namespace clang { + +class ASTContext; +class Decl; +class DeclContext; + +/// \brief Reads a precompiled head containing the contents of a +/// translation unit. +/// +/// The PCHReader class reads a bitstream (produced by the PCHWriter +/// class) containing the serialized representation of a given +/// abstract syntax tree and its supporting data structures. An +/// instance of the PCHReader can be attached to an ASTContext object, +/// which will provide access to the contents of the PCH file. +/// +/// The PCH reader provides lazy de-serialization of declarations, as +/// required when traversing the AST. Only those AST nodes that are +/// actually required will be de-serialized. +class PCHReader : public ExternalASTSource { + /// \brief The AST context into which we'll read the PCH file. + ASTContext &Context; + + /// \brief The bitstream reader from which we'll read the PCH file. + llvm::BitstreamReader Stream; + + /// \brief The memory buffer that stores the data associated with + /// this PCH file. + llvm::OwningPtr<llvm::MemoryBuffer> Buffer; + + /// \brief Offset of each type within the bitstream, indexed by the + /// type ID, or the representation of a Type*. + llvm::SmallVector<uint64_t, 16> TypeOffsets; + + /// \brief Whether the type with a given index has already been loaded. + /// + /// When the bit at a given index I is true, then TypeOffsets[I] is + /// the already-loaded Type*. Otherwise, TypeOffsets[I] is the + /// location of the type's record in the PCH file. + /// + /// FIXME: We can probably eliminate this, e.g., by bitmangling the + /// values in TypeOffsets. + std::vector<bool> TypeAlreadyLoaded; + + /// \brief Offset of each declaration within the bitstream, indexed + /// by the declaration ID. + llvm::SmallVector<uint64_t, 16> DeclOffsets; + + /// \brief Whether the declaration with a given index has already + /// been loaded. + /// + /// When the bit at the given index I is true, then DeclOffsets[I] + /// is the already-loaded Decl*. Otherwise, DeclOffsets[I] is the + /// location of the declaration's record in the PCH file. + /// + /// FIXME: We can probably eliminate this, e.g., by bitmangling the + /// values in DeclOffsets. + std::vector<bool> DeclAlreadyLoaded; + + typedef llvm::DenseMap<const DeclContext *, std::pair<uint64_t, uint64_t> > + DeclContextOffsetsMap; + + /// \brief Offsets of the lexical and visible declarations for each + /// DeclContext. + DeclContextOffsetsMap DeclContextOffsets; + + bool ReadPCHBlock(); + bool ReadTypeOffsets(); + bool ReadDeclOffsets(); + + QualType ReadTypeRecord(uint64_t Offset); + void LoadedDecl(unsigned Index, Decl *D); + Decl *ReadDeclRecord(uint64_t Offset, unsigned Index); + + PCHReader(const PCHReader&); // do not implement + PCHReader &operator=(const PCHReader &); // do not implement + +public: + typedef llvm::SmallVector<uint64_t, 64> RecordData; + + PCHReader(ASTContext &Context) : Context(Context), Buffer() { } + ~PCHReader(); + + bool ReadPCH(const std::string &FileName); + + /// \brief Resolve a type ID into a type, potentially building a new + /// type. + virtual QualType GetType(unsigned ID); + + /// \brief Resolve a declaration ID into a declaration, potentially + /// building a new declaration. + virtual Decl *GetDecl(unsigned ID); + + /// \brief Read all of the declarations lexically stored in a + /// declaration context. + /// + /// \param DC The declaration context whose declarations will be + /// read. + /// + /// \param Decls Vector that will contain the declarations loaded + /// from the external source. The caller is responsible for merging + /// these declarations with any declarations already stored in the + /// declaration context. + /// + /// \returns true if there was an error while reading the + /// declarations for this declaration context. + virtual bool ReadDeclsLexicallyInContext(DeclContext *DC, + llvm::SmallVectorImpl<unsigned> &Decls); + + /// \brief Read all of the declarations visible from a declaration + /// context. + /// + /// \param DC The declaration context whose visible declarations + /// will be read. + /// + /// \param Decls A vector of visible declaration structures, + /// providing the mapping from each name visible in the declaration + /// context to the declaration IDs of declarations with that name. + /// + /// \returns true if there was an error while reading the + /// declarations for this declaration context. + /// + /// FIXME: Using this intermediate data structure results in an + /// extraneous copying of the data. Could we pass in a reference to + /// the StoredDeclsMap instead? + virtual bool ReadDeclsVisibleInContext(DeclContext *DC, + llvm::SmallVectorImpl<VisibleDeclaration> & Decls); + + /// \brief Print some statistics about PCH usage. + virtual void PrintStats(); + + const IdentifierInfo *GetIdentifierInfo(const RecordData &Record, + unsigned &Idx); + DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx); +}; + +} // end namespace clang + +#endif |