https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/186757

It's been mostly living inside `Pointer` for a long time now, so remove the 
leftovers.

>From 248f34ed2511addb595cee3926e97e618bf06f6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Mon, 16 Mar 2026 10:23:40 +0100
Subject: [PATCH] [clang][bytecode] Remove FunctionPointer class

It's been mostly living inside `Pointer` for a long time now, so remove
the leftovers.
---
 clang/lib/AST/ByteCode/Disasm.cpp          |  1 -
 clang/lib/AST/ByteCode/FunctionPointer.cpp | 36 --------------
 clang/lib/AST/ByteCode/FunctionPointer.h   | 55 ----------------------
 clang/lib/AST/ByteCode/Interp.cpp          |  3 +-
 clang/lib/AST/ByteCode/Interp.h            |  2 +-
 clang/lib/AST/ByteCode/MemberPointer.cpp   |  6 ---
 clang/lib/AST/ByteCode/MemberPointer.h     |  2 -
 clang/lib/AST/ByteCode/Pointer.cpp         | 13 ++---
 clang/lib/AST/ByteCode/Pointer.h           | 28 +++++++----
 clang/lib/AST/ByteCode/PrimType.h          |  1 -
 clang/lib/AST/CMakeLists.txt               |  1 -
 clang/unittests/AST/ByteCode/toAPValue.cpp |  3 +-
 12 files changed, 26 insertions(+), 125 deletions(-)
 delete mode 100644 clang/lib/AST/ByteCode/FunctionPointer.cpp
 delete mode 100644 clang/lib/AST/ByteCode/FunctionPointer.h

diff --git a/clang/lib/AST/ByteCode/Disasm.cpp 
b/clang/lib/AST/ByteCode/Disasm.cpp
index 35937e3483e38..5fd15f8a2f0d1 100644
--- a/clang/lib/AST/ByteCode/Disasm.cpp
+++ b/clang/lib/AST/ByteCode/Disasm.cpp
@@ -16,7 +16,6 @@
 #include "FixedPoint.h"
 #include "Floating.h"
 #include "Function.h"
-#include "FunctionPointer.h"
 #include "Integral.h"
 #include "IntegralAP.h"
 #include "InterpFrame.h"
diff --git a/clang/lib/AST/ByteCode/FunctionPointer.cpp 
b/clang/lib/AST/ByteCode/FunctionPointer.cpp
deleted file mode 100644
index 2488626697284..0000000000000
--- a/clang/lib/AST/ByteCode/FunctionPointer.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-//===----------------------- FunctionPointer.cpp ----------------*- C++ 
-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "FunctionPointer.h"
-
-namespace clang {
-namespace interp {
-
-APValue FunctionPointer::toAPValue(const ASTContext &) const {
-  if (!Func)
-    return APValue(static_cast<Expr *>(nullptr), CharUnits::Zero(), {},
-                   /*OnePastTheEnd=*/false, /*IsNull=*/true);
-
-  if (Func->getDecl())
-    return APValue(Func->getDecl(), CharUnits::fromQuantity(0), {},
-                   /*OnePastTheEnd=*/false, /*IsNull=*/false);
-  return APValue(Func->getExpr(), CharUnits::fromQuantity(0), {},
-                 /*OnePastTheEnd=*/false, /*IsNull=*/false);
-}
-
-void FunctionPointer::print(llvm::raw_ostream &OS) const {
-  OS << "FnPtr(";
-  if (Func)
-    OS << Func->getName();
-  else
-    OS << "nullptr";
-  OS << ")";
-}
-
-} // namespace interp
-} // namespace clang
diff --git a/clang/lib/AST/ByteCode/FunctionPointer.h 
b/clang/lib/AST/ByteCode/FunctionPointer.h
deleted file mode 100644
index 9e8ea2f1af5f8..0000000000000
--- a/clang/lib/AST/ByteCode/FunctionPointer.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===--- FunctionPointer.h - Types for the constexpr VM ---------*- C++ 
-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_INTERP_FUNCTION_POINTER_H
-#define LLVM_CLANG_AST_INTERP_FUNCTION_POINTER_H
-
-#include "Function.h"
-#include "Primitives.h"
-
-namespace clang {
-class ASTContext;
-class APValue;
-namespace interp {
-
-class FunctionPointer final {
-private:
-  const Function *Func;
-
-public:
-  FunctionPointer() = default;
-  FunctionPointer(const Function *Func) : Func(Func) {}
-
-  const Function *getFunction() const { return Func; }
-  bool isZero() const { return !Func; }
-  bool isWeak() const {
-    if (!Func || !Func->getDecl())
-      return false;
-
-    return Func->getDecl()->isWeak();
-  }
-
-  APValue toAPValue(const ASTContext &) const;
-  void print(llvm::raw_ostream &OS) const;
-
-  std::string toDiagnosticString(const ASTContext &Ctx) const {
-    if (!Func)
-      return "nullptr";
-
-    return toAPValue(Ctx).getAsString(Ctx, Func->getDecl()->getType());
-  }
-
-  uint64_t getIntegerRepresentation() const {
-    return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Func));
-  }
-};
-
-} // namespace interp
-} // namespace clang
-
-#endif
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index ebc7220aa5671..3b92c1858126a 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1903,8 +1903,7 @@ bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t 
ArgSize,
   if (!Ptr.isFunctionPointer())
     return Invalid(S, OpPC);
 
