summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-08-13 00:28:03 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-08-13 00:28:03 +0000
commite7c1fe6ab7c1d9d26abde49dcf52b8ccc53e914c (patch)
tree6a1fd774a5d288c39333ff6c209e3c3e5df12dcb /clang/lib/Frontend
parentf7f020bb2afe2943f2f351c5d5e91f5587aa7661 (diff)
downloadbcm5719-llvm-e7c1fe6ab7c1d9d26abde49dcf52b8ccc53e914c.tar.gz
bcm5719-llvm-e7c1fe6ab7c1d9d26abde49dcf52b8ccc53e914c.zip
Instead of modifying the ObjC AST to not modify existing declarations, teach chained PCH to overwrite declarations from earlier PCH files in dependent ones. Tell Sema to note when it changes AST nodes so that they have to be reserialized. Finally, the ObjCProtocolDecls created in forward decls, like the ObjCInterfaceDecls in @class forward decls, are not lexically part of the decl context; only the definition is.
llvm-svn: 110989
Diffstat (limited to 'clang/lib/Frontend')
-rw-r--r--clang/lib/Frontend/PCHReader.cpp11
-rw-r--r--clang/lib/Frontend/PCHReaderDecl.cpp10
-rw-r--r--clang/lib/Frontend/PCHWriter.cpp22
-rw-r--r--clang/lib/Frontend/PCHWriterDecl.cpp32
4 files changed, 60 insertions, 15 deletions
diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp
index 16afabbb7e4..e55605b2743 100644
--- a/clang/lib/Frontend/PCHReader.cpp
+++ b/clang/lib/Frontend/PCHReader.cpp
@@ -1774,6 +1774,17 @@ PCHReader::ReadPCHBlock(PerFileData &F) {
F.NumPreallocatedPreprocessingEntities = Record[0];
F.LocalNumMacroDefinitions = Record[1];
break;
+
+ case pch::DECL_REPLACEMENTS: {
+ if (Record.size() % 2 != 0) {
+ Error("invalid DECL_REPLACEMENTS block in PCH file");
+ return Failure;
+ }
+ for (unsigned I = 0, N = Record.size(); I != N; I += 2)
+ ReplacedDecls[static_cast<pch::DeclID>(Record[I])] =
+ std::make_pair(&F, Record[I+1]);
+ break;
+ }
}
First = false;
}
diff --git a/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp
index 212eaa1332c..aa5ce7aad6a 100644
--- a/clang/lib/Frontend/PCHReaderDecl.cpp
+++ b/clang/lib/Frontend/PCHReaderDecl.cpp
@@ -1307,7 +1307,13 @@ static bool isConsumerInterestedIn(Decl *D) {
}
/// \brief Get the correct cursor and offset for loading a type.
-PCHReader::RecordLocation PCHReader::DeclCursorForIndex(unsigned Index) {
+PCHReader::RecordLocation
+PCHReader::DeclCursorForIndex(unsigned Index, pch::DeclID ID) {
+ // See if there's an override.
+ DeclReplacementMap::iterator It = ReplacedDecls.find(ID);
+ if (It != ReplacedDecls.end())
+ return RecordLocation(&It->second.first->DeclsCursor, It->second.second);
+
PerFileData *F = 0;
for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
F = Chain[N - I - 1];
@@ -1321,7 +1327,7 @@ PCHReader::RecordLocation PCHReader::DeclCursorForIndex(unsigned Index) {
/// \brief Read the declaration at the given offset from the PCH file.
Decl *PCHReader::ReadDeclRecord(unsigned Index, pch::DeclID ID) {
- RecordLocation Loc = DeclCursorForIndex(Index);
+ RecordLocation Loc = DeclCursorForIndex(Index, ID);
llvm::BitstreamCursor &DeclsCursor = *Loc.first;
// Keep track of where we are in the stream, then jump back there
// after reading this declaration.
diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp
index d7da4fc41ce..a86bdb9278d 100644
--- a/clang/lib/Frontend/PCHWriter.cpp
+++ b/clang/lib/Frontend/PCHWriter.cpp
@@ -2414,6 +2414,8 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
I != E; ++I) {
if ((*I)->getPCHLevel() == 0)
NewGlobalDecls.push_back(GetDeclRef(*I));
+ else if ((*I)->isChangedSinceDeserialization())
+ (void)GetDeclRef(*I); // Make sure it's written, but don't record it.
}
// We also need to write a lexical updates block for the TU.
llvm::BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev();
@@ -2596,10 +2598,24 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
Record.push_back(NumMacros);
Record.push_back(NumLexicalDeclContexts);
Record.push_back(NumVisibleDeclContexts);
+ WriteDeclUpdateBlock();
Stream.EmitRecord(pch::STATISTICS, Record);
Stream.ExitBlock();
}
+void PCHWriter::WriteDeclUpdateBlock() {
+ if (ReplacedDecls.empty())
+ return;
+
+ RecordData Record;
+ for (llvm::SmallVector<std::pair<pch::DeclID, uint64_t>, 16>::iterator
+ I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) {
+ Record.push_back(I->first);
+ Record.push_back(I->second);
+ }
+ Stream.EmitRecord(pch::DECL_REPLACEMENTS, Record);
+}
+
void PCHWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) {
Record.push_back(Loc.getRawEncoding());
}
@@ -2817,6 +2833,12 @@ pch::DeclID PCHWriter::GetDeclRef(const Decl *D) {
// enqueue it in the list of declarations to emit.
ID = NextDeclID++;
DeclTypesToEmit.push(const_cast<Decl *>(D));
+ } else if (ID < FirstDeclID && D->isChangedSinceDeserialization()) {
+ // We don't add it to the replacement collection here, because we don't
+ // have the offset yet.
+ DeclTypesToEmit.push(const_cast<Decl *>(D));
+ // Reset the flag, so that we don't add this decl multiple times.
+ const_cast<Decl *>(D)->setChangedSinceDeserialization(false);
}
return ID;
diff --git a/clang/lib/Frontend/PCHWriterDecl.cpp b/clang/lib/Frontend/PCHWriterDecl.cpp
index 13e5239fe78..9893d254e9e 100644
--- a/clang/lib/Frontend/PCHWriterDecl.cpp
+++ b/clang/lib/Frontend/PCHWriterDecl.cpp
@@ -1126,18 +1126,24 @@ void PCHWriter::WriteDecl(ASTContext &Context, Decl *D) {
}
// Determine the ID for this declaration
- pch::DeclID &ID = DeclIDs[D];
- if (ID == 0)
- ID = NextDeclID++;
-
- unsigned Index = ID - FirstDeclID;
-
- // Record the offset for this declaration
- if (DeclOffsets.size() == Index)
- DeclOffsets.push_back(Stream.GetCurrentBitNo());
- else if (DeclOffsets.size() < Index) {
- DeclOffsets.resize(Index+1);
- DeclOffsets[Index] = Stream.GetCurrentBitNo();
+ pch::DeclID &IDR = DeclIDs[D];
+ if (IDR == 0)
+ IDR = NextDeclID++;
+ pch::DeclID ID = IDR;
+
+ if (ID < FirstDeclID) {
+ // We're replacing a decl in a previous file.
+ ReplacedDecls.push_back(std::make_pair(ID, Stream.GetCurrentBitNo()));
+ } else {
+ unsigned Index = ID - FirstDeclID;
+
+ // Record the offset for this declaration
+ if (DeclOffsets.size() == Index)
+ DeclOffsets.push_back(Stream.GetCurrentBitNo());
+ else if (DeclOffsets.size() < Index) {
+ DeclOffsets.resize(Index+1);
+ DeclOffsets[Index] = Stream.GetCurrentBitNo();
+ }
}
// Build and emit a record for this declaration
@@ -1164,5 +1170,5 @@ void PCHWriter::WriteDecl(ASTContext &Context, Decl *D) {
//
// FIXME: This should be renamed, the predicate is much more complicated.
if (isRequiredDecl(D, Context))
- ExternalDefinitions.push_back(Index + 1);
+ ExternalDefinitions.push_back(ID);
}
OpenPOWER on IntegriCloud