@@ -1462,7 +1462,7 @@ TEST(FunctionReflectionTest, JitCallAdvanced) {
14621462 auto * I = clang_createInterpreterFromRawPtr (Cpp::GetInterpreter ());
14631463 auto S = clang_getDefaultConstructor (make_scope (Decls[0 ], I));
14641464 void * object_c = nullptr ;
1465- clang_invoke (S, &object_c, nullptr , 0 , nullptr );
1465+ clang_invoke (S, &object_c, nullptr , 0 , 0UL , nullptr );
14661466 EXPECT_TRUE (object_c) << " Failed to call the ctor." ;
14671467 clang_destruct (object_c, make_scope (Decls[1 ], I), true );
14681468 // Clean up resources
@@ -1874,7 +1874,7 @@ TEST(FunctionReflectionTest, Construct) {
18741874 testing::internal::CaptureStdout ();
18751875 auto * I = clang_createInterpreterFromRawPtr (Cpp::GetInterpreter ());
18761876 auto scope_c = make_scope (static_cast <clang::Decl*>(scope), I);
1877- auto object_c = clang_construct (scope_c, nullptr );
1877+ auto object_c = clang_construct (scope_c, nullptr , 0UL );
18781878 EXPECT_TRUE (object_c != nullptr );
18791879 output = testing::internal::GetCapturedStdout ();
18801880 EXPECT_EQ (output, " Constructor Executed" );
@@ -1950,6 +1950,58 @@ TEST(FunctionReflectionTest, ConstructNested) {
19501950 output.clear ();
19511951}
19521952
1953+ TEST (FunctionReflectionTest, ConstructArray) {
1954+ #if defined(EMSCRIPTEN) && (CLANG_VERSION_MAJOR < 20)
1955+ GTEST_SKIP () << " Test fails for LLVM < 20 Emscripten builds" ;
1956+ #endif
1957+ if (llvm::sys::RunningOnValgrind ())
1958+ GTEST_SKIP () << " XFAIL due to Valgrind report" ;
1959+ #ifdef _WIN32
1960+ GTEST_SKIP () << " Disabled on Windows. Needs fixing." ;
1961+ #endif
1962+
1963+ Cpp::CreateInterpreter ();
1964+
1965+ Interp->declare (R"(
1966+ #include <new>
1967+ extern "C" int printf(const char*,...);
1968+ class C {
1969+ int x;
1970+ C() {
1971+ x = 42;
1972+ printf("\nConstructor Executed\n");
1973+ }
1974+ };
1975+ )" );
1976+
1977+ Cpp::TCppScope_t scope = Cpp::GetNamed (" C" );
1978+ std::string output;
1979+
1980+ size_t a = 5 ; // Construct an array of 5 objects
1981+ void * where = Cpp::Allocate (scope, a); // operator new
1982+
1983+ testing::internal::CaptureStdout ();
1984+ EXPECT_TRUE (where == Cpp::Construct (scope, where, a)); // placement new
1985+ // Check for the value of x which should be at the start of the object.
1986+ EXPECT_TRUE (*(int *)where == 42 );
1987+ // Check for the value of x in the second object
1988+ int * obj = reinterpret_cast <int *>(reinterpret_cast <char *>(where) +
1989+ Cpp::SizeOf (scope));
1990+ EXPECT_TRUE (*obj == 42 );
1991+
1992+ // Check for the value of x in the last object
1993+ obj = reinterpret_cast <int *>(reinterpret_cast <char *>(where) +
1994+ Cpp::SizeOf (scope) * 4 );
1995+ EXPECT_TRUE (*obj == 42 );
1996+ Cpp::Destruct (where, scope, /* withFree=*/ false , 5 );
1997+ Cpp::Deallocate (scope, where, 5 );
1998+ output = testing::internal::GetCapturedStdout ();
1999+ EXPECT_EQ (output,
2000+ " \n Constructor Executed\n\n Constructor Executed\n\n Constructor "
2001+ " Executed\n\n Constructor Executed\n\n Constructor Executed\n " );
2002+ output.clear ();
2003+ }
2004+
19532005TEST (FunctionReflectionTest, Destruct) {
19542006#ifdef EMSCRIPTEN
19552007 GTEST_SKIP () << " Test fails for Emscipten builds" ;
@@ -1997,7 +2049,7 @@ TEST(FunctionReflectionTest, Destruct) {
19972049 testing::internal::CaptureStdout ();
19982050 auto * I = clang_createInterpreterFromRawPtr (Cpp::GetInterpreter ());
19992051 auto scope_c = make_scope (static_cast <clang::Decl*>(scope), I);
2000- auto object_c = clang_construct (scope_c, nullptr );
2052+ auto object_c = clang_construct (scope_c, nullptr , 0UL );
20012053 clang_destruct (object_c, scope_c, true );
20022054 output = testing::internal::GetCapturedStdout ();
20032055 EXPECT_EQ (output, " Destructor Executed" );
@@ -2007,6 +2059,81 @@ TEST(FunctionReflectionTest, Destruct) {
20072059 clang_Interpreter_dispose (I);
20082060}
20092061
2062+ TEST (FunctionReflectionTest, DestructArray) {
2063+ #ifdef EMSCRIPTEN
2064+ GTEST_SKIP () << " Test fails for Emscipten builds" ;
2065+ #endif
2066+ if (llvm::sys::RunningOnValgrind ())
2067+ GTEST_SKIP () << " XFAIL due to Valgrind report" ;
2068+
2069+ #ifdef _WIN32
2070+ GTEST_SKIP () << " Disabled on Windows. Needs fixing." ;
2071+ #endif
2072+
2073+ std::vector<const char *> interpreter_args = {" -include" , " new" };
2074+ Cpp::CreateInterpreter (interpreter_args);
2075+
2076+ Interp->declare (R"(
2077+ #include <new>
2078+ extern "C" int printf(const char*,...);
2079+ class C {
2080+ int x;
2081+ C() {
2082+ x = 42;
2083+ }
2084+ ~C() {
2085+ printf("\nDestructor Executed\n");
2086+ }
2087+ };
2088+ )" );
2089+
2090+ Cpp::TCppScope_t scope = Cpp::GetNamed (" C" );
2091+ std::string output;
2092+
2093+ size_t a = 5 ; // Construct an array of 5 objects
2094+ void * where = Cpp::Allocate (scope, a); // operator new
2095+ EXPECT_TRUE (where == Cpp::Construct (scope, where, a)); // placement new
2096+
2097+ // verify the array of objects has been constructed
2098+ int * obj = reinterpret_cast <int *>(reinterpret_cast <char *>(where) +
2099+ Cpp::SizeOf (scope) * 4 );
2100+ EXPECT_TRUE (*obj == 42 );
2101+
2102+ testing::internal::CaptureStdout ();
2103+ // destruct 3 out of 5 objects
2104+ Cpp::Destruct (where, scope, false , 3 );
2105+ output = testing::internal::GetCapturedStdout ();
2106+
2107+ EXPECT_EQ (
2108+ output,
2109+ " \n Destructor Executed\n\n Destructor Executed\n\n Destructor Executed\n " );
2110+ output.clear ();
2111+ testing::internal::CaptureStdout ();
2112+
2113+ // destruct the rest
2114+ auto new_head = reinterpret_cast <void *>(reinterpret_cast <char *>(where) +
2115+ Cpp::SizeOf (scope) * 3 );
2116+ Cpp::Destruct (new_head, scope, false , 2 );
2117+
2118+ output = testing::internal::GetCapturedStdout ();
2119+ EXPECT_EQ (output, " \n Destructor Executed\n\n Destructor Executed\n " );
2120+ output.clear ();
2121+
2122+ // deallocate since we call the destructor withFree = false
2123+ Cpp::Deallocate (scope, where, 5 );
2124+
2125+ // perform the same withFree=true
2126+ where = Cpp::Allocate (scope, a);
2127+ EXPECT_TRUE (where == Cpp::Construct (scope, where, a));
2128+ testing::internal::CaptureStdout ();
2129+ // FIXME : This should work with the array of objects as well
2130+ // Cpp::Destruct(where, scope, true, 5);
2131+ Cpp::Destruct (where, scope, true );
2132+ output = testing::internal::GetCapturedStdout ();
2133+ EXPECT_EQ (output, " \n Destructor Executed\n " );
2134+ output.clear ();
2135+ }
2136+
20102137TEST (FunctionReflectionTest, UndoTest) {
20112138#ifdef _WIN32
20122139 GTEST_SKIP () << " Disabled on Windows. Needs fixing." ;
0 commit comments