18#include "llvm/ADT/StringExtras.h"
19#include "llvm/Support/ErrorHandling.h"
20#include "llvm/Support/raw_os_ostream.h"
30 using DtorFunc = void (*)(
void *);
32 static unsigned char *CreatePayload(
void *DtorF,
size_t AllocSize,
33 size_t ElementsSize) {
34 if (AllocSize <
sizeof(Canary))
35 AllocSize =
sizeof(Canary);
37 new unsigned char[ValueStorage::getPayloadOffset() + AllocSize];
38 ValueStorage *VS =
new (Buf) ValueStorage(DtorF, AllocSize, ElementsSize);
39 std::memcpy(VS->getPayload(), Canary,
sizeof(Canary));
40 return VS->getPayload();
43 unsigned char *getPayload() {
return Storage; }
44 const unsigned char *getPayload()
const {
return Storage; }
46 static unsigned getPayloadOffset() {
47 static ValueStorage Dummy(
nullptr, 0, 0);
48 return Dummy.getPayload() -
reinterpret_cast<unsigned char *
>(&Dummy);
51 static ValueStorage *getFromPayload(
void *Payload) {
52 ValueStorage *R =
reinterpret_cast<ValueStorage *
>(
53 (
unsigned char *)Payload - getPayloadOffset());
57 void Retain() { ++RefCnt; }
60 assert(RefCnt > 0 &&
"Can't release if reference count is already zero");
63 if (Dtor && IsAlive()) {
64 assert(Elements &&
"We at least should have 1 element in Value");
65 size_t Stride = AllocSize / Elements;
66 for (
size_t Idx = 0; Idx < Elements; ++Idx)
67 (*Dtor)(getPayload() + Idx * Stride);
69 delete[]
reinterpret_cast<unsigned char *
>(
this);
76 bool IsAlive()
const {
77 return std::memcmp(getPayload(), Canary,
sizeof(Canary)) != 0;
81 ValueStorage(
void *DtorF,
size_t AllocSize,
size_t ElementsNum)
82 : RefCnt(1), Dtor(reinterpret_cast<DtorFunc>(DtorF)),
83 AllocSize(AllocSize), Elements(ElementsNum) {}
85 mutable unsigned RefCnt;
86 DtorFunc Dtor =
nullptr;
93 static constexpr unsigned char Canary[8] = {0x4c, 0x37, 0xad, 0x8f,
94 0x2d, 0x23, 0x95, 0x91};
105 QT = ET->getDecl()->getIntegerType();
108 if (!BT || BT->isNullPtrType())
113 assert(
false &&
"Type not supported");
115#define X(type, name) \
116 case BuiltinType::name: \
117 return Value::K_##name;
134 void *DtorF =
nullptr;
135 size_t ElementsSize = 1;
138 if (
const auto *ArrTy =
139 llvm::dyn_cast<ConstantArrayType>(DtorTy.
getTypePtr())) {
140 DtorTy = ArrTy->getElementType();
141 llvm::APInt ArrSize(
sizeof(
size_t) * 8, 1);
143 ArrSize *= ArrTy->getSize();
144 ArrTy = llvm::dyn_cast<ConstantArrayType>(
145 ArrTy->getElementType().getTypePtr());
147 ElementsSize =
static_cast<size_t>(ArrSize.getZExtValue());
151 llvm::dyn_cast<CXXRecordDecl>(RT->getDecl())) {
154 DtorF =
reinterpret_cast<void *
>(Addr->getValue());
156 llvm::logAllUnhandledErrors(Addr.takeError(), llvm::errs());
162 unsigned char *Payload =
163 ValueStorage::CreatePayload(DtorF, AllocSize, ElementsSize);
170 : Interp(RHS.Interp), OpaqueType(RHS.OpaqueType),
Data(RHS.
Data),
171 ValueKind(RHS.ValueKind), IsManuallyAlloc(RHS.IsManuallyAlloc) {
173 ValueStorage::getFromPayload(
getPtr())->Retain();
177 Interp = std::exchange(RHS.Interp,
nullptr);
178 OpaqueType = std::exchange(RHS.OpaqueType,
nullptr);
180 ValueKind = std::exchange(RHS.ValueKind, K_Unspecified);
181 IsManuallyAlloc = std::exchange(RHS.IsManuallyAlloc,
false);
184 ValueStorage::getFromPayload(getPtr())->Release();
189 ValueStorage::getFromPayload(
getPtr())->Release();
198 ValueStorage::getFromPayload(
getPtr())->Retain();
206 ValueStorage::getFromPayload(getPtr())->Release();
208 Interp = std::exchange(RHS.Interp,
nullptr);
209 OpaqueType = std::exchange(RHS.OpaqueType,
nullptr);
210 ValueKind = std::exchange(RHS.ValueKind, K_Unspecified);
211 IsManuallyAlloc = std::exchange(RHS.IsManuallyAlloc,
false);
220 ValueStorage::getFromPayload(
getPtr())->Release();
239 assert(
Interp !=
nullptr &&
240 "Can't get interpreter from a default constructed value");
245 assert(
Interp !=
nullptr &&
246 "Can't get interpreter from a default constructed value");
259 Out <<
"Not implement yet.\n";
262 Out <<
"Not implement yet.\n";
265 assert(
OpaqueType !=
nullptr &&
"Can't print default Value");
266 Out <<
"Not implement yet.\n";
Defines the clang::ASTContext interface.
#define REPL_BUILTIN_TYPES
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
This class is used for builtin types like 'int'.
Represents a C++ struct/union/class.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Provides top-level interfaces for incremental compilation and execution.
llvm::Expected< llvm::orc::ExecutorAddr > CompileDtorCall(CXXRecordDecl *CXXRD)
const ASTContext & getASTContext() const
A (possibly-)qualified type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
static QualType getFromOpaquePtr(const void *Ptr)
QualType getCanonicalType() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
bool isConstantArrayType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isMemberPointerType() const
bool isObjectType() const
Determine whether this type is an object type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
void print(llvm::raw_ostream &Out) const
ASTContext & getASTContext()
Interpreter & getInterpreter()
void printType(llvm::raw_ostream &Out) const
Value & operator=(const Value &RHS)
void printData(llvm::raw_ostream &Out) const
The JSON file list parser is used to communicate input to InstallAPI.
static Value::Kind ConvertQualTypeToKind(const ASTContext &Ctx, QualType QT)