diff options
Diffstat (limited to 'clang/lib/AST/Interp/EvalEmitter.cpp')
-rw-r--r-- | clang/lib/AST/Interp/EvalEmitter.cpp | 29 |
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; } |