Skip to content

Commit 2052b82

Browse files
committed
[cxxmodules][wip] Add SetupModules call to load all available PCMs
1 parent 22e7efe commit 2052b82

File tree

6 files changed

+86
-0
lines changed

6 files changed

+86
-0
lines changed

core/base/src/TROOT.cxx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2035,6 +2035,8 @@ void TROOT::InitInterpreter()
20352035

20362036
// Enable autoloading
20372037
fInterpreter->EnableAutoLoading();
2038+
if (fInterpreter->getCI()->getLangOpts().Modules)
2039+
fInterpreter->SetupModules();
20382040
}
20392041

20402042
////////////////////////////////////////////////////////////////////////////////

core/meta/inc/TInterpreter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ class TInterpreter : public TNamed {
162162
void (*histaddFunc)(const char* line)) = 0;
163163
virtual void Reset() = 0;
164164
virtual void ResetAll() = 0;
165+
virtual void SetupModules() = 0;
165166
virtual void ResetGlobals() = 0;
166167
virtual void ResetGlobalVar(void *obj) = 0;
167168
virtual void RewindDictionary() = 0;

core/metacling/src/TCling.cxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3768,6 +3768,12 @@ void TCling::UpdateListOfDataMembers(TClass* cl) const
37683768
{
37693769
}
37703770

3771+
void TCling::SetupModules() {
3772+
assert (fInterpreter->getCI()->getLangOpts().Modules &&
3773+
"Should only be called with modules enabled!");
3774+
fInterpreter->setupModules();
3775+
}
3776+
37713777
////////////////////////////////////////////////////////////////////////////////
37723778
/// Create list of pointers to method arguments for TMethod m.
37733779

core/metacling/src/TCling.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ class TCling : public TInterpreter {
234234
void CreateListOfMethodArgs(TFunction* m) const;
235235
void UpdateListOfMethods(TClass* cl) const;
236236
void UpdateListOfDataMembers(TClass* cl) const;
237+
virtual void SetupModules();
237238

238239
virtual DeclId_t GetDataMember(ClassInfo_t *cl, const char *name) const;
239240
virtual DeclId_t GetDataMemberAtAddr(const void *addr) const;

interpreter/cling/include/cling/Interpreter/Interpreter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,8 @@ namespace cling {
648648
int getDefaultOptLevel() const { return m_OptLevel; }
649649
void setDefaultOptLevel(int optLevel) { m_OptLevel = optLevel; }
650650

651+
void setupModules();
652+
651653
clang::CompilerInstance* getCI() const;
652654
clang::CompilerInstance* getCIOrNull() const;
653655
clang::Sema& getSema() const;

interpreter/cling/lib/Interpreter/Interpreter.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@
6060

6161
#include <string>
6262
#include <vector>
63+
#include <fstream>
64+
#include <iostream>
65+
#include <sstream>
6366

6467
using namespace clang;
6568

@@ -1473,6 +1476,77 @@ namespace cling {
14731476
m_DynamicLookupEnabled = value;
14741477
}
14751478

1479+
void Interpreter::setupModules() {
1480+
clang::CompilerInstance* CI = getCI();
1481+
std::stringstream declarations;
1482+
if (CI->getLangOpts().Modules && CI->getLangOpts().CurrentModule.empty()) {
1483+
1484+
clang::HeaderSearch &headerSearch = CI->getPreprocessor().getHeaderSearchInfo();
1485+
clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
1486+
1487+
llvm::SetVector<clang::Module *> modules;
1488+
auto& PP = getParser().getPreprocessor();
1489+
1490+
for (auto MI = moduleMap.module_begin(), end = moduleMap.module_end(); MI != end; MI++) {
1491+
clang::Module* Module = MI->second;
1492+
HeaderSearchOptions &HSOpts =
1493+
PP.getHeaderSearchInfo().getHeaderSearchOpts();
1494+
1495+
std::string ModuleFileName;
1496+
bool LoadFromPrebuiltModulePath = false;
1497+
// We try to load the module from the prebuilt module paths. If not
1498+
// successful, we then try to find it in the module cache.
1499+
if (!HSOpts.PrebuiltModulePaths.empty()) {
1500+
// Load the module from the prebuilt module path.
1501+
ModuleFileName = PP.getHeaderSearchInfo().getModuleFileName(
1502+
Module->Name, "", /*UsePrebuiltPath*/ true);
1503+
if (!ModuleFileName.empty())
1504+
LoadFromPrebuiltModulePath = true;
1505+
}
1506+
if (!LoadFromPrebuiltModulePath && Module) {
1507+
// Load the module from the module cache.
1508+
ModuleFileName = PP.getHeaderSearchInfo().getModuleFileName(Module);
1509+
}
1510+
bool Exists = false;
1511+
{
1512+
std::ifstream f(ModuleFileName);
1513+
Exists = f.good();
1514+
}
1515+
if (Exists)
1516+
modules.insert(Module);
1517+
}
1518+
1519+
for (size_t i = 0; i < modules.size(); ++i) {
1520+
clang::Module *M = modules[i];
1521+
for (clang::Module *subModule : M->submodules()) modules.insert(subModule);
1522+
}
1523+
1524+
// Now we collect all header files from the previously collected modules.
1525+
std::set<StringRef> moduleHeaders;
1526+
for (clang::Module *module : modules) {
1527+
for (int i = 0; i < 4; i++) {
1528+
auto &headerList = module->Headers[i];
1529+
for (const clang::Module::Header &moduleHeader : headerList) {
1530+
moduleHeaders.insert(moduleHeader.NameAsWritten);
1531+
}
1532+
}
1533+
}
1534+
1535+
for (StringRef H : moduleHeaders) {
1536+
if (H == "GL/glew.h")
1537+
continue;
1538+
if (H == "GL/glxew.h")
1539+
continue;
1540+
if (H.endswith(".inc"))
1541+
continue;
1542+
if (H == "TException.h")
1543+
continue;
1544+
declarations << "#include \"" << H << "\"\n";
1545+
}
1546+
}
1547+
declare(declarations.str());
1548+
}
1549+
14761550
Interpreter::ExecutionResult
14771551
Interpreter::executeTransaction(Transaction& T) {
14781552
assert(!isInSyntaxOnlyMode() && "Running on what?");

0 commit comments

Comments
 (0)