@@ -1959,6 +1959,58 @@ TEST(FunctionReflectionTest, ConstructNested) {
1959
1959
output.clear ();
1960
1960
}
1961
1961
1962
+ TEST (FunctionReflectionTest, ConstructArray) {
1963
+ #if defined(EMSCRIPTEN) && (CLANG_VERSION_MAJOR < 20)
1964
+ GTEST_SKIP () << " Test fails for LLVM < 20 Emscripten builds" ;
1965
+ #endif
1966
+ if (llvm::sys::RunningOnValgrind ())
1967
+ GTEST_SKIP () << " XFAIL due to Valgrind report" ;
1968
+ #ifdef _WIN32
1969
+ GTEST_SKIP () << " Disabled on Windows. Needs fixing." ;
1970
+ #endif
1971
+
1972
+ Cpp::CreateInterpreter ();
1973
+
1974
+ Interp->declare (R"(
1975
+ #include <new>
1976
+ extern "C" int printf(const char*,...);
1977
+ class C {
1978
+ int x;
1979
+ C() {
1980
+ x = 42;
1981
+ printf("\nConstructor Executed\n");
1982
+ }
1983
+ };
1984
+ )" );
1985
+
1986
+ Cpp::TCppScope_t scope = Cpp::GetNamed (" C" );
1987
+ std::string output;
1988
+
1989
+ size_t a = 5 ; // Construct an array of 5 objects
1990
+ void * where = Cpp::Allocate (scope, a); // operator new
1991
+
1992
+ testing::internal::CaptureStdout ();
1993
+ EXPECT_TRUE (where == Cpp::Construct (scope, where, a)); // placement new
1994
+ // Check for the value of x which should be at the start of the object.
1995
+ EXPECT_TRUE (*(int *)where == 42 );
1996
+ // Check for the value of x in the second object
1997
+ int * obj = reinterpret_cast <int *>(reinterpret_cast <char *>(where) +
1998
+ Cpp::SizeOf (scope));
1999
+ EXPECT_TRUE (*obj == 42 );
2000
+
2001
+ // Check for the value of x in the last object
2002
+ obj = reinterpret_cast <int *>(reinterpret_cast <char *>(where) +
2003
+ Cpp::SizeOf (scope) * 4 );
2004
+ EXPECT_TRUE (*obj == 42 );
2005
+ Cpp::Destruct (where, scope, /* withFree=*/ false , 5 );
2006
+ Cpp::Deallocate (scope, where, 5 );
2007
+ output = testing::internal::GetCapturedStdout ();
2008
+ EXPECT_EQ (output,
2009
+ " \n Constructor Executed\n\n Constructor Executed\n\n Constructor "
2010
+ " Executed\n\n Constructor Executed\n\n Constructor Executed\n " );
2011
+ output.clear ();
2012
+ }
2013
+
1962
2014
TEST (FunctionReflectionTest, Destruct) {
1963
2015
#ifdef EMSCRIPTEN
1964
2016
GTEST_SKIP () << " Test fails for Emscipten builds" ;
@@ -2016,6 +2068,82 @@ TEST(FunctionReflectionTest, Destruct) {
2016
2068
clang_Interpreter_dispose (I);
2017
2069
}
2018
2070
2071
+ TEST (FunctionReflectionTest, DestructArray) {
2072
+ #ifdef EMSCRIPTEN
2073
+ GTEST_SKIP () << " Test fails for Emscipten builds" ;
2074
+ #endif
2075
+ if (llvm::sys::RunningOnValgrind ())
2076
+ GTEST_SKIP () << " XFAIL due to Valgrind report" ;
2077
+
2078
+ #ifdef _WIN32
2079
+ GTEST_SKIP () << " Disabled on Windows. Needs fixing." ;
2080
+ #endif
2081
+
2082
+ std::vector<const char *> interpreter_args = {" -include" , " new" };
2083
+ Cpp::CreateInterpreter (interpreter_args);
2084
+
2085
+ Interp->declare (R"(
2086
+ #include <new>
2087
+ extern "C" int printf(const char*,...);
2088
+ class C {
2089
+ int x;
2090
+ C() {
2091
+ printf("\nCtor Executed\n");
2092
+ x = 42;
2093
+ }
2094
+ ~C() {
2095
+ printf("\nDestructor Executed\n");
2096
+ }
2097
+ };
2098
+ )" );
2099
+
2100
+ Cpp::TCppScope_t scope = Cpp::GetNamed (" C" );
2101
+ std::string output;
2102
+
2103
+ size_t a = 5 ; // Construct an array of 5 objects
2104
+ void * where = Cpp::Allocate (scope, a); // operator new
2105
+ EXPECT_TRUE (where == Cpp::Construct (scope, where, a)); // placement new
2106
+
2107
+ // verify the array of objects has been constructed
2108
+ int * obj = reinterpret_cast <int *>(reinterpret_cast <char *>(where) +
2109
+ Cpp::SizeOf (scope) * 4 );
2110
+ EXPECT_TRUE (*obj == 42 );
2111
+
2112
+ testing::internal::CaptureStdout ();
2113
+ // destruct 3 out of 5 objects
2114
+ Cpp::Destruct (where, scope, false , 3 );
2115
+ output = testing::internal::GetCapturedStdout ();
2116
+
2117
+ EXPECT_EQ (
2118
+ output,
2119
+ " \n Destructor Executed\n\n Destructor Executed\n\n Destructor Executed\n " );
2120
+ output.clear ();
2121
+ testing::internal::CaptureStdout ();
2122
+
2123
+ // destruct the rest
2124
+ auto new_head = reinterpret_cast <void *>(reinterpret_cast <char *>(where) +
2125
+ Cpp::SizeOf (scope) * 3 );
2126
+ Cpp::Destruct (new_head, scope, false , 2 );
2127
+
2128
+ output = testing::internal::GetCapturedStdout ();
2129
+ EXPECT_EQ (output, " \n Destructor Executed\n\n Destructor Executed\n " );
2130
+ output.clear ();
2131
+
2132
+ // deallocate since we call the destructor withFree = false
2133
+ Cpp::Deallocate (scope, where, 5 );
2134
+
2135
+ // perform the same withFree=true
2136
+ where = Cpp::Allocate (scope, a);
2137
+ EXPECT_TRUE (where == Cpp::Construct (scope, where, a));
2138
+ testing::internal::CaptureStdout ();
2139
+ // FIXME : This should work with the array of objects as well
2140
+ // Cpp::Destruct(where, scope, true, 5);
2141
+ Cpp::Destruct (where, scope, true );
2142
+ output = testing::internal::GetCapturedStdout ();
2143
+ EXPECT_EQ (output, " \n Destructor Executed\n " );
2144
+ output.clear ();
2145
+ }
2146
+
2019
2147
TEST (FunctionReflectionTest, UndoTest) {
2020
2148
#ifdef _WIN32
2021
2149
GTEST_SKIP () << " Disabled on Windows. Needs fixing." ;
0 commit comments