From a44749fdcb6ed25098821ca88a0ccbc9bfb04e23 Mon Sep 17 00:00:00 2001 From: Smit1603 Date: Tue, 24 Oct 2023 12:52:49 +0530 Subject: [PATCH] Adding edge tests for API's --- include/clang/Interpreter/CppInterOp.h | 2 +- lib/Interpreter/CppInterOp.cpp | 15 ++++---- .../CppInterOp/FunctionReflectionTest.cpp | 38 +++++++++++++++++++ unittests/CppInterOp/ScopeReflectionTest.cpp | 20 +++++++++- unittests/CppInterOp/TypeReflectionTest.cpp | 3 ++ .../CppInterOp/VariableReflectionTest.cpp | 7 ++++ 6 files changed, 75 insertions(+), 10 deletions(-) diff --git a/include/clang/Interpreter/CppInterOp.h b/include/clang/Interpreter/CppInterOp.h index 94f6ce861..e870fb3ac 100644 --- a/include/clang/Interpreter/CppInterOp.h +++ b/include/clang/Interpreter/CppInterOp.h @@ -338,7 +338,7 @@ namespace Cpp { bool IsDestructor(TCppConstFunction_t method); /// Checks if the provided parameter is a 'Static' method. - bool IsStaticMethod(TCppFunction_t method); + bool IsStaticMethod(TCppConstFunction_t method); /// Gets the address of the function to be able to call it. TCppFuncAddr_t GetFunctionAddress(TCppFunction_t method); diff --git a/lib/Interpreter/CppInterOp.cpp b/lib/Interpreter/CppInterOp.cpp index a43b14a14..f4fc22c6a 100644 --- a/lib/Interpreter/CppInterOp.cpp +++ b/lib/Interpreter/CppInterOp.cpp @@ -80,7 +80,7 @@ namespace Cpp { Valid &= (bool)args.m_Args; } if (!Cpp::IsConstructor(m_FD) && !Cpp::IsDestructor(m_FD) && - Cpp::IsMethod(m_FD)) { + Cpp::IsMethod(m_FD) && !Cpp::IsStaticMethod(m_FD)) { assert(self && "Must pass the pointer to object"); Valid &= (bool)self; } @@ -406,6 +406,10 @@ namespace Cpp { auto &C = getSema().getASTContext(); auto *D = (Decl *) klass; + if (llvm::isa_and_nonnull(D)) { + return ""; + } + if (auto *ND = llvm::dyn_cast_or_null(D)) { if (auto *TD = llvm::dyn_cast(ND)) { std::string type_name; @@ -422,10 +426,6 @@ namespace Cpp { return ND->getNameAsString(); } - if (llvm::isa_and_nonnull(D)) { - return ""; - } - return ""; } @@ -970,9 +970,8 @@ namespace Cpp { return llvm::isa_and_nonnull(D); } - bool IsStaticMethod(TCppFunction_t method) - { - auto *D = (Decl *) method; + bool IsStaticMethod(TCppConstFunction_t method) { + auto* D = (const Decl*)method; if (auto *CXXMD = llvm::dyn_cast_or_null(D)) { return CXXMD->isStatic(); } diff --git a/unittests/CppInterOp/FunctionReflectionTest.cpp b/unittests/CppInterOp/FunctionReflectionTest.cpp index 7eebe8f5f..d15cb1c02 100644 --- a/unittests/CppInterOp/FunctionReflectionTest.cpp +++ b/unittests/CppInterOp/FunctionReflectionTest.cpp @@ -375,6 +375,8 @@ TEST(FunctionReflectionTest, IsTemplatedFunction) { template void f2(T a) {} }; + + class ABC {}; )"; GetAllTopLevelDecls(code, Decls); @@ -382,6 +384,7 @@ TEST(FunctionReflectionTest, IsTemplatedFunction) { EXPECT_FALSE(Cpp::IsTemplatedFunction(Decls[0])); EXPECT_TRUE(Cpp::IsTemplatedFunction(Decls[1])); + EXPECT_FALSE(Cpp::IsTemplatedFunction(Decls[3])); EXPECT_FALSE(Cpp::IsTemplatedFunction(SubDeclsC1[1])); EXPECT_TRUE(Cpp::IsTemplatedFunction(SubDeclsC1[2])); } @@ -396,11 +399,14 @@ TEST(FunctionReflectionTest, ExistsFunctionTemplate) { template void f(T a) {} }; + + void f(char ch) {} )"; GetAllTopLevelDecls(code, Decls); EXPECT_TRUE(Cpp::ExistsFunctionTemplate("f", 0)); EXPECT_TRUE(Cpp::ExistsFunctionTemplate("f", Decls[1])); + EXPECT_FALSE(Cpp::ExistsFunctionTemplate("f", Decls[2])); } TEST(FunctionReflectionTest, IsPublicMethod) { @@ -415,6 +421,7 @@ TEST(FunctionReflectionTest, IsPublicMethod) { void pri_f() {} protected: void pro_f() {} + int a; }; )"; @@ -426,6 +433,7 @@ TEST(FunctionReflectionTest, IsPublicMethod) { EXPECT_TRUE(Cpp::IsPublicMethod(SubDecls[4])); EXPECT_FALSE(Cpp::IsPublicMethod(SubDecls[6])); EXPECT_FALSE(Cpp::IsPublicMethod(SubDecls[8])); + EXPECT_FALSE(Cpp::IsPublicMethod(SubDecls[9])); } TEST(FunctionReflectionTest, IsProtectedMethod) { @@ -540,6 +548,7 @@ TEST(FunctionReflectionTest, IsStaticMethod) { GetAllTopLevelDecls(code, Decls); GetAllSubDecls(Decls[0], SubDecls); + EXPECT_FALSE(Cpp::IsStaticMethod(Decls[0])); EXPECT_FALSE(Cpp::IsStaticMethod(SubDecls[1])); EXPECT_TRUE(Cpp::IsStaticMethod(SubDecls[2])); } @@ -584,6 +593,7 @@ TEST(FunctionReflectionTest, IsVirtualMethod) { EXPECT_TRUE(Cpp::IsVirtualMethod(SubDecls[2])); EXPECT_EQ(Cpp::GetName(SubDecls[3]), "y"); EXPECT_FALSE(Cpp::IsVirtualMethod(SubDecls[3])); // y() + EXPECT_FALSE(Cpp::IsVirtualMethod(Decls[0])); } #ifdef __APPLE__ @@ -695,6 +705,34 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) { FCI_Dtor.Invoke(object); output = testing::internal::GetCapturedStdout(); EXPECT_EQ(output, "Dtor Called\n"); + + std::vector Decls1; + std::string code1 = R"( + template + struct S { + + static T Add(T a, T b) { return a + b; } + + }; + )"; + + GetAllTopLevelDecls(code1, Decls1); + ASTContext& C = Interp->getCI()->getASTContext(); + + std::vector argument = {C.IntTy.getAsOpaquePtr()}; + auto Instance1 = Cpp::InstantiateClassTemplate(Decls1[0], argument.data(), + /*type_size*/ argument.size()); + EXPECT_TRUE(isa((Decl*)Instance1)); + auto* CTSD1 = static_cast(Instance1); + auto* Add_D = Cpp::GetNamed("Add",CTSD1); + Cpp::JitCall FCI_Add = Cpp::MakeFunctionCallable(Add_D); + EXPECT_TRUE(FCI_Add.getKind() == Cpp::JitCall::kGenericCall); + + int a = 5, b = 10, result; + void* args[2] = {(void*)&a, (void*)&b}; + + FCI_Add.Invoke(&result, {args, /*args_size=*/2}); + EXPECT_EQ(result, a + b); } TEST(FunctionReflectionTest, IsConstMethod) { diff --git a/unittests/CppInterOp/ScopeReflectionTest.cpp b/unittests/CppInterOp/ScopeReflectionTest.cpp index c2b63469f..af88724d5 100644 --- a/unittests/CppInterOp/ScopeReflectionTest.cpp +++ b/unittests/CppInterOp/ScopeReflectionTest.cpp @@ -248,6 +248,7 @@ TEST(ScopeReflectionTest, GetName) { EXPECT_EQ(Cpp::GetName(Decls[5]), "U"); EXPECT_EQ(Cpp::GetName(Decls[6]), "Size4"); EXPECT_EQ(Cpp::GetName(Decls[7]), "Size16"); + EXPECT_EQ(Cpp::GetName(nullptr), ""); } TEST(ScopeReflectionTest, GetCompleteName) { @@ -282,6 +283,7 @@ TEST(ScopeReflectionTest, GetCompleteName) { Cpp::GetVariableType( Decls[9]))), "A"); EXPECT_EQ(Cpp::GetCompleteName(Decls[10]), "(unnamed)"); + EXPECT_EQ(Cpp::GetCompleteName(nullptr), ""); } TEST(ScopeReflectionTest, GetQualifiedName) { @@ -330,7 +332,7 @@ TEST(ScopeReflectionTest, GetQualifiedCompleteName) { } TEST(ScopeReflectionTest, GetUsingNamespaces) { - std::vector Decls; + std::vector Decls, Decls1; std::string code = R"( namespace abc { @@ -351,6 +353,15 @@ TEST(ScopeReflectionTest, GetUsingNamespaces) { //EXPECT_EQ(Cpp::GetName(usingNamespaces[0]), "runtime"); EXPECT_EQ(Cpp::GetName(usingNamespaces[usingNamespaces.size()-2]), "std"); EXPECT_EQ(Cpp::GetName(usingNamespaces[usingNamespaces.size()-1]), "abc"); + + std::string code1 = R"( + int x; + )"; + + GetAllTopLevelDecls(code1, Decls1); + std::vector usingNamespaces1; + usingNamespaces1 = Cpp::GetUsingNamespaces(Decls1[0]); + EXPECT_EQ(usingNamespaces1.size(), 0); } TEST(ScopeReflectionTest, GetGlobalScope) { @@ -394,11 +405,13 @@ TEST(ScopeReflectionTest, GetScope) { Cpp::TCppScope_t ns_N = Cpp::GetScope("N", 0); Cpp::TCppScope_t cl_C = Cpp::GetScope("C", ns_N); Cpp::TCppScope_t td_T = Cpp::GetScope("T", 0); + Cpp::TCppScope_t non_existent = Cpp::GetScope("sum", 0); EXPECT_EQ(Cpp::GetQualifiedName(tu), ""); EXPECT_EQ(Cpp::GetQualifiedName(ns_N), "N"); EXPECT_EQ(Cpp::GetQualifiedName(cl_C), "N::C"); EXPECT_EQ(Cpp::GetQualifiedName(td_T), "T"); + EXPECT_EQ(Cpp::GetQualifiedName(non_existent), ""); } TEST(ScopeReflectionTest, GetScopefromCompleteName) { @@ -513,6 +526,8 @@ TEST(ScopeReflectionTest, GetScopeFromType) { N::T t; N::E e; + + N::C myFunc(); )"; GetAllTopLevelDecls(code, Decls); @@ -521,6 +536,7 @@ TEST(ScopeReflectionTest, GetScopeFromType) { QualType QT3 = llvm::dyn_cast(Decls[3])->getType(); QualType QT4 = llvm::dyn_cast(Decls[4])->getType(); QualType QT5 = llvm::dyn_cast(Decls[5])->getType(); + QualType QT6 = llvm::dyn_cast(Decls[6])->getReturnType(); EXPECT_EQ(Cpp::GetQualifiedName(Cpp::GetScopeFromType(QT1.getAsOpaquePtr())), "N::C"); EXPECT_EQ(Cpp::GetQualifiedName(Cpp::GetScopeFromType(QT2.getAsOpaquePtr())), @@ -531,6 +547,8 @@ TEST(ScopeReflectionTest, GetScopeFromType) { "N::C"); EXPECT_EQ(Cpp::GetQualifiedName(Cpp::GetScopeFromType(QT5.getAsOpaquePtr())), "N::E"); + EXPECT_EQ(Cpp::GetQualifiedName(Cpp::GetScopeFromType(QT6.getAsOpaquePtr())), + "N::C"); } TEST(ScopeReflectionTest, GetNumBases) { diff --git a/unittests/CppInterOp/TypeReflectionTest.cpp b/unittests/CppInterOp/TypeReflectionTest.cpp index 80687214f..48c863e6f 100644 --- a/unittests/CppInterOp/TypeReflectionTest.cpp +++ b/unittests/CppInterOp/TypeReflectionTest.cpp @@ -357,12 +357,15 @@ TEST(TypeReflectionTest, GetTypeFromScope) { std::string code = R"( class C {}; struct S {}; + int a = 10; )"; GetAllTopLevelDecls(code, Decls); EXPECT_EQ(Cpp::GetTypeAsString(Cpp::GetTypeFromScope(Decls[0])), "C"); EXPECT_EQ(Cpp::GetTypeAsString(Cpp::GetTypeFromScope(Decls[1])), "S"); + EXPECT_EQ(Cpp::GetTypeAsString(Cpp::GetTypeFromScope(Decls[2])), "int"); + EXPECT_EQ(Cpp::GetTypeAsString(Cpp::GetTypeFromScope(nullptr)), "NULL TYPE"); } TEST(TypeReflectionTest, IsTypeDerivedFrom) { diff --git a/unittests/CppInterOp/VariableReflectionTest.cpp b/unittests/CppInterOp/VariableReflectionTest.cpp index c5a346d6d..700ac7a45 100644 --- a/unittests/CppInterOp/VariableReflectionTest.cpp +++ b/unittests/CppInterOp/VariableReflectionTest.cpp @@ -25,15 +25,18 @@ TEST(VariableReflectionTest, GetDatamembers) { int e; static int f; }; + void sum(int,int); )"; GetAllTopLevelDecls(code, Decls); auto datamembers = Cpp::GetDatamembers(Decls[0]); + auto datamembers1 = Cpp::GetDatamembers(Decls[1]); EXPECT_EQ(Cpp::GetQualifiedName(datamembers[0]), "C::a"); EXPECT_EQ(Cpp::GetQualifiedName(datamembers[1]), "C::c"); EXPECT_EQ(Cpp::GetQualifiedName(datamembers[2]), "C::e"); EXPECT_EQ(datamembers.size(), 3); + EXPECT_EQ(datamembers1.size(), 0); } TEST(VariableReflectionTest, LookupDatamember) { @@ -57,6 +60,7 @@ TEST(VariableReflectionTest, LookupDatamember) { EXPECT_EQ(Cpp::GetQualifiedName(Cpp::LookupDatamember("a", Decls[0])), "C::a"); EXPECT_EQ(Cpp::GetQualifiedName(Cpp::LookupDatamember("c", Decls[0])), "C::c"); EXPECT_EQ(Cpp::GetQualifiedName(Cpp::LookupDatamember("e", Decls[0])), "C::e"); + EXPECT_EQ(Cpp::GetQualifiedName(Cpp::LookupDatamember("k", Decls[0])), ""); } TEST(VariableReflectionTest, GetVariableType) { @@ -138,6 +142,7 @@ TEST(VariableReflectionTest, IsPublicVariable) { int b; protected: int c; + int sum(int,int); }; )"; @@ -147,6 +152,7 @@ TEST(VariableReflectionTest, IsPublicVariable) { EXPECT_TRUE(Cpp::IsPublicVariable(SubDecls[2])); EXPECT_FALSE(Cpp::IsPublicVariable(SubDecls[4])); EXPECT_FALSE(Cpp::IsPublicVariable(SubDecls[6])); + EXPECT_FALSE(Cpp::IsPublicVariable(SubDecls[7])); } TEST(VariableReflectionTest, IsProtectedVariable) { @@ -219,6 +225,7 @@ TEST(VariableReflectionTest, IsConstVariable) { GetAllTopLevelDecls(code, Decls); GetAllSubDecls(Decls[0], SubDecls); + EXPECT_FALSE(Cpp::IsConstVariable(Decls[0])); EXPECT_FALSE(Cpp::IsConstVariable(SubDecls[1])); EXPECT_TRUE(Cpp::IsConstVariable(SubDecls[2])); }