@@ -2876,71 +2876,165 @@ namespace Cpp {
28762876 }
28772877 } // namespace
28782878
2879- TInterp_t CreateInterpreter (const std::vector<const char *>& Args /* ={}*/ ,
2880- const std::vector<const char *>& GpuArgs /* ={}*/ ) {
2881- std::string MainExecutableName =
2882- sys::fs::getMainExecutable (nullptr , nullptr );
2883- std::string ResourceDir = MakeResourcesPath ();
2884- std::vector<const char *> ClingArgv = {" -resource-dir" , ResourceDir.c_str (),
2885- " -std=c++14" };
2886- ClingArgv.insert (ClingArgv.begin (), MainExecutableName.c_str ());
2879+ // This Methond is Deprecated and should not be used
2880+ // It is kept for backward compatibility
2881+ // Updated overload of CreateInterpreter using std::vector<std::string>
2882+ // is preferred and defined below
2883+ [[deprecated(" Use the overload that takes std::vector<std::string> instead." )]]
2884+ TInterp_t CreateInterpreter (const std::vector<const char *>& Args,
2885+ const std::vector<const char *>& GpuArgs) {
2886+
2887+ // Convert const char* vectors to std::string vectors
2888+ std::vector<std::string> ArgsStr (Args.begin (), Args.end ());
2889+ std::vector<std::string> GpuArgsStr (GpuArgs.begin (), GpuArgs.end ());
2890+ // forwarding to the overloaded implementation
2891+ return CreateInterpreter (ArgsStr, GpuArgsStr);
2892+
2893+ // std::string MainExecutableName =
2894+ // sys::fs::getMainExecutable(nullptr, nullptr);
2895+ // std::string ResourceDir = MakeResourcesPath();
2896+ // std::vector<const char *> ClingArgv = {"-resource-dir", ResourceDir.c_str(),
2897+ // "-std=c++14"};
2898+ // ClingArgv.insert(ClingArgv.begin(), MainExecutableName.c_str());
2899+ // #ifdef _WIN32
2900+ // // FIXME : Workaround Sema::PushDeclContext assert on windows
2901+ // ClingArgv.push_back("-fno-delayed-template-parsing");
2902+ // #endif
2903+ // ClingArgv.insert(ClingArgv.end(), Args.begin(), Args.end());
2904+ // // To keep the Interpreter creation interface between cling and clang-repl
2905+ // // to some extent compatible we should put Args and GpuArgs together. On the
2906+ // // receiving end we should check for -xcuda to know.
2907+ // if (!GpuArgs.empty()) {
2908+ // llvm::StringRef Arg0 = GpuArgs[0];
2909+ // Arg0 = Arg0.trim().ltrim('-');
2910+ // if (Arg0 != "cuda") {
2911+ // llvm::errs() << "[CreateInterpreter]: Make sure --cuda is passed as the"
2912+ // << " first argument of the GpuArgs\n";
2913+ // return nullptr;
2914+ // }
2915+ // }
2916+ // ClingArgv.insert(ClingArgv.end(), GpuArgs.begin(), GpuArgs.end());
2917+
2918+ // // Process externally passed arguments if present.
2919+ // std::vector<std::string> ExtraArgs;
2920+ // auto EnvOpt =
2921+ // llvm::sys::Process::GetEnv("CPPINTEROP_EXTRA_INTERPRETER_ARGS");
2922+ // if (EnvOpt) {
2923+ // StringRef Env(*EnvOpt);
2924+ // while (!Env.empty()) {
2925+ // StringRef Arg;
2926+ // std::tie(Arg, Env) = Env.split(' ');
2927+ // ExtraArgs.push_back(Arg.str());
2928+ // }
2929+ // }
2930+ // std::transform(ExtraArgs.begin(), ExtraArgs.end(),
2931+ // std::back_inserter(ClingArgv),
2932+ // [&](const std::string& str) { return str.c_str(); });
2933+
2934+ // auto I = new compat::Interpreter(ClingArgv.size(), &ClingArgv[0]);
2935+
2936+ // // Honor -mllvm.
2937+ // //
2938+ // // FIXME: Remove this, one day.
2939+ // // This should happen AFTER plugins have been loaded!
2940+ // const CompilerInstance* Clang = I->getCI();
2941+ // if (!Clang->getFrontendOpts().LLVMArgs.empty()) {
2942+ // unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();
2943+ // auto Args = std::make_unique<const char*[]>(NumArgs + 2);
2944+ // Args[0] = "clang (LLVM option parsing)";
2945+ // for (unsigned i = 0; i != NumArgs; ++i)
2946+ // Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
2947+ // Args[NumArgs + 1] = nullptr;
2948+ // llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
2949+ // }
2950+ // // FIXME: Enable this assert once we figure out how to fix the multiple
2951+ // // calls to CreateInterpreter.
2952+ // //assert(!sInterpreter && "Interpreter already set.");
2953+ // sInterpreter = I;
2954+ // return I;
2955+ }
2956+
2957+ // Overloaded defination of CreateInterpreter using std::initializer_list
2958+ // for Args and GpuArgs
2959+ // This is a convenience function that allows the user to pass
2960+ // arguments as initializer lists, which are then converted to
2961+ // std::vector<std::string> internally.
2962+ TInterp_t CreateInterpreter (std::initializer_list<std::string> Args,
2963+ std::initializer_list<std::string> GpuArgs) {
2964+ return CreateInterpreter (std::vector<std::string>(Args),
2965+ std::vector<std::string>(GpuArgs));
2966+ }
2967+
2968+ // overloaded defination of CreateInterpreter using std::vector<std::string>
2969+ // for Args and GpuArgs
2970+ TInterp_t CreateInterpreter (const std::vector<std::string>& Args,
2971+ const std::vector<std::string>& GpuArgs) {
2972+ // Retrieve the path to the main executable
2973+ std::string MainExecutableName = sys::fs::getMainExecutable (nullptr , nullptr );
2974+
2975+ // Construct the resource directory path
2976+ std::string ResourceDir = MakeResourcesPath ();
2977+
2978+ // Initialize the argument list for the interpreter
2979+ std::vector<std::string> ClingArgv = {MainExecutableName, " -resource-dir" , ResourceDir, " -std=c++14" };
2980+
28872981#ifdef _WIN32
2888- // FIXME : Workaround Sema::PushDeclContext assert on windows
2889- ClingArgv.push_back (" -fno-delayed-template-parsing" );
2982+ // Add Windows-specific workaround for delayed template parsing
2983+ ClingArgv.push_back (" -fno-delayed-template-parsing" );
28902984#endif
2891- ClingArgv.insert (ClingArgv.end (), Args.begin (), Args.end ());
2892- // To keep the Interpreter creation interface between cling and clang-repl
2893- // to some extent compatible we should put Args and GpuArgs together. On the
2894- // receiving end we should check for -xcuda to know.
2895- if (!GpuArgs.empty ()) {
2896- llvm::StringRef Arg0 = GpuArgs[0 ];
2897- Arg0 = Arg0.trim ().ltrim (' -' );
2898- if (Arg0 != " cuda" ) {
2899- llvm::errs () << " [CreateInterpreter]: Make sure --cuda is passed as the"
2900- << " first argument of the GpuArgs\n " ;
2901- return nullptr ;
2902- }
2903- }
2904- ClingArgv.insert (ClingArgv.end (), GpuArgs.begin (), GpuArgs.end ());
2905-
2906- // Process externally passed arguments if present.
2907- std::vector<std::string> ExtraArgs;
2908- auto EnvOpt =
2909- llvm::sys::Process::GetEnv (" CPPINTEROP_EXTRA_INTERPRETER_ARGS" );
2910- if (EnvOpt) {
2911- StringRef Env (*EnvOpt);
2912- while (!Env.empty ()) {
2913- StringRef Arg;
2914- std::tie (Arg, Env) = Env.split (' ' );
2915- ExtraArgs.push_back (Arg.str ());
2916- }
2917- }
2918- std::transform (ExtraArgs.begin (), ExtraArgs.end (),
2919- std::back_inserter (ClingArgv),
2920- [&](const std::string& str) { return str.c_str (); });
2921-
2922- auto I = new compat::Interpreter (ClingArgv.size (), &ClingArgv[0 ]);
29232985
2924- // Honor -mllvm.
2925- //
2926- // FIXME: Remove this, one day.
2927- // This should happen AFTER plugins have been loaded!
2928- const CompilerInstance* Clang = I->getCI ();
2929- if (!Clang->getFrontendOpts ().LLVMArgs .empty ()) {
2930- unsigned NumArgs = Clang->getFrontendOpts ().LLVMArgs .size ();
2931- auto Args = std::make_unique<const char *[]>(NumArgs + 2 );
2932- Args[0 ] = " clang (LLVM option parsing)" ;
2933- for (unsigned i = 0 ; i != NumArgs; ++i)
2934- Args[i + 1 ] = Clang->getFrontendOpts ().LLVMArgs [i].c_str ();
2935- Args[NumArgs + 1 ] = nullptr ;
2936- llvm::cl::ParseCommandLineOptions (NumArgs + 1 , Args.get ());
2937- }
2938- // FIXME: Enable this assert once we figure out how to fix the multiple
2939- // calls to CreateInterpreter.
2940- // assert(!sInterpreter && "Interpreter already set.");
2941- sInterpreter = I;
2942- return I;
2943- }
2986+ // Append user-provided arguments
2987+ ClingArgv.insert (ClingArgv.end (), Args.begin (), Args.end ());
2988+
2989+ // Validate and append GPU-specific arguments
2990+ if (!GpuArgs.empty ()) {
2991+ llvm::StringRef Arg0 = GpuArgs[0 ];
2992+ Arg0 = Arg0.trim ().ltrim (' -' );
2993+ if (Arg0 != " cuda" ) {
2994+ llvm::errs () << " [CreateInterpreter]: Make sure --cuda is passed as the"
2995+ << " first argument of the GpuArgs\n " ;
2996+ return nullptr ;
2997+ }
2998+ }
2999+ ClingArgv.insert (ClingArgv.end (), GpuArgs.begin (), GpuArgs.end ());
3000+
3001+ // Process additional arguments from the environment variable
3002+ auto EnvOpt = llvm::sys::Process::GetEnv (" CPPINTEROP_EXTRA_INTERPRETER_ARGS" );
3003+ if (EnvOpt) {
3004+ llvm::StringRef Env (*EnvOpt);
3005+ while (!Env.empty ()) {
3006+ llvm::StringRef Arg;
3007+ std::tie (Arg, Env) = Env.split (' ' );
3008+ ClingArgv.push_back (Arg.str ());
3009+ }
3010+ }
3011+
3012+ // Convert std::vector<std::string> to std::vector<const char*> for compatibility
3013+ std::vector<const char *> ClingArgvCStr;
3014+ for (const auto & arg : ClingArgv) {
3015+ ClingArgvCStr.push_back (arg.c_str ());
3016+ }
3017+
3018+ // Create the interpreter instance
3019+ auto I = new compat::Interpreter (ClingArgvCStr.size (), ClingArgvCStr.data ());
3020+
3021+ // Process LLVM-specific arguments
3022+ const CompilerInstance* Clang = I->getCI ();
3023+ if (!Clang->getFrontendOpts ().LLVMArgs .empty ()) {
3024+ unsigned NumArgs = Clang->getFrontendOpts ().LLVMArgs .size ();
3025+ auto Args = std::make_unique<const char *[]>(NumArgs + 2 );
3026+ Args[0 ] = " clang (LLVM option parsing)" ;
3027+ for (unsigned i = 0 ; i != NumArgs; ++i) {
3028+ Args[i + 1 ] = Clang->getFrontendOpts ().LLVMArgs [i].c_str ();
3029+ }
3030+ Args[NumArgs + 1 ] = nullptr ;
3031+ llvm::cl::ParseCommandLineOptions (NumArgs + 1 , Args.get ());
3032+ }
3033+
3034+ // Set the global interpreter instance
3035+ sInterpreter = I;
3036+ return I;
3037+ }
29443038
29453039 TInterp_t GetInterpreter () { return sInterpreter ; }
29463040
0 commit comments