diff --git a/include/clang/Interpreter/CppInterOp.h b/include/clang/Interpreter/CppInterOp.h index 3d4f6a855..9aa7f5676 100644 --- a/include/clang/Interpreter/CppInterOp.h +++ b/include/clang/Interpreter/CppInterOp.h @@ -459,6 +459,15 @@ namespace Cpp { GetStaticDatamembers(TCppScope_t scope, std::vector& datamembers); + /// Gets all the Enum Constants declared in a Class + ///\param[in] scope - class + ///\param[out] funcs - vector of static data members + ///\param[in] include_enum_class - include enum constants from enum class + CPPINTEROP_API + void GetEnumConstantDatamembers(TCppScope_t scope, + std::vector& datamembers, + bool include_enum_class = true); + /// This is a Lookup function to be used specifically for data members. CPPINTEROP_API TCppScope_t LookupDatamember(const std::string& name, TCppScope_t parent); diff --git a/lib/Interpreter/CppInterOp.cpp b/lib/Interpreter/CppInterOp.cpp index 15a177281..4d360ac2a 100755 --- a/lib/Interpreter/CppInterOp.cpp +++ b/lib/Interpreter/CppInterOp.cpp @@ -36,6 +36,8 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/raw_os_ostream.h" +#include +#include #include #include #include @@ -1223,6 +1225,23 @@ namespace Cpp { GetClassDecls(scope, datamembers); } + void GetEnumConstantDatamembers(TCppScope_t scope, + std::vector& datamembers, + bool include_enum_class) { + std::vector EDs; + GetClassDecls(scope, EDs); + for (TCppScope_t i : EDs) { + auto* ED = static_cast(i); + + bool is_class_tagged = ED->isScopedUsingClassTag(); + if (is_class_tagged && !include_enum_class) + continue; + + std::copy(ED->enumerator_begin(), ED->enumerator_end(), + std::back_inserter(datamembers)); + } + } + TCppScope_t LookupDatamember(const std::string& name, TCppScope_t parent) { clang::DeclContext *Within = 0; if (parent) { @@ -1256,6 +1275,9 @@ namespace Cpp { return QT.getAsOpaquePtr(); } + if (auto* ECD = llvm::dyn_cast_or_null(D)) + return ECD->getType().getAsOpaquePtr(); + return 0; } diff --git a/unittests/CppInterOp/VariableReflectionTest.cpp b/unittests/CppInterOp/VariableReflectionTest.cpp index 379f5af89..4a0940848 100644 --- a/unittests/CppInterOp/VariableReflectionTest.cpp +++ b/unittests/CppInterOp/VariableReflectionTest.cpp @@ -576,3 +576,27 @@ TEST(VariableReflectionTest, StaticConstExprDatamember) { offset = Cpp::GetVariableOffset(datamembers[0]); EXPECT_EQ(2, *(int*)offset); } + +TEST(VariableReflectionTest, GetEnumConstantDatamembers) { + Cpp::CreateInterpreter(); + + Cpp::Declare(R"( + class MyEnumClass { + enum { FOUR, FIVE, SIX }; + enum A { ONE, TWO, THREE }; + enum class B { SEVEN, EIGHT, NINE }; + }; + )"); + + Cpp::TCppScope_t MyEnumClass = Cpp::GetNamed("MyEnumClass"); + EXPECT_TRUE(MyEnumClass); + + std::vector datamembers; + Cpp::GetEnumConstantDatamembers(MyEnumClass, datamembers); + EXPECT_EQ(datamembers.size(), 9); + EXPECT_TRUE(Cpp::IsEnumType(Cpp::GetVariableType(datamembers[0]))); + + std::vector datamembers2; + Cpp::GetEnumConstantDatamembers(MyEnumClass, datamembers2, false); + EXPECT_EQ(datamembers2.size(), 6); +}