Path: blob/main/contrib/llvm-project/clang/lib/AST/Interp/MemberPointer.h
35292 views
//===------------------------- MemberPointer.h ------------------*- 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#ifndef LLVM_CLANG_AST_INTERP_MEMBER_POINTER_H9#define LLVM_CLANG_AST_INTERP_MEMBER_POINTER_H1011#include "Pointer.h"12#include <optional>1314namespace clang {15class ASTContext;16namespace interp {1718class Context;19class FunctionPointer;2021class MemberPointer final {22private:23Pointer Base;24const Decl *Dcl = nullptr;25int32_t PtrOffset = 0;2627MemberPointer(Pointer Base, const Decl *Dcl, int32_t PtrOffset)28: Base(Base), Dcl(Dcl), PtrOffset(PtrOffset) {}2930public:31MemberPointer() = default;32MemberPointer(Pointer Base, const Decl *Dcl) : Base(Base), Dcl(Dcl) {}33MemberPointer(uint32_t Address, const Descriptor *D) {34// We only reach this for Address == 0, when creating a null member pointer.35assert(Address == 0);36}3738MemberPointer(const Decl *D) : Dcl(D) {39assert((isa<FieldDecl, IndirectFieldDecl, CXXMethodDecl>(D)));40}4142uint64_t getIntegerRepresentation() const {43assert(44false &&45"getIntegerRepresentation() shouldn't be reachable for MemberPointers");46return 17;47}4849std::optional<Pointer> toPointer(const Context &Ctx) const;5051FunctionPointer toFunctionPointer(const Context &Ctx) const;5253Pointer getBase() const {54if (PtrOffset < 0)55return Base.atField(-PtrOffset);56return Base.atFieldSub(PtrOffset);57}58bool isMemberFunctionPointer() const {59return isa_and_nonnull<CXXMethodDecl>(Dcl);60}61const CXXMethodDecl *getMemberFunction() const {62return dyn_cast_if_present<CXXMethodDecl>(Dcl);63}64const FieldDecl *getField() const {65return dyn_cast_if_present<FieldDecl>(Dcl);66}6768bool hasDecl() const { return Dcl; }69const Decl *getDecl() const { return Dcl; }7071MemberPointer atInstanceBase(unsigned Offset) const {72if (Base.isZero())73return MemberPointer(Base, Dcl, Offset);74return MemberPointer(this->Base, Dcl, Offset + PtrOffset);75}7677MemberPointer takeInstance(Pointer Instance) const {78assert(this->Base.isZero());79return MemberPointer(Instance, this->Dcl, this->PtrOffset);80}8182APValue toAPValue(const ASTContext &) const;8384bool isZero() const { return Base.isZero() && !Dcl; }85bool hasBase() const { return !Base.isZero(); }8687void print(llvm::raw_ostream &OS) const {88OS << "MemberPtr(" << Base << " " << (const void *)Dcl << " + " << PtrOffset89<< ")";90}9192std::string toDiagnosticString(const ASTContext &Ctx) const {93return "FIXME";94}9596ComparisonCategoryResult compare(const MemberPointer &RHS) const {97if (this->Dcl == RHS.Dcl)98return ComparisonCategoryResult::Equal;99return ComparisonCategoryResult::Unordered;100}101};102103inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, MemberPointer FP) {104FP.print(OS);105return OS;106}107108} // namespace interp109} // namespace clang110111#endif112113114