Skip to content

Commit 5b3c6d5

Browse files
vgvassilevTeemperor
authored andcommitted
[cxxmodules] Refactor LoadCoreModules.
NFC beside fixing the nullptr deref's in the previous LoadCoreModules implementation.
1 parent fd16aca commit 5b3c6d5

File tree

1 file changed

+37
-49
lines changed

1 file changed

+37
-49
lines changed

core/metacling/src/TCling.cxx

Lines changed: 37 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,8 +1088,10 @@ inline bool TCling::TUniqueString::Append(const std::string& str)
10881088
return notPresent;
10891089
}
10901090

1091+
////////////////////////////////////////////////////////////////////////////////
10911092
///\returns true if the module was loaded.
1092-
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp) {
1093+
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp, bool Complain = true)
1094+
{
10931095
clang::CompilerInstance &CI = *interp.getCI();
10941096

10951097
assert(CI.getLangOpts().Modules && "Function only relevant when C++ modules are turned on!");
@@ -1103,57 +1105,30 @@ static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp
11031105
clang::IdentifierInfo *II = PP.getIdentifierInfo(M->Name);
11041106
SourceLocation ValidLoc = M->DefinitionLoc;
11051107
bool success = !CI.getSema().ActOnModuleImport(ValidLoc, ValidLoc, std::make_pair(II, ValidLoc)).isInvalid();
1106-
// Also make the module visible in the preprocessor to export its macros.
1107-
PP.makeModuleVisible(M, ValidLoc);
1108-
return success;
1108+
if (success) {
1109+
// Also make the module visible in the preprocessor to export its macros.
1110+
PP.makeModuleVisible(M, ValidLoc);
1111+
return success;
1112+
}
1113+
if (Complain) {
1114+
if (M->IsSystem)
1115+
Error("TCling::LoadModule", "Module %s failed to load", M->Name.c_str());
1116+
else
1117+
Info("TCling::LoadModule", "Module %s failed to load", M->Name.c_str());
1118+
}
11091119
}
1120+
if (Complain)
1121+
Error("TCling::LoadModule", "Module %s not found!", ModuleName.c_str());
11101122
return false;
11111123
}
11121124

11131125
////////////////////////////////////////////////////////////////////////////////
1114-
/// Loads the basic C++ modules that we require to run any ROOT program.
1115-
/// This is just supposed to make the declarations in their headers available
1116-
/// to the interpreter.
1117-
static void LoadCoreModules(cling::Interpreter &interp)
1126+
/// Loads the C++ modules that we require to run any ROOT program. This is just
1127+
/// supposed to make a C++ module from a modulemap available to the interpreter.
1128+
static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
11181129
{
1119-
clang::CompilerInstance &CI = *interp.getCI();
1120-
// Without modules, this function is just a no-op.
1121-
if (!CI.getLangOpts().Modules)
1122-
return;
1123-
1124-
clang::HeaderSearch &headerSearch = CI.getPreprocessor().getHeaderSearchInfo();
1125-
clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
1126-
// List of core modules we can load, but it's ok if they are missing because
1127-
// the system doesn't have these modules.
1128-
if (clang::Module *LIBCM = moduleMap.findModule("libc"))
1129-
if (!LoadModule(LIBCM->Name, interp))
1130-
Error("TCling::LoadCoreModules", "Cannot load module %s", LIBCM->Name.c_str());
1131-
1132-
if (clang::Module *STLM = moduleMap.findModule("stl"))
1133-
if (!LoadModule(STLM->Name, interp))
1134-
Error("TCling::LoadCoreModules", "Cannot load module %s", STLM->Name.c_str());
1135-
1136-
// ROOT_Types is a module outside core because we need C and -no-rtti compatibility.
1137-
// Preload it as it is an integral part of module Core.
1138-
if (!LoadModule(moduleMap.findModule("ROOT_Types")->Name, interp))
1139-
Error("TCling::LoadCoreModules", "Cannot load module ROOT_Types");
1140-
1141-
if (!LoadModule(moduleMap.findModule("Core")->Name, interp))
1142-
Error("TCling::LoadCoreModules", "Cannot load module Core");
1143-
1144-
if (!LoadModule(moduleMap.findModule("RIO")->Name, interp))
1145-
Error("TCling::LoadCoreModules", "Cannot load module RIO");
1146-
1147-
// Check that the gROOT macro was exported by any core module.
1148-
assert(interp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1149-
1150-
// C99 decided that it's a very good idea to name a macro `I` (the letter I).
1151-
// This seems to screw up nearly all the template code out there as `I` is
1152-
// common template parameter name and iterator variable name.
1153-
// Let's follow the GCC recommendation and undefine `I` in case any of the
1154-
// core modules have defined it:
1155-
// https://www.gnu.org/software/libc/manual/html_node/Complex-Numbers.html
1156-
interp.declare("#ifdef I\n #undef I\n #endif\n");
1130+
for (const auto &modName : modules)
1131+
LoadModule(modName, interp);
11571132
}
11581133

11591134
static bool FileExists(const char *file)
@@ -1292,6 +1267,22 @@ TCling::TCling(const char *name, const char *title)
12921267
static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
12931268
fMetaProcessor = new cling::MetaProcessor(*fInterpreter, fMPOuts);
12941269

1270+
if (fInterpreter->getCI()->getLangOpts().Modules) {
1271+
// Setup core C++ modules if we have any to setup.
1272+
LoadModules({"libc", "stl", "ROOT_Types", "Core", "RIO"}, *fInterpreter);
1273+
1274+
// Check that the gROOT macro was exported by any core module.
1275+
assert(fInterpreter->getMacro("gROOT") && "Couldn't load gROOT macro?");
1276+
1277+
// C99 decided that it's a very good idea to name a macro `I` (the letter I).
1278+
// This seems to screw up nearly all the template code out there as `I` is
1279+
// common template parameter name and iterator variable name.
1280+
// Let's follow the GCC recommendation and undefine `I` in case any of the
1281+
// core modules have defined it:
1282+
// https://www.gnu.org/software/libc/manual/html_node/Complex-Numbers.html
1283+
fInterpreter->declare("#ifdef I\n #undef I\n #endif\n");
1284+
}
1285+
12951286
// For the list to also include string, we have to include it now.
12961287
// rootcling does parts already if needed, e.g. genreflex does not want using
12971288
// namespace std.
@@ -1309,9 +1300,6 @@ TCling::TCling(const char *name, const char *title)
13091300
"using namespace std;");
13101301
}
13111302

1312-
// Setup core C++ modules if we have any to setup.
1313-
LoadCoreModules(*fInterpreter);
1314-
13151303
// We are now ready (enough is loaded) to init the list of opaque typedefs.
13161304
fNormalizedCtxt = new ROOT::TMetaUtils::TNormalizedCtxt(fInterpreter->getLookupHelper());
13171305
fLookupHelper = new ROOT::TMetaUtils::TClingLookupHelper(*fInterpreter, *fNormalizedCtxt, TClingLookupHelper__ExistingTypeCheck, TClingLookupHelper__AutoParse);

0 commit comments

Comments
 (0)