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 
24 public:
25   FunctionPointer() : Func(nullptr) {}
26   FunctionPointer(const Function *Func) : Func(Func) { assert(Func); }
27 
28   const Function *getFunction() const { return Func; }
29 
30   APValue toAPValue() const {
31     if (!Func)
32       return APValue(static_cast<Expr *>(nullptr), CharUnits::Zero(), {},
33                      /*OnePastTheEnd=*/false, /*IsNull=*/true);
34 
35     return APValue(Func->getDecl(), CharUnits::Zero(), {},
36                    /*OnePastTheEnd=*/false, /*IsNull=*/false);
37   }
38 
39   void print(llvm::raw_ostream &OS) const {
40     OS << "FnPtr(";
41     if (Func)
42       OS << Func->getName();
43     else
44       OS << "nullptr";
45     OS << ")";
46   }
47 
48   std::string toDiagnosticString(const ASTContext &Ctx) const {
49     if (!Func)
50       return "nullptr";
51 
52     return toAPValue().getAsString(Ctx, Func->getDecl()->getType());
53   }
54 
55   ComparisonCategoryResult compare(const FunctionPointer &RHS) const {
56     if (Func == RHS.Func)
57       return ComparisonCategoryResult::Equal;
58     return ComparisonCategoryResult::Unordered;
59   }
60 };
61 
62 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
63                                      FunctionPointer FP) {
64   FP.print(OS);
65   return OS;
66 }
67 
68 } // namespace interp
69 } // namespace clang
70 
71 #endif
72