-  const FunctionPointer &FuncPtr = Ptr.asFunctionPointer();
-  const Function *F = FuncPtr.getFunction();
+  const Function *F = Ptr.asFunctionPointer().Func;
   assert(F);
   // Don't allow calling block pointers.
   if (!F->getDecl())
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 7b8a7c80c5423..01ea334f65cd3 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2310,7 +2310,7 @@ std::optional<Pointer> OffsetHelper(InterpState &S, 
CodePtr OpPC,
     if (N > 1)
       S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_array_index)
           << N << /*non-array*/ true << 0;
-    return Pointer(Ptr.asFunctionPointer().getFunction(), N);
+    return Pointer(Ptr.asFunctionPointer().Func, N);
   } else if (!Ptr.isBlockPointer()) {
     return std::nullopt;
   }
diff --git a/clang/lib/AST/ByteCode/MemberPointer.cpp 
b/clang/lib/AST/ByteCode/MemberPointer.cpp
index c821b0fc689fd..f0c1fe5930261 100644
--- a/clang/lib/AST/ByteCode/MemberPointer.cpp
+++ b/clang/lib/AST/ByteCode/MemberPointer.cpp
@@ -8,7 +8,6 @@
 
 #include "MemberPointer.h"
 #include "Context.h"
-#include "FunctionPointer.h"
 #include "Program.h"
 #include "Record.h"
 
@@ -76,11 +75,6 @@ std::optional<Pointer> MemberPointer::toPointer(const 
Context &Ctx) const {
   return Pointer(const_cast<Block *>(Base.block()), Offset, Offset);
 }
 
