ExplodedGraph.h revision a19f4af7a94835ce4693bfe12d6270754e79eb56
151125a21eafc29c925cac3655b46cfd8ef55f764Ted Kremenek//=-- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -*- C++ -*-------==//
24241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//
34241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//                     The LLVM Compiler Infrastructure
44241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//
54241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek// This file is distributed under the University of Illinois Open Source
64241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek// License. See LICENSE.TXT for details.
74241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//
84241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//===----------------------------------------------------------------------===//
94241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//
1051125a21eafc29c925cac3655b46cfd8ef55f764Ted Kremenek//  This file defines the template classes ExplodedNode and ExplodedGraph,
1151125a21eafc29c925cac3655b46cfd8ef55f764Ted Kremenek//  which represent a path-sensitive, intra-procedural "exploded graph."
12b2213dc3dd8f58b611b91d2fce4834a767efcba7Jeffrey Yasskin//  See "Precise interprocedural dataflow analysis via graph reachability"
13b2213dc3dd8f58b611b91d2fce4834a767efcba7Jeffrey Yasskin//  by Reps, Horwitz, and Sagiv
14b2213dc3dd8f58b611b91d2fce4834a767efcba7Jeffrey Yasskin//  (http://portal.acm.org/citation.cfm?id=199462) for the definition of an
15b2213dc3dd8f58b611b91d2fce4834a767efcba7Jeffrey Yasskin//  exploded graph.
164241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//
174241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//===----------------------------------------------------------------------===//
184241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
195a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis#ifndef LLVM_CLANG_GR_EXPLODEDGRAPH
205a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis#define LLVM_CLANG_GR_EXPLODEDGRAPH
214241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
224a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek#include "clang/Analysis/ProgramPoint.h"
231309f9a3b225ea846e5822691c39a77423125505Ted Kremenek#include "clang/Analysis/AnalysisContext.h"
2463bbe5312cd89ce0ceb684bff68c5baef636e93cTed Kremenek#include "clang/AST/Decl.h"
254241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek#include "llvm/ADT/SmallVector.h"
264241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek#include "llvm/ADT/FoldingSet.h"
27f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek#include "llvm/ADT/SmallPtrSet.h"
284241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek#include "llvm/Support/Allocator.h"
29ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek#include "llvm/ADT/OwningPtr.h"
304a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek#include "llvm/ADT/GraphTraits.h"
314a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek#include "llvm/ADT/DepthFirstIterator.h"
3263bbe5312cd89ce0ceb684bff68c5baef636e93cTed Kremenek#include "llvm/Support/Casting.h"
335fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek#include "clang/Analysis/Support/BumpVector.h"
3418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
354241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
364241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremeneknamespace clang {
374a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
3811062b118476368fa5b294954713e5df97d8599fTed Kremenekclass CFG;
395a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
409ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremeneknamespace ento {
415a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
425fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenekclass ExplodedGraph;
4311062b118476368fa5b294954713e5df97d8599fTed Kremenek
44cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
45cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// ExplodedGraph "implementation" classes.  These classes are not typed to
46cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// contain a specific kind of state.  Typed-specialized versions are defined
47cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// on top of these classes.
48cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
50bda1efd0daf6fca9f515c6ce38d1ed71a3cca5b7Zhongxing Xu// ExplodedNode is not constified all over the engine because we need to add
51bda1efd0daf6fca9f515c6ce38d1ed71a3cca5b7Zhongxing Xu// successors to it at any time after creating it.
52bda1efd0daf6fca9f515c6ce38d1ed71a3cca5b7Zhongxing Xu
53c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuclass ExplodedNode : public llvm::FoldingSetNode {
5438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  friend class ExplodedGraph;
55d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  friend class CoreEngine;
56a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks  friend class NodeBuilder;
57d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  friend class StmtNodeBuilder;
58d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  friend class BranchNodeBuilder;
59d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  friend class IndirectGotoNodeBuilder;
60d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  friend class SwitchNodeBuilder;
61e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  friend class EndOfFunctionNodeBuilder;
621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
634c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek  class NodeGroup {
64b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek    enum { Size1 = 0x0, SizeOther = 0x1, AuxFlag = 0x2, Mask = 0x3 };
654c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek    uintptr_t P;
661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
67ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek    unsigned getKind() const {
68596f0a1e54f610926e8bfded9efa1c639f824dedTed Kremenek      return P & 0x1;
69ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek    }
701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
719c378f705405d37f49795d5e915989de774fe11fTed Kremenek    void *getPtr() const {
72ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek      assert (!getFlag());
73b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek      return reinterpret_cast<void*>(P & ~Mask);
74ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek    }
75ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek
76c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    ExplodedNode *getNode() const {
77c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu      return reinterpret_cast<ExplodedNode*>(getPtr());
78ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek    }
79d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek
804c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek  public:
814c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek    NodeGroup() : P(0) {}
821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
835fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek    ExplodedNode **begin() const;
841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
855fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek    ExplodedNode **end() const;
861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
875d5480380d7b7c3590a0283ddf239220e514e576Ted Kremenek    unsigned size() const;
881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
895fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek    bool empty() const { return (P & ~Mask) == 0; }
901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
919c378f705405d37f49795d5e915989de774fe11fTed Kremenek    void addNode(ExplodedNode *N, ExplodedGraph &G);
921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
93d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek    void replaceNode(ExplodedNode *node);
94d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek
95b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek    void setFlag() {
965fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek      assert(P == 0);
97ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek      P = AuxFlag;
98f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek    }
991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
100b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek    bool getFlag() const {
101b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek      return P & AuxFlag ? true : false;
102f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek    }
1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  };
1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1054a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  /// Location - The program location (within a function body) associated
1064a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  ///  with this node.
1074a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  const ProgramPoint Location;
1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1094323a57627e796dcfdfdb7d47672dc09ed308edaTed Kremenek  /// State - The state associated with this node.
11018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *State;
1111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1124a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  /// Preds - The predecessors of this node.
1134c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek  NodeGroup Preds;
1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1154a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  /// Succs - The successors of this node.
1164c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek  NodeGroup Succs;
117c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
1184a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenekpublic:
119c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
12018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  explicit ExplodedNode(const ProgramPoint &loc, const ProgramState *state)
121e3115e257163321ecde429aeae75f1702f099d4cTed Kremenek    : Location(loc), State(state) {
12218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    const_cast<ProgramState*>(State)->incrementReferenceCount();
123e40b69de464bc695afcaf7ef9602ad727d77b981Ted Kremenek  }
124e40b69de464bc695afcaf7ef9602ad727d77b981Ted Kremenek
125e40b69de464bc695afcaf7ef9602ad727d77b981Ted Kremenek  ~ExplodedNode() {
12618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    const_cast<ProgramState*>(State)->decrementReferenceCount();
127e3115e257163321ecde429aeae75f1702f099d4cTed Kremenek  }
128c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
1294a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  /// getLocation - Returns the edge associated with the given node.
1300f9063c116b7c3b05d8042b5976463c2dae04861Ted Kremenek  ProgramPoint getLocation() const { return Location; }
131c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const LocationContext *getLocationContext() const {
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return getLocation().getLocationContext();
13425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  }
13525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu
1365032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu  const Decl &getCodeDecl() const { return *getLocationContext()->getDecl(); }
1375032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu
1385032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu  CFG &getCFG() const { return *getLocationContext()->getCFG(); }
1395032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu
140b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu  ParentMap &getParentMap() const {return getLocationContext()->getParentMap();}
141b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu
142a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  template <typename T>
143a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  T &getAnalysis() const {
144a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek    return *getLocationContext()->getAnalysis<T>();
145c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  }
146c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
14718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *getState() const { return State; }
148b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu
14952c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek  template <typename T>
15052c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek  const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); }
151c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void Profile(llvm::FoldingSetNodeID &ID,
15318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                      const ProgramPoint &Loc, const ProgramState *state) {
1545fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek    ID.Add(Loc);
1555fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek    ID.AddPointer(state);
1565fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek  }
157c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
158c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  void Profile(llvm::FoldingSetNodeID& ID) const {
159c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    Profile(ID, getLocation(), getState());
160c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  }
161c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
1621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// addPredeccessor - Adds a predecessor to the current node, and
163c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  ///  in tandem add this node as a successor of the other node.
1649c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void addPredecessor(ExplodedNode *V, ExplodedGraph &G);
165c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
1664a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  unsigned succ_size() const { return Succs.size(); }
1674a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  unsigned pred_size() const { return Preds.size(); }
1684a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  bool succ_empty() const { return Succs.empty(); }
1690e8a3c743b9b3e3039e329a1736122d3b5b5fed9Ted Kremenek  bool pred_empty() const { return Preds.empty(); }
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
171ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek  bool isSink() const { return Succs.getFlag(); }
1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void markAsSink() { Succs.setFlag(); }
1734a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
1749c378f705405d37f49795d5e915989de774fe11fTed Kremenek  ExplodedNode *getFirstPred() {
17552c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek    return pred_empty() ? NULL : *(pred_begin());
17652c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek  }
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1789c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *getFirstPred() const {
17952c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek    return const_cast<ExplodedNode*>(this)->getFirstPred();
18052c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek  }
1811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1824a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  // Iterators over successor and predecessor vertices.
1834a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  typedef ExplodedNode**       succ_iterator;
1843148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  typedef const ExplodedNode* const * const_succ_iterator;
1854a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  typedef ExplodedNode**       pred_iterator;
1863148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  typedef const ExplodedNode* const * const_pred_iterator;
1874a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
188c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  pred_iterator pred_begin() { return Preds.begin(); }
189c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  pred_iterator pred_end() { return Preds.end(); }
1904a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
1914a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  const_pred_iterator pred_begin() const {
1924a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    return const_cast<ExplodedNode*>(this)->pred_begin();
1931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
1944a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  const_pred_iterator pred_end() const {
1954a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    return const_cast<ExplodedNode*>(this)->pred_end();
1964a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  }
1974a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
198c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  succ_iterator succ_begin() { return Succs.begin(); }
199c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  succ_iterator succ_end() { return Succs.end(); }
2004a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
2014a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  const_succ_iterator succ_begin() const {
2024a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    return const_cast<ExplodedNode*>(this)->succ_begin();
2034a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  }
2044a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  const_succ_iterator succ_end() const {
2054a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    return const_cast<ExplodedNode*>(this)->succ_end();
2064a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  }
207c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
208c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  // For debugging.
2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
210c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xupublic:
2111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
212c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  class Auditor {
213c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  public:
214c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    virtual ~Auditor();
2159c378f705405d37f49795d5e915989de774fe11fTed Kremenek    virtual void AddEdge(ExplodedNode *Src, ExplodedNode *Dst) = 0;
216c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  };
2171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
218c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  static void SetAuditor(Auditor* A);
219d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek
220d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenekprivate:
221d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  void replaceSuccessor(ExplodedNode *node) { Succs.replaceNode(node); }
222d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  void replacePredecessor(ExplodedNode *node) { Preds.replaceNode(node); }
223c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu};
224c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
22538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu// FIXME: Is this class necessary?
22638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xuclass InterExplodedGraphMap {
22738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  llvm::DenseMap<const ExplodedNode*, ExplodedNode*> M;
2281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  friend class ExplodedGraph;
229c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
23038b02b912e1a55c912f603c4369431264d36a381Zhongxing Xupublic:
2319c378f705405d37f49795d5e915989de774fe11fTed Kremenek  ExplodedNode *getMappedNode(const ExplodedNode *N) const;
2321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2337177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar  InterExplodedGraphMap() {}
23438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  virtual ~InterExplodedGraphMap() {}
2354a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek};
2364a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
23738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xuclass ExplodedGraph {
2384241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenekprotected:
239d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  friend class CoreEngine;
240e96de2dfde487211fb52f9139cdcae64d051a406Zhongxing Xu
2414241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  // Type definitions.
242686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<ExplodedNode*,2>    RootsTy;
243686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<ExplodedNode*,10>   EndNodesTy;
2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2454241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  /// Roots - The roots of the simulation graph. Usually there will be only
2464241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  /// one, but clients are free to establish multiple subgraphs within a single
2474241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  /// SimulGraph. Moreover, these subgraphs can often merge when paths from
2484241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  /// different roots reach the same state at the same program location.
2494241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  RootsTy Roots;
2504241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
2514241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  /// EndNodes - The nodes in the simulation graph which have been
2524241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  ///  specially marked as the endpoint of an abstract simulation path.
2534241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  EndNodesTy EndNodes;
25438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu
25538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  /// Nodes - The nodes in the graph.
25638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  llvm::FoldingSet<ExplodedNode> Nodes;
25738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu
2585fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek  /// BVC - Allocator and context for allocating nodes and their predecessor
2595fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek  /// and successor groups.
2605fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek  BumpVectorContext BVC;
2611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
26239b4c6c98d391b25c376782cf92346aa88c96f7eTed Kremenek  /// NumNodes - The number of nodes in the graph.
26339b4c6c98d391b25c376782cf92346aa88c96f7eTed Kremenek  unsigned NumNodes;
264d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek
265d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  /// A list of recently allocated nodes that can potentially be recycled.
266d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  void *recentlyAllocatedNodes;
267d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek
268d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  /// A list of nodes that can be reused.
269d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  void *freeNodes;
270d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek
271d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  /// A flag that indicates whether nodes should be recycled.
272d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  bool reclaimNodes;
2734241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
27438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xupublic:
27538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  /// getNode - Retrieve the node associated with a (Location,State) pair,
27638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  ///  where the 'Location' is a ProgramPoint in the CFG.  If no node for
27738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  ///  this pair exists, it is created.  IsNew is set to true if
27838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  ///  the node was freshly created.
27938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu
28018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  ExplodedNode *getNode(const ProgramPoint &L, const ProgramState *State,
28138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu                        bool* IsNew = 0);
2821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
28338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  ExplodedGraph* MakeEmptyGraph() const {
284c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu    return new ExplodedGraph();
28538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  }
2864a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
2874241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  /// addRoot - Add an untyped node to the set of roots.
2889c378f705405d37f49795d5e915989de774fe11fTed Kremenek  ExplodedNode *addRoot(ExplodedNode *V) {
289ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek    Roots.push_back(V);
290ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek    return V;
291ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek  }
2924241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
2934241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  /// addEndOfPath - Add an untyped node to the set of EOP nodes.
2949c378f705405d37f49795d5e915989de774fe11fTed Kremenek  ExplodedNode *addEndOfPath(ExplodedNode *V) {
295ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek    EndNodes.push_back(V);
296ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek    return V;
297ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek  }
29838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu
299824c547dc5d4451b9dbacc56621592fa010878f4Ted Kremenek  ExplodedGraph()
300824c547dc5d4451b9dbacc56621592fa010878f4Ted Kremenek    : NumNodes(0), recentlyAllocatedNodes(0),
301824c547dc5d4451b9dbacc56621592fa010878f4Ted Kremenek      freeNodes(0), reclaimNodes(false) {}
3024a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
303d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  ~ExplodedGraph();
304d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek
3054241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  unsigned num_roots() const { return Roots.size(); }
3064a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  unsigned num_eops() const { return EndNodes.size(); }
3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
30839b4c6c98d391b25c376782cf92346aa88c96f7eTed Kremenek  bool empty() const { return NumNodes == 0; }
30939b4c6c98d391b25c376782cf92346aa88c96f7eTed Kremenek  unsigned size() const { return NumNodes; }
310c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
3114241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  // Iterators.
31238b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  typedef ExplodedNode                        NodeTy;
31338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  typedef llvm::FoldingSet<ExplodedNode>      AllNodesTy;
3147ebde953bb050caa69f791fc1de449d435c6a36fTed Kremenek  typedef NodeTy**                            roots_iterator;
31538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  typedef NodeTy* const *                     const_roots_iterator;
3167ebde953bb050caa69f791fc1de449d435c6a36fTed Kremenek  typedef NodeTy**                            eop_iterator;
31738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  typedef NodeTy* const *                     const_eop_iterator;
31838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  typedef AllNodesTy::iterator                node_iterator;
31938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  typedef AllNodesTy::const_iterator          const_node_iterator;
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
32138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  node_iterator nodes_begin() { return Nodes.begin(); }
3227ebde953bb050caa69f791fc1de449d435c6a36fTed Kremenek
32338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  node_iterator nodes_end() { return Nodes.end(); }
3241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
32538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  const_node_iterator nodes_begin() const { return Nodes.begin(); }
3261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
32738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  const_node_iterator nodes_end() const { return Nodes.end(); }
3281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
32938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  roots_iterator roots_begin() { return Roots.begin(); }
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  roots_iterator roots_end() { return Roots.end(); }
3321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  const_roots_iterator roots_begin() const { return Roots.begin(); }
3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const_roots_iterator roots_end() const { return Roots.end(); }
3364241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
33738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  eop_iterator eop_begin() { return EndNodes.begin(); }
3381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  eop_iterator eop_end() { return EndNodes.end(); }
3401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  const_eop_iterator eop_begin() const { return EndNodes.begin(); }
3421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  const_eop_iterator eop_end() const { return EndNodes.end(); }
34438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu
3455fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek  llvm::BumpPtrAllocator & getAllocator() { return BVC.getAllocator(); }
3465fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek  BumpVectorContext &getNodeAllocator() { return BVC; }
34738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu
34838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap;
34938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu
350c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  std::pair<ExplodedGraph*, InterExplodedGraphMap*>
351fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek  Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd,
35238b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu       llvm::DenseMap<const void*, const void*> *InverseMap = 0) const;
353cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
35438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  ExplodedGraph* TrimInternal(const ExplodedNode* const * NBeg,
35538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu                              const ExplodedNode* const * NEnd,
35638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu                              InterExplodedGraphMap *M,
35738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu                    llvm::DenseMap<const void*, const void*> *InverseMap) const;
358d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek
359d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  /// Enable tracking of recently allocated nodes for potential reclamation
360d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  /// when calling reclaimRecentlyAllocatedNodes().
361d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  void enableNodeReclamation() { reclaimNodes = true; }
362d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek
363d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  /// Reclaim "uninteresting" nodes created since the last time this method
364d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  /// was called.
365d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  void reclaimRecentlyAllocatedNodes();
3664241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek};
367cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
368f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenekclass ExplodedNodeSet {
369c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  typedef llvm::SmallPtrSet<ExplodedNode*,5> ImplTy;
370f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek  ImplTy Impl;
3711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
372f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenekpublic:
3739c378f705405d37f49795d5e915989de774fe11fTed Kremenek  ExplodedNodeSet(ExplodedNode *N) {
374c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    assert (N && !static_cast<ExplodedNode*>(N)->isSink());
375f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek    Impl.insert(N);
376f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek  }
3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
378f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek  ExplodedNodeSet() {}
3791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3809c378f705405d37f49795d5e915989de774fe11fTed Kremenek  inline void Add(ExplodedNode *N) {
381c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    if (N && !static_cast<ExplodedNode*>(N)->isSink()) Impl.insert(N);
382f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek  }
3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3849c378f705405d37f49795d5e915989de774fe11fTed Kremenek  ExplodedNodeSet &operator=(const ExplodedNodeSet &X) {
385cc2c6eb04d882466c7cfbb544c251d7e0ba0f356Ted Kremenek    Impl = X.Impl;
386cc2c6eb04d882466c7cfbb544c251d7e0ba0f356Ted Kremenek    return *this;
387cc2c6eb04d882466c7cfbb544c251d7e0ba0f356Ted Kremenek  }
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
389c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  typedef ImplTy::iterator       iterator;
390c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  typedef ImplTy::const_iterator const_iterator;
391f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek
392fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek  unsigned size() const { return Impl.size();  }
393fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek  bool empty()    const { return Impl.empty(); }
394fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek
395fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek  void clear() { Impl.clear(); }
396fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek  void insert(const ExplodedNodeSet &S) {
397fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek    if (empty())
398fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek      Impl = S.Impl;
399fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek    else
400fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek      Impl.insert(S.begin(), S.end());
401fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek  }
4021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
403f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek  inline iterator begin() { return Impl.begin(); }
404f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek  inline iterator end()   { return Impl.end();   }
4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
406f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek  inline const_iterator begin() const { return Impl.begin(); }
407f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek  inline const_iterator end()   const { return Impl.end();   }
4081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
4091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4105a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis} // end GR namespace
4115a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
4124241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek} // end clang namespace
4134241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
4144a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek// GraphTraits
4154a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
4164a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremeneknamespace llvm {
4179ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek  template<> struct GraphTraits<clang::ento::ExplodedNode*> {
4189ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek    typedef clang::ento::ExplodedNode NodeType;
419c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    typedef NodeType::succ_iterator  ChildIteratorType;
4204a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    typedef llvm::df_iterator<NodeType*>      nodes_iterator;
4211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4224a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    static inline NodeType* getEntryNode(NodeType* N) {
4234a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek      return N;
4244a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    }
4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4264a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    static inline ChildIteratorType child_begin(NodeType* N) {
4274a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek      return N->succ_begin();
4284a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    }
4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4304a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    static inline ChildIteratorType child_end(NodeType* N) {
4314a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek      return N->succ_end();
4324a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    }
4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4344a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    static inline nodes_iterator nodes_begin(NodeType* N) {
4354a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek      return df_begin(N);
4364a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    }
4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4384a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    static inline nodes_iterator nodes_end(NodeType* N) {
4394a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek      return df_end(N);
4404a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    }
4414a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  };
4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4439ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek  template<> struct GraphTraits<const clang::ento::ExplodedNode*> {
4449ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek    typedef const clang::ento::ExplodedNode NodeType;
445c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    typedef NodeType::const_succ_iterator   ChildIteratorType;
4464a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    typedef llvm::df_iterator<NodeType*>       nodes_iterator;
4471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4484a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    static inline NodeType* getEntryNode(NodeType* N) {
4494a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek      return N;
4504a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    }
4511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4524a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    static inline ChildIteratorType child_begin(NodeType* N) {
4534a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek      return N->succ_begin();
4544a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    }
4551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4564a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    static inline ChildIteratorType child_end(NodeType* N) {
4574a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek      return N->succ_end();
4584a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    }
4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4604a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    static inline nodes_iterator nodes_begin(NodeType* N) {
4614a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek      return df_begin(N);
4624a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    }
4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4644a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    static inline nodes_iterator nodes_end(NodeType* N) {
4654a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek      return df_end(N);
4664a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    }
4674a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  };
4681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4694a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek} // end llvm namespace
4704a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
4714241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek#endif
472