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