Author: Timm Bäder Date: 2024-07-20T15:29:32+02:00 New Revision: 56a9f7ce611ba21f51043d91c965b59e116013f2
URL: https://github.com/llvm/llvm-project/commit/56a9f7ce611ba21f51043d91c965b59e116013f2 DIFF: https://github.com/llvm/llvm-project/commit/56a9f7ce611ba21f51043d91c965b59e116013f2.diff LOG: [clang][Interp] Pass ASTContext to toAPValue() Not yet needed, but we need to ASTContext in a later patch when we start computing proper values for the APValue offset. Added: Modified: clang/lib/AST/Interp/Boolean.h clang/lib/AST/Interp/Disasm.cpp clang/lib/AST/Interp/EvalEmitter.cpp clang/lib/AST/Interp/EvaluationResult.cpp clang/lib/AST/Interp/Floating.h clang/lib/AST/Interp/FunctionPointer.h clang/lib/AST/Interp/Integral.h clang/lib/AST/Interp/IntegralAP.h clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/MemberPointer.cpp clang/lib/AST/Interp/MemberPointer.h clang/lib/AST/Interp/Pointer.cpp clang/lib/AST/Interp/Pointer.h clang/unittests/AST/Interp/toAPValue.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/Boolean.h b/clang/lib/AST/Interp/Boolean.h index 1bfb26b1b669f..23f7286036764 100644 --- a/clang/lib/AST/Interp/Boolean.h +++ b/clang/lib/AST/Interp/Boolean.h @@ -56,7 +56,7 @@ class Boolean final { APSInt toAPSInt(unsigned NumBits) const { return APSInt(toAPSInt().zextOrTrunc(NumBits), true); } - APValue toAPValue() const { return APValue(toAPSInt()); } + APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); } Boolean toUnsigned() const { return *this; } diff --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp index c6c6275593007..867284ecf7f4b 100644 --- a/clang/lib/AST/Interp/Disasm.cpp +++ b/clang/lib/AST/Interp/Disasm.cpp @@ -366,9 +366,9 @@ LLVM_DUMP_METHOD void EvaluationResult::dump() const { OS << "LValue: "; if (const auto *P = std::get_if<Pointer>(&Value)) - P->toAPValue().printPretty(OS, ASTCtx, SourceType); + P->toAPValue(ASTCtx).printPretty(OS, ASTCtx, SourceType); else if (const auto *FP = std::get_if<FunctionPointer>(&Value)) // Nope - FP->toAPValue().printPretty(OS, ASTCtx, SourceType); + FP->toAPValue(ASTCtx).printPretty(OS, ASTCtx, SourceType); OS << "\n"; break; } diff --git a/clang/lib/AST/Interp/EvalEmitter.cpp b/clang/lib/AST/Interp/EvalEmitter.cpp index 221bbfdc542ff..08536536ac3c2 100644 --- a/clang/lib/AST/Interp/EvalEmitter.cpp +++ b/clang/lib/AST/Interp/EvalEmitter.cpp @@ -145,7 +145,7 @@ template <PrimType OpType> bool EvalEmitter::emitRet(const SourceInfo &Info) { return false; using T = typename PrimConv<OpType>::T; - EvalResult.setValue(S.Stk.pop<T>().toAPValue()); + EvalResult.setValue(S.Stk.pop<T>().toAPValue(Ctx.getASTContext())); return true; } @@ -181,7 +181,7 @@ template <> bool EvalEmitter::emitRet<PT_Ptr>(const SourceInfo &Info) { return false; } } else { - EvalResult.setValue(Ptr.toAPValue()); + EvalResult.setValue(Ptr.toAPValue(Ctx.getASTContext())); } return true; @@ -285,7 +285,8 @@ void EvalEmitter::updateGlobalTemporaries() { APValue *Cached = Temp->getOrCreateValue(true); if (std::optional<PrimType> T = Ctx.classify(E->getType())) { - TYPE_SWITCH(*T, { *Cached = Ptr.deref<T>().toAPValue(); }); + TYPE_SWITCH( + *T, { *Cached = Ptr.deref<T>().toAPValue(Ctx.getASTContext()); }); } else { if (std::optional<APValue> APV = Ptr.toRValue(Ctx, Temp->getTemporaryExpr()->getType())) diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp b/clang/lib/AST/Interp/EvaluationResult.cpp index 0bebfd4ad984e..1b255711c7b36 100644 --- a/clang/lib/AST/Interp/EvaluationResult.cpp +++ b/clang/lib/AST/Interp/EvaluationResult.cpp @@ -21,9 +21,9 @@ APValue EvaluationResult::toAPValue() const { case LValue: // Either a pointer or a function pointer. if (const auto *P = std::get_if<Pointer>(&Value)) - return P->toAPValue(); + return P->toAPValue(Ctx->getASTContext()); else if (const auto *FP = std::get_if<FunctionPointer>(&Value)) - return FP->toAPValue(); + return FP->toAPValue(Ctx->getASTContext()); else llvm_unreachable("Unhandled LValue type"); break; @@ -46,7 +46,7 @@ std::optional<APValue> EvaluationResult::toRValue() const { if (const auto *P = std::get_if<Pointer>(&Value)) return P->toRValue(*Ctx, getSourceType()); else if (const auto *FP = std::get_if<FunctionPointer>(&Value)) // Nope - return FP->toAPValue(); + return FP->toAPValue(Ctx->getASTContext()); llvm_unreachable("Unhandled lvalue kind"); } diff --git a/clang/lib/AST/Interp/Floating.h b/clang/lib/AST/Interp/Floating.h index e4ac76d8509fb..114487821880f 100644 --- a/clang/lib/AST/Interp/Floating.h +++ b/clang/lib/AST/Interp/Floating.h @@ -69,7 +69,7 @@ class Floating final { APSInt toAPSInt(unsigned NumBits = 0) const { return APSInt(F.bitcastToAPInt()); } - APValue toAPValue() const { return APValue(F); } + APValue toAPValue(const ASTContext &) const { return APValue(F); } void print(llvm::raw_ostream &OS) const { // Can't use APFloat::print() since it appends a newline. SmallVector<char, 16> Buffer; diff --git a/clang/lib/AST/Interp/FunctionPointer.h b/clang/lib/AST/Interp/FunctionPointer.h index fc3d7a4214a72..0f2c6e571a1d8 100644 --- a/clang/lib/AST/Interp/FunctionPointer.h +++ b/clang/lib/AST/Interp/FunctionPointer.h @@ -40,7 +40,7 @@ class FunctionPointer final { return Func->getDecl()->isWeak(); } - APValue toAPValue() const { + APValue toAPValue(const ASTContext &) const { if (!Func) return APValue(static_cast<Expr *>(nullptr), CharUnits::Zero(), {}, /*OnePastTheEnd=*/false, /*IsNull=*/true); @@ -69,7 +69,7 @@ class FunctionPointer final { if (!Func) return "nullptr"; - return toAPValue().getAsString(Ctx, Func->getDecl()->getType()); + return toAPValue(Ctx).getAsString(Ctx, Func->getDecl()->getType()); } uint64_t getIntegerRepresentation() const { diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h index db4cc9ae45b49..aafdd02676c96 100644 --- a/clang/lib/AST/Interp/Integral.h +++ b/clang/lib/AST/Interp/Integral.h @@ -112,7 +112,7 @@ template <unsigned Bits, bool Signed> class Integral final { else return APSInt(toAPSInt().zextOrTrunc(NumBits), !Signed); } - APValue toAPValue() const { return APValue(toAPSInt()); } + APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); } Integral<Bits, false> toUnsigned() const { return Integral<Bits, false>(*this); diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index 7464f15cdb03b..b8aa21038256c 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -133,7 +133,7 @@ template <bool Signed> class IntegralAP final { else return APSInt(V.zext(Bits), !Signed); } - APValue toAPValue() const { return APValue(toAPSInt()); } + APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); } bool isZero() const { return V.isZero(); } bool isPositive() const { return V.isNonNegative(); } diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index f86b787fb034e..b2581b5f7b5d0 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -39,8 +39,9 @@ namespace interp { using APSInt = llvm::APSInt; /// Convert a value to an APValue. -template <typename T> bool ReturnValue(const T &V, APValue &R) { - R = V.toAPValue(); +template <typename T> +bool ReturnValue(const InterpState &S, const T &V, APValue &R) { + R = V.toAPValue(S.getCtx()); return true; } @@ -286,7 +287,7 @@ bool Ret(InterpState &S, CodePtr &PC, APValue &Result) { } else { delete S.Current; S.Current = nullptr; - if (!ReturnValue<T>(Ret, Result)) + if (!ReturnValue<T>(S, Ret, Result)) return false; } return true; @@ -1318,7 +1319,7 @@ bool InitGlobalTemp(InterpState &S, CodePtr OpPC, uint32_t I, const Pointer &Ptr = S.P.getGlobal(I); const T Value = S.Stk.peek<T>(); - APValue APV = Value.toAPValue(); + APValue APV = Value.toAPValue(S.getCtx()); APValue *Cached = Temp->getOrCreateValue(true); *Cached = APV; diff --git a/clang/lib/AST/Interp/MemberPointer.cpp b/clang/lib/AST/Interp/MemberPointer.cpp index 96f63643e83c9..0c1b6edc5f7e1 100644 --- a/clang/lib/AST/Interp/MemberPointer.cpp +++ b/clang/lib/AST/Interp/MemberPointer.cpp @@ -60,13 +60,13 @@ FunctionPointer MemberPointer::toFunctionPointer(const Context &Ctx) const { return FunctionPointer(Ctx.getProgram().getFunction(cast<FunctionDecl>(Dcl))); } -APValue MemberPointer::toAPValue() const { +APValue MemberPointer::toAPValue(const ASTContext &ASTCtx) const { if (isZero()) return APValue(static_cast<ValueDecl *>(nullptr), /*IsDerivedMember=*/false, /*Path=*/{}); if (hasBase()) - return Base.toAPValue(); + return Base.toAPValue(ASTCtx); return APValue(cast<ValueDecl>(getDecl()), /*IsDerivedMember=*/false, /*Path=*/{}); diff --git a/clang/lib/AST/Interp/MemberPointer.h b/clang/lib/AST/Interp/MemberPointer.h index f56dc530431e4..2b3be124db426 100644 --- a/clang/lib/AST/Interp/MemberPointer.h +++ b/clang/lib/AST/Interp/MemberPointer.h @@ -80,7 +80,7 @@ class MemberPointer final { return MemberPointer(Instance, this->Dcl, this->PtrOffset); } - APValue toAPValue() const; + APValue toAPValue(const ASTContext &) const; bool isZero() const { return Base.isZero() && !Dcl; } bool hasBase() const { return !Base.isZero(); } diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp index b22b4b1918ba5..f7bd76b260584 100644 --- a/clang/lib/AST/Interp/Pointer.cpp +++ b/clang/lib/AST/Interp/Pointer.cpp @@ -119,7 +119,7 @@ void Pointer::operator=(Pointer &&P) { } } -APValue Pointer::toAPValue() const { +APValue Pointer::toAPValue(const ASTContext &ASTCtx) const { llvm::SmallVector<APValue::LValuePathEntry, 5> Path; if (isZero()) @@ -220,7 +220,7 @@ std::string Pointer::toDiagnosticString(const ASTContext &Ctx) const { if (isIntegralPointer()) return (Twine("&(") + Twine(asIntPointer().Value + Offset) + ")").str(); - return toAPValue().getAsString(Ctx, getType()); + return toAPValue(Ctx).getAsString(Ctx, getType()); } bool Pointer::isInitialized() const { @@ -344,10 +344,12 @@ bool Pointer::hasSameArray(const Pointer &A, const Pointer &B) { std::optional<APValue> Pointer::toRValue(const Context &Ctx, QualType ResultType) const { + const ASTContext &ASTCtx = Ctx.getASTContext(); assert(!ResultType.isNull()); // Method to recursively traverse composites. std::function<bool(QualType, const Pointer &, APValue &)> Composite; - Composite = [&Composite, &Ctx](QualType Ty, const Pointer &Ptr, APValue &R) { + Composite = [&Composite, &Ctx, &ASTCtx](QualType Ty, const Pointer &Ptr, + APValue &R) { if (const auto *AT = Ty->getAs<AtomicType>()) Ty = AT->getValueType(); @@ -358,7 +360,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx, // Primitive values. if (std::optional<PrimType> T = Ctx.classify(Ty)) { - TYPE_SWITCH(*T, R = Ptr.deref<T>().toAPValue()); + TYPE_SWITCH(*T, R = Ptr.deref<T>().toAPValue(ASTCtx)); return true; } @@ -375,7 +377,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx, QualType FieldTy = F.Decl->getType(); if (FP.isActive()) { if (std::optional<PrimType> T = Ctx.classify(FieldTy)) { - TYPE_SWITCH(*T, Value = FP.deref<T>().toAPValue()); + TYPE_SWITCH(*T, Value = FP.deref<T>().toAPValue(ASTCtx)); } else { Ok &= Composite(FieldTy, FP, Value); } @@ -398,7 +400,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx, APValue &Value = R.getStructField(I); if (std::optional<PrimType> T = Ctx.classify(FieldTy)) { - TYPE_SWITCH(*T, Value = FP.deref<T>().toAPValue()); + TYPE_SWITCH(*T, Value = FP.deref<T>().toAPValue(ASTCtx)); } else { Ok &= Composite(FieldTy, FP, Value); } @@ -436,7 +438,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx, APValue &Slot = R.getArrayInitializedElt(I); const Pointer &EP = Ptr.atIndex(I); if (std::optional<PrimType> T = Ctx.classify(ElemTy)) { - TYPE_SWITCH(*T, Slot = EP.deref<T>().toAPValue()); + TYPE_SWITCH(*T, Slot = EP.deref<T>().toAPValue(ASTCtx)); } else { Ok &= Composite(ElemTy, EP.narrow(), Slot); } @@ -475,7 +477,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx, Values.reserve(VT->getNumElements()); for (unsigned I = 0; I != VT->getNumElements(); ++I) { TYPE_SWITCH(ElemT, { - Values.push_back(Ptr.atIndex(I).deref<T>().toAPValue()); + Values.push_back(Ptr.atIndex(I).deref<T>().toAPValue(ASTCtx)); }); } @@ -493,11 +495,11 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx, // We can return these as rvalues, but we can't deref() them. if (isZero() || isIntegralPointer()) - return toAPValue(); + return toAPValue(ASTCtx); // Just load primitive types. if (std::optional<PrimType> T = Ctx.classify(ResultType)) { - TYPE_SWITCH(*T, return this->deref<T>().toAPValue()); + TYPE_SWITCH(*T, return this->deref<T>().toAPValue(ASTCtx)); } // Return the composite type. diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h index 972f55a553f6e..7fa6a3230a4f9 100644 --- a/clang/lib/AST/Interp/Pointer.h +++ b/clang/lib/AST/Interp/Pointer.h @@ -118,7 +118,7 @@ class Pointer { bool operator!=(const Pointer &P) const { return !(P == *this); } /// Converts the pointer to an APValue. - APValue toAPValue() const; + APValue toAPValue(const ASTContext &ASTCtx) const; /// Converts the pointer to a string usable in diagnostics. std::string toDiagnosticString(const ASTContext &Ctx) const; diff --git a/clang/unittests/AST/Interp/toAPValue.cpp b/clang/unittests/AST/Interp/toAPValue.cpp index d6879d6e0bca3..5ec607a824349 100644 --- a/clang/unittests/AST/Interp/toAPValue.cpp +++ b/clang/unittests/AST/Interp/toAPValue.cpp @@ -27,6 +27,7 @@ TEST(ToAPValue, Pointers) { auto AST = tooling::buildASTFromCodeWithArgs( Code, {"-fexperimental-new-constant-interpreter"}); + auto &ASTCtx = AST->getASTContext(); auto &Ctx = AST->getASTContext().getInterpContext(); Program &Prog = Ctx.getProgram(); @@ -47,7 +48,7 @@ TEST(ToAPValue, Pointers) { const Pointer &GP = getGlobalPtr("b"); const Pointer &P = GP.deref<Pointer>(); ASSERT_TRUE(P.isLive()); - APValue A = P.toAPValue(); + APValue A = P.toAPValue(ASTCtx); ASSERT_TRUE(A.isLValue()); ASSERT_TRUE(A.hasLValuePath()); const auto &Path = A.getLValuePath(); @@ -62,7 +63,7 @@ TEST(ToAPValue, Pointers) { const Pointer &GP = getGlobalPtr("p"); const Pointer &P = GP.deref<Pointer>(); ASSERT_TRUE(P.isIntegralPointer()); - APValue A = P.toAPValue(); + APValue A = P.toAPValue(ASTCtx); ASSERT_TRUE(A.isLValue()); ASSERT_TRUE(A.getLValueBase().isNull()); APSInt I; @@ -77,7 +78,7 @@ TEST(ToAPValue, Pointers) { const Pointer &GP = getGlobalPtr("nullp"); const Pointer &P = GP.deref<Pointer>(); ASSERT_TRUE(P.isIntegralPointer()); - APValue A = P.toAPValue(); + APValue A = P.toAPValue(ASTCtx); ASSERT_TRUE(A.isLValue()); ASSERT_TRUE(A.getLValueBase().isNull()); ASSERT_TRUE(A.isNullPointer()); @@ -96,6 +97,7 @@ TEST(ToAPValue, FunctionPointers) { auto AST = tooling::buildASTFromCodeWithArgs( Code, {"-fexperimental-new-constant-interpreter"}); + auto &ASTCtx = AST->getASTContext(); auto &Ctx = AST->getASTContext().getInterpContext(); Program &Prog = Ctx.getProgram(); @@ -117,7 +119,7 @@ TEST(ToAPValue, FunctionPointers) { const Pointer &GP = getGlobalPtr("func"); const FunctionPointer &FP = GP.deref<FunctionPointer>(); ASSERT_FALSE(FP.isZero()); - APValue A = FP.toAPValue(); + APValue A = FP.toAPValue(ASTCtx); ASSERT_TRUE(A.hasValue()); ASSERT_TRUE(A.isLValue()); ASSERT_TRUE(A.hasLValuePath()); @@ -132,7 +134,7 @@ TEST(ToAPValue, FunctionPointers) { ASSERT_NE(D, nullptr); const Pointer &GP = getGlobalPtr("nullp"); const auto &P = GP.deref<FunctionPointer>(); - APValue A = P.toAPValue(); + APValue A = P.toAPValue(ASTCtx); ASSERT_TRUE(A.isLValue()); ASSERT_TRUE(A.getLValueBase().isNull()); ASSERT_TRUE(A.isNullPointer()); @@ -151,6 +153,7 @@ TEST(ToAPValue, FunctionPointersC) { auto AST = tooling::buildASTFromCodeWithArgs( Code, {"-x", "c", "-fexperimental-new-constant-interpreter"}); + auto &ASTCtx = AST->getASTContext(); auto &Ctx = AST->getASTContext().getInterpContext(); Program &Prog = Ctx.getProgram(); @@ -174,7 +177,7 @@ TEST(ToAPValue, FunctionPointersC) { ASSERT_TRUE(GP.isLive()); const FunctionPointer &FP = GP.deref<FunctionPointer>(); ASSERT_FALSE(FP.isZero()); - APValue A = FP.toAPValue(); + APValue A = FP.toAPValue(ASTCtx); ASSERT_TRUE(A.hasValue()); ASSERT_TRUE(A.isLValue()); const auto &Path = A.getLValuePath(); @@ -197,6 +200,7 @@ TEST(ToAPValue, MemberPointers) { auto AST = tooling::buildASTFromCodeWithArgs( Code, {"-fexperimental-new-constant-interpreter"}); + auto &ASTCtx = AST->getASTContext(); auto &Ctx = AST->getASTContext().getInterpContext(); Program &Prog = Ctx.getProgram(); @@ -218,7 +222,7 @@ TEST(ToAPValue, MemberPointers) { const Pointer &GP = getGlobalPtr("pm"); ASSERT_TRUE(GP.isLive()); const MemberPointer &FP = GP.deref<MemberPointer>(); - APValue A = FP.toAPValue(); + APValue A = FP.toAPValue(ASTCtx); ASSERT_EQ(A.getMemberPointerDecl(), getDecl("m")); ASSERT_EQ(A.getKind(), APValue::MemberPointer); } @@ -228,7 +232,7 @@ TEST(ToAPValue, MemberPointers) { ASSERT_TRUE(GP.isLive()); const MemberPointer &NP = GP.deref<MemberPointer>(); ASSERT_TRUE(NP.isZero()); - APValue A = NP.toAPValue(); + APValue A = NP.toAPValue(ASTCtx); ASSERT_EQ(A.getKind(), APValue::MemberPointer); } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits