blob: 269aaf02c181733a32636d04c4812b3e6442ce8e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
//=- ReachableCodePathInsensitive.cpp ---------------------------*- C++ --*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a flow-sensitive, path-insensitive analysis of
// determining reachable blocks within a CFG.
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "clang/Analysis/Analyses/ReachableCode.h"
#include "clang/Analysis/CFG.h"
using namespace clang;
/// ScanReachableFromBlock - Mark all blocks reachable from Start.
/// Returns the total number of blocks that were marked reachable.
unsigned clang::ScanReachableFromBlock(const CFGBlock &Start,
llvm::BitVector &Reachable) {
unsigned count = 0;
llvm::SmallVector<const CFGBlock*, 12> WL;
// Prep work queue
Reachable.set(Start.getBlockID());
++count;
WL.push_back(&Start);
// Find the reachable blocks from 'Start'.
while (!WL.empty()) {
const CFGBlock *item = WL.back();
WL.pop_back();
// Look at the successors and mark then reachable.
for (CFGBlock::const_succ_iterator I=item->succ_begin(), E=item->succ_end();
I != E; ++I)
if (const CFGBlock *B = *I) {
unsigned blockID = B->getBlockID();
if (!Reachable[blockID]) {
Reachable.set(blockID);
++count;
WL.push_back(B);
}
}
}
return count;
}
|