diff --git a/include/clang/Interpreter/CppInterOp.h b/include/clang/Interpreter/CppInterOp.h index 96677dbe1..c7c3d51ee 100644 --- a/include/clang/Interpreter/CppInterOp.h +++ b/include/clang/Interpreter/CppInterOp.h @@ -504,6 +504,18 @@ namespace Cpp { /// Checks if the provided parameter is a Plain Old Data Type (POD). CPPINTEROP_API bool IsPODType(TCppType_t type); + /// Checks if type is a pointer + CPPINTEROP_API bool IsPointerType(TCppType_t type); + + /// Get the underlying pointee type + CPPINTEROP_API TCppType_t GetPointeeType(TCppType_t type); + + /// Checks if type is a reference + CPPINTEROP_API bool IsReferenceType(TCppType_t type); + + /// Get the type that the reference refers to + CPPINTEROP_API TCppType_t GetNonReferenceType(TCppType_t type); + /// Gets the pure, Underlying Type (as opposed to the Using Type). CPPINTEROP_API TCppType_t GetUnderlyingType(TCppType_t type); diff --git a/lib/Interpreter/CppInterOp.cpp b/lib/Interpreter/CppInterOp.cpp index 7cdfcfec3..51f26a2b3 100755 --- a/lib/Interpreter/CppInterOp.cpp +++ b/lib/Interpreter/CppInterOp.cpp @@ -1493,6 +1493,30 @@ namespace Cpp { return QT.isPODType(getASTContext()); } + bool IsPointerType(TCppType_t type) { + QualType QT = QualType::getFromOpaquePtr(type); + return QT->isPointerType(); + } + + TCppType_t GetPointeeType(TCppType_t type) { + if (!IsPointerType(type)) + return nullptr; + QualType QT = QualType::getFromOpaquePtr(type); + return QT->getPointeeType().getAsOpaquePtr(); + } + + bool IsReferenceType(TCppType_t type) { + QualType QT = QualType::getFromOpaquePtr(type); + return QT->isReferenceType(); + } + + TCppType_t GetNonReferenceType(TCppType_t type) { + if (!IsReferenceType(type)) + return nullptr; + QualType QT = QualType::getFromOpaquePtr(type); + return QT.getNonReferenceType().getAsOpaquePtr(); + } + TCppType_t GetUnderlyingType(TCppType_t type) { QualType QT = QualType::getFromOpaquePtr(type); diff --git a/unittests/CppInterOp/VariableReflectionTest.cpp b/unittests/CppInterOp/VariableReflectionTest.cpp index 4a0940848..8b76e7f5c 100644 --- a/unittests/CppInterOp/VariableReflectionTest.cpp +++ b/unittests/CppInterOp/VariableReflectionTest.cpp @@ -600,3 +600,67 @@ TEST(VariableReflectionTest, GetEnumConstantDatamembers) { Cpp::GetEnumConstantDatamembers(MyEnumClass, datamembers2, false); EXPECT_EQ(datamembers2.size(), 6); } + +TEST(VariableReflectionTest, Is_Get_Pointer) { + Cpp::CreateInterpreter(); + std::vector Decls; + std::string code = R"( + class A {}; + int a; + int *b; + double c; + double *d; + A e; + A *f; + )"; + + GetAllTopLevelDecls(code, Decls); + + EXPECT_FALSE(Cpp::IsPointerType(Cpp::GetVariableType(Decls[1]))); + EXPECT_TRUE(Cpp::IsPointerType(Cpp::GetVariableType(Decls[2]))); + EXPECT_FALSE(Cpp::IsPointerType(Cpp::GetVariableType(Decls[3]))); + EXPECT_TRUE(Cpp::IsPointerType(Cpp::GetVariableType(Decls[4]))); + EXPECT_FALSE(Cpp::IsPointerType(Cpp::GetVariableType(Decls[5]))); + EXPECT_TRUE(Cpp::IsPointerType(Cpp::GetVariableType(Decls[6]))); + + EXPECT_EQ(Cpp::GetPointeeType(Cpp::GetVariableType(Decls[2])), + Cpp::GetVariableType(Decls[1])); + EXPECT_EQ(Cpp::GetPointeeType(Cpp::GetVariableType(Decls[4])), + Cpp::GetVariableType(Decls[3])); + EXPECT_EQ(Cpp::GetPointeeType(Cpp::GetVariableType(Decls[6])), + Cpp::GetVariableType(Decls[5])); + + EXPECT_FALSE(Cpp::GetPointeeType(Cpp::GetVariableType(Decls[5]))); +} + +TEST(VariableReflectionTest, Is_Get_Reference) { + Cpp::CreateInterpreter(); + std::vector Decls; + std::string code = R"( + class A {}; + int a; + int &b = a; + double c; + double &d = c; + A e; + A &f = e; + )"; + + GetAllTopLevelDecls(code, Decls); + + EXPECT_FALSE(Cpp::IsReferenceType(Cpp::GetVariableType(Decls[1]))); + EXPECT_TRUE(Cpp::IsReferenceType(Cpp::GetVariableType(Decls[2]))); + EXPECT_FALSE(Cpp::IsReferenceType(Cpp::GetVariableType(Decls[3]))); + EXPECT_TRUE(Cpp::IsReferenceType(Cpp::GetVariableType(Decls[4]))); + EXPECT_FALSE(Cpp::IsReferenceType(Cpp::GetVariableType(Decls[5]))); + EXPECT_TRUE(Cpp::IsReferenceType(Cpp::GetVariableType(Decls[6]))); + + EXPECT_EQ(Cpp::GetNonReferenceType(Cpp::GetVariableType(Decls[2])), + Cpp::GetVariableType(Decls[1])); + EXPECT_EQ(Cpp::GetNonReferenceType(Cpp::GetVariableType(Decls[4])), + Cpp::GetVariableType(Decls[3])); + EXPECT_EQ(Cpp::GetNonReferenceType(Cpp::GetVariableType(Decls[6])), + Cpp::GetVariableType(Decls[5])); + + EXPECT_FALSE(Cpp::GetNonReferenceType(Cpp::GetVariableType(Decls[5]))); +}