@@ -2914,71 +2914,165 @@ namespace Cpp {
29142914 }
29152915 } // namespace
29162916
2917- TInterp_t CreateInterpreter (const std::vector<const char *>& Args /* ={}*/ ,
2918- const std::vector<const char *>& GpuArgs /* ={}*/ ) {
2919- std::string MainExecutableName =
2920- sys::fs::getMainExecutable (nullptr , nullptr );
2921- std::string ResourceDir = MakeResourcesPath ();
2922- std::vector<const char *> ClingArgv = {" -resource-dir" , ResourceDir.c_str (),
2923- " -std=c++14" };
2924- ClingArgv.insert (ClingArgv.begin (), MainExecutableName.c_str ());
2917+ // This Methond is Deprecated and should not be used
2918+ // It is kept for backward compatibility
2919+ // Updated overload of CreateInterpreter using std::vector<std::string>
2920+ // is preferred and defined below
2921+ [[deprecated(" Use the overload that takes std::vector<std::string> instead." )]]
2922+ TInterp_t CreateInterpreter (const std::vector<const char *>& Args,
2923+ const std::vector<const char *>& GpuArgs) {
2924+
2925+ // Convert const char* vectors to std::string vectors
2926+ std::vector<std::string> ArgsStr (Args.begin (), Args.end ());
2927+ std::vector<std::string> GpuArgsStr (GpuArgs.begin (), GpuArgs.end ());
2928+ // forwarding to the overloaded implementation
2929+ return CreateInterpreter (ArgsStr, GpuArgsStr);
2930+
2931+ // std::string MainExecutableName =
2932+ // sys::fs::getMainExecutable(nullptr, nullptr);
2933+ // std::string ResourceDir = MakeResourcesPath();
2934+ // std::vector<const char *> ClingArgv = {"-resource-dir", ResourceDir.c_str(),
2935+ // "-std=c++14"};
2936+ // ClingArgv.insert(ClingArgv.begin(), MainExecutableName.c_str());
2937+ // #ifdef _WIN32
2938+ // // FIXME : Workaround Sema::PushDeclContext assert on windows
2939+ // ClingArgv.push_back("-fno-delayed-template-parsing");
2940+ // #endif
2941+ // ClingArgv.insert(ClingArgv.end(), Args.begin(), Args.end());
2942+ // // To keep the Interpreter creation interface between cling and clang-repl
2943+ // // to some extent compatible we should put Args and GpuArgs together. On the
2944+ // // receiving end we should check for -xcuda to know.
2945+ // if (!GpuArgs.empty()) {
2946+ // llvm::StringRef Arg0 = GpuArgs[0];
2947+ // Arg0 = Arg0.trim().ltrim('-');
2948+ // if (Arg0 != "cuda") {
2949+ // llvm::errs() << "[CreateInterpreter]: Make sure --cuda is passed as the"
2950+ // << " first argument of the GpuArgs\n";
2951+ // return nullptr;
2952+ // }
2953+ // }
2954+ // ClingArgv.insert(ClingArgv.end(), GpuArgs.begin(), GpuArgs.end());
2955+
2956+ // // Process externally passed arguments if present.
2957+ // std::vector<std::string> ExtraArgs;
2958+ // auto EnvOpt =
2959+ // llvm::sys::Process::GetEnv("CPPINTEROP_EXTRA_INTERPRETER_ARGS");
2960+ // if (EnvOpt) {
2961+ // StringRef Env(*EnvOpt);
2962+ // while (!Env.empty()) {
2963+ // StringRef Arg;
2964+ // std::tie(Arg, Env) = Env.split(' ');
2965+ // ExtraArgs.push_back(Arg.str());
2966+ // }
2967+ // }
2968+ // std::transform(ExtraArgs.begin(), ExtraArgs.end(),
2969+ // std::back_inserter(ClingArgv),
2970+ // [&](const std::string& str) { return str.c_str(); });
2971+
2972+ // auto I = new compat::Interpreter(ClingArgv.size(), &ClingArgv[0]);
2973+
2974+ // // Honor -mllvm.
2975+ // //
2976+ // // FIXME: Remove this, one day.
2977+ // // This should happen AFTER plugins have been loaded!
2978+ // const CompilerInstance* Clang = I->getCI();
2979+ // if (!Clang->getFrontendOpts().LLVMArgs.empty()) {
2980+ // unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();
2981+ // auto Args = std::make_unique<const char*[]>(NumArgs + 2);
2982+ // Args[0] = "clang (LLVM option parsing)";
2983+ // for (unsigned i = 0; i != NumArgs; ++i)
2984+ // Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
2985+ // Args[NumArgs + 1] = nullptr;
2986+ // llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
2987+ // }
2988+ // // FIXME: Enable this assert once we figure out how to fix the multiple
2989+ // // calls to CreateInterpreter.
2990+ // //assert(!sInterpreter && "Interpreter already set.");
2991+ // sInterpreter = I;
2992+ // return I;
2993+ }
2994+
2995+ // Overloaded defination of CreateInterpreter using std::initializer_list
2996+ // for Args and GpuArgs
2997+ // This is a convenience function that allows the user to pass
2998+ // arguments as initializer lists, which are then converted to
2999+ // std::vector<std::string> internally.
3000+ TInterp_t CreateInterpreter (std::initializer_list<std::string> Args,
3001+ std::initializer_list<std::string> GpuArgs) {
3002+ return CreateInterpreter (std::vector<std::string>(Args),
3003+ std::vector<std::string>(GpuArgs));
3004+ }
3005+
3006+ // overloaded defination of CreateInterpreter using std::vector<std::string>
3007+ // for Args and GpuArgs
3008+ TInterp_t CreateInterpreter (const std::vector<std::string>& Args,
3009+ const std::vector<std::string>& GpuArgs) {
3010+ // Retrieve the path to the main executable
3011+ std::string MainExecutableName = sys::fs::getMainExecutable (nullptr , nullptr );
3012+
3013+ // Construct the resource directory path
3014+ std::string ResourceDir = MakeResourcesPath ();
3015+
3016+ // Initialize the argument list for the interpreter
3017+ std::vector<std::string> ClingArgv = {MainExecutableName, " -resource-dir" , ResourceDir, " -std=c++14" };
3018+
29253019#ifdef _WIN32
2926- // FIXME : Workaround Sema::PushDeclContext assert on windows
2927- ClingArgv.push_back (" -fno-delayed-template-parsing" );
3020+ // Add Windows-specific workaround for delayed template parsing
3021+ ClingArgv.push_back (" -fno-delayed-template-parsing" );
29283022#endif
2929- ClingArgv.insert (ClingArgv.end (), Args.begin (), Args.end ());
2930- // To keep the Interpreter creation interface between cling and clang-repl
2931- // to some extent compatible we should put Args and GpuArgs together. On the
2932- // receiving end we should check for -xcuda to know.
2933- if (!GpuArgs.empty ()) {
2934- llvm::StringRef Arg0 = GpuArgs[0 ];
2935- Arg0 = Arg0.trim ().ltrim (' -' );
2936- if (Arg0 != " cuda" ) {
2937- llvm::errs () << " [CreateInterpreter]: Make sure --cuda is passed as the"
2938- << " first argument of the GpuArgs\n " ;
2939- return nullptr ;
2940- }
2941- }
2942- ClingArgv.insert (ClingArgv.end (), GpuArgs.begin (), GpuArgs.end ());
2943-
2944- // Process externally passed arguments if present.
2945- std::vector<std::string> ExtraArgs;
2946- auto EnvOpt =
2947- llvm::sys::Process::GetEnv (" CPPINTEROP_EXTRA_INTERPRETER_ARGS" );
2948- if (EnvOpt) {
2949- StringRef Env (*EnvOpt);
2950- while (!Env.empty ()) {
2951- StringRef Arg;
2952- std::tie (Arg, Env) = Env.split (' ' );
2953- ExtraArgs.push_back (Arg.str ());
2954- }
2955- }
2956- std::transform (ExtraArgs.begin (), ExtraArgs.end (),
2957- std::back_inserter (ClingArgv),
2958- [&](const std::string& str) { return str.c_str (); });
2959-
2960- auto I = new compat::Interpreter (ClingArgv.size (), &ClingArgv[0 ]);
29613023
2962- // Honor -mllvm.
2963- //
2964- // FIXME: Remove this, one day.
2965- // This should happen AFTER plugins have been loaded!
2966- const CompilerInstance* Clang = I->getCI ();
2967- if (!Clang->getFrontendOpts ().LLVMArgs .empty ()) {
2968- unsigned NumArgs = Clang->getFrontendOpts ().LLVMArgs .size ();
2969- auto Args = std::make_unique<const char *[]>(NumArgs + 2 );
2970- Args[0 ] = " clang (LLVM option parsing)" ;
2971- for (unsigned i = 0 ; i != NumArgs; ++i)
2972- Args[i + 1 ] = Clang->getFrontendOpts ().LLVMArgs [i].c_str ();
2973- Args[NumArgs + 1 ] = nullptr ;
2974- llvm::cl::ParseCommandLineOptions (NumArgs + 1 , Args.get ());
2975- }
2976- // FIXME: Enable this assert once we figure out how to fix the multiple
2977- // calls to CreateInterpreter.
2978- // assert(!sInterpreter && "Interpreter already set.");
2979- sInterpreter = I;
2980- return I;
2981- }
3024+ // Append user-provided arguments
3025+ ClingArgv.insert (ClingArgv.end (), Args.begin (), Args.end ());
3026+
3027+ // Validate and append GPU-specific arguments
3028+ if (!GpuArgs.empty ()) {
3029+ llvm::StringRef Arg0 = GpuArgs[0 ];
3030+ Arg0 = Arg0.trim ().ltrim (' -' );
3031+ if (Arg0 != " cuda" ) {
3032+ llvm::errs () << " [CreateInterpreter]: Make sure --cuda is passed as the"
3033+ << " first argument of the GpuArgs\n " ;
3034+ return nullptr ;
3035+ }
3036+ }
3037+ ClingArgv.insert (ClingArgv.end (), GpuArgs.begin (), GpuArgs.end ());
3038+
3039+ // Process additional arguments from the environment variable
3040+ auto EnvOpt = llvm::sys::Process::GetEnv (" CPPINTEROP_EXTRA_INTERPRETER_ARGS" );
3041+ if (EnvOpt) {
3042+ llvm::StringRef Env (*EnvOpt);
3043+ while (!Env.empty ()) {
3044+ llvm::StringRef Arg;
3045+ std::tie (Arg, Env) = Env.split (' ' );
3046+ ClingArgv.push_back (Arg.str ());
3047+ }
3048+ }
3049+
3050+ // Convert std::vector<std::string> to std::vector<const char*> for compatibility
3051+ std::vector<const char *> ClingArgvCStr;
3052+ for (const auto & arg : ClingArgv) {
3053+ ClingArgvCStr.push_back (arg.c_str ());
3054+ }
3055+
3056+ // Create the interpreter instance
3057+ auto I = new compat::Interpreter (ClingArgvCStr.size (), ClingArgvCStr.data ());
3058+
3059+ // Process LLVM-specific arguments
3060+ const CompilerInstance* Clang = I->getCI ();
3061+ if (!Clang->getFrontendOpts ().LLVMArgs .empty ()) {
3062+ unsigned NumArgs = Clang->getFrontendOpts ().LLVMArgs .size ();
3063+ auto Args = std::make_unique<const char *[]>(NumArgs + 2 );
3064+ Args[0 ] = " clang (LLVM option parsing)" ;
3065+ for (unsigned i = 0 ; i != NumArgs; ++i) {
3066+ Args[i + 1 ] = Clang->getFrontendOpts ().LLVMArgs [i].c_str ();
3067+ }
3068+ Args[NumArgs + 1 ] = nullptr ;
3069+ llvm::cl::ParseCommandLineOptions (NumArgs + 1 , Args.get ());
3070+ }
3071+
3072+ // Set the global interpreter instance
3073+ sInterpreter = I;
3074+ return I;
3075+ }
29823076
29833077 TInterp_t GetInterpreter () { return sInterpreter ; }
29843078
0 commit comments