blob: 64f4b27d3fe3d9685e1deea4df2bc2003b39f58d [file] [log] [blame]
Ted Kremenekd70d0b02008-02-16 01:12:31 +00001// ValueManager.h - Low-level value management for Value Tracking -*- C++ -*--==
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This files defines ValueManager, a class that manages the lifetime of APSInt
11// objects and symbolic constraints used by GRExprEngine and related classes.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Analysis/PathSensitive/ValueManager.h"
16
17using namespace clang;
18
19ValueManager::~ValueManager() {
20 // Note that the dstor for the contents of APSIntSet will never be called,
21 // so we iterate over the set and invoke the dstor for each APSInt. This
22 // frees an aux. memory allocated to represent very large constants.
23 for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
24 I->getValue().~APSInt();
25}
26
27const llvm::APSInt& ValueManager::getValue(const llvm::APSInt& X) {
28 llvm::FoldingSetNodeID ID;
29 void* InsertPos;
30 typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
31
32 X.Profile(ID);
33 FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
34
35 if (!P) {
36 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
37 new (P) FoldNodeTy(X);
38 APSIntSet.InsertNode(P, InsertPos);
39 }
40
41 return *P;
42}
43
44const llvm::APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth,
45 bool isUnsigned) {
46 llvm::APSInt V(BitWidth, isUnsigned);
47 V = X;
48 return getValue(V);
49}
50
51const llvm::APSInt& ValueManager::getValue(uint64_t X, QualType T,
52 SourceLocation Loc) {
53
54 unsigned bits = Ctx.getTypeSize(T, Loc);
55 llvm::APSInt V(bits, T->isUnsignedIntegerType());
56 V = X;
57 return getValue(V);
58}
59
60const SymIntConstraint&
61ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
62 const llvm::APSInt& V) {
63
64 llvm::FoldingSetNodeID ID;
65 SymIntConstraint::Profile(ID, sym, Op, V);
66 void* InsertPos;
67
68 SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos);
69
70 if (!C) {
71 C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>();
72 new (C) SymIntConstraint(sym, Op, V);
73 SymIntCSet.InsertNode(C, InsertPos);
74 }
75
76 return *C;
77}
78
79const llvm::APSInt&
80ValueManager::EvaluateAPSInt(BinaryOperator::Opcode Op,
81 const llvm::APSInt& V1, const llvm::APSInt& V2) {
82
83 switch (Op) {
84 default:
85 assert (false && "Invalid Opcode.");
86
87 case BinaryOperator::Mul:
88 return getValue( V1 * V2 );
89
90 case BinaryOperator::Div:
91 return getValue( V1 / V2 );
92
93 case BinaryOperator::Rem:
94 return getValue( V1 % V2 );
95
96 case BinaryOperator::Add:
97 return getValue( V1 + V2 );
98
99 case BinaryOperator::Sub:
100 return getValue( V1 - V2 );
101
102 case BinaryOperator::Shl:
103 return getValue( V1.operator<<( (unsigned) V2.getZExtValue() ));
104
105 case BinaryOperator::Shr:
106 return getValue( V1.operator>>( (unsigned) V2.getZExtValue() ));
107
108 case BinaryOperator::LT:
109 return getTruthValue( V1 < V2 );
110
111 case BinaryOperator::GT:
112 return getTruthValue( V1 > V2 );
113
114 case BinaryOperator::LE:
115 return getTruthValue( V1 <= V2 );
116
117 case BinaryOperator::GE:
118 return getTruthValue( V1 >= V2 );
119
120 case BinaryOperator::EQ:
121 return getTruthValue( V1 == V2 );
122
123 case BinaryOperator::NE:
124 return getTruthValue( V1 != V2 );
125
126 // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
127
128 case BinaryOperator::And:
129 return getValue( V1 & V2 );
130
131 case BinaryOperator::Or:
132 return getValue( V1 | V2 );
Ted Kremenek1caf26a2008-02-19 20:53:37 +0000133
134 case BinaryOperator::Xor:
135 return getValue( V1 ^ V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000136 }
137}