clang 24.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_SCALABLESTATICANALYSIS_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVEL_H
10#define LLVM_CLANG_SCALABLESTATICANALYSIS_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVEL_H
11
12#include "clang/AST/Expr.h"
14#include "llvm/ADT/SmallVector.h"
15#include <set>
16
17namespace clang::ssaf {
19
20// Intermediate data structure that can be converted to a `EntityPointerLevel`,
21// which abstracts away all the additional information carried in the NamedDecl.
24 unsigned PointerLevel;
26};
27
29
30/// An EntityPointerLevel is associated with a level of the declared
31/// pointer/array type of an entity. In the fully-expanded spelling of the
32/// declared type, a EntityPointerLevel is associated with a '*' (or a '[]`) in
33/// that declaration.
34///
35/// For example, for 'int *p[10];', there are two EntityPointerLevels.
36/// One is associated with 'int *[10]' of 'p' and the other is associated with
37/// 'int *' of 'p'.
38///
39/// An EntityPointerLevel can be identified by an EntityId and an unsigned
40/// integer indicating the pointer level: '(EntityId, PointerLevel)'.
41/// An EntityPointerLevel 'P' is valid iff 'P.EntityId' has a pointer type with
42/// at least 'P.PointerLevel' levels (This implies 'P.PointerLevel > 0').
43///
44/// For the same example 'int *p[10];', the EntityPointerLevels below are valid:
45/// - '(p, 2)' is associated with the 'int *' part of the declared type of 'p';
46/// - '(p, 1)' is associated with the 'int *[10]' part of the declared type of
47/// 'p'.
48class EntityPointerLevel {
49 EntityId Entity;
50 unsigned PointerLevel;
51
53 // For unittests:
54 friend EntityPointerLevel buildEntityPointerLevel(EntityId, unsigned);
55
56 explicit EntityPointerLevel(std::pair<EntityId, unsigned> Pair)
57 : Entity(Pair.first), PointerLevel(Pair.second) {}
58
59public:
60 EntityId getEntity() const { return Entity; }
61 unsigned getPointerLevel() const { return PointerLevel; }
62
63 bool operator==(const EntityPointerLevel &Other) const {
64 return std::tie(Entity, PointerLevel) ==
65 std::tie(Other.Entity, Other.PointerLevel);
66 }
67
68 bool operator!=(const EntityPointerLevel &Other) const {
69 return !(*this == Other);
70 }
71
72 bool operator<(const EntityPointerLevel &Other) const {
73 return std::tie(Entity, PointerLevel) <
74 std::tie(Other.Entity, Other.PointerLevel);
75 }
76
77 /// Compares `EntityPointerLevel`s; additionally, partially compares
78 /// `EntityPointerLevel` with `EntityId`.
79 struct Comparator {
80 using is_transparent = void;
81 bool operator()(const EntityPointerLevel &L,
82 const EntityPointerLevel &R) const {
83 return L < R;
84 }
85 bool operator()(const EntityId &L, const EntityPointerLevel &R) const {
86 return L < R.getEntity();
87 }
88 bool operator()(const EntityPointerLevel &L, const EntityId &R) const {
89 return L.getEntity() < R;
90 }
91 };
92};
93
94using EntityPointerLevelSet =
95 std::set<EntityPointerLevel, EntityPointerLevel::Comparator>;
96
97/// Translate a pointer/array type expression 'E' to a (set of)
98/// EntityPointerLevel(s) associated with the declared type of the base address
99/// of `E`. If the base address of `E` is not associated with an entity, the
100/// translation result is an empty set.
101///
102/// \param E the pointer expression to be translated
103/// \param Ctx the AST context of `E`
104/// \param Extractor the TUSummaryExtractor used to convert NamedDecls to
105/// EntityIds.
107translateEntityPointerLevel(const Expr *E, ASTContext &Ctx,
108 TUSummaryExtractor &Extractor);
109
110/// Same as \c translateEntityPointerLevel, except it returns raw
111/// `(NamedDecl *, pointer level, is-return)` tuples (a.k.a. DeclPointerLevels)
112/// instead of assembling an `EntityPointerLevelSet` directly.
114translateDeclPointerLevel(const Expr *E, ASTContext &Ctx,
115 TUSummaryExtractor &Extractor);
116
117/// Assemble `DeclPointerLevels` into an `EntityPointerLevelSet`.
119toEntityPointerLevels(const DeclPointerLevelVec &DPLs, ASTContext &Ctx,
120 TUSummaryExtractor &Extractor);
121
122/// Convert a single `DeclPointerLevel` to an `EntityPointerLevel`.
124toEntityPointerLevel(const DeclPointerLevel &DPL, ASTContext &Ctx,
125 TUSummaryExtractor &Extractor);
126
127/// Creates a `EntityPointerLevel` from a pair of an EntityId and a pointer
128/// level:
129EntityPointerLevel buildEntityPointerLevel(EntityId, unsigned);
130
131/// Create an DeclPointerLevel (DPL) from a NamedDecl of a pointer/array type.
132///
133/// \param ND the NamedDecl of a pointer/array type.
134/// \param IsFunRet true iff the created DPL is associated with the return type
135/// of a function entity.
136DeclPointerLevel createDeclPointerLevel(const NamedDecl *ND,
137 bool IsFunRet = false);
138
139/// Create an EntityPointerLevel (EPL) from a NamedDecl of a pointer/array type.
140///
141/// \param ND the NamedDecl of a pointer/array type.
142/// \param AddEntity the callback provided by the caller to convert EntityNames
143/// to EntityIds.
144/// \param IsFunRet true iff the created EPL is associated with the return type
145/// of a function entity.
147createEntityPointerLevel(const NamedDecl *ND, TUSummaryExtractor &Extractor,
148 bool IsFunRet = false);
149
150/// \return an exhaustive vector of unique DeclPointerLevels, sorted in
151/// ascending order of pointer levels. All elements are identical to \p DPL
152/// except with a pointer level greater than or equal to that of \p DPL. The
153/// pointer level of each element is bounded by the type of \p DPL's NamedDecl.
155elaborateHigherDeclPointerLevels(const DeclPointerLevel &DPL);
156} // namespace clang::ssaf
157
158#endif // LLVM_CLANG_SCALABLESTATICANALYSIS_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVEL_H
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
This represents one expression.
Definition Expr.h:113
This represents a decl that may have a name.
Definition Decl.h:275
Lightweight opaque handle representing an entity in an EntityIdTable.
Definition EntityId.h:31
EntityPointerLevel buildEntityPointerLevel(EntityId, unsigned)
An EntityPointerLevel is associated with a level of the declared pointer/array type of an entity.
DeclPointerLevel createDeclPointerLevel(const NamedDecl *ND, bool IsFunRet=false)
Create an DeclPointerLevel (DPL) from a NamedDecl of a pointer/array type.
DeclPointerLevelVec elaborateHigherDeclPointerLevels(const DeclPointerLevel &DPL)
llvm::Expected< EntityPointerLevel > createEntityPointerLevel(const NamedDecl *ND, TUSummaryExtractor &Extractor, bool IsFunRet=false)
Create an EntityPointerLevel (EPL) from a NamedDecl of a pointer/array type.
llvm::SmallVector< DeclPointerLevel, 2 > DeclPointerLevelVec
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
Definition CallGraph.h:218
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
bool operator!=(CanQual< T > x, CanQual< U > y)
@ Other
Other implicit parameter.
Definition Decl.h:1775