clang 18.0.0git
StorageLocation.h
Go to the documentation of this file.
1//===-- StorageLocation.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 that represent elements of the local variable store
10// and of the heap during dataflow analysis.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H
15#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H
16
17#include "clang/AST/Decl.h"
18#include "clang/AST/Type.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/Support/Debug.h"
21#include <cassert>
22
23#define DEBUG_TYPE "dataflow"
24
25namespace clang {
26namespace dataflow {
27
28/// Base class for elements of the local variable store and of the heap.
29///
30/// Each storage location holds a value. The mapping from storage locations to
31/// values is stored in the environment.
33public:
34 enum class Kind {
35 Scalar,
36 Record,
37 };
38
39 StorageLocation(Kind LocKind, QualType Type) : LocKind(LocKind), Type(Type) {
40 assert(Type.isNull() || !Type->isReferenceType());
41 }
42
43 // Non-copyable because addresses of storage locations are used as their
44 // identities throughout framework and user code. The framework is responsible
45 // for construction and destruction of storage locations.
48
49 virtual ~StorageLocation() = default;
50
51 Kind getKind() const { return LocKind; }
52
53 QualType getType() const { return Type; }
54
55private:
56 Kind LocKind;
58};
59
60/// A storage location that is not subdivided further for the purposes of
61/// abstract interpretation. For example: `int`, `int*`, `int&`.
63public:
66
67 static bool classof(const StorageLocation *Loc) {
68 return Loc->getKind() == Kind::Scalar;
69 }
70};
71
72/// A storage location for a record (struct, class, or union).
73///
74/// Contains storage locations for all modeled fields of the record (also
75/// referred to as "children"). The child map is flat, so accessible members of
76/// the base class are directly accesible as children of this location.
77///
78/// The storage location for a field of reference type may be null. This
79/// typically occurs in one of two situations:
80/// - The record has not been fully initialized.
81/// - The maximum depth for modelling a self-referential data structure has been
82/// reached.
83/// Storage locations for fields of all other types must be non-null.
84///
85/// FIXME: Currently, the storage location of unions is modelled the same way as
86/// that of structs or classes. Eventually, we need to change this modelling so
87/// that all of the members of a given union have the same storage location.
89public:
90 using FieldToLoc = llvm::DenseMap<const ValueDecl *, StorageLocation *>;
91
94
96 : StorageLocation(Kind::Record, Type), Children(std::move(TheChildren)) {
97 assert(!Type.isNull());
98 assert(Type->isRecordType());
99 assert([this] {
100 for (auto [Field, Loc] : Children) {
101 if (!Field->getType()->isReferenceType() && Loc == nullptr)
102 return false;
103 }
104 return true;
105 }());
106 }
107
108 static bool classof(const StorageLocation *Loc) {
109 return Loc->getKind() == Kind::Record;
110 }
111
112 /// Returns the child storage location for `D`.
113 ///
114 /// May return null if `D` has reference type; guaranteed to return non-null
115 /// in all other cases.
116 ///
117 /// Note that it is an error to call this with a field that does not exist.
118 /// The function does not return null in this case.
120 auto It = Children.find(&D);
121 LLVM_DEBUG({
122 if (It == Children.end()) {
123 llvm::dbgs() << "Couldn't find child " << D.getNameAsString()
124 << " on StorageLocation " << this << " of type "
125 << getType() << "\n";
126 llvm::dbgs() << "Existing children:\n";
127 for ([[maybe_unused]] auto [Field, Loc] : Children) {
128 llvm::dbgs() << Field->getNameAsString() << "\n";
129 }
130 }
131 });
132 assert(It != Children.end());
133 return It->second;
134 }
135
136 /// Changes the child storage location for a field `D` of reference type.
137 /// All other fields cannot change their storage location and always retain
138 /// the storage location passed to the `RecordStorageLocation` constructor.
139 ///
140 /// Requirements:
141 ///
142 /// `D` must have reference type.
143 void setChild(const ValueDecl &D, StorageLocation *Loc) {
144 assert(D.getType()->isReferenceType());
145 Children[&D] = Loc;
146 }
147
148 llvm::iterator_range<FieldToLoc::const_iterator> children() const {
149 return {Children.begin(), Children.end()};
150 }
151
152private:
153 FieldToLoc Children;
154};
155
156} // namespace dataflow
157} // namespace clang
158
159#undef DEBUG_TYPE
160
161#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H
C Language Family Type Representation.
A (possibly-)qualified type.
Definition: Type.h:736
The base class of the type hierarchy.
Definition: Type.h:1602
bool isReferenceType() const
Definition: Type.h:7045
bool isRecordType() const
Definition: Type.h:7123
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:704
QualType getType() const
Definition: Decl.h:715
A storage location for a record (struct, class, or union).
StorageLocation * getChild(const ValueDecl &D) const
Returns the child storage location for D.
RecordStorageLocation(QualType Type, FieldToLoc TheChildren)
llvm::DenseMap< const ValueDecl *, StorageLocation * > FieldToLoc
void setChild(const ValueDecl &D, StorageLocation *Loc)
Changes the child storage location for a field D of reference type.
static bool classof(const StorageLocation *Loc)
llvm::iterator_range< FieldToLoc::const_iterator > children() const
A storage location that is not subdivided further for the purposes of abstract interpretation.
static bool classof(const StorageLocation *Loc)
Base class for elements of the local variable store and of the heap.
virtual ~StorageLocation()=default
StorageLocation(Kind LocKind, QualType Type)
StorageLocation & operator=(const StorageLocation &)=delete
StorageLocation(const StorageLocation &)=delete
Definition: Format.h:5226