xref: /llvm-project/clang/lib/AST/ByteCode/FunctionPointer.h (revision db94852b9b4ca1008ef2889175fe3af51f26a5b0)
1a07aba5dSTimm Baeder //===--- FunctionPointer.h - Types for the constexpr VM ---------*- C++ -*-===//
2a07aba5dSTimm Baeder //
3a07aba5dSTimm Baeder // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a07aba5dSTimm Baeder // See https://llvm.org/LICENSE.txt for license information.
5a07aba5dSTimm Baeder // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a07aba5dSTimm Baeder //
7a07aba5dSTimm Baeder //===----------------------------------------------------------------------===//
8a07aba5dSTimm Baeder 
9a07aba5dSTimm Baeder #ifndef LLVM_CLANG_AST_INTERP_FUNCTION_POINTER_H
10a07aba5dSTimm Baeder #define LLVM_CLANG_AST_INTERP_FUNCTION_POINTER_H
11a07aba5dSTimm Baeder 
12a07aba5dSTimm Baeder #include "Function.h"
13a07aba5dSTimm Baeder #include "Primitives.h"
14a07aba5dSTimm Baeder 
15a07aba5dSTimm Baeder namespace clang {
16a07aba5dSTimm Baeder class ASTContext;
17*db94852bSTimm Baeder class APValue;
18a07aba5dSTimm Baeder namespace interp {
19a07aba5dSTimm Baeder 
20a07aba5dSTimm Baeder class FunctionPointer final {
21a07aba5dSTimm Baeder private:
22a07aba5dSTimm Baeder   const Function *Func;
23*db94852bSTimm Baeder   uint64_t Offset;
24a07aba5dSTimm Baeder   bool Valid;
25a07aba5dSTimm Baeder 
26a07aba5dSTimm Baeder public:
27a07aba5dSTimm Baeder   FunctionPointer() = default;
28*db94852bSTimm Baeder   FunctionPointer(const Function *Func, uint64_t Offset = 0)
29*db94852bSTimm Baeder       : Func(Func), Offset(Offset), Valid(true) {}
30a07aba5dSTimm Baeder 
31a07aba5dSTimm Baeder   FunctionPointer(uintptr_t IntVal, const Descriptor *Desc = nullptr)
32*db94852bSTimm Baeder       : Func(reinterpret_cast<const Function *>(IntVal)), Offset(0),
33*db94852bSTimm Baeder         Valid(false) {}
34a07aba5dSTimm Baeder 
35a07aba5dSTimm Baeder   const Function *getFunction() const { return Func; }
36*db94852bSTimm Baeder   uint64_t getOffset() const { return Offset; }
37a07aba5dSTimm Baeder   bool isZero() const { return !Func; }
38a07aba5dSTimm Baeder   bool isValid() const { return Valid; }
39a07aba5dSTimm Baeder   bool isWeak() const {
40ca148b21STimm Baeder     if (!Func || !Valid || !Func->getDecl())
41a07aba5dSTimm Baeder       return false;
42a07aba5dSTimm Baeder 
43a07aba5dSTimm Baeder     return Func->getDecl()->isWeak();
44a07aba5dSTimm Baeder   }
45a07aba5dSTimm Baeder 
46*db94852bSTimm Baeder   APValue toAPValue(const ASTContext &) const;
47*db94852bSTimm Baeder   void print(llvm::raw_ostream &OS) const;
48a07aba5dSTimm Baeder 
49a07aba5dSTimm Baeder   std::string toDiagnosticString(const ASTContext &Ctx) const {
50a07aba5dSTimm Baeder     if (!Func)
51a07aba5dSTimm Baeder       return "nullptr";
52a07aba5dSTimm Baeder 
53a07aba5dSTimm Baeder     return toAPValue(Ctx).getAsString(Ctx, Func->getDecl()->getType());
54a07aba5dSTimm Baeder   }
55a07aba5dSTimm Baeder 
56a07aba5dSTimm Baeder   uint64_t getIntegerRepresentation() const {
57a07aba5dSTimm Baeder     return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Func));
58a07aba5dSTimm Baeder   }
59a07aba5dSTimm Baeder 
60a07aba5dSTimm Baeder   ComparisonCategoryResult compare(const FunctionPointer &RHS) const {
61*db94852bSTimm Baeder     if (Func == RHS.Func && Offset == RHS.Offset)
62a07aba5dSTimm Baeder       return ComparisonCategoryResult::Equal;
63a07aba5dSTimm Baeder     return ComparisonCategoryResult::Unordered;
64a07aba5dSTimm Baeder   }
65a07aba5dSTimm Baeder };
66a07aba5dSTimm Baeder 
67a07aba5dSTimm Baeder inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
68a07aba5dSTimm Baeder                                      FunctionPointer FP) {
69a07aba5dSTimm Baeder   FP.print(OS);
70a07aba5dSTimm Baeder   return OS;
71a07aba5dSTimm Baeder }
72a07aba5dSTimm Baeder 
73a07aba5dSTimm Baeder } // namespace interp
74a07aba5dSTimm Baeder } // namespace clang
75a07aba5dSTimm Baeder 
76a07aba5dSTimm Baeder #endif
77