AsmFunctionIndex.h

Go to the documentation of this file.
00001 #ifndef ROSE_AsmFunctionIndex_H
00002 #define ROSE_AsmFunctionIndex_H
00003 
00004 #include <algorithm>
00005 #include <ostream>
00006 #include <vector>
00007 
00008 #include "callbacks.h"
00009 
00058 class AsmFunctionIndex {
00059     /**************************************************************************************************************************
00060      *                                  The main public members
00061      **************************************************************************************************************************/
00062 public:
00063 
00065     AsmFunctionIndex() {
00066         init();
00067     }
00068 
00070     AsmFunctionIndex(SgNode *ast) {
00071         init();
00072         add_functions(ast);
00073     }
00074     
00075     virtual ~AsmFunctionIndex() {}
00076 
00078     virtual void add_function(SgAsmFunction*);
00079 
00083     virtual void add_functions(SgNode *ast);
00084 
00086     virtual void clear() {
00087         functions.clear();
00088     }
00089 
00091     virtual bool empty() const {
00092         return functions.empty();
00093     }
00094 
00096     virtual size_t size() const {
00097         return functions.size();
00098     }
00099 
00100     /**************************************************************************************************************************
00101      *                                  Functors for sorting
00102      * These are expected to be commonly used, so we define them here for convenience.  The generic sorting method is defined
00103      * below.
00104      **************************************************************************************************************************/
00105 public:
00106 
00108     struct SortByEntryAddr {
00109         bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
00110             return a->get_entry_va() < b->get_entry_va();
00111         }
00112         bool unique(SgAsmFunction *a, SgAsmFunction *b) {
00113             return a->get_entry_va() != b->get_entry_va();
00114         }
00115     };
00116 
00118     struct SortByBeginAddr {
00119         bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
00120             return val(a)<val(b);
00121         }
00122         bool unique(SgAsmFunction *a, SgAsmFunction *b) {
00123             return val(a)!=val(b);
00124         }
00125         rose_addr_t val(SgAsmFunction *x) {
00126             rose_addr_t lo;
00127             x->get_extent(NULL, &lo);
00128             return lo;
00129         }
00130     };
00131 
00133     struct SortByInsnsSize {
00134         bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
00135             return val(a) < val(b);
00136         }
00137         bool unique(SgAsmFunction *a, SgAsmFunction *b) {
00138             return val(a) != val(b);
00139         }
00140         size_t val(SgAsmFunction *x) {
00141             return SageInterface::querySubTree<SgAsmInstruction>(x).size();
00142         }
00143     };
00144 
00147     struct SortByBytesSize {
00148         bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
00149             return val(a) < val(b);
00150         }
00151         bool unique(SgAsmFunction *a, SgAsmFunction *b) {
00152             return val(a) != val(b);
00153         }
00154         size_t val(SgAsmFunction *x) {
00155             ExtentMap extent;
00156             x->get_extent(&extent);
00157             return extent.size();
00158         }
00159     };
00160 
00162     struct SortByName {
00163         bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
00164             return a->get_name().compare(b->get_name()) < 0;
00165         }
00166         bool unique(SgAsmFunction *a, SgAsmFunction *b) {
00167             return 0 != a->get_name().compare(b->get_name());
00168         }
00169     };
00170 
00171 
00172 
00173     /**************************************************************************************************************************
00174      *                                  Sorting methods
00175      **************************************************************************************************************************/
00176 public:
00177 
00183     template<class Comparator> AsmFunctionIndex& sort(Comparator comp, bool unique=false) {
00184         std::stable_sort(functions.begin(), functions.end(), comp);
00185         if (unique) {
00186             Functions newlist;
00187             for (Functions::iterator fi=functions.begin(); fi!=functions.end(); fi++) {
00188                 if (newlist.empty() || comp.unique(newlist.back(), *fi))
00189                     newlist.push_back(*fi);
00190             }
00191             if (newlist.size()!=functions.size())
00192                 functions = newlist;
00193         }
00194         return *this;
00195     }
00196 
00200     AsmFunctionIndex& sort_by_entry_addr(bool unique=false) { return sort(SortByEntryAddr(), unique); }
00201     AsmFunctionIndex& sort_by_begin_addr(bool unique=false) { return sort(SortByBeginAddr(), unique); }
00202     AsmFunctionIndex& sort_by_ninsns(bool unique=false)     { return sort(SortByInsnsSize(), unique); }
00203     AsmFunctionIndex& sort_by_nbytes(bool unique=false)     { return sort(SortByBytesSize(), unique); }
00204     AsmFunctionIndex& sort_by_name(bool unique=false)       { return sort(SortByName(),      unique); }
00208     AsmFunctionIndex& reverse() {
00209         std::reverse(functions.begin(), functions.end());
00210         return *this;
00211     }
00212 
00213     /**************************************************************************************************************************
00214      *                                  Footnotes
00215      **************************************************************************************************************************/
00216 public:
00217     class Footnotes {
00218     public:
00219         Footnotes() {
00220             set_footnote_title("== Footnotes ==");
00221         }
00222 
00230         size_t add_footnote(const std::string &text);
00231 
00236         void change_footnote(size_t idx, const std::string &text);
00237 
00240         const std::string& get_footnote(size_t idx) const;
00241 
00244         size_t size() const { return footnotes.size(); }
00245 
00248         void set_footnote_title(const std::string &title);
00249 
00251         const std::string& get_footnote_title() const;
00252 
00255         void set_footnote_prefix(const std::string &prefix) { footnote_prefix = prefix; }
00256 
00258         const std::string& get_footnote_prefix() const { return footnote_prefix; }
00259 
00261         std::string get_footnote_name(size_t idx) const;
00262 
00264         void print(std::ostream&) const;
00265 
00267         friend std::ostream& operator<<(std::ostream &o, const Footnotes *footnotes) {
00268             footnotes->print(o);
00269             return o;
00270         }
00271 
00272     protected:
00273         std::vector<std::string> footnotes;     
00274         std::string footnote_prefix;            
00275     };
00276     
00277     /**************************************************************************************************************************
00278      *                                  Output methods
00279      **************************************************************************************************************************/
00280 public:
00282     virtual void print(std::ostream&) const;
00283     friend std::ostream& operator<<(std::ostream&, const AsmFunctionIndex&);
00284 
00285 
00286 
00287     /**************************************************************************************************************************
00288      *                                  Output callback base classes
00289      **************************************************************************************************************************/
00290 public:
00291 
00307     class OutputCallback {
00308     public:
00310         struct GeneralArgs {
00311             GeneralArgs(const AsmFunctionIndex *index, std::ostream &output, Footnotes *footnotes)
00312                 : index(index), output(output), footnotes(footnotes) {}
00313             const AsmFunctionIndex *index;              
00314             std::ostream &output;                       
00315             Footnotes *footnotes;                       
00316         };
00317 
00319         struct BeforeAfterArgs: public GeneralArgs {
00320             BeforeAfterArgs(const AsmFunctionIndex *index, std::ostream &output, Footnotes *footnotes, int when)
00321                 : GeneralArgs(index, output, footnotes), when(when) {}
00322             int when;                                  
00323         };
00324 
00327         struct HeadingArgs: public GeneralArgs {
00328             HeadingArgs(const AsmFunctionIndex *index, std::ostream &output, Footnotes *footnotes, char sep='\0')
00329                 : GeneralArgs(index, output, footnotes), sep(sep) {}
00330             char sep;                                   
00331         };
00332 
00334         struct DataArgs: public GeneralArgs {
00335             DataArgs(const AsmFunctionIndex *index, std::ostream &output, Footnotes *footnotes, SgAsmFunction *func, size_t rowid)
00336                 : GeneralArgs(index, output, footnotes), func(func), rowid(rowid) {}
00337             SgAsmFunction *func;
00338             size_t rowid;
00339         };
00340 
00344         OutputCallback(const std::string &name, size_t width, const std::string description="")
00345             : name(name), desc(description), width(width), header_prefix(" "), separator_prefix(" "), data_prefix(" ") {
00346             assert(width>0 || name.empty());
00347         }
00348 
00349         virtual ~OutputCallback() {}
00350 
00352         void set_prefix(const std::string &header, const std::string &separator=" ", const std::string &data=" ");
00353 
00356         virtual bool operator()(bool enabled, const BeforeAfterArgs&);
00357 
00360         virtual bool operator()(bool enabled, const HeadingArgs&);
00361 
00364         virtual bool operator()(bool enabled, const DataArgs&);
00365 
00366     protected:
00367         std::string center(const std::string&, size_t width); 
00369         std::string name;                               
00370         std::string desc;                               
00371         size_t width;                                   
00372         std::string header_prefix;                      
00373         std::string separator_prefix;                   
00374         std::string data_prefix;                        
00375     };
00376 
00377 
00378 
00379     /**************************************************************************************************************************
00380      *                                  Predefined output callbacks
00381      **************************************************************************************************************************/
00382 public:
00383 
00385     class RowIdCallback: public OutputCallback {
00386     public:
00387         RowIdCallback(): OutputCallback("Num", 4) {}
00388         virtual bool operator()(bool enabled, const DataArgs&);
00389     } rowIdCallback;
00390 
00392     class EntryAddrCallback: public OutputCallback {
00393     public:
00394         EntryAddrCallback(): OutputCallback("Entry-Addr", 10) {}
00395         virtual bool operator()(bool enabled, const DataArgs&);
00396     } entryAddrCallback;
00397 
00399     class BeginAddrCallback: public OutputCallback {
00400     public:
00401         BeginAddrCallback(): OutputCallback("Begin-Addr", 10) {}
00402         virtual bool operator()(bool enabled, const DataArgs&);
00403     } beginAddrCallback;
00404 
00406     class EndAddrCallback: public OutputCallback {
00407     public:
00408         EndAddrCallback(): OutputCallback("End-Addr", 10) {}
00409         virtual bool operator()(bool enabled, const DataArgs&);
00410     } endAddrCallback;
00411 
00413     class SizeInsnsCallback: public OutputCallback {
00414     public:
00415         SizeInsnsCallback(): OutputCallback("Insns", 5) {}
00416         virtual bool operator()(bool enabled, const DataArgs&);
00417     } sizeInsnsCallback;
00418 
00420     class SizeBytesCallback: public OutputCallback {
00421     public:
00422         SizeBytesCallback(): OutputCallback("Bytes", 6) {
00423             set_prefix("/", "-", "/");
00424         }
00425         virtual bool operator()(bool enabled, const DataArgs&);
00426     } sizeBytesCallback;
00427 
00429     class ReasonCallback: public OutputCallback {
00430     public:
00431         ReasonCallback(): OutputCallback("Reason", 1) {} // width will be overridden in the callback
00432         virtual bool operator()(bool enabled, const HeadingArgs&);
00433         virtual bool operator()(bool enabled, const DataArgs&);
00434     } reasonCallback;
00435 
00437     class CallingConventionCallback: public OutputCallback {
00438     public:
00439         CallingConventionCallback(): OutputCallback("Kind", 8) {}
00440         virtual bool operator()(bool enabled, const DataArgs&);
00441     } callingConventionCallback;
00442 
00444     class NameCallback: public OutputCallback {
00445     public:
00446         NameCallback(): OutputCallback("Name", 32) {}
00447         virtual bool operator()(bool enabled, const DataArgs&);
00448     } nameCallback;
00449 
00451     class FootnotesCallback: public OutputCallback {
00452     public:
00453         FootnotesCallback(): OutputCallback("", 0) {}   // not a table column
00454         virtual bool operator()(bool enabled, const BeforeAfterArgs&);
00455     } footnotesCallback;
00456 
00457 
00458 
00459     /**************************************************************************************************************************
00460      *                                  Miscellaneous
00461      **************************************************************************************************************************/
00462 protected:
00463     typedef std::vector<SgAsmFunction*> Functions;
00464     Functions functions;                                
00467     virtual void init();
00468 
00470     ROSE_Callbacks::List<OutputCallback> output_callbacks;
00471 };
00472 
00473     
00474 #endif

Generated on Wed May 16 06:17:52 2012 for ROSE by  doxygen 1.4.7