clang  15.0.0git
Value.h
Go to the documentation of this file.
1 //===-- Value.h -------------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines classes for values computed by abstract interpretation
10 // during dataflow analysis.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H
15 #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H
16 
17 #include "clang/AST/Decl.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/ADT/StringRef.h"
22 #include <cassert>
23 #include <utility>
24 
25 namespace clang {
26 namespace dataflow {
27 
28 /// Base class for all values computed by abstract interpretation.
29 class Value {
30 public:
31  enum class Kind {
32  Integer,
33  Reference,
34  Pointer,
35  Struct,
36 
37  // Synthetic boolean values are either atomic values or composites that
38  // represent conjunctions, disjunctions, and negations.
39  AtomicBool,
42  Negation
43  };
44 
45  explicit Value(Kind ValKind) : ValKind(ValKind) {}
46 
47  virtual ~Value() = default;
48 
49  Kind getKind() const { return ValKind; }
50 
51 private:
52  Kind ValKind;
53 };
54 
55 /// Models a boolean.
56 class BoolValue : public Value {
57 public:
58  explicit BoolValue(Kind ValueKind) : Value(ValueKind) {}
59 
60  static bool classof(const Value *Val) {
61  return Val->getKind() == Kind::AtomicBool ||
62  Val->getKind() == Kind::Conjunction ||
63  Val->getKind() == Kind::Disjunction ||
64  Val->getKind() == Kind::Negation;
65  }
66 };
67 
68 /// Models an atomic boolean.
69 class AtomicBoolValue : public BoolValue {
70 public:
71  explicit AtomicBoolValue() : BoolValue(Kind::AtomicBool) {}
72 
73  static bool classof(const Value *Val) {
74  return Val->getKind() == Kind::AtomicBool;
75  }
76 };
77 
78 /// Models a boolean conjunction.
79 // FIXME: Consider representing binary and unary boolean operations similar
80 // to how they are represented in the AST. This might become more pressing
81 // when such operations need to be added for other data types.
82 class ConjunctionValue : public BoolValue {
83 public:
84  explicit ConjunctionValue(BoolValue &LeftSubVal, BoolValue &RightSubVal)
85  : BoolValue(Kind::Conjunction), LeftSubVal(LeftSubVal),
86  RightSubVal(RightSubVal) {}
87 
88  static bool classof(const Value *Val) {
89  return Val->getKind() == Kind::Conjunction;
90  }
91 
92  /// Returns the left sub-value of the conjunction.
93  BoolValue &getLeftSubValue() const { return LeftSubVal; }
94 
95  /// Returns the right sub-value of the conjunction.
96  BoolValue &getRightSubValue() const { return RightSubVal; }
97 
98 private:
99  BoolValue &LeftSubVal;
100  BoolValue &RightSubVal;
101 };
102 
103 /// Models a boolean disjunction.
104 class DisjunctionValue : public BoolValue {
105 public:
106  explicit DisjunctionValue(BoolValue &LeftSubVal, BoolValue &RightSubVal)
107  : BoolValue(Kind::Disjunction), LeftSubVal(LeftSubVal),
108  RightSubVal(RightSubVal) {}
109 
110  static bool classof(const Value *Val) {
111  return Val->getKind() == Kind::Disjunction;
112  }
113 
114  /// Returns the left sub-value of the disjunction.
115  BoolValue &getLeftSubValue() const { return LeftSubVal; }
116 
117  /// Returns the right sub-value of the disjunction.
118  BoolValue &getRightSubValue() const { return RightSubVal; }
119 
120 private:
121  BoolValue &LeftSubVal;
122  BoolValue &RightSubVal;
123 };
124 
125 /// Models a boolean negation.
126 class NegationValue : public BoolValue {
127 public:
128  explicit NegationValue(BoolValue &SubVal)
129  : BoolValue(Kind::Negation), SubVal(SubVal) {}
130 
131  static bool classof(const Value *Val) {
132  return Val->getKind() == Kind::Negation;
133  }
134 
135  /// Returns the sub-value of the negation.
136  BoolValue &getSubVal() const { return SubVal; }
137 
138 private:
139  BoolValue &SubVal;
140 };
141 
142 /// Models an integer.
143 class IntegerValue : public Value {
144 public:
145  explicit IntegerValue() : Value(Kind::Integer) {}
146 
147  static bool classof(const Value *Val) {
148  return Val->getKind() == Kind::Integer;
149  }
150 };
151 
152 /// Base class for values that refer to storage locations.
153 class IndirectionValue : public Value {
154 public:
155  /// Constructs a value that refers to `PointeeLoc`.
156  explicit IndirectionValue(Kind ValueKind, StorageLocation &PointeeLoc)
157  : Value(ValueKind), PointeeLoc(PointeeLoc) {}
158 
159  static bool classof(const Value *Val) {
160  return Val->getKind() == Kind::Reference || Val->getKind() == Kind::Pointer;
161  }
162 
163  StorageLocation &getPointeeLoc() const { return PointeeLoc; }
164 
165 private:
166  StorageLocation &PointeeLoc;
167 };
168 
169 /// Models a dereferenced pointer. For example, a reference in C++ or an lvalue
170 /// in C.
171 class ReferenceValue final : public IndirectionValue {
172 public:
173  explicit ReferenceValue(StorageLocation &PointeeLoc)
174  : IndirectionValue(Kind::Reference, PointeeLoc) {}
175 
176  static bool classof(const Value *Val) {
177  return Val->getKind() == Kind::Reference;
178  }
179 };
180 
181 /// Models a symbolic pointer. Specifically, any value of type `T*`.
182 class PointerValue final : public IndirectionValue {
183 public:
184  explicit PointerValue(StorageLocation &PointeeLoc)
185  : IndirectionValue(Kind::Pointer, PointeeLoc) {}
186 
187  static bool classof(const Value *Val) {
188  return Val->getKind() == Kind::Pointer;
189  }
190 };
191 
192 /// Models a value of `struct` or `class` type, with a flat map of fields to
193 /// child storage locations, containing all accessible members of base struct
194 /// and class types.
195 class StructValue final : public Value {
196 public:
197  StructValue() : StructValue(llvm::DenseMap<const ValueDecl *, Value *>()) {}
198 
199  explicit StructValue(llvm::DenseMap<const ValueDecl *, Value *> Children)
200  : Value(Kind::Struct), Children(std::move(Children)) {}
201 
202  static bool classof(const Value *Val) {
203  return Val->getKind() == Kind::Struct;
204  }
205 
206  /// Returns the child value that is assigned for `D` or null if the child is
207  /// not initialized.
208  Value *getChild(const ValueDecl &D) const {
209  auto It = Children.find(&D);
210  if (It == Children.end())
211  return nullptr;
212  return It->second;
213  }
214 
215  /// Assigns `Val` as the child value for `D`.
216  void setChild(const ValueDecl &D, Value &Val) { Children[&D] = &Val; }
217 
218  /// Returns the value of the synthetic property with the given `Name` or null
219  /// if the property isn't assigned a value.
220  Value *getProperty(llvm::StringRef Name) const {
221  auto It = Properties.find(Name);
222  return It == Properties.end() ? nullptr : It->second;
223  }
224 
225  /// Assigns `Val` as the value of the synthetic property with the given
226  /// `Name`.
227  void setProperty(llvm::StringRef Name, Value &Val) {
228  Properties.insert_or_assign(Name, &Val);
229  }
230 
231 private:
232  llvm::DenseMap<const ValueDecl *, Value *> Children;
233  llvm::StringMap<Value *> Properties;
234 };
235 
236 } // namespace dataflow
237 } // namespace clang
238 
239 #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H
clang::dataflow::BoolValue::classof
static bool classof(const Value *Val)
Definition: Value.h:60
llvm
YAML serialization mapping.
Definition: Dominators.h:30
clang::dataflow::StructValue::getChild
Value * getChild(const ValueDecl &D) const
Returns the child value that is assigned for D or null if the child is not initialized.
Definition: Value.h:208
clang::dataflow::PointerValue::classof
static bool classof(const Value *Val)
Definition: Value.h:187
clang::dataflow::IndirectionValue
Base class for values that refer to storage locations.
Definition: Value.h:153
clang::dataflow::ReferenceValue::ReferenceValue
ReferenceValue(StorageLocation &PointeeLoc)
Definition: Value.h:173
clang::dataflow::StorageLocation
Base class for elements of the local variable store and of the heap.
Definition: StorageLocation.h:28
clang::dataflow::AtomicBoolValue::classof
static bool classof(const Value *Val)
Definition: Value.h:73
clang::dataflow::SkipPast::Reference
@ Reference
An optional reference should be skipped past.
clang::dataflow::Value::Value
Value(Kind ValKind)
Definition: Value.h:45
clang::dataflow::Value::Kind::Disjunction
@ Disjunction
clang::dataflow::Value::~Value
virtual ~Value()=default
Decl.h
clang::dataflow::AtomicBoolValue::AtomicBoolValue
AtomicBoolValue()
Definition: Value.h:71
clang::dataflow::DisjunctionValue
Models a boolean disjunction.
Definition: Value.h:104
clang::dataflow::StructValue::getProperty
Value * getProperty(llvm::StringRef Name) const
Returns the value of the synthetic property with the given Name or null if the property isn't assigne...
Definition: Value.h:220
clang::dataflow::DisjunctionValue::getLeftSubValue
BoolValue & getLeftSubValue() const
Returns the left sub-value of the disjunction.
Definition: Value.h:115
clang::dataflow::ConjunctionValue
Models a boolean conjunction.
Definition: Value.h:82
clang::dataflow::IndirectionValue::getPointeeLoc
StorageLocation & getPointeeLoc() const
Definition: Value.h:163
clang::dataflow::Value::Kind::Reference
@ Reference
clang::dataflow::ReferenceValue::classof
static bool classof(const Value *Val)
Definition: Value.h:176
clang::dataflow::Value::Kind::Integer
@ Integer
clang::dataflow::Value::Kind
Kind
Definition: Value.h:31
clang::dataflow::IndirectionValue::classof
static bool classof(const Value *Val)
Definition: Value.h:159
clang::dataflow::AtomicBoolValue
Models an atomic boolean.
Definition: Value.h:69
clang::dataflow::StructValue::setChild
void setChild(const ValueDecl &D, Value &Val)
Assigns Val as the child value for D.
Definition: Value.h:216
clang::dataflow::IntegerValue::classof
static bool classof(const Value *Val)
Definition: Value.h:147
clang::dataflow::IntegerValue::IntegerValue
IntegerValue()
Definition: Value.h:145
clang::dataflow::Value::Kind::Conjunction
@ Conjunction
clang::dataflow::Value::Kind::Negation
@ Negation
clang::dataflow::BoolValue::BoolValue
BoolValue(Kind ValueKind)
Definition: Value.h:58
clang::dataflow::StructValue::StructValue
StructValue()
Definition: Value.h:197
clang::dataflow::BoolValue
Models a boolean.
Definition: Value.h:56
clang::dataflow::IndirectionValue::IndirectionValue
IndirectionValue(Kind ValueKind, StorageLocation &PointeeLoc)
Constructs a value that refers to PointeeLoc.
Definition: Value.h:156
clang::dataflow::IntegerValue
Models an integer.
Definition: Value.h:143
clang::dataflow::ConjunctionValue::getLeftSubValue
BoolValue & getLeftSubValue() const
Returns the left sub-value of the conjunction.
Definition: Value.h:93
clang::dataflow::ConjunctionValue::ConjunctionValue
ConjunctionValue(BoolValue &LeftSubVal, BoolValue &RightSubVal)
Definition: Value.h:84
clang::dataflow::ReferenceValue
Models a dereferenced pointer.
Definition: Value.h:171
clang::dataflow::Value::Kind::Pointer
@ Pointer
clang::ValueDecl
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:674
clang::dataflow::PointerValue::PointerValue
PointerValue(StorageLocation &PointeeLoc)
Definition: Value.h:184
clang::dataflow::NegationValue
Models a boolean negation.
Definition: Value.h:126
clang::dataflow::StructValue::classof
static bool classof(const Value *Val)
Definition: Value.h:202
clang::dataflow::NegationValue::NegationValue
NegationValue(BoolValue &SubVal)
Definition: Value.h:128
clang::dataflow::StructValue::StructValue
StructValue(llvm::DenseMap< const ValueDecl *, Value * > Children)
Definition: Value.h:199
clang::dataflow::ConjunctionValue::getRightSubValue
BoolValue & getRightSubValue() const
Returns the right sub-value of the conjunction.
Definition: Value.h:96
clang::dataflow::DisjunctionValue::getRightSubValue
BoolValue & getRightSubValue() const
Returns the right sub-value of the disjunction.
Definition: Value.h:118
std
Definition: Format.h:4296
clang::dataflow::ConjunctionValue::classof
static bool classof(const Value *Val)
Definition: Value.h:88
clang::dataflow::StructValue
Models a value of struct or class type, with a flat map of fields to child storage locations,...
Definition: Value.h:195
clang
Definition: CalledOnceCheck.h:17
clang::dataflow::Value::Kind::AtomicBool
@ AtomicBool
clang::dataflow::DisjunctionValue::DisjunctionValue
DisjunctionValue(BoolValue &LeftSubVal, BoolValue &RightSubVal)
Definition: Value.h:106
clang::dataflow::Value
Base class for all values computed by abstract interpretation.
Definition: Value.h:29
clang::dataflow::Value::Kind::Struct
@ Struct
clang::dataflow::StructValue::setProperty
void setProperty(llvm::StringRef Name, Value &Val)
Assigns Val as the value of the synthetic property with the given Name.
Definition: Value.h:227
clang::dataflow::DisjunctionValue::classof
static bool classof(const Value *Val)
Definition: Value.h:110
StorageLocation.h
GCCTypeClass::Integer
@ Integer
clang::dataflow::PointerValue
Models a symbolic pointer. Specifically, any value of type T*.
Definition: Value.h:182
clang::dataflow::Value::getKind
Kind getKind() const
Definition: Value.h:49
clang::dataflow::NegationValue::getSubVal
BoolValue & getSubVal() const
Returns the sub-value of the negation.
Definition: Value.h:136
clang::dataflow::NegationValue::classof
static bool classof(const Value *Val)
Definition: Value.h:131