summaryrefslogtreecommitdiff
path: root/include/lldb/Target/ExecutionContext.h
blob: 167189c3a83753d6f41b4da9d6088bdfd2ace35f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
//===-- ExecutionContext.h --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_ExecutionContext_h_
#define liblldb_ExecutionContext_h_

#include <mutex>

#include "lldb/Target/StackID.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

//===----------------------------------------------------------------------===//
/// Execution context objects refer to objects in the execution of the program
/// that is being debugged. The consist of one or more of the following
/// objects: target, process, thread, and frame. Many objects in the debugger
/// need to track different executions contexts. For example, a local function
/// variable might have an execution context that refers to a stack frame. A
/// global or static variable might refer to a target since a stack frame
/// isn't required in order to evaluate a global or static variable (a process
/// isn't necessarily needed for a global variable since we might be able to
/// read the variable value from a data section in one of the object files in
/// a target). There are two types of objects that hold onto execution
/// contexts: ExecutionContextRef and ExecutionContext. Both of these objects
/// are described below.
///
/// Not all objects in an ExecutionContext objects will be valid. If you want
/// to refer strongly (ExecutionContext) or weakly (ExecutionContextRef) to a
/// process, then only the process and target references will be valid. For
/// threads, only the thread, process and target references will be filled in.
/// For frames, all of the objects will be filled in.
///
/// These classes are designed to be used as baton objects that get passed to
/// a wide variety of functions that require execution contexts.
//===----------------------------------------------------------------------===//

//----------------------------------------------------------------------
/// @class ExecutionContextRef ExecutionContext.h
/// "lldb/Target/ExecutionContext.h"
/// A class that holds a weak reference to an execution context.
///
/// ExecutionContextRef objects are designed to hold onto an execution context
/// that might change over time. For example, if an object wants to refer to a
/// stack frame, it should hold onto an ExecutionContextRef to a frame object.
/// The backing object that represents the stack frame might change over time
/// and instances of this object can track the logical object that refers to a
/// frame even if it does change.
///
/// These objects also don't keep execution objects around longer than they
/// should since they use weak pointers. For example if an object refers to a
/// stack frame and a stack frame is no longer in a thread, then a
/// ExecutionContextRef object that refers to that frame will not be able to
/// get a shared pointer to those objects since they are no longer around.
///
/// ExecutionContextRef objects can also be used as objects in classes that
/// want to track a "previous execution context". Since the weak references to
/// the execution objects (target, process, thread and frame) don't keep these
/// objects around, they are safe to keep around.
///
/// The general rule of thumb is all long lived objects that want to refer to
/// execution contexts should use ExecutionContextRef objects. The
/// ExecutionContext class is used to temporarily get shared pointers to any
/// execution context objects that are still around so they are guaranteed to
/// exist during a function that requires the objects. ExecutionContext
/// objects should NOT be used for long term storage since they will keep
/// objects alive with extra shared pointer references to these  objects.
//----------------------------------------------------------------------
class ExecutionContextRef {
public:
  //------------------------------------------------------------------
  /// Default Constructor.
  //------------------------------------------------------------------
  ExecutionContextRef();

  //------------------------------------------------------------------
  /// Copy Constructor.
  //------------------------------------------------------------------
  ExecutionContextRef(const ExecutionContextRef &rhs);

  //------------------------------------------------------------------
  /// Construct using an ExecutionContext object that might be nullptr.
  ///
  /// If \a exe_ctx_ptr is valid, then make weak references to any valid
  /// objects in the ExecutionContext, otherwise no weak references to any
  /// execution context objects will be made.
  //------------------------------------------------------------------
  ExecutionContextRef(const ExecutionContext *exe_ctx_ptr);

  //------------------------------------------------------------------
  /// Construct using an ExecutionContext object.
  ///
  /// Make weak references to any valid objects in the ExecutionContext.
  //------------------------------------------------------------------
  ExecutionContextRef(const ExecutionContext &exe_ctx);

