aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp')
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp28
1 files changed, 20 insertions, 8 deletions
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 008f744957..dd60b201f8 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -103,6 +103,8 @@ public:
/// working with a PCH file.
SetOfDecls LocalTUDecls;
+ SetOfDecls::Factory LocalTUDeclsFactory;
+
// PD is owned by AnalysisManager.
PathDiagnosticConsumer *PD;
@@ -306,7 +308,9 @@ void AnalysisConsumer::storeTopLevelDecls(DeclGroupRef DG) {
if (isa<ObjCMethodDecl>(*I))
continue;
- LocalTUDecls.insert(*I);
+ // We use an ImmutableList to avoid issues with invalidating iterators
+ // to the list while we are traversing it.
+ LocalTUDecls = LocalTUDeclsFactory.add(*I, LocalTUDecls);
}
}
@@ -315,6 +319,9 @@ void AnalysisConsumer::HandleDeclsGallGraph() {
// Build the Call Graph.
CallGraph CG;
// Add all the top level declarations to the graph.
+ //
+ // NOTE: We use an ImmutableList to avoid issues with invalidating iterators
+ // to the list while we are traversing it.
for (SetOfDecls::iterator I = LocalTUDecls.begin(),
E = LocalTUDecls.end(); I != E; ++I)
CG.addToCallGraph(*I);
@@ -338,11 +345,11 @@ void AnalysisConsumer::HandleDeclsGallGraph() {
// translation unit. This step is very important for performance. It ensures
// that we analyze the root functions before the externally available
// subroutines.
- std::queue<CallGraphNode*> BFSQueue;
+ std::deque<CallGraphNode*> BFSQueue;
for (llvm::SmallVector<CallGraphNode*, 24>::reverse_iterator
TI = TopLevelFunctions.rbegin(), TE = TopLevelFunctions.rend();
TI != TE; ++TI)
- BFSQueue.push(*TI);
+ BFSQueue.push_front(*TI);
// BFS over all of the functions, while skipping the ones inlined into
// the previously processed functions. Use external Visited set, which is
@@ -350,7 +357,7 @@ void AnalysisConsumer::HandleDeclsGallGraph() {
SmallPtrSet<CallGraphNode*,24> Visited;
while(!BFSQueue.empty()) {
CallGraphNode *N = BFSQueue.front();
- BFSQueue.pop();
+ BFSQueue.pop_front();
// Skip the functions which have been processed already or previously
// inlined.
@@ -365,8 +372,8 @@ void AnalysisConsumer::HandleDeclsGallGraph() {
(Mgr->InliningMode == All ? 0 : &VisitedCallees));
// Add the visited callees to the global visited set.
- for (SetOfConstDecls::const_iterator I = VisitedCallees.begin(),
- E = VisitedCallees.end(); I != E; ++I){
+ for (SetOfConstDecls::iterator I = VisitedCallees.begin(),
+ E = VisitedCallees.end(); I != E; ++I) {
CallGraphNode *VN = CG.getNode(*I);
if (VN)
Visited.insert(VN);
@@ -376,7 +383,7 @@ void AnalysisConsumer::HandleDeclsGallGraph() {
// Push the children into the queue.
for (CallGraphNode::const_iterator CI = N->begin(),
CE = N->end(); CI != CE; ++CI) {
- BFSQueue.push(*CI);
+ BFSQueue.push_front(*CI);
}
}
}
@@ -402,9 +409,14 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
RecVisitorBR = &BR;
// Process all the top level declarations.
+ //
+ // NOTE: We use an ImmutableList to avoid issues with invalidating iterators
+ // to the list while we are traversing it.
+ //
for (SetOfDecls::iterator I = LocalTUDecls.begin(),
- E = LocalTUDecls.end(); I != E; ++I)
+ E = LocalTUDecls.end(); I != E; ++I) {
TraverseDecl(*I);
+ }
if (Mgr->shouldInlineCall())
HandleDeclsGallGraph();