clang 20.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 "FunctionPointer.h"
12#include "Program.h"
13#include "Record.h"
14
15namespace clang {
16namespace interp {
17
18std::optional<Pointer> MemberPointer::toPointer(const Context &Ctx) const {
19 if (!Dcl || isa<FunctionDecl>(Dcl))
20 return Base;
21 assert((isa<FieldDecl, IndirectFieldDecl>(Dcl)));
22
23 if (!Base.isBlockPointer())
24 return std::nullopt;
25
26 Pointer CastedBase =
27 (PtrOffset < 0 ? Base.atField(-PtrOffset) : Base.atFieldSub(PtrOffset));
28
29 const Record *BaseRecord = CastedBase.getRecord();
30 if (!BaseRecord)
31 return std::nullopt;
32
33 unsigned Offset = 0;
34 Offset += CastedBase.block()->getDescriptor()->getMetadataSize();
35
36 if (const auto *FD = dyn_cast<FieldDecl>(Dcl)) {
37 if (FD->getParent() == BaseRecord->getDecl())
38 return CastedBase.atField(BaseRecord->getField(FD)->Offset);
39
40 const RecordDecl *FieldParent = FD->getParent();
41 const Record *FieldRecord = Ctx.getRecord(FieldParent);
42
43 Offset += FieldRecord->getField(FD)->Offset;
44 if (Offset > CastedBase.block()->getSize())
45 return std::nullopt;
46
47 if (const RecordDecl *BaseDecl = Base.getDeclPtr().getRecord()->getDecl();
48 BaseDecl != FieldParent)
49 Offset += Ctx.collectBaseOffset(FieldParent, BaseDecl);
50
51 } else {
52 const auto *IFD = cast<IndirectFieldDecl>(Dcl);
53
54 for (const NamedDecl *ND : IFD->chain()) {
55 const FieldDecl *F = cast<FieldDecl>(ND);
56 const RecordDecl *FieldParent = F->getParent();
57 const Record *FieldRecord = Ctx.getRecord(FieldParent);
58 Offset += FieldRecord->getField(F)->Offset;
59 }
60 }
61
62 assert(BaseRecord);
63 if (Offset > CastedBase.block()->getSize())
64 return std::nullopt;
65
66 assert(Offset <= CastedBase.block()->getSize());
67 return Pointer(const_cast<Block *>(Base.block()), Offset, Offset);
68}
69
71 return FunctionPointer(Ctx.getProgram().getFunction(cast<FunctionDecl>(Dcl)));
72}
73
75 if (isZero())
76 return APValue(static_cast<ValueDecl *>(nullptr), /*IsDerivedMember=*/false,
77 /*Path=*/{});
78
79 if (hasBase())
80 return Base.toAPValue(ASTCtx);
81
82 return APValue(cast<ValueDecl>(getDecl()), /*IsDerivedMember=*/false,
83 /*Path=*/{});
84}
85
86} // namespace interp
87} // 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:187
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2090
Represents a member of a struct/union/class.
Definition: Decl.h:3030
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Definition: Decl.h:3247
This represents a decl that may have a name.
Definition: Decl.h:249
Represents a struct/union/class.
Definition: Decl.h:4145
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:667
A memory block, either on the stack or in the heap.
Definition: InterpBlock.h:49
unsigned getSize() const
Returns the size of the block.
Definition: InterpBlock.h:78
const Descriptor * getDescriptor() const
Returns the block's descriptor.
Definition: InterpBlock.h:67
Holds all information required to evaluate constexpr code in a module.
Definition: Context.h:40
Program & getProgram() const
Returns the program. This is only needed for unittests.
Definition: Context.h:105
unsigned collectBaseOffset(const RecordDecl *BaseDecl, const RecordDecl *DerivedDecl) const
Definition: Context.cpp:281
const Record * getRecord(const RecordDecl *D) const
Definition: Context.cpp:312
APValue toAPValue(const ASTContext &) const
const Decl * getDecl() const
Definition: MemberPointer.h:70
FunctionPointer toFunctionPointer(const Context &Ctx) const
std::optional< Pointer > toPointer(const Context &Ctx) const
A pointer to a memory block, live or dead.
Definition: Pointer.h:82
Pointer atField(unsigned Off) const
Creates a pointer to a field.
Definition: Pointer.h:168
const Block * block() const
Definition: Pointer.h:569
const Record * getRecord() const
Returns the record descriptor of a class.
Definition: Pointer.h:461
Function * getFunction(const FunctionDecl *F)
Returns a function.
Definition: Program.cpp:247
Structure/Class descriptor.
Definition: Record.h:25
const RecordDecl * getDecl() const
Returns the underlying declaration.
Definition: Record.h:52
const Field * getField(const FieldDecl *FD) const
Returns a field.
Definition: Record.cpp:39
The JSON file list parser is used to communicate input to InstallAPI.
unsigned getMetadataSize() const
Returns the size of the metadata.
Definition: Descriptor.h:234