@@ -1087,6 +1087,77 @@ inline bool TCling::TUniqueString::Append(const std::string& str)
10871087 return notPresent;
10881088}
10891089
1090+ // //////////////////////////////////////////////////////////////////////////////
1091+ // / Loads the basic C++ modules that we require to run any ROOT program.
1092+ // / This is just supposed to make the declarations in their headers available
1093+ // / to the interpreter.
1094+ static void LoadCoreModules (cling::Interpreter &interp)
1095+ {
1096+ clang::CompilerInstance &CI = *interp.getCI ();
1097+ // Without modules, this function is just a no-op.
1098+ if (!CI.getLangOpts ().Modules )
1099+ return ;
1100+
1101+ clang::HeaderSearch &headerSearch = CI.getPreprocessor ().getHeaderSearchInfo ();
1102+ clang::ModuleMap &moduleMap = headerSearch.getModuleMap ();
1103+ // List of core modules we need to load.
1104+ std::vector<std::string> neededCoreModuleNames = {" Core" , " RIO" };
1105+ std::vector<std::string> missingCoreModuleNames;
1106+
1107+ std::vector<clang::Module *> coreModules;
1108+
1109+ // Lookup the core modules in the modulemap by name.
1110+ for (std::string moduleName : neededCoreModuleNames) {
1111+ clang::Module *module = moduleMap.findModule (moduleName);
1112+ if (module ) {
1113+ coreModules.push_back (module );
1114+ } else {
1115+ // If we can't find a module, we record that to report it later.
1116+ missingCoreModuleNames.push_back (moduleName);
1117+ }
1118+ }
1119+
1120+ // If we couldn't find some modules, so let's print an error message.
1121+ if (!missingCoreModuleNames.empty ()) {
1122+ std::string MissingModuleNameList;
1123+ for (const std::string &name : missingCoreModuleNames) {
1124+ MissingModuleNameList += " " + name;
1125+ }
1126+
1127+ Error (" TCling::LoadCoreModules" ,
1128+ " Internal error, couldn't find core "
1129+ " C++ modules in modulemap:%s\n " ,
1130+ MissingModuleNameList.c_str ());
1131+ }
1132+
1133+ // Collect all submodules in the found core modules.
1134+ for (size_t i = 0 ; i < coreModules.size (); ++i) {
1135+ for (clang::Module *subModule : coreModules[i]->submodules ())
1136+ coreModules.push_back (subModule);
1137+ }
1138+
1139+ // Now we collect all header files from the previously collected modules.
1140+ std::vector<StringRef> moduleHeaders;
1141+ for (clang::Module *module : coreModules) {
1142+ ROOT::TMetaUtils::foreachHeaderInModule (
1143+ *module , [&moduleHeaders](const clang::Module::Header &h) { moduleHeaders.push_back (h.NameAsWritten ); });
1144+ }
1145+
1146+ // Turn the list of found header files into C++ code that includes all of
1147+ // them. This will be wrapped into an `import` declaration by clang, so we
1148+ // only make those modules available, not actually textually include those
1149+ // headers.
1150+ std::stringstream declarations;
1151+ for (StringRef H : moduleHeaders) {
1152+ declarations << " #include \" " << H.str () << " \"\n " ;
1153+ }
1154+ auto result = interp.declare (declarations.str ());
1155+
1156+ if (result != cling::Interpreter::CompilationResult::kSuccess ) {
1157+ Error (" TCling::LoadCoreModules" , " Couldn't parse core headers: %s\n " , declarations.str ().c_str ());
1158+ }
1159+ }
1160+
10901161// //////////////////////////////////////////////////////////////////////////////
10911162// / Initialize the cling interpreter interface.
10921163
@@ -1226,6 +1297,9 @@ TCling::TCling(const char *name, const char *title)
12261297 " using namespace std;" );
12271298 }
12281299
1300+ // Setup core C++ modules if we have any to setup.
1301+ LoadCoreModules (*fInterpreter );
1302+
12291303 // We are now ready (enough is loaded) to init the list of opaque typedefs.
12301304 fNormalizedCtxt = new ROOT::TMetaUtils::TNormalizedCtxt (fInterpreter ->getLookupHelper ());
12311305 fLookupHelper = new ROOT::TMetaUtils::TClingLookupHelper (*fInterpreter , *fNormalizedCtxt , TClingLookupHelper__ExistingTypeCheck, TClingLookupHelper__AutoParse);
0 commit comments