clang: lib/Analysis/FlowSensitive/AdornedCFG.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

20#include "llvm/ADT/BitVector.h"

21#include "llvm/ADT/DenseMap.h"

22#include "llvm/Support/Error.h"

23#include

24

26namespace dataflow {

27

28

29static llvm::DenseMap<const Stmt *, const CFGBlock *>

31 llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;

33 if (Block == nullptr)

34 continue;

35

39 continue;

40

41 StmtToBlock[Stmt->getStmt()] = Block;

42 }

43 }

44

45

46

47

48

49

50

52 if (Block != nullptr)

53 if (const Stmt *TerminatorCond = Block->getTerminatorCondition())

54 StmtToBlock.insert({TerminatorCond, Block});

55 }

56

57

58

59

60

61

62

63

64

65

66

67

69 if (Block != nullptr)

70 if (const Stmt *TerminatorStmt = Block->getTerminatorStmt())

71 StmtToBlock.insert({TerminatorStmt, Block});

72 }

73 return StmtToBlock;

74}

75

77 llvm::BitVector BlockReachable(Cfg.getNumBlockIDs(), false);

78

80 BlocksToVisit.push_back(&Cfg.getEntry());

81 while (!BlocksToVisit.empty()) {

83 BlocksToVisit.pop_back();

84

85 if (BlockReachable[Block->getBlockID()])

86 continue;

87

88 BlockReachable[Block->getBlockID()] = true;

89

91 if (Succ)

92 BlocksToVisit.push_back(Succ);

93 }

94

95 return BlockReachable;

96}

97

98static llvm::DenseSet<const CFGBlock *>

101 llvm::DenseSet<const CFGBlock *> Result;

102

103 auto CheckChildExprs = [&Result, &StmtToBlock](const Stmt *S,

105 for (const Stmt *Child : S->children()) {

106 if (!isa_and_nonnull(Child))

107 continue;

108 const CFGBlock *ChildBlock = StmtToBlock.lookup(*Child);

109 if (ChildBlock != Block)

110 Result.insert(ChildBlock);

111 }

112 };

113

115 if (Block == nullptr)

116 continue;

117

119 if (auto S = Element.getAs<CFGStmt>())

120 CheckChildExprs(S->getStmt(), Block);

121

122 if (const Stmt *TerminatorCond = Block->getTerminatorCondition())

123 CheckChildExprs(TerminatorCond, Block);

124 }

125

126 return Result;

127}

128

129namespace internal {

130

131StmtToBlockMap::StmtToBlockMap(const CFG &Cfg)

133

134}

135

137 if (Func.doesThisDeclarationHaveABody())

138 return llvm::createStringError(

139 std::make_error_code(std::errc::invalid_argument),

140 "Cannot analyze function without a body");

141

143}

144

147 if (D.isTemplated())

148 return llvm::createStringError(

149 std::make_error_code(std::errc::invalid_argument),

150 "Cannot analyze templated declarations");

151

152

153

154 if (C.getLangOpts().CPlusPlus || C.getLangOpts().ObjC)

155 return llvm::createStringError(

156 std::make_error_code(std::errc::invalid_argument),

157 "Can only analyze C++");

158

160 Options.PruneTriviallyFalseEdges = true;

161 Options.AddImplicitDtors = true;

162 Options.AddTemporaryDtors = true;

163 Options.AddInitializers = true;

164 Options.AddCXXDefaultInitExprInCtors = true;

165 Options.AddLifetime = true;

166

167

168 Options.setAllAlwaysAdd();

169

171 if (Cfg == nullptr)

172 return llvm::createStringError(

173 std::make_error_code(std::errc::invalid_argument),

174 "CFG::buildCFG failed");

175

177

179

180 llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock =

182

183 return AdornedCFG(D, std::move(Cfg), std::move(StmtToBlock),

184 std::move(BlockReachable),

185 std::move(ContainsExprConsumedInDifferentBlock));

186}

187

188}

189}

Defines the clang::ASTContext interface.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

Represents a single basic block in a source-level CFG.

Represents a top-level expression in a basic block.

Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.

static std::unique_ptr< CFG > buildCFG(const Decl *D, Stmt *AST, ASTContext *C, const BuildOptions &BO)

Builds a CFG from an AST.

unsigned getNumBlockIDs() const

Returns the total number of BlockIDs allocated (which start at 0).

Decl - This represents one declaration (or definition), e.g.

Represents a function declaration or definition.

Stmt - This represents one statement.

Holds CFG with additional information derived from it that is needed to perform dataflow analysis.

static llvm::Expected< AdornedCFG > build(const FunctionDecl &Func)

Builds an AdornedCFG from a FunctionDecl.

const CFGBlock * lookup(const Stmt &S) const

static llvm::DenseSet< const CFGBlock * > buildContainsExprConsumedInDifferentBlock(const CFG &Cfg, const internal::StmtToBlockMap &StmtToBlock)

static llvm::DenseMap< const Stmt *, const CFGBlock * > buildStmtToBasicBlockMap(const CFG &Cfg)

Returns a map from statements to basic blocks that contain them.

static llvm::BitVector findReachableBlocks(const CFG &Cfg)

The JSON file list parser is used to communicate input to InstallAPI.