module_iterator module_begin() const { return Modules.begin(); }
module_iterator module_end() const { return Modules.end(); }
+ llvm::iterator_range<module_iterator> modules() const {
+ return {module_begin(), module_end()};
+ }
/// Cache a module load. M might be nullptr.
void cacheModuleLoad(const IdentifierInfo &II, Module *M) {
}
}
-void Module::print(raw_ostream &OS, unsigned Indent) const {
+void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
OS.indent(Indent);
if (IsFramework)
OS << "framework ";
// the module. Regular inferred submodules are OK, as we need to look at all
// those header files anyway.
if (!(*MI)->IsInferred || (*MI)->IsFramework)
- (*MI)->print(OS, Indent + 2);
+ (*MI)->print(OS, Indent + 2, Dump);
for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
OS.indent(Indent + 2);
OS << "\n";
}
+ if (Dump) {
+ for (Module *M : Imports) {
+ OS.indent(Indent + 2);
+ llvm::errs() << "import " << M->getFullModuleName() << "\n";
+ }
+ }
+
for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
OS.indent(Indent + 2);
OS << "use ";
}
LLVM_DUMP_METHOD void Module::dump() const {
- print(llvm::errs());
+ print(llvm::errs(), 0, true);
}
void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
DebugOverflowStack();
} else if (II->isStr("captured")) {
HandleCaptured(PP);
+ } else if (II->isStr("modules")) {
+ struct ModuleVisitor {
+ Preprocessor &PP;
+ void visit(Module *M, bool VisibleOnly) {
+ SourceLocation ImportLoc = PP.getModuleImportLoc(M);
+ if (!VisibleOnly || ImportLoc.isValid()) {
+ llvm::errs() << M->getFullModuleName() << " ";
+ if (ImportLoc.isValid()) {
+ llvm::errs() << M << " visible ";
+ ImportLoc.print(llvm::errs(), PP.getSourceManager());
+ }
+ llvm::errs() << "\n";
+ }
+ for (Module *Sub : M->submodules()) {
+ if (!VisibleOnly || ImportLoc.isInvalid() || Sub->IsExplicit)
+ visit(Sub, VisibleOnly);
+ }
+ }
+ void visitAll(bool VisibleOnly) {
+ for (auto &NameAndMod :
+ PP.getHeaderSearchInfo().getModuleMap().modules())
+ visit(NameAndMod.second, VisibleOnly);
+ }
+ } Visitor{PP};
+
+ Token Kind;
+ PP.LexUnexpandedToken(Kind);
+ auto *DumpII = Kind.getIdentifierInfo();
+ if (!DumpII) {
+ PP.Diag(Kind, diag::warn_pragma_debug_missing_argument)
+ << II->getName();
+ } else if (DumpII->isStr("all")) {
+ Visitor.visitAll(false);
+ } else if (DumpII->isStr("visible")) {
+ Visitor.visitAll(true);
+ } else if (DumpII->isStr("building")) {
+ for (auto &Building : PP.getBuildingSubmodules()) {
+ llvm::errs() << "in " << Building.M->getFullModuleName();
+ if (Building.ImportLoc.isValid()) {
+ llvm::errs() << " imported ";
+ if (Building.IsPragma)
+ llvm::errs() << "via pragma ";
+ llvm::errs() << "at ";
+ Building.ImportLoc.print(llvm::errs(), PP.getSourceManager());
+ llvm::errs() << "\n";
+ }
+ }
+ } else {
+ PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
+ << DumpII->getName();
+ }
} else {
PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
<< II->getName();