summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimm Bäder <tbaeder@redhat.com>2024-04-15 15:11:23 +0200
committerTimm Bäder <tbaeder@redhat.com>2024-04-16 12:34:35 +0200
commitc09384e2b419c7b4e4167e0d0295d9018cc6169c (patch)
treef4630f01d0b81d3441475044816c0739d89b108b
parent01f79899ba349a0200586c8d05f5e22cca2ced31 (diff)
[clang][Interp] Support MemberExprs pointing to VarDecls
-rw-r--r--clang/lib/AST/Interp/ByteCodeExprGen.cpp11
-rw-r--r--clang/test/AST/Interp/records.cpp8
2 files changed, 17 insertions, 2 deletions
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 4a7b40440770..a069f3ec27e7 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1267,10 +1267,19 @@ template <class Emitter>
bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) {
// 'Base.Member'
const Expr *Base = E->getBase();
+ const ValueDecl *Member = E->getMemberDecl();
if (DiscardResult)
return this->discard(Base);
+ if (const auto *VD = dyn_cast<VarDecl>(Member)) {
+ // I am almost confident in saying that a var decl must be static
+ // and therefore registered as a global variable. But this will probably
+ // turn out to be wrong some time in the future, as always.
+ if (auto GlobalIndex = P.getGlobal(VD))
+ return this->emitGetPtrGlobal(*GlobalIndex, E);
+ }
+
if (Initializing) {
if (!this->delegate(Base))
return false;
@@ -1280,8 +1289,6 @@ bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) {
}
// Base above gives us a pointer on the stack.
- // TODO: Implement non-FieldDecl members.
- const ValueDecl *Member = E->getMemberDecl();
if (const auto *FD = dyn_cast<FieldDecl>(Member)) {
const RecordDecl *RD = FD->getParent();
const Record *R = getRecord(RD);
diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp
index f251497ed701..2c33fa1bf884 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -1309,3 +1309,11 @@ namespace pr18633 {
func2<int>();
}
}
+
+namespace {
+ struct F {
+ static constexpr int Z = 12;
+ };
+ F f;
+ static_assert(f.Z == 12, "");
+}