clang 23.0.0git
MemberPointer.cpp
Go to the documentation of this file.
1//===------------------------- MemberPointer.cpp ----------------*- 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#include "MemberPointer.h"
10#include "Context.h"
11#include "Program.h"
12#include "Record.h"
13
14namespace clang {
15namespace interp {
16
17std::optional<Pointer> MemberPointer::toPointer(const Context &Ctx) const {
19 return Base;
21
22 if (!Base.isBlockPointer())
23 return std::nullopt;
24
25 unsigned BlockMDSize = Base.block()->getDescriptor()->getMetadataSize();
26
27 if (PtrOffset >= 0) {
28 // If the resulting base would be too small, return nullopt.
29 if (Base.BS.Base < static_cast<unsigned>(PtrOffset) ||
30 (Base.BS.Base - PtrOffset < BlockMDSize))
31 return std::nullopt;
32 }
33
34 Pointer CastedBase =
35 (PtrOffset < 0 ? Base.atField(-PtrOffset) : Base.atFieldSub(PtrOffset));
36
37 const Record *BaseRecord = CastedBase.getRecord();
38 if (!BaseRecord)
39 return std::nullopt;
40
41 unsigned Offset = 0;
42 Offset += BlockMDSize;
43
44 if (const auto *FD = dyn_cast<FieldDecl>(getDecl())) {
45 if (FD->getParent() == BaseRecord->getDecl())
46 return CastedBase.atField(BaseRecord->getField(FD)->Offset);
47
48 const RecordDecl *FieldParent = FD->getParent();
49 const Record *FieldRecord = Ctx.getRecord(FieldParent);
50
51 Offset += FieldRecord->getField(FD)->Offset;
52 if (Offset > CastedBase.block()->getSize())
53 return std::nullopt;
54
55 if (const RecordDecl *BaseDecl = Base.getDeclPtr().getRecord()->getDecl();
56 BaseDecl != FieldParent)
57 Offset += Ctx.collectBaseOffset(FieldParent, BaseDecl);
58
59 } else {
60 const auto *IFD = cast<IndirectFieldDecl>(getDecl());
61
62 for (const NamedDecl *ND : IFD->chain()) {
63 const FieldDecl *F = cast<FieldDecl>(ND);
64 const RecordDecl *FieldParent = F->getParent();
65 const Record *FieldRecord = Ctx.getRecord(FieldParent);
66 Offset += FieldRecord->getField(F)->Offset;
67 }
68 }
69
70 assert(BaseRecord);
71 if (Offset > CastedBase.block()->getSize())
72 return std::nullopt;
73
74 assert(Offset <= CastedBase.block()->getSize());
75 return Pointer(const_cast<Block *>(Base.block()), Offset, Offset);
76}
77
79 if (isZero())
80 return APValue(static_cast<ValueDecl *>(nullptr), /*IsDerivedMember=*/false,
81 /*Path=*/{});
82
83 if (hasBase())
84 return Base.toAPValue(ASTCtx);
85
86 return APValue(getDecl(), /*IsDerivedMember=*/isDerivedMember(),
87 /*Path=*/ArrayRef(Path, PathLength));
88}
89
91MemberPointer::compare(const MemberPointer &RHS) const {
92 if (this->getDecl() == RHS.getDecl()) {
93
94 if (this->PathLength != RHS.PathLength)
96
97 if (PathLength != 0 &&
98 std::memcmp(Path, RHS.Path, PathLength * sizeof(CXXRecordDecl *)) != 0)
100
102 }
104}
105
106} // namespace interp
107} // namespace clang
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:226
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2109
Represents a member of a struct/union/class.
Definition Decl.h:3175
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Definition Decl.h:3411
This represents a decl that may have a name.
Definition Decl.h:274
Represents a struct/union/class.
Definition Decl.h:4342
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
A memory block, either on the stack or in the heap.
Definition InterpBlock.h:44
unsigned getSize() const
Returns the size of the block.
Definition InterpBlock.h:87
Holds all information required to evaluate constexpr code in a module.
Definition Context.h:47
unsigned collectBaseOffset(const RecordDecl *BaseDecl, const RecordDecl *DerivedDecl) const
Definition Context.cpp:687
const Record * getRecord(const RecordDecl *D) const
Definition Context.cpp:718
const ValueDecl * getDecl() const
Return the base declaration. Might be null.
APValue toAPValue(const ASTContext &) const
ComparisonCategoryResult compare(const MemberPointer &RHS) const
std::optional< Pointer > toPointer(const Context &Ctx) const
A pointer to a memory block, live or dead.
Definition Pointer.h:97
Pointer atField(unsigned Off) const
Creates a pointer to a field.
Definition Pointer.h:179
const Block * block() const
Definition Pointer.h:617
const Record * getRecord() const
Returns the record descriptor of a class.
Definition Pointer.h:485
Structure/Class descriptor.
Definition Record.h:25
const RecordDecl * getDecl() const
Returns the underlying declaration.
Definition Record.h:65
const Field * getField(unsigned I) const
Definition Record.h:95
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