<commit_before>//=-- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -*- C++ -*-------==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the template classes ExplodedNode and ExplodedGraph,
//  which represent a path-sensitive, intra-procedural "exploded graph."
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH
#define LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH

#include "clang/Analysis/ProgramPoint.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Allocator.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include <vector>

namespace clang {

class GREngineImpl;
class ExplodedNodeImpl;
  
/// ExplodedNodeGroup - A utility class used to represent the set of successor
///  and predecessor nodes of a node.  Most nodes will have only 1 successor
///  and 1 predecessor, so class allows us to store such unit sets of nodes
///  using a single pointer without allocating an entire vector.  For
///  larger sets of nodes, we dynamically allocate a vector.  This class
///  will likely be revised in the future to further improve performance and
///  to reduce memory footprint.
class ExplodedNodeGroup {
  enum { Size1 = 0x0, SizeOther = 0x1, Flags = 0x1 };
  uintptr_t P;
  
  unsigned getKind() const { return P & Flags; }
  
  std::vector<ExplodedNodeImpl*>& getVector() {
    assert (getKind() == SizeOther);
    return *reinterpret_cast<std::vector<ExplodedNodeImpl*>*>(P & ~Flags);
  }  
  const std::vector<ExplodedNodeImpl*>& getVector() const {
    assert (getKind() == SizeOther);
    return *reinterpret_cast<std::vector<ExplodedNodeImpl*>*>(P & ~Flags);
  }
  
  ExplodedNodeImpl* getNode() const {
    assert (getKind() == Size1);
    return reinterpret_cast<ExplodedNodeImpl*>(P);
  }
  
public:
  ExplodedNodeGroup() : P(0) {}
  
  ~ExplodedNodeGroup() { if (getKind() == SizeOther) delete &getVector(); }
  
  inline ExplodedNodeImpl** begin() const {
    if (getKind() == Size1)
      return (ExplodedNodeImpl**) &P;
    else
      return const_cast<ExplodedNodeImpl**>(&*(getVector().begin()));
  }
  
  inline ExplodedNodeImpl** end() const {
    if (getKind() == Size1)
      return ((ExplodedNodeImpl**) &P)+1;
    else
      return const_cast<ExplodedNodeImpl**>(&*(getVector().rbegin())+1);
  }
  
  inline unsigned size() const {
    if (getKind() == Size1)
      return getNode() ? 1 : 0;
    else
      return getVector().size();
  }
  
  inline bool empty() const {
    if (getKind() == Size1)
      return getNode() ? false : true;
    else
      return getVector().empty();
  }
  
  inline void addNode(ExplodedNodeImpl* N) {
    if (getKind() == Size1) {
      if (ExplodedNodeImpl* NOld = getNode()) {
        std::vector<ExplodedNodeImpl*>* V = new std::vector<ExplodedNodeImpl*>();
        V->push_back(NOld);
        V->push_back(N);
        P = reinterpret_cast<uintptr_t>(V) & SizeOther;
      }
      else
        P = reinterpret_cast<uintptr_t>(N);
    }
    else
      getVector().push_back(N);
  }
};

/// ExplodedNodeImpl - 
class ExplodedNodeImpl : public llvm::FoldingSetNode {
protected:
  friend class ExplodedGraphImpl;
  
  /// Location - The program location (within a function body) associated
  ///  with this node.
  const ProgramPoint Location;
  
  /// State - The state associated with this node. Normally this value
  ///  is immutable, but we anticipate there will be times when algorithms
  ///  that directly manipulate the analysis graph will need to change it.
  void* State;
  
  /// Preds - The predecessors of this node.
  ExplodedNodeGroup Preds;
  
  /// Succs - The successors of this node.
  ExplodedNodeGroup Succs;
  
  /// Construct a ExplodedNodeImpl with the provided location and state.<commit_msg>Moved 'ExplodedNodeGroup' into class 'ExplodedNode' as the nested class 'NodeGroup.'<commit_after>//=-- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -*- C++ -*-------==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the template classes ExplodedNode and ExplodedGraph,
//  which represent a path-sensitive, intra-procedural "exploded graph."
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH
#define LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH

#include "clang/Analysis/ProgramPoint.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Allocator.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include <vector>

namespace clang {

class GREngineImpl;
class ExplodedNodeImpl;

class ExplodedNodeImpl : public llvm::FoldingSetNode {
protected:
  friend class ExplodedGraphImpl;
  
  class NodeGroup {
    enum { Size1 = 0x0, SizeOther = 0x1, Flags = 0x1 };
    uintptr_t P;
    
    unsigned getKind() const { return P & Flags; }
    
    std::vector<ExplodedNodeImpl*>& getVector() {
      assert (getKind() == SizeOther);
      return *reinterpret_cast<std::vector<ExplodedNodeImpl*>*>(P & ~Flags);
    }  
    const std::vector<ExplodedNodeImpl*>& getVector() const {
      assert (getKind() == SizeOther);
      return *reinterpret_cast<std::vector<ExplodedNodeImpl*>*>(P & ~Flags);
    }
    
    ExplodedNodeImpl* getNode() const {
      assert (getKind() == Size1);
      return reinterpret_cast<ExplodedNodeImpl*>(P);
    }
    
  public:
    NodeGroup() : P(0) {}
    
    ~NodeGroup() { if (getKind() == SizeOther) delete &getVector(); }
    
    inline ExplodedNodeImpl** begin() const {
      if (getKind() == Size1)
        return (ExplodedNodeImpl**) &P;
      else
        return const_cast<ExplodedNodeImpl**>(&*(getVector().begin()));
    }
    
    inline ExplodedNodeImpl** end() const {
      if (getKind() == Size1)
        return ((ExplodedNodeImpl**) &P)+1;
      else
        return const_cast<ExplodedNodeImpl**>(&*(getVector().rbegin())+1);
    }
    
    inline unsigned size() const {
      if (getKind() == Size1)
        return getNode() ? 1 : 0;
      else
        return getVector().size();
    }
    
    inline bool empty() const {
      if (getKind() == Size1)
        return getNode() ? false : true;
      else
        return getVector().empty();
    }
    
    inline void addNode(ExplodedNodeImpl* N) {
      if (getKind() == Size1) {
        if (ExplodedNodeImpl* NOld = getNode()) {
          std::vector<ExplodedNodeImpl*>* V = new std::vector<ExplodedNodeImpl*>();
          V->push_back(NOld);
          V->push_back(N);
          P = reinterpret_cast<uintptr_t>(V) & SizeOther;
        }
        else
          P = reinterpret_cast<uintptr_t>(N);
      }
      else
        getVector().push_back(N);
    }
  };
  
  
  /// Location - The program location (within a function body) associated
  ///  with this node.
  const ProgramPoint Location;
  
  /// State - The state associated with this node. Normally this value
  ///  is immutable, but we anticipate there will be times when algorithms
  ///  that directly manipulate the analysis graph will need to change it.
  void* State;
  
  /// Preds - The predecessors of this node.
  NodeGroup Preds;
  
  /// Succs - The successors of this node.
  NodeGroup Succs;
  
  /// Construct a ExplodedNodeImpl with the provided location and state.
{'fraction_non_alphanumeric': 0.1635673624288425, 'fraction_numerical': 0.00480708412397217, 'mean_word_length': 2.61996336996337, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7244358', 'n_tokens_mistral': 2480, 'n_tokens_neox': 2408, 'n_words': 652}