1 //===-- ClangUserExpression.cpp ---------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include <stdio.h>
11 #if HAVE_SYS_TYPES_H
12 #  include <sys/types.h>
13 #endif
14 
15 #include <cstdlib>
16 #include <string>
17 #include <map>
18 
19 #include "ClangUserExpression.h"
20 
21 #include "ASTResultSynthesizer.h"
22 #include "ClangExpressionDeclMap.h"
23 #include "ClangExpressionParser.h"
24 #include "ClangModulesDeclVendor.h"
25 #include "ClangPersistentVariables.h"
26 #include "ClangDiagnostic.h"
27 
28 #include "lldb/Core/ConstString.h"
29 #include "lldb/Core/Log.h"
30 #include "lldb/Core/Module.h"
31 #include "lldb/Core/StreamFile.h"
32 #include "lldb/Core/StreamString.h"
33 #include "lldb/Core/ValueObjectConstResult.h"
34 #include "lldb/Expression/ExpressionSourceCode.h"
35 #include "lldb/Expression/IRExecutionUnit.h"
36 #include "lldb/Expression/IRInterpreter.h"
37 #include "lldb/Expression/Materializer.h"
38 #include "lldb/Host/HostInfo.h"
39 #include "lldb/Symbol/Block.h"
40 #include "lldb/Symbol/ClangASTContext.h"
41 #include "lldb/Symbol/Function.h"
42 #include "lldb/Symbol/ObjectFile.h"
43 #include "lldb/Symbol/SymbolVendor.h"
44 #include "lldb/Symbol/Type.h"
45 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
46 #include "lldb/Symbol/VariableList.h"
47 #include "lldb/Target/ExecutionContext.h"
48 #include "lldb/Target/Process.h"
49 #include "lldb/Target/StackFrame.h"
50 #include "lldb/Target/Target.h"
51 #include "lldb/Target/ThreadPlan.h"
52 #include "lldb/Target/ThreadPlanCallUserExpression.h"
53 
54 #include "clang/AST/DeclCXX.h"
55 #include "clang/AST/DeclObjC.h"
56 
57 using namespace lldb_private;
58 
59 ClangUserExpression::ClangUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
60                                          lldb::LanguageType language, ResultType desired_type,
61                                          const EvaluateExpressionOptions &options)
62     : LLVMUserExpression(exe_scope, expr, expr_prefix, language, desired_type, options),
63       m_type_system_helper(*m_target_wp.lock().get(), options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
64 {
65     switch (m_language)
66     {
67         case lldb::eLanguageTypeC_plus_plus:
68             m_allow_cxx = true;
69             break;
70         case lldb::eLanguageTypeObjC:
71             m_allow_objc = true;
72             break;
73         case lldb::eLanguageTypeObjC_plus_plus:
74         default:
75             m_allow_cxx = true;
76             m_allow_objc = true;
77             break;
78     }
79 }
80 
81 ClangUserExpression::~ClangUserExpression ()
82 {
83 }
84 
85 void
86 ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
87 {
88     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
89 
90     if (log)
91         log->Printf("ClangUserExpression::ScanContext()");
92 
93     m_target = exe_ctx.GetTargetPtr();
94 
95     if (!(m_allow_cxx || m_allow_objc))
96     {
97         if (log)
98             log->Printf("  [CUE::SC] Settings inhibit C++ and Objective-C");
99         return;
100     }
101 
102     StackFrame *frame = exe_ctx.GetFramePtr();
103     if (frame == NULL)
104     {
105         if (log)
106             log->Printf("  [CUE::SC] Null stack frame");
107         return;
108     }
109 
110     SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
111 
112     if (!sym_ctx.function)
113     {
114         if (log)
115             log->Printf("  [CUE::SC] Null function");
116         return;
117     }
118 
119     // Find the block that defines the function represented by "sym_ctx"
120     Block *function_block = sym_ctx.GetFunctionBlock();
121 
122     if (!function_block)
123     {
124         if (log)
125             log->Printf("  [CUE::SC] Null function block");
126         return;
127     }
128 
129     CompilerDeclContext decl_context = function_block->GetDeclContext();
130 
131     if (!decl_context)
132     {
133         if (log)
134             log->Printf("  [CUE::SC] Null decl context");
135         return;
136     }
137 
138     if (clang::CXXMethodDecl *method_decl = ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context))
139     {
140         if (m_allow_cxx && method_decl->isInstance())
141         {
142             if (m_enforce_valid_object)
143             {
144                 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
145 
146                 const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
147 
148                 if (!variable_list_sp)
149                 {
150                     err.SetErrorString(thisErrorString);
151                     return;
152                 }
153 
154                 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
155 
156                 if (!this_var_sp ||
157                     !this_var_sp->IsInScope(frame) ||
158                     !this_var_sp->LocationIsValidForFrame (frame))
159                 {
160                     err.SetErrorString(thisErrorString);
161                     return;
162                 }
163             }
164 
165             m_in_cplusplus_method = true;
166             m_needs_object_ptr = true;
167         }
168     }
169     else if (clang::ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(decl_context))
170     {
171         if (m_allow_objc)
172         {
173             if (m_enforce_valid_object)
174             {
175                 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
176 
177                 const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
178 
179                 if (!variable_list_sp)
180                 {
181                     err.SetErrorString(selfErrorString);
182                     return;
183                 }
184 
185                 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
186 
187                 if (!self_variable_sp ||
188                     !self_variable_sp->IsInScope(frame) ||
189                     !self_variable_sp->LocationIsValidForFrame (frame))
190                 {
191                     err.SetErrorString(selfErrorString);
192                     return;
193                 }
194             }
195 
196             m_in_objectivec_method = true;
197             m_needs_object_ptr = true;
198 
199             if (!method_decl->isInstanceMethod())
200                 m_in_static_method = true;
201         }
202     }
203     else if (clang::FunctionDecl *function_decl = ClangASTContext::DeclContextGetAsFunctionDecl(decl_context))
204     {
205         // We might also have a function that said in the debug information that it captured an
206         // object pointer.  The best way to deal with getting to the ivars at present is by pretending
207         // that this is a method of a class in whatever runtime the debug info says the object pointer
208         // belongs to.  Do that here.
209 
210         ClangASTMetadata *metadata = ClangASTContext::DeclContextGetMetaData (decl_context, function_decl);
211         if (metadata && metadata->HasObjectPtr())
212         {
213             lldb::LanguageType language = metadata->GetObjectPtrLanguage();
214             if (language == lldb::eLanguageTypeC_plus_plus)
215             {
216                 if (m_enforce_valid_object)
217                 {
218                     lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
219 
220                     const char *thisErrorString = "Stopped in a context claiming to capture a C++ object pointer, but 'this' isn't available; pretending we are in a generic context";
221 
222                     if (!variable_list_sp)
223                     {
224                         err.SetErrorString(thisErrorString);
225                         return;
226                     }
227 
228                     lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
229 
230                     if (!this_var_sp ||
231                         !this_var_sp->IsInScope(frame) ||
232                         !this_var_sp->LocationIsValidForFrame (frame))
233                     {
234                         err.SetErrorString(thisErrorString);
235                         return;
236                     }
237                 }
238 
239                 m_in_cplusplus_method = true;
240                 m_needs_object_ptr = true;
241             }
242             else if (language == lldb::eLanguageTypeObjC)
243             {
244                 if (m_enforce_valid_object)
245                 {
246                     lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
247 
248                     const char *selfErrorString = "Stopped in a context claiming to capture an Objective-C object pointer, but 'self' isn't available; pretending we are in a generic context";
249 
250                     if (!variable_list_sp)
251                     {
252                         err.SetErrorString(selfErrorString);
253                         return;
254                     }
255 
256                     lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
257 
258                     if (!self_variable_sp ||
259                         !self_variable_sp->IsInScope(frame) ||
260                         !self_variable_sp->LocationIsValidForFrame (frame))
261                     {
262                         err.SetErrorString(selfErrorString);
263                         return;
264                     }
265 
266                     Type *self_type = self_variable_sp->GetType();
267 
268                     if (!self_type)
269                     {
270                         err.SetErrorString(selfErrorString);
271                         return;
272                     }
273 
274                     CompilerType self_clang_type = self_type->GetForwardCompilerType ();
275 
276                     if (!self_clang_type)
277                     {
278                         err.SetErrorString(selfErrorString);
279                         return;
280                     }
281 
282                     if (ClangASTContext::IsObjCClassType(self_clang_type))
283                     {
284                         return;
285                     }
286                     else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type))
287                     {
288                         m_in_objectivec_method = true;
289                         m_needs_object_ptr = true;
290                     }
291                     else
292                     {
293                         err.SetErrorString(selfErrorString);
294                         return;
295                     }
296                 }
297                 else
298                 {
299                     m_in_objectivec_method = true;
300                     m_needs_object_ptr = true;
301                 }
302             }
303         }
304     }
305 }
306 
307 // This is a really nasty hack, meant to fix Objective-C expressions of the form
308 // (int)[myArray count].  Right now, because the type information for count is
309 // not available, [myArray count] returns id, which can't be directly cast to
310 // int without causing a clang error.
311 static void
312 ApplyObjcCastHack(std::string &expr)
313 {
314 #define OBJC_CAST_HACK_FROM "(int)["
315 #define OBJC_CAST_HACK_TO   "(int)(long long)["
316 
317     size_t from_offset;
318 
319     while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
320         expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
321 
322 #undef OBJC_CAST_HACK_TO
323 #undef OBJC_CAST_HACK_FROM
324 }
325 
326 bool
327 ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
328                            lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
329                            bool generate_debug_info)
330 {
331     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
332 
333     Error err;
334 
335     InstallContext(exe_ctx);
336 
337     if (Target *target = exe_ctx.GetTargetPtr())
338     {
339         if (PersistentExpressionState *persistent_state = target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))
340         {
341             m_result_delegate.RegisterPersistentState(persistent_state);
342         }
343         else
344         {
345             diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't start parsing (no persistent data)");
346             return false;
347         }
348     }
349     else
350     {
351         diagnostic_manager.PutCString(eDiagnosticSeverityError, "error: couldn't start parsing (no target)");
352         return false;
353     }
354 
355     ScanContext(exe_ctx, err);
356 
357     if (!err.Success())
358     {
359         diagnostic_manager.PutCString(eDiagnosticSeverityWarning, err.AsCString());
360     }
361 
362     ////////////////////////////////////
363     // Generate the expression
364     //
365 
366     ApplyObjcCastHack(m_expr_text);
367     //ApplyUnicharHack(m_expr_text);
368 
369     std::string prefix = m_expr_prefix;
370 
371     if (ClangModulesDeclVendor *decl_vendor = m_target->GetClangModulesDeclVendor())
372     {
373         const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = llvm::cast<ClangPersistentVariables>(m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))->GetHandLoadedClangModules();
374         ClangModulesDeclVendor::ModuleVector modules_for_macros;
375 
376         for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules)
377         {
378             modules_for_macros.push_back(module);
379         }
380 
381         if (m_target->GetEnableAutoImportClangModules())
382         {
383             if (StackFrame *frame = exe_ctx.GetFramePtr())
384             {
385                 if (Block *block = frame->GetFrameBlock())
386                 {
387                     SymbolContext sc;
388 
389                     block->CalculateSymbolContext(&sc);
390 
391                     if (sc.comp_unit)
392                     {
393                         StreamString error_stream;
394 
395                         decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream);
396                     }
397                 }
398             }
399         }
400     }
401 
402     lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown;
403 
404     if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
405     {
406         m_transformed_text = m_expr_text;
407     }
408     else
409     {
410         std::unique_ptr<ExpressionSourceCode> source_code(
411             ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str()));
412 
413         if (m_in_cplusplus_method)
414             lang_type = lldb::eLanguageTypeC_plus_plus;
415         else if (m_in_objectivec_method)
416             lang_type = lldb::eLanguageTypeObjC;
417         else
418             lang_type = lldb::eLanguageTypeC;
419 
420         if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_in_static_method, exe_ctx))
421         {
422             diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't construct expression body");
423             return false;
424         }
425     }
426 
427     if (log)
428         log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
429 
430     ////////////////////////////////////
431     // Set up the target and compiler
432     //
433 
434     Target *target = exe_ctx.GetTargetPtr();
435 
436     if (!target)
437     {
438         diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
439         return false;
440     }
441 
442     //////////////////////////
443     // Parse the expression
444     //
445 
446     m_materializer_ap.reset(new Materializer());
447 
448     ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
449 
450     class OnExit
451     {
452     public:
453         typedef std::function <void (void)> Callback;
454 
455         OnExit (Callback const &callback) :
456             m_callback(callback)
457         {
458         }
459 
460         ~OnExit ()
461         {
462             m_callback();
463         }
464     private:
465         Callback m_callback;
466     };
467 
468     OnExit on_exit([this]() { ResetDeclMap(); });
469 
470     if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get()))
471     {
472         diagnostic_manager.PutCString(eDiagnosticSeverityError,
473                                       "current process state is unsuitable for expression parsing");
474 
475         ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
476 
477         return false;
478     }
479 
480     if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
481     {
482         DeclMap()->SetLookupsEnabled(true);
483     }
484 
485     Process *process = exe_ctx.GetProcessPtr();
486     ExecutionContextScope *exe_scope = process;
487 
488     if (!exe_scope)
489         exe_scope = exe_ctx.GetTargetPtr();
490 
491     // We use a shared pointer here so we can use the original parser - if it succeeds
492     // or the rewrite parser we might make if it fails.  But the parser_sp will never be empty.
493 
494     ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
495 
496     unsigned num_errors = parser.Parse(diagnostic_manager);
497 
498     // Check here for FixItHints.  If there are any try to apply the fixits and set the fixed text in m_fixed_text
499     // before returning an error.
500     if (num_errors)
501     {
502         if (diagnostic_manager.HasFixIts())
503         {
504             if (parser.RewriteExpression(diagnostic_manager))
505             {
506                 size_t fixed_start;
507                 size_t fixed_end;
508                 const std::string &fixed_expression = diagnostic_manager.GetFixedExpression();
509                 if (ExpressionSourceCode::GetOriginalBodyBounds(fixed_expression, lang_type, fixed_start, fixed_end))
510                     m_fixed_text = fixed_expression.substr(fixed_start, fixed_end - fixed_start);
511             }
512         }
513         diagnostic_manager.Printf(eDiagnosticSeverityError, "%u error%s parsing expression", num_errors,
514                                   num_errors == 1 ? "" : "s");
515 
516         ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
517 
518         return false;
519     }
520 
521     //////////////////////////////////////////////////////////////////////////////////////////
522     // Prepare the output of the parser for execution, evaluating it statically if possible
523     //
524 
525     {
526         Error jit_error = parser.PrepareForExecution(m_jit_start_addr,
527                                                      m_jit_end_addr,
528                                                      m_execution_unit_sp,
529                                                      exe_ctx,
530                                                      m_can_interpret,
531                                                      execution_policy);
532 
533         if (!jit_error.Success())
534         {
535             const char *error_cstr = jit_error.AsCString();
536             if (error_cstr && error_cstr[0])
537                 diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
538             else
539                 diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
540             return false;
541         }
542     }
543 
544     if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel)
545     {
546         Error static_init_error = parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx);
547 
548         if (!static_init_error.Success())
549         {
550             const char *error_cstr = static_init_error.AsCString();
551             if (error_cstr && error_cstr[0])
552                 diagnostic_manager.Printf(eDiagnosticSeverityError, "couldn't run static initializers: %s\n",
553                                           error_cstr);
554             else
555                 diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't run static initializers\n");
556             return false;
557         }
558     }
559 
560     if (m_execution_unit_sp)
561     {
562         bool register_execution_unit = false;
563 
564         if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
565         {
566             register_execution_unit = true;
567         }
568 
569         // If there is more than one external function in the execution
570         // unit, it needs to keep living even if it's not top level, because
571         // the result could refer to that function.
572 
573         if (m_execution_unit_sp->GetJittedFunctions().size() > 1)
574         {
575             register_execution_unit = true;
576         }
577 
578         if (register_execution_unit)
579         {
580             llvm::cast<PersistentExpressionState>(
581                 exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(m_language))
582                 ->RegisterExecutionUnit(m_execution_unit_sp);
583         }
584     }
585 
586     if (generate_debug_info)
587     {
588         lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
589 
590         if (jit_module_sp)
591         {
592             ConstString const_func_name(FunctionName());
593             FileSpec jit_file;
594             jit_file.GetFilename() = const_func_name;
595             jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
596             m_jit_module_wp = jit_module_sp;
597             target->GetImages().Append(jit_module_sp);
598         }
599     }
600 
601     ResetDeclMap(); // Make this go away since we don't need any of its state after parsing.  This also gets rid of any
602                     // ClangASTImporter::Minions.
603 
604     if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
605         m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
606     return true;
607 }
608 
609 bool
610 ClangUserExpression::AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
611                                   lldb::addr_t struct_address, DiagnosticManager &diagnostic_manager)
612 {
613     lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
614     lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
615 
616     if (m_needs_object_ptr)
617     {
618         lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
619         if (!frame_sp)
620             return true;
621 
622         ConstString object_name;
623 
624         if (m_in_cplusplus_method)
625         {
626             object_name.SetCString("this");
627         }
628         else if (m_in_objectivec_method)
629         {
630             object_name.SetCString("self");
631         }
632         else
633         {
634             diagnostic_manager.PutCString(eDiagnosticSeverityError, "need object pointer but don't know the language");
635             return false;
636         }
637 
638         Error object_ptr_error;
639 
640         object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
641 
642         if (!object_ptr_error.Success())
643         {
644             diagnostic_manager.Printf(eDiagnosticSeverityWarning,
645                                       "couldn't get required object pointer (substituting NULL): %s",
646                                       object_ptr_error.AsCString());
647             object_ptr = 0;
648         }
649 
650         if (m_in_objectivec_method)
651         {
652             ConstString cmd_name("_cmd");
653 
654             cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
655 
656             if (!object_ptr_error.Success())
657             {
658                 diagnostic_manager.Printf(eDiagnosticSeverityWarning,
659                                           "couldn't get cmd pointer (substituting NULL): %s",
660                                           object_ptr_error.AsCString());
661                 cmd_ptr = 0;
662             }
663         }
664         if (object_ptr)
665             args.push_back(object_ptr);
666 
667         if (m_in_objectivec_method)
668             args.push_back(cmd_ptr);
669 
670         args.push_back(struct_address);
671     }
672     else
673     {
674         args.push_back(struct_address);
675     }
676     return true;
677 }
678 
679 lldb::ExpressionVariableSP
680 ClangUserExpression::GetResultAfterDematerialization(ExecutionContextScope *exe_scope)
681 {
682     return m_result_delegate.GetVariable();
683 }
684 
685 void
686 ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &delegate, bool keep_result_in_memory)
687 {
688     m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx));
689 }
690 
691 clang::ASTConsumer *
692 ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(clang::ASTConsumer *passthrough)
693 {
694     m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough, m_top_level, m_target));
695 
696     return m_result_synthesizer_up.get();
697 }
698 
699 void
700 ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls()
701 {
702     if (m_result_synthesizer_up.get())
703     {
704         m_result_synthesizer_up->CommitPersistentDecls();
705     }
706 }
707 
708 ClangUserExpression::ResultDelegate::ResultDelegate()
709 {
710 }
711 
712 ConstString
713 ClangUserExpression::ResultDelegate::GetName()
714 {
715     return m_persistent_state->GetNextPersistentVariableName();
716 }
717 
718 void
719 ClangUserExpression::ResultDelegate::DidDematerialize(lldb::ExpressionVariableSP &variable)
720 {
721     m_variable = variable;
722 }
723 
724 void
725 ClangUserExpression::ResultDelegate::RegisterPersistentState(PersistentExpressionState *persistent_state)
726 {
727     m_persistent_state = persistent_state;
728 }
729 
730 lldb::ExpressionVariableSP &
731 ClangUserExpression::ResultDelegate::GetVariable()
732 {
733     return m_variable;
734 }
735 
736