From: Sebastian Redl Date: Wed, 4 Aug 2010 17:20:04 +0000 (+0000) Subject: Store the IDs of selectors in the PCH file explicitly. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5d05007b7a7883159154e3f65f338a2542d53913;p=clang Store the IDs of selectors in the PCH file explicitly. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110219 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Frontend/PCHDeserializationListener.h b/include/clang/Frontend/PCHDeserializationListener.h index 52adda9f3f..a908687ffc 100644 --- a/include/clang/Frontend/PCHDeserializationListener.h +++ b/include/clang/Frontend/PCHDeserializationListener.h @@ -38,6 +38,8 @@ public: virtual void TypeRead(pch::TypeID ID, QualType T) = 0; /// \brief A decl was deserialized from the PCH. virtual void DeclRead(pch::DeclID ID, const Decl *D) = 0; + /// \brief A selector was read from the PCH. + virtual void SelectorRead(pch::SelectorID iD, Selector Sel) = 0; }; } diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h index 86ff026748..e22272e44f 100644 --- a/include/clang/Frontend/PCHWriter.h +++ b/include/clang/Frontend/PCHWriter.h @@ -178,9 +178,6 @@ private: /// table, indexed by the Selector ID (-1). std::vector SelectorOffsets; - /// \brief A vector of all Selectors (ordered by ID). - std::vector SelVector; - /// \brief Offsets of each of the macro identifiers into the /// bitstream. /// @@ -318,9 +315,11 @@ public: /// \brief Emit a CXXTemporary. void AddCXXTemporary(const CXXTemporary *Temp, RecordData &Record); + + /// \brief Get the unique number used to refer to the given selector. + pch::SelectorID getSelectorRef(Selector Sel); - /// \brief Get the unique number used to refer to the given - /// identifier. + /// \brief Get the unique number used to refer to the given identifier. pch::IdentID getIdentifierRef(const IdentifierInfo *II); /// \brief Retrieve the offset of the macro definition for the given @@ -434,6 +433,7 @@ public: void IdentifierRead(pch::IdentID ID, IdentifierInfo *II); void TypeRead(pch::TypeID ID, QualType T); void DeclRead(pch::DeclID ID, const Decl *D); + void SelectorRead(pch::SelectorID iD, Selector Sel); }; /// \brief AST and semantic-analysis consumer that generates a diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 7d3a25f367..ac817ac050 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -471,7 +471,10 @@ class PCHMethodPoolLookupTrait { PCHReader &Reader; public: - typedef std::pair data_type; + struct data_type { + pch::SelectorID ID; + ObjCMethodList Instance, Factory; + }; typedef Selector external_key_type; typedef external_key_type internal_key_type; @@ -527,20 +530,22 @@ public: data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) { using namespace clang::io; - unsigned NumInstanceMethods = ReadUnalignedLE16(d); - unsigned NumFactoryMethods = ReadUnalignedLE16(d); data_type Result; + Result.ID = ReadUnalignedLE32(d); + unsigned NumInstanceMethods = ReadUnalignedLE16(d); + unsigned NumFactoryMethods = ReadUnalignedLE16(d); + // Load instance methods ObjCMethodList *Prev = 0; for (unsigned I = 0; I != NumInstanceMethods; ++I) { ObjCMethodDecl *Method = cast(Reader.GetDecl(ReadUnalignedLE32(d))); - if (!Result.first.Method) { + if (!Result.Instance.Method) { // This is the first method, which is the easy case. - Result.first.Method = Method; - Prev = &Result.first; + Result.Instance.Method = Method; + Prev = &Result.Instance; continue; } @@ -555,10 +560,10 @@ public: for (unsigned I = 0; I != NumFactoryMethods; ++I) { ObjCMethodDecl *Method = cast(Reader.GetDecl(ReadUnalignedLE32(d))); - if (!Result.second.Method) { + if (!Result.Factory.Method) { // This is the first method, which is the easy case. - Result.second.Method = Method; - Prev = &Result.second; + Result.Factory.Method = Method; + Prev = &Result.Factory; continue; } @@ -3215,11 +3220,14 @@ PCHReader::ReadMethodPool(Selector Sel) { PCHMethodPoolLookupTable::iterator Pos = PoolTable->find(Sel); if (Pos == PoolTable->end()) { ++NumMethodPoolMisses; - return std::pair();; + return std::pair(); } ++NumMethodPoolSelectorsRead; - return *Pos; + PCHMethodPoolLookupTrait::data_type Data = *Pos; + if (DeserializationListener) + DeserializationListener->SelectorRead(Data.ID, Sel); + return std::make_pair(Data.Instance, Data.Factory); } void PCHReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) { diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 4517bf2073..3675186052 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -1562,7 +1562,10 @@ public: typedef Selector key_type; typedef key_type key_type_ref; - typedef std::pair data_type; + struct data_type { + pch::SelectorID ID; + ObjCMethodList Instance, Factory; + }; typedef const data_type& data_type_ref; explicit PCHMethodPoolTrait(PCHWriter &Writer) : Writer(Writer) { } @@ -1583,12 +1586,12 @@ public: data_type_ref Methods) { unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4); clang::io::Emit16(Out, KeyLen); - unsigned DataLen = 2 + 2; // 2 bytes for each of the method counts - for (const ObjCMethodList *Method = &Methods.first; Method; + unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts + for (const ObjCMethodList *Method = &Methods.Instance; Method; Method = Method->Next) if (Method->Method) DataLen += 4; - for (const ObjCMethodList *Method = &Methods.second; Method; + for (const ObjCMethodList *Method = &Methods.Factory; Method; Method = Method->Next) if (Method->Method) DataLen += 4; @@ -1612,25 +1615,26 @@ public: void EmitData(llvm::raw_ostream& Out, key_type_ref, data_type_ref Methods, unsigned DataLen) { uint64_t Start = Out.tell(); (void)Start; + clang::io::Emit32(Out, Methods.ID); unsigned NumInstanceMethods = 0; - for (const ObjCMethodList *Method = &Methods.first; Method; + for (const ObjCMethodList *Method = &Methods.Instance; Method; Method = Method->Next) if (Method->Method) ++NumInstanceMethods; unsigned NumFactoryMethods = 0; - for (const ObjCMethodList *Method = &Methods.second; Method; + for (const ObjCMethodList *Method = &Methods.Factory; Method; Method = Method->Next) if (Method->Method) ++NumFactoryMethods; clang::io::Emit16(Out, NumInstanceMethods); clang::io::Emit16(Out, NumFactoryMethods); - for (const ObjCMethodList *Method = &Methods.first; Method; + for (const ObjCMethodList *Method = &Methods.Instance; Method; Method = Method->Next) if (Method->Method) clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); - for (const ObjCMethodList *Method = &Methods.second; Method; + for (const ObjCMethodList *Method = &Methods.Factory; Method; Method = Method->Next) if (Method->Method) clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); @@ -1649,7 +1653,7 @@ void PCHWriter::WriteSelectors(Sema &SemaRef) { using namespace llvm; // Do we have to do anything at all? - if (SemaRef.MethodPool.empty() && SelVector.empty()) + if (SemaRef.MethodPool.empty() && SelectorIDs.empty()) return; // Create and write out the blob that contains selectors and the method pool. { @@ -1657,13 +1661,22 @@ void PCHWriter::WriteSelectors(Sema &SemaRef) { // Create the on-disk hash table representation. We walk through every // selector we've seen and look it up in the method pool. - SelectorOffsets.resize(SelVector.size()); - for (unsigned I = 0, N = SelVector.size(); I != N; ++I) { - Selector S = SelVector[I]; + SelectorOffsets.resize(SelectorIDs.size()); + for (llvm::DenseMap::iterator + I = SelectorIDs.begin(), E = SelectorIDs.end(); + I != E; ++I) { + Selector S = I->first; Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S); - Generator.insert(S, F != SemaRef.MethodPool.end() ? F->second : - std::make_pair(ObjCMethodList(), ObjCMethodList())); - + PCHMethodPoolTrait::data_type Data = { + I->second, + ObjCMethodList(), + ObjCMethodList() + }; + if (F != SemaRef.MethodPool.end()) { + Data.Instance = F->second.first; + Data.Factory = F->second.second; + } + Generator.insert(S, Data); } // Create the on-disk hash table in a buffer. @@ -1689,7 +1702,7 @@ void PCHWriter::WriteSelectors(Sema &SemaRef) { RecordData Record; Record.push_back(pch::METHOD_POOL); Record.push_back(BucketOffset); - Record.push_back(SelVector.size()); + Record.push_back(SelectorIDs.size()); Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str()); // Create a blob abbreviation for the selector table offsets. @@ -2497,17 +2510,19 @@ pch::IdentID PCHWriter::getMacroDefinitionID(MacroDefinition *MD) { } void PCHWriter::AddSelectorRef(const Selector SelRef, RecordData &Record) { - if (SelRef.getAsOpaquePtr() == 0) { - Record.push_back(0); - return; + Record.push_back(getSelectorRef(SelRef)); +} + +pch::SelectorID PCHWriter::getSelectorRef(Selector Sel) { + if (Sel.getAsOpaquePtr() == 0) { + return 0; } - pch::SelectorID &SID = SelectorIDs[SelRef]; + pch::SelectorID &SID = SelectorIDs[Sel]; if (SID == 0) { SID = SelectorIDs.size(); - SelVector.push_back(SelRef); } - Record.push_back(SID); + return SID; } void PCHWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordData &Record) { @@ -2875,3 +2890,7 @@ void PCHWriter::TypeRead(pch::TypeID ID, QualType T) { void PCHWriter::DeclRead(pch::DeclID ID, const Decl *D) { DeclIDs[D] = ID; } + +void PCHWriter::SelectorRead(pch::SelectorID ID, Selector S) { + SelectorIDs[S] = ID; +}