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);
 }
  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));
    }
  }