Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Analysis/FlowSensitive/Value.h
Line
Count
Source (jump to first uncovered line)
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"
18
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
19
#include "llvm/ADT/DenseMap.h"
20
#include <cassert>
21
#include <utility>
22
23
namespace clang {
24
namespace dataflow {
25
26
/// Base class for all values computed by abstract interpretation.
27
class Value {
28
public:
29
  enum class Kind { Integer, Reference, Pointer, Struct };
30
31
462
  explicit Value(Kind ValKind) : ValKind(ValKind) {}
32
33
462
  virtual ~Value() = default;
34
35
1.31k
  Kind getKind() const { return ValKind; }
36
37
private:
38
  Kind ValKind;
39
};
40
41
/// Models an integer.
42
class IntegerValue : public Value {
43
public:
44
162
  explicit IntegerValue() : Value(Kind::Integer) {}
45
46
  static bool classof(const Value *Val) {
47
    return Val->getKind() == Kind::Integer;
48
  }
49
};
50
51
/// Base class for values that refer to storage locations.
52
class IndirectionValue : public Value {
53
public:
54
  /// Constructs a value that refers to `PointeeLoc`.
55
  explicit IndirectionValue(Kind ValueKind, StorageLocation &PointeeLoc)
56
232
      : Value(ValueKind), PointeeLoc(PointeeLoc) {}
57
58
0
  static bool classof(const Value *Val) {
59
0
    return Val->getKind() == Kind::Reference || Val->getKind() == Kind::Pointer;
60
0
  }
61
62
223
  StorageLocation &getPointeeLoc() const { return PointeeLoc; }
63
64
private:
65
  StorageLocation &PointeeLoc;
66
};
67
68
/// Models a dereferenced pointer. For example, a reference in C++ or an lvalue
69
/// in C.
70
class ReferenceValue final : public IndirectionValue {
71
public:
72
  explicit ReferenceValue(StorageLocation &PointeeLoc)
73
197
      : IndirectionValue(Kind::Reference, PointeeLoc) {}
74
75
414
  static bool classof(const Value *Val) {
76
414
    return Val->getKind() == Kind::Reference;
77
414
  }
78
};
79
80
/// Models a symbolic pointer. Specifically, any value of type `T*`.
81
class PointerValue final : public IndirectionValue {
82
public:
83
  explicit PointerValue(StorageLocation &PointeeLoc)
84
35
      : IndirectionValue(Kind::Pointer, PointeeLoc) {}
85
86
65
  static bool classof(const Value *Val) {
87
65
    return Val->getKind() == Kind::Pointer;
88
65
  }
89
};
90
91
/// Models a value of `struct` or `class` type.
92
class StructValue final : public Value {
93
public:
94
0
  StructValue() : StructValue(llvm::DenseMap<const ValueDecl *, Value *>()) {}
95
96
  explicit StructValue(llvm::DenseMap<const ValueDecl *, Value *> Children)
97
68
      : Value(Kind::Struct), Children(std::move(Children)) {}
98
99
798
  static bool classof(const Value *Val) {
100
798
    return Val->getKind() == Kind::Struct;
101
798
  }
102
103
  /// Returns the child value for `D`.
104
111
  Value &getChild(const ValueDecl &D) const {
105
111
    auto It = Children.find(&D);
106
111
    assert(It != Children.end());
107
0
    return *It->second;
108
111
  }
109
110
private:
111
  const llvm::DenseMap<const ValueDecl *, Value *> Children;
112
};
113
114
} // namespace dataflow
115
} // namespace clang
116
117
#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H