  //------------------------------------------------------------------
  /// Construct using the target and all the selected items inside of it (the
  /// process and its selected thread, and the thread's selected frame). If
  /// there is no selected thread, default to the first thread If there is no
  /// selected frame, default to the first frame.
  //------------------------------------------------------------------
  ExecutionContextRef(Target *target, bool adopt_selected);

  //------------------------------------------------------------------
  /// Construct using an execution context scope.
  ///
  /// If the ExecutionContextScope object is valid and refers to a frame, make
  /// weak references too the frame, thread, process and target. If the
  /// ExecutionContextScope object is valid and refers to a thread, make weak
  /// references too the thread, process and target. If the
  /// ExecutionContextScope object is valid and refers to a process, make weak
  /// references too the process and target. If the ExecutionContextScope
  /// object is valid and refers to a target, make weak references too the
  /// target.
  //------------------------------------------------------------------
  ExecutionContextRef(ExecutionContextScope *exe_scope);

  //------------------------------------------------------------------
  /// Construct using an execution context scope.
  ///
  /// If the ExecutionContextScope object refers to a frame, make weak
  /// references too the frame, thread, process and target. If the
  /// ExecutionContextScope object refers to a thread, make weak references
  /// too the thread, process and target. If the ExecutionContextScope object
  /// refers to a process, make weak references too the process and target. If
  /// the ExecutionContextScope object refers to a target, make weak
  /// references too the target.
  //------------------------------------------------------------------
  ExecutionContextRef(ExecutionContextScope &exe_scope);

  ~ExecutionContextRef();

  //------------------------------------------------------------------
  /// Assignment operator
  ///
  /// Copy all weak references in \a rhs.
  //------------------------------------------------------------------
  ExecutionContextRef &operator=(const ExecutionContextRef &rhs);

  //------------------------------------------------------------------
  /// Assignment operator from a ExecutionContext
  ///
  /// Make weak references to any strongly referenced objects in \a exe_ctx.
  //------------------------------------------------------------------
  ExecutionContextRef &operator=(const ExecutionContext &exe_ctx);

  //------------------------------------------------------------------
  /// Clear the object's state.
  ///
  /// Sets the process and thread to nullptr, and the frame index to an
  /// invalid value.
  //------------------------------------------------------------------
  void Clear();

  //------------------------------------------------------------------
  /// Set accessor that creates a weak reference to the target referenced in
  /// \a target_sp.
  ///
  /// If \a target_sp is valid this object will create a weak reference to
  /// that object, otherwise any previous target weak reference contained in
  /// this object will be reset.
  ///
  /// Only the weak reference to the target will be updated, no other weak
  /// references will be modified. If you want this execution context to make
  /// a weak reference to the target's process, use the
  /// ExecutionContextRef::SetContext() functions.
  ///
  /// @see ExecutionContextRef::SetContext(const lldb::TargetSP &, bool)
  //------------------------------------------------------------------
  void SetTargetSP(const lldb::TargetSP &target_sp);

  //------------------------------------------------------------------
  /// Set accessor that creates a weak reference to the process referenced in
  /// \a process_sp.
  ///
  /// If \a process_sp is valid this object will create a weak reference to
  /// that object, otherwise any previous process weak reference contained in
  /// this object will be reset.
  ///
  /// Only the weak reference to the process will be updated, no other weak
  /// references will be modified. If you want this execution context to make
  /// a weak reference to the target, use the
  /// ExecutionContextRef::SetContext() functions.
  ///
  /// @see ExecutionContextRef::SetContext(const lldb::ProcessSP &)
  //------------------------------------------------------------------
  void SetProcessSP(const lldb::ProcessSP &process_sp);

