summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Frontend/PCHReader.cpp29
-rw-r--r--clang/lib/Frontend/PCHWriter.cpp80
2 files changed, 87 insertions, 22 deletions
diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp
index 98b274d1751..ab8bd5957be 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 86b2273ea6c..4646f424b7c 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<IdentifierInfo*,Sema::WeakInfo>::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<Sema::PendingImplicitInstantiation>::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);
OpenPOWER on IntegriCloud