Clang Project

clang_source_code/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
1//===- CoreEngine.h - Path-Sensitive Dataflow Engine ------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//  This file defines a generic engine for intraprocedural, path-sensitive,
10//  dataflow analysis via graph reachability.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
15#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
16
17#include "clang/AST/Stmt.h"
18#include "clang/Analysis/AnalysisDeclContext.h"
19#include "clang/Analysis/CFG.h"
20#include "clang/Analysis/ProgramPoint.h"
21#include "clang/Basic/LLVM.h"
22#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
23#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
24#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
25#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
26#include "llvm/ADT/SmallVector.h"
27#include "llvm/Support/Casting.h"
28#include <cassert>
29#include <memory>
30#include <utility>
31#include <vector>
32
33namespace clang {
34
35class AnalyzerOptions;
36class CXXBindTemporaryExpr;
37class Expr;
38class LabelDecl;
39
40namespace ento {
41
42class FunctionSummariesTy;
43class SubEngine;
44
45//===----------------------------------------------------------------------===//
46/// CoreEngine - Implements the core logic of the graph-reachability
47///   analysis. It traverses the CFG and generates the ExplodedGraph.
48///   Program "states" are treated as opaque void pointers.
49///   The template class CoreEngine (which subclasses CoreEngine)
50///   provides the matching component to the engine that knows the actual types
51///   for states.  Note that this engine only dispatches to transfer functions
52///   at the statement and block-level.  The analyses themselves must implement
53///   any transfer function logic and the sub-expression level (if any).
54class CoreEngine {
55  friend class CommonNodeBuilder;
56  friend class EndOfFunctionNodeBuilder;
57  friend class ExprEngine;
58  friend class IndirectGotoNodeBuilder;
59  friend class NodeBuilder;
60  friend struct NodeBuilderContext;
61  friend class SwitchNodeBuilder;
62
63public:
64  using BlocksExhausted =
65      std::vector<std::pair<BlockEdgeconst ExplodedNode *>>;
66
67  using BlocksAborted =
68      std::vector<std::pair<const CFGBlock *, const ExplodedNode *>>;
69
70private:
71  SubEngine &SubEng;
72
73  /// G - The simulation graph.  Each node is a (location,state) pair.
74  mutable ExplodedGraph G;
75
76  /// WList - A set of queued nodes that need to be processed by the
77  ///  worklist algorithm.  It is up to the implementation of WList to decide
78  ///  the order that nodes are processed.
79  std::unique_ptr<WorkListWList;
80
81  /// BCounterFactory - A factory object for created BlockCounter objects.
82  ///   These are used to record for key nodes in the ExplodedGraph the
83  ///   number of times different CFGBlocks have been visited along a path.
84  BlockCounter::Factory BCounterFactory;
85
86  /// The locations where we stopped doing work because we visited a location
87  ///  too many times.
88  BlocksExhausted blocksExhausted;
89
90  /// The locations where we stopped because the engine aborted analysis,
91  /// usually because it could not reason about something.
92  BlocksAborted blocksAborted;
93
94  /// The information about functions shared by the whole translation unit.
95  /// (This data is owned by AnalysisConsumer.)
96  FunctionSummariesTy *FunctionSummaries;
97
98  void generateNode(const ProgramPoint &Loc,
99                    ProgramStateRef State,
100                    ExplodedNode *Pred);
101
102  void HandleBlockEdge(const BlockEdge &EExplodedNode *Pred);
103  void HandleBlockEntrance(const BlockEntrance &EExplodedNode *Pred);
104  void HandleBlockExit(const CFGBlock *BExplodedNode *Pred);
105
106  void HandleCallEnter(const CallEnter &CEExplodedNode *Pred);
107
108  void HandlePostStmt(const CFGBlock *Bunsigned StmtIdxExplodedNode *Pred);
109
110  void HandleBranch(const Stmt *Condconst Stmt *Termconst CFGBlock *B,
111                    ExplodedNode *Pred);
112  void HandleCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
113                                    const CFGBlock *BExplodedNode *Pred);
114
115  /// Handle conditional logic for running static initializers.
116  void HandleStaticInit(const DeclStmt *DSconst CFGBlock *B,
117                        ExplodedNode *Pred);
118
119private:
120  ExplodedNode *generateCallExitBeginNode(ExplodedNode *N,
121                                          const ReturnStmt *RS);
122
123public:
124  /// Construct a CoreEngine object to analyze the provided CFG.
125  CoreEngine(SubEngine &subengine,
126             FunctionSummariesTy *FS,
127             AnalyzerOptions &Opts);
128
129  CoreEngine(const CoreEngine &) = delete;
130  CoreEngine &operator=(const CoreEngine &) = delete;
131
132  /// getGraph - Returns the exploded graph.
133  ExplodedGraph &getGraph() { return G; }
134
135  /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
136  ///  steps.  Returns true if there is still simulation state on the worklist.
137  bool ExecuteWorkList(const LocationContext *Lunsigned Steps,
138                       ProgramStateRef InitState);
139
140  /// Returns true if there is still simulation state on the worklist.
141  bool ExecuteWorkListWithInitialState(const LocationContext *L,
142                                       unsigned Steps,
143                                       ProgramStateRef InitState,
144                                       ExplodedNodeSet &Dst);
145
146  /// Dispatch the work list item based on the given location information.
147  /// Use Pred parameter as the predecessor state.
148  void dispatchWorkItem(ExplodedNodePredProgramPoint Loc,
149                        const WorkListUnitWU);
150
151  // Functions for external checking of whether we have unfinished work
152  bool wasBlockAborted() const { return !blocksAborted.empty(); }
153  bool wasBlocksExhausted() const { return !blocksExhausted.empty(); }
154  bool hasWorkRemaining() const { return wasBlocksExhausted() ||
155                                         WList->hasWork() ||
156                                         wasBlockAborted(); }
157
158  /// Inform the CoreEngine that a basic block was aborted because
159  /// it could not be completely analyzed.
160  void addAbortedBlock(const ExplodedNode *nodeconst CFGBlock *block) {
161    blocksAborted.push_back(std::make_pair(blocknode));
162  }
163
164  WorkList *getWorkList() const { return WList.get(); }
165
166  BlocksExhausted::const_iterator blocks_exhausted_begin() const {
167    return blocksExhausted.begin();
168  }
169
170  BlocksExhausted::const_iterator blocks_exhausted_end() const {
171    return blocksExhausted.end();
172  }
173
174  BlocksAborted::const_iterator blocks_aborted_begin() const {
175    return blocksAborted.begin();
176  }
177
178  BlocksAborted::const_iterator blocks_aborted_end() const {
179    return blocksAborted.end();
180  }
181
182  /// Enqueue the given set of nodes onto the work list.
183  void enqueue(ExplodedNodeSet &Set);
184
185  /// Enqueue nodes that were created as a result of processing
186  /// a statement onto the work list.
187  void enqueue(ExplodedNodeSet &Setconst CFGBlock *Blockunsigned Idx);
188
189  /// enqueue the nodes corresponding to the end of function onto the
190  /// end of path / work list.
191  void enqueueEndOfFunction(ExplodedNodeSet &Setconst ReturnStmt *RS);
192
193  /// Enqueue a single node created as a result of statement processing.
194  void enqueueStmtNode(ExplodedNode *Nconst CFGBlock *Blockunsigned Idx);
195};
196
197// TODO: Turn into a class.
198struct NodeBuilderContext {
199  const CoreEngine &Eng;
200  const CFGBlock *Block;
201  const LocationContext *LC;
202
203  NodeBuilderContext(const CoreEngine &Econst CFGBlock *BExplodedNode *N)
204      : Eng(E), Block(B), LC(N->getLocationContext()) { assert(B); }
205
206  /// Return the CFGBlock associated with this builder.
207  const CFGBlock *getBlock() const { return Block; }
208
209  /// Returns the number of times the current basic block has been
210  /// visited on the exploded graph path.
211  unsigned blockCount() const {
212    return Eng.WList->getBlockCounter().getNumVisited(
213                    LC->getStackFrame(),
214                    Block->getBlockID());
215  }
216};
217
218/// \class NodeBuilder
219/// This is the simplest builder which generates nodes in the
220/// ExplodedGraph.
221///
222/// The main benefit of the builder is that it automatically tracks the
223/// frontier nodes (or destination set). This is the set of nodes which should
224/// be propagated to the next step / builder. They are the nodes which have been
225/// added to the builder (either as the input node set or as the newly
226/// constructed nodes) but did not have any outgoing transitions added.
227class NodeBuilder {
228  virtual void anchor();
229
230protected:
231  const NodeBuilderContext &C;
232
233  /// Specifies if the builder results have been finalized. For example, if it
234  /// is set to false, autotransitions are yet to be generated.
235  bool Finalized;
236
237  bool HasGeneratedNodes = false;
238
239  /// The frontier set - a set of nodes which need to be propagated after
240  /// the builder dies.
241  ExplodedNodeSet &Frontier;
242
243  /// Checks if the results are ready.
244  virtual bool checkResults() {
245    return Finalized;
246  }
247
248  bool hasNoSinksInFrontier() {
249    for (const auto  I : Frontier)
250      if (I->isSink())
251        return false;
252    return true;
253  }
254
255  /// Allow subclasses to finalize results before result_begin() is executed.
256  virtual void finalizeResults() {}
257
258  ExplodedNode *generateNodeImpl(const ProgramPoint &PP,
259                                 ProgramStateRef State,
260                                 ExplodedNode *Pred,
261                                 bool MarkAsSink = false);
262
263public:
264  NodeBuilder(ExplodedNode *SrcNodeExplodedNodeSet &DstSet,
265              const NodeBuilderContext &Ctxbool F = true)
266      : C(Ctx), Finalized(F), Frontier(DstSet) {
267    Frontier.Add(SrcNode);
268  }
269
270  NodeBuilder(const ExplodedNodeSet &SrcSetExplodedNodeSet &DstSet,
271              const NodeBuilderContext &Ctxbool F = true)
272      : C(Ctx), Finalized(F), Frontier(DstSet) {
273    Frontier.insert(SrcSet);
274    assert(hasNoSinksInFrontier());
275  }
276
277  virtual ~NodeBuilder() = default;
278
279  /// Generates a node in the ExplodedGraph.
280  ExplodedNode *generateNode(const ProgramPoint &PP,
281                             ProgramStateRef State,
282                             ExplodedNode *Pred) {
283    return generateNodeImpl(PP, State, Pred, false);
284  }
285
286  /// Generates a sink in the ExplodedGraph.
287  ///
288  /// When a node is marked as sink, the exploration from the node is stopped -
289  /// the node becomes the last node on the path and certain kinds of bugs are
290  /// suppressed.
291  ExplodedNode *generateSink(const ProgramPoint &PP,
292                             ProgramStateRef State,
293                             ExplodedNode *Pred) {
294    return generateNodeImpl(PP, State, Pred, true);
295  }
296
297  const ExplodedNodeSet &getResults() {
298    finalizeResults();
299    assert(checkResults());
300    return Frontier;
301  }
302
303  using iterator = ExplodedNodeSet::iterator;
304
305  /// Iterators through the results frontier.
306  iterator begin() {
307    finalizeResults();
308    assert(checkResults());
309    return Frontier.begin();
310  }
311
312  iterator end() {
313    finalizeResults();
314    return Frontier.end();
315  }
316
317  const NodeBuilderContext &getContext() { return C; }
318  bool hasGeneratedNodes() { return HasGeneratedNodes; }
319
320  void takeNodes(const ExplodedNodeSet &S) {
321    for (const auto I : S)
322      Frontier.erase(I);
323  }
324
325  void takeNodes(ExplodedNode *N) { Frontier.erase(N); }
326  void addNodes(const ExplodedNodeSet &S) { Frontier.insert(S); }
327  void addNodes(ExplodedNode *N) { Frontier.Add(N); }
328};
329
330/// \class NodeBuilderWithSinks
331/// This node builder keeps track of the generated sink nodes.
332class NodeBuilderWithSinkspublic NodeBuilder {
333  void anchor() override;
334
335protected:
336  SmallVector<ExplodedNode*, 2sinksGenerated;
337  ProgramPoint &Location;
338
339public:
340  NodeBuilderWithSinks(ExplodedNode *PredExplodedNodeSet &DstSet,
341                       const NodeBuilderContext &CtxProgramPoint &L)
342      : NodeBuilder(PredDstSetCtx), Location(L) {}
343
344  ExplodedNode *generateNode(ProgramStateRef State,
345                             ExplodedNode *Pred,
346                             const ProgramPointTag *Tag = nullptr) {
347    const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
348    return NodeBuilder::generateNode(LocalLoc, State, Pred);
349  }
350
351  ExplodedNode *generateSink(ProgramStateRef StateExplodedNode *Pred,
352                             const ProgramPointTag *Tag = nullptr) {
353    const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
354    ExplodedNode *N = NodeBuilder::generateSink(LocalLoc, State, Pred);
355    if (N && N->isSink())
356      sinksGenerated.push_back(N);
357    return N;
358  }
359
360  const SmallVectorImpl<ExplodedNode*> &getSinks() const {
361    return sinksGenerated;
362  }
363};
364
365/// \class StmtNodeBuilder
366/// This builder class is useful for generating nodes that resulted from
367/// visiting a statement. The main difference from its parent NodeBuilder is
368/// that it creates a statement specific ProgramPoint.
369class StmtNodeBuilderpublic NodeBuilder {
370  NodeBuilder *EnclosingBldr;
371
372public:
373  /// Constructs a StmtNodeBuilder. If the builder is going to process
374  /// nodes currently owned by another builder(with larger scope), use
375  /// Enclosing builder to transfer ownership.
376  StmtNodeBuilder(ExplodedNode *SrcNodeExplodedNodeSet &DstSet,
377                  const NodeBuilderContext &Ctx,
378                  NodeBuilder *Enclosing = nullptr)
379      : NodeBuilder(SrcNodeDstSetCtx), EnclosingBldr(Enclosing) {
380    if (EnclosingBldr)
381      EnclosingBldr->takeNodes(SrcNode);
382  }
383
384  StmtNodeBuilder(ExplodedNodeSet &SrcSetExplodedNodeSet &DstSet,
385                  const NodeBuilderContext &Ctx,
386                  NodeBuilder *Enclosing = nullptr)
387      : NodeBuilder(SrcSetDstSetCtx), EnclosingBldr(Enclosing) {
388    if (EnclosingBldr)
389      for (const auto I : SrcSet)
390        EnclosingBldr->takeNodes(I);
391  }
392
393  ~StmtNodeBuilder() override;
394
395  using NodeBuilder::generateNode;
396  using NodeBuilder::generateSink;
397
398  ExplodedNode *generateNode(const Stmt *S,
399                             ExplodedNode *Pred,
400                             ProgramStateRef St,
401                             const ProgramPointTag *tag = nullptr,
402                             ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
403    const ProgramPoint &L = ProgramPoint::getProgramPoint(SK,
404                                  Pred->getLocationContext(), tag);
405    return NodeBuilder::generateNode(L, St, Pred);
406  }
407
408  ExplodedNode *generateSink(const Stmt *S,
409                             ExplodedNode *Pred,
410                             ProgramStateRef St,
411                             const ProgramPointTag *tag = nullptr,
412                             ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
413    const ProgramPoint &L = ProgramPoint::getProgramPoint(SK,
414                                  Pred->getLocationContext(), tag);
415    return NodeBuilder::generateSink(L, St, Pred);
416  }
417};
418
419/// BranchNodeBuilder is responsible for constructing the nodes
420/// corresponding to the two branches of the if statement - true and false.
421class BranchNodeBuilderpublic NodeBuilder {
422  const CFGBlock *DstT;
423  const CFGBlock *DstF;
424
425  bool InFeasibleTrue;
426  bool InFeasibleFalse;
427
428  void anchor() override;
429
430public:
431  BranchNodeBuilder(ExplodedNode *SrcNodeExplodedNodeSet &DstSet,
432                    const NodeBuilderContext &C,
433                    const CFGBlock *dstTconst CFGBlock *dstF)
434      : NodeBuilder(SrcNodeDstSetC), DstT(dstT), DstF(dstF),
435        InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
436    // The branch node builder does not generate autotransitions.
437    // If there are no successors it means that both branches are infeasible.
438    takeNodes(SrcNode);
439  }
440
441  BranchNodeBuilder(const ExplodedNodeSet &SrcSetExplodedNodeSet &DstSet,
442                    const NodeBuilderContext &C,
443                    const CFGBlock *dstTconst CFGBlock *dstF)
444      : NodeBuilder(SrcSetDstSetC), DstT(dstT), DstF(dstF),
445        InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
446    takeNodes(SrcSet);
447  }
448
449  ExplodedNode *generateNode(ProgramStateRef Statebool branch,
450                             ExplodedNode *Pred);
451
452  const CFGBlock *getTargetBlock(bool branchconst {
453    return branch ? DstT : DstF;
454  }
455
456  void markInfeasible(bool branch) {
457    if (branch)
458      InFeasibleTrue = true;
459    else
460      InFeasibleFalse = true;
461  }
462
463  bool isFeasible(bool branch) {
464    return branch ? !InFeasibleTrue : !InFeasibleFalse;
465  }
466};
467
468class IndirectGotoNodeBuilder {
469  CoreEngineEng;
470  const CFGBlock *Src;
471  const CFGBlock &DispatchBlock;
472  const Expr *E;
473  ExplodedNode *Pred;
474
475public:
476  IndirectGotoNodeBuilder(ExplodedNode *predconst CFGBlock *src,
477                    const Expr *econst CFGBlock *dispatchCoreEngineeng)
478      : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
479
480  class iterator {
481    friend class IndirectGotoNodeBuilder;
482
483    CFGBlock::const_succ_iterator I;
484
485    iterator(CFGBlock::const_succ_iterator i) : I(i) {}
486
487  public:
488    iterator &operator++() { ++Ireturn *this; }
489    bool operator!=(const iterator &Xconst { return I != X.I; }
490
491    const LabelDecl *getLabel() const {
492      return cast<LabelStmt>((*I)->getLabel())->getDecl();
493    }
494
495    const CFGBlock *getBlock() const {
496      return *I;
497    }
498  };
499
500  iterator begin() { return iterator(DispatchBlock.succ_begin()); }
501  iterator end() { return iterator(DispatchBlock.succ_end()); }
502
503  ExplodedNode *generateNode(const iterator &I,
504                             ProgramStateRef State,
505                             bool isSink = false);
506
507  const Expr *getTarget() const { return E; }
508
509  ProgramStateRef getState() const { return Pred->State; }
510
511  const LocationContext *getLocationContext() const {
512    return Pred->getLocationContext();
513  }
514};
515
516class SwitchNodeBuilder {
517  CoreEngineEng;
518  const CFGBlock *Src;
519  const Expr *Condition;
520  ExplodedNode *Pred;
521
522public:
523  SwitchNodeBuilder(ExplodedNode *predconst CFGBlock *src,
524                    const Expr *conditionCoreEngineeng)
525      : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
526
527  class iterator {
528    friend class SwitchNodeBuilder;
529
530    CFGBlock::const_succ_reverse_iterator I;
531
532    iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {}
533
534  public:
535    iterator &operator++() { ++Ireturn *this; }
536    bool operator!=(const iterator &Xconst { return I != X.I; }
537    bool operator==(const iterator &Xconst { return I == X.I; }
538
539    const CaseStmt *getCase() const {
540      return cast<CaseStmt>((*I)->getLabel());
541    }
542
543    const CFGBlock *getBlock() const {
544      return *I;
545    }
546  };
547
548  iterator begin() { return iterator(Src->succ_rbegin()+1); }
549  iterator end() { return iterator(Src->succ_rend()); }
550
551  const SwitchStmt *getSwitch() const {
552    return cast<SwitchStmt>(Src->getTerminator());
553  }
554
555  ExplodedNode *generateCaseStmtNode(const iterator &I,
556                                     ProgramStateRef State);
557
558  ExplodedNode *generateDefaultCaseNode(ProgramStateRef State,
559                                        bool isSink = false);
560
561  const Expr *getCondition() const { return Condition; }
562
563  ProgramStateRef getState() const { return Pred->State; }
564
565  const LocationContext *getLocationContext() const {
566    return Pred->getLocationContext();
567  }
568};
569
570// namespace ento
571
572// namespace clang
573
574#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
575
clang::ento::CoreEngine::SubEng
clang::ento::CoreEngine::G
clang::ento::CoreEngine::WList
clang::ento::CoreEngine::BCounterFactory
clang::ento::CoreEngine::blocksExhausted
clang::ento::CoreEngine::blocksAborted
clang::ento::CoreEngine::FunctionSummaries
clang::ento::CoreEngine::generateNode
clang::ento::CoreEngine::HandleBlockEdge
clang::ento::CoreEngine::HandleBlockEntrance
clang::ento::CoreEngine::HandleBlockExit
clang::ento::CoreEngine::HandleCallEnter
clang::ento::CoreEngine::HandlePostStmt
clang::ento::CoreEngine::HandleBranch
clang::ento::CoreEngine::HandleCleanupTemporaryBranch
clang::ento::CoreEngine::HandleStaticInit
clang::ento::CoreEngine::generateCallExitBeginNode
clang::ento::CoreEngine::getGraph
clang::ento::CoreEngine::ExecuteWorkList
clang::ento::CoreEngine::ExecuteWorkListWithInitialState
clang::ento::CoreEngine::dispatchWorkItem
clang::ento::CoreEngine::wasBlockAborted
clang::ento::CoreEngine::wasBlocksExhausted
clang::ento::CoreEngine::hasWorkRemaining
clang::ento::CoreEngine::addAbortedBlock
clang::ento::CoreEngine::getWorkList
clang::ento::CoreEngine::blocks_exhausted_begin
clang::ento::CoreEngine::blocks_exhausted_end
clang::ento::CoreEngine::blocks_aborted_begin
clang::ento::CoreEngine::blocks_aborted_end
clang::ento::CoreEngine::enqueue
clang::ento::CoreEngine::enqueue
clang::ento::CoreEngine::enqueueEndOfFunction
clang::ento::CoreEngine::enqueueStmtNode
clang::ento::NodeBuilderContext::Eng
clang::ento::NodeBuilderContext::Block
clang::ento::NodeBuilderContext::LC
clang::ento::NodeBuilderContext::getBlock
clang::ento::NodeBuilderContext::blockCount
clang::ento::NodeBuilder::anchor
clang::ento::NodeBuilder::C
clang::ento::NodeBuilder::Finalized
clang::ento::NodeBuilder::HasGeneratedNodes
clang::ento::NodeBuilder::Frontier
clang::ento::NodeBuilder::checkResults
clang::ento::NodeBuilder::hasNoSinksInFrontier
clang::ento::NodeBuilder::finalizeResults
clang::ento::NodeBuilder::generateNodeImpl
clang::ento::NodeBuilder::generateNode
clang::ento::NodeBuilder::generateSink
clang::ento::NodeBuilder::getResults
clang::ento::NodeBuilder::begin
clang::ento::NodeBuilder::end
clang::ento::NodeBuilder::getContext
clang::ento::NodeBuilder::hasGeneratedNodes
clang::ento::NodeBuilder::takeNodes
clang::ento::NodeBuilder::takeNodes
clang::ento::NodeBuilder::addNodes
clang::ento::NodeBuilder::addNodes
clang::ento::NodeBuilderWithSinks::anchor
clang::ento::NodeBuilderWithSinks::sinksGenerated
clang::ento::NodeBuilderWithSinks::Location
clang::ento::NodeBuilderWithSinks::generateNode
clang::ento::NodeBuilderWithSinks::generateSink
clang::ento::NodeBuilderWithSinks::getSinks
clang::ento::StmtNodeBuilder::EnclosingBldr
clang::ento::StmtNodeBuilder::generateNode
clang::ento::StmtNodeBuilder::generateSink
clang::ento::BranchNodeBuilder::DstT
clang::ento::BranchNodeBuilder::DstF
clang::ento::BranchNodeBuilder::InFeasibleTrue
clang::ento::BranchNodeBuilder::InFeasibleFalse
clang::ento::BranchNodeBuilder::anchor
clang::ento::BranchNodeBuilder::generateNode
clang::ento::BranchNodeBuilder::getTargetBlock
clang::ento::BranchNodeBuilder::markInfeasible
clang::ento::BranchNodeBuilder::isFeasible
clang::ento::IndirectGotoNodeBuilder::Eng
clang::ento::IndirectGotoNodeBuilder::Src
clang::ento::IndirectGotoNodeBuilder::DispatchBlock
clang::ento::IndirectGotoNodeBuilder::E
clang::ento::IndirectGotoNodeBuilder::Pred
clang::ento::IndirectGotoNodeBuilder::iterator
clang::ento::IndirectGotoNodeBuilder::iterator::I
clang::ento::IndirectGotoNodeBuilder::iterator::getLabel
clang::ento::IndirectGotoNodeBuilder::iterator::getBlock
clang::ento::IndirectGotoNodeBuilder::begin
clang::ento::IndirectGotoNodeBuilder::end
clang::ento::IndirectGotoNodeBuilder::generateNode
clang::ento::IndirectGotoNodeBuilder::getTarget
clang::ento::IndirectGotoNodeBuilder::getState
clang::ento::IndirectGotoNodeBuilder::getLocationContext
clang::ento::SwitchNodeBuilder::Eng
clang::ento::SwitchNodeBuilder::Src
clang::ento::SwitchNodeBuilder::Condition
clang::ento::SwitchNodeBuilder::Pred
clang::ento::SwitchNodeBuilder::iterator
clang::ento::SwitchNodeBuilder::iterator::I
clang::ento::SwitchNodeBuilder::iterator::getCase
clang::ento::SwitchNodeBuilder::iterator::getBlock
clang::ento::SwitchNodeBuilder::begin
clang::ento::SwitchNodeBuilder::end
clang::ento::SwitchNodeBuilder::getSwitch
clang::ento::SwitchNodeBuilder::generateCaseStmtNode
clang::ento::SwitchNodeBuilder::generateDefaultCaseNode
clang::ento::SwitchNodeBuilder::getCondition
clang::ento::SwitchNodeBuilder::getState
clang::ento::SwitchNodeBuilder::getLocationContext