  //------------------------------------------------------------------
  /// Set accessor that creates a weak reference to the thread referenced in
  /// \a thread_sp.
  ///
  /// If \a thread_sp is valid this object will create a weak reference to
  /// that object, otherwise any previous thread weak reference contained in
  /// this object will be reset.
  ///
  /// Only the weak reference to the thread will be updated, no other weak
  /// references will be modified. If you want this execution context to make
  /// a weak reference to the thread's process and target, use the
  /// ExecutionContextRef::SetContext() functions.
  ///
  /// @see ExecutionContextRef::SetContext(const lldb::ThreadSP &)
  //------------------------------------------------------------------
  void SetThreadSP(const lldb::ThreadSP &thread_sp);

  //------------------------------------------------------------------
  /// Set accessor that creates a weak reference to the frame referenced in \a
  /// frame_sp.
  ///
  /// If \a frame_sp is valid this object will create a weak reference to that
  /// object, otherwise any previous frame weak reference contained in this
  /// object will be reset.
  ///
  /// Only the weak reference to the frame will be updated, no other weak
  /// references will be modified. If you want this execution context to make
  /// a weak reference to the frame's thread, process and target, use the
  /// ExecutionContextRef::SetContext() functions.
  ///
  /// @see ExecutionContextRef::SetContext(const lldb::StackFrameSP &)
  //------------------------------------------------------------------
  void SetFrameSP(const lldb::StackFrameSP &frame_sp);

  void SetTargetPtr(Target *target, bool adopt_selected);

  void SetProcessPtr(Process *process);

  void SetThreadPtr(Thread *thread);

  void SetFramePtr(StackFrame *frame);

  //------------------------------------------------------------------
  /// Get accessor that creates a strong reference from the weak target
  /// reference contained in this object.
  ///
  /// @returns
  ///     A shared pointer to a target that is not guaranteed to be valid.
  //------------------------------------------------------------------
  lldb::TargetSP GetTargetSP() const;

  //------------------------------------------------------------------
  /// Get accessor that creates a strong reference from the weak process
  /// reference contained in this object.
  ///
  /// @returns
  ///     A shared pointer to a process that is not guaranteed to be valid.
  //------------------------------------------------------------------
  lldb::ProcessSP GetProcessSP() const;

  //------------------------------------------------------------------
  /// Get accessor that creates a strong reference from the weak thread
  /// reference contained in this object.
  ///
  /// @returns
  ///     A shared pointer to a thread that is not guaranteed to be valid.
  //------------------------------------------------------------------
  lldb::ThreadSP GetThreadSP() const;

  //------------------------------------------------------------------
  /// Get accessor that creates a strong reference from the weak frame
  /// reference contained in this object.
  ///
  /// @returns
  ///     A shared pointer to a frame that is not guaranteed to be valid.
  //------------------------------------------------------------------
  lldb::StackFrameSP GetFrameSP() const;

  //------------------------------------------------------------------
  /// Create an ExecutionContext object from this object.
  ///
  /// Create strong references to any execution context objects that are still
  /// valid. Any of the returned shared pointers in the ExecutionContext
  /// objects is not guaranteed to be valid. @returns
  ///     An execution context object that has strong references to
  ///     any valid weak references in this object.
  //------------------------------------------------------------------
  ExecutionContext Lock(bool thread_and_frame_only_if_stopped) const;

  //------------------------------------------------------------------
  /// Returns true if this object has a weak reference to a thread. The return
  /// value is only an indication of whether this object has a weak reference
  /// and does not indicate whether the weak reference is valid or not.
  //------------------------------------------------------------------
  bool HasThreadRef() const { return m_tid != LLDB_INVALID_THREAD_ID; }

  //------------------------------------------------------------------
  /// Returns true if this object has a weak reference to a frame. The return
  /// value is only an indication of whether this object has a weak reference
  /// and does not indicate whether the weak reference is valid or not.
  //------------------------------------------------------------------
  bool HasFrameRef() const { return m_stack_id.IsValid(); }

