InterpreterCallbacks::InterpreterCallbacks(Interpreter* interp, bool enableExternalSemaSourceCallbacks/* = false*/, bool enableDeserializationListenerCallbacks/* = false*/, bool enablePPCallbacks/* = false*/) : m_Interpreter(interp), m_IsRuntime(false) { if (enableExternalSemaSourceCallbacks) { m_ExternalSemaSource.reset(new InterpreterExternalSemaSource(this)); m_Interpreter->getSema().addExternalSource(m_ExternalSemaSource.get()); } ASTReader* Reader = m_Interpreter->getCI()->getModuleManager(); if (enableDeserializationListenerCallbacks && Reader) { // FIXME: need to create a multiplexer if a DeserializationListener is // alreday present. m_DeserializationListener. reset(new InterpreterDeserializationListener(this)); Reader->setDeserializationListener(m_DeserializationListener.get()); } if (enablePPCallbacks) { m_PPCallbacks.reset(new InterpreterPPCallbacks(this)); Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor(); PP.addPPCallbacks(m_PPCallbacks.get()); } }
InterpreterCallbacks::InterpreterCallbacks(Interpreter* interp, InterpreterExternalSemaSource* IESS, InterpreterDeserializationListener* IDL, InterpreterPPCallbacks* IPPC) : m_Interpreter(interp), m_ExternalSemaSource(IESS), m_DeserializationListener(IDL), m_IsRuntime(false) { if (IESS) m_Interpreter->getSema().addExternalSource(m_ExternalSemaSource.get()); ASTReader* Reader = m_Interpreter->getCI()->getModuleManager(); if (IDL && Reader) Reader->setDeserializationListener(IDL); if (IPPC) m_Interpreter->getCI()->getPreprocessor().addPPCallbacks(IPPC); }
static void dumpModuleFileInputs(serialization::ModuleFile &Mod, ASTReader &Reader, raw_ostream &OS) { OS << "---- Module Inputs ----\n"; Reader.visitInputFiles(Mod, /*IncludeSystem=*/true, /*Complain=*/false, [&](const serialization::InputFile &IF, bool isSystem) { OS << (isSystem ? "system" : "user") << " | "; OS << IF.getFile()->getName() << '\n'; }); }
InterpreterCallbacks::InterpreterCallbacks(Interpreter* interp, bool enableExternalSemaSourceCallbacks/* = false*/, bool enableDeserializationListenerCallbacks/* = false*/, bool enablePPCallbacks/* = false*/) : m_Interpreter(interp), m_ExternalSemaSource(0), m_PPCallbacks(0), m_IsRuntime(false) { Sema& SemaRef = interp->getSema(); ASTReader* Reader = m_Interpreter->getCI()->getModuleManager().get(); ExternalSemaSource* externalSemaSrc = SemaRef.getExternalSource(); if (enableExternalSemaSourceCallbacks) if (!externalSemaSrc || externalSemaSrc == Reader) { // If the ExternalSemaSource is the PCH reader we still need to insert // our listener. m_ExternalSemaSource = new InterpreterExternalSemaSource(this); m_ExternalSemaSource->InitializeSema(SemaRef); m_Interpreter->getSema().addExternalSource(m_ExternalSemaSource); // FIXME: We should add a multiplexer in the ASTContext, too. llvm::IntrusiveRefCntPtr<ExternalASTSource> astContextExternalSource(SemaRef.getExternalSource()); clang::ASTContext& Ctx = SemaRef.getASTContext(); // FIXME: This is a gross hack. We must make multiplexer in the // astcontext or a derived class that extends what we need. Ctx.ExternalSource.resetWithoutRelease();//FIXME: make sure we delete it. Ctx.setExternalSource(astContextExternalSource); } if (enableDeserializationListenerCallbacks && Reader) { // FIXME: need to create a multiplexer if a DeserializationListener is // alreday present. m_DeserializationListener. reset(new InterpreterDeserializationListener(this)); Reader->setDeserializationListener(m_DeserializationListener.get()); } if (enablePPCallbacks) { Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor(); m_PPCallbacks = new InterpreterPPCallbacks(this); PP.addPPCallbacks(std::unique_ptr<InterpreterPPCallbacks>(m_PPCallbacks)); } }
std::unique_ptr<ModuleFileExtensionReader> TestModuleFileExtension::createExtensionReader( const ModuleFileExtensionMetadata &Metadata, ASTReader &Reader, serialization::ModuleFile &Mod, const llvm::BitstreamCursor &Stream) { assert(Metadata.BlockName == BlockName && "Wrong block name"); if (std::make_pair(Metadata.MajorVersion, Metadata.MinorVersion) != std::make_pair(MajorVersion, MinorVersion)) { Reader.getDiags().Report(Mod.ImportLoc, diag::err_test_module_file_extension_version) << BlockName << Metadata.MajorVersion << Metadata.MinorVersion << MajorVersion << MinorVersion; return nullptr; } return std::unique_ptr<ModuleFileExtensionReader>( new TestModuleFileExtension::Reader(this, Stream)); }
void DependencyFileGenerator::AttachToASTReader(ASTReader &R) { DFGImpl *I = reinterpret_cast<DFGImpl *>(Impl); assert(I && "missing implementation"); R.addListener(llvm::make_unique<DFGASTReaderListener>(*I)); }
void DependencyCollector::attachToASTReader(ASTReader &R) { R.addListener(llvm::make_unique<DepCollectorASTListener>(*this)); }
void DependencyCollector::attachToASTReader(ASTReader &R) { R.addListener(new DepCollectorASTListener(*this)); }
void ModuleDependencyCollector::attachToASTReader(ASTReader &R) { R.addListener(llvm::make_unique<ModuleDependencyListener>(*this)); }
ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls, RemappedFile *RemappedFiles, unsigned NumRemappedFiles, bool CaptureDiagnostics) { llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true)); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> ASTUnitCleanup(AST.get()); llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > DiagCleanup(Diags.getPtr()); ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; AST->Diagnostics = Diags; AST->FileMgr = new FileManager(FileSystemOpts); AST->SourceMgr = new SourceManager(AST->getDiagnostics(), AST->getFileManager()); AST->ImportInfo.reset(new ImportSearch(AST->getFileManager())); for (unsigned I = 0; I != NumRemappedFiles; ++I) { FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; if (const llvm::MemoryBuffer * memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { // Create the file entry for the file that we're mapping from. const FileEntry *FromFile = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, memBuf->getBufferSize(), 0); if (!FromFile) { AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) << RemappedFiles[I].first; delete memBuf; continue; } // Override the contents of the "from" file with the contents of // the "to" file. AST->getSourceManager().overrideFileContents(FromFile, memBuf); } else { const char *fname = fileOrBuf.get<const char *>(); const FileEntry *ToFile = AST->FileMgr->getFile(fname); if (!ToFile) { AST->getDiagnostics().Report(diag::err_fe_remap_missing_to_file) << RemappedFiles[I].first << fname; continue; } // Create the file entry for the file that we're mapping from. const FileEntry *FromFile = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, ToFile->getSize(), 0); if (!FromFile) { AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) << RemappedFiles[I].first; delete memBuf; continue; } // Override the contents of the "from" file with the contents of // the "to" file. AST->getSourceManager().overrideFileContents(FromFile, ToFile); } } // Gather Info for preprocessor construction later on. LangOptions LangInfo; ImportSearch &HeaderInfo = *AST->ImportInfo.get(); std::string TargetTriple; std::string Predefines; unsigned Counter; llvm::OwningPtr<ASTReader> Reader; Reader.reset(new ASTReader(AST->getSourceManager(), AST->getFileManager(), AST->getDiagnostics())); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<ASTReader> ReaderCleanup(Reader.get()); Reader->setListener(new ASTInfoCollector(LangInfo, HeaderInfo, TargetTriple, Predefines, Counter)); switch (Reader->ReadAST(Filename, ASTReader::MainFile)) { case ASTReader::Success: break; case ASTReader::Failure: case ASTReader::IgnorePCH: AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch); return NULL; } AST->OriginalSourceFile = Reader->getOriginalSourceFile(); // AST file loaded successfully. Now create the preprocessor. // Get information about the target being compiled for. // // FIXME: This is broken, we should store the TargetOptions in the AST file. TargetOptions TargetOpts; TargetOpts.ABI = ""; //TargetOpts.GmatABI = ""; TargetOpts.CPU = ""; TargetOpts.Features.clear(); TargetOpts.Triple = TargetTriple; AST->Target = TargetInfo::CreateTargetInfo(AST->getDiagnostics(), TargetOpts); AST->PP = new Preprocessor(AST->getDiagnostics(), LangInfo, *AST->Target, AST->getSourceManager(), HeaderInfo); Preprocessor &PP = *AST->PP; PP.setCounterValue(Counter); Reader->setPreprocessor(PP); // Create and initialize the ASTContext. AST->Ctx = new ASTContext(LangInfo, AST->getSourceManager(), *AST->Target, PP.getIdentifierTable(), PP.getBuiltinInfo(), /* size_reserve = */0); ASTContext &Context = *AST->Ctx; Reader->InitializeContext(Context); // Attach the AST reader to the AST context as an external AST // source, so that declarations will be deserialized from the // AST file as needed. ASTReader *ReaderPtr = Reader.get(); llvm::OwningPtr<ExternalASTSource> Source(Reader.take()); // Unregister the cleanup for ASTReader. It will get cleaned up // by the ASTUnit cleanup. ReaderCleanup.unregister(); Context.setExternalSource(Source); // Create an AST consumer, even though it isn't used. AST->Consumer.reset(new ASTConsumer); // Create a semantic analysis object and tell the AST reader about it. AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer)); AST->TheSema->Initialize(); ReaderPtr->InitializeSema(*AST->TheSema); return AST.take(); }