svf-lib 1.0.730 → 1.0.734
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SVF-linux/Release-build/lib/libSvf.a +0 -0
- package/SVF-linux/include/DDA/ContextDDA.h +1 -1
- package/SVF-linux/include/DDA/DDAClient.h +8 -8
- package/SVF-linux/include/DDA/DDAVFSolver.h +6 -6
- package/SVF-linux/include/DDA/FlowDDA.h +1 -1
- package/SVF-linux/include/Graphs/ConsG.h +6 -6
- package/SVF-linux/include/Graphs/ConsGEdge.h +2 -2
- package/SVF-linux/include/Graphs/ConsGNode.h +1 -1
- package/SVF-linux/include/Graphs/ExternalPAG.h +14 -14
- package/SVF-linux/include/Graphs/ICFGNode.h +14 -14
- package/SVF-linux/include/Graphs/IRGraph.h +245 -0
- package/SVF-linux/include/Graphs/OfflineConsG.h +1 -1
- package/SVF-linux/include/Graphs/PAG.h +4 -4
- package/SVF-linux/include/Graphs/PAGNode.h +3 -3
- package/SVF-linux/include/Graphs/SVFG.h +1 -1
- package/SVF-linux/include/Graphs/SVFGOPT.h +3 -3
- package/SVF-linux/include/Graphs/VFG.h +19 -19
- package/SVF-linux/include/Graphs/VFGNode.h +2 -3
- package/SVF-linux/include/MSSA/MemRegion.h +11 -11
- package/SVF-linux/include/MSSA/MemSSA.h +4 -4
- package/SVF-linux/include/MTA/FSMPTA.h +1 -1
- package/SVF-linux/include/MemoryModel/PAGBuilderFromFile.h +8 -8
- package/SVF-linux/include/MemoryModel/PTAStat.h +31 -31
- package/SVF-linux/include/MemoryModel/PointerAnalysis.h +9 -9
- package/SVF-linux/include/MemoryModel/PointerAnalysisImpl.h +3 -3
- package/SVF-linux/include/MemoryModel/SVFIR.h +591 -233
- package/SVF-linux/include/MemoryModel/SVFStatements.h +738 -0
- package/SVF-linux/include/MemoryModel/SVFSymbols.h +648 -0
- package/SVF-linux/include/MemoryModel/SVFVariables.h +842 -0
- package/SVF-linux/include/MemoryModel/SymbolTableInfo.h +343 -40
- package/SVF-linux/include/SABER/SaberSVFGBuilder.h +0 -2
- package/SVF-linux/include/SABER/SrcSnkDDA.h +3 -3
- package/SVF-linux/include/SVF-FE/Graph2Json.h +1 -3
- package/SVF-linux/include/SVF-FE/SVFIRBuilder.h +392 -0
- package/SVF-linux/include/SVF-FE/SymbolTableBuilder.h +0 -1
- package/SVF-linux/include/Util/CFLSolver.h +1 -1
- package/SVF-linux/include/Util/ExtAPI.h +1 -1
- package/SVF-linux/include/Util/IRAnnotator.h +6 -6
- package/SVF-linux/include/Util/Options.h +1 -1
- package/SVF-linux/include/Util/TypeBasedHeapCloning.h +11 -11
- package/SVF-linux/include/WPA/Andersen.h +11 -11
- package/SVF-linux/include/WPA/AndersenSFR.h +4 -4
- package/SVF-linux/include/WPA/FlowSensitive.h +2 -2
- package/SVF-linux/include/WPA/FlowSensitiveTBHC.h +1 -1
- package/SVF-linux/include/WPA/Steensgaard.h +2 -2
- package/SVF-linux/include/WPA/TypeAnalysis.h +1 -1
- package/SVF-linux/include/WPA/VersionedFlowSensitive.h +2 -2
- package/SVF-linux/include/WPA/WPAStat.h +1 -2
- package/SVF-osx/Release-build/lib/CUDD/libCudd.a +0 -0
- package/SVF-osx/Release-build/lib/libSvf.a +0 -0
- package/SVF-osx/include/DDA/ContextDDA.h +1 -1
- package/SVF-osx/include/DDA/DDAClient.h +8 -8
- package/SVF-osx/include/DDA/DDAVFSolver.h +6 -6
- package/SVF-osx/include/DDA/FlowDDA.h +1 -1
- package/SVF-osx/include/Graphs/ConsG.h +6 -6
- package/SVF-osx/include/Graphs/ConsGEdge.h +2 -2
- package/SVF-osx/include/Graphs/ConsGNode.h +1 -1
- package/SVF-osx/include/Graphs/ExternalPAG.h +14 -14
- package/SVF-osx/include/Graphs/ICFGNode.h +14 -14
- package/SVF-osx/include/Graphs/IRGraph.h +245 -0
- package/SVF-osx/include/Graphs/OfflineConsG.h +1 -1
- package/SVF-osx/include/Graphs/PAG.h +4 -4
- package/SVF-osx/include/Graphs/PAGNode.h +3 -3
- package/SVF-osx/include/Graphs/SVFG.h +1 -1
- package/SVF-osx/include/Graphs/SVFGOPT.h +3 -3
- package/SVF-osx/include/Graphs/VFG.h +19 -19
- package/SVF-osx/include/Graphs/VFGNode.h +2 -3
- package/SVF-osx/include/MSSA/MemRegion.h +11 -11
- package/SVF-osx/include/MSSA/MemSSA.h +4 -4
- package/SVF-osx/include/MTA/FSMPTA.h +1 -1
- package/SVF-osx/include/MemoryModel/PAGBuilderFromFile.h +8 -8
- package/SVF-osx/include/MemoryModel/PTAStat.h +31 -31
- package/SVF-osx/include/MemoryModel/PointerAnalysis.h +9 -9
- package/SVF-osx/include/MemoryModel/PointerAnalysisImpl.h +3 -3
- package/SVF-osx/include/MemoryModel/SVFIR.h +591 -233
- package/SVF-osx/include/MemoryModel/SVFStatements.h +738 -0
- package/SVF-osx/include/MemoryModel/SVFSymbols.h +648 -0
- package/SVF-osx/include/MemoryModel/SVFVariables.h +842 -0
- package/SVF-osx/include/MemoryModel/SymbolTableInfo.h +343 -40
- package/SVF-osx/include/SABER/SaberSVFGBuilder.h +0 -2
- package/SVF-osx/include/SABER/SrcSnkDDA.h +3 -3
- package/SVF-osx/include/SVF-FE/Graph2Json.h +1 -3
- package/SVF-osx/include/SVF-FE/SVFIRBuilder.h +392 -0
- package/SVF-osx/include/SVF-FE/SymbolTableBuilder.h +0 -1
- package/SVF-osx/include/Util/CFLSolver.h +1 -1
- package/SVF-osx/include/Util/ExtAPI.h +1 -1
- package/SVF-osx/include/Util/IRAnnotator.h +6 -6
- package/SVF-osx/include/Util/Options.h +1 -1
- package/SVF-osx/include/Util/TypeBasedHeapCloning.h +11 -11
- package/SVF-osx/include/WPA/Andersen.h +11 -11
- package/SVF-osx/include/WPA/AndersenSFR.h +4 -4
- package/SVF-osx/include/WPA/FlowSensitive.h +2 -2
- package/SVF-osx/include/WPA/FlowSensitiveTBHC.h +1 -1
- package/SVF-osx/include/WPA/Steensgaard.h +2 -2
- package/SVF-osx/include/WPA/TypeAnalysis.h +1 -1
- package/SVF-osx/include/WPA/VersionedFlowSensitive.h +2 -2
- package/SVF-osx/include/WPA/WPAStat.h +1 -2
- package/package.json +1 -1
|
@@ -0,0 +1,842 @@
|
|
|
1
|
+
//===- SVFSymbols.h -- SVF Variables------------------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* SVFVariables.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: Nov 11, 2013
|
|
27
|
+
* Author: Yulei Sui
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#ifndef OBJECTANDSYMBOL_H_
|
|
31
|
+
#define OBJECTANDSYMBOL_H_
|
|
32
|
+
|
|
33
|
+
#include "Graphs/GenericGraph.h"
|
|
34
|
+
#include "MemoryModel/SymbolTableInfo.h"
|
|
35
|
+
#include "SVF-FE/LLVMUtil.h"
|
|
36
|
+
#include "MemoryModel/SVFStatements.h"
|
|
37
|
+
|
|
38
|
+
namespace SVF
|
|
39
|
+
{
|
|
40
|
+
|
|
41
|
+
class SVFVar;
|
|
42
|
+
/*
|
|
43
|
+
* SVFIR node
|
|
44
|
+
*/
|
|
45
|
+
typedef GenericNode<SVFVar,SVFStmt> GenericPAGNodeTy;
|
|
46
|
+
class SVFVar : public GenericPAGNodeTy
|
|
47
|
+
{
|
|
48
|
+
|
|
49
|
+
public:
|
|
50
|
+
/// Nine kinds of SVFIR nodes
|
|
51
|
+
/// ValNode: llvm pointer value
|
|
52
|
+
/// ObjNode: memory object
|
|
53
|
+
/// RetNode: unique return node
|
|
54
|
+
/// Vararg: unique node for vararg parameter
|
|
55
|
+
/// GepValNode: tempory gep value node for field sensitivity
|
|
56
|
+
/// GepValNode: tempory gep obj node for field sensitivity
|
|
57
|
+
/// FIObjNode: for field insensitive analysis
|
|
58
|
+
/// DummyValNode and DummyObjNode: for non-llvm-value node
|
|
59
|
+
/// Clone*Node: objects created by TBHC.
|
|
60
|
+
enum PNODEK
|
|
61
|
+
{
|
|
62
|
+
ValNode,
|
|
63
|
+
ObjNode,
|
|
64
|
+
RetNode,
|
|
65
|
+
VarargNode,
|
|
66
|
+
GepValNode,
|
|
67
|
+
GepObjNode,
|
|
68
|
+
FIObjNode,
|
|
69
|
+
DummyValNode,
|
|
70
|
+
DummyObjNode,
|
|
71
|
+
CloneGepObjNode, // NOTE: only used for TBHC.
|
|
72
|
+
CloneFIObjNode, // NOTE: only used for TBHC.
|
|
73
|
+
CloneDummyObjNode // NOTE: only used for TBHC.
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
protected:
|
|
78
|
+
const Value* value; ///< value of this SVFIR node
|
|
79
|
+
SVFStmt::PAGKindToEdgeSetMapTy InEdgeKindToSetMap;
|
|
80
|
+
SVFStmt::PAGKindToEdgeSetMapTy OutEdgeKindToSetMap;
|
|
81
|
+
bool isTLPointer; /// top-level pointer
|
|
82
|
+
bool isATPointer; /// address-taken pointer
|
|
83
|
+
|
|
84
|
+
public:
|
|
85
|
+
/// Constructor
|
|
86
|
+
SVFVar(const Value* val, NodeID i, PNODEK k);
|
|
87
|
+
/// Destructor
|
|
88
|
+
virtual ~SVFVar()
|
|
89
|
+
{
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/// Get/has methods of the components
|
|
93
|
+
//@{
|
|
94
|
+
inline const Value* getValue() const
|
|
95
|
+
{
|
|
96
|
+
assert((this->getNodeKind() != DummyValNode && this->getNodeKind() != DummyObjNode) && "dummy node do not have value!");
|
|
97
|
+
assert((SymbolTableInfo::isBlkObjOrConstantObj(this->getId())==false) && "blackhole and constant obj do not have value");
|
|
98
|
+
assert(value && "value is null (GepObjNode whose basenode is a DummyObj?)");
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/// Return type of the value
|
|
103
|
+
inline virtual const Type* getType() const
|
|
104
|
+
{
|
|
105
|
+
if (value)
|
|
106
|
+
return value->getType();
|
|
107
|
+
return nullptr;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
inline bool hasValue() const
|
|
111
|
+
{
|
|
112
|
+
return value!=nullptr;
|
|
113
|
+
}
|
|
114
|
+
/// Whether it is a pointer
|
|
115
|
+
virtual inline bool isPointer() const
|
|
116
|
+
{
|
|
117
|
+
return isTopLevelPtr() || isAddressTakenPtr();
|
|
118
|
+
}
|
|
119
|
+
/// Whether it is a top-level pointer
|
|
120
|
+
inline bool isTopLevelPtr() const
|
|
121
|
+
{
|
|
122
|
+
return isTLPointer;
|
|
123
|
+
}
|
|
124
|
+
/// Whether it is an address-taken pointer
|
|
125
|
+
inline bool isAddressTakenPtr() const
|
|
126
|
+
{
|
|
127
|
+
return isATPointer;
|
|
128
|
+
}
|
|
129
|
+
/// Whether it is constant data, i.e., "0", "1.001", "str"
|
|
130
|
+
/// or llvm's metadata, i.e., metadata !4087
|
|
131
|
+
inline bool isConstantData() const
|
|
132
|
+
{
|
|
133
|
+
if (hasValue())
|
|
134
|
+
return SVFUtil::isConstantData(value);
|
|
135
|
+
else
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/// Whether this is an isoloated node on the SVFIR graph
|
|
140
|
+
bool isIsolatedNode() const;
|
|
141
|
+
|
|
142
|
+
/// Get name of the LLVM value
|
|
143
|
+
virtual const std::string getValueName() const = 0;
|
|
144
|
+
|
|
145
|
+
/// Return the function that this SVFVar resides in. Return nullptr if it is a global or constantexpr node
|
|
146
|
+
virtual inline const Function* getFunction() const
|
|
147
|
+
{
|
|
148
|
+
if(value)
|
|
149
|
+
{
|
|
150
|
+
if(const Instruction* inst = SVFUtil::dyn_cast<Instruction>(value))
|
|
151
|
+
return inst->getParent()->getParent();
|
|
152
|
+
else if (const Argument* arg = SVFUtil::dyn_cast<Argument>(value))
|
|
153
|
+
return arg->getParent();
|
|
154
|
+
else if (const Function* fun = SVFUtil::dyn_cast<Function>(value))
|
|
155
|
+
return fun;
|
|
156
|
+
}
|
|
157
|
+
return nullptr;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/// Get incoming SVFIR edges
|
|
161
|
+
inline SVFStmt::PAGEdgeSetTy& getIncomingEdges(SVFStmt::PEDGEK kind)
|
|
162
|
+
{
|
|
163
|
+
return InEdgeKindToSetMap[kind];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/// Get outgoing SVFIR edges
|
|
167
|
+
inline SVFStmt::PAGEdgeSetTy& getOutgoingEdges(SVFStmt::PEDGEK kind)
|
|
168
|
+
{
|
|
169
|
+
return OutEdgeKindToSetMap[kind];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/// Has incoming SVFIR edges
|
|
173
|
+
inline bool hasIncomingEdges(SVFStmt::PEDGEK kind) const
|
|
174
|
+
{
|
|
175
|
+
SVFStmt::PAGKindToEdgeSetMapTy::const_iterator it = InEdgeKindToSetMap.find(kind);
|
|
176
|
+
if (it != InEdgeKindToSetMap.end())
|
|
177
|
+
return (!it->second.empty());
|
|
178
|
+
else
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/// Has incoming VariantGepEdges
|
|
183
|
+
inline bool hasIncomingVariantGepEdge() const
|
|
184
|
+
{
|
|
185
|
+
SVFStmt::PAGKindToEdgeSetMapTy::const_iterator it = InEdgeKindToSetMap.find(SVFStmt::VariantGep);
|
|
186
|
+
if (it != InEdgeKindToSetMap.end())
|
|
187
|
+
{
|
|
188
|
+
return (!it->second.empty());
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/// Get incoming SVFStmt iterator
|
|
194
|
+
inline SVFStmt::PAGEdgeSetTy::iterator getIncomingEdgesBegin(SVFStmt::PEDGEK kind) const
|
|
195
|
+
{
|
|
196
|
+
SVFStmt::PAGKindToEdgeSetMapTy::const_iterator it = InEdgeKindToSetMap.find(kind);
|
|
197
|
+
assert(it!=InEdgeKindToSetMap.end() && "The node does not have such kind of edge");
|
|
198
|
+
return it->second.begin();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/// Get incoming SVFStmt iterator
|
|
202
|
+
inline SVFStmt::PAGEdgeSetTy::iterator getIncomingEdgesEnd(SVFStmt::PEDGEK kind) const
|
|
203
|
+
{
|
|
204
|
+
SVFStmt::PAGKindToEdgeSetMapTy::const_iterator it = InEdgeKindToSetMap.find(kind);
|
|
205
|
+
assert(it!=InEdgeKindToSetMap.end() && "The node does not have such kind of edge");
|
|
206
|
+
return it->second.end();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/// Has outgoing SVFIR edges
|
|
210
|
+
inline bool hasOutgoingEdges(SVFStmt::PEDGEK kind) const
|
|
211
|
+
{
|
|
212
|
+
SVFStmt::PAGKindToEdgeSetMapTy::const_iterator it = OutEdgeKindToSetMap.find(kind);
|
|
213
|
+
if (it != OutEdgeKindToSetMap.end())
|
|
214
|
+
return (!it->second.empty());
|
|
215
|
+
else
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/// Get outgoing SVFStmt iterator
|
|
220
|
+
inline SVFStmt::PAGEdgeSetTy::iterator getOutgoingEdgesBegin(SVFStmt::PEDGEK kind) const
|
|
221
|
+
{
|
|
222
|
+
SVFStmt::PAGKindToEdgeSetMapTy::const_iterator it = OutEdgeKindToSetMap.find(kind);
|
|
223
|
+
assert(it!=OutEdgeKindToSetMap.end() && "The node does not have such kind of edge");
|
|
224
|
+
return it->second.begin();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/// Get outgoing SVFStmt iterator
|
|
228
|
+
inline SVFStmt::PAGEdgeSetTy::iterator getOutgoingEdgesEnd(SVFStmt::PEDGEK kind) const
|
|
229
|
+
{
|
|
230
|
+
SVFStmt::PAGKindToEdgeSetMapTy::const_iterator it = OutEdgeKindToSetMap.find(kind);
|
|
231
|
+
assert(it!=OutEdgeKindToSetMap.end() && "The node does not have such kind of edge");
|
|
232
|
+
return it->second.end();
|
|
233
|
+
}
|
|
234
|
+
//@}
|
|
235
|
+
|
|
236
|
+
/// add methods of the components
|
|
237
|
+
//@{
|
|
238
|
+
inline void addInEdge(SVFStmt* inEdge)
|
|
239
|
+
{
|
|
240
|
+
GNodeK kind = inEdge->getEdgeKind();
|
|
241
|
+
InEdgeKindToSetMap[kind].insert(inEdge);
|
|
242
|
+
addIncomingEdge(inEdge);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
inline void addOutEdge(SVFStmt* outEdge)
|
|
246
|
+
{
|
|
247
|
+
GNodeK kind = outEdge->getEdgeKind();
|
|
248
|
+
OutEdgeKindToSetMap[kind].insert(outEdge);
|
|
249
|
+
addOutgoingEdge(outEdge);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
virtual const std::string toString() const;
|
|
253
|
+
|
|
254
|
+
/// Dump to console for debugging
|
|
255
|
+
void dump() const;
|
|
256
|
+
|
|
257
|
+
//@}
|
|
258
|
+
/// Overloading operator << for dumping SVFVar value
|
|
259
|
+
//@{
|
|
260
|
+
friend raw_ostream& operator<< (raw_ostream &o, const SVFVar &node)
|
|
261
|
+
{
|
|
262
|
+
o << node.toString();
|
|
263
|
+
return o;
|
|
264
|
+
}
|
|
265
|
+
//@}
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
/*
|
|
271
|
+
* Value(Pointer) node
|
|
272
|
+
*/
|
|
273
|
+
class ValPN: public SVFVar
|
|
274
|
+
{
|
|
275
|
+
|
|
276
|
+
public:
|
|
277
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
278
|
+
//@{
|
|
279
|
+
static inline bool classof(const ValPN *)
|
|
280
|
+
{
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
static inline bool classof(const SVFVar *node)
|
|
284
|
+
{
|
|
285
|
+
return node->getNodeKind() == SVFVar::ValNode ||
|
|
286
|
+
node->getNodeKind() == SVFVar::GepValNode ||
|
|
287
|
+
node->getNodeKind() == SVFVar::DummyValNode;
|
|
288
|
+
}
|
|
289
|
+
static inline bool classof(const GenericPAGNodeTy *node)
|
|
290
|
+
{
|
|
291
|
+
return node->getNodeKind() == SVFVar::ValNode ||
|
|
292
|
+
node->getNodeKind() == SVFVar::GepValNode ||
|
|
293
|
+
node->getNodeKind() == SVFVar::DummyValNode;
|
|
294
|
+
}
|
|
295
|
+
//@}
|
|
296
|
+
|
|
297
|
+
/// Constructor
|
|
298
|
+
ValPN(const Value* val, NodeID i, PNODEK ty = ValNode) :
|
|
299
|
+
SVFVar(val, i, ty)
|
|
300
|
+
{
|
|
301
|
+
}
|
|
302
|
+
/// Return name of a LLVM value
|
|
303
|
+
inline const std::string getValueName() const
|
|
304
|
+
{
|
|
305
|
+
if (value && value->hasName())
|
|
306
|
+
return value->getName().str();
|
|
307
|
+
return "";
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
virtual const std::string toString() const;
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
/*
|
|
315
|
+
* Memory Object node
|
|
316
|
+
*/
|
|
317
|
+
class ObjPN: public SVFVar
|
|
318
|
+
{
|
|
319
|
+
|
|
320
|
+
protected:
|
|
321
|
+
const MemObj* mem; ///< memory object
|
|
322
|
+
/// Constructor
|
|
323
|
+
ObjPN(const Value* val, NodeID i, const MemObj* m, PNODEK ty = ObjNode) :
|
|
324
|
+
SVFVar(val, i, ty), mem(m)
|
|
325
|
+
{
|
|
326
|
+
}
|
|
327
|
+
public:
|
|
328
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
329
|
+
//@{
|
|
330
|
+
static inline bool classof(const ObjPN *)
|
|
331
|
+
{
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
static inline bool classof(const SVFVar *node)
|
|
335
|
+
{
|
|
336
|
+
return node->getNodeKind() == SVFVar::ObjNode ||
|
|
337
|
+
node->getNodeKind() == SVFVar::GepObjNode ||
|
|
338
|
+
node->getNodeKind() == SVFVar::FIObjNode ||
|
|
339
|
+
node->getNodeKind() == SVFVar::DummyObjNode ||
|
|
340
|
+
node->getNodeKind() == SVFVar::CloneGepObjNode ||
|
|
341
|
+
node->getNodeKind() == SVFVar::CloneFIObjNode ||
|
|
342
|
+
node->getNodeKind() == SVFVar::CloneDummyObjNode;
|
|
343
|
+
}
|
|
344
|
+
static inline bool classof(const GenericPAGNodeTy *node)
|
|
345
|
+
{
|
|
346
|
+
return node->getNodeKind() == SVFVar::ObjNode ||
|
|
347
|
+
node->getNodeKind() == SVFVar::GepObjNode ||
|
|
348
|
+
node->getNodeKind() == SVFVar::FIObjNode ||
|
|
349
|
+
node->getNodeKind() == SVFVar::DummyObjNode ||
|
|
350
|
+
node->getNodeKind() == SVFVar::CloneGepObjNode ||
|
|
351
|
+
node->getNodeKind() == SVFVar::CloneFIObjNode ||
|
|
352
|
+
node->getNodeKind() == SVFVar::CloneDummyObjNode;
|
|
353
|
+
}
|
|
354
|
+
//@}
|
|
355
|
+
|
|
356
|
+
/// Return memory object
|
|
357
|
+
const MemObj* getMemObj() const
|
|
358
|
+
{
|
|
359
|
+
return mem;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/// Return name of a LLVM value
|
|
363
|
+
virtual const std::string getValueName() const
|
|
364
|
+
{
|
|
365
|
+
if (value && value->hasName())
|
|
366
|
+
return value->getName().str();
|
|
367
|
+
return "";
|
|
368
|
+
}
|
|
369
|
+
/// Return type of the value
|
|
370
|
+
inline virtual const llvm::Type* getType() const
|
|
371
|
+
{
|
|
372
|
+
return mem->getType();
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
virtual const std::string toString() const;
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
/*
|
|
380
|
+
* Gep Value (Pointer) node, this node can be dynamic generated for field sensitive analysis
|
|
381
|
+
* e.g. memcpy, temp gep value node needs to be created
|
|
382
|
+
* Each Gep Value node is connected to base value node via gep edge
|
|
383
|
+
*/
|
|
384
|
+
class GepValPN: public ValPN
|
|
385
|
+
{
|
|
386
|
+
|
|
387
|
+
private:
|
|
388
|
+
LocationSet ls; // LocationSet
|
|
389
|
+
const Type *gepValType;
|
|
390
|
+
u32_t fieldIdx;
|
|
391
|
+
|
|
392
|
+
public:
|
|
393
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
394
|
+
//@{
|
|
395
|
+
static inline bool classof(const GepValPN *)
|
|
396
|
+
{
|
|
397
|
+
return true;
|
|
398
|
+
}
|
|
399
|
+
static inline bool classof(const ValPN * node)
|
|
400
|
+
{
|
|
401
|
+
return node->getNodeKind() == SVFVar::GepValNode;
|
|
402
|
+
}
|
|
403
|
+
static inline bool classof(const SVFVar *node)
|
|
404
|
+
{
|
|
405
|
+
return node->getNodeKind() == SVFVar::GepValNode;
|
|
406
|
+
}
|
|
407
|
+
static inline bool classof(const GenericPAGNodeTy *node)
|
|
408
|
+
{
|
|
409
|
+
return node->getNodeKind() == SVFVar::GepValNode;
|
|
410
|
+
}
|
|
411
|
+
//@}
|
|
412
|
+
|
|
413
|
+
/// Constructor
|
|
414
|
+
GepValPN(const Value* val, NodeID i, const LocationSet& l, const Type *ty, u32_t idx) :
|
|
415
|
+
ValPN(val, i, GepValNode), ls(l), gepValType(ty), fieldIdx(idx)
|
|
416
|
+
{
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/// offset of the base value node
|
|
420
|
+
inline u32_t getOffset() const
|
|
421
|
+
{
|
|
422
|
+
return ls.getOffset();
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/// Return name of a LLVM value
|
|
426
|
+
inline const std::string getValueName() const
|
|
427
|
+
{
|
|
428
|
+
if (value && value->hasName())
|
|
429
|
+
return value->getName().str() + "_" + llvm::utostr(getOffset());
|
|
430
|
+
return "offset_" + llvm::utostr(getOffset());
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
inline const Type* getType() const
|
|
434
|
+
{
|
|
435
|
+
return gepValType;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
u32_t getFieldIdx() const
|
|
439
|
+
{
|
|
440
|
+
return fieldIdx;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
virtual const std::string toString() const;
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
/*
|
|
448
|
+
* Gep Obj node, this is dynamic generated for field sensitive analysis
|
|
449
|
+
* Each gep obj node is one field of a MemObj (base)
|
|
450
|
+
*/
|
|
451
|
+
class GepObjPN: public ObjPN
|
|
452
|
+
{
|
|
453
|
+
private:
|
|
454
|
+
LocationSet ls;
|
|
455
|
+
NodeID base = 0;
|
|
456
|
+
|
|
457
|
+
public:
|
|
458
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
459
|
+
//@{
|
|
460
|
+
static inline bool classof(const GepObjPN *)
|
|
461
|
+
{
|
|
462
|
+
return true;
|
|
463
|
+
}
|
|
464
|
+
static inline bool classof(const ObjPN * node)
|
|
465
|
+
{
|
|
466
|
+
return node->getNodeKind() == SVFVar::GepObjNode
|
|
467
|
+
|| node->getNodeKind() == SVFVar::CloneGepObjNode;
|
|
468
|
+
}
|
|
469
|
+
static inline bool classof(const SVFVar *node)
|
|
470
|
+
{
|
|
471
|
+
return node->getNodeKind() == SVFVar::GepObjNode
|
|
472
|
+
|| node->getNodeKind() == SVFVar::CloneGepObjNode;
|
|
473
|
+
}
|
|
474
|
+
static inline bool classof(const GenericPAGNodeTy *node)
|
|
475
|
+
{
|
|
476
|
+
return node->getNodeKind() == SVFVar::GepObjNode
|
|
477
|
+
|| node->getNodeKind() == SVFVar::CloneGepObjNode;
|
|
478
|
+
}
|
|
479
|
+
//@}
|
|
480
|
+
|
|
481
|
+
/// Constructor
|
|
482
|
+
GepObjPN(const MemObj* mem, NodeID i, const LocationSet& l, PNODEK ty = GepObjNode) :
|
|
483
|
+
ObjPN(mem->getValue(), i, mem, ty), ls(l)
|
|
484
|
+
{
|
|
485
|
+
base = mem->getId();
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/// offset of the mem object
|
|
489
|
+
inline const LocationSet& getLocationSet() const
|
|
490
|
+
{
|
|
491
|
+
return ls;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/// Set the base object from which this GEP node came from.
|
|
495
|
+
inline void setBaseNode(NodeID base)
|
|
496
|
+
{
|
|
497
|
+
this->base = base;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/// Return the base object from which this GEP node came from.
|
|
501
|
+
inline NodeID getBaseNode(void) const
|
|
502
|
+
{
|
|
503
|
+
return base;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/// Return the type of this gep object
|
|
507
|
+
inline virtual const llvm::Type* getType() const
|
|
508
|
+
{
|
|
509
|
+
return SymbolTableInfo::SymbolInfo()->getOrigSubTypeWithByteOffset(mem->getType(), ls.getByteOffset());
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/// Return name of a LLVM value
|
|
513
|
+
inline const std::string getValueName() const
|
|
514
|
+
{
|
|
515
|
+
if (value && value->hasName())
|
|
516
|
+
return value->getName().str() + "_" + llvm::itostr(ls.getOffset());
|
|
517
|
+
return "offset_" + llvm::itostr(ls.getOffset());
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
virtual const std::string toString() const;
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
/*
|
|
524
|
+
* Field-insensitive Gep Obj node, this is dynamic generated for field sensitive analysis
|
|
525
|
+
* Each field-insensitive gep obj node represents all fields of a MemObj (base)
|
|
526
|
+
*/
|
|
527
|
+
class FIObjPN: public ObjPN
|
|
528
|
+
{
|
|
529
|
+
public:
|
|
530
|
+
|
|
531
|
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
532
|
+
//@{
|
|
533
|
+
static inline bool classof(const FIObjPN *)
|
|
534
|
+
{
|
|
535
|
+
return true;
|
|
536
|
+
}
|
|
537
|
+
static inline bool classof(const ObjPN * node)
|
|
538
|
+
{
|
|
539
|
+
return node->getNodeKind() == SVFVar::FIObjNode
|
|
540
|
+
|| node->getNodeKind() == SVFVar::CloneFIObjNode;
|
|
541
|
+
}
|
|
542
|
+
static inline bool classof(const SVFVar *node)
|
|
543
|
+
{
|
|
544
|
+
return node->getNodeKind() == SVFVar::FIObjNode
|
|
545
|
+
|| node->getNodeKind() == SVFVar::CloneFIObjNode;
|
|
546
|
+
}
|
|
547
|
+
static inline bool classof(const GenericPAGNodeTy *node)
|
|
548
|
+
{
|
|
549
|
+
return node->getNodeKind() == SVFVar::FIObjNode
|
|
550
|
+
|| node->getNodeKind() == SVFVar::CloneFIObjNode;
|
|
551
|
+
}
|
|
552
|
+
//@}
|
|
553
|
+
|
|
554
|
+
/// Constructor
|
|
555
|
+
FIObjPN(const Value* val, NodeID i, const MemObj* mem, PNODEK ty = FIObjNode) :
|
|
556
|
+
ObjPN(val, i, mem, ty)
|
|
557
|
+
{
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/// Return name of a LLVM value
|
|
561
|
+
inline const std::string getValueName() const
|
|
562
|
+
{
|
|
563
|
+
if (value && value->hasName())
|
|
564
|
+
return value->getName().str() + " (base object)";
|
|
565
|
+
return " (base object)";
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
virtual const std::string toString() const;
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
/*
|
|
572
|
+
* Unique Return node of a procedure
|
|
573
|
+
*/
|
|
574
|
+
class RetPN: public SVFVar
|
|
575
|
+
{
|
|
576
|
+
|
|
577
|
+
public:
|
|
578
|
+
|
|
579
|
+
//@{ Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
580
|
+
static inline bool classof(const RetPN *)
|
|
581
|
+
{
|
|
582
|
+
return true;
|
|
583
|
+
}
|
|
584
|
+
static inline bool classof(const SVFVar *node)
|
|
585
|
+
{
|
|
586
|
+
return node->getNodeKind() == SVFVar::RetNode;
|
|
587
|
+
}
|
|
588
|
+
static inline bool classof(const GenericPAGNodeTy *node)
|
|
589
|
+
{
|
|
590
|
+
return node->getNodeKind() == SVFVar::RetNode;
|
|
591
|
+
}
|
|
592
|
+
//@}
|
|
593
|
+
|
|
594
|
+
/// Constructor
|
|
595
|
+
RetPN(const SVFFunction* val, NodeID i) :
|
|
596
|
+
SVFVar(val->getLLVMFun(), i, RetNode)
|
|
597
|
+
{
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/// Return name of a LLVM value
|
|
601
|
+
const std::string getValueName() const
|
|
602
|
+
{
|
|
603
|
+
return value->getName().str() + "_ret";
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
virtual const std::string toString() const;
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
/*
|
|
611
|
+
* Unique vararg node of a procedure
|
|
612
|
+
*/
|
|
613
|
+
class VarArgPN: public SVFVar
|
|
614
|
+
{
|
|
615
|
+
|
|
616
|
+
public:
|
|
617
|
+
|
|
618
|
+
//@{ Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
619
|
+
static inline bool classof(const VarArgPN *)
|
|
620
|
+
{
|
|
621
|
+
return true;
|
|
622
|
+
}
|
|
623
|
+
static inline bool classof(const SVFVar *node)
|
|
624
|
+
{
|
|
625
|
+
return node->getNodeKind() == SVFVar::VarargNode;
|
|
626
|
+
}
|
|
627
|
+
static inline bool classof(const GenericPAGNodeTy *node)
|
|
628
|
+
{
|
|
629
|
+
return node->getNodeKind() == SVFVar::VarargNode;
|
|
630
|
+
}
|
|
631
|
+
//@}
|
|
632
|
+
|
|
633
|
+
/// Constructor
|
|
634
|
+
VarArgPN(const SVFFunction* val, NodeID i) :
|
|
635
|
+
SVFVar(val->getLLVMFun(), i, VarargNode)
|
|
636
|
+
{
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/// Return name of a LLVM value
|
|
640
|
+
inline const std::string getValueName() const
|
|
641
|
+
{
|
|
642
|
+
return value->getName().str() + "_vararg";
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
virtual const std::string toString() const;
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
/*
|
|
652
|
+
* Dummy node
|
|
653
|
+
*/
|
|
654
|
+
class DummyValPN: public ValPN
|
|
655
|
+
{
|
|
656
|
+
|
|
657
|
+
public:
|
|
658
|
+
|
|
659
|
+
//@{ Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
660
|
+
static inline bool classof(const DummyValPN *)
|
|
661
|
+
{
|
|
662
|
+
return true;
|
|
663
|
+
}
|
|
664
|
+
static inline bool classof(const SVFVar *node)
|
|
665
|
+
{
|
|
666
|
+
return node->getNodeKind() == SVFVar::DummyValNode;
|
|
667
|
+
}
|
|
668
|
+
static inline bool classof(const GenericPAGNodeTy *node)
|
|
669
|
+
{
|
|
670
|
+
return node->getNodeKind() == SVFVar::DummyValNode;
|
|
671
|
+
}
|
|
672
|
+
//@}
|
|
673
|
+
|
|
674
|
+
/// Constructor
|
|
675
|
+
DummyValPN(NodeID i) : ValPN(nullptr, i, DummyValNode)
|
|
676
|
+
{
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
/// Return name of this node
|
|
681
|
+
inline const std::string getValueName() const
|
|
682
|
+
{
|
|
683
|
+
return "dummyVal";
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
virtual const std::string toString() const;
|
|
687
|
+
};
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
/*
|
|
691
|
+
* Dummy node
|
|
692
|
+
*/
|
|
693
|
+
class DummyObjPN: public ObjPN
|
|
694
|
+
{
|
|
695
|
+
|
|
696
|
+
public:
|
|
697
|
+
|
|
698
|
+
//@{ Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
699
|
+
static inline bool classof(const DummyObjPN *)
|
|
700
|
+
{
|
|
701
|
+
return true;
|
|
702
|
+
}
|
|
703
|
+
static inline bool classof(const SVFVar *node)
|
|
704
|
+
{
|
|
705
|
+
return node->getNodeKind() == SVFVar::DummyObjNode
|
|
706
|
+
|| node->getNodeKind() == SVFVar::CloneDummyObjNode;
|
|
707
|
+
}
|
|
708
|
+
static inline bool classof(const GenericPAGNodeTy *node)
|
|
709
|
+
{
|
|
710
|
+
return node->getNodeKind() == SVFVar::DummyObjNode
|
|
711
|
+
|| node->getNodeKind() == SVFVar::CloneDummyObjNode;
|
|
712
|
+
}
|
|
713
|
+
//@}
|
|
714
|
+
|
|
715
|
+
/// Constructor
|
|
716
|
+
DummyObjPN(NodeID i,const MemObj* m, PNODEK ty = DummyObjNode)
|
|
717
|
+
: ObjPN(nullptr, i, m, ty)
|
|
718
|
+
{
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/// Return name of this node
|
|
722
|
+
inline const std::string getValueName() const
|
|
723
|
+
{
|
|
724
|
+
return "dummyObj";
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
virtual const std::string toString() const;
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
/*
|
|
731
|
+
* Clone object node for dummy objects.
|
|
732
|
+
*/
|
|
733
|
+
class CloneDummyObjPN: public DummyObjPN
|
|
734
|
+
{
|
|
735
|
+
public:
|
|
736
|
+
//@{ Methods to support type inquiry through isa, cast, and dyn_cast:
|
|
737
|
+
static inline bool classof(const CloneDummyObjPN *)
|
|
738
|
+
{
|
|
739
|
+
return true;
|
|
740
|
+
}
|
|
741
|
+
static inline bool classof(const SVFVar *node)
|
|
742
|
+
{
|
|
743
|
+
return node->getNodeKind() == SVFVar::CloneDummyObjNode;
|
|
744
|
+
}
|
|
745
|
+
static inline bool classof(const GenericPAGNodeTy *node)
|
|
746
|
+
{
|
|
747
|
+
return node->getNodeKind() == SVFVar::CloneDummyObjNode;
|
|
748
|
+
}
|
|
749
|
+
//@}
|
|
750
|
+
|
|
751
|
+
/// Constructor
|
|
752
|
+
CloneDummyObjPN(NodeID i, const MemObj* m, PNODEK ty = CloneDummyObjNode)
|
|
753
|
+
: DummyObjPN(i, m, ty)
|
|
754
|
+
{
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/// Return name of this node
|
|
758
|
+
inline const std::string getValueName() const
|
|
759
|
+
{
|
|
760
|
+
return "clone of " + ObjPN::getValueName();
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
virtual const std::string toString() const;
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
/*
|
|
767
|
+
* Clone object for GEP objects.
|
|
768
|
+
*/
|
|
769
|
+
class CloneGepObjPN : public GepObjPN
|
|
770
|
+
{
|
|
771
|
+
public:
|
|
772
|
+
//@{ Methods to support type inquiry through isa, cast, and dyn_cast:
|
|
773
|
+
static inline bool classof(const CloneGepObjPN *)
|
|
774
|
+
{
|
|
775
|
+
return true;
|
|
776
|
+
}
|
|
777
|
+
static inline bool classof(const SVFVar *node)
|
|
778
|
+
{
|
|
779
|
+
return node->getNodeKind() == SVFVar::CloneGepObjNode;
|
|
780
|
+
}
|
|
781
|
+
static inline bool classof(const GenericPAGNodeTy *node)
|
|
782
|
+
{
|
|
783
|
+
return node->getNodeKind() == SVFVar::CloneGepObjNode;
|
|
784
|
+
}
|
|
785
|
+
//@}
|
|
786
|
+
|
|
787
|
+
/// Constructor
|
|
788
|
+
CloneGepObjPN(const MemObj* mem, NodeID i, const LocationSet& l, PNODEK ty = CloneGepObjNode) :
|
|
789
|
+
GepObjPN(mem, i, l, ty)
|
|
790
|
+
{
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
/// Return name of this node
|
|
794
|
+
inline const std::string getValueName() const
|
|
795
|
+
{
|
|
796
|
+
return "clone (gep) of " + GepObjPN::getValueName();
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
virtual const std::string toString() const;
|
|
800
|
+
};
|
|
801
|
+
|
|
802
|
+
/*
|
|
803
|
+
* Clone object for FI objects.
|
|
804
|
+
*/
|
|
805
|
+
class CloneFIObjPN : public FIObjPN
|
|
806
|
+
{
|
|
807
|
+
public:
|
|
808
|
+
//@{ Methods to support type inquiry through isa, cast, and dyn_cast:
|
|
809
|
+
static inline bool classof(const CloneFIObjPN *)
|
|
810
|
+
{
|
|
811
|
+
return true;
|
|
812
|
+
}
|
|
813
|
+
static inline bool classof(const SVFVar *node)
|
|
814
|
+
{
|
|
815
|
+
return node->getNodeKind() == SVFVar::CloneFIObjNode;
|
|
816
|
+
}
|
|
817
|
+
static inline bool classof(const GenericPAGNodeTy *node)
|
|
818
|
+
{
|
|
819
|
+
return node->getNodeKind() == SVFVar::CloneFIObjNode;
|
|
820
|
+
}
|
|
821
|
+
//@}
|
|
822
|
+
|
|
823
|
+
/// Constructor
|
|
824
|
+
CloneFIObjPN(const Value* val, NodeID i, const MemObj* mem, PNODEK ty = CloneFIObjNode) :
|
|
825
|
+
FIObjPN(val, i, mem, ty)
|
|
826
|
+
{
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/// Return name of this node
|
|
830
|
+
inline const std::string getValueName() const
|
|
831
|
+
{
|
|
832
|
+
return "clone (FI) of " + FIObjPN::getValueName();
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
virtual const std::string toString() const;
|
|
836
|
+
};
|
|
837
|
+
|
|
838
|
+
} // End namespace SVF
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
#endif /* OBJECTANDSYMBOL_H_ */
|