aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/Interp/EvalEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/Interp/EvalEmitter.cpp')
-rw-r--r--clang/lib/AST/Interp/EvalEmitter.cpp29
1 files changed, 22 insertions, 7 deletions
diff --git a/clang/lib/AST/Interp/EvalEmitter.cpp b/clang/lib/AST/Interp/EvalEmitter.cpp
index 22e8695b9211..72fd3b45254b 100644
--- a/clang/lib/AST/Interp/EvalEmitter.cpp
+++ b/clang/lib/AST/Interp/EvalEmitter.cpp
@@ -23,7 +23,8 @@ EvalEmitter::EvalEmitter(Context &Ctx, Program &P, State &Parent,
InterpStack &Stk, APValue &Result)
: Ctx(Ctx), P(P), S(Parent, P, Stk, Ctx, this), Result(Result) {
// Create a dummy frame for the interpreter which does not have locals.
- S.Current = new InterpFrame(S, nullptr, nullptr, CodePtr(), Pointer());
+ S.Current =
+ new InterpFrame(S, /*Func=*/nullptr, /*Caller=*/nullptr, CodePtr());
}
llvm::Expected<bool> EvalEmitter::interpretExpr(const Expr *E) {
@@ -54,6 +55,16 @@ Scope::Local EvalEmitter::createLocal(Descriptor *D) {
auto *B = new (Memory.get()) Block(D, /*isStatic=*/false);
B->invokeCtor();
+ // Initialize local variable inline descriptor.
+ InlineDescriptor &Desc = *reinterpret_cast<InlineDescriptor *>(B->rawData());
+ Desc.Desc = D;
+ Desc.Offset = sizeof(InlineDescriptor);
+ Desc.IsActive = true;
+ Desc.IsBase = false;
+ Desc.IsFieldMutable = false;
+ Desc.IsConst = false;
+ Desc.IsInitialized = false;
+
// Register the local.
unsigned Off = Locals.size();
Locals.insert({Off, std::move(Memory)});
@@ -123,7 +134,7 @@ bool EvalEmitter::emitRetValue(const SourceInfo &Info) {
const Pointer &FP = Ptr.atField(F.Offset);
QualType FieldTy = F.Decl->getType();
if (FP.isActive()) {
- if (llvm::Optional<PrimType> T = Ctx.classify(FieldTy)) {
+ if (std::optional<PrimType> T = Ctx.classify(FieldTy)) {
TYPE_SWITCH(*T, Ok &= ReturnValue<T>(FP.deref<T>(), Value));
} else {
Ok &= Composite(FieldTy, FP, Value);
@@ -145,7 +156,7 @@ bool EvalEmitter::emitRetValue(const SourceInfo &Info) {
const Pointer &FP = Ptr.atField(FD->Offset);
APValue &Value = R.getStructField(I);
- if (llvm::Optional<PrimType> T = Ctx.classify(FieldTy)) {
+ if (std::optional<PrimType> T = Ctx.classify(FieldTy)) {
TYPE_SWITCH(*T, Ok &= ReturnValue<T>(FP.deref<T>(), Value));
} else {
Ok &= Composite(FieldTy, FP, Value);
@@ -177,7 +188,7 @@ bool EvalEmitter::emitRetValue(const SourceInfo &Info) {
for (unsigned I = 0; I < NumElems; ++I) {
APValue &Slot = R.getArrayInitializedElt(I);
const Pointer &EP = Ptr.atIndex(I);
- if (llvm::Optional<PrimType> T = Ctx.classify(ElemTy)) {
+ if (std::optional<PrimType> T = Ctx.classify(ElemTy)) {
TYPE_SWITCH(*T, Ok &= ReturnValue<T>(EP.deref<T>(), Slot));
} else {
Ok &= Composite(ElemTy, EP.narrow(), Slot);
@@ -199,7 +210,8 @@ bool EvalEmitter::emitGetPtrLocal(uint32_t I, const SourceInfo &Info) {
auto It = Locals.find(I);
assert(It != Locals.end() && "Missing local variable");
- S.Stk.push<Pointer>(reinterpret_cast<Block *>(It->second.get()));
+ Block *B = reinterpret_cast<Block *>(It->second.get());
+ S.Stk.push<Pointer>(B, sizeof(InlineDescriptor));
return true;
}
@@ -213,7 +225,7 @@ bool EvalEmitter::emitGetLocal(uint32_t I, const SourceInfo &Info) {
auto It = Locals.find(I);
assert(It != Locals.end() && "Missing local variable");
auto *B = reinterpret_cast<Block *>(It->second.get());
- S.Stk.push<T>(*reinterpret_cast<T *>(B + 1));
+ S.Stk.push<T>(*reinterpret_cast<T *>(B->data()));
return true;
}
@@ -227,7 +239,10 @@ bool EvalEmitter::emitSetLocal(uint32_t I, const SourceInfo &Info) {
auto It = Locals.find(I);
assert(It != Locals.end() && "Missing local variable");
auto *B = reinterpret_cast<Block *>(It->second.get());
- *reinterpret_cast<T *>(B + 1) = S.Stk.pop<T>();
+ *reinterpret_cast<T *>(B->data()) = S.Stk.pop<T>();
+ InlineDescriptor &Desc = *reinterpret_cast<InlineDescriptor *>(B->rawData());
+ Desc.IsInitialized = true;
+
return true;
}