From b60736ec1405bb0a8dd40989f67ef4c93da068ab Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 16 Feb 2021 21:13:02 +0100 Subject: Vendor import of llvm-project main 8e464dd76bef, the last commit before the upstream release/12.x branch was created. --- .../ExpressionParser/Clang/ClangUserExpression.cpp | 155 +++++++++++++-------- 1 file changed, 95 insertions(+), 60 deletions(-) (limited to 'lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp') diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index a28b4a7fb42c..9be294750fa0 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -417,7 +417,6 @@ void ClangUserExpression::CreateSourceCode( DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, std::vector modules_to_import, bool for_completion) { - m_filename = m_clang_state->GetNextExprFileName(); std::string prefix = m_expr_prefix; if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) { @@ -477,9 +476,6 @@ CppModuleConfiguration GetModuleConfig(lldb::LanguageType language, if (!target) return LogConfigError("No target"); - if (!target->GetEnableImportStdModule()) - return LogConfigError("Importing std module not enabled in settings"); - StackFrame *frame = exe_ctx.GetFramePtr(); if (!frame) return LogConfigError("No frame"); @@ -529,8 +525,6 @@ CppModuleConfiguration GetModuleConfig(lldb::LanguageType language, bool ClangUserExpression::PrepareForParsing( DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, bool for_completion) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - InstallContext(exe_ctx); if (!SetupPersistentState(diagnostic_manager, exe_ctx)) @@ -551,50 +545,20 @@ bool ClangUserExpression::PrepareForParsing( SetupDeclVendor(exe_ctx, m_target, diagnostic_manager); - CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx); - llvm::ArrayRef imported_modules = - module_config.GetImportedModules(); - m_imported_cpp_modules = !imported_modules.empty(); - m_include_directories = module_config.GetIncludeDirs(); + m_filename = m_clang_state->GetNextExprFileName(); - LLDB_LOG(log, "List of imported modules in expression: {0}", - llvm::make_range(imported_modules.begin(), imported_modules.end())); - LLDB_LOG(log, "List of include directories gathered for modules: {0}", - llvm::make_range(m_include_directories.begin(), - m_include_directories.end())); + if (m_target->GetImportStdModule() == eImportStdModuleTrue) + SetupCppModuleImports(exe_ctx); - CreateSourceCode(diagnostic_manager, exe_ctx, imported_modules, + CreateSourceCode(diagnostic_manager, exe_ctx, m_imported_cpp_modules, for_completion); return true; } -bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, - ExecutionContext &exe_ctx, - lldb_private::ExecutionPolicy execution_policy, - bool keep_result_in_memory, - bool generate_debug_info) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - - if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ false)) - return false; - - LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str()); - - //////////////////////////////////// - // Set up the target and compiler - // - - Target *target = exe_ctx.GetTargetPtr(); - - if (!target) { - diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target"); - return false; - } - - ////////////////////////// - // Parse the expression - // - +bool ClangUserExpression::TryParse( + DiagnosticManager &diagnostic_manager, ExecutionContextScope *exe_scope, + ExecutionContext &exe_ctx, lldb_private::ExecutionPolicy execution_policy, + bool keep_result_in_memory, bool generate_debug_info) { m_materializer_up = std::make_unique(); ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory); @@ -612,26 +576,16 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, DeclMap()->SetLookupsEnabled(true); } - Process *process = exe_ctx.GetProcessPtr(); - ExecutionContextScope *exe_scope = process; - - if (!exe_scope) - exe_scope = exe_ctx.GetTargetPtr(); - - // We use a shared pointer here so we can use the original parser - if it - // succeeds or the rewrite parser we might make if it fails. But the - // parser_sp will never be empty. - - ClangExpressionParser parser(exe_scope, *this, generate_debug_info, - m_include_directories, m_filename); + m_parser = std::make_unique( + exe_scope, *this, generate_debug_info, m_include_directories, m_filename); - unsigned num_errors = parser.Parse(diagnostic_manager); + unsigned num_errors = m_parser->Parse(diagnostic_manager); // Check here for FixItHints. If there are any try to apply the fixits and // set the fixed text in m_fixed_text before returning an error. if (num_errors) { if (diagnostic_manager.HasFixIts()) { - if (parser.RewriteExpression(diagnostic_manager)) { + if (m_parser->RewriteExpression(diagnostic_manager)) { size_t fixed_start; size_t fixed_end; m_fixed_text = diagnostic_manager.GetFixedExpression(); @@ -652,7 +606,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, // { - Status jit_error = parser.PrepareForExecution( + Status jit_error = m_parser->PrepareForExecution( m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx, m_can_interpret, execution_policy); @@ -666,10 +620,91 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, return false; } } + return true; +} + +void ClangUserExpression::SetupCppModuleImports(ExecutionContext &exe_ctx) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx); + m_imported_cpp_modules = module_config.GetImportedModules(); + m_include_directories = module_config.GetIncludeDirs(); + + LLDB_LOG(log, "List of imported modules in expression: {0}", + llvm::make_range(m_imported_cpp_modules.begin(), + m_imported_cpp_modules.end())); + LLDB_LOG(log, "List of include directories gathered for modules: {0}", + llvm::make_range(m_include_directories.begin(), + m_include_directories.end())); +} + +static bool shouldRetryWithCppModule(Target &target, ExecutionPolicy exe_policy) { + // Top-level expression don't yet support importing C++ modules. + if (exe_policy == ExecutionPolicy::eExecutionPolicyTopLevel) + return false; + return target.GetImportStdModule() == eImportStdModuleFallback; +} + +bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, + ExecutionContext &exe_ctx, + lldb_private::ExecutionPolicy execution_policy, + bool keep_result_in_memory, + bool generate_debug_info) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ false)) + return false; + + LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str()); + + //////////////////////////////////// + // Set up the target and compiler + // + + Target *target = exe_ctx.GetTargetPtr(); + + if (!target) { + diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target"); + return false; + } + + ////////////////////////// + // Parse the expression + // + + Process *process = exe_ctx.GetProcessPtr(); + ExecutionContextScope *exe_scope = process; + + if (!exe_scope) + exe_scope = exe_ctx.GetTargetPtr(); + + bool parse_success = TryParse(diagnostic_manager, exe_scope, exe_ctx, + execution_policy, keep_result_in_memory, + generate_debug_info); + // If the expression failed to parse, check if retrying parsing with a loaded + // C++ module is possible. + if (!parse_success && shouldRetryWithCppModule(*target, execution_policy)) { + // Load the loaded C++ modules. + SetupCppModuleImports(exe_ctx); + // If we did load any modules, then retry parsing. + if (!m_imported_cpp_modules.empty()) { + // The module imports are injected into the source code wrapper, + // so recreate those. + CreateSourceCode(diagnostic_manager, exe_ctx, m_imported_cpp_modules, + /*for_completion*/ false); + // Clear the error diagnostics from the previous parse attempt. + diagnostic_manager.Clear(); + parse_success = TryParse(diagnostic_manager, exe_scope, exe_ctx, + execution_policy, keep_result_in_memory, + generate_debug_info); + } + } + if (!parse_success) + return false; if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel) { Status static_init_error = - parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx); + m_parser->RunStaticInitializers(m_execution_unit_sp, exe_ctx); if (!static_init_error.Success()) { const char *error_cstr = static_init_error.AsCString(); -- cgit v1.3