1a07aba5dSTimm Baeder //===--- FunctionPointer.h - Types for the constexpr VM ---------*- C++ -*-===// 2a07aba5dSTimm Baeder // 3a07aba5dSTimm Baeder // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a07aba5dSTimm Baeder // See https://llvm.org/LICENSE.txt for license information. 5a07aba5dSTimm Baeder // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a07aba5dSTimm Baeder // 7a07aba5dSTimm Baeder //===----------------------------------------------------------------------===// 8a07aba5dSTimm Baeder 9a07aba5dSTimm Baeder #ifndef LLVM_CLANG_AST_INTERP_FUNCTION_POINTER_H 10a07aba5dSTimm Baeder #define LLVM_CLANG_AST_INTERP_FUNCTION_POINTER_H 11a07aba5dSTimm Baeder 12a07aba5dSTimm Baeder #include "Function.h" 13a07aba5dSTimm Baeder #include "Primitives.h" 14a07aba5dSTimm Baeder 15a07aba5dSTimm Baeder namespace clang { 16a07aba5dSTimm Baeder class ASTContext; 17*db94852bSTimm Baeder class APValue; 18a07aba5dSTimm Baeder namespace interp { 19a07aba5dSTimm Baeder 20a07aba5dSTimm Baeder class FunctionPointer final { 21a07aba5dSTimm Baeder private: 22a07aba5dSTimm Baeder const Function *Func; 23*db94852bSTimm Baeder uint64_t Offset; 24a07aba5dSTimm Baeder bool Valid; 25a07aba5dSTimm Baeder 26a07aba5dSTimm Baeder public: 27a07aba5dSTimm Baeder FunctionPointer() = default; 28*db94852bSTimm Baeder FunctionPointer(const Function *Func, uint64_t Offset = 0) 29*db94852bSTimm Baeder : Func(Func), Offset(Offset), Valid(true) {} 30a07aba5dSTimm Baeder 31a07aba5dSTimm Baeder FunctionPointer(uintptr_t IntVal, const Descriptor *Desc = nullptr) 32*db94852bSTimm Baeder : Func(reinterpret_cast<const Function *>(IntVal)), Offset(0), 33*db94852bSTimm Baeder Valid(false) {} 34a07aba5dSTimm Baeder 35a07aba5dSTimm Baeder const Function *getFunction() const { return Func; } 36*db94852bSTimm Baeder uint64_t getOffset() const { return Offset; } 37a07aba5dSTimm Baeder bool isZero() const { return !Func; } 38a07aba5dSTimm Baeder bool isValid() const { return Valid; } 39a07aba5dSTimm Baeder bool isWeak() const { 40ca148b21STimm Baeder if (!Func || !Valid || !Func->getDecl()) 41a07aba5dSTimm Baeder return false; 42a07aba5dSTimm Baeder 43a07aba5dSTimm Baeder return Func->getDecl()->isWeak(); 44a07aba5dSTimm Baeder } 45a07aba5dSTimm Baeder 46*db94852bSTimm Baeder APValue toAPValue(const ASTContext &) const; 47*db94852bSTimm Baeder void print(llvm::raw_ostream &OS) const; 48a07aba5dSTimm Baeder 49a07aba5dSTimm Baeder std::string toDiagnosticString(const ASTContext &Ctx) const { 50a07aba5dSTimm Baeder if (!Func) 51a07aba5dSTimm Baeder return "nullptr"; 52a07aba5dSTimm Baeder 53a07aba5dSTimm Baeder return toAPValue(Ctx).getAsString(Ctx, Func->getDecl()->getType()); 54a07aba5dSTimm Baeder } 55a07aba5dSTimm Baeder 56a07aba5dSTimm Baeder uint64_t getIntegerRepresentation() const { 57a07aba5dSTimm Baeder return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Func)); 58a07aba5dSTimm Baeder } 59a07aba5dSTimm Baeder 60a07aba5dSTimm Baeder ComparisonCategoryResult compare(const FunctionPointer &RHS) const { 61*db94852bSTimm Baeder if (Func == RHS.Func && Offset == RHS.Offset) 62a07aba5dSTimm Baeder return ComparisonCategoryResult::Equal; 63a07aba5dSTimm Baeder return ComparisonCategoryResult::Unordered; 64a07aba5dSTimm Baeder } 65a07aba5dSTimm Baeder }; 66a07aba5dSTimm Baeder 67a07aba5dSTimm Baeder inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 68a07aba5dSTimm Baeder FunctionPointer FP) { 69a07aba5dSTimm Baeder FP.print(OS); 70a07aba5dSTimm Baeder return OS; 71a07aba5dSTimm Baeder } 72a07aba5dSTimm Baeder 73a07aba5dSTimm Baeder } // namespace interp 74a07aba5dSTimm Baeder } // namespace clang 75a07aba5dSTimm Baeder 76a07aba5dSTimm Baeder #endif 77