  void ClearThread() {
    m_thread_wp.reset();
    m_tid = LLDB_INVALID_THREAD_ID;
  }

  void ClearFrame() { m_stack_id.Clear(); }

protected:
  //------------------------------------------------------------------
  // Member variables
  //------------------------------------------------------------------
  lldb::TargetWP m_target_wp;         ///< A weak reference to a target
  lldb::ProcessWP m_process_wp;       ///< A weak reference to a process
  mutable lldb::ThreadWP m_thread_wp; ///< A weak reference to a thread
  lldb::tid_t m_tid;  ///< The thread ID that this object refers to in case the
                      ///backing object changes
  StackID m_stack_id; ///< The stack ID that this object refers to in case the
                      ///backing object changes
};

//----------------------------------------------------------------------
/// @class ExecutionContext ExecutionContext.h
/// "lldb/Target/ExecutionContext.h"
/// A class that contains an execution context.
///
/// This baton object can be passed into any function that requires a context
/// that specifies a target, process, thread and frame. These objects are
/// designed to be used for short term execution context object storage while
/// a function might be trying to evaluate something that requires a thread or
/// frame. ExecutionContextRef objects can be used to initialize one of these
/// objects to turn the weak execution context object references to the
/// target, process, thread and frame into strong references (shared pointers)
/// so that functions can guarantee that these objects won't go away in the
/// middle of a function.
///
/// ExecutionContext objects should be used as short lived objects (typically
/// on the stack) in order to lock down an execution context for local use and
/// for passing down to other functions that also require specific contexts.
/// They should NOT be used for long term storage, for long term storage use
/// ExecutionContextRef objects.
//----------------------------------------------------------------------
class ExecutionContext {
public:
  //------------------------------------------------------------------
  /// Default Constructor.
  //------------------------------------------------------------------
  ExecutionContext();

  //------------------------------------------------------------------
  // Copy constructor
  //------------------------------------------------------------------
  ExecutionContext(const ExecutionContext &rhs);

  //------------------------------------------------------------------
  // Adopt the target and optionally its current context.
  //------------------------------------------------------------------
  ExecutionContext(Target *t, bool fill_current_process_thread_frame = true);

  //------------------------------------------------------------------
  // Create execution contexts from shared pointers
  //------------------------------------------------------------------
  ExecutionContext(const lldb::TargetSP &target_sp, bool get_process);
  ExecutionContext(const lldb::ProcessSP &process_sp);
  ExecutionContext(const lldb::ThreadSP &thread_sp);
  ExecutionContext(const lldb::StackFrameSP &frame_sp);

  //------------------------------------------------------------------
  // Create execution contexts from weak pointers
  //------------------------------------------------------------------
  ExecutionContext(const lldb::TargetWP &target_wp, bool get_process);
  ExecutionContext(const lldb::ProcessWP &process_wp);
  ExecutionContext(const lldb::ThreadWP &thread_wp);
  ExecutionContext(const lldb::StackFrameWP &frame_wp);
  ExecutionContext(const ExecutionContextRef &exe_ctx_ref);
  ExecutionContext(const ExecutionContextRef *exe_ctx_ref,
                   bool thread_and_frame_only_if_stopped = false);

