aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-02-09 07:31:52 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-02-09 07:31:52 +0000
commit44d2dbdce49d1fca3826d543ba875bb82f759091 (patch)
tree1f6669c3cd6619f2f9ce9ec6aea1a179016cd4bf /lib/Serialization/ASTReader.cpp
parent3b8e197bbfd2c9a1a5fc3ab6509f89cc274e77f8 (diff)
Fix ASTReader::FinishedDeserializing().
We were passing a decl to the consumer after all pending deserializations were finished but this was not enough; due to processing by the consumer we may end up into yet another deserialization process but the way FinishedDeserializing() was setup we would not ensure that everything was fully deserialized before returning to the consumer. Separate ASTReader::FinishedDeserializing() into two semantic actions. The first is ensuring that a deserialization process ends up will fully deserialized decls/types even if the process is started by the consumer. The second is pushing "interesting" decls to the consumer; we make sure that we don't re-enter this section recursively be checking a variable. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150160 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r--lib/Serialization/ASTReader.cpp32
1 files changed, 14 insertions, 18 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 1d19312105..5c9905f049 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -27,6 +27,7 @@
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLocVisitor.h"
+#include "clang/Analysis/Support/SaveAndRestore.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
@@ -6246,33 +6247,27 @@ void ASTReader::FinishedDeserializing() {
assert(NumCurrentElementsDeserializing &&
"FinishedDeserializing not paired with StartedDeserializing");
if (NumCurrentElementsDeserializing == 1) {
+ // We decrease NumCurrentElementsDeserializing only after pending actions
+ // are finished, to avoid recursively re-calling finishPendingActions().
+ finishPendingActions();
+ }
+ --NumCurrentElementsDeserializing;
- while (Consumer && !InterestingDecls.empty()) {
- finishPendingActions();
+ if (NumCurrentElementsDeserializing == 0 &&
+ Consumer && !PassingDeclsToConsumer) {
+ // Guard variable to avoid recursively redoing the process of passing
+ // decls to consumer.
+ SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
+ true);
+ while (!InterestingDecls.empty()) {
// We are not in recursive loading, so it's safe to pass the "interesting"
// decls to the consumer.
Decl *D = InterestingDecls.front();
InterestingDecls.pop_front();
-
- // Fully load the interesting decls, including deserializing their
- // bodies, so that any other declarations that get referenced in the
- // body will be fully deserialized by the time we pass them to the
- // consumer.
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- if (FD->doesThisDeclarationHaveABody()) {
- FD->getBody();
- finishPendingActions();
- }
- }
-
PassInterestingDeclToConsumer(D);
}
-
- finishPendingActions();
- PendingDeclChainsKnown.clear();
}
- --NumCurrentElementsDeserializing;
}
ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
@@ -6293,6 +6288,7 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0),
+ PassingDeclsToConsumer(false),
NumCXXBaseSpecifiersLoaded(0)
{
SourceMgr.setExternalSLocEntrySource(this);