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