1 //===--- FunctionPointer.h - Types for the constexpr VM ---------*- 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 #ifndef LLVM_CLANG_AST_INTERP_FUNCTION_POINTER_H 10 #define LLVM_CLANG_AST_INTERP_FUNCTION_POINTER_H 11 12 #include "Function.h" 13 #include "Primitives.h" 14 #include "clang/AST/APValue.h" 15 16 namespace clang { 17 class ASTContext; 18 namespace interp { 19 20 class FunctionPointer final { 21 private: 22 const Function *Func; 23 bool Valid; 24 25 public: 26 FunctionPointer(const Function *Func) : Func(Func), Valid(true) { 27 assert(Func); 28 } 29 30 FunctionPointer(uintptr_t IntVal = 0, const Descriptor *Desc = nullptr) 31 : Func(reinterpret_cast<const Function *>(IntVal)), Valid(false) {} 32 33 const Function *getFunction() const { return Func; } 34 bool isZero() const { return !Func; } 35 bool isValid() const { return Valid; } 36 bool isWeak() const { 37 if (!Func || !Valid) 38 return false; 39 40 return Func->getDecl()->isWeak(); 41 } 42 43 APValue toAPValue(const ASTContext &) const { 44 if (!Func) 45 return APValue(static_cast<Expr *>(nullptr), CharUnits::Zero(), {}, 46 /*OnePastTheEnd=*/false, /*IsNull=*/true); 47 48 if (!Valid) 49 return APValue(static_cast<Expr *>(nullptr), 50 CharUnits::fromQuantity(getIntegerRepresentation()), {}, 51 /*OnePastTheEnd=*/false, /*IsNull=*/false); 52 53 return APValue(Func->getDecl(), CharUnits::Zero(), {}, 54 /*OnePastTheEnd=*/false, /*IsNull=*/false); 55 } 56 57 void print(llvm::raw_ostream &OS) const { 58 OS << "FnPtr("; 59 if (Func && Valid) 60 OS << Func->getName(); 61 else if (Func) 62 OS << reinterpret_cast<uintptr_t>(Func); 63 else 64 OS << "nullptr"; 65 OS << ")"; 66 } 67 68 std::string toDiagnosticString(const ASTContext &Ctx) const { 69 if (!Func) 70 return "nullptr"; 71 72 return toAPValue(Ctx).getAsString(Ctx, Func->getDecl()->getType()); 73 } 74 75 uint64_t getIntegerRepresentation() const { 76 return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Func)); 77 } 78 79 ComparisonCategoryResult compare(const FunctionPointer &RHS) const { 80 if (Func == RHS.Func) 81 return ComparisonCategoryResult::Equal; 82 return ComparisonCategoryResult::Unordered; 83 } 84 }; 85 86 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 87 FunctionPointer FP) { 88 FP.print(OS); 89 return OS; 90 } 91 92 } // namespace interp 93 } // namespace clang 94 95 #endif 96