Path: blob/main/contrib/llvm-project/clang/lib/AST/Interp/MemberPointer.cpp
35291 views
//===------------------------- MemberPointer.cpp ----------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "MemberPointer.h"9#include "Context.h"10#include "FunctionPointer.h"11#include "Program.h"12#include "Record.h"1314namespace clang {15namespace interp {1617std::optional<Pointer> MemberPointer::toPointer(const Context &Ctx) const {18if (!Dcl || isa<FunctionDecl>(Dcl))19return Base;20const FieldDecl *FD = cast<FieldDecl>(Dcl);21assert(FD);2223if (!Base.isBlockPointer())24return std::nullopt;2526Pointer CastedBase =27(PtrOffset < 0 ? Base.atField(-PtrOffset) : Base.atFieldSub(PtrOffset));2829const Record *BaseRecord = CastedBase.getRecord();30if (!BaseRecord)31return std::nullopt;3233assert(BaseRecord);34if (FD->getParent() == BaseRecord->getDecl())35return CastedBase.atField(BaseRecord->getField(FD)->Offset);3637const RecordDecl *FieldParent = FD->getParent();38const Record *FieldRecord = Ctx.getRecord(FieldParent);3940unsigned Offset = 0;41Offset += FieldRecord->getField(FD)->Offset;42Offset += CastedBase.block()->getDescriptor()->getMetadataSize();4344if (Offset > CastedBase.block()->getSize())45return std::nullopt;4647if (const RecordDecl *BaseDecl = Base.getDeclPtr().getRecord()->getDecl();48BaseDecl != FieldParent)49Offset += Ctx.collectBaseOffset(FieldParent, BaseDecl);5051if (Offset > CastedBase.block()->getSize())52return std::nullopt;5354assert(Offset <= CastedBase.block()->getSize());55return Pointer(const_cast<Block *>(Base.block()), Offset, Offset);56}5758FunctionPointer MemberPointer::toFunctionPointer(const Context &Ctx) const {59return FunctionPointer(Ctx.getProgram().getFunction(cast<FunctionDecl>(Dcl)));60}6162APValue MemberPointer::toAPValue(const ASTContext &ASTCtx) const {63if (isZero())64return APValue(static_cast<ValueDecl *>(nullptr), /*IsDerivedMember=*/false,65/*Path=*/{});6667if (hasBase())68return Base.toAPValue(ASTCtx);6970return APValue(cast<ValueDecl>(getDecl()), /*IsDerivedMember=*/false,71/*Path=*/{});72}7374} // namespace interp75} // namespace clang767778