mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-11 00:39:36 +00:00
Initial implementation of some source-level debugging stuff
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10684 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bdfb339b8d
commit
4575dcb587
169
include/llvm/Debugger/Debugger.h
Normal file
169
include/llvm/Debugger/Debugger.h
Normal file
@ -0,0 +1,169 @@
|
||||
//===- Debugger.h - LLVM debugger library interface -------------*- 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 the LLVM source-level debugger library interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEBUGGER_DEBUGGER_H
|
||||
#define LLVM_DEBUGGER_DEBUGGER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
class InferiorProcess;
|
||||
|
||||
/// Debugger class - This class implements the LLVM source-level debugger.
|
||||
/// This allows clients to handle the user IO processing without having to
|
||||
/// worry about how the debugger itself works.
|
||||
///
|
||||
class Debugger {
|
||||
// State the debugger needs when starting and stopping the program.
|
||||
std::vector<std::string> ProgramArguments;
|
||||
|
||||
// The environment to run the program with. This should eventually be
|
||||
// changed to vector of strings when we allow the user to edit the
|
||||
// environment.
|
||||
const char * const *Environment;
|
||||
|
||||
// Program - The currently loaded program, or null if none is loaded.
|
||||
Module *Program;
|
||||
|
||||
// Process - The currently executing inferior process.
|
||||
InferiorProcess *Process;
|
||||
|
||||
Debugger(const Debugger &); // DO NOT IMPLEMENT
|
||||
void operator=(const Debugger &); // DO NOT IMPLEMENT
|
||||
public:
|
||||
Debugger();
|
||||
~Debugger();
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Methods for manipulating and inspecting the execution environment.
|
||||
//
|
||||
|
||||
/// initializeEnvironment - Specify the environment the program should run
|
||||
/// with. This is used to initialize the environment of the program to the
|
||||
/// environment of the debugger.
|
||||
void initializeEnvironment(const char *const *envp) {
|
||||
Environment = envp;
|
||||
}
|
||||
|
||||
/// setWorkingDirectory - Specify the working directory for the program to
|
||||
/// be started from.
|
||||
void setWorkingDirectory(const std::string &Dir) {
|
||||
// FIXME: implement
|
||||
}
|
||||
|
||||
template<typename It>
|
||||
void setProgramArguments(It I, It E) {
|
||||
ProgramArguments.assign(I, E);
|
||||
}
|
||||
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Methods for manipulating and inspecting the program currently loaded.
|
||||
//
|
||||
|
||||
/// isProgramLoaded - Return true if there is a program currently loaded.
|
||||
///
|
||||
bool isProgramLoaded() const { return Program != 0; }
|
||||
|
||||
/// getProgram - Return the LLVM module corresponding to the program.
|
||||
///
|
||||
Module *getProgram() const { return Program; }
|
||||
|
||||
/// getProgramPath - Get the path of the currently loaded program, or an
|
||||
/// empty string if none is loaded.
|
||||
std::string getProgramPath() const;
|
||||
|
||||
/// loadProgram - If a program is currently loaded, unload it. Then search
|
||||
/// the PATH for the specified program, loading it when found. If the
|
||||
/// specified program cannot be found, an exception is thrown to indicate
|
||||
/// the error.
|
||||
void loadProgram(const std::string &Path);
|
||||
|
||||
/// unloadProgram - If a program is running, kill it, then unload all traces
|
||||
/// of the current program. If no program is loaded, this method silently
|
||||
/// succeeds.
|
||||
void unloadProgram();
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Methods for manipulating and inspecting the program currently running.
|
||||
//
|
||||
// If the program is running, and the debugger is active, then we know that
|
||||
// the program has stopped. This being the case, we can inspect the
|
||||
// program, ask it for its source location, set breakpoints, etc.
|
||||
//
|
||||
|
||||
/// isProgramRunning - Return true if a program is loaded and has a
|
||||
/// currently active instance.
|
||||
bool isProgramRunning() const { return Process != 0; }
|
||||
|
||||
/// getRunningProcess - If there is no program running, throw an exception.
|
||||
/// Otherwise return the running process so that it can be inspected by the
|
||||
/// debugger.
|
||||
const InferiorProcess &getRunningProcess() const {
|
||||
if (Process == 0) throw "No process running.";
|
||||
return *Process;
|
||||
}
|
||||
|
||||
/// createProgram - Create an instance of the currently loaded program,
|
||||
/// killing off any existing one. This creates the program and stops it at
|
||||
/// the first possible moment. If there is no program loaded or if there is
|
||||
/// a problem starting the program, this method throws an exception.
|
||||
void createProgram();
|
||||
|
||||
/// killProgram - If the program is currently executing, kill off the
|
||||
/// process and free up any state related to the currently running program.
|
||||
/// If there is no program currently running, this just silently succeeds.
|
||||
/// If something horrible happens when killing the program, an exception
|
||||
/// gets thrown.
|
||||
void killProgram();
|
||||
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Methods for continuing execution. These methods continue the execution
|
||||
// of the program by some amount. If the program is successfully stopped,
|
||||
// execution returns, otherwise an exception is thrown.
|
||||
//
|
||||
// NOTE: These methods should always be used in preference to directly
|
||||
// accessing the Dbg object, because these will delete the Process object if
|
||||
// the process unexpectedly dies.
|
||||
//
|
||||
|
||||
/// stepProgram - Implement the 'step' command, continuing execution until
|
||||
/// the next possible stop point.
|
||||
void stepProgram();
|
||||
|
||||
/// nextProgram - Implement the 'next' command, continuing execution until
|
||||
/// the next possible stop point that is in the current function.
|
||||
void nextProgram();
|
||||
|
||||
/// finishProgram - Implement the 'finish' command, continuing execution
|
||||
/// until the specified frame ID returns.
|
||||
void finishProgram(void *Frame);
|
||||
|
||||
/// contProgram - Implement the 'cont' command, continuing execution until
|
||||
/// the next breakpoint is encountered.
|
||||
void contProgram();
|
||||
};
|
||||
|
||||
class NonErrorException {
|
||||
std::string Message;
|
||||
public:
|
||||
NonErrorException(const std::string &M) : Message(M) {}
|
||||
const std::string &getMessage() const { return Message; }
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
138
include/llvm/Debugger/InferiorProcess.h
Normal file
138
include/llvm/Debugger/InferiorProcess.h
Normal file
@ -0,0 +1,138 @@
|
||||
//===- InferiorProcess.h - Represent the program being debugged -*- 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 the InferiorProcess class, which is used to represent,
|
||||
// inspect, and manipulate a process under the control of the LLVM debugger.
|
||||
//
|
||||
// This is an abstract class which should allow various different types of
|
||||
// implementations. Initially we implement a unix specific debugger backend
|
||||
// that does not require code generator support, but we could eventually use
|
||||
// code generator support with ptrace, support windows based targets, supported
|
||||
// remote targets, etc.
|
||||
//
|
||||
// If the inferior process unexpectedly dies, an attempt to communicate with it
|
||||
// will cause an InferiorProcessDead exception to be thrown, indicating the exit
|
||||
// code of the process. When this occurs, no methods on the InferiorProcess
|
||||
// class should be called except for the destructor.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEBUGGER_INFERIORPROCESS_H
|
||||
#define LLVM_DEBUGGER_INFERIORPROCESS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
class GlobalVariable;
|
||||
|
||||
/// InferiorProcessDead exception - This class is thrown by methods that
|
||||
/// communicate with the interior process if the process unexpectedly exits or
|
||||
/// dies. The instance variable indicates what the exit code of the process
|
||||
/// was, or -1 if unknown.
|
||||
class InferiorProcessDead {
|
||||
int ExitCode;
|
||||
public:
|
||||
InferiorProcessDead(int EC) : ExitCode(EC) {}
|
||||
int getExitCode() const { return ExitCode; }
|
||||
};
|
||||
|
||||
/// InferiorProcess class - This class represents the process being debugged
|
||||
/// by the debugger. Objects of this class should not be stack allocated,
|
||||
/// because the destructor can throw exceptions.
|
||||
///
|
||||
class InferiorProcess {
|
||||
Module *M;
|
||||
protected:
|
||||
InferiorProcess(Module *m) : M(m) {}
|
||||
public:
|
||||
/// create - Create an inferior process of the specified module, and
|
||||
/// stop it at the first opportunity. If there is a problem starting the
|
||||
/// program (for example, it has no main), throw an exception.
|
||||
static InferiorProcess *create(Module *M,
|
||||
const std::vector<std::string> &Arguments,
|
||||
const char * const *envp);
|
||||
|
||||
// InferiorProcess destructor - Kill the current process. If something
|
||||
// terrible happens, we throw an exception from the destructor.
|
||||
virtual ~InferiorProcess() {}
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Status methods - These methods return information about the currently
|
||||
// stopped process.
|
||||
//
|
||||
|
||||
/// getStatus - Return a status message that is specific to the current type
|
||||
/// of inferior process that is created. This can return things like the
|
||||
/// PID of the inferior or other potentially interesting things.
|
||||
virtual std::string getStatus() const {
|
||||
return "";
|
||||
}
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Methods for inspecting the call stack.
|
||||
//
|
||||
|
||||
/// getPreviousFrame - Given the descriptor for the current stack frame,
|
||||
/// return the descriptor for the caller frame. This returns null when it
|
||||
/// runs out of frames. If Frame is null, the initial frame should be
|
||||
/// returned.
|
||||
virtual void *getPreviousFrame(void *Frame) const = 0;
|
||||
|
||||
/// getSubprogramDesc - Return the subprogram descriptor for the current
|
||||
/// stack frame.
|
||||
virtual const GlobalVariable *getSubprogramDesc(void *Frame) const = 0;
|
||||
|
||||
/// getFrameLocation - This method returns the source location where each
|
||||
/// stack frame is stopped.
|
||||
virtual void getFrameLocation(void *Frame, unsigned &LineNo,
|
||||
unsigned &ColNo,
|
||||
const GlobalVariable *&SourceDesc) const = 0;
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Methods for manipulating breakpoints.
|
||||
//
|
||||
|
||||
/// addBreakpoint - This method adds a breakpoint at the specified line,
|
||||
/// column, and source file, and returns a unique identifier for it.
|
||||
///
|
||||
/// It is up to the debugger to determine whether or not there is actually a
|
||||
/// stop-point that corresponds with the specified location.
|
||||
virtual unsigned addBreakpoint(unsigned LineNo, unsigned ColNo,
|
||||
const GlobalVariable *SourceDesc) = 0;
|
||||
|
||||
/// removeBreakpoint - This deletes the breakpoint with the specified ID
|
||||
/// number.
|
||||
virtual void removeBreakpoint(unsigned ID) = 0;
|
||||
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Execution methods - These methods cause the program to continue execution
|
||||
// by some amount. If the program successfully stops, this returns.
|
||||
// Otherwise, if the program unexpectedly terminates, an InferiorProcessDead
|
||||
// exception is thrown.
|
||||
//
|
||||
|
||||
/// stepProgram - Implement the 'step' command, continuing execution until
|
||||
/// the next possible stop point.
|
||||
virtual void stepProgram() = 0;
|
||||
|
||||
/// finishProgram - Implement the 'finish' command, continuing execution
|
||||
/// until the current function returns.
|
||||
virtual void finishProgram(void *Frame) = 0;
|
||||
|
||||
/// contProgram - Implement the 'cont' command, continuing execution until
|
||||
/// a breakpoint is encountered.
|
||||
virtual void contProgram() = 0;
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
245
include/llvm/Debugger/ProgramInfo.h
Normal file
245
include/llvm/Debugger/ProgramInfo.h
Normal file
@ -0,0 +1,245 @@
|
||||
//===- 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 <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.
|
||||
unsigned long long 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.
|
||||
unsigned long long 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
|
141
include/llvm/Debugger/RuntimeInfo.h
Normal file
141
include/llvm/Debugger/RuntimeInfo.h
Normal file
@ -0,0 +1,141 @@
|
||||
//===- 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>
|
||||
|
||||
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
|
95
include/llvm/Debugger/SourceFile.h
Normal file
95
include/llvm/Debugger/SourceFile.h
Normal file
@ -0,0 +1,95 @@
|
||||
//===- SourceFile.h - Class to represent a source code file -----*- 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 the SourceFile class which is used to represent a single
|
||||
// file of source code in the program, caching data from the file to make access
|
||||
// efficient.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEBUGGER_SOURCEFILE_H
|
||||
#define LLVM_DEBUGGER_SOURCEFILE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class GlobalVariable;
|
||||
|
||||
class SourceFile {
|
||||
/// Filename - This is the full path of the file that is loaded.
|
||||
///
|
||||
std::string Filename;
|
||||
|
||||
/// Descriptor - The debugging descriptor for this source file. If there
|
||||
/// are multiple descriptors for the same file, this is just the first one
|
||||
/// encountered.
|
||||
///
|
||||
const GlobalVariable *Descriptor;
|
||||
|
||||
/// FileStart, FileEnd - These pointers point to the start and end of the
|
||||
/// file data for this file. If there was an error loading the file, these
|
||||
/// pointers will both be null.
|
||||
const char *FileStart, *FileEnd;
|
||||
|
||||
/// LineOffset - This vector contains a mapping from source line numbers to
|
||||
/// their offsets in the file. This data is computed lazily, the first time
|
||||
/// it is asked for. If there are zero elements allocated in this vector,
|
||||
/// then it has not yet been computed.
|
||||
mutable std::vector<unsigned> LineOffset;
|
||||
|
||||
public:
|
||||
/// SourceFile constructor - Read in the specified source file if it exists,
|
||||
/// but do not build the LineOffsets table until it is requested. This will
|
||||
/// NOT throw an exception if the file is not found, if there is an error
|
||||
/// reading it, or if the user cancels the operation. Instead, it will just
|
||||
/// be an empty source file.
|
||||
SourceFile(const std::string &fn, const GlobalVariable *Desc)
|
||||
: Filename(fn), Descriptor(Desc), FileStart(0), FileEnd(0) {
|
||||
readFile();
|
||||
}
|
||||
~SourceFile() {
|
||||
delete[] FileStart;
|
||||
}
|
||||
|
||||
/// getDescriptor - Return the debugging decriptor for this source file.
|
||||
///
|
||||
const GlobalVariable *getDescriptor() const { return Descriptor; }
|
||||
|
||||
/// getFilename - Return the fully resolved path that this file was loaded
|
||||
/// from.
|
||||
const std::string &getFilename() const { return Filename; }
|
||||
|
||||
/// getSourceLine - Given a line number, return the start and end of the
|
||||
/// line in the file. If the line number is invalid, or if the file could
|
||||
/// not be loaded, null pointers are returned for the start and end of the
|
||||
/// file. Note that line numbers start with 0, not 1. This also strips off
|
||||
/// any newlines from the end of the line, to ease formatting of the text.
|
||||
void getSourceLine(unsigned LineNo, const char *&LineStart,
|
||||
const char *&LineEnd) const;
|
||||
|
||||
/// getNumLines - Return the number of lines the source file contains.
|
||||
///
|
||||
unsigned getNumLines() const {
|
||||
if (LineOffset.empty()) calculateLineOffsets();
|
||||
return LineOffset.size();
|
||||
}
|
||||
|
||||
private:
|
||||
/// readFile - Load Filename into FileStart and FileEnd.
|
||||
///
|
||||
void readFile();
|
||||
|
||||
/// calculateLineOffsets - Compute the LineOffset vector for the current
|
||||
/// file.
|
||||
void calculateLineOffsets() const;
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
99
include/llvm/Debugger/SourceLanguage.h
Normal file
99
include/llvm/Debugger/SourceLanguage.h
Normal file
@ -0,0 +1,99 @@
|
||||
//===- SourceLanguage.h - Interact with source languages --------*- 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 the abstract SourceLanguage interface, which is used by the
|
||||
// LLVM debugger to parse source-language expressions and render program objects
|
||||
// into a human readable string. In general, these classes perform all of the
|
||||
// analysis and interpretation of the language-specific debugger information.
|
||||
//
|
||||
// This interface is designed to be completely stateless, so all methods are
|
||||
// const.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEBUGGER_SOURCELANGUAGE_H
|
||||
#define LLVM_DEBUGGER_SOURCELANGUAGE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class GlobalVariable;
|
||||
class SourceFileInfo;
|
||||
class SourceFunctionInfo;
|
||||
class ProgramInfo;
|
||||
class RuntimeInfo;
|
||||
|
||||
struct SourceLanguage {
|
||||
virtual ~SourceLanguage() {}
|
||||
|
||||
/// getSourceLanguageName - This method is used to implement the 'show
|
||||
/// language' command in the debugger.
|
||||
virtual const char *getSourceLanguageName() const = 0;
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Methods used to implement debugger hooks.
|
||||
//
|
||||
|
||||
/// printInfo - Implementing this method allows the debugger to use
|
||||
/// language-specific 'info' extensions, e.g., 'info selectors' for objc.
|
||||
/// This method should return true if the specified string is recognized.
|
||||
///
|
||||
virtual bool printInfo(const std::string &What) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// lookupFunction - Given a textual function name, return the
|
||||
/// SourceFunctionInfo descriptor for that function, or null if it cannot be
|
||||
/// found. If the program is currently running, the RuntimeInfo object
|
||||
/// provides information about the current evaluation context, otherwise it
|
||||
/// will be null.
|
||||
///
|
||||
virtual SourceFunctionInfo *lookupFunction(const std::string &FunctionName,
|
||||
ProgramInfo &PI,
|
||||
RuntimeInfo *RI = 0) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Methods used to parse various pieces of program information.
|
||||
//
|
||||
|
||||
/// createSourceFileInfo - This method can be implemented by the front-end
|
||||
/// if it needs to keep track of information beyond what the debugger
|
||||
/// requires.
|
||||
virtual SourceFileInfo *
|
||||
createSourceFileInfo(const GlobalVariable *Desc, ProgramInfo &PI) const;
|
||||
|
||||
/// createSourceFunctionInfo - This method can be implemented by the derived
|
||||
/// SourceLanguage if it needs to keep track of more information than the
|
||||
/// SourceFunctionInfo has.
|
||||
virtual SourceFunctionInfo *
|
||||
createSourceFunctionInfo(const GlobalVariable *Desc, ProgramInfo &PI) const;
|
||||
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Static methods used to get instances of various source languages.
|
||||
//
|
||||
|
||||
/// get - This method returns a source-language instance for the specified
|
||||
/// Dwarf 3 language identifier. If the language is unknown, an object is
|
||||
/// returned that can support some minimal operations, but is not terribly
|
||||
/// bright.
|
||||
static const SourceLanguage &get(unsigned ID);
|
||||
|
||||
/// get*Instance() - These methods return specific instances of languages.
|
||||
///
|
||||
static const SourceLanguage &getCFamilyInstance();
|
||||
static const SourceLanguage &getCPlusPlusInstance();
|
||||
static const SourceLanguage &getUnknownLanguageInstance();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user