aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-01-05 05:23:38 +0000
committerChris Lattner <sabre@nondot.org>2004-01-05 05:23:38 +0000
commit4575dcb5873af0163f871196b92a77928fbb5c8e (patch)
treec04f8da5c90bb8edc54f37421fc077a744919306
parentbdfb339b8d1d0480c42bfbcf76b96c1f7fcdec75 (diff)
downloadexternal_llvm-4575dcb5873af0163f871196b92a77928fbb5c8e.zip
external_llvm-4575dcb5873af0163f871196b92a77928fbb5c8e.tar.gz
external_llvm-4575dcb5873af0163f871196b92a77928fbb5c8e.tar.bz2
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
-rw-r--r--include/llvm/Debugger/Debugger.h169
-rw-r--r--include/llvm/Debugger/InferiorProcess.h138
-rw-r--r--include/llvm/Debugger/ProgramInfo.h245
-rw-r--r--include/llvm/Debugger/RuntimeInfo.h141
-rw-r--r--include/llvm/Debugger/SourceFile.h95
-rw-r--r--include/llvm/Debugger/SourceLanguage.h99
6 files changed, 887 insertions, 0 deletions
diff --git a/include/llvm/Debugger/Debugger.h b/include/llvm/Debugger/Debugger.h
new file mode 100644
index 0000000..b1115da
--- /dev/null
+++ b/include/llvm/Debugger/Debugger.h
@@ -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
diff --git a/include/llvm/Debugger/InferiorProcess.h b/include/llvm/Debugger/InferiorProcess.h
new file mode 100644
index 0000000..c3f3886
--- /dev/null
+++ b/include/llvm/Debugger/InferiorProcess.h
@@ -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
+
diff --git a/include/llvm/Debugger/ProgramInfo.h b/include/llvm/Debugger/ProgramInfo.h
new file mode 100644
index 0000000..0807d8c
--- /dev/null
+++ b/include/llvm/Debugger/ProgramInfo.h
@@ -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
diff --git a/include/llvm/Debugger/RuntimeInfo.h b/include/llvm/Debugger/RuntimeInfo.h
new file mode 100644
index 0000000..360b923
--- /dev/null
+++ b/include/llvm/Debugger/RuntimeInfo.h
@@ -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
diff --git a/include/llvm/Debugger/SourceFile.h b/include/llvm/Debugger/SourceFile.h
new file mode 100644
index 0000000..86a7f36
--- /dev/null
+++ b/include/llvm/Debugger/SourceFile.h
@@ -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
diff --git a/include/llvm/Debugger/SourceLanguage.h b/include/llvm/Debugger/SourceLanguage.h
new file mode 100644
index 0000000..798e0fb
--- /dev/null
+++ b/include/llvm/Debugger/SourceLanguage.h
@@ -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