Design of LLVM-TV ----------------- TVApplication implements the wxApp interface and is the launcher of LLVM-TV. It is responsible for keeping track of all the windows, and the list of available snapshots. It is also responsible for handling Unix signals sent to the LLVM-TV process; this is the mechanism the LLVM optimizer uses for communicating with LLVM-TV. TVFrame is responsible for the main LLVM-TV user interface - it sets up the vertically-split main window having a tree of snapshots on the left (TVTreeCtrl), and a tabbed view containing visualizers on the right (TVNotebook). TVFrame is also responsible for the menu bar, and it is the first object that deals with commands issued as a result of the user choosing menu items. TVTreeItemData is the basic unit of visualization in LLVM-TV. It is also the abstract superclass for all nodes that appear in the tree view on the left-hand side of LLVM-TV's main window. The root of the tree is the Singleton TVTreeRootItem, which is hidden (the user cannot select it) and has no displayable data. The TVTreeRootItem contains TVTreeModuleItems, which point to snapshots of LLVM Modules; the TVTreeModuleItems in turn contain TVTreeFunctionItems, which point to snapshots of LLVM Functions within the parent Modules. The TVHtmlWindow class is an ItemDisplayer that displays syntax-highlighted LLVM assembly code for TVTreeItems (either Functions or Modules) in HTML format. A TVTreeItem uses an HTMLPrinter to display a Function or a Module in a syntax-highlighted view. It also chooses a HTMLMarkup strategy class to decide whether to use Cascading Style Sheets (CSS) or old-style "font" tags for syntax highlighting of elements such as keywords, types, and basic-block names. HTMLPrinter is a Visitor, implemented using the standard LLVM InstVisitor C++ template. TVNotebook is responsible for implementing the tabbed interface which you see on the right-hand side of the main window (the TVFrame). ItemDisplayer is the abstract superclass for objects that know how to visualize LLVM Functions and/or Modules. ItemDisplayers can be displayed in tabs in the TVNotebook view, or in their own windows (called PictureFrames). TVCodeViewer is the ItemDisplayer which implements the "interactive code view" which highlights use-def chains. Each TVCodeViewer contains a TVCodeListCtrl, which is responsible for the actual drawing of the list view, and which is where most of the interesting stuff happens -- TVCodeViewer is essentially an Adapter around TVCodeListCtrl to allow it to display itself either in a tab view or a window. GraphDrawer is an abstract superclass for all graph-drawing visualizers. It inherits the ItemDisplayer interface, so all GraphDrawers are also ItemDisplayers. GraphDrawer simplifies the ItemDisplayer interface using the Template Method pattern. Concrete GraphDrawers only need to be able to provide an image object given a TVTreeItem; the abstract GraphDrawer class provides for displaying the image in a convenient scrolling viewer (called a PictureCanvas). CallGraphDrawer and CFGGraphDrawer are GraphDrawers for displaying the call graph (for a Module) and the control-flow graph (for a Function), respectively. DSAGraphDrawer is an abstract class for Data Structure Graph viewers. It implements GraphDrawer's Abstract Methods drawFunctionGraph() and drawModuleGraph() as Template Methods which rely on pure-virtual C++ methods that return the Pass object to write out the graph, which is different for each of BUGraphDrawer, TDGraphDrawer, and LocalGraphDrawer, as well as the filename to which they output the results of their analysis. The functions createFunctionPass() and createModulePass() are Factory Methods as they create passes of different classes that are subclasses of FunctionPass or Pass, respectively. The algorithm for running the pass on a Function or Module is shared among the 3 subclasses of DSAGraphDrawer. BUGraphDrawer, TDGraphDrawer, and LocalGraphDrawer are also ItemDisplayers, which allows them to be displayed in tabs or in separate new windows. Extending LLVM-TV ----------------- In order to add a new visualization to LLVM-TV, the programmer should add a new concrete subclass of ItemDisplayer. The requirements for a new ItemDisplayer subclass are: 1) An ItemDisplayer must create and hold a wxWindows display widget (subclass of wxWindow) to draw in. The widget should be of a type appropriate to the visualization - for example, if you are displaying a list of things, use a wxListCtrl; if you are displaying a tree, use a wxTreeCtrl. If you want to display an image, you probably will want to create a subclass of GraphDrawer instead (see below). When your getWindow() method is called, you should create the display widget (if it has not already been created) and return a pointer to it. 2) An ItemDisplayer must respond to the displayItem(TVTreeItemData *) message by updating its display widget to contain visual information about the given item. 3) An ItemDisplayer must respond to the getDisplayTitle(TVTreeItemData *) message by returning a string, suitable for a window or tab title, which describes the visualization of the given item -- or if no item is passed in, a string which describes the kind of visualization it generally performs (e.g., "Dominator tree view of java.lang.System.arraycopy()" vs. "Dominator tree view".) If you want to add a new visualization to LLVM-TV which *only* draws images and allows the user to view them, you can subclass GraphDrawer. Instead of requirements 1) and 2) above, a new subclass of GraphDrawer is required to respond to the drawModuleGraph(Module *) and drawFunctionGraph(Function *) messages by returning a wxImage object that contains an image representing the LLVM item passed in. GraphDrawer will take care of displaying the image in a scrolling canvas, either in a tab or a separate window.