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 
15 namespace clang {
16 namespace interp {
17 
18 std::optional<Pointer> MemberPointer::toPointer(const Context &Ctx) const {
19  if (!Dcl || isa<FunctionDecl>(Dcl))
20  return Base;
21  const FieldDecl *FD = cast<FieldDecl>(Dcl);
22  assert(FD);
23 
24  if (!Base.isBlockPointer())
25  return std::nullopt;
26 
27  Pointer CastedBase =
28  (PtrOffset < 0 ? Base.atField(-PtrOffset) : Base.atFieldSub(PtrOffset));
29 
30  const Record *BaseRecord = CastedBase.getRecord();
31  if (!BaseRecord)
32  return std::nullopt;
33 
34  assert(BaseRecord);
35  if (FD->getParent() == BaseRecord->getDecl())
36  return CastedBase.atField(BaseRecord->getField(FD)->Offset);
37 
38  const RecordDecl *FieldParent = FD->getParent();
39  const Record *FieldRecord = Ctx.getRecord(FieldParent);
40 
41  unsigned Offset = 0;
42  Offset += FieldRecord->getField(FD)->Offset;
43  Offset += CastedBase.block()->getDescriptor()->getMetadataSize();
44 
45  if (Offset > CastedBase.block()->getSize())
46  return std::nullopt;
47 
48  if (const RecordDecl *BaseDecl = Base.getDeclPtr().getRecord()->getDecl();
49  BaseDecl != FieldParent)
50  Offset += Ctx.collectBaseOffset(FieldParent, BaseDecl);
51 
52  if (Offset > CastedBase.block()->getSize())
53  return std::nullopt;
54 
55  assert(Offset <= CastedBase.block()->getSize());
56  return Pointer(const_cast<Block *>(Base.block()), Offset, Offset);
57 }
58 
60  return FunctionPointer(Ctx.getProgram().getFunction(cast<FunctionDecl>(Dcl)));
61 }
62 
64  if (isZero())
65  return APValue(static_cast<ValueDecl *>(nullptr), /*IsDerivedMember=*/false,
66  /*Path=*/{});
67 
68  if (hasBase())
69  return Base.toAPValue(ASTCtx);
70 
71  return APValue(cast<ValueDecl>(getDecl()), /*IsDerivedMember=*/false,
72  /*Path=*/{});
73 }
74 
75 } // namespace interp
76 } // namespace clang
unsigned Offset
Definition: Format.cpp:3003
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
Represents a member of a struct/union/class.
Definition: Decl.h:3031
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Definition: Decl.h:3248
Represents a struct/union/class.
Definition: Decl.h:4146
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:668
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
unsigned collectBaseOffset(const RecordDecl *BaseDecl, const RecordDecl *DerivedDecl) const
Definition: Context.cpp:281
const Record * getRecord(const RecordDecl *D) const
Definition: Context.cpp:312
Program & getProgram() const
Returns the program. This is only needed for unittests.
Definition: Context.h:105
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 Record * getRecord() const
Returns the record descriptor of a class.
Definition: Pointer.h:461
const Block * block() const
Definition: Pointer.h:569
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