Skip to content

Commit e034eab

Browse files
fix GetVariableOffset for static constexpr class attribute
by explicitly initializing constexpr with `Sema::InstantiateVariableDefinition`
1 parent 826be78 commit e034eab

File tree

2 files changed

+94
-5
lines changed

2 files changed

+94
-5
lines changed

lib/Interpreter/CppInterOp.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,12 +1284,22 @@ namespace Cpp {
12841284
#endif
12851285
}
12861286
auto VDAorErr = compat::getSymbolAddress(I, StringRef(mangledName));
1287-
if (!VDAorErr) {
1288-
llvm::logAllUnhandledErrors(VDAorErr.takeError(), llvm::errs(),
1289-
"Failed to GetVariableOffset:");
1290-
return 0;
1287+
if (VDAorErr)
1288+
return (intptr_t)jitTargetAddressToPointer<void*>(VDAorErr.get());
1289+
1290+
llvm::logAllUnhandledErrors(VDAorErr.takeError(), llvm::errs(),
1291+
"Failed to GetVariableOffset:");
1292+
1293+
if (!VD->hasInit())
1294+
getSema().InstantiateVariableDefinition(SourceLocation(), VD);
1295+
if (VD->hasInit() &&
1296+
(VD->isConstexpr() || VD->getType().isConstQualified())) {
1297+
if (const APValue* val = VD->evaluateValue()) {
1298+
if (VD->getType()->isIntegralType(C)) {
1299+
return (intptr_t)val->getInt().getRawData();
1300+
}
1301+
}
12911302
}
1292-
return (intptr_t) jitTargetAddressToPointer<void*>(VDAorErr.get());
12931303
}
12941304

12951305
return 0;

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,3 +1154,82 @@ 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+
#ifdef _WIN32
1163+
GTEST_SKIP() << "Disabled on Windows. Needs fixing.";
1164+
#endif
1165+
1166+
Cpp::CreateInterpreter();
1167+
1168+
Cpp::Declare(R"(
1169+
class MyClass {
1170+
public:
1171+
static constexpr int x = 3;
1172+
};
1173+
1174+
template<int i>
1175+
class MyTemplatedClass {
1176+
public:
1177+
static constexpr int x = i;
1178+
};
1179+
1180+
template<typename _Tp, _Tp __v>
1181+
struct integral_constant
1182+
{
1183+
static constexpr _Tp value = __v;
1184+
};
1185+
1186+
template<typename... Eles>
1187+
struct Elements
1188+
: public integral_constant<int, sizeof...(Eles)> {};
1189+
)");
1190+
1191+
Cpp::TCppScope_t MyClass = Cpp::GetNamed("MyClass");
1192+
EXPECT_TRUE(MyClass);
1193+
1194+
std::vector<Cpp::TCppScope_t> datamembers;
1195+
Cpp::GetStaticDatamembers(MyClass, datamembers);
1196+
EXPECT_EQ(datamembers.size(), 1);
1197+
1198+
intptr_t offset = Cpp::GetVariableOffset(datamembers[0]);
1199+
EXPECT_EQ(3, *(int*)offset);
1200+
1201+
ASTContext& C = Interp->getCI()->getASTContext();
1202+
std::vector<Cpp::TemplateArgInfo> template_args = {
1203+
{C.IntTy.getAsOpaquePtr(), "5"}};
1204+
1205+
Cpp::TCppFunction_t MyTemplatedClass =
1206+
Cpp::InstantiateTemplate(Cpp::GetNamed("MyTemplatedClass"),
1207+
template_args.data(), template_args.size());
1208+
EXPECT_TRUE(MyTemplatedClass);
1209+
1210+
datamembers.clear();
1211+
Cpp::GetStaticDatamembers(MyTemplatedClass, datamembers);
1212+
EXPECT_EQ(datamembers.size(), 1);
1213+
1214+
offset = Cpp::GetVariableOffset(datamembers[0]);
1215+
EXPECT_EQ(5, *(int*)offset);
1216+
1217+
std::vector<Cpp::TemplateArgInfo> ele_template_args = {
1218+
{C.IntTy.getAsOpaquePtr()}, {C.FloatTy.getAsOpaquePtr()}};
1219+
1220+
Cpp::TCppFunction_t Elements = Cpp::InstantiateTemplate(
1221+
Cpp::GetNamed("Elements"), ele_template_args.data(),
1222+
ele_template_args.size());
1223+
EXPECT_TRUE(Elements);
1224+
1225+
EXPECT_EQ(1, Cpp::GetNumBases(Elements));
1226+
1227+
Cpp::TCppScope_t IC = Cpp::GetBaseClass(Elements, 0);
1228+
1229+
datamembers.clear();
1230+
Cpp::GetStaticDatamembers(IC, datamembers);
1231+
EXPECT_EQ(datamembers.size(), 1);
1232+
1233+
offset = Cpp::GetVariableOffset(datamembers[0]);
1234+
EXPECT_EQ(2, *(int*)offset);
1235+
}

0 commit comments

Comments
 (0)