SVals.cpp revision 8cc13ea74fea1c04042a2f4087665bc5182e8408
1a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//= RValues.cpp - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*-==//
2a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//
3a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//                     The LLVM Compiler Infrastructure
4a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//
5a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// This file is distributed under the University of Illinois Open Source
6a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// License. See LICENSE.TXT for details.
7a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//
8a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===//
9a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//
10aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek//  This files defines RVal, LVal, and NonLVal, classes that represent
11a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//  abstract r-values for use with path-sensitive value tracking.
12a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//
13a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===//
14a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
15cc409b764e12ff81d422bc4317e0b7552cf10011Ted Kremenek#include "clang/Analysis/PathSensitive/RValues.h"
16d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek#include "llvm/Support/Streams.h"
17a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
18a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing namespace clang;
19a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing llvm::dyn_cast;
20a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing llvm::cast;
21a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing llvm::APSInt;
22a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
23a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===//
2490e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek// Symbol Iteration.
2590e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek//===----------------------------------------------------------------------===//
2690e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek
27aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekRVal::symbol_iterator RVal::symbol_begin() const {
28aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  if (isa<lval::SymbolVal>(this))
29aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return (symbol_iterator) (&Data);
30aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  else if (isa<nonlval::SymbolVal>(this))
31aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return (symbol_iterator) (&Data);
32aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  else if (isa<nonlval::SymIntConstraintVal>(this)) {
33aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    const SymIntConstraint& C =
34aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      cast<nonlval::SymIntConstraintVal>(this)->getConstraint();
35aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
36aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    return (symbol_iterator) &C.getSymbol();
3790e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek  }
3890e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek
3990e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek  return NULL;
4090e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek}
41a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
42aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekRVal::symbol_iterator RVal::symbol_end() const {
4390e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek  symbol_iterator X = symbol_begin();
4490e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek  return X ? X+1 : NULL;
4590e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek}
46cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
47cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===//
48aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// Transfer function dispatch for Non-LVals.
49cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===//
50cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
518cc13ea74fea1c04042a2f4087665bc5182e8408Ted KremenekRVal
52aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremeneknonlval::ConcreteInt::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
53aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                                const nonlval::ConcreteInt& R) const {
54aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
558cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek  const llvm::APSInt* X = ValMgr.EvaluateAPSInt(Op, getValue(), R.getValue());
568cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek
578cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek  if (X)
588cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek    return nonlval::ConcreteInt(*X);
598cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek  else
608cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek    return UndefinedVal();
61cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek}
62cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
63cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
64cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek  // Bitwise-Complement.
65cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
66cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremeneknonlval::ConcreteInt
67cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremeneknonlval::ConcreteInt::EvalComplement(ValueManager& ValMgr) const {
68cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek  return ValMgr.getValue(~getValue());
69cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek}
70cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
71cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek  // Unary Minus.
72a6e4d21dc4fe87fe1b0bcd9c3c3ec43b391aa44bTed Kremenek
73cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremeneknonlval::ConcreteInt
74cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremeneknonlval::ConcreteInt::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
75cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek  assert (U->getType() == U->getSubExpr()->getType());
76cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek  assert (U->getType()->isIntegerType());
77cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek  return ValMgr.getValue(-getValue());
78c5d3b4ca4707b1fe69629bfefd73087dc4893dd8Ted Kremenek}
79c5d3b4ca4707b1fe69629bfefd73087dc4893dd8Ted Kremenek
80cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===//
81aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// Transfer function dispatch for LVals.
82cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===//
83c5d3b4ca4707b1fe69629bfefd73087dc4893dd8Ted Kremenek
848cc13ea74fea1c04042a2f4087665bc5182e8408Ted KremenekRVal
85aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremeneklval::ConcreteInt::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
86aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                             const lval::ConcreteInt& R) const {
87cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
88cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek  assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
89cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek          (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
90cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
918cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek  const llvm::APSInt* X = ValMgr.EvaluateAPSInt(Op, getValue(), R.getValue());
928cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek
938cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek  if (X)
948cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek    return lval::ConcreteInt(*X);
958cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek  else
968cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek    return UndefinedVal();
97a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}
98a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
99aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekNonLVal LVal::EQ(ValueManager& ValMgr, const LVal& R) const {
100aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
101a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  switch (getSubKind()) {
102a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    default:
103aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      assert(false && "EQ not implemented for this LVal.");
104aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      break;
105cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
1060806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek    case lval::ConcreteIntKind:
107aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      if (isa<lval::ConcreteInt>(R)) {
1080806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek        bool b = cast<lval::ConcreteInt>(this)->getValue() ==
109aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                 cast<lval::ConcreteInt>(R).getValue();
110cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
111aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek        return NonLVal::MakeIntTruthVal(ValMgr, b);
1120806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      }
113aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      else if (isa<lval::SymbolVal>(R)) {
114cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
1150806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek        const SymIntConstraint& C =
116aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek          ValMgr.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
117aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                               BinaryOperator::EQ,
118aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                               cast<lval::ConcreteInt>(this)->getValue());
1190806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
1200806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek        return nonlval::SymIntConstraintVal(C);
1210806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      }
1220806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
1230806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      break;
1240806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
125cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek      case lval::SymbolValKind: {
126aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek        if (isa<lval::ConcreteInt>(R)) {
127cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
128cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek          const SymIntConstraint& C =
129aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek            ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
130aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                                 BinaryOperator::EQ,
131aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                                 cast<lval::ConcreteInt>(R).getValue());
132cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
133cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek          return nonlval::SymIntConstraintVal(C);
134cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek        }
135cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
136aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek        assert (!isa<lval::SymbolVal>(R) && "FIXME: Implement unification.");
1370806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
138cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek        break;
1390806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      }
140a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
141cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek      case lval::DeclValKind:
142aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      if (isa<lval::DeclVal>(R)) {
143aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek        bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(R);
144aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek        return NonLVal::MakeIntTruthVal(ValMgr, b);
1450806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      }
1460806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
1470806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      break;
148a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
1490806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
150aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  return NonLVal::MakeIntTruthVal(ValMgr, false);
151a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}
152a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
153aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekNonLVal LVal::NE(ValueManager& ValMgr, const LVal& R) const {
154a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  switch (getSubKind()) {
155a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    default:
156aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      assert(false && "NE not implemented for this LVal.");
157aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      break;
158a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
1590806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek    case lval::ConcreteIntKind:
160aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      if (isa<lval::ConcreteInt>(R)) {
1610806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek        bool b = cast<lval::ConcreteInt>(this)->getValue() !=
162aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                 cast<lval::ConcreteInt>(R).getValue();
1630806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
164aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek        return NonLVal::MakeIntTruthVal(ValMgr, b);
1650806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      }
166aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      else if (isa<lval::SymbolVal>(R)) {
1670806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
1680806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek        const SymIntConstraint& C =
169aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek        ValMgr.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
1700806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek                             BinaryOperator::NE,
1710806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek                             cast<lval::ConcreteInt>(this)->getValue());
1720806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
1730806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek        return nonlval::SymIntConstraintVal(C);
1740806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      }
175a6e4d21dc4fe87fe1b0bcd9c3c3ec43b391aa44bTed Kremenek
1760806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      break;
177a6e4d21dc4fe87fe1b0bcd9c3c3ec43b391aa44bTed Kremenek
1780806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      case lval::SymbolValKind: {
179aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek        if (isa<lval::ConcreteInt>(R)) {
1800806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
1810806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek          const SymIntConstraint& C =
1820806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek          ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
1830806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek                               BinaryOperator::NE,
184aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                               cast<lval::ConcreteInt>(R).getValue());
1850806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
1860806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek          return nonlval::SymIntConstraintVal(C);
1870806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek        }
1880806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
189aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek        assert (!isa<lval::SymbolVal>(R) && "FIXME: Implement sym !=.");
1900806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
1910806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek        break;
1920806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      }
1930806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
1940806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      case lval::DeclValKind:
195aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek        if (isa<lval::DeclVal>(R)) {
196aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek          bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(R);
197aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek          return NonLVal::MakeIntTruthVal(ValMgr, b);
198aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek        }
1990806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
200aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek        break;
201a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
2020806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
203aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  return NonLVal::MakeIntTruthVal(ValMgr, true);
204a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}
205a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
206a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===//
207aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// Utility methods for constructing Non-LVals.
208a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===//
209a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
210aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekNonLVal NonLVal::MakeVal(ValueManager& ValMgr, uint64_t X, QualType T,
211aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                             SourceLocation Loc) {
212aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
213329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek  return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc));
214a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}
215a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
216aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekNonLVal NonLVal::MakeVal(ValueManager& ValMgr, IntegerLiteral* I) {
217aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
218329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek  return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
219aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek                              I->getType()->isUnsignedIntegerType())));
220a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}
221a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
222aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekNonLVal NonLVal::MakeIntTruthVal(ValueManager& ValMgr, bool b) {
223aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
224cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek  return nonlval::ConcreteInt(ValMgr.getTruthValue(b));
225cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek}
226cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
227d763eb91aab5bdecd11825fadb35d6d8cc905f63Ted KremenekRVal RVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
228aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
229a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  QualType T = D->getType();
230a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
231a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  if (T->isPointerType() || T->isReferenceType())
232329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek    return lval::SymbolVal(SymMgr.getSymbol(D));
233a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  else
234329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek    return nonlval::SymbolVal(SymMgr.getSymbol(D));
235a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}
236a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
2372a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek//===----------------------------------------------------------------------===//
238aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// Utility methods for constructing LVals.
2392a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek//===----------------------------------------------------------------------===//
2402a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
241aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekLVal LVal::MakeVal(AddrLabelExpr* E) { return lval::GotoLabel(E->getLabel()); }
242cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
243a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===//
244a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// Pretty-Printing.
245a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===//
246a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
247aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekvoid RVal::printStdErr() const { print(*llvm::cerr.stream()); }
248aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
249aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekvoid RVal::print(std::ostream& Out) const {
2502a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
251a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  switch (getBaseKind()) {
252aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
25353c641a735da0c3fe077aab63a6fef16c8798937Ted Kremenek    case UnknownKind:
254aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      Out << "Invalid"; break;
255a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
256aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case NonLValKind:
257aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      cast<NonLVal>(this)->print(Out); break;
258a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
259aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case LValKind:
260aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      cast<LVal>(this)->print(Out); break;
261a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
2624a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek    case UndefinedKind:
2634a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek      Out << "Undefined"; break;
264a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
265a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    default:
266aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      assert (false && "Invalid RVal.");
267a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
268a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}
269a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
2700806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenekstatic void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
271aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
272aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek  switch (Op) {
273aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::Mul: Out << '*'  ; break;
274aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::Div: Out << '/'  ; break;
275aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::Rem: Out << '%'  ; break;
276aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::Add: Out << '+'  ; break;
277aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::Sub: Out << '-'  ; break;
27850d0ac299c641bee9024f3fbae2ea0640898a040Ted Kremenek    case BinaryOperator::Shl: Out << "<<" ; break;
27950d0ac299c641bee9024f3fbae2ea0640898a040Ted Kremenek    case BinaryOperator::Shr: Out << ">>" ; break;
280aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::LT:  Out << "<"  ; break;
281aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::GT:  Out << '>'  ; break;
282aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::LE:  Out << "<=" ; break;
283aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::GE:  Out << ">=" ; break;
284aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::EQ:  Out << "==" ; break;
285aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::NE:  Out << "!=" ; break;
286aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::And: Out << '&'  ; break;
287aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::Xor: Out << '^'  ; break;
288aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    case BinaryOperator::Or:  Out << '|'  ; break;
289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2900806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek    default: assert(false && "Not yet implemented.");
2910806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek  }
2920806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek}
2930806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
294aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekvoid NonLVal::print(std::ostream& Out) const {
295aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
296a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  switch (getSubKind()) {
297aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
298329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek    case nonlval::ConcreteIntKind:
299329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek      Out << cast<nonlval::ConcreteInt>(this)->getValue().toString();
300cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
301cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek      if (cast<nonlval::ConcreteInt>(this)->getValue().isUnsigned())
302cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek        Out << 'U';
303cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
304a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek      break;
305a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
306329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek    case nonlval::SymbolValKind:
3070806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
308a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek      break;
3090806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
3100806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek    case nonlval::SymIntConstraintValKind: {
3110806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      const nonlval::SymIntConstraintVal& C =
3120806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek        *cast<nonlval::SymIntConstraintVal>(this);
3130806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek
3140806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      Out << '$' << C.getConstraint().getSymbol() << ' ';
3150806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      printOpcode(Out, C.getConstraint().getOpcode());
3160806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      Out << ' ' << C.getConstraint().getInt().toString();
317cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
318cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek      if (C.getConstraint().getInt().isUnsigned())
319cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek        Out << 'U';
320cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
3210806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      break;
3220806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek    }
323a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
324a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    default:
325aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      assert (false && "Pretty-printed not implemented for this NonLVal.");
326a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek      break;
327a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
328a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}
329a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
330aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekvoid LVal::print(std::ostream& Out) const {
331aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
332a6e4d21dc4fe87fe1b0bcd9c3c3ec43b391aa44bTed Kremenek  switch (getSubKind()) {
333aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
334329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek    case lval::ConcreteIntKind:
335329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek      Out << cast<lval::ConcreteInt>(this)->getValue().toString()
336aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek          << " (LVal)";
337a6e4d21dc4fe87fe1b0bcd9c3c3ec43b391aa44bTed Kremenek      break;
338a6e4d21dc4fe87fe1b0bcd9c3c3ec43b391aa44bTed Kremenek
339329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek    case lval::SymbolValKind:
3400806acf6a197ac7bd5c87649c0429e64e5d0db06Ted Kremenek      Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
341a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek      break;
3422a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek
3432a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek    case lval::GotoLabelKind:
3442a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek      Out << "&&"
3452a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek          << cast<lval::GotoLabel>(this)->getLabel()->getID()->getName();
3462a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek      break;
34708b66255e2605adfa8777dbff293db1c69bc1092Ted Kremenek
348329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek    case lval::DeclValKind:
349a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek      Out << '&'
350de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek          << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
351de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek      break;
352de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek
353de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek    case lval::FuncValKind:
354de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek      Out << "function "
355de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek          << cast<lval::FuncVal>(this)->getDecl()->getIdentifier()->getName();
356a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek      break;
357a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
358a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek    default:
359aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek      assert (false && "Pretty-printing not implemented for this LVal.");
360a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek      break;
361a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek  }
362a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}
363