diff options
| -rw-r--r-- | llvm/include/llvm/Debugger/Debugger.h | 169 | ||||
| -rw-r--r-- | llvm/include/llvm/Debugger/InferiorProcess.h | 138 | ||||
| -rw-r--r-- | llvm/include/llvm/Debugger/ProgramInfo.h | 245 | ||||
| -rw-r--r-- | llvm/include/llvm/Debugger/RuntimeInfo.h | 141 | ||||
| -rw-r--r-- | llvm/include/llvm/Debugger/SourceFile.h | 95 | ||||
| -rw-r--r-- | llvm/include/llvm/Debugger/SourceLanguage.h | 99 | 
6 files changed, 887 insertions, 0 deletions
diff --git a/llvm/include/llvm/Debugger/Debugger.h b/llvm/include/llvm/Debugger/Debugger.h new file mode 100644 index 00000000000..b1115daca6a --- /dev/null +++ b/llvm/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/llvm/include/llvm/Debugger/InferiorProcess.h b/llvm/include/llvm/Debugger/InferiorProcess.h new file mode 100644 index 00000000000..c3f388654ae --- /dev/null +++ b/llvm/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/llvm/include/llvm/Debugger/ProgramInfo.h b/llvm/include/llvm/Debugger/ProgramInfo.h new file mode 100644 index 00000000000..0807d8ca5b6 --- /dev/null +++ b/llvm/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/llvm/include/llvm/Debugger/RuntimeInfo.h b/llvm/include/llvm/Debugger/RuntimeInfo.h new file mode 100644 index 00000000000..360b923e55d --- /dev/null +++ b/llvm/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/llvm/include/llvm/Debugger/SourceFile.h b/llvm/include/llvm/Debugger/SourceFile.h new file mode 100644 index 00000000000..86a7f36b10a --- /dev/null +++ b/llvm/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/llvm/include/llvm/Debugger/SourceLanguage.h b/llvm/include/llvm/Debugger/SourceLanguage.h new file mode 100644 index 00000000000..798e0fb49c8 --- /dev/null +++ b/llvm/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  | 

