summaryrefslogtreecommitdiff
path: root/include/llvm/Debugger/ProgramInfo.h
blob: f7ee77dc314496be8eb139fdf5e87dd57cbccea9 (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
//===- ProgramInfo.h - Information about the loaded 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 various pieces of information about the currently loaded
// program.  One instance of this object is created every time a program is
// loaded, and destroyed every time it is unloaded.
//
// The various pieces of information gathered about the source program are all
// designed to be extended by various SourceLanguage implementations.  This
// allows source languages to keep any extended information that they support in
// the derived class portions of the class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGGER_PROGRAMINFO_H
#define LLVM_DEBUGGER_PROGRAMINFO_H

#include "llvm/System/TimeValue.h"
#include <string>
#include <map>
#include <vector>

namespace llvm {
  class GlobalVariable;
  class Module;
  class SourceFile;
  class SourceLanguage;
  class ProgramInfo;

  /// SourceLanguageCache - SourceLanguage implementations are allowed to cache
  /// stuff in the ProgramInfo object.  The only requirement we have on these
  /// instances is that they are destroyable.
  struct SourceLanguageCache {
    virtual ~SourceLanguageCache() {}
  };

  /// SourceFileInfo - One instance of this structure is created for each
  /// source file in the program.
  ///
  class SourceFileInfo {
    /// BaseName - The filename of the source file.
    std::string BaseName;

    /// Directory - The working directory of this source file when it was
    /// compiled.
    std::string Directory;

    /// Version - The version of the LLVM debug information that this file was
    /// compiled with.
    unsigned Version;

    /// Language - The source language that the file was compiled with.  This
    /// pointer is never null.
    ///
    const SourceLanguage *Language;

    /// Descriptor - The LLVM Global Variable which describes the source file.
    ///
    const GlobalVariable *Descriptor;

    /// SourceText - The body of this source file, or null if it has not yet
    /// been loaded.
    mutable SourceFile *SourceText;
  public:
    SourceFileInfo(const GlobalVariable *Desc, const SourceLanguage &Lang);
    ~SourceFileInfo();
    
    const std::string &getBaseName() const { return BaseName; }
    const std::string &getDirectory() const { return Directory; }
    unsigned getDebugVersion() const { return Version; }
    const GlobalVariable *getDescriptor() const { return Descriptor; }
    SourceFile &getSourceText() const;

    const SourceLanguage &getLanguage() const { return *Language; }
  };


  /// SourceFunctionInfo - An instance of this class is used to represent each
  /// source function in the program.
  ///
  class SourceFunctionInfo {
    /// Name - This contains an abstract name that is potentially useful to the
    /// end-user.  If there is no explicit support for the current language,
    /// then this string is used to identify the function.
    std::string Name;

    /// Descriptor - The descriptor for this function.
    ///
    const GlobalVariable *Descriptor;

    /// SourceFile - The file that this function is defined in.
    ///
    const SourceFileInfo *SourceFile;

    /// LineNo, ColNo - The location of the first stop-point in the function.
    /// These are computed on demand.
    mutable unsigned LineNo, ColNo;

  public:
    SourceFunctionInfo(ProgramInfo &PI, const GlobalVariable *Desc);
    virtual ~SourceFunctionInfo() {}

    /// getSymbolicName - Return a human-readable symbolic name to identify the
    /// function (for example, in stack traces).
    virtual std::string getSymbolicName() const { return Name; }

    /// getDescriptor - This returns the descriptor for the function.
    ///
    const GlobalVariable *getDescriptor() const { return Descriptor; }

    /// getSourceFile - This returns the source file that defines the function.
    ///
    const SourceFileInfo &getSourceFile() const { return *SourceFile; }

    /// getSourceLocation - This method returns the location of the first
    /// stopping point in the function.  If the body of the function cannot be
    /// found, this returns zeros for both values.
    void getSourceLocation(unsigned &LineNo, unsigned &ColNo) const;
  };


  /// ProgramInfo - This object contains information about the loaded program.
  /// When a new program is loaded, an instance of this class is created.  When
  /// the program is unloaded, the instance is destroyed.  This object basically
  /// manages the lazy computation of information useful for the debugger.
  class ProgramInfo {
    Module *M;

    /// ProgramTimeStamp - This is the timestamp of the executable file that we
    /// currently have loaded into the debugger.
    sys::TimeValue ProgramTimeStamp;

    /// SourceFiles - This map is used to transform source file descriptors into
    /// their corresponding SourceFileInfo objects.  This mapping owns the
    /// memory for the SourceFileInfo objects.
    ///
    bool SourceFilesIsComplete;
    std::map<const GlobalVariable*, SourceFileInfo*> SourceFiles;

    /// SourceFileIndex - Mapping from source file basenames to the information
    /// about the file.  Note that there can be filename collisions, so this is
    /// a multimap.  This map is populated incrementally as the user interacts
    /// with the program, through the getSourceFileFromDesc method.  If ALL of
    /// the source files are needed, the getSourceFiles() method scans the
    /// entire program looking for them.
    /// 
    std::multimap<std::string, SourceFileInfo*> SourceFileIndex;

    /// SourceFunctions - This map contains entries functions in the source
    /// program.  If SourceFunctionsIsComplete is true, then this is ALL of the
    /// functions in the program are in this map.
    bool SourceFunctionsIsComplete;
    std::map<const GlobalVariable*, SourceFunctionInfo*> SourceFunctions;

    /// LanguageCaches - Each source language is permitted to keep a per-program
    /// cache of information specific to whatever it needs.  This vector is
    /// effectively a small map from the languages that are active in the
    /// program to their caches.  This can be accessed by the language by the
    /// "getLanguageCache" method.
    std::vector<std::pair<const SourceLanguage*, 
                          SourceLanguageCache*> > LanguageCaches;
  public:
    ProgramInfo(Module *m);
    ~ProgramInfo();

    /// getProgramTimeStamp - Return the time-stamp of the program when it was
    /// loaded.
    sys::TimeValue getProgramTimeStamp() const { return ProgramTimeStamp; }
    
    //===------------------------------------------------------------------===//
    // Interfaces to the source code files that make up the program.
    //

    /// getSourceFile - Return source file information for the specified source
    /// file descriptor object, adding it to the collection as needed.  This
    /// method always succeeds (is unambiguous), and is always efficient.
    ///
    const SourceFileInfo &getSourceFile(const GlobalVariable *Desc);

    /// getSourceFile - Look up the file with the specified name.  If there is
    /// more than one match for the specified filename, prompt the user to pick
    /// one.  If there is no source file that matches the specified name, throw
    /// an exception indicating that we can't find the file.  Otherwise, return
    /// the file information for that file.
    ///
    /// If the source file hasn't been discovered yet in the program, this
    /// method might have to index the whole program by calling the
    /// getSourceFiles() method.
    ///
    const SourceFileInfo &getSourceFile(const std::string &Filename);

    /// getSourceFiles - Index all of the source files in the program and return
    /// them.  This information is lazily computed the first time that it is
    /// requested.  Since this information can take a long time to compute, the
    /// user is given a chance to cancel it.  If this occurs, an exception is
    /// thrown.
    const std::map<const GlobalVariable*, SourceFileInfo*> &
    getSourceFiles(bool RequiresCompleteMap = true);

    //===------------------------------------------------------------------===//
    // Interfaces to the functions that make up the program.
    //

    /// getFunction - Return source function information for the specified
    /// function descriptor object, adding it to the collection as needed.  This
    /// method always succeeds (is unambiguous), and is always efficient.
    ///
    const SourceFunctionInfo &getFunction(const GlobalVariable *Desc);

    /// getSourceFunctions - Index all of the functions in the program and
    /// return them.  This information is lazily computed the first time that it
    /// is requested.  Since this information can take a long time to compute,
    /// the user is given a chance to cancel it.  If this occurs, an exception
    /// is thrown.
    const std::map<const GlobalVariable*, SourceFunctionInfo*> &
    getSourceFunctions(bool RequiresCompleteMap = true);

    /// addSourceFunctionsRead - Return true if the source functions map is
    /// complete: that is, all functions in the program have been read in.
    bool allSourceFunctionsRead() const { return SourceFunctionsIsComplete; }

    /// getLanguageCache - This method is used to build per-program caches of
    /// information, such as the functions or types visible to the program.
    /// This can be used by SourceLanguage implementations because it requires
    /// an accessible [sl]::CacheType typedef, where [sl] is the C++ type of the
    /// source-language subclass.
    template<typename SL>
    typename SL::CacheType &getLanguageCache(const SL *L) {
      for (unsigned i = 0, e = LanguageCaches.size(); i != e; ++i)
        if (LanguageCaches[i].first == L)
          return *(typename SL::CacheType*)LanguageCaches[i].second;
      typename SL::CacheType *NewCache = L->createSourceLanguageCache(*this);
      LanguageCaches.push_back(std::make_pair(L, NewCache));
      return *NewCache;
    }
  };

} // end namespace llvm

#endif