Skip to content

Commit c09384e

Browse files
committed
[clang][Interp] Support MemberExprs pointing to VarDecls
1 parent 01f7989 commit c09384e

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,10 +1267,19 @@ template <class Emitter>
12671267
bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) {
12681268
// 'Base.Member'
12691269
const Expr *Base = E->getBase();
1270+
const ValueDecl *Member = E->getMemberDecl();
12701271

12711272
if (DiscardResult)
12721273
return this->discard(Base);
12731274

1275+
if (const auto *VD = dyn_cast<VarDecl>(Member)) {
1276+
// I am almost confident in saying that a var decl must be static
1277+
// and therefore registered as a global variable. But this will probably
1278+
// turn out to be wrong some time in the future, as always.
1279+
if (auto GlobalIndex = P.getGlobal(VD))
1280+
return this->emitGetPtrGlobal(*GlobalIndex, E);
1281+
}
1282+
12741283
if (Initializing) {
12751284
if (!this->delegate(Base))
12761285
return false;
@@ -1280,8 +1289,6 @@ bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) {
12801289
}
12811290

12821291
// Base above gives us a pointer on the stack.
1283-
// TODO: Implement non-FieldDecl members.
1284-
const ValueDecl *Member = E->getMemberDecl();
12851292
if (const auto *FD = dyn_cast<FieldDecl>(Member)) {
12861293
const RecordDecl *RD = FD->getParent();
12871294
const Record *R = getRecord(RD);

clang/test/AST/Interp/records.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,3 +1309,11 @@ namespace pr18633 {
13091309
func2<int>();
13101310
}
13111311
}
1312+
1313+
namespace {
1314+
struct F {
1315+
static constexpr int Z = 12;
1316+
};
1317+
F f;
1318+
static_assert(f.Z == 12, "");
1319+
}

0 commit comments

Comments
 (0)