@@ -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,55 @@ 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 =
1989+ reinterpret_cast <int *>(reinterpret_cast <char *>(where) + 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) + Cpp::SizeOf (scope) * 4 );
1994+ EXPECT_TRUE (*obj == 42 );
1995+ Cpp::Destruct (where, scope, /* withFree=*/ false , 5 );
1996+ Cpp::Deallocate (scope, where, 5 );
1997+ output = testing::internal::GetCapturedStdout ();
1998+ EXPECT_EQ (output, " \n Constructor Executed\n\n Constructor Executed\n\n Constructor Executed\n\n Constructor Executed\n\n Constructor Executed\n " );
1999+ output.clear ();
2000+ }
2001+
19532002TEST (FunctionReflectionTest, Destruct) {
19542003#ifdef EMSCRIPTEN
19552004 GTEST_SKIP () << " Test fails for Emscipten builds" ;
@@ -1997,7 +2046,7 @@ TEST(FunctionReflectionTest, Destruct) {
19972046 testing::internal::CaptureStdout ();
19982047 auto * I = clang_createInterpreterFromRawPtr (Cpp::GetInterpreter ());
19992048 auto scope_c = make_scope (static_cast <clang::Decl*>(scope), I);
2000- auto object_c = clang_construct (scope_c, nullptr );
2049+ auto object_c = clang_construct (scope_c, nullptr , 0UL );
20012050 clang_destruct (object_c, scope_c, true );
20022051 output = testing::internal::GetCapturedStdout ();
20032052 EXPECT_EQ (output, " Destructor Executed" );
@@ -2007,6 +2056,77 @@ TEST(FunctionReflectionTest, Destruct) {
20072056 clang_Interpreter_dispose (I);
20082057}
20092058
2059+ TEST (FunctionReflectionTest, DestructArray) {
2060+ #ifdef EMSCRIPTEN
2061+ GTEST_SKIP () << " Test fails for Emscipten builds" ;
2062+ #endif
2063+ if (llvm::sys::RunningOnValgrind ())
2064+ GTEST_SKIP () << " XFAIL due to Valgrind report" ;
2065+
2066+ #ifdef _WIN32
2067+ GTEST_SKIP () << " Disabled on Windows. Needs fixing." ;
2068+ #endif
2069+
2070+ std::vector<const char *> interpreter_args = {" -include" , " new" };
2071+ Cpp::CreateInterpreter (interpreter_args);
2072+
2073+ Interp->declare (R"(
2074+ #include <new>
2075+ extern "C" int printf(const char*,...);
2076+ class C {
2077+ int x;
2078+ C() {
2079+ x = 42;
2080+ }
2081+ ~C() {
2082+ printf("\nDestructor Executed\n");
2083+ }
2084+ };
2085+ )" );
2086+
2087+ Cpp::TCppScope_t scope = Cpp::GetNamed (" C" );
2088+ std::string output;
2089+
2090+ size_t a = 5 ; // Construct an array of 5 objects
2091+ void * where = Cpp::Allocate (scope, a); // operator new
2092+ EXPECT_TRUE (where == Cpp::Construct (scope, where, a)); // placement new
2093+
2094+ // verify the array of objects has been constructed
2095+ int *obj = reinterpret_cast <int *>(reinterpret_cast <char *>(where) + Cpp::SizeOf (scope) * 4 );
2096+ EXPECT_TRUE (*obj == 42 );
2097+
2098+ testing::internal::CaptureStdout ();
2099+ // destruct 3 out of 5 objects
2100+ Cpp::Destruct (where, scope, false , 3 );
2101+ output = testing::internal::GetCapturedStdout ();
2102+
2103+ EXPECT_EQ (output, " \n Destructor Executed\n\n Destructor Executed\n\n Destructor Executed\n " );
2104+ output.clear ();
2105+ testing::internal::CaptureStdout ();
2106+
2107+ // destruct the rest
2108+ auto new_head = reinterpret_cast <void *>(reinterpret_cast <char *>(where) + Cpp::SizeOf (scope) * 3 );
2109+ Cpp::Destruct (new_head, scope, false , 2 );
2110+
2111+ output = testing::internal::GetCapturedStdout ();
2112+ EXPECT_EQ (output, " \n Destructor Executed\n\n Destructor Executed\n " );
2113+ output.clear ();
2114+
2115+ // deallocate since we call the destructor withFree = false
2116+ Cpp::Deallocate (scope, where, 5 );
2117+
2118+ // perform the same withFree=true
2119+ where = Cpp::Allocate (scope, a);
2120+ EXPECT_TRUE (where == Cpp::Construct (scope, where, a));
2121+ testing::internal::CaptureStdout ();
2122+ // FIXME : This should work with the array of objects as well
2123+ // Cpp::Destruct(where, scope, true, 5);
2124+ Cpp::Destruct (where, scope, true );
2125+ output = testing::internal::GetCapturedStdout ();
2126+ EXPECT_EQ (output, " \n Destructor Executed\n " );
2127+ output.clear ();
2128+ }
2129+
20102130TEST (FunctionReflectionTest, UndoTest) {
20112131#ifdef _WIN32
20122132 GTEST_SKIP () << " Disabled on Windows. Needs fixing." ;
0 commit comments