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);
 }
예제 #3
0
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));
}
예제 #6
0
void DependencyFileGenerator::AttachToASTReader(ASTReader &R) {
  DFGImpl *I = reinterpret_cast<DFGImpl *>(Impl);
  assert(I && "missing implementation");
  R.addListener(llvm::make_unique<DFGASTReaderListener>(*I));
}
예제 #7
0
void DependencyCollector::attachToASTReader(ASTReader &R) {
  R.addListener(llvm::make_unique<DepCollectorASTListener>(*this));
}
예제 #8
0
void DependencyCollector::attachToASTReader(ASTReader &R) {
  R.addListener(new DepCollectorASTListener(*this));
}
void ModuleDependencyCollector::attachToASTReader(ASTReader &R) {
  R.addListener(llvm::make_unique<ModuleDependencyListener>(*this));
}
예제 #10
0
파일: ASTUnit.cpp 프로젝트: YabinHu/mlang
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();
}