bool SwiftASTManager::initCompilerInvocation(CompilerInvocation &Invocation, ArrayRef<const char *> OrigArgs, DiagnosticEngine &Diags, StringRef UnresolvedPrimaryFile, std::string &Error) { SmallVector<const char *, 16> Args(OrigArgs.begin(), OrigArgs.end()); Args.push_back("-resource-dir"); Args.push_back(Impl.RuntimeResourcePath.c_str()); if (auto driverInvocation = driver::createCompilerInvocation(Args, Diags)) { Invocation = *driverInvocation; } else { // FIXME: Get the actual diagnostic. Error = "error when parsing the compiler arguments"; return true; } Invocation.getFrontendOptions().InputsAndOutputs = resolveSymbolicLinksInInputs( Invocation.getFrontendOptions().InputsAndOutputs, UnresolvedPrimaryFile, Error); if (!Error.empty()) return true; ClangImporterOptions &ImporterOpts = Invocation.getClangImporterOptions(); ImporterOpts.DetailedPreprocessingRecord = true; assert(!Invocation.getModuleName().empty()); Invocation.getLangOptions().AttachCommentsToDecls = true; Invocation.getLangOptions().DiagnosticsEditorMode = true; Invocation.getLangOptions().CollectParsedToken = true; auto &FrontendOpts = Invocation.getFrontendOptions(); if (FrontendOpts.PlaygroundTransform) { // The playground instrumenter changes the AST in ways that disrupt the // SourceKit functionality. Since we don't need the instrumenter, and all we // actually need is the playground semantics visible to the user, like // silencing the "expression resolves to an unused l-value" error, disable it. FrontendOpts.PlaygroundTransform = false; } // Disable the index-store functionality for the sourcekitd requests. FrontendOpts.IndexStorePath.clear(); ImporterOpts.IndexStorePath.clear(); // Force the action type to be -typecheck. This affects importing the // SwiftONoneSupport module. FrontendOpts.RequestedAction = FrontendOptions::ActionType::Typecheck; // We don't care about LLVMArgs FrontendOpts.LLVMArgs.clear(); // Disable expensive SIL options to reduce time spent in SILGen. disableExpensiveSILOptions(Invocation.getSILOptions()); return false; }
void updateCode(std::unique_ptr<llvm::MemoryBuffer> Buffer) { BufferID = SM.addNewSourceBuffer(std::move(Buffer)); Parser.reset(new ParserUnit(SM, BufferID, CompInv.getLangOptions(), CompInv.getModuleName())); Parser->getDiagnosticEngine().addConsumer(DiagConsumer); auto &P = Parser->getParser(); for (bool Done = false; !Done; Done = P.Tok.is(tok::eof)) { P.parseTopLevel(); } }
static void setModuleName(CompilerInvocation &Invocation) { if (!Invocation.getModuleName().empty()) return; StringRef Filename = Invocation.getOutputFilename(); if (Filename.empty()) { if (Invocation.getInputFilenames().empty()) { Invocation.setModuleName("__main__"); return; } Filename = Invocation.getInputFilenames()[0]; } Filename = llvm::sys::path::filename(Filename); StringRef ModuleName = llvm::sys::path::stem(Filename); if (ModuleName.empty() || !Lexer::isIdentifier(ModuleName)) { Invocation.setModuleName("__main__"); return; } Invocation.setModuleName(ModuleName); }
ImportDepth::ImportDepth(ASTContext &context, CompilerInvocation &invocation) { llvm::DenseSet<ModuleDecl *> seen; std::deque<std::pair<ModuleDecl *, uint8_t>> worklist; StringRef mainModule = invocation.getModuleName(); auto *main = context.getLoadedModule(context.getIdentifier(mainModule)); assert(main && "missing main module"); worklist.emplace_back(main, uint8_t(0)); // Imports from -import-name such as Playground auxiliary sources are treated // specially by applying import depth 0. llvm::StringSet<> auxImports; for (StringRef moduleName : invocation.getFrontendOptions().ImplicitImportModuleNames) auxImports.insert(moduleName); // Private imports from this module. // FIXME: only the private imports from the current source file. ModuleDecl::ImportFilter importFilter; importFilter |= ModuleDecl::ImportFilterKind::Private; importFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly; SmallVector<ModuleDecl::ImportedModule, 16> mainImports; main->getImportedModules(mainImports, importFilter); for (auto &import : mainImports) { uint8_t depth = 1; if (auxImports.count(import.second->getName().str())) depth = 0; worklist.emplace_back(import.second, depth); } // Fill depths with BFS over module imports. while (!worklist.empty()) { ModuleDecl *module; uint8_t depth; std::tie(module, depth) = worklist.front(); worklist.pop_front(); if (!seen.insert(module).second) continue; // Insert new module:depth mapping. const clang::Module *CM = module->findUnderlyingClangModule(); if (CM) { depths[CM->getFullModuleName()] = depth; } else { depths[module->getName().str()] = depth; } // Add imports to the worklist. SmallVector<ModuleDecl::ImportedModule, 16> imports; module->getImportedModules(imports); for (auto &import : imports) { uint8_t next = std::max(depth, uint8_t(depth + 1)); // unsigned wrap // Implicitly imported sub-modules get the same depth as their parent. if (const clang::Module *CMI = import.second->findUnderlyingClangModule()) if (CM && CMI->isSubModuleOf(CM)) next = depth; worklist.emplace_back(import.second, next); } } }