70 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			70 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			HTML
		
	
	
	
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 | |
| <html xmlns="http://www.w3.org/1999/xhtml">
 | |
| <head>
 | |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
 | |
| <link href="style.css" rel="stylesheet" type="text/css" />
 | |
| <title>LLDB Tutorial</title>
 | |
| </head>
 | |
| 
 | |
| <body>
 | |
|     <div class="www_title">
 | |
|       The SB API Coding Rules
 | |
|     </div>
 | |
|     
 | |
| <div id="container">
 | |
| 	<div id="content">
 | |
|          <!--#include virtual="sidebar.incl"-->
 | |
| 		<div id="middle">
 | |
| 			<div class="post">
 | |
| 				<h1 class ="postheader">SB API Coding Rules</h1>
 | |
| 				<div class="postcontent">
 | |
| 
 | |
| 
 | |
|                                   <p>The SB APIs constitute the stable C++ API that lldb presents to external clients, 
 | |
|                                     and which get processed by SWIG to produce the Python bindings to lldb.  As such
 | |
|                                     it is important that they not suffer from the binary incompatibilities that C++ is
 | |
|                                     so susceptible to.  We've established a few rules to ensure that this happens.
 | |
|                                     
 | |
|                                   <p>The classes in the SB API's are all called SB<SomeName>, where SomeName is in CamelCase
 | |
|                                       starting with an upper case letter.  The method names are all CamelCase with initial
 | |
|                                       capital letter as well.
 | |
|                                       
 | |
|                                       <p>All the SB API classes are non-virtual, single inheritance classes.  They should only include
 | |
|                                         SBDefines.h or other SB headers as needed.  There should be no inlined method implementations
 | |
|                                         in the header files, they should all be in the implementation files.  And there should be no
 | |
|                                         direct ivar access.
 | |
| 
 | |
|                                       <p>You also need to choose the ivars for the class with care, since you can't add or remove ivars
 | |
|                                         without breaking binary compatibility.  In some cases, the SB class is a thin wrapper around
 | |
|                                         an interal lldb_private object.  In that case, the class can have a single ivar, which is 
 | |
|                                         either a pointer, shared_ptr or unique_ptr to the object in the lldb_private API.  All the
 | |
|                                         lldb_private classes that get used this way are declared as opaque classes in lldb_forward.h,
 | |
|                                         which is included in SBDefines.h.  So if you need an SB class to wrap an lldb_private class
 | |
|                                         that isn't in lldb_forward.h, add it there rather than making a direct opaque declaration in
 | |
|                                         the SB classes .h file.  
 | |
| 
 | |
|                                       <p>If the SB Class needs some state of its own, as well as the backing object, don't include that
 | |
|                                         as a direct ivar in the SB Class.  Instead, make an Impl class in the SB's .cpp file, and then
 | |
|                                         make the SB object hold a shared or unique pointer to the Impl object.  The theory behind this is
 | |
|                                         that if you need more state in the SB object, those needs are likely to change over time, 
 | |
|                                         and this way the impl class can pick up members without changing the size of the object.
 | |
|                                         An example of this is the SBValue class.
 | |
|                                         
 | |
|                                       <p>In order to fit into the Python API's, we need to be able to default construct all the SB objects.
 | |
|                                         Since the ivars of the classes are all pointers of one sort or other, this can easily be done, but
 | |
|                                         it means all the methods must be prepared to handle their opaque implementation pointer being
 | |
|                                         empty, and doing something reasonable.  We also always have an "IsValid" method on all the SB 
 | |
|                                         classes to report whether the object is empty or not.
 | |
| 
 | |
|                                       <p>Another piece of the SB API infrastructure is the Python (or other script interpreter) customization.  
 | |
|                                         SWIG allows you to add property access, iterators and documentation to classes, but to do that you have to use
 | |
|                                         a Swig interface file in place of the .h file. Those files have a different format than a straight C++ header file.  These 
 | |
|                                         files are called SB<ClassName>.i, and live in "scripts/interface".  They are constructed by
 | |
|                                         starting with the associated .h file, and adding documentation and the Python decorations, etc.  We
 | |
|                                         do this in a decidedly low-tech way, by maintaining the two files in parallel.  That simplifies the
 | |
|                                         build process, but it does mean that if you add a method to the C++ API's for an SB class, you have
 | |
|                                         to copy the interface to the .i file.
 | |
| </div>
 | |
| </body>
 | |
| </html>
 |