Skip to content

Commit 7466d62

Browse files
tbaederryuxuanchen1997
authored andcommitted
[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.
1 parent 8940802 commit 7466d62

File tree

14 files changed

+48
-40
lines changed

14 files changed

+48
-40
lines changed

clang/lib/AST/Interp/Boolean.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class Boolean final {
5656
APSInt toAPSInt(unsigned NumBits) const {
5757
return APSInt(toAPSInt().zextOrTrunc(NumBits), true);
5858
}
59-
APValue toAPValue() const { return APValue(toAPSInt()); }
59+
APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); }
6060

6161
Boolean toUnsigned() const { return *this; }
6262

clang/lib/AST/Interp/Disasm.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,9 +366,9 @@ LLVM_DUMP_METHOD void EvaluationResult::dump() const {
366366

367367
OS << "LValue: ";
368368
if (const auto *P = std::get_if<Pointer>(&Value))
369-
P->toAPValue().printPretty(OS, ASTCtx, SourceType);
369+
P->toAPValue(ASTCtx).printPretty(OS, ASTCtx, SourceType);
370370
else if (const auto *FP = std::get_if<FunctionPointer>(&Value)) // Nope
371-
FP->toAPValue().printPretty(OS, ASTCtx, SourceType);
371+
FP->toAPValue(ASTCtx).printPretty(OS, ASTCtx, SourceType);
372372
OS << "\n";
373373
break;
374374
}

clang/lib/AST/Interp/EvalEmitter.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ template <PrimType OpType> bool EvalEmitter::emitRet(const SourceInfo &Info) {
145145
return false;
146146

147147
using T = typename PrimConv<OpType>::T;
148-
EvalResult.setValue(S.Stk.pop<T>().toAPValue());
148+
EvalResult.setValue(S.Stk.pop<T>().toAPValue(Ctx.getASTContext()));
149149
return true;
150150
}
151151

@@ -181,7 +181,7 @@ template <> bool EvalEmitter::emitRet<PT_Ptr>(const SourceInfo &Info) {
181181
return false;
182182
}
183183
} else {
184-
EvalResult.setValue(Ptr.toAPValue());
184+
EvalResult.setValue(Ptr.toAPValue(Ctx.getASTContext()));
185185
}
186186

