1717#include  " clang-c/CXCppInterOp.h" 
1818
1919#include  " llvm/ADT/SmallString.h" 
20+ #include  " llvm/Support/FileSystem.h" 
2021#include  " llvm/Support/Path.h" 
21- #include  < llvm/Support/FileSystem.h > 
22+ #include  " llvm/Support/raw_ostream.h " 
2223
2324#include  < gmock/gmock.h> 
2425#include  " gtest/gtest.h" 
2526
2627#include  < algorithm> 
28+ #include  < cstdint> 
29+ #include  < thread> 
2730#include  < utility> 
2831
2932using  ::testing::StartsWith;
@@ -247,7 +250,7 @@ TEST(InterpreterTest, DISABLED_DetectResourceDir) {
247250#ifdef  _WIN32
248251  GTEST_SKIP () << " Disabled on Windows. Needs fixing." 
249252#endif 
250-   Cpp::CreateInterpreter ();
253+   auto * I =  Cpp::CreateInterpreter ();
251254  EXPECT_STRNE (Cpp::DetectResourceDir ().c_str (), Cpp::GetResourceDir ());
252255  llvm::SmallString<256 > Clang (LLVM_BINARY_DIR);
253256  llvm::sys::path::append (Clang, " bin" " clang" 
@@ -256,7 +259,7 @@ TEST(InterpreterTest, DISABLED_DetectResourceDir) {
256259    GTEST_SKIP () << " Test not run (Clang binary does not exist)" 
257260
258261  std::string DetectedPath = Cpp::DetectResourceDir (Clang.str ().str ().c_str ());
259-   EXPECT_STREQ (DetectedPath.c_str (), Cpp::GetResourceDir ());
262+   EXPECT_STREQ (DetectedPath.c_str (), Cpp::GetResourceDir (I ));
260263}
261264
262265TEST (InterpreterTest, DetectSystemCompilerIncludePaths) {
@@ -364,26 +367,81 @@ if (llvm::sys::RunningOnValgrind())
364367#endif 
365368}
366369
370+ static  int  printf_jit (const  char * format, ...) {
371+   llvm::errs () << " printf_jit called!\n " 
372+   return  0 ;
373+ }
374+ 
367375TEST (InterpreterTest, MultipleInterpreter) {
368- #if  CLANG_VERSION_MAJOR < 20 && defined( EMSCRIPTEN) 
369-   GTEST_SKIP () << " Test fails for Emscipten LLVM 20  builds" 
376+ #ifdef   EMSCRIPTEN
377+   GTEST_SKIP () << " Test fails for Emscipten builds" 
370378#endif 
371-   auto * I = Cpp::CreateInterpreter ();
372-   EXPECT_TRUE (I);
373-   Cpp::Declare (R"( 
374-   void f() {} 
375-   )"  );
376-   Cpp::TCppScope_t f = Cpp::GetNamed (" f" 
379+ #ifdef  _WIN32
380+   GTEST_SKIP () << " Disabled on Windows. Needs fixing." 
381+ #endif 
382+   //  delete all old interpreters
383+   while  (Cpp::DeleteInterpreter ())
384+     ;
385+   auto * I1 = Cpp::CreateInterpreter ();
386+   EXPECT_TRUE (I1);
387+ 
388+   auto  F = [](Cpp::TInterp_t I) {
389+     bool  hasError = true ;
390+     EXPECT_TRUE (Cpp::Evaluate (" __cplusplus" 201402 );
391+     EXPECT_FALSE (hasError);
392+ 
393+     Cpp::Declare (R"( 
394+     extern "C" int printf(const char*,...); 
395+     class MyKlass {}; 
396+     )"  ,
397+                  false , I);
398+     Cpp::TCppScope_t f = Cpp::GetNamed (" printf" Cpp::GetGlobalScope (I));
399+     EXPECT_TRUE (f);
400+     EXPECT_TRUE (Cpp::GetComplexType (Cpp::GetType (" int" 
401+     Cpp::TCppType_t MyKlass = Cpp::GetType (" MyKlass" 
402+     EXPECT_EQ (Cpp::GetTypeAsString (MyKlass), " MyKlass" 
403+     EXPECT_EQ (Cpp::GetNumBases (MyKlass), 0 );
404+     EXPECT_FALSE (Cpp::GetBaseClass (MyKlass, 3 ));
405+     std::vector<Cpp::TCppScope_t> members;
406+     Cpp::GetEnumConstantDatamembers (Cpp::GetScopeFromType (MyKlass), members);
407+     EXPECT_EQ (members.size (), 0 );
408+ 
409+     EXPECT_FALSE (
410+         Cpp::InsertOrReplaceJitSymbol (" printf" uint64_t )&printf_jit, I));
411+ 
412+     auto  f_callable = Cpp::MakeFunctionCallable (f);
413+     EXPECT_EQ (f_callable.getKind (), Cpp::JitCall::Kind::kGenericCall );
414+ 
415+     EXPECT_FALSE (
416+         Cpp::TakeInterpreter ((TInterp_t)1 )); //  try to take ownership of an
417+                                              //  interpreter that does not exist
418+ 
419+     std::vector<std::string> includes;
420+     Cpp::AddIncludePath (" /non/existent/" 
421+     Cpp::GetIncludePaths (includes, false , false , I);
422+     EXPECT_NE (std::find (includes.begin (), includes.end (), " /non/existent/" 
423+               std::end (includes));
424+ 
425+     EXPECT_TRUE (Cpp::InsertOrReplaceJitSymbol (" non_existent" uint64_t )&f, I));
426+   };
427+   F (I1);
377428
378429  auto * I2 = Cpp::CreateInterpreter ();
430+   auto * I3 = Cpp::CreateInterpreter ();
431+   auto * I4 = Cpp::CreateInterpreter ();
379432  EXPECT_TRUE (I2);
380-   Cpp::Declare (R"( 
381-   void ff() {} 
382-   )"  );
383-   Cpp::TCppScope_t ff = Cpp::GetNamed (" ff" 
384- 
385-   auto  f_callable = Cpp::MakeFunctionCallable (f);
386-   EXPECT_EQ (f_callable.getKind (), Cpp::JitCall::Kind::kGenericCall );
387-   auto  ff_callable = Cpp::MakeFunctionCallable (ff);
388-   EXPECT_EQ (ff_callable.getKind (), Cpp::JitCall::Kind::kGenericCall );
433+   EXPECT_TRUE (I3);
434+   EXPECT_TRUE (I4);
435+ 
436+   std::thread t2 (F, I2);
437+   std::thread t3 (F, I3);
438+   std::thread t4 (F, I4);
439+   t2.join ();
440+   t3.join ();
441+   t4.join ();
442+ 
443+   testing::internal::CaptureStderr ();
444+   Cpp::Process (" printf(\" Blah\" );" 
445+   std::string cerrs = testing::internal::GetCapturedStderr ();
446+   EXPECT_STREQ (cerrs.c_str (), " printf_jit called!\n " 
389447}
0 commit comments