/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
Line | Count | Source (jump to first uncovered line) |
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 | | |
21 | | namespace clang { |
22 | | namespace dataflow { |
23 | | |
24 | | /// Base class for elements of the local variable store and of the heap. |
25 | | /// |
26 | | /// Each storage location holds a value. The mapping from storage locations to |
27 | | /// values is stored in the environment. |
28 | | class StorageLocation { |
29 | | public: |
30 | | enum class Kind { Scalar, Aggregate }; |
31 | | |
32 | 3.10k | StorageLocation(Kind LocKind, QualType Type) : LocKind(LocKind), Type(Type) {} |
33 | | |
34 | | // Non-copyable because addresses of storage locations are used as their |
35 | | // identities throughout framework and user code. The framework is responsible |
36 | | // for construction and destruction of storage locations. |
37 | | StorageLocation(const StorageLocation &) = delete; |
38 | | StorageLocation &operator=(const StorageLocation &) = delete; |
39 | | |
40 | 3.10k | virtual ~StorageLocation() = default; |
41 | | |
42 | 5.50k | Kind getKind() const { return LocKind; } |
43 | | |
44 | 2.77k | QualType getType() const { return Type; } |
45 | | |
46 | | private: |
47 | | Kind LocKind; |
48 | | QualType Type; |
49 | | }; |
50 | | |
51 | | /// A storage location that is not subdivided further for the purposes of |
52 | | /// abstract interpretation. For example: `int`, `int*`, `int&`. |
53 | | class ScalarStorageLocation final : public StorageLocation { |
54 | | public: |
55 | | explicit ScalarStorageLocation(QualType Type) |
56 | 1.55k | : StorageLocation(Kind::Scalar, Type) {} |
57 | | |
58 | 1.58k | static bool classof(const StorageLocation *Loc) { |
59 | 1.58k | return Loc->getKind() == Kind::Scalar; |
60 | 1.58k | } |
61 | | }; |
62 | | |
63 | | /// A storage location which is subdivided into smaller storage locations that |
64 | | /// can be traced independently by abstract interpretation. For example: a |
65 | | /// struct with public members. The child map is flat, so when used for a struct |
66 | | /// or class type, all accessible members of base struct and class types are |
67 | | /// directly accesible as children of this location. |
68 | | class AggregateStorageLocation final : public StorageLocation { |
69 | | public: |
70 | | explicit AggregateStorageLocation(QualType Type) |
71 | | : AggregateStorageLocation( |
72 | 0 | Type, llvm::DenseMap<const ValueDecl *, StorageLocation *>()) {} |
73 | | |
74 | | AggregateStorageLocation( |
75 | | QualType Type, |
76 | | llvm::DenseMap<const ValueDecl *, StorageLocation *> Children) |
77 | 1.55k | : StorageLocation(Kind::Aggregate, Type), Children(std::move(Children)) {} |
78 | | |
79 | 3.92k | static bool classof(const StorageLocation *Loc) { |
80 | 3.92k | return Loc->getKind() == Kind::Aggregate; |
81 | 3.92k | } |
82 | | |
83 | | /// Returns the child storage location for `D`. |
84 | 344 | StorageLocation &getChild(const ValueDecl &D) const { |
85 | 344 | auto It = Children.find(&D); |
86 | 344 | assert(It != Children.end()); |
87 | 0 | return *It->second; |
88 | 344 | } |
89 | | |
90 | | private: |
91 | | llvm::DenseMap<const ValueDecl *, StorageLocation *> Children; |
92 | | }; |
93 | | |
94 | | } // namespace dataflow |
95 | | } // namespace clang |
96 | | |
97 | | #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H |