xref: /openbsd-src/gnu/llvm/clang/lib/Analysis/FlowSensitive/Value.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1*12c85518Srobert //===-- Value.cpp -----------------------------------------------*- C++ -*-===//
2*12c85518Srobert //
3*12c85518Srobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*12c85518Srobert // See https://llvm.org/LICENSE.txt for license information.
5*12c85518Srobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*12c85518Srobert //
7*12c85518Srobert //===----------------------------------------------------------------------===//
8*12c85518Srobert //
9*12c85518Srobert //  This file defines support functions for the `Value` type.
10*12c85518Srobert //
11*12c85518Srobert //===----------------------------------------------------------------------===//
12*12c85518Srobert 
13*12c85518Srobert #include "clang/Analysis/FlowSensitive/Value.h"
14*12c85518Srobert #include "clang/Analysis/FlowSensitive/DebugSupport.h"
15*12c85518Srobert #include "llvm/Support/Casting.h"
16*12c85518Srobert 
17*12c85518Srobert namespace clang {
18*12c85518Srobert namespace dataflow {
19*12c85518Srobert 
areEquivalentIndirectionValues(const Value & Val1,const Value & Val2)20*12c85518Srobert static bool areEquivalentIndirectionValues(const Value &Val1,
21*12c85518Srobert                                            const Value &Val2) {
22*12c85518Srobert   if (auto *IndVal1 = dyn_cast<ReferenceValue>(&Val1)) {
23*12c85518Srobert     auto *IndVal2 = cast<ReferenceValue>(&Val2);
24*12c85518Srobert     return &IndVal1->getReferentLoc() == &IndVal2->getReferentLoc();
25*12c85518Srobert   }
26*12c85518Srobert   if (auto *IndVal1 = dyn_cast<PointerValue>(&Val1)) {
27*12c85518Srobert     auto *IndVal2 = cast<PointerValue>(&Val2);
28*12c85518Srobert     return &IndVal1->getPointeeLoc() == &IndVal2->getPointeeLoc();
29*12c85518Srobert   }
30*12c85518Srobert   return false;
31*12c85518Srobert }
32*12c85518Srobert 
areEquivalentValues(const Value & Val1,const Value & Val2)33*12c85518Srobert bool areEquivalentValues(const Value &Val1, const Value &Val2) {
34*12c85518Srobert   return &Val1 == &Val2 || (Val1.getKind() == Val2.getKind() &&
35*12c85518Srobert                             (isa<TopBoolValue>(&Val1) ||
36*12c85518Srobert                              areEquivalentIndirectionValues(Val1, Val2)));
37*12c85518Srobert }
38*12c85518Srobert 
operator <<(raw_ostream & OS,const Value & Val)39*12c85518Srobert raw_ostream &operator<<(raw_ostream &OS, const Value &Val) {
40*12c85518Srobert   switch (Val.getKind()) {
41*12c85518Srobert   case Value::Kind::Reference: {
42*12c85518Srobert     const auto *RV = cast<ReferenceValue>(&Val);
43*12c85518Srobert     return OS << "Reference(" << &RV->getReferentLoc() << ")";
44*12c85518Srobert   }
45*12c85518Srobert   case Value::Kind::Pointer: {
46*12c85518Srobert     const auto *PV = dyn_cast<PointerValue>(&Val);
47*12c85518Srobert     return OS << "Pointer(" << &PV->getPointeeLoc() << ")";
48*12c85518Srobert   }
49*12c85518Srobert   // FIXME: support remaining cases.
50*12c85518Srobert   default:
51*12c85518Srobert     return OS << debugString(Val.getKind());
52*12c85518Srobert   }
53*12c85518Srobert }
54*12c85518Srobert 
55*12c85518Srobert } // namespace dataflow
56*12c85518Srobert } // namespace clang
57