Skip to content

Commit d576e30

Browse files
Gnimucvgvassilev
authored andcommitted
Improve the test coverage of the C API
1 parent f0f59f2 commit d576e30

File tree

6 files changed

+132
-18
lines changed

6 files changed

+132
-18
lines changed

lib/Interpreter/CXCppInterOp.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -326,17 +326,15 @@ void clang_Interpreter_addIncludePath(CXInterpreter I, const char* dir) {
326326
getInterpreter(I)->AddIncludePath(dir);
327327
}
328328

329+
namespace Cpp {
330+
int Declare(compat::Interpreter& interp, const char* code, bool silent);
331+
} // namespace Cpp
332+
329333
enum CXErrorCode clang_Interpreter_declare(CXInterpreter I, const char* code,
330334
bool silent) {
331335
auto* interp = getInterpreter(I);
332-
auto& diag = interp->getSema().getDiagnostics();
333-
334-
const bool is_silent_old = diag.getSuppressAllDiagnostics();
335-
336-
diag.setSuppressAllDiagnostics(silent);
337-
const auto result = interp->declare(code);
338-
diag.setSuppressAllDiagnostics(is_silent_old);
339336

337+
const auto result = Cpp::Declare(*interp, code, silent);
340338
if (result)
341339
return CXError_Failure;
342340

lib/Interpreter/CppInterOp.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -836,12 +836,17 @@ namespace Cpp {
836836
return false;
837837
}
838838

839-
TCppFunction_t GetDefaultConstructor(TCppScope_t scope) {
839+
TCppFunction_t GetDefaultConstructor(compat::Interpreter& interp,
840+
TCppScope_t scope) {
840841
if (!HasDefaultConstructor(scope))
841842
return nullptr;
842843

843844
auto *CXXRD = (clang::CXXRecordDecl*)scope;
844-
return getSema().LookupDefaultConstructor(CXXRD);
845+
return interp.getCI()->getSema().LookupDefaultConstructor(CXXRD);
846+
}
847+
848+
TCppFunction_t GetDefaultConstructor(TCppScope_t scope) {
849+
return GetDefaultConstructor(getInterp(), scope);
845850
}
846851

847852
TCppFunction_t GetDestructor(TCppScope_t scope) {
@@ -3039,9 +3044,7 @@ namespace Cpp {
30393044
};
30403045
} // namespace
30413046

3042-
int Declare(const char* code, bool silent) {
3043-
auto& I = getInterp();
3044-
3047+
int Declare(compat::Interpreter& I, const char* code, bool silent) {
30453048
if (silent) {
30463049
clangSilent diagSuppr(I.getSema().getDiagnostics());
30473050
return I.declare(code);
@@ -3050,6 +3053,10 @@ namespace Cpp {
30503053
return I.declare(code);
30513054
}
30523055

3056+
int Declare(const char* code, bool silent) {
3057+
return Declare(getInterp(), code, silent);
3058+
}
3059+
30533060
int Process(const char *code) {
30543061
return getInterp().process(code);
30553062
}
@@ -3533,7 +3540,7 @@ namespace Cpp {
35333540
if (!HasDefaultConstructor(Class))
35343541
return nullptr;
35353542

3536-
auto* const Ctor = GetDefaultConstructor(Class);
3543+
auto* const Ctor = GetDefaultConstructor(interp, Class);
35373544
if (JitCall JC = MakeFunctionCallable(&interp, Ctor)) {
35383545
if (arena) {
35393546
JC.Invoke(&arena, {}, (void*)~0); // Tell Invoke to use placement new.

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "clang/Interpreter/CppInterOp.h"
77
#include "clang/Sema/Sema.h"
88

9+
#include "clang-c/CXCppInterOp.h"
10+
911
#include "gtest/gtest.h"
1012

1113
#include <string>
@@ -105,6 +107,20 @@ TEST(FunctionReflectionTest, GetClassMethods) {
105107
std::vector<Cpp::TCppFunction_t> methods5;
106108
Cpp::GetClassMethods(nullptr, methods5);
107109
EXPECT_EQ(methods5.size(), 0);
110+
111+
// C API
112+
auto* I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
113+
auto C_API_SHIM = [&](Cpp::TCppFunction_t method) {
114+
auto Str = clang_getFunctionSignature(
115+
make_scope(static_cast<clang::Decl*>(method), I));
116+
auto Res = std::string(get_c_string(Str));
117+
dispose_string(Str);
118+
return Res;
119+
};
120+
EXPECT_EQ(C_API_SHIM(methods0[0]), "int A::f1(int a, int b)");
121+
// Clean up resources
122+
clang_Interpreter_takeInterpreterAsPtr(I);
123+
clang_Interpreter_dispose(I);
108124
}
109125

110126
TEST(FunctionReflectionTest, ConstructorInGetClassMethods) {
@@ -161,6 +177,15 @@ TEST(FunctionReflectionTest, HasDefaultConstructor) {
161177
EXPECT_TRUE(Cpp::HasDefaultConstructor(Decls[0]));
162178
EXPECT_TRUE(Cpp::HasDefaultConstructor(Decls[1]));
163179
EXPECT_FALSE(Cpp::HasDefaultConstructor(Decls[3]));
180+
181+
// C API
182+
auto* I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
183+
EXPECT_TRUE(clang_hasDefaultConstructor(make_scope(Decls[0], I)));
184+
EXPECT_TRUE(clang_hasDefaultConstructor(make_scope(Decls[1], I)));
185+
EXPECT_FALSE(clang_hasDefaultConstructor(make_scope(Decls[3], I)));
186+
// Clean up resources
187+
clang_Interpreter_takeInterpreterAsPtr(I);
188+
clang_Interpreter_dispose(I);
164189
}
165190

166191
TEST(FunctionReflectionTest, GetDestructor) {
@@ -189,6 +214,14 @@ TEST(FunctionReflectionTest, GetDestructor) {
189214
EXPECT_TRUE(DeletedDtor);
190215
EXPECT_TRUE(Cpp::IsFunctionDeleted(DeletedDtor));
191216
EXPECT_FALSE(Cpp::GetDestructor(Decls[3]));
217+
218+
// C API
219+
auto* I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
220+
EXPECT_TRUE(clang_getDestructor(make_scope(Decls[0], I)).data[0]);
221+
EXPECT_TRUE(clang_getDestructor(make_scope(Decls[1], I)).data[0]);
222+
// Clean up resources
223+
clang_Interpreter_takeInterpreterAsPtr(I);
224+
clang_Interpreter_dispose(I);
192225
}
193226

194227
TEST(FunctionReflectionTest, GetFunctionsUsingName) {
@@ -524,6 +557,17 @@ TEST(FunctionReflectionTest, IsTemplatedFunction) {
524557
EXPECT_FALSE(Cpp::IsTemplatedFunction(Decls[3]));
525558
EXPECT_FALSE(Cpp::IsTemplatedFunction(SubDeclsC1[1]));
526559
EXPECT_TRUE(Cpp::IsTemplatedFunction(SubDeclsC1[2]));
560+
561+
// C API
562+
auto* I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
563+
EXPECT_FALSE(clang_isTemplatedFunction(make_scope(Decls[0], I)));
564+
EXPECT_TRUE(clang_isTemplatedFunction(make_scope(Decls[1], I)));
565+
EXPECT_FALSE(clang_isTemplatedFunction(make_scope(Decls[3], I)));
566+
EXPECT_FALSE(clang_isTemplatedFunction(make_scope(SubDeclsC1[1], I)));
567+
EXPECT_TRUE(clang_isTemplatedFunction(make_scope(SubDeclsC1[2], I)));
568+
// Clean up resources
569+
clang_Interpreter_takeInterpreterAsPtr(I);
570+
clang_Interpreter_dispose(I);
527571
}
528572

529573
TEST(FunctionReflectionTest, ExistsFunctionTemplate) {
@@ -544,6 +588,14 @@ TEST(FunctionReflectionTest, ExistsFunctionTemplate) {
544588
EXPECT_TRUE(Cpp::ExistsFunctionTemplate("f", 0));
545589
EXPECT_TRUE(Cpp::ExistsFunctionTemplate("f", Decls[1]));
546590
EXPECT_FALSE(Cpp::ExistsFunctionTemplate("f", Decls[2]));
591+
592+
// C API
593+
auto* I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
594+
EXPECT_TRUE(clang_existsFunctionTemplate("f", make_scope(Decls[1], I)));
595+
EXPECT_FALSE(clang_existsFunctionTemplate("f", make_scope(Decls[2], I)));
596+
// Clean up resources
597+
clang_Interpreter_takeInterpreterAsPtr(I);
598+
clang_Interpreter_dispose(I);
547599
}
548600

549601
TEST(FunctionReflectionTest, InstantiateTemplateFunctionFromString) {
@@ -1119,6 +1171,17 @@ TEST(FunctionReflectionTest, JitCallAdvanced) {
11191171
EXPECT_TRUE(object) << "Failed to call the ctor.";
11201172
// Building a wrapper with a typedef decl must be possible.
11211173
Cpp::Destruct(object, Decls[1]);
1174+
1175+
// C API
1176+
auto* I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
1177+
auto S = clang_getDefaultConstructor(make_scope(Decls[0], I));
1178+
void* object_c = nullptr;
1179+
clang_invoke(S, &object_c, nullptr, 0, nullptr);
1180+
EXPECT_TRUE(object_c) << "Failed to call the ctor.";
1181+
clang_destruct(object_c, make_scope(Decls[1], I), true);
1182+
// Clean up resources
1183+
clang_Interpreter_takeInterpreterAsPtr(I);
1184+
clang_Interpreter_dispose(I);
11221185
}
11231186

11241187

@@ -1473,6 +1536,23 @@ TEST(FunctionReflectionTest, Construct) {
14731536
Cpp::Deallocate(scope, where);
14741537
output = testing::internal::GetCapturedStdout();
14751538
EXPECT_EQ(output, "Constructor Executed");
1539+
output.clear();
1540+
1541+
// C API
1542+
testing::internal::CaptureStdout();
1543+
auto* I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
1544+
auto scope_c = make_scope(static_cast<clang::Decl*>(scope), I);
1545+
auto object_c = clang_construct(scope_c, nullptr);
1546+
EXPECT_TRUE(object_c != nullptr);
1547+
output = testing::internal::GetCapturedStdout();
1548+
EXPECT_EQ(output, "Constructor Executed");
1549+
output.clear();
1550+
auto* dummy = clang_allocate(8);
1551+
EXPECT_TRUE(dummy);
1552+
clang_deallocate(dummy);
1553+
// Clean up resources
1554+
clang_Interpreter_takeInterpreterAsPtr(I);
1555+
clang_Interpreter_dispose(I);
14761556
}
14771557

14781558
TEST(FunctionReflectionTest, Destruct) {
@@ -1516,4 +1596,17 @@ TEST(FunctionReflectionTest, Destruct) {
15161596
Cpp::Deallocate(scope, object);
15171597
output = testing::internal::GetCapturedStdout();
15181598
EXPECT_EQ(output, "Destructor Executed");
1599+
1600+
// C API
1601+
testing::internal::CaptureStdout();
1602+
auto* I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
1603+
auto scope_c = make_scope(static_cast<clang::Decl*>(scope), I);
1604+
auto object_c = clang_construct(scope_c, nullptr);
1605+
clang_destruct(object_c, scope_c, true);
1606+
output = testing::internal::GetCapturedStdout();
1607+
EXPECT_EQ(output, "Destructor Executed");
1608+
output.clear();
1609+
// Clean up resources
1610+
clang_Interpreter_takeInterpreterAsPtr(I);
1611+
clang_Interpreter_dispose(I);
15191612
}

unittests/CppInterOp/InterpreterTest.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "clang/Basic/Version.h"
1515

16+
#include <clang-c/CXErrorCode.h>
1617
#include "clang-c/CXCppInterOp.h"
1718

1819
#include "llvm/ADT/SmallString.h"
@@ -85,16 +86,26 @@ TEST(InterpreterTest, Process) {
8586
#endif
8687
if (llvm::sys::RunningOnValgrind())
8788
GTEST_SKIP() << "XFAIL due to Valgrind report";
88-
Cpp::CreateInterpreter();
89+
auto* I = Cpp::CreateInterpreter();
8990
EXPECT_TRUE(Cpp::Process("") == 0);
9091
EXPECT_TRUE(Cpp::Process("int a = 12;") == 0);
9192
EXPECT_FALSE(Cpp::Process("error_here;") == 0);
9293
// Linker/JIT error.
9394
EXPECT_FALSE(Cpp::Process("int f(); int res = f();") == 0);
95+
96+
// C API
97+
auto* CXI = clang_createInterpreterFromRawPtr(I);
98+
clang_Interpreter_declare(CXI, "#include <iostream>", false);
99+
clang_Interpreter_process(CXI, "int c = 42;");
100+
auto* CXV = clang_createValue();
101+
auto Res = clang_Interpreter_evaluate(CXI, "c", CXV);
102+
EXPECT_EQ(Res, CXError_Success);
103+
clang_Value_dispose(CXV);
104+
clang_Interpreter_dispose(CXI);
94105
}
95106

96107
TEST(InterpreterTest, CreateInterpreter) {
97-
auto I = Cpp::CreateInterpreter();
108+
auto* I = Cpp::CreateInterpreter();
98109
EXPECT_TRUE(I);
99110
// Check if the default standard is c++14
100111

@@ -118,9 +129,10 @@ TEST(InterpreterTest, CreateInterpreter) {
118129

119130
#ifndef CPPINTEROP_USE_CLING
120131
// C API
121-
auto CXI = clang_createInterpreterFromRawPtr(I);
132+
auto* CXI = clang_createInterpreterFromRawPtr(I);
122133
auto CLI = clang_Interpreter_getClangInterpreter(CXI);
123134
EXPECT_TRUE(CLI);
135+
124136
auto I2 = clang_Interpreter_takeInterpreterAsPtr(CXI);
125137
EXPECT_EQ(I, I2);
126138
clang_Interpreter_dispose(CXI);

unittests/CppInterOp/ScopeReflectionTest.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
#include "llvm/Support/Valgrind.h"
1717

18+
#include "clang-c/CXCppInterOp.h"
19+
1820
#include "gtest/gtest.h"
1921

2022
#include <string>
@@ -816,7 +818,7 @@ TEST(ScopeReflectionTest, InstantiateNNTPClassTemplate) {
816818
/*type_size*/ args1.size()));
817819

818820
// C API
819-
auto I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
821+
auto* I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
820822
CXTemplateArgInfo Args1[] = {{IntTy, "5"}};
821823
auto C_API_SHIM = [&](auto Decl) {
822824
return clang_instantiateTemplate(make_scope(Decl, I), Args1, 1).data[0];

unittests/CppInterOp/TypeReflectionTest.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include "clang/Frontend/CompilerInstance.h"
66
#include "clang/Sema/Sema.h"
77

8+
#include "clang-c/CXCppInterOp.h"
9+
810
#include "gtest/gtest.h"
911

1012
#include <cstdint>
@@ -354,7 +356,7 @@ TEST(TypeReflectionTest, GetComplexType) {
354356
EXPECT_EQ(get_complex_type_as_string("double"), "_Complex double");
355357

356358
// C API
357-
auto I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
359+
auto* I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
358360
auto C_API_SHIM = [&](const std::string& element_type) {
359361
auto ElementQT = Cpp::GetType(element_type);
360362
CXQualType EQT = {CXType_Unexposed, {ElementQT, I}};

0 commit comments

Comments
 (0)