diff --git a/lib/Interpreter/CppInterOp.cpp b/lib/Interpreter/CppInterOp.cpp index 417290c3f..e25ee9a2a 100644 --- a/lib/Interpreter/CppInterOp.cpp +++ b/lib/Interpreter/CppInterOp.cpp @@ -1212,12 +1212,20 @@ namespace Cpp { return 0; } - TCppType_t GetVariableType(TCppScope_t var) - { - auto D = (Decl *) var; + TCppType_t GetVariableType(TCppScope_t var) { + auto* D = static_cast(var); if (auto DD = llvm::dyn_cast_or_null(D)) { - return DD->getType().getAsOpaquePtr(); + QualType QT = DD->getType(); + + // Check if the type is a typedef type + if (QT->isTypedefNameType()) { + return QT.getAsOpaquePtr(); + } + + // Else, return the canonical type + QT = QT.getCanonicalType(); + return QT.getAsOpaquePtr(); } return 0; diff --git a/unittests/CppInterOp/VariableReflectionTest.cpp b/unittests/CppInterOp/VariableReflectionTest.cpp index e913f38b8..379f5af89 100644 --- a/unittests/CppInterOp/VariableReflectionTest.cpp +++ b/unittests/CppInterOp/VariableReflectionTest.cpp @@ -6,6 +6,7 @@ #include "clang/Sema/Sema.h" #include "gtest/gtest.h" +#include #include @@ -159,6 +160,39 @@ TEST(VariableReflectionTest, DatamembersWithAnonymousStructOrUnion) { #endif } +TEST(VariableReflectionTest, GetTypeAsString) { + if (llvm::sys::RunningOnValgrind()) + GTEST_SKIP() << "XFAIL due to Valgrind report"; + + std::string code = R"( + namespace my_namespace { + + struct Container { + int value; + }; + + struct Wrapper { + Container item; + }; + + } + )"; + + Cpp::CreateInterpreter(); + EXPECT_EQ(Cpp::Declare(code.c_str()), 0); + + Cpp::TCppScope_t wrapper = + Cpp::GetScopeFromCompleteName("my_namespace::Wrapper"); + EXPECT_TRUE(wrapper); + + std::vector datamembers; + Cpp::GetDatamembers(wrapper, datamembers); + EXPECT_EQ(datamembers.size(), 1); + + EXPECT_EQ(Cpp::GetTypeAsString(Cpp::GetVariableType(datamembers[0])), + "my_namespace::Container"); +} + TEST(VariableReflectionTest, LookupDatamember) { std::vector Decls; std::string code = R"(