diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:02:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:02:28 +0000 |
commit | 7442d6faa2719e4e7d33a7021c406c5a4facd74d (patch) | |
tree | c72b9241553fc9966179aba84f90f17bfa9235c3 /include/clang/Serialization | |
parent | b52119637f743680a99710ce5fdb6646da2772af (diff) |
Notes
Diffstat (limited to 'include/clang/Serialization')
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 53 | ||||
-rw-r--r-- | include/clang/Serialization/ASTDeserializationListener.h | 4 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 98 | ||||
-rw-r--r-- | include/clang/Serialization/ASTWriter.h | 36 | ||||
-rw-r--r-- | include/clang/Serialization/Module.h | 114 | ||||
-rw-r--r-- | include/clang/Serialization/ModuleManager.h | 34 |
6 files changed, 232 insertions, 107 deletions
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index acbd6d1deb5b3..823440b197137 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -226,7 +226,7 @@ namespace clang { /// \brief The block containing the detailed preprocessing record. PREPROCESSOR_DETAIL_BLOCK_ID, - + /// \brief The block containing the submodule structure. SUBMODULE_BLOCK_ID, @@ -253,6 +253,12 @@ namespace clang { /// \brief A block containing a module file extension. EXTENSION_BLOCK_ID, + + /// A block with unhashed content. + /// + /// These records should not change the \a ASTFileSignature. See \a + /// UnhashedControlBlockRecordTypes for the list of records. + UNHASHED_CONTROL_BLOCK_ID, }; /// \brief Record types that occur within the control block. @@ -288,9 +294,6 @@ namespace clang { /// AST file. MODULE_MAP_FILE, - /// \brief Record code for the signature that identifiers this AST file. - SIGNATURE, - /// \brief Record code for the module build directory. MODULE_DIRECTORY, }; @@ -309,9 +312,6 @@ namespace clang { /// \brief Record code for the target options table. TARGET_OPTIONS, - /// \brief Record code for the diagnostic options table. - DIAGNOSTIC_OPTIONS, - /// \brief Record code for the filesystem options table. FILE_SYSTEM_OPTIONS, @@ -322,6 +322,18 @@ namespace clang { PREPROCESSOR_OPTIONS, }; + /// Record codes for the unhashed control block. + enum UnhashedControlBlockRecordTypes { + /// Record code for the signature that identifiers this AST file. + SIGNATURE = 1, + + /// Record code for the diagnostic options table. + DIAGNOSTIC_OPTIONS, + + /// Record code for \#pragma diagnostic mappings. + DIAG_PRAGMA_MAPPINGS, + }; + /// \brief Record code for extension blocks. enum ExtensionBlockRecordTypes { /// Metadata describing this particular extension. @@ -493,8 +505,7 @@ namespace clang { // ID 31 used to be a list of offsets to DECL_CXX_BASE_SPECIFIERS records. - /// \brief Record code for \#pragma diagnostic mappings. - DIAG_PRAGMA_MAPPINGS = 32, + // ID 32 used to be the code for \#pragma diagnostic mappings. /// \brief Record code for special CUDA declarations. CUDA_SPECIAL_DECL_REFS = 33, @@ -591,6 +602,11 @@ namespace clang { /// \brief Record code for declarations associated with OpenCL extensions. OPENCL_EXTENSION_DECLS = 59, + + MODULAR_CODEGEN_DECLS = 60, + + /// \brief Record code for \#pragma pack options. + PACK_PRAGMA_OPTIONS = 61, }; /// \brief Record types used within a source manager block. @@ -801,14 +817,12 @@ namespace clang { PREDEF_TYPE_SAMPLER_ID = 39, /// \brief OpenCL queue type. PREDEF_TYPE_QUEUE_ID = 40, - /// \brief OpenCL ndrange type. - PREDEF_TYPE_NDRANGE_ID = 41, /// \brief OpenCL reserve_id type. - PREDEF_TYPE_RESERVE_ID_ID = 42, + PREDEF_TYPE_RESERVE_ID_ID = 41, /// \brief The placeholder type for OpenMP array section. - PREDEF_TYPE_OMP_ARRAY_SECTION = 43, + PREDEF_TYPE_OMP_ARRAY_SECTION = 42, /// \brief The '__float128' type - PREDEF_TYPE_FLOAT128_ID = 44, + PREDEF_TYPE_FLOAT128_ID = 43, /// \brief OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, @@ -914,7 +928,11 @@ namespace clang { /// \brief A PipeType record. TYPE_PIPE = 43, /// \brief An ObjCTypeParamType record. - TYPE_OBJC_TYPE_PARAM = 44 + TYPE_OBJC_TYPE_PARAM = 44, + /// \brief A DeducedTemplateSpecializationType record. + TYPE_DEDUCED_TEMPLATE_SPECIALIZATION = 45, + /// \brief A DependentSizedExtVectorType record. + TYPE_DEPENDENT_SIZED_EXT_VECTOR = 46 }; /// \brief The type IDs for special types constructed by semantic @@ -1121,6 +1139,8 @@ namespace clang { DECL_EXPORT, /// \brief A CXXRecordDecl record. DECL_CXX_RECORD, + /// \brief A CXXDeductionGuideDecl record. + DECL_CXX_DEDUCTION_GUIDE, /// \brief A CXXMethodDecl record. DECL_CXX_METHOD, /// \brief A CXXConstructorDecl record. @@ -1624,7 +1644,8 @@ namespace clang { IdentifierInfo *getIdentifier() const { assert(Kind == DeclarationName::Identifier || - Kind == DeclarationName::CXXLiteralOperatorName); + Kind == DeclarationName::CXXLiteralOperatorName || + Kind == DeclarationName::CXXDeductionGuideName); return (IdentifierInfo *)Data; } Selector getSelector() const { diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h index 4b10c39d8fb22..c26f3e0b425e4 100644 --- a/include/clang/Serialization/ASTDeserializationListener.h +++ b/include/clang/Serialization/ASTDeserializationListener.h @@ -26,6 +26,7 @@ class QualType; class MacroDefinitionRecord; class MacroInfo; class Module; +class SourceLocation; class ASTDeserializationListener { public: @@ -52,6 +53,9 @@ public: MacroDefinitionRecord *MD) {} /// \brief A module definition was read from the AST file. virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) {} + /// \brief A module import was read from the AST file. + virtual void ModuleImportRead(serialization::SubmoduleID ID, + SourceLocation ImportLoc) {} }; } diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 93994e2c519c7..63ccb24616165 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -408,6 +408,9 @@ private: /// \brief The module manager which manages modules and their dependencies ModuleManager ModuleMgr; + /// The cache that manages memory buffers for PCM files. + MemoryBufferCache &PCMCache; + /// \brief A dummy identifier resolver used to merge TU-scope declarations in /// C, for the cases where we don't have a Sema object to provide a real /// identifier resolver. @@ -700,7 +703,7 @@ private: /// \brief Mapping from global preprocessing entity IDs to the module in /// which the preprocessed entity resides along with the offset that should be - /// added to the global preprocessing entitiy ID to produce a local ID. + /// added to the global preprocessing entity ID to produce a local ID. GlobalPreprocessedEntityMapType GlobalPreprocessedEntityMap; /// \name CodeGen-relevant special data @@ -808,6 +811,17 @@ private: int PragmaMSPointersToMembersState = -1; SourceLocation PointersToMembersPragmaLocation; + /// \brief The pragma pack state. + Optional<unsigned> PragmaPackCurrentValue; + SourceLocation PragmaPackCurrentLocation; + struct PragmaPackStackEntry { + unsigned Value; + SourceLocation Location; + StringRef SlotLabel; + }; + llvm::SmallVector<PragmaPackStackEntry, 2> PragmaPackStack; + llvm::SmallVector<std::string, 2> PragmaPackStrings; + /// \brief The OpenCL extension settings. OpenCLOptions OpenCLExtensions; @@ -970,14 +984,26 @@ private: /// \brief The generation number of each identifier, which keeps track of /// the last time we loaded information about this identifier. llvm::DenseMap<IdentifierInfo *, unsigned> IdentifierGeneration; - - /// \brief Contains declarations and definitions that will be + + class InterestingDecl { + Decl *D; + bool DeclHasPendingBody; + + public: + InterestingDecl(Decl *D, bool HasBody) + : D(D), DeclHasPendingBody(HasBody) {} + Decl *getDecl() { return D; } + /// Whether the declaration has a pending body. + bool hasPendingBody() { return DeclHasPendingBody; } + }; + + /// \brief Contains declarations and definitions that could be /// "interesting" to the ASTConsumer, when we get that AST consumer. /// /// "Interesting" declarations are those that have data that may /// need to be emitted, such as inline function definitions or /// Objective-C protocols. - std::deque<Decl *> InterestingDecls; + std::deque<InterestingDecl> PotentiallyInterestingDecls; /// \brief The list of redeclaration chains that still need to be /// reconstructed, and the local offset to the corresponding list @@ -1101,6 +1127,8 @@ private: /// predefines buffer may contain additional definitions. std::string SuggestedPredefines; + llvm::DenseMap<const Decl *, bool> BodySource; + /// \brief Reads a statement from the specified cursor. Stmt *ReadStmtFromStream(ModuleFile &F); @@ -1174,7 +1202,7 @@ private: SourceLocation ImportLoc, ModuleFile *ImportedBy, SmallVectorImpl<ImportedModule> &Loaded, off_t ExpectedSize, time_t ExpectedModTime, - serialization::ASTFileSignature ExpectedSignature, + ASTFileSignature ExpectedSignature, unsigned ClientLoadCapabilities); ASTReadResult ReadControlBlock(ModuleFile &F, SmallVectorImpl<ImportedModule> &Loaded, @@ -1183,9 +1211,25 @@ private: static ASTReadResult ReadOptionsBlock( llvm::BitstreamCursor &Stream, unsigned ClientLoadCapabilities, bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener, - std::string &SuggestedPredefines, bool ValidateDiagnosticOptions); + std::string &SuggestedPredefines); + + /// Read the unhashed control block. + /// + /// This has no effect on \c F.Stream, instead creating a fresh cursor from + /// \c F.Data and reading ahead. + ASTReadResult readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy, + unsigned ClientLoadCapabilities); + + static ASTReadResult + readUnhashedControlBlockImpl(ModuleFile *F, llvm::StringRef StreamData, + unsigned ClientLoadCapabilities, + bool AllowCompatibleConfigurationMismatch, + ASTReaderListener *Listener, + bool ValidateDiagnosticOptions); + ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities); ASTReadResult ReadExtensionBlock(ModuleFile &F); + void ReadModuleOffsetMap(ModuleFile &F) const; bool ParseLineTable(ModuleFile &F, const RecordData &Record); bool ReadSourceManagerBlock(ModuleFile &F); llvm::BitstreamCursor &SLocCursorForID(int ID); @@ -1268,6 +1312,7 @@ private: llvm::iterator_range<PreprocessingRecord::iterator> getModulePreprocessedEntities(ModuleFile &Mod) const; +public: class ModuleDeclIterator : public llvm::iterator_adaptor_base< ModuleDeclIterator, const serialization::LocalDeclID *, @@ -1298,6 +1343,7 @@ private: llvm::iterator_range<ModuleDeclIterator> getModuleFileLevelDecls(ModuleFile &Mod); +private: void PassInterestingDeclsToConsumer(); void PassInterestingDeclToConsumer(Decl *D); @@ -1318,9 +1364,9 @@ private: /// /// This routine should only be used for fatal errors that have to /// do with non-routine failures (e.g., corrupted AST file). - void Error(StringRef Msg); + void Error(StringRef Msg) const; void Error(unsigned DiagID, StringRef Arg1 = StringRef(), - StringRef Arg2 = StringRef()); + StringRef Arg2 = StringRef()) const; ASTReader(const ASTReader &) = delete; void operator=(const ASTReader &) = delete; @@ -1564,7 +1610,7 @@ public: const LangOptions &LangOpts, const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts, - std::string ExistingModuleCachePath); + StringRef ExistingModuleCachePath); /// \brief Returns the suggested contents of the predefines buffer, /// which contains a (typically-empty) subset of the predefines @@ -1631,11 +1677,8 @@ public: /// reader. unsigned getTotalNumPreprocessedEntities() const { unsigned Result = 0; - for (ModuleConstIterator I = ModuleMgr.begin(), - E = ModuleMgr.end(); I != E; ++I) { - Result += (*I)->NumPreprocessedEntities; - } - + for (const auto &M : ModuleMgr) + Result += M.NumPreprocessedEntities; return Result; } @@ -1904,10 +1947,10 @@ public: SmallVectorImpl<Decl *> *Decls = nullptr); /// \brief Report a diagnostic. - DiagnosticBuilder Diag(unsigned DiagID); + DiagnosticBuilder Diag(unsigned DiagID) const; /// \brief Report a diagnostic. - DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID); + DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const; IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID); @@ -1968,6 +2011,8 @@ public: /// \brief Return a descriptor for the corresponding module. llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override; + ExtKind hasExternalDefinitions(const Decl *D) override; + /// \brief Retrieve a selector from the given module with its local ID /// number. Selector getLocalSelector(ModuleFile &M, unsigned LocalID); @@ -2057,6 +2102,8 @@ public: /// location space into ours. SourceLocation TranslateSourceLocation(ModuleFile &ModuleFile, SourceLocation Loc) const { + if (!ModuleFile.ModuleOffsetMap.empty()) + ReadModuleOffsetMap(ModuleFile); assert(ModuleFile.SLocRemap.find(Loc.getOffset()) != ModuleFile.SLocRemap.end() && "Cannot find offset to remap."); @@ -2098,8 +2145,7 @@ public: unsigned &Idx); /// \brief Reads attributes from the current stream position. - void ReadAttributes(ModuleFile &F, AttrVec &Attrs, - const RecordData &Record, unsigned &Idx); + void ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs); /// \brief Reads a statement. Stmt *ReadStmt(ModuleFile &F); @@ -2189,6 +2235,12 @@ public: /// \brief Loads comments ranges. void ReadComments() override; + /// Visit all the input files of the given module file. + void visitInputFiles(serialization::ModuleFile &MF, + bool IncludeSystem, bool Complain, + llvm::function_ref<void(const serialization::InputFile &IF, + bool isSystem)> Visitor); + bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; } }; @@ -2284,6 +2336,14 @@ public: /// \brief Reads a sub-expression operand during statement reading. Expr *readSubExpr() { return Reader->ReadSubExpr(); } + /// \brief Reads a declaration with the given local ID in the given module. + /// + /// \returns The requested declaration, casted to the given return type. + template<typename T> + T *GetLocalDeclAs(uint32_t LocalID) { + return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID)); + } + /// \brief Reads a TemplateArgumentLocInfo appropriate for the /// given TemplateArgument kind, advancing Idx. TemplateArgumentLocInfo @@ -2455,7 +2515,7 @@ public: /// \brief Reads attributes from the current stream position, advancing Idx. void readAttributes(AttrVec &Attrs) { - return Reader->ReadAttributes(*F, Attrs, Record, Idx); + return Reader->ReadAttributes(*this, Attrs); } /// \brief Reads a token out of a record, advancing Idx. diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 0d6b0268109dc..17cf726e4d6bb 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -54,6 +54,7 @@ class MacroInfo; class OpaqueValueExpr; class OpenCLOptions; class ASTReader; +class MemoryBufferCache; class Module; class ModuleFileExtension; class ModuleFileExtensionWriter; @@ -106,6 +107,12 @@ private: /// \brief The bitstream writer used to emit this precompiled header. llvm::BitstreamWriter &Stream; + /// The buffer associated with the bitstream. + const SmallVectorImpl<char> &Buffer; + + /// \brief The PCM manager which manages memory buffers for pcm files. + MemoryBufferCache &PCMCache; + /// \brief The ASTContext we're writing. ASTContext *Context = nullptr; @@ -365,6 +372,7 @@ private: /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS /// record. SmallVector<uint64_t, 16> EagerlyDeserializedDecls; + SmallVector<uint64_t, 16> ModularCodegenDecls; /// \brief DeclContexts that have received extensions since their serialized /// form. @@ -424,8 +432,16 @@ private: void WriteSubStmt(Stmt *S); void WriteBlockInfoBlock(); - uint64_t WriteControlBlock(Preprocessor &PP, ASTContext &Context, - StringRef isysroot, const std::string &OutputFile); + void WriteControlBlock(Preprocessor &PP, ASTContext &Context, + StringRef isysroot, const std::string &OutputFile); + + /// Write out the signature and diagnostic options, and return the signature. + ASTFileSignature writeUnhashedControlBlock(Preprocessor &PP, + ASTContext &Context); + + /// Calculate hash of the pcm content. + static ASTFileSignature createSignature(StringRef Bytes); + void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts, bool Modules); void WriteSourceManagerBlock(SourceManager &SourceMgr, @@ -469,6 +485,7 @@ private: void WriteOptimizePragmaOptions(Sema &SemaRef); void WriteMSStructPragmaOptions(Sema &SemaRef); void WriteMSPointersToMembersPragmaOptions(Sema &SemaRef); + void WritePackPragmaOptions(Sema &SemaRef); void WriteModuleFileExtension(Sema &SemaRef, ModuleFileExtensionWriter &Writer); @@ -492,14 +509,15 @@ private: void WriteDeclAbbrevs(); void WriteDecl(ASTContext &Context, Decl *D); - uint64_t WriteASTCore(Sema &SemaRef, - StringRef isysroot, const std::string &OutputFile, - Module *WritingModule); + ASTFileSignature WriteASTCore(Sema &SemaRef, StringRef isysroot, + const std::string &OutputFile, + Module *WritingModule); public: /// \brief Create a new precompiled header writer that outputs to /// the given bitstream. - ASTWriter(llvm::BitstreamWriter &Stream, + ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer, + MemoryBufferCache &PCMCache, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, bool IncludeTimestamps = true); ~ASTWriter() override; @@ -525,9 +543,9 @@ public: /// /// \return the module signature, which eventually will be a hash of /// the module but currently is merely a random 32-bit number. - uint64_t WriteAST(Sema &SemaRef, const std::string &OutputFile, - Module *WritingModule, StringRef isysroot, - bool hasErrors = false); + ASTFileSignature WriteAST(Sema &SemaRef, const std::string &OutputFile, + Module *WritingModule, StringRef isysroot, + bool hasErrors = false); /// \brief Emit a token. void AddToken(const Token &Tok, RecordDataImpl &Record); diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h index 58b3149d407e7..4e4bf44f34920 100644 --- a/include/clang/Serialization/Module.h +++ b/include/clang/Serialization/Module.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_SERIALIZATION_MODULE_H #include "clang/Basic/FileManager.h" +#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ContinuousRangeMap.h" @@ -89,8 +90,6 @@ public: bool isNotFound() const { return Val.getInt() == NotFound; } }; -typedef unsigned ASTFileSignature; - /// \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 @@ -100,13 +99,14 @@ typedef unsigned ASTFileSignature; /// other modules. class ModuleFile { public: - ModuleFile(ModuleKind Kind, unsigned Generation); + ModuleFile(ModuleKind Kind, unsigned Generation) + : Kind(Kind), Generation(Generation) {} ~ModuleFile(); // === General information === /// \brief The index of this module in the list of modules. - unsigned Index; + unsigned Index = 0; /// \brief The type of this module. ModuleKind Kind; @@ -144,34 +144,34 @@ public: std::string ModuleMapPath; /// \brief Whether this precompiled header is a relocatable PCH file. - bool RelocatablePCH; + bool RelocatablePCH = false; /// \brief Whether timestamps are included in this module file. - bool HasTimestamps; + bool HasTimestamps = false; /// \brief The file entry for the module file. - const FileEntry *File; + const FileEntry *File = nullptr; - /// \brief The signature of the module file, which may be used along with size + /// The signature of the module file, which may be used instead of the size /// and modification time to identify this particular file. ASTFileSignature Signature; /// \brief Whether this module has been directly imported by the /// user. - bool DirectlyImported; + bool DirectlyImported = false; /// \brief The generation of which this module file is a part. unsigned Generation; - /// \brief The memory buffer that stores the data associated with - /// this AST file. - std::unique_ptr<llvm::MemoryBuffer> Buffer; + /// The memory buffer that stores the data associated with + /// this AST file, owned by the PCMCache in the ModuleManager. + llvm::MemoryBuffer *Buffer; /// \brief The size of this file, in bits. - uint64_t SizeInBits; + uint64_t SizeInBits = 0; /// \brief The global bit offset (or base) of this module - uint64_t GlobalBitOffset; + uint64_t GlobalBitOffset = 0; /// \brief The serialized bitstream data for this file. StringRef Data; @@ -200,21 +200,29 @@ public: /// file. std::vector<std::unique_ptr<ModuleFileExtensionReader>> ExtensionReaders; + /// The module offset map data for this file. If non-empty, the various + /// ContinuousRangeMaps described below have not yet been populated. + StringRef ModuleOffsetMap; + // === Input Files === /// \brief The cursor to the start of the input-files block. llvm::BitstreamCursor InputFilesCursor; /// \brief Offsets for all of the input file entries in the AST file. - const llvm::support::unaligned_uint64_t *InputFileOffsets; + const llvm::support::unaligned_uint64_t *InputFileOffsets = nullptr; /// \brief The input files that have been loaded from this AST file. std::vector<InputFile> InputFilesLoaded; + // All user input files reside at the index range [0, NumUserInputFiles), and + // system input files reside at [NumUserInputFiles, InputFilesLoaded.size()). + unsigned NumUserInputFiles = 0; + /// \brief If non-zero, specifies the time when we last validated input /// files. Zero means we never validated them. /// /// The time is specified in seconds since the start of the Epoch. - uint64_t InputFilesValidationTimestamp; + uint64_t InputFilesValidationTimestamp = 0; // === Source Locations === @@ -222,17 +230,17 @@ public: llvm::BitstreamCursor SLocEntryCursor; /// \brief The number of source location entries in this AST file. - unsigned LocalNumSLocEntries; + unsigned LocalNumSLocEntries = 0; /// \brief The base ID in the source manager's view of this module. - int SLocEntryBaseID; + int SLocEntryBaseID = 0; /// \brief The base offset in the source manager's view of this module. - unsigned SLocEntryBaseOffset; + unsigned SLocEntryBaseOffset = 0; /// \brief Offsets for all of the source location entries in the /// AST file. - const uint32_t *SLocEntryOffsets; + const uint32_t *SLocEntryOffsets = nullptr; /// \brief SLocEntries that we're going to preload. SmallVector<uint64_t, 4> PreloadSLocEntries; @@ -243,17 +251,17 @@ public: // === Identifiers === /// \brief The number of identifiers in this AST file. - unsigned LocalNumIdentifiers; + unsigned LocalNumIdentifiers = 0; /// \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; + const uint32_t *IdentifierOffsets = nullptr; /// \brief Base identifier ID for identifiers local to this module. - serialization::IdentID BaseIdentifierID; + serialization::IdentID BaseIdentifierID = 0; /// \brief Remapping table for identifier IDs in this module. ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap; @@ -262,11 +270,11 @@ public: /// /// This pointer points into a memory buffer, where the on-disk hash /// table for identifiers actually lives. - const char *IdentifierTableData; + const char *IdentifierTableData = nullptr; /// \brief A pointer to an on-disk hash table of opaque type /// IdentifierHashTable. - void *IdentifierLookupTable; + void *IdentifierLookupTable = nullptr; /// \brief Offsets of identifiers that we're going to preload within /// IdentifierTableData. @@ -279,23 +287,23 @@ public: llvm::BitstreamCursor MacroCursor; /// \brief The number of macros in this AST file. - unsigned LocalNumMacros; + unsigned LocalNumMacros = 0; /// \brief Offsets of macros in the preprocessor block. /// /// This array is indexed by the macro ID (-1), and provides /// the offset into the preprocessor block where macro definitions are /// stored. - const uint32_t *MacroOffsets; + const uint32_t *MacroOffsets = nullptr; /// \brief Base macro ID for macros local to this module. - serialization::MacroID BaseMacroID; + serialization::MacroID BaseMacroID = 0; /// \brief Remapping table for macro IDs in this module. ContinuousRangeMap<uint32_t, int, 2> MacroRemap; /// \brief The offset of the start of the set of defined macros. - uint64_t MacroStartOffset; + uint64_t MacroStartOffset = 0; // === Detailed PreprocessingRecord === @@ -304,40 +312,40 @@ public: llvm::BitstreamCursor PreprocessorDetailCursor; /// \brief The offset of the start of the preprocessor detail cursor. - uint64_t PreprocessorDetailStartOffset; + uint64_t PreprocessorDetailStartOffset = 0; /// \brief Base preprocessed entity ID for preprocessed entities local to /// this module. - serialization::PreprocessedEntityID BasePreprocessedEntityID; + serialization::PreprocessedEntityID BasePreprocessedEntityID = 0; /// \brief Remapping table for preprocessed entity IDs in this module. ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap; - const PPEntityOffset *PreprocessedEntityOffsets; - unsigned NumPreprocessedEntities; + const PPEntityOffset *PreprocessedEntityOffsets = nullptr; + unsigned NumPreprocessedEntities = 0; // === Header search information === /// \brief The number of local HeaderFileInfo structures. - unsigned LocalNumHeaderFileInfos; + unsigned LocalNumHeaderFileInfos = 0; /// \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; + const char *HeaderFileInfoTableData = nullptr; /// \brief The on-disk hash table that contains information about each of /// the header files. - void *HeaderFileInfoTable; + void *HeaderFileInfoTable = nullptr; // === Submodule information === /// \brief The number of submodules in this module. - unsigned LocalNumSubmodules; + unsigned LocalNumSubmodules = 0; /// \brief Base submodule ID for submodules local to this module. - serialization::SubmoduleID BaseSubmoduleID; + serialization::SubmoduleID BaseSubmoduleID = 0; /// \brief Remapping table for submodule IDs in this module. ContinuousRangeMap<uint32_t, int, 2> SubmoduleRemap; @@ -347,14 +355,14 @@ public: /// \brief The number of selectors new to this file. /// /// This is the number of entries in SelectorOffsets. - unsigned LocalNumSelectors; + unsigned LocalNumSelectors = 0; /// \brief Offsets into the selector lookup table's data array /// where each selector resides. - const uint32_t *SelectorOffsets; + const uint32_t *SelectorOffsets = nullptr; /// \brief Base selector ID for selectors local to this module. - serialization::SelectorID BaseSelectorID; + serialization::SelectorID BaseSelectorID = 0; /// \brief Remapping table for selector IDs in this module. ContinuousRangeMap<uint32_t, int, 2> SelectorRemap; @@ -362,14 +370,14 @@ public: /// \brief A pointer to the character data that comprises the selector table /// /// The SelectorOffsets table refers into this memory. - const unsigned char *SelectorLookupTableData; + const unsigned char *SelectorLookupTableData = nullptr; /// \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; + void *SelectorLookupTable = nullptr; // === Declarations === @@ -379,14 +387,14 @@ public: llvm::BitstreamCursor DeclsCursor; /// \brief The number of declarations in this AST file. - unsigned LocalNumDecls; + unsigned LocalNumDecls = 0; /// \brief Offset of each declaration within the bitstream, indexed /// by the declaration ID (-1). - const DeclOffset *DeclOffsets; + const DeclOffset *DeclOffsets = nullptr; /// \brief Base declaration ID for declarations local to this module. - serialization::DeclID BaseDeclID; + serialization::DeclID BaseDeclID = 0; /// \brief Remapping table for declaration IDs in this module. ContinuousRangeMap<uint32_t, int, 2> DeclRemap; @@ -401,15 +409,15 @@ public: llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs; /// \brief Array of file-level DeclIDs sorted by file. - const serialization::DeclID *FileSortedDecls; - unsigned NumFileSortedDecls; + const serialization::DeclID *FileSortedDecls = nullptr; + unsigned NumFileSortedDecls = 0; /// \brief Array of category list location information within this /// module file, sorted by the definition ID. - const serialization::ObjCCategoriesInfo *ObjCCategoriesMap; + const serialization::ObjCCategoriesInfo *ObjCCategoriesMap = nullptr; /// \brief The number of redeclaration info entries in ObjCCategoriesMap. - unsigned LocalNumObjCCategoriesInMap; + unsigned LocalNumObjCCategoriesInMap = 0; /// \brief The Objective-C category lists for categories known to this /// module. @@ -418,15 +426,15 @@ public: // === Types === /// \brief The number of types in this AST file. - unsigned LocalNumTypes; + unsigned LocalNumTypes = 0; /// \brief Offset of each type within the bitstream, indexed by the /// type ID, or the representation of a Type*. - const uint32_t *TypeOffsets; + const uint32_t *TypeOffsets = nullptr; /// \brief Base type ID for types local to this module as represented in /// the global type ID space. - serialization::TypeID BaseTypeIndex; + serialization::TypeID BaseTypeIndex = 0; /// \brief Remapping table for type IDs in this module. ContinuousRangeMap<uint32_t, int, 2> TypeRemap; diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h index 1c4d88e979e3a..fae387cac7e21 100644 --- a/include/clang/Serialization/ModuleManager.h +++ b/include/clang/Serialization/ModuleManager.h @@ -19,10 +19,12 @@ #include "clang/Serialization/Module.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/iterator.h" namespace clang { class GlobalModuleIndex; +class MemoryBufferCache; class ModuleMap; class PCHContainerReader; @@ -32,7 +34,7 @@ namespace serialization { class ModuleManager { /// \brief The chain of AST files, in the order in which we started to load /// them (this order isn't really useful for anything). - SmallVector<ModuleFile *, 2> Chain; + SmallVector<std::unique_ptr<ModuleFile>, 2> Chain; /// \brief The chain of non-module PCH files. The first entry is the one named /// by the user, the last one is the one that doesn't depend on anything @@ -50,6 +52,9 @@ class ModuleManager { /// FileEntry *. FileManager &FileMgr; + /// Cache of PCM files. + IntrusiveRefCntPtr<MemoryBufferCache> PCMCache; + /// \brief Knows how to unwrap module containers. const PCHContainerReader &PCHContainerRdr; @@ -111,12 +116,18 @@ class ModuleManager { void returnVisitState(VisitState *State); public: - typedef SmallVectorImpl<ModuleFile*>::iterator ModuleIterator; - typedef SmallVectorImpl<ModuleFile*>::const_iterator ModuleConstIterator; - typedef SmallVectorImpl<ModuleFile*>::reverse_iterator ModuleReverseIterator; + typedef llvm::pointee_iterator< + SmallVectorImpl<std::unique_ptr<ModuleFile>>::iterator> + ModuleIterator; + typedef llvm::pointee_iterator< + SmallVectorImpl<std::unique_ptr<ModuleFile>>::const_iterator> + ModuleConstIterator; + typedef llvm::pointee_iterator< + SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator> + ModuleReverseIterator; typedef std::pair<uint32_t, StringRef> ModuleOffset; - explicit ModuleManager(FileManager &FileMgr, + explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache, const PCHContainerReader &PCHContainerRdr); ~ModuleManager(); @@ -136,7 +147,8 @@ public: ModuleReverseIterator rend() { return Chain.rend(); } /// \brief A range covering the PCH and preamble module files loaded. - llvm::iterator_range<ModuleConstIterator> pch_modules() const { + llvm::iterator_range<SmallVectorImpl<ModuleFile *>::const_iterator> + pch_modules() const { return llvm::make_range(PCHChain.begin(), PCHChain.end()); } @@ -152,10 +164,10 @@ public: ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; } /// \brief Returns the module associated with the given name - ModuleFile *lookup(StringRef Name); + ModuleFile *lookup(StringRef Name) const; /// \brief Returns the module associated with the given module file. - ModuleFile *lookup(const FileEntry *File); + ModuleFile *lookup(const FileEntry *File) const; /// \brief Returns the in-memory (virtual file) buffer with the given name std::unique_ptr<llvm::MemoryBuffer> lookupBuffer(StringRef Name); @@ -220,8 +232,8 @@ public: ModuleFile *&Module, std::string &ErrorStr); - /// \brief Remove the given set of modules. - void removeModules(ModuleIterator first, ModuleIterator last, + /// \brief Remove the modules starting from First (to the end). + void removeModules(ModuleIterator First, llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully, ModuleMap *modMap); @@ -282,6 +294,8 @@ public: /// \brief View the graphviz representation of the module graph. void viewGraph(); + + MemoryBufferCache &getPCMCache() const { return *PCMCache; } }; } } // end namespace clang::serialization |