summaryrefslogtreecommitdiffstats
path: root/lib/Serialization
diff options
context:
space:
mode:
authorVassil Vassilev <v.g.vassilev@gmail.com>2017-05-19 16:46:06 +0000
committerVassil Vassilev <v.g.vassilev@gmail.com>2017-05-19 16:46:06 +0000
commit03e56f3de71918828f20e09dc0c8fe541e9045f4 (patch)
tree385a4e09b29433e82d07baaf37ebd37f53703cef /lib/Serialization
parent4ee33b072b6b54d95cd982aec4946ff886038a6f (diff)
[modules] Further delay calling DeclMustBeEmitted until it's safe.
As discussed in D30793, we have some unsafe calls to isConsumerInterestedIn(). This patch implements Richard's suggestion (from the inline comment) that we should track if we just deserialized an declaration. If we just deserialized, we can skip the unsafe call because we know it's interesting. If we didn't just deserialize the declaration, calling isConsumerInterestedIn() should be safe. We tried to create a test case for this but we were not successful. Patch by Raphael Isemann (D32499)! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@303432 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization')
-rw-r--r--lib/Serialization/ASTReader.cpp8
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp17
2 files changed, 16 insertions, 9 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 5cabd0e674..55cb670f42 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -2756,7 +2756,8 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
// If we've already loaded the decl, perform the updates when we finish
// loading this block.
if (Decl *D = GetExistingDecl(ID))
- PendingUpdateRecords.push_back(std::make_pair(ID, D));
+ PendingUpdateRecords.push_back(
+ PendingUpdateRecord(ID, D, /*JustLoaded=*/false));
break;
}
@@ -3086,7 +3087,8 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
// If we've already loaded the decl, perform the updates when we finish
// loading this block.
if (Decl *D = GetExistingDecl(ID))
- PendingUpdateRecords.push_back(std::make_pair(ID, D));
+ PendingUpdateRecords.push_back(
+ PendingUpdateRecord(ID, D, /*JustLoaded=*/false));
}
break;
}
@@ -8956,7 +8958,7 @@ void ASTReader::finishPendingActions() {
while (!PendingUpdateRecords.empty()) {
auto Update = PendingUpdateRecords.pop_back_val();
ReadingKindTracker ReadingKind(Read_Decl, *this);
- loadDeclUpdateRecords(Update.first, Update.second);
+ loadDeclUpdateRecords(Update);
}
}
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index e0304d22fe..f3ee907829 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -3612,7 +3612,8 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
assert(Record.getIdx() == Record.size());
// Load any relevant update records.
- PendingUpdateRecords.push_back(std::make_pair(ID, D));
+ PendingUpdateRecords.push_back(
+ PendingUpdateRecord(ID, D, /*JustLoaded=*/true));
// Load the categories after recursive loading is finished.
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
@@ -3657,20 +3658,24 @@ void ASTReader::PassInterestingDeclsToConsumer() {
}
}
-void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
+void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
// The declaration may have been modified by files later in the chain.
// If this is the case, read the record containing the updates from each file
// and pass it to ASTDeclReader to make the modifications.
+ serialization::GlobalDeclID ID = Record.ID;
+ Decl *D = Record.D;
ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
if (UpdI != DeclUpdateOffsets.end()) {
auto UpdateOffsets = std::move(UpdI->second);
DeclUpdateOffsets.erase(UpdI);
- // FIXME: This call to isConsumerInterestedIn is not safe because
- // we could be deserializing declarations at the moment. We should
- // delay calling this in the same way as done in D30793.
- bool WasInteresting = isConsumerInterestedIn(Context, D, false);
+ // Check if this decl was interesting to the consumer. If we just loaded
+ // the declaration, then we know it was interesting and we skip the call
+ // to isConsumerInterestedIn because it is unsafe to call in the
+ // current ASTReader state.
+ bool WasInteresting =
+ Record.JustLoaded || isConsumerInterestedIn(Context, D, false);
for (auto &FileAndOffset : UpdateOffsets) {
ModuleFile *F = FileAndOffset.first;
uint64_t Offset = FileAndOffset.second;