[clang][bytecode] Remove FunctionPointer class (#186757)
It's been mostly living inside `Pointer` for a long time now, so remove the leftovers.
This commit is contained in:
parent
5709638262
commit
e4a2d9cd8a
@ -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"
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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())
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -19,7 +19,6 @@ class CXXRecordDecl;
|
||||
namespace interp {
|
||||
|
||||
class Context;
|
||||
class FunctionPointer;
|
||||
|
||||
class MemberPointer final {
|
||||
private:
|
||||
@ -100,7 +99,6 @@ public:
|
||||
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)
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
|
||||
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@ -24,7 +24,6 @@ namespace interp {
|
||||
class Pointer;
|
||||
class Boolean;
|
||||
class Floating;
|
||||
class FunctionPointer;
|
||||
class MemberPointer;
|
||||
class FixedPoint;
|
||||
template <bool Signed> class IntegralAP;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user