From 08aca902538a54614d7dd37a54f45e68171f1d74 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Thu, 5 Aug 2010 18:21:25 +0000 Subject: [PATCH] Write various C++-specific records to chained PCHs. Tests will come later. llvm-svn: 110357 --- clang/lib/Frontend/PCHReader.cpp | 29 ++++-------- clang/lib/Frontend/PCHWriter.cpp | 80 ++++++++++++++++++++++++++++++-- 2 files changed, 87 insertions(+), 22 deletions(-) diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 98b274d17517..ab8bd5957be8 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -1643,12 +1643,8 @@ PCHReader::ReadPCHBlock(PerFileData &F) { break; case pch::WEAK_UNDECLARED_IDENTIFIERS: - // Optimization for the first block. - if (WeakUndeclaredIdentifiers.empty()) - WeakUndeclaredIdentifiers.swap(Record); - else - WeakUndeclaredIdentifiers.insert(WeakUndeclaredIdentifiers.end(), - Record.begin(), Record.end()); + // Later blocks overwrite earlier ones. + WeakUndeclaredIdentifiers.swap(Record); break; case pch::LOCALLY_SCOPED_EXTERNAL_DECLS: @@ -1724,19 +1720,17 @@ PCHReader::ReadPCHBlock(PerFileData &F) { break; case pch::VTABLE_USES: - if (!VTableUses.empty()) { - Error("duplicate VTABLE_USES record in PCH file"); - return Failure; - } + // Later tables overwrite earlier ones. VTableUses.swap(Record); break; case pch::DYNAMIC_CLASSES: - if (!DynamicClasses.empty()) { - Error("duplicate DYNAMIC_CLASSES record in PCH file"); - return Failure; - } - DynamicClasses.swap(Record); + // Optimization for the first block. + if (DynamicClasses.empty()) + DynamicClasses.swap(Record); + else + DynamicClasses.insert(DynamicClasses.end(), + Record.begin(), Record.end()); break; case pch::PENDING_IMPLICIT_INSTANTIATIONS: @@ -1749,10 +1743,7 @@ PCHReader::ReadPCHBlock(PerFileData &F) { break; case pch::SEMA_DECL_REFS: - if (!SemaDeclRefs.empty()) { - Error("duplicate SEMA_DECL_REFS record in PCH file"); - return Failure; - } + // Later tables overwrite earlier ones. SemaDeclRefs.swap(Record); break; diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 86b2273ea6c0..4646f424b7c6 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -2207,7 +2207,7 @@ void PCHWriter::WritePCHCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, RecordData UnusedStaticFuncs; for (unsigned i=0, e = SemaRef.UnusedStaticFuncs.size(); i !=e; ++i) AddDeclRef(SemaRef.UnusedStaticFuncs[i], UnusedStaticFuncs); - + RecordData WeakUndeclaredIdentifiers; if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { WeakUndeclaredIdentifiers.push_back( @@ -2440,6 +2440,21 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, AddDeclRef(SemaRef.UnusedStaticFuncs[i], UnusedStaticFuncs); } + // We write the entire table, overwriting the tables from the chain. + RecordData WeakUndeclaredIdentifiers; + if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { + WeakUndeclaredIdentifiers.push_back( + SemaRef.WeakUndeclaredIdentifiers.size()); + for (llvm::DenseMap::iterator + I = SemaRef.WeakUndeclaredIdentifiers.begin(), + E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) { + AddIdentifierRef(I->first, WeakUndeclaredIdentifiers); + AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers); + AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers); + WeakUndeclaredIdentifiers.push_back(I->second.getUsed()); + } + } + // Build a record containing all of the locally-scoped external // declarations in this header file. Generally, this record will be // empty. @@ -2461,6 +2476,46 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls); } + // Build a record containing all of the VTable uses information. + // We write everything here, because it's too hard to determine whether + // a use is new to this part. + RecordData VTableUses; + if (!SemaRef.VTableUses.empty()) { + VTableUses.push_back(SemaRef.VTableUses.size()); + for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) { + AddDeclRef(SemaRef.VTableUses[I].first, VTableUses); + AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses); + VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]); + } + } + + // Build a record containing all of dynamic classes declarations. + RecordData DynamicClasses; + for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I) + if (SemaRef.DynamicClasses[I]->getPCHLevel() == 0) + AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses); + + // Build a record containing all of pending implicit instantiations. + RecordData PendingImplicitInstantiations; + for (std::deque::iterator + I = SemaRef.PendingImplicitInstantiations.begin(), + N = SemaRef.PendingImplicitInstantiations.end(); I != N; ++I) { + if (I->first->getPCHLevel() == 0) { + AddDeclRef(I->first, PendingImplicitInstantiations); + AddSourceLocation(I->second, PendingImplicitInstantiations); + } + } + assert(SemaRef.PendingLocalImplicitInstantiations.empty() && + "There are local ones at end of translation unit!"); + + // Build a record containing some declaration references. + // It's not worth the effort to avoid duplication here. + RecordData SemaDeclRefs; + if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) { + AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs); + AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs); + } + Stream.EnterSubblock(pch::DECLTYPES_BLOCK_ID, 3); WriteDeclsBlockAbbrevs(); while (!DeclTypesToEmit.empty()) { @@ -2504,6 +2559,11 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, if (!UnusedStaticFuncs.empty()) Stream.EmitRecord(pch::UNUSED_STATIC_FUNCS, UnusedStaticFuncs); + // Write the record containing weak undeclared identifiers. + if (!WeakUndeclaredIdentifiers.empty()) + Stream.EmitRecord(pch::WEAK_UNDECLARED_IDENTIFIERS, + WeakUndeclaredIdentifiers); + // Write the record containing locally-scoped external definitions. if (!LocallyScopedExternalDecls.empty()) Stream.EmitRecord(pch::LOCALLY_SCOPED_EXTERNAL_DECLS, @@ -2513,8 +2573,22 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, if (!ExtVectorDecls.empty()) Stream.EmitRecord(pch::EXT_VECTOR_DECLS, ExtVectorDecls); - // FIXME: Vtable uses - // FIXME: Dynamic classes declarations + // Write the record containing VTable uses information. + if (!VTableUses.empty()) + Stream.EmitRecord(pch::VTABLE_USES, VTableUses); + + // Write the record containing dynamic classes declarations. + if (!DynamicClasses.empty()) + Stream.EmitRecord(pch::DYNAMIC_CLASSES, DynamicClasses); + + // Write the record containing pending implicit instantiations. + if (!PendingImplicitInstantiations.empty()) + Stream.EmitRecord(pch::PENDING_IMPLICIT_INSTANTIATIONS, + PendingImplicitInstantiations); + + // Write the record containing declaration references of Sema. + if (!SemaDeclRefs.empty()) + Stream.EmitRecord(pch::SEMA_DECL_REFS, SemaDeclRefs); Record.clear(); Record.push_back(NumStatements);