aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
commitb60736ec1405bb0a8dd40989f67ef4c93da068ab (patch)
tree5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
parentcfca06d7963fa0909f90483b42a6d7d194d01e08 (diff)
Diffstat (limited to 'lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp')
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp155
1 files changed, 95 insertions, 60 deletions
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<std::string> 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<std::string> 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<Materializer>();
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<ClangExpressionParser>(
+ 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();