IncrementalParser::IncrementalParser(Interpreter* interp, 
                                       int argc, const char* const *argv,
                                       const char* llvmdir):
    m_Interpreter(interp),
    m_DynamicLookupEnabled(false),
    m_Consumer(0),
    m_FirstTopLevelDecl(0),
    m_LastTopLevelDecl(0),
    m_SyntaxOnly(false)
  {
    CompilerInstance* CI 
      = CIFactory::createCI(llvm::MemoryBuffer::getMemBuffer("", "CLING"), 
                            argc, argv, llvmdir);
    assert(CI && "CompilerInstance is (null)!");
    m_CI.reset(CI);
    m_SyntaxOnly 
      = CI->getFrontendOpts().ProgramAction == clang::frontend::ParseSyntaxOnly;

    CreateSLocOffsetGenerator();

    m_Consumer = dyn_cast<ChainedConsumer>(&CI->getASTConsumer());
    assert(m_Consumer && "Expected ChainedConsumer!");
    // Add consumers to the ChainedConsumer, which owns them
    EvaluateTSynthesizer* ES = new EvaluateTSynthesizer(interp);
    ES->Attach(m_Consumer);
    m_Consumer->Add(ChainedConsumer::kEvaluateTSynthesizer, ES);

    DeclExtractor* DE = new DeclExtractor();
    DE->Attach(m_Consumer);
    m_Consumer->Add(ChainedConsumer::kDeclExtractor, DE);

    ValuePrinterSynthesizer* VPS = new ValuePrinterSynthesizer(interp);
    VPS->Attach(m_Consumer);
    m_Consumer->Add(ChainedConsumer::kValuePrinterSynthesizer, VPS);
    m_Consumer->Add(ChainedConsumer::kASTDumper, new ASTDumper());
    if (!m_SyntaxOnly) {
      CodeGenerator* CG = CreateLLVMCodeGen(CI->getDiagnostics(), 
                                            "cling input",
                                            CI->getCodeGenOpts(), 
                                  /*Owned by codegen*/ * new llvm::LLVMContext()
                                            );
      assert(CG && "No CodeGen?!");
      m_Consumer->Add(ChainedConsumer::kCodeGenerator, CG);
    }
    m_Parser.reset(new Parser(CI->getPreprocessor(), CI->getSema(),
                              false /*skipFuncBodies*/));
    CI->getPreprocessor().EnterMainSourceFile();
    // Initialize the parser after we have entered the main source file.
    m_Parser->Initialize();
    // Perform initialization that occurs after the parser has been initialized 
    // but before it parses anything. Initializes the consumers too.
    CI->getSema().Initialize();
  }
Exemple #2
0
  IncrementalParser::IncrementalParser(Interpreter* interp,
                                       int argc, const char* const *argv,
                                       const char* llvmdir):
    m_Interpreter(interp), m_Consumer(0) {

    CompilerInstance* CI
      = CIFactory::createCI(0, argc, argv, llvmdir);
    assert(CI && "CompilerInstance is (null)!");

    m_Consumer = dyn_cast<DeclCollector>(&CI->getASTConsumer());
    assert(m_Consumer && "Expected ChainedConsumer!");
    m_Consumer->setInterpreter(interp);

    m_CI.reset(CI);

    if (CI->getFrontendOpts().ProgramAction != clang::frontend::ParseSyntaxOnly){
      m_CodeGen.reset(CreateLLVMCodeGen(CI->getDiagnostics(), "cling input",
                                        CI->getCodeGenOpts(),
                                        CI->getTargetOpts(),
                                        *m_Interpreter->getLLVMContext()
                                        ));
      m_Consumer->setCodeGen(m_CodeGen.get());
    }

    CreateSLocOffsetGenerator();

    // Add transformers to the IncrementalParser, which owns them
    Sema* TheSema = &CI->getSema();
    // Register the AST Transformers
    m_ASTTransformers.push_back(new EvaluateTSynthesizer(TheSema));
    m_ASTTransformers.push_back(new AutoSynthesizer(TheSema));
    m_ASTTransformers.push_back(new ValuePrinterSynthesizer(TheSema, 0));
    m_ASTTransformers.push_back(new ASTDumper());
    m_ASTTransformers.push_back(new DeclExtractor(TheSema));
    m_ASTTransformers.push_back(new ReturnSynthesizer(TheSema));
    
    // Register the IR Transformers
    m_IRTransformers.push_back(new IRDumper());
    m_IRTransformers.push_back(new NullDerefProtectionTransformer());
  }