summaryrefslogtreecommitdiff
path: root/include/llvm/Debugger/RuntimeInfo.h
blob: 2f4d37a148d11f5f208d46cf05a9d13213a5cc80 (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
//===- RuntimeInfo.h - Information about running program --------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines classes that capture various pieces of information about
// the currently executing, but stopped, program.  One instance of this object
// is created every time a program is stopped, and destroyed every time it
// starts running again.  This object's main goal is to make access to runtime
// information easy and efficient, by caching information as requested.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGGER_RUNTIMEINFO_H
#define LLVM_DEBUGGER_RUNTIMEINFO_H

#include <vector>
#include <cassert>

namespace llvm {
  class ProgramInfo;
  class RuntimeInfo;
  class InferiorProcess;
  class GlobalVariable;
  class SourceFileInfo;

  /// StackFrame - One instance of this structure is created for each stack
  /// frame that is active in the program.
  ///
  class StackFrame {
    RuntimeInfo &RI;
    void *FrameID;
    const GlobalVariable *FunctionDesc;

    /// LineNo, ColNo, FileInfo - This information indicates WHERE in the source
    /// code for the program the stack frame is located.
    unsigned LineNo, ColNo;
    const SourceFileInfo *SourceInfo;
  public:
    StackFrame(RuntimeInfo &RI, void *ParentFrameID);

    StackFrame &operator=(const StackFrame &RHS) {
      FrameID = RHS.FrameID;
      FunctionDesc = RHS.FunctionDesc;
      return *this;
    }

    /// getFrameID - return the low-level opaque frame ID of this stack frame.
    ///
    void *getFrameID() const { return FrameID; }

    /// getFunctionDesc - Return the descriptor for the function that contains
    /// this stack frame, or null if it is unknown.
    ///
    const GlobalVariable *getFunctionDesc();

    /// getSourceLocation - Return the source location that this stack frame is
    /// sitting at.
    void getSourceLocation(unsigned &LineNo, unsigned &ColNo,
                           const SourceFileInfo *&SourceInfo);
  };


  /// RuntimeInfo - This class collects information about the currently running
  /// process.  It is created whenever the program stops execution for the
  /// debugger, and destroyed whenver execution continues.
  class RuntimeInfo {
    /// ProgInfo - This object contains static information about the program.
    ///
    ProgramInfo *ProgInfo;

    /// IP - This object contains information about the actual inferior process
    /// that we are communicating with and aggregating information from.
    const InferiorProcess &IP;

    /// CallStack - This caches information about the current stack trace of the
    /// program.  This is lazily computed as needed.
    std::vector<StackFrame> CallStack;

    /// CurrentFrame - The user can traverse the stack frame with the
    /// up/down/frame family of commands.  This index indicates the current
    /// stack frame.
    unsigned CurrentFrame;

  public:
    RuntimeInfo(ProgramInfo *PI, const InferiorProcess &ip)
      : ProgInfo(PI), IP(ip), CurrentFrame(0) {
      // Make sure that the top of stack has been materialized.  If this throws
      // an exception, something is seriously wrong and the RuntimeInfo object
      // would be unusable anyway.
      getStackFrame(0);
    }

    ProgramInfo &getProgramInfo() { return *ProgInfo; }
    const InferiorProcess &getInferiorProcess() const { return IP; }

    //===------------------------------------------------------------------===//
    // Methods for inspecting the call stack of the program.
    //

    /// getStackFrame - Materialize the specified stack frame and return it.  If
    /// the specified ID is off of the bottom of the stack, throw an exception
    /// indicating the problem.
    StackFrame &getStackFrame(unsigned ID) {
      if (ID >= CallStack.size())
        materializeFrame(ID);
      return CallStack[ID];
    }

    /// getCurrentFrame - Return the current stack frame object that the user is
    /// inspecting.
    StackFrame &getCurrentFrame() {
      assert(CallStack.size() > CurrentFrame &&
             "Must have materialized frame before making it current!");
      return CallStack[CurrentFrame];
    }

    /// getCurrentFrameIdx - Return the current frame the user is inspecting.
    ///
    unsigned getCurrentFrameIdx() const { return CurrentFrame; }

    /// setCurrentFrameIdx - Set the current frame index to the specified value.
    /// Note that the specified frame must have been materialized with
    /// getStackFrame before it can be made current.
    void setCurrentFrameIdx(unsigned Idx) {
      assert(Idx < CallStack.size() &&
             "Must materialize frame before making it current!");
      CurrentFrame = Idx;
    }
  private:
    /// materializeFrame - Create and process all frames up to and including the
    /// specified frame number.  This throws an exception if the specified frame
    /// ID is nonexistant.
    void materializeFrame(unsigned ID);
  };
}

#endif