SwiftInterfaceGenContextRef SwiftInterfaceGenContext::create(StringRef DocumentName, bool IsModule, StringRef ModuleOrHeaderName, CompilerInvocation Invocation, std::string &ErrMsg) { SwiftInterfaceGenContextRef IFaceGenCtx{ new SwiftInterfaceGenContext() }; IFaceGenCtx->Impl.DocumentName = DocumentName; IFaceGenCtx->Impl.IsModule = IsModule; IFaceGenCtx->Impl.ModuleOrHeaderName = ModuleOrHeaderName; IFaceGenCtx->Impl.Invocation = Invocation; CompilerInstance &CI = IFaceGenCtx->Impl.Instance; // Display diagnostics to stderr. CI.addDiagnosticConsumer(&IFaceGenCtx->Impl.DiagConsumer); Invocation.clearInputs(); if (CI.setup(Invocation)) { ErrMsg = "Error during invocation setup"; return nullptr; } ASTContext &Ctx = CI.getASTContext(); CloseClangModuleFiles scopedCloseFiles(*Ctx.getClangModuleLoader()); // Load standard library so that Clang importer can use it. auto *Stdlib = getModuleByFullName(Ctx, Ctx.StdlibModuleName); if (!Stdlib) { ErrMsg = "Could not load the stdlib module"; return nullptr; } if (IsModule) { if (getModuleInterfaceInfo(Ctx, ModuleOrHeaderName, IFaceGenCtx->Impl, ErrMsg)) return nullptr; } else { auto &FEOpts = Invocation.getFrontendOptions(); if (FEOpts.ImplicitObjCHeaderPath.empty()) { ErrMsg = "Implicit ObjC header path is empty"; return nullptr; } auto &Importer = static_cast<ClangImporter &>(*Ctx.getClangModuleLoader()); Importer.importBridgingHeader(FEOpts.ImplicitObjCHeaderPath, CI.getMainModule(), /*diagLoc=*/{}, /*trackParsedSymbols=*/true); if (getHeaderInterfaceInfo(Ctx, ModuleOrHeaderName, IFaceGenCtx->Impl.Info, ErrMsg)) return nullptr; } if (makeParserAST(IFaceGenCtx->Impl.TextCI, IFaceGenCtx->Impl.Info.Text)) { ErrMsg = "Error during syntactic parsing"; return nullptr; } return IFaceGenCtx; }
void SwiftLangSupport::findModuleGroups(StringRef ModuleName, ArrayRef<const char *> Args, std::function<void(ArrayRef<StringRef>, StringRef Error)> Receiver) { CompilerInvocation Invocation; Invocation.getClangImporterOptions().ImportForwardDeclarations = true; Invocation.clearInputs(); CompilerInstance CI; // Display diagnostics to stderr. PrintingDiagnosticConsumer PrintDiags; CI.addDiagnosticConsumer(&PrintDiags); std::vector<StringRef> Groups; std::string Error; if (getASTManager().initCompilerInvocation(Invocation, Args, CI.getDiags(), StringRef(), Error)) { Receiver(Groups, Error); return; } if (CI.setup(Invocation)) { Error = "Compiler invocation set up fails."; Receiver(Groups, Error); return; } ASTContext &Ctx = CI.getASTContext(); // Setup a typechecker for protocol conformance resolving. OwnedResolver TypeResolver = createLazyResolver(Ctx); // Load standard library so that Clang importer can use it. auto *Stdlib = getModuleByFullName(Ctx, Ctx.StdlibModuleName); if (!Stdlib) { Error = "Cannot load stdlib."; Receiver(Groups, Error); return; } auto *M = getModuleByFullName(Ctx, ModuleName); if (!M) { Error = "Cannot find the module."; Receiver(Groups, Error); return; } std::vector<StringRef> Scratch; Receiver(collectModuleGroups(M, Scratch), Error); }
std::unique_ptr<swift::CompilerInstance> Migrator::performAFixItMigration(version::Version SwiftLanguageVersion) { auto InputState = States.back(); auto InputText = InputState->getOutputText(); auto InputBuffer = llvm::MemoryBuffer::getMemBufferCopy(InputText, getInputFilename()); CompilerInvocation Invocation { StartInvocation }; Invocation.clearInputs(); Invocation.getLangOptions().EffectiveLanguageVersion = SwiftLanguageVersion; auto &LLVMArgs = Invocation.getFrontendOptions().LLVMArgs; auto aarch64_use_tbi = std::find(LLVMArgs.begin(), LLVMArgs.end(), "-aarch64-use-tbi"); if (aarch64_use_tbi != LLVMArgs.end()) { LLVMArgs.erase(aarch64_use_tbi); } // SE-0160: When migrating, always use the Swift 3 @objc inference rules, // which drives warnings with the "@objc" Fix-Its. Invocation.getLangOptions().EnableSwift3ObjCInference = true; // The default behavior of the migrator, referred to as "minimal" migration // in SE-0160, only adds @objc Fix-Its to those cases where the Objective-C // entry point is explicitly used somewhere in the source code. The user // may also select a workflow that adds @objc for every declaration that // would infer @objc under the Swift 3 rules but would no longer infer // @objc in Swift 4. Invocation.getLangOptions().WarnSwift3ObjCInference = getMigratorOptions().KeepObjcVisibility ? Swift3ObjCInferenceWarnings::Complete : Swift3ObjCInferenceWarnings::Minimal; const auto &OrigFrontendOpts = StartInvocation.getFrontendOptions(); auto InputBuffers = OrigFrontendOpts.InputBuffers; auto InputFilenames = OrigFrontendOpts.InputFilenames; for (const auto &Buffer : InputBuffers) { Invocation.addInputBuffer(Buffer); } for (const auto &Filename : InputFilenames) { Invocation.addInputFilename(Filename); } const unsigned PrimaryIndex = Invocation.getFrontendOptions().InputBuffers.size(); Invocation.addInputBuffer(InputBuffer.get()); Invocation.getFrontendOptions().PrimaryInput = { PrimaryIndex, SelectedInput::InputKind::Buffer }; auto Instance = llvm::make_unique<swift::CompilerInstance>(); if (Instance->setup(Invocation)) { return nullptr; } FixitApplyDiagnosticConsumer FixitApplyConsumer { InputText, getInputFilename(), }; Instance->addDiagnosticConsumer(&FixitApplyConsumer); Instance->performSema(); StringRef ResultText = InputText; unsigned ResultBufferID = InputState->getOutputBufferID(); if (FixitApplyConsumer.getNumFixitsApplied() > 0) { SmallString<4096> Scratch; llvm::raw_svector_ostream OS(Scratch); FixitApplyConsumer.printResult(OS); auto ResultBuffer = llvm::MemoryBuffer::getMemBufferCopy(OS.str()); ResultText = ResultBuffer->getBuffer(); ResultBufferID = SrcMgr.addNewSourceBuffer(std::move(ResultBuffer)); } States.push_back(MigrationState::make(MigrationKind::CompilerFixits, SrcMgr, InputState->getOutputBufferID(), ResultBufferID)); return Instance; }