diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:09:23 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:09:23 +0000 |
| commit | f73363f1dd94996356cefbf24388f561891acf0b (patch) | |
| tree | e3c31248bdb36eaec5fd833490d4278162dba2a0 /source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp | |
| parent | 160ee69dd7ae18978f4068116777639ea98dc951 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp')
| -rw-r--r-- | source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp | 164 |
1 files changed, 89 insertions, 75 deletions
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index 18fe8b49227b..2e61f704127a 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -65,7 +65,8 @@ ClangUserExpression::ClangUserExpression( options), m_type_system_helper(*m_target_wp.lock().get(), options.GetExecutionPolicy() == - eExecutionPolicyTopLevel) { + eExecutionPolicyTopLevel), + m_result_delegate(exe_scope.CalculateTarget()) { switch (m_language) { case lldb::eLanguageTypeC_plus_plus: m_allow_cxx = true; @@ -195,12 +196,10 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { } else if (clang::FunctionDecl *function_decl = ClangASTContext::DeclContextGetAsFunctionDecl(decl_context)) { // We might also have a function that said in the debug information that it - // captured an - // object pointer. The best way to deal with getting to the ivars at - // present is by pretending - // that this is a method of a class in whatever runtime the debug info says - // the object pointer - // belongs to. Do that here. + // captured an object pointer. The best way to deal with getting to the + // ivars at present is by pretending that this is a method of a class in + // whatever runtime the debug info says the object pointer belongs to. Do + // that here. ClangASTMetadata *metadata = ClangASTContext::DeclContextGetMetaData(decl_context, function_decl); @@ -290,10 +289,10 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { } } -// This is a really nasty hack, meant to fix Objective-C expressions of the form -// (int)[myArray count]. Right now, because the type information for count is -// not available, [myArray count] returns id, which can't be directly cast to -// int without causing a clang error. +// This is a really nasty hack, meant to fix Objective-C expressions of the +// form (int)[myArray count]. Right now, because the type information for +// count is not available, [myArray count] returns id, which can't be directly +// cast to int without causing a clang error. static void ApplyObjcCastHack(std::string &expr) { #define OBJC_CAST_HACK_FROM "(int)[" #define OBJC_CAST_HACK_TO "(int)(long long)[" @@ -308,17 +307,23 @@ static void ApplyObjcCastHack(std::string &expr) { #undef OBJC_CAST_HACK_FROM } -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)); +namespace { +// Utility guard that calls a callback when going out of scope. +class OnExit { +public: + typedef std::function<void(void)> Callback; - Status err; + OnExit(Callback const &callback) : m_callback(callback) {} - InstallContext(exe_ctx); + ~OnExit() { m_callback(); } + +private: + Callback m_callback; +}; +} // namespace +bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_manager, + ExecutionContext &exe_ctx) { if (Target *target = exe_ctx.GetTargetPtr()) { if (PersistentExpressionState *persistent_state = target->GetPersistentExpressionStateForLanguage( @@ -335,26 +340,15 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, "error: couldn't start parsing (no target)"); return false; } + return true; +} - ScanContext(exe_ctx, err); - - if (!err.Success()) { - diagnostic_manager.PutString(eDiagnosticSeverityWarning, err.AsCString()); - } - - //////////////////////////////////// - // Generate the expression - // - - ApplyObjcCastHack(m_expr_text); - - std::string prefix = m_expr_prefix; - +static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) { if (ClangModulesDeclVendor *decl_vendor = - m_target->GetClangModulesDeclVendor()) { + target->GetClangModulesDeclVendor()) { const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = llvm::cast<ClangPersistentVariables>( - m_target->GetPersistentExpressionStateForLanguage( + target->GetPersistentExpressionStateForLanguage( lldb::eLanguageTypeC)) ->GetHandLoadedClangModules(); ClangModulesDeclVendor::ModuleVector modules_for_macros; @@ -363,7 +357,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, modules_for_macros.push_back(module); } - if (m_target->GetEnableAutoImportClangModules()) { + if (target->GetEnableAutoImportClangModules()) { if (StackFrame *frame = exe_ctx.GetFramePtr()) { if (Block *block = frame->GetFrameBlock()) { SymbolContext sc; @@ -380,8 +374,13 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, } } } +} - lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown; +llvm::Optional<lldb::LanguageType> ClangUserExpression::GetLanguageForExpr( + DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) { + lldb::LanguageType lang_type = lldb::LanguageType::eLanguageTypeUnknown; + + std::string prefix = m_expr_prefix; if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) { m_transformed_text = m_expr_text; @@ -401,9 +400,50 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, exe_ctx)) { diagnostic_manager.PutString(eDiagnosticSeverityError, "couldn't construct expression body"); - return false; + return llvm::Optional<lldb::LanguageType>(); } } + return lang_type; +} + +bool ClangUserExpression::PrepareForParsing( + DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) { + InstallContext(exe_ctx); + + if (!SetupPersistentState(diagnostic_manager, exe_ctx)) + return false; + + Status err; + ScanContext(exe_ctx, err); + + if (!err.Success()) { + diagnostic_manager.PutString(eDiagnosticSeverityWarning, err.AsCString()); + } + + //////////////////////////////////// + // Generate the expression + // + + ApplyObjcCastHack(m_expr_text); + + SetupDeclVendor(exe_ctx, m_target); + 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)) + return false; + + lldb::LanguageType lang_type = lldb::LanguageType::eLanguageTypeUnknown; + if (auto new_lang = GetLanguageForExpr(diagnostic_manager, exe_ctx)) { + lang_type = new_lang.getValue(); + } if (log) log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str()); @@ -427,28 +467,12 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory); - class OnExit { - public: - typedef std::function<void(void)> Callback; - - OnExit(Callback const &callback) : m_callback(callback) {} - - ~OnExit() { m_callback(); } - - private: - Callback m_callback; - }; - OnExit on_exit([this]() { ResetDeclMap(); }); if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get())) { diagnostic_manager.PutString( eDiagnosticSeverityError, "current process state is unsuitable for expression parsing"); - - ResetDeclMap(); // We are being careful here in the case of breakpoint - // conditions. - return false; } @@ -463,17 +487,15 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, 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. + // 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); unsigned num_errors = 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. + // set the fixed text in m_fixed_text before returning an error. if (num_errors) { if (diagnostic_manager.HasFixIts()) { if (parser.RewriteExpression(diagnostic_manager)) { @@ -487,16 +509,12 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, fixed_expression.substr(fixed_start, fixed_end - fixed_start); } } - - ResetDeclMap(); // We are being careful here in the case of breakpoint - // conditions. - return false; } ////////////////////////////////////////////////////////////////////////////////////////// - // Prepare the output of the parser for execution, evaluating it statically if - // possible + // Prepare the output of the parser for execution, evaluating it statically + // if possible // { @@ -539,9 +557,9 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, register_execution_unit = true; } - // If there is more than one external function in the execution - // unit, it needs to keep living even if it's not top level, because - // the result could refer to that function. + // If there is more than one external function in the execution unit, it + // needs to keep living even if it's not top level, because the result + // could refer to that function. if (m_execution_unit_sp->GetJittedFunctions().size() > 1) { register_execution_unit = true; @@ -568,10 +586,6 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, } } - ResetDeclMap(); // Make this go away since we don't need any of its state - // after parsing. This also gets rid of any - // ClangASTImporter::Minions. - if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS) m_jit_process_wp = lldb::ProcessWP(process->shared_from_this()); return true; @@ -667,10 +681,10 @@ void ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls() { } } -ClangUserExpression::ResultDelegate::ResultDelegate() {} - ConstString ClangUserExpression::ResultDelegate::GetName() { - return m_persistent_state->GetNextPersistentVariableName(); + auto prefix = m_persistent_state->GetPersistentVariablePrefix(); + return m_persistent_state->GetNextPersistentVariableName(*m_target_sp, + prefix); } void ClangUserExpression::ResultDelegate::DidDematerialize( |
