clang 23.0.0git
MemberPointer.h
Go to the documentation of this file.
1//===------------------------- MemberPointer.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_AST_INTERP_MEMBER_POINTER_H
10#define LLVM_CLANG_AST_INTERP_MEMBER_POINTER_H
11
12#include "Pointer.h"
13#include "llvm/ADT/PointerIntPair.h"
14#include <optional>
15
16namespace clang {
17class ASTContext;
18class CXXRecordDecl;
19namespace interp {
20
21class Context;
22class FunctionPointer;
23
24class MemberPointer final {
25private:
26 Pointer Base;
27 /// The member declaration, and a flag indicating
28 /// whether the member is a member of some class derived from the class type
29 /// of the member pointer.
30 llvm::PointerIntPair<const ValueDecl *, 1, bool> DeclAndIsDerivedMember;
31 /// The path of base/derived classes from the member declaration's
32 /// class (exclusive) to the class type of the member pointer (inclusive).
33 /// This a allocated by the InterpState or the Program.
34 const CXXRecordDecl **Path = nullptr;
35 int32_t PtrOffset = 0;
36 uint8_t PathLength = 0;
37
38 MemberPointer(Pointer Base, const ValueDecl *Dcl, int32_t PtrOffset,
39 uint8_t PathLength = 0, const CXXRecordDecl **Path = nullptr,
40 bool IsDerived = false)
41 : Base(Base), DeclAndIsDerivedMember(Dcl, IsDerived), Path(Path),
42 PtrOffset(PtrOffset), PathLength(PathLength) {}
43
44public:
45 MemberPointer() = default;
47 : Base(Base), DeclAndIsDerivedMember(Dcl) {}
48 MemberPointer(uint32_t Address, const Descriptor *D) {
49 // We only reach this for Address == 0, when creating a null member pointer.
50 assert(Address == 0);
51 }
52
53 MemberPointer(const ValueDecl *D) : DeclAndIsDerivedMember(D) {
55 }
56
57 uint64_t getIntegerRepresentation() const {
58 assert(
59 false &&
60 "getIntegerRepresentation() shouldn't be reachable for MemberPointers");
61 return 17;
62 }
63
64 /// Does this member pointer have a base declaration?
65 bool hasDecl() const { return DeclAndIsDerivedMember.getPointer(); }
66 bool isDerivedMember() const { return DeclAndIsDerivedMember.getInt(); }
67 /// Return the base declaration. Might be null.
68 const ValueDecl *getDecl() const {
69 return DeclAndIsDerivedMember.getPointer();
70 }
71 /// Does this member pointer have a path (i.e. path length is > 0)?
72 bool hasPath() const { return PathLength != 0; }
73 /// Return the length of the cast path.
74 unsigned getPathLength() const { return PathLength; }
75 /// Return the cast path entry at the given position.
76 const CXXRecordDecl *getPathEntry(unsigned Index) const {
77 assert(Index < PathLength);
78 return Path[Index];
79 }
80 /// Return the cast path. Might return null.
81 const CXXRecordDecl **path() const { return Path; }
82 bool isZero() const { return Base.isZero() && !hasDecl(); }
83 bool hasBase() const { return !Base.isZero(); }
84 bool isWeak() const {
85 if (const auto *MF = getMemberFunction())
86 return MF->isWeak();
87 return false;
88 }
89
90 /// Sets the path of this member pointer. After this call,
91 /// the memory pointed to by \p NewPath is assumed to be owned
92 /// by this member pointer.
93 void takePath(const CXXRecordDecl **NewPath) {
94 assert(Path != NewPath);
95 Path = NewPath;
96 }
97
98 // Pretend we always have a path.
99 bool singleWord() const { return false; }
101
102 std::optional<Pointer> toPointer(const Context &Ctx) const;
103 FunctionPointer toFunctionPointer(const Context &Ctx) const;
104
105 bool isBaseCastPossible() const {
106 if (PtrOffset < 0)
107 return true;
108 return static_cast<uint64_t>(PtrOffset) <= Base.getByteOffset();
109 }
110
111 Pointer getBase() const {
112 if (PtrOffset < 0)
113 return Base.atField(-PtrOffset);
114 return Base.atFieldSub(PtrOffset);
115 }
116 /// Is the base declaration a member function?
118 return isa_and_nonnull<CXXMethodDecl>(DeclAndIsDerivedMember.getPointer());
119 }
120 /// Return the base declaration as a CXXMethodDecl. Might return null.
122 return dyn_cast_if_present<CXXMethodDecl>(
123 DeclAndIsDerivedMember.getPointer());
124 }
125 /// Return the base declaration as a FieldDecl. Might return null.
126 const FieldDecl *getField() const {
127 return dyn_cast_if_present<FieldDecl>(DeclAndIsDerivedMember.getPointer());
128 }
129 /// Returns the record decl this member pointer points into.
131 if (const FieldDecl *FD = getField())
132 return cast<CXXRecordDecl>(FD->getParent());
133
134 if (const CXXMethodDecl *MD = getMemberFunction())
135 return MD->getParent();
136 return nullptr;
137 }
138
139 MemberPointer atInstanceBase(unsigned Offset, uint8_t PathLength = 0,
140 const CXXRecordDecl **Path = nullptr,
141 bool NewIsDerived = false) const {
142 if (Base.isZero())
143 return MemberPointer(Base, DeclAndIsDerivedMember.getPointer(), Offset,
144 PathLength, Path, NewIsDerived);
145 return MemberPointer(this->Base, DeclAndIsDerivedMember.getPointer(),
146 Offset + PtrOffset, PathLength, Path, NewIsDerived);
147 }
148
149 MemberPointer takeInstance(Pointer Instance) const {
150 assert(this->Base.isZero());
151 return MemberPointer(Instance, DeclAndIsDerivedMember.getPointer(),
152 this->PtrOffset);
153 }
154
155 APValue toAPValue(const ASTContext &) const;
156
157 void print(llvm::raw_ostream &OS) const {
158 OS << "MemberPtr(" << Base << " " << (const void *)getDecl() << " + "
159 << PtrOffset << ". PathLength: " << getPathLength()
160 << ". IsDerived: " << isDerivedMember() << ")";
161 }
162
163 std::string toDiagnosticString(const ASTContext &Ctx) const {
164 return toAPValue(Ctx).getAsString(Ctx, getDecl()->getType());
165 }
166};
167
168inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
169 const MemberPointer &FP) {
170 FP.print(OS);
171 return OS;
172}
173
174} // namespace interp
175} // namespace clang
176
177#endif
TokenType getType() const
Returns the token's type, e.g.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
Definition APValue.cpp:988
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:226
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2136
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
Represents a member of a struct/union/class.
Definition Decl.h:3160
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
Holds all information required to evaluate constexpr code in a module.
Definition Context.h:42
const ValueDecl * getDecl() const
Return the base declaration. Might be null.
bool hasDecl() const
Does this member pointer have a base declaration?
APValue toAPValue(const ASTContext &) const
uint64_t getIntegerRepresentation() const
MemberPointer takeInstance(Pointer Instance) const
const CXXRecordDecl * getRecordDecl() const
Returns the record decl this member pointer points into.
const CXXRecordDecl * getPathEntry(unsigned Index) const
Return the cast path entry at the given position.
bool hasPath() const
Does this member pointer have a path (i.e. path length is > 0)?
std::string toDiagnosticString(const ASTContext &Ctx) const
MemberPointer(uint32_t Address, const Descriptor *D)
bool isMemberFunctionPointer() const
Is the base declaration a member function?
MemberPointer(const ValueDecl *D)
const FieldDecl * getField() const
Return the base declaration as a FieldDecl. Might return null.
MemberPointer atInstanceBase(unsigned Offset, uint8_t PathLength=0, const CXXRecordDecl **Path=nullptr, bool NewIsDerived=false) const
void print(llvm::raw_ostream &OS) const
void takePath(const CXXRecordDecl **NewPath)
Sets the path of this member pointer.
unsigned getPathLength() const
Return the length of the cast path.
ComparisonCategoryResult compare(const MemberPointer &RHS) const
const CXXRecordDecl ** path() const
Return the cast path. Might return null.
FunctionPointer toFunctionPointer(const Context &Ctx) const
const CXXMethodDecl * getMemberFunction() const
Return the base declaration as a CXXMethodDecl. Might return null.
std::optional< Pointer > toPointer(const Context &Ctx) const
MemberPointer(Pointer Base, const ValueDecl *Dcl)
A pointer to a memory block, live or dead.
Definition Pointer.h:93
Pointer atFieldSub(unsigned Off) const
Subtract the given offset from the current Base and Offset of the pointer.
Definition Pointer.h:183
Pointer atField(unsigned Off) const
Creates a pointer to a field.
Definition Pointer.h:175
bool isZero() const
Checks if the pointer is null.
Definition Pointer.h:260
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const Boolean &B)
Definition Boolean.h:154
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
U cast(CodeGen::Address addr)
Definition Address.h:327
Describes a memory block created by an allocation site.
Definition Descriptor.h:121