[clang] 56a9f7c - [clang][Interp] Pass ASTContext to toAPValue()
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Sat Jul 20 06:29:44 PDT 2024
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);
}
}
More information about the cfe-commits
mailing list