brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · 8dd75ca Raw
124 lines · c
1//===------------------------- MemberPointer.h ------------------*- 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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_AST_INTERP_MEMBER_POINTER_H10#define LLVM_CLANG_AST_INTERP_MEMBER_POINTER_H11 12#include "Pointer.h"13#include <optional>14 15namespace clang {16class ASTContext;17namespace interp {18 19class Context;20class FunctionPointer;21 22class MemberPointer final {23private:24  Pointer Base;25  const ValueDecl *Dcl = nullptr;26  int32_t PtrOffset = 0;27 28  MemberPointer(Pointer Base, const ValueDecl *Dcl, int32_t PtrOffset)29      : Base(Base), Dcl(Dcl), PtrOffset(PtrOffset) {}30 31public:32  MemberPointer() = default;33  MemberPointer(Pointer Base, const ValueDecl *Dcl) : Base(Base), Dcl(Dcl) {}34  MemberPointer(uint32_t Address, const Descriptor *D) {35    // We only reach this for Address == 0, when creating a null member pointer.36    assert(Address == 0);37  }38 39  MemberPointer(const ValueDecl *D) : Dcl(D) {40    assert((isa<FieldDecl, IndirectFieldDecl, CXXMethodDecl>(D)));41  }42 43  uint64_t getIntegerRepresentation() const {44    assert(45        false &&46        "getIntegerRepresentation() shouldn't be reachable for MemberPointers");47    return 17;48  }49 50  std::optional<Pointer> toPointer(const Context &Ctx) const;51 52  FunctionPointer toFunctionPointer(const Context &Ctx) const;53 54  bool isBaseCastPossible() const {55    if (PtrOffset < 0)56      return true;57    return static_cast<uint64_t>(PtrOffset) <= Base.getByteOffset();58  }59 60  Pointer getBase() const {61    if (PtrOffset < 0)62      return Base.atField(-PtrOffset);63    return Base.atFieldSub(PtrOffset);64  }65  bool isMemberFunctionPointer() const {66    return isa_and_nonnull<CXXMethodDecl>(Dcl);67  }68  const CXXMethodDecl *getMemberFunction() const {69    return dyn_cast_if_present<CXXMethodDecl>(Dcl);70  }71  const FieldDecl *getField() const {72    return dyn_cast_if_present<FieldDecl>(Dcl);73  }74 75  bool hasDecl() const { return Dcl; }76  const ValueDecl *getDecl() const { return Dcl; }77 78  MemberPointer atInstanceBase(unsigned Offset) const {79    if (Base.isZero())80      return MemberPointer(Base, Dcl, Offset);81    return MemberPointer(this->Base, Dcl, Offset + PtrOffset);82  }83 84  MemberPointer takeInstance(Pointer Instance) const {85    assert(this->Base.isZero());86    return MemberPointer(Instance, this->Dcl, this->PtrOffset);87  }88 89  APValue toAPValue(const ASTContext &) const;90 91  bool isZero() const { return Base.isZero() && !Dcl; }92  bool hasBase() const { return !Base.isZero(); }93  bool isWeak() const {94    if (const auto *MF = getMemberFunction())95      return MF->isWeak();96    return false;97  }98 99  void print(llvm::raw_ostream &OS) const {100    OS << "MemberPtr(" << Base << " " << (const void *)Dcl << " + " << PtrOffset101       << ")";102  }103 104  std::string toDiagnosticString(const ASTContext &Ctx) const {105    return toAPValue(Ctx).getAsString(Ctx, Dcl->getType());106  }107 108  ComparisonCategoryResult compare(const MemberPointer &RHS) const {109    if (this->Dcl == RHS.Dcl)110      return ComparisonCategoryResult::Equal;111    return ComparisonCategoryResult::Unordered;112  }113};114 115inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, MemberPointer FP) {116  FP.print(OS);117  return OS;118}119 120} // namespace interp121} // namespace clang122 123#endif124