-FunctionPointer MemberPointer::toFunctionPointer(const Context &Ctx) const {
-  return FunctionPointer(
-      Ctx.getProgram().getFunction(cast<FunctionDecl>(getDecl())));
-}
-
 APValue MemberPointer::toAPValue(const ASTContext &ASTCtx) const {
   if (isZero())
     return APValue(static_cast<ValueDecl *>(nullptr), 
/*IsDerivedMember=*/false,
diff --git a/clang/lib/AST/ByteCode/MemberPointer.h 
b/clang/lib/AST/ByteCode/MemberPointer.h
index a9b95471038e0..7bef2accd39e5 100644
--- a/clang/lib/AST/ByteCode/MemberPointer.h
+++ b/clang/lib/AST/ByteCode/MemberPointer.h
@@ -19,7 +19,6 @@ class CXXRecordDecl;
 namespace interp {
 
 class Context;
-class FunctionPointer;
 
 class MemberPointer final {
 private:
@@ -100,7 +99,6 @@ class MemberPointer final {
   ComparisonCategoryResult compare(const MemberPointer &RHS) const;
 
   std::optional<Pointer> toPointer(const Context &Ctx) const;
-  FunctionPointer toFunctionPointer(const Context &Ctx) const;
 
   bool isBaseCastPossible() const {
     if (PtrOffset < 0)
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp 
b/clang/lib/AST/ByteCode/Pointer.cpp
index 740a72ca241a8..689407e60c542 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -182,11 +182,10 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) 
const {
                    /*IsOnePastEnd=*/false, /*IsNullPtr=*/false);
   if (isFunctionPointer()) {
     const FunctionPointer &FP = asFunctionPointer();
-    if (const FunctionDecl *FD = FP.getFunction()->getDecl())
+    if (const FunctionDecl *FD = FP.Func->getDecl())
       return APValue(FD, CharUnits::fromQuantity(Offset), {},
                      /*OnePastTheEnd=*/false, /*IsNull=*/false);
-    return APValue(FP.getFunction()->getExpr(), 
CharUnits::fromQuantity(Offset),
-                   {},
+    return APValue(FP.Func->getExpr(), CharUnits::fromQuantity(Offset), {},
                    /*OnePastTheEnd=*/false, /*IsNull=*/false);
   }
 
@@ -352,8 +351,7 @@ void Pointer::print(llvm::raw_ostream &OS) const {
     OS << "}";
     break;
   case Storage::Fn:
-    OS << "(Fn) { " << asFunctionPointer().getFunction() << " + " << Offset
-       << " }";
+    OS << "(Fn) { " << Fn.Func << " + " << Offset << " }";
     break;
   case Storage::Typeid:
     OS << "(Typeid) { " << (const void *)asTypeidPointer().TypePtr << ", "
@@ -376,7 +374,7 @@ size_t Pointer::computeOffsetForComparison(const ASTContext 
&ASTCtx) const {
     // See below.
     break;
   case Storage::Fn:
-    return Fn.getIntegerRepresentation() + Offset;
+    return getIntegerRepresentation();
   case Storage::Typeid:
     return reinterpret_cast<uintptr_t>(asTypeidPointer().TypePtr) + Offset;
   }
@@ -438,9 +436,6 @@ std::string Pointer::toDiagnosticString(const ASTContext 
&Ctx) const {
   if (isIntegralPointer())
     return (Twine("&(") + Twine(asIntPointer().Value + Offset) + ")").str();
 
-  if (isFunctionPointer())
-    return asFunctionPointer().toDiagnosticString(Ctx);
-
   return toAPValue(Ctx).getAsString(Ctx, getType());
 }
 
diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index 010e917de81b2..ea9c7d4cb04db 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -14,7 +14,7 @@
 #define LLVM_CLANG_AST_INTERP_POINTER_H
 
 #include "Descriptor.h"
-#include "FunctionPointer.h"
+#include "Function.h"
 #include "InitMap.h"
 #include "InterpBlock.h"
 #include "clang/AST/ComparisonCategories.h"
@@ -53,6 +53,10 @@ struct IntPointer {
   IntPointer baseCast(const ASTContext &ASTCtx, unsigned BaseOffset) const;
 };
 
+struct FunctionPointer {
+  const Function *Func;
+};
+
 struct TypeidPointer {
   const Type *TypePtr;
   const Type *TypeInfoType;
@@ -106,7 +110,7 @@ class Pointer {
   Pointer(uint64_t Address, const Descriptor *Desc, uint64_t Offset = 0)
       : Offset(Offset), StorageKind(Storage::Int), Int{Desc, Address} {}
   Pointer(const Function *F, uint64_t Offset = 0)
-      : Offset(Offset), StorageKind(Storage::Fn), Fn(F) {}
+      : Offset(Offset), StorageKind(Storage::Fn), Fn{F} {}
   Pointer(const Type *TypePtr, const Type *TypeInfoType, uint64_t Offset = 0)
       : Offset(Offset), StorageKind(Storage::Typeid) {
     Typeid.TypePtr = TypePtr;
@@ -127,7 +131,7 @@ class Pointer {
              P.Offset == Offset;
 
     if (isFunctionPointer())
-      return P.Fn.getFunction() == Fn.getFunction() && P.Offset == Offset;
+      return P.Fn.Func == Fn.Func && P.Offset == Offset;
 
     assert(isBlockPointer());
     return P.BS.Pointee == BS.Pointee && P.BS.Base == BS.Base &&
@@ -146,7 +150,7 @@ class Pointer {
     if (isIntegralPointer())
       return Int.Value + (Offset * elemSize());
     if (isFunctionPointer())
-      return Fn.getIntegerRepresentation() + Offset;
+      return reinterpret_cast<uint64_t>(Fn.Func) + Offset;
     return reinterpret_cast<uint64_t>(BS.Pointee) + Offset;
   }
 
@@ -159,7 +163,7 @@ class Pointer {
     if (isIntegralPointer())
       return Pointer(Int.Value, Int.Desc, Idx);
     if (isFunctionPointer())
-      return Pointer(Fn.getFunction(), Idx);
+      return Pointer(Fn.Func, Idx);
 
     if (BS.Base == RootPtrMark)
       return Pointer(BS.Pointee, RootPtrMark, getDeclDesc()->getSize());
@@ -264,7 +268,7 @@ class Pointer {
     case Storage::Block:
       return BS.Pointee == nullptr;
     case Storage::Fn:
-      return Fn.isZero();
+      return !Fn.Func;
     case Storage::Typeid:
       return false;
     }
@@ -302,7 +306,7 @@ class Pointer {
     if (isBlockPointer())
       return getDeclDesc()->getSource();
     if (isFunctionPointer()) {
-      const Function *F = Fn.getFunction();
+      const Function *F = Fn.Func;
       return F ? F->getDecl() : DeclTy();
     }
     assert(isIntegralPointer());
@@ -343,7 +347,7 @@ class Pointer {
     if (isTypeidPointer())
       return QualType(Typeid.TypeInfoType, 0);
     if (isFunctionPointer())
-      return Fn.getFunction()->getDecl()->getType();
+      return Fn.Func->getDecl()->getType();
 
     if (inPrimitiveArray() && Offset != BS.Base) {
       // Unfortunately, complex and vector types are not array types in clang,
@@ -531,8 +535,12 @@ class Pointer {
   }
 
   bool isWeak() const {
-    if (isFunctionPointer())
-      return Fn.isWeak();
+    if (isFunctionPointer()) {
+      if (!Fn.Func || !Fn.Func->getDecl())
+        return false;
+
+      return Fn.Func->getDecl()->isWeak();
+    }
     if (!isBlockPointer())
       return false;
 
diff --git a/clang/lib/AST/ByteCode/PrimType.h 
b/clang/lib/AST/ByteCode/PrimType.h
index e29d6650a1495..2fa553b7b4a47 100644
--- a/clang/lib/AST/ByteCode/PrimType.h
+++ b/clang/lib/AST/ByteCode/PrimType.h
@@ -24,7 +24,6 @@ namespace interp {
 class Pointer;
 class Boolean;
 class Floating;
-class FunctionPointer;
 class MemberPointer;
 class FixedPoint;
 template <bool Signed> class IntegralAP;
diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 0e0a0c94d2ac5..a2eac60844ef8 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -76,7 +76,6 @@ add_clang_library(clangAST
   ByteCode/Disasm.cpp
   ByteCode/EvalEmitter.cpp
   ByteCode/Function.cpp
-  ByteCode/FunctionPointer.cpp
   ByteCode/InterpBuiltin.cpp
   ByteCode/InterpBuiltinBitCast.cpp
   ByteCode/Floating.cpp
diff --git a/clang/unittests/AST/ByteCode/toAPValue.cpp 
b/clang/unittests/AST/ByteCode/toAPValue.cpp
index 3571dcc41ad27..702a07a638915 100644
--- a/clang/unittests/AST/ByteCode/toAPValue.cpp
+++ b/clang/unittests/AST/ByteCode/toAPValue.cpp
@@ -151,7 +151,8 @@ TEST(ToAPValue, FunctionPointers) {
     const ValueDecl *D = getDecl("nullp");
     ASSERT_NE(D, nullptr);
     const Pointer &GP = getGlobalPtr("nullp");
-    const auto &P = GP.deref<FunctionPointer>();
+    const auto &P = GP.deref<Pointer>();
+    ASSERT_TRUE(P.isZero());
     APValue A = P.toAPValue(ASTCtx);
     ASSERT_TRUE(A.isLValue());
     ASSERT_TRUE(A.getLValueBase().isNull());

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to