clang: include/clang/Analysis/FlowSensitive/MatchSwitch.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_MATCHSWITCH_H_

23#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_MATCHSWITCH_H_

24

30#include "llvm/ADT/StringRef.h"

31#include

32#include

33#include <type_traits>

34#include

35#include

36

38namespace dataflow {

39

40

44

45

48};

49

50

51

52

53

54

58

59

62};

63

64template

66

67template <typename T, typename State, typename Result = void>

70

71template <typename BaseT, typename State, typename Result = void>

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95template <typename BaseT, typename State, typename Result = void>

97public:

98

99

100

101

102

103

104 template

107 static_assert(std::is_base_of<BaseT, NodeT>::value,

108 "NodeT must be derived from BaseT.");

109 Matchers.push_back(std::move(M));

110 Actions.push_back(

111 [A = std::move(A)](const BaseT *Node,

113 State &S) { return A(cast(Node), R, S); });

114 return std::move(*this);

115 }

116

118 return [Matcher = BuildMatcher(), Actions = std::move(Actions)](

121 if (Results.empty()) {

123 }

124

125

126 for (const auto &Element : Results[0].getMap()) {

127 llvm::StringRef ID(Element.first);

128 size_t Index = 0;

129 if (ID.consume_front("Tag") && ID.getAsInteger(10, Index) &&

130 Index < Actions.size()) {

131 return Actions[Index](

134 }

135 }

137 };

138 }

139

140private:

141 ast_matchers::internal::DynTypedMatcher BuildMatcher() {

145 using ast_matchers::internal::DynTypedMatcher;

146 if (Matchers.empty())

148 for (int I = 0, N = Matchers.size(); I < N; ++I) {

149 std::string Tag = ("Tag" + llvm::Twine(I)).str();

150

151 Matchers[I].setAllowBind(true);

152 auto M = *Matchers[I].tryBind(Tag);

153

154

155

156

157

158 Matchers[I] =

159 !M.getTraversalKind() ? M.withTraversalKind(TK_AsIs) : std::move(M);

160 }

161

162

163 return DynTypedMatcher::constructVariadic(

164 DynTypedMatcher::VO_AnyOf, ASTNodeKind::getFromNodeKind(),

165 std::move(Matchers));

166 }

167

168 std::vector<ast_matchers::internal::DynTypedMatcher> Matchers;

169 std::vector<MatchSwitchAction<BaseT, State, Result>> Actions;

170};

171

172}

173}

174#endif

Defines the clang::ASTContext interface.

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

Collects cases of a "match switch": a collection of matchers paired with callbacks,...

ASTMatchSwitchBuilder && CaseOf(MatchSwitchMatcher< BaseT > M, MatchSwitchAction< NodeT, State, Result > A) &&

Registers an action that will be triggered by the match of a pattern against the input statement.

ASTMatchSwitch< BaseT, State, Result > Build() &&

Holds the state of the program (store and heap) at a given program point.

const internal::VariadicOperatorMatcherFunc< 1, 1 > unless

Matches if the provided matcher does not match.

internal::TrueMatcher anything()

Matches any node.

SmallVector< BoundNodes, 1 > matchDynamic(internal::DynTypedMatcher Matcher, const DynTypedNode &Node, ASTContext &Context)

const internal::VariadicAllOfMatcher< Stmt > stmt

Matches statements.

std::function< Result(const T *, const ast_matchers::MatchFinder::MatchResult &, State &)> MatchSwitchAction

std::function< Result(const BaseT &, ASTContext &, State &)> ASTMatchSwitch

ast_matchers::internal::Matcher< T > MatchSwitchMatcher

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

@ TK_AsIs

Will traverse all child nodes.

@ Result

The result type of a method or function.

const FunctionProtoType * T

Contains all information for a given match.

A read-only version of TransferState.

const LatticeT & Lattice

Current lattice element.

TransferStateForDiagnostics(const LatticeT &Lattice, const Environment &Env)

A common form of state shared between the cases of a transfer function.

TransferState(LatticeT &Lattice, Environment &Env)

LatticeT & Lattice

Current lattice element.