clang 23.0.0git
EntityPointerLevel.h
Go to the documentation of this file.
1//===- EntityPointerLevel.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#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVEL_H
10#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVEL_H
11
12#include "clang/AST/Expr.h"
15#include "llvm/ADT/STLFunctionalExtras.h"
16#include <set>
17
18namespace clang::ssaf {
19
20/// An EntityPointerLevel is associated with a level of the declared
21/// pointer/array type of an entity. In the fully-expanded spelling of the
22/// declared type, a EntityPointerLevel is associated with a '*' (or a '[]`) in
23/// that declaration.
24///
25/// For example, for 'int *p[10];', there are two EntityPointerLevels.
26/// One is associated with 'int *[10]' of 'p' and the other is associated with
27/// 'int *' of 'p'.
28///
29/// An EntityPointerLevel can be identified by an EntityId and an unsigned
30/// integer indicating the pointer level: '(EntityId, PointerLevel)'.
31/// An EntityPointerLevel 'P' is valid iff 'P.EntityId' has a pointer type with
32/// at least 'P.PointerLevel' levels (This implies 'P.PointerLevel > 0').
33///
34/// For the same example 'int *p[10];', the EntityPointerLevels below are valid:
35/// - '(p, 2)' is associated with the 'int *' part of the declared type of 'p';
36/// - '(p, 1)' is associated with the 'int *[10]' part of the declared type of
37/// 'p'.
38class EntityPointerLevel {
39 EntityId Entity;
40 unsigned PointerLevel;
41
42 friend class EntityPointerLevelTranslator;
43 // For unittests:
44 friend EntityPointerLevel buildEntityPointerLevel(EntityId, unsigned);
45
46 EntityPointerLevel(std::pair<EntityId, unsigned> Pair)
47 : Entity(Pair.first), PointerLevel(Pair.second) {}
48
49public:
50 EntityId getEntity() const { return Entity; }
51 unsigned getPointerLevel() const { return PointerLevel; }
52
53 bool operator==(const EntityPointerLevel &Other) const {
54 return std::tie(Entity, PointerLevel) ==
55 std::tie(Other.Entity, Other.PointerLevel);
56 }
57
58 bool operator!=(const EntityPointerLevel &Other) const {
59 return !(*this == Other);
60 }
61
62 bool operator<(const EntityPointerLevel &Other) const {
63 return std::tie(Entity, PointerLevel) <
64 std::tie(Other.Entity, Other.PointerLevel);
65 }
66
67 /// Compares `EntityPointerLevel`s; additionally, partially compares
68 /// `EntityPointerLevel` with `EntityId`.
69 struct Comparator {
70 using is_transparent = void;
71 bool operator()(const EntityPointerLevel &L,
72 const EntityPointerLevel &R) const {
73 return L < R;
74 }
75 bool operator()(const EntityId &L, const EntityPointerLevel &R) const {
76 return L < R.getEntity();
77 }
78 bool operator()(const EntityPointerLevel &L, const EntityId &R) const {
79 return L.getEntity() < R;
80 }
81 };
82};
83
84using EntityPointerLevelSet =
85 std::set<EntityPointerLevel, EntityPointerLevel::Comparator>;
86
87/// Translate a pointer/array type expression 'E' to a (set of)
88/// EntityPointerLevel(s) associated with the declared type of the base address
89/// of `E`. If the base address of `E` is not associated with an entity, the
90/// translation result is an empty set.
91///
92/// \param E the pointer expression to be translated
93/// \param Ctx the AST context of `E`
94/// \param AddEntity the callback provided by the caller to convert EntityNames
95/// to EntityIds.
96llvm::Expected<EntityPointerLevelSet> translateEntityPointerLevel(
97 const Expr *E, ASTContext &Ctx,
98 llvm::function_ref<EntityId(EntityName EN)> AddEntity);
99
100/// Creates a `EntityPointerLevel` from a pair of an EntityId and a pointer
101/// level:
102EntityPointerLevel buildEntityPointerLevel(EntityId, unsigned);
103
104/// Create an EntityPointerLevel (EPL) from a NamedDecl of a pointer/array type.
105///
106/// \param ND the NamedDecl of a pointer/array type.
107/// \param AddEntity the callback provided by the caller to convert EntityNames
108/// to EntityIds.
109/// \param IsFunRet true iff the created EPL is associated with the return type
110/// of a function entity.
111llvm::Expected<EntityPointerLevel>
112createEntityPointerLevel(const NamedDecl *ND,
113 llvm::function_ref<EntityId(EntityName EN)> AddEntity,
114 bool IsFunRet = false);
115
116/// Creates a new EntityPointerLevel (EPL) from `E` by incrementing `E`'s
117/// pointer level.
118/// \return the EPL that is associated with the pointee (or array element) type
119/// of `E`'s associated pointer/array type of the same entity.
120EntityPointerLevel incrementPointerLevel(const EntityPointerLevel &E);
121} // namespace clang::ssaf
122
123#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVEL_H
Lightweight opaque handle representing an entity in an EntityIdTable.
Definition EntityId.h:31
Uniquely identifies an entity in a program.
Definition EntityName.h:28
bool operator!=(const CommonEntityInfo &LHS, const CommonEntityInfo &RHS)
Definition Types.h:153
EntityPointerLevel incrementPointerLevel(const EntityPointerLevel &E)
An EntityPointerLevel is associated with a level of the declared pointer/array type of an entity.
bool operator==(const ValueType &a, const ValueType &b)
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Other
Other implicit parameter.
Definition Decl.h:1763