diff options
Diffstat (limited to 'clang/lib/Serialization')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 97 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 32 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 121 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 6 |
4 files changed, 136 insertions, 120 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 05fa7cd1156..b24b35309a6 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -846,6 +846,54 @@ public: typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait> ASTDeclContextNameLookupTable; +bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor, + const std::pair<uint64_t, uint64_t> &Offsets, + DeclContextInfo &Info) { + SavedStreamPosition SavedPosition(Cursor); + // First the lexical decls. + if (Offsets.first != 0) { + Cursor.JumpToBit(Offsets.first); + + RecordData Record; + const char *Blob; + unsigned BlobLen; + unsigned Code = Cursor.ReadCode(); + unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen); + if (RecCode != DECL_CONTEXT_LEXICAL) { + Error("Expected lexical block"); + return true; + } + + Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob); + Info.NumLexicalDecls = BlobLen / sizeof(DeclID); + } else { + Info.LexicalDecls = 0; + Info.NumLexicalDecls = 0; + } + + // Now the lookup table. + if (Offsets.second != 0) { + Cursor.JumpToBit(Offsets.second); + + RecordData Record; + const char *Blob; + unsigned BlobLen; + unsigned Code = Cursor.ReadCode(); + unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen); + if (RecCode != DECL_CONTEXT_VISIBLE) { + Error("Expected visible lookup table block"); + return true; + } + Info.NameLookupTableData + = ASTDeclContextNameLookupTable::Create( + (const unsigned char *)Blob + Record[0], + (const unsigned char *)Blob, + ASTDeclContextNameLookupTrait(*this)); + } + + return false; +} + void ASTReader::Error(const char *Msg) { Diag(diag::err_fe_pch_malformed) << Msg; } @@ -1674,7 +1722,7 @@ ASTReader::ReadASTBlock(PerFileData &F) { case TU_UPDATE_LEXICAL: { DeclContextInfo Info = { - /* No visible information */ 0, 0, + /* No visible information */ 0, reinterpret_cast<const DeclID *>(BlobStart), BlobLen / sizeof(DeclID) }; @@ -3119,54 +3167,33 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) { assert(DC->hasExternalVisibleStorage() && "DeclContext has no visible decls in storage"); + if (!Name) + return DeclContext::lookup_result(DeclContext::lookup_iterator(0), + DeclContext::lookup_iterator(0)); - llvm::SmallVector<VisibleDeclaration, 64> Decls; + llvm::SmallVector<NamedDecl *, 64> 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) + if (!I->NameLookupTableData) 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); - - // 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 != DECL_CONTEXT_VISIBLE) { - Error("Expected visible block"); - return DeclContext::lookup_result(DeclContext::lookup_iterator(), - DeclContext::lookup_iterator()); - } - - if (Record.empty()) + ASTDeclContextNameLookupTable *LookupTable = + (ASTDeclContextNameLookupTable*)I->NameLookupTableData; + ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(Name); + if (Pos == LookupTable->end()) continue; - unsigned Idx = 0; - while (Idx < Record.size()) { - Decls.push_back(VisibleDeclaration()); - Decls.back().Name = ReadDeclarationName(Record, Idx); - - unsigned Size = Record[Idx++]; - llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations; - LoadedDecls.reserve(Size); - for (unsigned J = 0; J < Size; ++J) - LoadedDecls.push_back(Record[Idx++]); - } + ASTDeclContextNameLookupTrait::data_type Data = *Pos; + for (; Data.first != Data.second; ++Data.first) + Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first))); } ++NumVisibleDeclContextsRead; - SetExternalVisibleDecls(DC, Decls); + SetExternalVisibleDeclsForName(DC, Name, Decls); return const_cast<DeclContext*>(DC)->lookup(Name); } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 9094281cd4c..bc68e91e3ed 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1413,35 +1413,3 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { return D; } - -bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor, - const std::pair<uint64_t, uint64_t> &Offsets, - DeclContextInfo &Info) { - SavedStreamPosition SavedPosition(Cursor); - // First the lexical decls. - if (Offsets.first != 0) { - Cursor.JumpToBit(Offsets.first); - - RecordData Record; - const char *Blob; - unsigned BlobLen; - unsigned Code = Cursor.ReadCode(); - unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen); - if (RecCode != DECL_CONTEXT_LEXICAL) { - Error("Expected lexical block"); - return true; - } - - Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob); - Info.NumLexicalDecls = BlobLen / sizeof(DeclID); - } else { - Info.LexicalDecls = 0; - Info.NumLexicalDecls = 0; - } - - // Now the visible decls. - Info.Stream = &Cursor; - Info.OffsetToVisibleDecls = Offsets.second; - - return false; -} diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 94be24ad2c5..5deaf3d475d 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1466,59 +1466,6 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, return Offset; } -/// \brief Write the block containing all of the declaration IDs -/// visible from the given DeclContext. -/// -/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the -/// bistream, or 0 if no block was written. -uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, - DeclContext *DC) { - if (DC->getPrimaryContext() != DC) - return 0; - - // Since there is no name lookup into functions or methods, don't bother to - // build a visible-declarations table for these entities. - if (DC->isFunctionOrMethod()) - return 0; - - // If not in C++, we perform name lookup for the translation unit via the - // IdentifierInfo chains, don't bother to build a visible-declarations table. - // FIXME: In C++ we need the visible declarations in order to "see" the - // friend declarations, is there a way to do this without writing the table ? - if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus) - return 0; - - // Force the DeclContext to build a its name-lookup table. - DC->lookup(DeclarationName()); - - // Serialize the contents of the mapping used for lookup. Note that, - // although we have two very different code paths, the serialized - // representation is the same for both cases: a declaration name, - // followed by a size, followed by references to the visible - // declarations that have that name. - uint64_t Offset = Stream.GetCurrentBitNo(); - RecordData Record; - StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); - if (!Map) - return 0; - - for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); - D != DEnd; ++D) { - AddDeclarationName(D->first, Record); - DeclContext::lookup_result Result = D->second.getLookupResult(Context); - Record.push_back(Result.second - Result.first); - for (; Result.first != Result.second; ++Result.first) - AddDeclRef(*Result.first, Record); - } - - if (Record.size() == 0) - return 0; - - Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record); - ++NumVisibleDeclContexts; - return Offset; -} - void ASTWriter::WriteTypeDeclOffsets() { using namespace llvm; RecordData Record; @@ -2062,6 +2009,74 @@ public: }; } // end anonymous namespace +/// \brief Write the block containing all of the declaration IDs +/// visible from the given DeclContext. +/// +/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the +/// bistream, or 0 if no block was written. +uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, + DeclContext *DC) { + if (DC->getPrimaryContext() != DC) + return 0; + + // Since there is no name lookup into functions or methods, don't bother to + // build a visible-declarations table for these entities. + if (DC->isFunctionOrMethod()) + return 0; + + // If not in C++, we perform name lookup for the translation unit via the + // IdentifierInfo chains, don't bother to build a visible-declarations table. + // FIXME: In C++ we need the visible declarations in order to "see" the + // friend declarations, is there a way to do this without writing the table ? + if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus) + return 0; + + // Force the DeclContext to build a its name-lookup table. + DC->lookup(DeclarationName()); + + // Serialize the contents of the mapping used for lookup. Note that, + // although we have two very different code paths, the serialized + // representation is the same for both cases: a declaration name, + // followed by a size, followed by references to the visible + // declarations that have that name. + uint64_t Offset = Stream.GetCurrentBitNo(); + StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); + if (!Map || Map->empty()) + return 0; + + OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator; + ASTDeclContextNameLookupTrait Trait(*this); + + // Create the on-disk hash table representation. + for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); + D != DEnd; ++D) { + DeclarationName Name = D->first; + DeclContext::lookup_result Result = D->second.getLookupResult(); + Generator.insert(Name, Result, Trait); + } + + // Create the on-disk hash table in a buffer. + llvm::SmallString<4096> LookupTable; + uint32_t BucketOffset; + { + llvm::raw_svector_ostream Out(LookupTable); + // Make sure that no bucket is at offset 0 + clang::io::Emit32(Out, 0); + BucketOffset = Generator.Emit(Out, Trait); + } + + // Write the lookup table + RecordData Record; + Record.push_back(DECL_CONTEXT_VISIBLE); + Record.push_back(BucketOffset); + Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record, + LookupTable.str()); + + Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record); + ++NumVisibleDeclContexts; + return Offset; +} + //===----------------------------------------------------------------------===// // General Serialization Routines //===----------------------------------------------------------------------===// diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 016f4d3c738..a5d2ce21c21 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1086,6 +1086,12 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL)); Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); DeclContextLexicalAbbrev = Stream.EmitAbbrev(Abv); + + Abv = new BitCodeAbbrev(); + Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); + DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(Abv); } /// isRequiredDecl - Check if this is a "required" Decl, which must be seen by |