unsigned ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, CodeCompleteConsumer *completion_consumer, unsigned completion_line, unsigned completion_column) { ClangDiagnosticManagerAdapter *adapter = static_cast<ClangDiagnosticManagerAdapter *>( m_compiler->getDiagnostics().getClient()); clang::TextDiagnosticBuffer *diag_buf = adapter->GetPassthrough(); diag_buf->FlushDiagnostics(m_compiler->getDiagnostics()); adapter->ResetManager(&diagnostic_manager); const char *expr_text = m_expr.Text(); clang::SourceManager &source_mgr = m_compiler->getSourceManager(); bool created_main_file = false; // Clang wants to do completion on a real file known by Clang's file manager, // so we have to create one to make this work. // TODO: We probably could also simulate to Clang's file manager that there // is a real file that contains our code. bool should_create_file = completion_consumer != nullptr; // We also want a real file on disk if we generate full debug info. should_create_file |= m_compiler->getCodeGenOpts().getDebugInfo() == codegenoptions::FullDebugInfo; if (should_create_file) { int temp_fd = -1; llvm::SmallString<128> result_path; if (FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) { tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr"); std::string temp_source_path = tmpdir_file_spec.GetPath(); llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path); } else { llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path); } if (temp_fd != -1) { lldb_private::File file(temp_fd, true); const size_t expr_text_len = strlen(expr_text); size_t bytes_written = expr_text_len; if (file.Write(expr_text, bytes_written).Success()) { if (bytes_written == expr_text_len) { file.Close(); source_mgr.setMainFileID( source_mgr.createFileID(m_file_manager->getFile(result_path), SourceLocation(), SrcMgr::C_User)); created_main_file = true; } } } } if (!created_main_file) { std::unique_ptr<MemoryBuffer> memory_buffer = MemoryBuffer::getMemBufferCopy(expr_text, __FUNCTION__); source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer))); } diag_buf->BeginSourceFile(m_compiler->getLangOpts(), &m_compiler->getPreprocessor()); ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper()); ASTConsumer *ast_transformer = type_system_helper->ASTTransformer(m_code_generator.get()); if (ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap()) decl_map->InstallCodeGenerator(m_code_generator.get()); // If we want to parse for code completion, we need to attach our code // completion consumer to the Sema and specify a completion position. // While parsing the Sema will call this consumer with the provided // completion suggestions. if (completion_consumer) { auto main_file = source_mgr.getFileEntryForID(source_mgr.getMainFileID()); auto &PP = m_compiler->getPreprocessor(); // Lines and columns start at 1 in Clang, but code completion positions are // indexed from 0, so we need to add 1 to the line and column here. ++completion_line; ++completion_column; PP.SetCodeCompletionPoint(main_file, completion_line, completion_column); } if (ast_transformer) { ast_transformer->Initialize(m_compiler->getASTContext()); ParseAST(m_compiler->getPreprocessor(), ast_transformer, m_compiler->getASTContext(), false, TU_Complete, completion_consumer); } else { m_code_generator->Initialize(m_compiler->getASTContext()); ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(), m_compiler->getASTContext(), false, TU_Complete, completion_consumer); } diag_buf->EndSourceFile(); unsigned num_errors = diag_buf->getNumErrors(); if (m_pp_callbacks && m_pp_callbacks->hasErrors()) { num_errors++; diagnostic_manager.PutString(eDiagnosticSeverityError, "while importing modules:"); diagnostic_manager.AppendMessageToDiagnostic( m_pp_callbacks->getErrorString()); } if (!num_errors) { if (type_system_helper->DeclMap() && !type_system_helper->DeclMap()->ResolveUnknownTypes()) { diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't infer the type of a variable"); num_errors++; } } if (!num_errors) { type_system_helper->CommitPersistentDecls(); } adapter->ResetManager(); return num_errors; }
unsigned ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager) { ClangDiagnosticManagerAdapter *adapter = static_cast<ClangDiagnosticManagerAdapter *>(m_compiler->getDiagnostics().getClient()); clang::TextDiagnosticBuffer *diag_buf = adapter->GetPassthrough(); diag_buf->FlushDiagnostics(m_compiler->getDiagnostics()); adapter->ResetManager(&diagnostic_manager); const char *expr_text = m_expr.Text(); clang::SourceManager &source_mgr = m_compiler->getSourceManager(); bool created_main_file = false; if (m_compiler->getCodeGenOpts().getDebugInfo() == codegenoptions::FullDebugInfo) { int temp_fd = -1; llvm::SmallString<PATH_MAX> result_path; FileSpec tmpdir_file_spec; if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) { tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr"); std::string temp_source_path = tmpdir_file_spec.GetPath(); llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path); } else { llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path); } if (temp_fd != -1) { lldb_private::File file(temp_fd, true); const size_t expr_text_len = strlen(expr_text); size_t bytes_written = expr_text_len; if (file.Write(expr_text, bytes_written).Success()) { if (bytes_written == expr_text_len) { file.Close(); source_mgr.setMainFileID(source_mgr.createFileID(m_file_manager->getFile(result_path), SourceLocation(), SrcMgr::C_User)); created_main_file = true; } } } } if (!created_main_file) { std::unique_ptr<MemoryBuffer> memory_buffer = MemoryBuffer::getMemBufferCopy(expr_text, __FUNCTION__); source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer))); } diag_buf->BeginSourceFile(m_compiler->getLangOpts(), &m_compiler->getPreprocessor()); ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper()); ASTConsumer *ast_transformer = type_system_helper->ASTTransformer(m_code_generator.get()); if (ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap()) decl_map->InstallCodeGenerator(m_code_generator.get()); if (ast_transformer) { ast_transformer->Initialize(m_compiler->getASTContext()); ParseAST(m_compiler->getPreprocessor(), ast_transformer, m_compiler->getASTContext()); } else { m_code_generator->Initialize(m_compiler->getASTContext()); ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(), m_compiler->getASTContext()); } diag_buf->EndSourceFile(); unsigned num_errors = diag_buf->getNumErrors(); if (m_pp_callbacks && m_pp_callbacks->hasErrors()) { num_errors++; diagnostic_manager.PutCString(eDiagnosticSeverityError, "while importing modules:"); diagnostic_manager.AppendMessageToDiagnostic(m_pp_callbacks->getErrorString().c_str()); } if (!num_errors) { if (type_system_helper->DeclMap() && !type_system_helper->DeclMap()->ResolveUnknownTypes()) { diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't infer the type of a variable"); num_errors++; } } if (!num_errors) { type_system_helper->CommitPersistentDecls(); } adapter->ResetManager(); return num_errors; }
unsigned ClangExpressionParser::Parse (DiagnosticManager &diagnostic_manager, uint32_t first_line, uint32_t last_line, uint32_t line_offset) { ClangDiagnosticManagerAdapter *adapter = static_cast<ClangDiagnosticManagerAdapter *>(m_compiler->getDiagnostics().getClient()); clang::TextDiagnosticBuffer *diag_buf = adapter->GetPassthrough(); diag_buf->FlushDiagnostics(m_compiler->getDiagnostics()); adapter->ResetManager(&diagnostic_manager); const char *expr_text = m_expr.Text(); clang::SourceManager &SourceMgr = m_compiler->getSourceManager(); bool created_main_file = false; if (m_expr.GetOptions() && m_expr.GetOptions()->GetPoundLineFilePath() == NULL && m_compiler->getCodeGenOpts().getDebugInfo() == CodeGenOptions::FullDebugInfo) { std::string temp_source_path; if (ExpressionSourceCode::SaveExpressionTextToTempFile(expr_text, *m_expr.GetOptions(), temp_source_path)) { auto file = m_file_manager->getFile(temp_source_path); if (file) { SourceMgr.setMainFileID(SourceMgr.createFileID (file, SourceLocation(), SrcMgr::C_User)); created_main_file = true; } } } if (!created_main_file) { std::unique_ptr<MemoryBuffer> memory_buffer = MemoryBuffer::getMemBufferCopy(expr_text, __FUNCTION__); SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(memory_buffer))); } diag_buf->BeginSourceFile(m_compiler->getLangOpts(), &m_compiler->getPreprocessor()); ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper()); ASTConsumer *ast_transformer = type_system_helper->ASTTransformer(m_code_generator.get()); if (ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap()) decl_map->InstallCodeGenerator(m_code_generator.get()); if (ast_transformer) { ast_transformer->Initialize(m_compiler->getASTContext()); ParseAST(m_compiler->getPreprocessor(), ast_transformer, m_compiler->getASTContext()); } else { m_code_generator->Initialize(m_compiler->getASTContext()); ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(), m_compiler->getASTContext()); } diag_buf->EndSourceFile(); unsigned num_errors = diag_buf->getNumErrors(); if (m_pp_callbacks && m_pp_callbacks->hasErrors()) { num_errors++; diagnostic_manager.PutCString(eDiagnosticSeverityError, "while importing modules:"); diagnostic_manager.AppendMessageToDiagnostic(m_pp_callbacks->getErrorString().c_str()); } if (!num_errors) { if (type_system_helper->DeclMap() && !type_system_helper->DeclMap()->ResolveUnknownTypes()) { diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't infer the type of a variable"); num_errors++; } } if (!num_errors) { type_system_helper->CommitPersistentDecls(); } adapter->ResetManager(); return num_errors; }