|
60 | 60 |
|
61 | 61 | #include <string> |
62 | 62 | #include <vector> |
| 63 | +#include <fstream> |
| 64 | +#include <iostream> |
| 65 | +#include <sstream> |
63 | 66 |
|
64 | 67 | using namespace clang; |
65 | 68 |
|
@@ -1473,6 +1476,77 @@ namespace cling { |
1473 | 1476 | m_DynamicLookupEnabled = value; |
1474 | 1477 | } |
1475 | 1478 |
|
| 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 | + |
1476 | 1550 | Interpreter::ExecutionResult |
1477 | 1551 | Interpreter::executeTransaction(Transaction& T) { |
1478 | 1552 | assert(!isInSyntaxOnlyMode() && "Running on what?"); |
|
0 commit comments