187187
return true;
@@ -285,7 +285,8 @@ void EvalEmitter::updateGlobalTemporaries() {
285285
APValue *Cached = Temp->getOrCreateValue(true);
286286

287287
if (std::optional<PrimType> T = Ctx.classify(E->getType())) {
288-
TYPE_SWITCH(*T, { *Cached = Ptr.deref<T>().toAPValue(); });
288+
TYPE_SWITCH(
289+
*T, { *Cached = Ptr.deref<T>().toAPValue(Ctx.getASTContext()); });
289290
} else {
290291
if (std::optional<APValue> APV =
291292
Ptr.toRValue(Ctx, Temp->getTemporaryExpr()->getType()))

clang/lib/AST/Interp/EvaluationResult.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ APValue EvaluationResult::toAPValue() const {
2121
case LValue:
2222
// Either a pointer or a function pointer.
2323
if (const auto *P = std::get_if<Pointer>(&Value))
24-
return P->toAPValue();
24+
return P->toAPValue(Ctx->getASTContext());
2525
else if (const auto *FP = std::get_if<FunctionPointer>(&Value))
26-
return FP->toAPValue();
26+
return FP->toAPValue(Ctx->getASTContext());
2727
else
2828
llvm_unreachable("Unhandled LValue type");
2929
break;
@@ -46,7 +46,7 @@ std::optional<APValue> EvaluationResult::toRValue() const {
4646
if (const auto *P = std::get_if<Pointer>(&Value))
4747
return P->toRValue(*Ctx, getSourceType());
4848
else if (const auto *FP = std::get_if<FunctionPointer>(&Value)) // Nope
49-
return FP->toAPValue();
49+
return FP->toAPValue(Ctx->getASTContext());
5050
llvm_unreachable("Unhandled lvalue kind");
5151
}
5252

clang/lib/AST/Interp/Floating.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class Floating final {
6969
APSInt toAPSInt(unsigned NumBits = 0) const {
7070
return APSInt(F.bitcastToAPInt());
7171
}
72-
APValue toAPValue() const { return APValue(F); }
72+
APValue toAPValue(const ASTContext &) const { return APValue(F); }
7373
void print(llvm::raw_ostream &OS) const {
7474
// Can't use APFloat::print() since it appends a newline.
7575
SmallVector<char, 16> Buffer;

clang/lib/AST/Interp/FunctionPointer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class FunctionPointer final {
4040
return Func->getDecl()->isWeak();
4141
}
4242

43-
APValue toAPValue() const {
43+
APValue toAPValue(const ASTContext &) const {
4444
if (!Func)
4545
return APValue(static_cast<Expr *>(nullptr), CharUnits::Zero(), {},
4646
/*OnePastTheEnd=*/false, /*IsNull=*/true);
@@ -69,7 +69,7 @@ class FunctionPointer final {
6969
if (!Func)
7070
return "nullptr";
7171

72-
return toAPValue().getAsString(Ctx, Func->getDecl()->getType());
72+
return toAPValue(Ctx).getAsString(Ctx, Func->getDecl()->getType());
7373
}
7474

7575
uint64_t getIntegerRepresentation() const {

clang/lib/AST/Interp/Integral.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ template <unsigned Bits, bool Signed> class Integral final {
112112
else
113113
return APSInt(toAPSInt().zextOrTrunc(NumBits), !Signed);
114114
}
115-
APValue toAPValue() const { return APValue(toAPSInt()); }
115+
APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); }
116116

117117
Integral<Bits, false> toUnsigned() const {
118118
return Integral<Bits, false>(*this);

clang/lib/AST/Interp/IntegralAP.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ template <bool Signed> class IntegralAP final {
133133
else
134134
return APSInt(V.zext(Bits), !Signed);
135135
}
136-
APValue toAPValue() const { return APValue(toAPSInt()); }
136+
APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); }
137137

138138
bool isZero() const { return V.isZero(); }
139139
bool isPositive() const { return V.isNonNegative(); }

clang/lib/AST/Interp/Interp.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ namespace interp {
3939
using APSInt = llvm::APSInt;
4040

4141
/// Convert a value to an APValue.
42-
template <typename T> bool ReturnValue(const T &V, APValue &R) {
43-
R = V.toAPValue();
42+
template <typename T>
43+
bool ReturnValue(const InterpState &S, const T &V, APValue &R) {
44+
R = V.toAPValue(S.getCtx());
4445
return true;
4546
}
4647

@@ -286,7 +287,7 @@ bool Ret(InterpState &S, CodePtr &PC, APValue &Result) {
286287
} else {
287288
delete S.Current;
288289
S.Current = nullptr;
289-
if (!ReturnValue<T>(Ret, Result))
290+
if (!ReturnValue<T>(S, Ret, Result))
290291
return false;
291292
}
292293
return true;
@@ -1318,7 +1319,7 @@ bool InitGlobalTemp(InterpState &S, CodePtr OpPC, uint32_t I,
13181319
const Pointer &Ptr = S.P.getGlobal(I);
13191320

13201321
const T Value = S.Stk.peek<T>();
1321-
APValue APV = Value.toAPValue();
1322+
APValue APV = Value.toAPValue(S.getCtx());
13221323
APValue *Cached = Temp->getOrCreateValue(true);
13231324
*Cached = APV;
13241325

clang/lib/AST/Interp/MemberPointer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ FunctionPointer MemberPointer::toFunctionPointer(const Context &Ctx) const {
6060
return FunctionPointer(Ctx.getProgram().getFunction(cast<FunctionDecl>(Dcl)));
6161
}
6262

63-
APValue MemberPointer::toAPValue() const {
63+
APValue MemberPointer::toAPValue(const ASTContext &ASTCtx) const {
6464
if (isZero())
6565
return APValue(static_cast<ValueDecl *>(nullptr), /*IsDerivedMember=*/false,
6666
/*Path=*/{});
6767

6868
if (hasBase())
69-
return Base.toAPValue();
69+
return Base.toAPValue(ASTCtx);
7070

7171
return APValue(cast<ValueDecl>(getDecl()), /*IsDerivedMember=*/false,
7272
/*Path=*/{});

clang/lib/AST/Interp/MemberPointer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class MemberPointer final {
8080
return MemberPointer(Instance, this->Dcl, this->PtrOffset);
8181
}
8282

83-
APValue toAPValue() const;
83+
APValue toAPValue(const ASTContext &) const;
8484

8585
bool isZero() const { return Base.isZero() && !Dcl; }
8686
bool hasBase() const { return !Base.isZero(); }

clang/lib/AST/Interp/Pointer.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ void Pointer::operator=(Pointer &&P) {
119119
}
120120
}
121121

122-
APValue Pointer::toAPValue() const {
122+
APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
123123
llvm::SmallVector<APValue::LValuePathEntry, 5> Path;
124124

125125
if (isZero())
@@ -220,7 +220,7 @@ std::string Pointer::toDiagnosticString(const ASTContext &Ctx) const {
220220
if (isIntegralPointer())
221221
return (Twine("&(") + Twine(asIntPointer().Value + Offset) + ")").str();
222222

223-
return toAPValue().getAsString(Ctx, getType());
223+
return toAPValue(Ctx).getAsString(Ctx, getType());
224224
}
225225

226226
bool Pointer::isInitialized() const {
@@ -344,10 +344,12 @@ bool Pointer::hasSameArray(const Pointer &A, const Pointer &B) {
344344

345345
std::optional<APValue> Pointer::toRValue(const Context &Ctx,
346346
QualType ResultType) const {
347+
const ASTContext &ASTCtx = Ctx.getASTContext();
347348
assert(!ResultType.isNull());
348349
// Method to recursively traverse composites.
349350
std::function<bool(QualType, const Pointer &, APValue &)> Composite;
350-
Composite = [&Composite, &Ctx](QualType Ty, const Pointer &Ptr, APValue &R) {
351+
Composite = [&Composite, &Ctx, &ASTCtx](QualType Ty, const Pointer &Ptr,
352+
APValue &R) {
351353
if (const auto *AT = Ty->getAs<AtomicType>())
352354
Ty = AT->getValueType();
353355

@@ -358,7 +360,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
358360

359361
// Primitive values.
360362
if (std::optional<PrimType> T = Ctx.classify(Ty)) {
361-
TYPE_SWITCH(*T, R = Ptr.deref<T>().toAPValue());
363+
TYPE_SWITCH(*T, R = Ptr.deref<T>().toAPValue(ASTCtx));
362364
return true;
363365
}
364366

@@ -375,7 +377,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
375377
QualType FieldTy = F.Decl->getType();
376378
if (FP.isActive()) {
377379
if (std::optional<PrimType> T = Ctx.classify(FieldTy)) {
378-
TYPE_SWITCH(*T, Value = FP.deref<T>().toAPValue());
380+
TYPE_SWITCH(*T, Value = FP.deref<T>().toAPValue(ASTCtx));
379381
} else {
380382
Ok &= Composite(FieldTy, FP, Value);
381383
}
@@ -398,7 +400,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
398400
APValue &Value = R.getStructField(I);
399401

400402
if (std::optional<PrimType> T = Ctx.classify(FieldTy)) {
401-
TYPE_SWITCH(*T, Value = FP.deref<T>().toAPValue());
403+
TYPE_SWITCH(*T, Value = FP.deref<T>().toAPValue(ASTCtx));
402404
} else {
403405
Ok &= Composite(FieldTy, FP, Value);
404406
}
@@ -436,7 +438,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
436438
APValue &Slot = R.getArrayInitializedElt(I);
437439
const Pointer &EP = Ptr.atIndex(I);
438440
if (std::optional<PrimType> T = Ctx.classify(ElemTy)) {
439-
TYPE_SWITCH(*T, Slot = EP.deref<T>().toAPValue());
441+
TYPE_SWITCH(*T, Slot = EP.deref<T>().toAPValue(ASTCtx));
440442
} else {
441443
Ok &= Composite(ElemTy, EP.narrow(), Slot);
442444
}
@@ -475,7 +477,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
475477
Values.reserve(VT->getNumElements());
476478
for (unsigned I = 0; I != VT->getNumElements(); ++I) {
477479
TYPE_SWITCH(ElemT, {
478-
Values.push_back(Ptr.atIndex(I).deref<T>().toAPValue());
480+
Values.push_back(Ptr.atIndex(I).deref<T>().toAPValue(ASTCtx));
479481
});
480482
}
481483

@@ -493,11 +495,11 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
493495

494496
// We can return these as rvalues, but we can't deref() them.
495497
if (isZero() || isIntegralPointer())
496-
return toAPValue();
498+
return toAPValue(ASTCtx);
497499

498500
// Just load primitive types.
499501
if (std::optional<PrimType> T = Ctx.classify(ResultType)) {
500-
TYPE_SWITCH(*T, return this->deref<T>().toAPValue());
502+
TYPE_SWITCH(*T, return this->deref<T>().toAPValue(ASTCtx));
501503
}
502504

503505
// Return the composite type.

clang/lib/AST/Interp/Pointer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class Pointer {
118118
bool operator!=(const Pointer &P) const { return !(P == *this); }
119119

120120
/// Converts the pointer to an APValue.
121-
APValue toAPValue() const;
121+
APValue toAPValue(const ASTContext &ASTCtx) const;
122122

123123
/// Converts the pointer to a string usable in diagnostics.
124124
std::string toDiagnosticString(const ASTContext &Ctx) const;

clang/unittests/AST/Interp/toAPValue.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ TEST(ToAPValue, Pointers) {
2727
auto AST = tooling::buildASTFromCodeWithArgs(
2828
Code, {"-fexperimental-new-constant-interpreter"});
2929

30+
auto &ASTCtx = AST->getASTContext();
3031
auto &Ctx = AST->getASTContext().getInterpContext();
3132
Program &Prog = Ctx.getProgram();
3233

@@ -47,7 +48,7 @@ TEST(ToAPValue, Pointers) {
4748
const Pointer &GP = getGlobalPtr("b");
4849
const Pointer &P = GP.deref<Pointer>();
4950
ASSERT_TRUE(P.isLive());
50-
APValue A = P.toAPValue();
51+
APValue A = P.toAPValue(ASTCtx);
5152
ASSERT_TRUE(A.isLValue());
5253
ASSERT_TRUE(A.hasLValuePath());
5354
const auto &Path = A.getLValuePath();
@@ -62,7 +63,7 @@ TEST(ToAPValue, Pointers) {
6263
const Pointer &GP = getGlobalPtr("p");
6364
const Pointer &P = GP.deref<Pointer>();
6465
ASSERT_TRUE(P.isIntegralPointer());
65-
APValue A = P.toAPValue();
66+
APValue A = P.toAPValue(ASTCtx);
6667
ASSERT_TRUE(A.isLValue());
6768
ASSERT_TRUE(A.getLValueBase().isNull());
6869
APSInt I;
@@ -77,7 +78,7 @@ TEST(ToAPValue, Pointers) {
7778
const Pointer &GP = getGlobalPtr("nullp");
7879
const Pointer &P = GP.deref<Pointer>();
7980
ASSERT_TRUE(P.isIntegralPointer());
80-
APValue A = P.toAPValue();
81+
APValue A = P.toAPValue(ASTCtx);
8182
ASSERT_TRUE(A.isLValue());
8283
ASSERT_TRUE(A.getLValueBase().isNull());
8384
ASSERT_TRUE(A.isNullPointer());
@@ -96,6 +97,7 @@ TEST(ToAPValue, FunctionPointers) {
9697
auto AST = tooling::buildASTFromCodeWithArgs(
9798
Code, {"-fexperimental-new-constant-interpreter"});
9899

100+
auto &ASTCtx = AST->getASTContext();
99101
auto &Ctx = AST->getASTContext().getInterpContext();
100102
Program &Prog = Ctx.getProgram();
101103

@@ -117,7 +119,7 @@ TEST(ToAPValue, FunctionPointers) {
117119
const Pointer &GP = getGlobalPtr("func");
118120
const FunctionPointer &FP = GP.deref<FunctionPointer>();
119121
ASSERT_FALSE(FP.isZero());
120-
APValue A = FP.toAPValue();
122+
APValue A = FP.toAPValue(ASTCtx);
121123
ASSERT_TRUE(A.hasValue());
122124
ASSERT_TRUE(A.isLValue());
123125
ASSERT_TRUE(A.hasLValuePath());
@@ -132,7 +134,7 @@ TEST(ToAPValue, FunctionPointers) {
132134
ASSERT_NE(D, nullptr);
133135
const Pointer &GP = getGlobalPtr("nullp");
134136
const auto &P = GP.deref<FunctionPointer>();
135-
APValue A = P.toAPValue();
137+
APValue A = P.toAPValue(ASTCtx);
136138
ASSERT_TRUE(A.isLValue());
137139
ASSERT_TRUE(A.getLValueBase().isNull());
138140
ASSERT_TRUE(A.isNullPointer());
@@ -151,6 +153,7 @@ TEST(ToAPValue, FunctionPointersC) {
151153
auto AST = tooling::buildASTFromCodeWithArgs(
152154
Code, {"-x", "c", "-fexperimental-new-constant-interpreter"});
153155

156+
auto &ASTCtx = AST->getASTContext();
154157
auto &Ctx = AST->getASTContext().getInterpContext();
155158
Program &Prog = Ctx.getProgram();
156159

@@ -174,7 +177,7 @@ TEST(ToAPValue, FunctionPointersC) {
174177
ASSERT_TRUE(GP.isLive());
175178
const FunctionPointer &FP = GP.deref<FunctionPointer>();
176179
ASSERT_FALSE(FP.isZero());
177-
APValue A = FP.toAPValue();
180+
APValue A = FP.toAPValue(ASTCtx);
178181
ASSERT_TRUE(A.hasValue());
179182
ASSERT_TRUE(A.isLValue());
180183
const auto &Path = A.getLValuePath();
@@ -197,6 +200,7 @@ TEST(ToAPValue, MemberPointers) {
197200
auto AST = tooling::buildASTFromCodeWithArgs(
198201
Code, {"-fexperimental-new-constant-interpreter"});
199202

203+
auto &ASTCtx = AST->getASTContext();
200204
auto &Ctx = AST->getASTContext().getInterpContext();
201205
Program &Prog = Ctx.getProgram();
202206

@@ -218,7 +222,7 @@ TEST(ToAPValue, MemberPointers) {
218222
const Pointer &GP = getGlobalPtr("pm");
219223
ASSERT_TRUE(GP.isLive());
220224
const MemberPointer &FP = GP.deref<MemberPointer>();
221-
APValue A = FP.toAPValue();
225+
APValue A = FP.toAPValue(ASTCtx);
222226
ASSERT_EQ(A.getMemberPointerDecl(), getDecl("m"));
223227
ASSERT_EQ(A.getKind(), APValue::MemberPointer);
224228
}
@@ -228,7 +232,7 @@ TEST(ToAPValue, MemberPointers) {
228232
ASSERT_TRUE(GP.isLive());
229233
const MemberPointer &NP = GP.deref<MemberPointer>();
230234
ASSERT_TRUE(NP.isZero());
231-
APValue A = NP.toAPValue();
235+
APValue A = NP.toAPValue(ASTCtx);
232236
ASSERT_EQ(A.getKind(), APValue::MemberPointer);
233237
}
234238
}

0 commit comments

Comments
 (0)