From: Sebastian Redl Date: Thu, 22 Jul 2010 17:01:13 +0000 (+0000) Subject: Allow loading declcontext information from any file in the chain. Properly write... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0fa7d0b15ea2a224bfe43ac745d411f915da87dd;p=clang Allow loading declcontext information from any file in the chain. Properly write source locations to dependent files. WIP git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109119 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index b88a1d2938..34712369e7 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -300,7 +300,14 @@ private: /// = I + 1 has already been loaded. std::vector DeclsLoaded; - typedef llvm::DenseMap > + /// \brief Information about the contents of a DeclContext. + struct DeclContextInfo { + llvm::BitstreamCursor *Stream; + uint64_t OffsetToLexicalDecls; + uint64_t OffsetToVisibleDecls; + }; + typedef llvm::SmallVector DeclContextInfos; + typedef llvm::DenseMap DeclContextOffsetsMap; /// \brief Offsets of the lexical and visible declarations for each @@ -644,6 +651,11 @@ public: /// \brief Read preprocessed entities into the virtual void ReadPreprocessedEntities(); + /// \brief Returns the number of source locations found in this file. + unsigned getTotalNumSLocs() const { + return TotalNumSLocEntries; + } + /// \brief Returns the number of types found in this file. unsigned getTotalNumTypes() const { return static_cast(TypesLoaded.size()); diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index c3dce5df9d..cc44c30072 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -1779,6 +1779,10 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) { for (unsigned J = 0, M = Chain.size(); J != M; ++J) { PCHIdentifierLookupTable *IdTable = (PCHIdentifierLookupTable *)Chain[J]->IdentifierLookupTable; + // Not all PCH files necessarily have identifier tables, only the useful + // ones. + if (!IdTable) + continue; for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) { IdentifierInfo *II = Identifiers[I]; // Look in the on-disk hash tables for an entry for this identifier @@ -2856,10 +2860,18 @@ Decl *PCHReader::GetDecl(pch::DeclID ID) { /// source each time it is called, and is meant to be used via a /// LazyOffsetPtr (which is used by Decls for the body of functions, etc). Stmt *PCHReader::GetExternalDeclStmt(uint64_t Offset) { - // Since we know tha this statement is part of a decl, make sure to use the - // decl cursor to read it. - Chain[0]->DeclsCursor.JumpToBit(Offset); - return ReadStmtFromStream(Chain[0]->DeclsCursor); + // Offset here is a global offset across the entire chain. + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + PerFileData &F = *Chain[N - I - 1]; + if (Offset < F.SizeInBits) { + // Since we know that this statement is part of a decl, make sure to use + // the decl cursor to read it. + F.DeclsCursor.JumpToBit(Offset); + return ReadStmtFromStream(F.DeclsCursor); + } + Offset -= F.SizeInBits; + } + llvm_unreachable("Broken chain"); } bool PCHReader::FindExternalLexicalDecls(const DeclContext *DC, @@ -2867,32 +2879,37 @@ bool PCHReader::FindExternalLexicalDecls(const DeclContext *DC, assert(DC->hasExternalLexicalStorage() && "DeclContext has no lexical decls in storage"); - uint64_t Offset = DeclContextOffsets[DC].first; - if (Offset == 0) { - Error("DeclContext has no lexical decls in storage"); - return true; - } + // There might be lexical decls in multiple parts of the chain, for the TU + // at least. + DeclContextInfos &Infos = DeclContextOffsets[DC]; + for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end(); + I != E; ++I) { + uint64_t Offset = I->OffsetToLexicalDecls; + // Offset can be 0 if this file only contains visible decls. + if (Offset == 0) + continue; + llvm::BitstreamCursor &DeclsCursor = *I->Stream; - llvm::BitstreamCursor &DeclsCursor = Chain[0]->DeclsCursor; + // Keep track of where we are in the stream, then jump back there + // after reading this context. + SavedStreamPosition SavedPosition(DeclsCursor); - // Keep track of where we are in the stream, then jump back there - // after reading this context. - SavedStreamPosition SavedPosition(DeclsCursor); + // Load the record containing all of the declarations lexically in + // this context. + DeclsCursor.JumpToBit(Offset); + RecordData Record; + unsigned Code = DeclsCursor.ReadCode(); + unsigned RecCode = DeclsCursor.ReadRecord(Code, Record); + if (RecCode != pch::DECL_CONTEXT_LEXICAL) { + Error("Expected lexical block"); + return true; + } - // Load the record containing all of the declarations lexically in - // this context. - DeclsCursor.JumpToBit(Offset); - RecordData Record; - unsigned Code = DeclsCursor.ReadCode(); - unsigned RecCode = DeclsCursor.ReadRecord(Code, Record); - if (RecCode != pch::DECL_CONTEXT_LEXICAL) { - Error("Expected lexical block"); - return true; + // Load all of the declaration IDs + for (RecordData::iterator J = Record.begin(), F = Record.end(); J != F; ++J) + Decls.push_back(GetDecl(*J)); } - // Load all of the declaration IDs - for (RecordData::iterator I = Record.begin(), E = Record.end(); I != E; ++I) - Decls.push_back(GetDecl(*I)); ++NumLexicalDeclContextsRead; return false; } @@ -2902,48 +2919,49 @@ PCHReader::FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) { assert(DC->hasExternalVisibleStorage() && "DeclContext has no visible decls in storage"); - uint64_t Offset = DeclContextOffsets[DC].second; - if (Offset == 0) { - Error("DeclContext has no visible decls in storage"); - return DeclContext::lookup_result(DeclContext::lookup_iterator(), - DeclContext::lookup_iterator()); - } - llvm::BitstreamCursor &DeclsCursor = Chain[0]->DeclsCursor; + llvm::SmallVector Decls; + // There might be lexical decls in multiple parts of the chain, for the TU + // and namespaces. + DeclContextInfos &Infos = DeclContextOffsets[DC]; + for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end(); + I != E; ++I) { + uint64_t Offset = I->OffsetToVisibleDecls; + if (Offset == 0) + continue; + + llvm::BitstreamCursor &DeclsCursor = *I->Stream; - // Keep track of where we are in the stream, then jump back there - // after reading this context. - SavedStreamPosition SavedPosition(DeclsCursor); + // Keep track of where we are in the stream, then jump back there + // after reading this context. + SavedStreamPosition SavedPosition(DeclsCursor); - // Load the record containing all of the declarations visible in - // this context. - DeclsCursor.JumpToBit(Offset); - RecordData Record; - unsigned Code = DeclsCursor.ReadCode(); - unsigned RecCode = DeclsCursor.ReadRecord(Code, Record); - if (RecCode != pch::DECL_CONTEXT_VISIBLE) { - Error("Expected visible block"); - return DeclContext::lookup_result(DeclContext::lookup_iterator(), - DeclContext::lookup_iterator()); - } + // Load the record containing all of the declarations visible in + // this context. + DeclsCursor.JumpToBit(Offset); + RecordData Record; + unsigned Code = DeclsCursor.ReadCode(); + unsigned RecCode = DeclsCursor.ReadRecord(Code, Record); + if (RecCode != pch::DECL_CONTEXT_VISIBLE) { + Error("Expected visible block"); + return DeclContext::lookup_result(DeclContext::lookup_iterator(), + DeclContext::lookup_iterator()); + } - llvm::SmallVector Decls; - if (Record.empty()) { - SetExternalVisibleDecls(DC, Decls); - return DeclContext::lookup_result(DeclContext::lookup_iterator(), - DeclContext::lookup_iterator()); - } + if (Record.empty()) + continue; - unsigned Idx = 0; - while (Idx < Record.size()) { - Decls.push_back(VisibleDeclaration()); - Decls.back().Name = ReadDeclarationName(Record, Idx); + unsigned Idx = 0; + while (Idx < Record.size()) { + Decls.push_back(VisibleDeclaration()); + Decls.back().Name = ReadDeclarationName(Record, Idx); - unsigned Size = Record[Idx++]; - llvm::SmallVector &LoadedDecls = Decls.back().Declarations; - LoadedDecls.reserve(Size); - for (unsigned I = 0; I < Size; ++I) - LoadedDecls.push_back(Record[Idx++]); + unsigned Size = Record[Idx++]; + llvm::SmallVector &LoadedDecls = Decls.back().Declarations; + LoadedDecls.reserve(Size); + for (unsigned J = 0; J < Size; ++J) + LoadedDecls.push_back(Record[Idx++]); + } } ++NumVisibleDeclContextsRead; @@ -3112,6 +3130,8 @@ IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) { for (unsigned I = 0, N = Chain.size(); I != N; ++I) { PCHIdentifierLookupTable *IdTable = (PCHIdentifierLookupTable *)Chain[N - I - 1]->IdentifierLookupTable; + if (!IdTable) + continue; std::pair Key(NameStart, NameEnd - NameStart); PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key); if (Pos == IdTable->end()) diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index d562d6f621..7297fefcb2 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -1497,7 +1497,12 @@ Decl *PCHReader::ReadDeclRecord(unsigned Index) { if (Offsets.first || Offsets.second) { DC->setHasExternalLexicalStorage(Offsets.first != 0); DC->setHasExternalVisibleStorage(Offsets.second != 0); - DeclContextOffsets[DC] = Offsets; + PCHReader::DeclContextInfo Info = { + Loc.first, + Offsets.first, + Offsets.second + }; + DeclContextOffsets[DC].push_back(Info); } } assert(Idx == Record.size()); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index d8ce4e3b6e..b97aecbd8c 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -1099,8 +1099,10 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // entry, which is always the same dummy entry. std::vector SLocEntryOffsets; RecordData PreloadSLocs; - SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1); - for (unsigned I = 1, N = SourceMgr.sloc_entry_size(); I != N; ++I) { + unsigned BaseSLocID = Chain ? Chain->getTotalNumSLocs() : 0; + SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1 - BaseSLocID); + for (unsigned I = BaseSLocID + 1, N = SourceMgr.sloc_entry_size(); + I != N; ++I) { // Get this source location entry. const SrcMgr::SLocEntry *SLoc = &SourceMgr.getSLocEntry(I); @@ -1157,7 +1159,7 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // FIXME: For now, preload all file source locations, so that // we get the appropriate File entries in the reader. This is // a temporary measure. - PreloadSLocs.push_back(SLocEntryOffsets.size()); + PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size()); } else { // The source location entry is a buffer. The blob associated // with this entry contains the contents of the buffer. @@ -1177,7 +1179,7 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Buffer->getBufferSize() + 1)); if (strcmp(Name, "") == 0) - PreloadSLocs.push_back(SLocEntryOffsets.size()); + PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size()); } } else { // The source location entry is an instantiation.