1010#ifndef KLEE_LOCATIONINFO_H
1111#define KLEE_LOCATIONINFO_H
1212
13+ #include " klee/ADT/Ref.h"
14+
1315#include < cstdint>
16+ #include < functional>
1417#include < optional>
1518#include < string>
19+ #include < unordered_set>
1620
1721namespace llvm {
1822class Function ;
@@ -23,12 +27,16 @@ class Module;
2327
2428namespace klee {
2529struct PhysicalLocationJson ;
26- }
30+ struct LocationInfo ;
31+ } // namespace klee
2732
2833namespace klee {
2934
3035// / @brief Immutable struct representing location in source code.
3136struct LocationInfo {
37+ // / @brief Required by klee::ref-managed objects
38+ class ReferenceCounter _refCount;
39+
3240 // / @brief Path to source file for that location.
3341 const std::string file;
3442
@@ -44,14 +52,73 @@ struct LocationInfo {
4452 // / @return SARIFs representation of location.
4553 PhysicalLocationJson serialize () const ;
4654
55+ static ref<LocationInfo> create (std::string file, uint64_t line,
56+ std::optional<uint64_t > column) {
57+ LocationInfo *locationInfo = new LocationInfo (file, line, column);
58+ return createCachedLocationInfo (locationInfo);
59+ }
60+
4761 bool operator ==(const LocationInfo &rhs) const {
4862 return file == rhs.file && line == rhs.line && column == rhs.column ;
4963 }
64+
65+ bool equals (const LocationInfo &b) const { return *this == b; }
66+
67+ ~LocationInfo () {
68+ if (isCached) {
69+ toBeCleared = true ;
70+ cachedLocationInfo.cache .erase (this );
71+ }
72+ }
73+
74+ private:
75+ LocationInfo (std::string file, uint64_t line, std::optional<uint64_t > column)
76+ : file(file), line(line), column(column) {}
77+
78+ struct LocationInfoHash {
79+ std::size_t operator ()(LocationInfo *const s) const noexcept {
80+ std::size_t r = 0 ;
81+ std::size_t h1 = std::hash<std::string>{}(s->file );
82+ std::size_t h2 = std::hash<uint64_t >{}(s->line );
83+ std::size_t h3 = std::hash<std::optional<uint64_t >>{}(s->column );
84+ r ^= h1 + 0x9e3779b9 + (r << 6 ) + (r >> 2 );
85+ r ^= h2 + 0x9e3779b9 + (r << 6 ) + (r >> 2 );
86+ r ^= h3 + 0x9e3779b9 + (r << 6 ) + (r >> 2 );
87+ return r;
88+ }
89+ };
90+
91+ struct LocationInfoCmp {
92+ bool operator ()(LocationInfo *const a, LocationInfo *const b) const {
93+ return *a == *b;
94+ }
95+ };
96+
97+ using CacheType =
98+ std::unordered_set<LocationInfo *, LocationInfoHash, LocationInfoCmp>;
99+
100+ struct LocationInfoCacheSet {
101+ CacheType cache;
102+ ~LocationInfoCacheSet () {
103+ while (cache.size () != 0 ) {
104+ ref<LocationInfo> tmp = *cache.begin ();
105+ tmp->isCached = false ;
106+ cache.erase (cache.begin ());
107+ }
108+ }
109+ };
110+
111+ static LocationInfoCacheSet cachedLocationInfo;
112+ bool isCached = false ;
113+ bool toBeCleared = false ;
114+
115+ static ref<LocationInfo>
116+ createCachedLocationInfo (ref<LocationInfo> locationInfo);
50117};
51118
52- LocationInfo getLocationInfo (const llvm::Function *func);
53- LocationInfo getLocationInfo (const llvm::Instruction *inst);
54- LocationInfo getLocationInfo (const llvm::GlobalVariable *global);
119+ ref< LocationInfo> getLocationInfo (const llvm::Function *func);
120+ ref< LocationInfo> getLocationInfo (const llvm::Instruction *inst);
121+ ref< LocationInfo> getLocationInfo (const llvm::GlobalVariable *global);
55122
56123} // namespace klee
57124
0 commit comments