xref: /llvm-project/clang/lib/AST/ByteCode/FunctionPointer.h (revision db94852b9b4ca1008ef2889175fe3af51f26a5b0)
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 
15 namespace clang {
16 class ASTContext;
17 class APValue;
18 namespace interp {
19 
20 class FunctionPointer final {
21 private:
22   const Function *Func;
23   uint64_t Offset;
24   bool Valid;
25 
26 public:
27   FunctionPointer() = default;
28   FunctionPointer(const Function *Func, uint64_t Offset = 0)
29       : Func(Func), Offset(Offset), Valid(true) {}
30 
31   FunctionPointer(uintptr_t IntVal, const Descriptor *Desc = nullptr)
32       : Func(reinterpret_cast<const Function *>(IntVal)), Offset(0),
33         Valid(false) {}
34 
35   const Function *getFunction() const { return Func; }
36   uint64_t getOffset() const { return Offset; }
37   bool isZero() const { return !Func; }
38   bool isValid() const { return Valid; }
39   bool isWeak() const {
40     if (!Func || !Valid || !Func->getDecl())
41       return false;
42 
43     return Func->getDecl()->isWeak();
44   }
45 
46   APValue toAPValue(const ASTContext &) const;
47   void print(llvm::raw_ostream &OS) const;
48 
49   std::string toDiagnosticString(const ASTContext &Ctx) const {
50     if (!Func)
51       return "nullptr";
52 
53     return toAPValue(Ctx).getAsString(Ctx, Func->getDecl()->getType());
54   }
55 
56   uint64_t getIntegerRepresentation() const {
57     return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Func));
58   }
59 
60   ComparisonCategoryResult compare(const FunctionPointer &RHS) const {
61     if (Func == RHS.Func && Offset == RHS.Offset)
62       return ComparisonCategoryResult::Equal;
63     return ComparisonCategoryResult::Unordered;
64   }
65 };
66 
67 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
68                                      FunctionPointer FP) {
69   FP.print(OS);
70   return OS;
71 }
72 
73 } // namespace interp
74 } // namespace clang
75 
76 #endif
77