  // These two variants take in a locker, and grab the target, lock the API
  // mutex into locker, then fill in the rest of the shared pointers.
  ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
                   std::unique_lock<std::recursive_mutex> &locker);
  ExecutionContext(const ExecutionContextRef *exe_ctx_ref,
                   std::unique_lock<std::recursive_mutex> &locker);
  //------------------------------------------------------------------
  // Create execution contexts from execution context scopes
  //------------------------------------------------------------------
  ExecutionContext(ExecutionContextScope *exe_scope);
  ExecutionContext(ExecutionContextScope &exe_scope);

  //------------------------------------------------------------------
  /// Construct with process, thread, and frame index.
  ///
  /// Initialize with process \a p, thread \a t, and frame index \a f.
  ///
  /// @param[in] process
  ///     The process for this execution context.
  ///
  /// @param[in] thread
  ///     The thread for this execution context.
  ///
  /// @param[in] frame
  ///     The frame index for this execution context.
  //------------------------------------------------------------------
  ExecutionContext(Process *process, Thread *thread = nullptr,
                   StackFrame *frame = nullptr);

  ~ExecutionContext();

  ExecutionContext &operator=(const ExecutionContext &rhs);

  bool operator==(const ExecutionContext &rhs) const;

  bool operator!=(const ExecutionContext &rhs) const;

  //------------------------------------------------------------------
  /// Clear the object's state.
  ///
  /// Sets the process and thread to nullptr, and the frame index to an
  /// invalid value.
  //------------------------------------------------------------------
  void Clear();

  RegisterContext *GetRegisterContext() const;

  ExecutionContextScope *GetBestExecutionContextScope() const;

  uint32_t GetAddressByteSize() const;

  lldb::ByteOrder GetByteOrder() const;

  //------------------------------------------------------------------
  /// Returns a pointer to the target object.
  ///
  /// The returned pointer might be nullptr. Calling HasTargetScope(),
  /// HasProcessScope(), HasThreadScope(), or HasFrameScope() can help to pre-
  /// validate this pointer so that this accessor can freely be used without
  /// having to check for nullptr each time.
  ///
  /// @see ExecutionContext::HasTargetScope() const @see
  /// ExecutionContext::HasProcessScope() const @see
  /// ExecutionContext::HasThreadScope() const @see
  /// ExecutionContext::HasFrameScope() const
  //------------------------------------------------------------------
  Target *GetTargetPtr() const;

  //------------------------------------------------------------------
  /// Returns a pointer to the process object.
  ///
  /// The returned pointer might be nullptr. Calling HasProcessScope(),
  /// HasThreadScope(), or HasFrameScope()  can help to pre-validate this
  /// pointer so that this accessor can freely be used without having to check
  /// for nullptr each time.
  ///
  /// @see ExecutionContext::HasProcessScope() const @see
  /// ExecutionContext::HasThreadScope() const @see
  /// ExecutionContext::HasFrameScope() const
  //------------------------------------------------------------------
  Process *GetProcessPtr() const;

  //------------------------------------------------------------------
  /// Returns a pointer to the thread object.
  ///
  /// The returned pointer might be nullptr. Calling HasThreadScope() or
  /// HasFrameScope() can help to pre-validate this pointer so that this
  /// accessor can freely be used without having to check for nullptr each
  /// time.
  ///
  /// @see ExecutionContext::HasThreadScope() const @see
  /// ExecutionContext::HasFrameScope() const
  //------------------------------------------------------------------
  Thread *GetThreadPtr() const { return m_thread_sp.get(); }

  //------------------------------------------------------------------
  /// Returns a pointer to the frame object.
  ///
  /// The returned pointer might be nullptr. Calling HasFrameScope(), can help
  /// to pre-validate this pointer so that this accessor can freely be used
  /// without having to check for nullptr each time.
  ///
  /// @see ExecutionContext::HasFrameScope() const
  //------------------------------------------------------------------
  StackFrame *GetFramePtr() const { return m_frame_sp.get(); }

  //------------------------------------------------------------------
  /// Returns a reference to the target object.
  ///
  /// Clients should call HasTargetScope(), HasProcessScope(),
  /// HasThreadScope(), or HasFrameScope() prior to calling this function to
  /// ensure that this ExecutionContext object contains a valid target.
  ///
  /// @see ExecutionContext::HasTargetScope() const @see
  /// ExecutionContext::HasProcessScope() const @see
  /// ExecutionContext::HasThreadScope() const @see
  /// ExecutionContext::HasFrameScope() const
  //------------------------------------------------------------------
  Target &GetTargetRef() const;

  //------------------------------------------------------------------
  /// Returns a reference to the process object.
  ///
  /// Clients should call HasProcessScope(), HasThreadScope(), or
  /// HasFrameScope() prior to calling this  function to ensure that this
  /// ExecutionContext object contains a valid target.
  ///
  /// @see ExecutionContext::HasProcessScope() const @see
  /// ExecutionContext::HasThreadScope() const @see
  /// ExecutionContext::HasFrameScope() const
  //------------------------------------------------------------------
  Process &GetProcessRef() const;

  //------------------------------------------------------------------
  /// Returns a reference to the thread object.
  ///
  /// Clients should call HasThreadScope(), or  HasFrameScope() prior to
  /// calling this  function to ensure that  this ExecutionContext object
  /// contains a valid target.
  ///
  /// @see ExecutionContext::HasThreadScope() const @see
  /// ExecutionContext::HasFrameScope() const
  //------------------------------------------------------------------
  Thread &GetThreadRef() const;

  //------------------------------------------------------------------
  /// Returns a reference to the thread object.
  ///
  /// Clients should call HasFrameScope() prior to calling this function to
  /// ensure that  this ExecutionContext object contains a valid target.
  ///
  /// @see ExecutionContext::HasFrameScope() const
  //------------------------------------------------------------------
  StackFrame &GetFrameRef() const;

  //------------------------------------------------------------------
  /// Get accessor to get the target shared pointer.
  ///
  /// The returned shared pointer is not guaranteed to be valid.
  //------------------------------------------------------------------
  const lldb::TargetSP &GetTargetSP() const { return m_target_sp; }

  //------------------------------------------------------------------
  /// Get accessor to get the process shared pointer.
  ///
  /// The returned shared pointer is not guaranteed to be valid.
  //------------------------------------------------------------------
  const lldb::ProcessSP &GetProcessSP() const { return m_process_sp; }

  //------------------------------------------------------------------
  /// Get accessor to get the thread shared pointer.
  ///
  /// The returned shared pointer is not guaranteed to be valid.
  //------------------------------------------------------------------
  const lldb::ThreadSP &GetThreadSP() const { return m_thread_sp; }

  //------------------------------------------------------------------
  /// Get accessor to get the frame shared pointer.
  ///
  /// The returned shared pointer is not guaranteed to be valid.
  //------------------------------------------------------------------
  const lldb::StackFrameSP &GetFrameSP() const { return m_frame_sp; }

  //------------------------------------------------------------------
  /// Set accessor to set only the target shared pointer.
  //------------------------------------------------------------------
  void SetTargetSP(const lldb::TargetSP &target_sp);

  //------------------------------------------------------------------
  /// Set accessor to set only the process shared pointer.
  //------------------------------------------------------------------
  void SetProcessSP(const lldb::ProcessSP &process_sp);

  //------------------------------------------------------------------
  /// Set accessor to set only the thread shared pointer.
  //------------------------------------------------------------------
  void SetThreadSP(const lldb::ThreadSP &thread_sp);

  //------------------------------------------------------------------
  /// Set accessor to set only the frame shared pointer.
  //------------------------------------------------------------------
  void SetFrameSP(const lldb::StackFrameSP &frame_sp);

  //------------------------------------------------------------------
  /// Set accessor to set only the target shared pointer from a target
  /// pointer.
  //------------------------------------------------------------------
  void SetTargetPtr(Target *target);

  //------------------------------------------------------------------
  /// Set accessor to set only the process shared pointer from a process
  /// pointer.
  //------------------------------------------------------------------
  void SetProcessPtr(Process *process);

  //------------------------------------------------------------------
  /// Set accessor to set only the thread shared pointer from a thread
  /// pointer.
  //------------------------------------------------------------------
  void SetThreadPtr(Thread *thread);

  //------------------------------------------------------------------
  /// Set accessor to set only the frame shared pointer from a frame pointer.
  //------------------------------------------------------------------
  void SetFramePtr(StackFrame *frame);

  //------------------------------------------------------------------
  // Set the execution context using a target shared pointer.
  //
  // If "target_sp" is valid, sets the target context to match and if
  // "get_process" is true, sets the process shared pointer if the target
  // currently has a process.
  //------------------------------------------------------------------
  void SetContext(const lldb::TargetSP &target_sp, bool get_process);

  //------------------------------------------------------------------
  // Set the execution context using a process shared pointer.
  //
  // If "process_sp" is valid, then set the process and target in this context.
  // Thread and frame contexts will be cleared. If "process_sp" is not valid,
  // all shared pointers are reset.
  //------------------------------------------------------------------
  void SetContext(const lldb::ProcessSP &process_sp);

  //------------------------------------------------------------------
  // Set the execution context using a thread shared pointer.
  //
  // If "thread_sp" is valid, then set the thread, process and target in this
  // context. The frame context will be cleared. If "thread_sp" is not valid,
  // all shared pointers are reset.
  //------------------------------------------------------------------
  void SetContext(const lldb::ThreadSP &thread_sp);

  //------------------------------------------------------------------
  // Set the execution context using a frame shared pointer.
  //
  // If "frame_sp" is valid, then set the frame, thread, process and target in
  // this context If "frame_sp" is not valid, all shared pointers are reset.
  //------------------------------------------------------------------
  void SetContext(const lldb::StackFrameSP &frame_sp);

  //------------------------------------------------------------------
  /// Returns true the ExecutionContext object contains a valid target.
  ///
  /// This function can be called after initializing an ExecutionContext
  /// object, and if it returns true, calls to GetTargetPtr() and
  /// GetTargetRef() do not need to be checked for validity.
  //------------------------------------------------------------------
  bool HasTargetScope() const;

  //------------------------------------------------------------------
  /// Returns true the ExecutionContext object contains a valid target and
  /// process.
  ///
  /// This function can be called after initializing an ExecutionContext
  /// object, and if it returns true, calls to GetTargetPtr() and
  /// GetTargetRef(), GetProcessPtr(), and GetProcessRef(), do not need to be
  /// checked for validity.
  //------------------------------------------------------------------
  bool HasProcessScope() const;

  //------------------------------------------------------------------
  /// Returns true the ExecutionContext object contains a valid target,
  /// process, and thread.
  ///
  /// This function can be called after initializing an ExecutionContext
  /// object, and if it returns true, calls to GetTargetPtr(), GetTargetRef(),
  /// GetProcessPtr(), GetProcessRef(), GetThreadPtr(), and GetThreadRef() do
  /// not need to be checked for validity.
  //------------------------------------------------------------------
  bool HasThreadScope() const;

  //------------------------------------------------------------------
  /// Returns true the ExecutionContext object contains a valid target,
  /// process, thread and frame.
  ///
  /// This function can be called after initializing an ExecutionContext
  /// object, and if it returns true, calls to GetTargetPtr(), GetTargetRef(),
  /// GetProcessPtr(), GetProcessRef(), GetThreadPtr(), GetThreadRef(),
  /// GetFramePtr(), and GetFrameRef() do not need to be checked for validity.
  //------------------------------------------------------------------
  bool HasFrameScope() const;

protected:
  //------------------------------------------------------------------
  // Member variables
  //------------------------------------------------------------------
  lldb::TargetSP m_target_sp; ///< The target that owns the process/thread/frame
  lldb::ProcessSP m_process_sp;  ///< The process that owns the thread/frame
  lldb::ThreadSP m_thread_sp;    ///< The thread that owns the frame
  lldb::StackFrameSP m_frame_sp; ///< The stack frame in thread.
};

} // namespace lldb_private

#endif // liblldb_ExecutionContext_h_