Skip to content

Commit 24c82c5

Browse files
resolve static constexpr class attribute
1 parent 826be78 commit 24c82c5

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

lib/Interpreter/CppInterOp.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,18 @@ namespace Cpp {
12481248

12491249
if (!address)
12501250
address = I.getAddressOfGlobal(GD);
1251+
if (!address) {
1252+
if (VD->isConstexpr())
1253+
Declare((GetQualifiedCompleteName(VD) + ";").c_str());
1254+
if (VD->hasInit() &&
1255+
(VD->isConstexpr() || VD->getType().isConstQualified())) {
1256+
if (const APValue* val = VD->evaluateValue()) {
1257+
if (VD->getType()->isIntegralType(C)) {
1258+
return (intptr_t)val->getInt().getRawData();
1259+
}
1260+
}
1261+
}
1262+
}
12511263
if (!address) {
12521264
auto Linkage = C.GetGVALinkageForVariable(VD);
12531265
// The decl was deferred by CodeGen. Force its emission.

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,3 +1154,49 @@ TEST(FunctionReflectionTest, Destruct) {
11541154
output = testing::internal::GetCapturedStdout();
11551155
EXPECT_EQ(output, "Destructor Executed");
11561156
}
1157+
1158+
TEST(FunctionReflectionTest, StaticConstExprDatamember) {
1159+
if (llvm::sys::RunningOnValgrind())
1160+
GTEST_SKIP() << "XFAIL due to Valgrind report";
1161+
1162+
Cpp::CreateInterpreter();
1163+
1164+
Cpp::Declare(R"(
1165+
class MyClass {
1166+
public:
1167+
static constexpr int x = 3;
1168+
};
1169+
1170+
template<int i>
1171+
class MyTemplatedClass {
1172+
public:
1173+
static constexpr int x = i;
1174+
};
1175+
)");
1176+
1177+
Cpp::TCppScope_t MyClass = Cpp::GetNamed("MyClass");
1178+
EXPECT_TRUE(MyClass);
1179+
1180+
std::vector<Cpp::TCppScope_t> datamembers;
1181+
Cpp::GetStaticDatamembers(MyClass, datamembers);
1182+
EXPECT_EQ(datamembers.size(), 1);
1183+
1184+
intptr_t offset = Cpp::GetVariableOffset(datamembers[0]);
1185+
EXPECT_EQ(3, *(int*)offset);
1186+
1187+
ASTContext& C = Interp->getCI()->getASTContext();
1188+
std::vector<Cpp::TemplateArgInfo> template_args = {
1189+
{C.IntTy.getAsOpaquePtr(), "5"}};
1190+
1191+
Cpp::TCppFunction_t MyTemplatedClass =
1192+
Cpp::InstantiateTemplate(Cpp::GetNamed("MyTemplatedClass"),
1193+
template_args.data(), template_args.size());
1194+
EXPECT_TRUE(MyTemplatedClass);
1195+
1196+
datamembers.clear();
1197+
Cpp::GetStaticDatamembers(MyTemplatedClass, datamembers);
1198+
EXPECT_EQ(datamembers.size(), 1);
1199+
1200+
offset = Cpp::GetVariableOffset(datamembers[0]);
1201+
EXPECT_EQ(5, *(int*)offset);
1202+
}

0 commit comments

Comments
 (0)