Skip to content

Commit fc852d5

Browse files
Add GetEnumConstantDatamembers function (#499)
to resolve all `EnumConstantDecl`s declared in a class
1 parent b797dbb commit fc852d5

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

include/clang/Interpreter/CppInterOp.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,15 @@ namespace Cpp {
459459
GetStaticDatamembers(TCppScope_t scope,
460460
std::vector<TCppScope_t>& datamembers);
461461

462+
/// Gets all the Enum Constants declared in a Class
463+
///\param[in] scope - class
464+
///\param[out] funcs - vector of static data members
465+
///\param[in] include_enum_class - include enum constants from enum class
466+
CPPINTEROP_API
467+
void GetEnumConstantDatamembers(TCppScope_t scope,
468+
std::vector<TCppScope_t>& datamembers,
469+
bool include_enum_class = true);
470+
462471
/// This is a Lookup function to be used specifically for data members.
463472
CPPINTEROP_API TCppScope_t LookupDatamember(const std::string& name,
464473
TCppScope_t parent);

lib/Interpreter/CppInterOp.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#include "llvm/Support/Debug.h"
3737
#include "llvm/Support/raw_os_ostream.h"
3838

39+
#include <algorithm>
40+
#include <iterator>
3941
#include <map>
4042
#include <set>
4143
#include <sstream>
@@ -1223,6 +1225,23 @@ namespace Cpp {
12231225
GetClassDecls<VarDecl>(scope, datamembers);
12241226
}
12251227

1228+
void GetEnumConstantDatamembers(TCppScope_t scope,
1229+
std::vector<TCppScope_t>& datamembers,
1230+
bool include_enum_class) {
1231+
std::vector<TCppScope_t> EDs;
1232+
GetClassDecls<EnumDecl>(scope, EDs);
1233+
for (TCppScope_t i : EDs) {
1234+
auto* ED = static_cast<EnumDecl*>(i);
1235+
1236+
bool is_class_tagged = ED->isScopedUsingClassTag();
1237+
if (is_class_tagged && !include_enum_class)
1238+
continue;
1239+
1240+
std::copy(ED->enumerator_begin(), ED->enumerator_end(),
1241+
std::back_inserter(datamembers));
1242+
}
1243+
}
1244+
12261245
TCppScope_t LookupDatamember(const std::string& name, TCppScope_t parent) {
12271246
clang::DeclContext *Within = 0;
12281247
if (parent) {
@@ -1256,6 +1275,9 @@ namespace Cpp {
12561275
return QT.getAsOpaquePtr();
12571276
}
12581277

1278+
if (auto* ECD = llvm::dyn_cast_or_null<EnumConstantDecl>(D))
1279+
return ECD->getType().getAsOpaquePtr();
1280+
12591281
return 0;
12601282
}
12611283

unittests/CppInterOp/VariableReflectionTest.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,3 +576,27 @@ TEST(VariableReflectionTest, StaticConstExprDatamember) {
576576
offset = Cpp::GetVariableOffset(datamembers[0]);
577577
EXPECT_EQ(2, *(int*)offset);
578578
}
579+
580+
TEST(VariableReflectionTest, GetEnumConstantDatamembers) {
581+
Cpp::CreateInterpreter();
582+
583+
Cpp::Declare(R"(
584+
class MyEnumClass {
585+
enum { FOUR, FIVE, SIX };
586+
enum A { ONE, TWO, THREE };
587+
enum class B { SEVEN, EIGHT, NINE };
588+
};
589+
)");
590+
591+
Cpp::TCppScope_t MyEnumClass = Cpp::GetNamed("MyEnumClass");
592+
EXPECT_TRUE(MyEnumClass);
593+
594+
std::vector<Cpp::TCppScope_t> datamembers;
595+
Cpp::GetEnumConstantDatamembers(MyEnumClass, datamembers);
596+
EXPECT_EQ(datamembers.size(), 9);
597+
EXPECT_TRUE(Cpp::IsEnumType(Cpp::GetVariableType(datamembers[0])));
598+
599+
std::vector<Cpp::TCppScope_t> datamembers2;
600+
Cpp::GetEnumConstantDatamembers(MyEnumClass, datamembers2, false);
601+
EXPECT_EQ(datamembers2.size(), 6);
602+
}

0 commit comments

Comments
 (0)