include/EDoc/Function.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003    Copyright (C) 2007 by Brendon Costa
00004 
00005    This library is free software; you can redistribute it and/or modify 
00006    it under the terms of the "LGPL Like" License defined in the file COPYING 
00007    that should have been distributed along with this source.
00008 
00009    This library is distributed in the hope that it will be useful, 
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of 
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013    You should have received a copy of the "LGPL Like" License 
00014    along with this library; see the file COPYING. if not, it can be 
00015    obtained from the EDoc++ website: 
00016    http://edoc.sourceforge.net/license.html
00017 
00018 *******************************************************************************/
00019 #ifndef EDOC_FUNCTION_H
00020 #define EDOC_FUNCTION_H
00021 
00022 #include "EDoc/StringIdentifiedObject.h"
00023 #include "EDoc/exceptions.h"
00024 #include "EDoc/CodeBlock.h"
00025 #include "EDoc/PropogatingException.h"
00026 #include "EDoc/exceptions.h"
00027 
00028 #include <ostream>
00029 #include <string>
00030 #include <sstream>
00031 #include <map>
00032 #include <set>
00033 
00034 namespace EDoc
00035 {
00036    class PersistenceIFace;
00037    class IndexedDictionary;
00038    class Type;
00039    class PStack;
00040    class TranslationUnit;
00041    
00042    //===========================================================================
00043    /** \brief Represents a function in C/C++ code that has been encounterd
00044     * during compilation.
00045     *
00046     * The function object stores all information about encountered functions.
00047     * This includes information about functions that are called which do not
00048     * have implementations in the translation unit.
00049     */
00050    class Function : public StringIdentifiedObject
00051    {
00052    public:
00053 
00054       //------------------------------------------------------------------------
00055       /** \brief See StringIdentifiedObject::(Dictionary& dict_in, 
00056        * std::string key_name_in, bool populated_in=false)
00057        */
00058       Function(Dictionary& dict_in, std::string key_name_in);
00059 
00060       //------------------------------------------------------------------------
00061       /** \brief See StringIdentifiedObject(Dictionary& dict_in, 
00062        * int32_t index_in, bool populated_in=false)
00063        */
00064       Function(Dictionary& dict_in, int32_t index_in);
00065 
00066       //------------------------------------------------------------------------
00067       /** \brief Destructor.
00068        */
00069       virtual ~Function();
00070 
00071       //------------------------------------------------------------------------
00072       /** \brief Copies data from another object into this one.
00073        *
00074        * This can be used across different dictionaries and will only copy
00075        * object data but not identification information used in the
00076        * StringIdentifiedObject such as the key name.
00077        */
00078       Function& operator=(const Function& right);
00079 
00080 
00081       //------------------------------------------------------------------------
00082       /** \brief See StringIdentifiedObject::Read()
00083        */
00084       void Read(PersistenceIFace& file, IndexedDictionary& idict);
00085 
00086       //------------------------------------------------------------------------
00087       /** \brief See StringIdentifiedObject::Write()
00088        */
00089       void Write(PersistenceIFace& file) const;
00090 
00091       //------------------------------------------------------------------------
00092       /** \brief See StringIdentifiedObject::Merge()
00093        *
00094        * Merging two functions can occur in a few ways:
00095        *    -# One function has an implementation the other does not.
00096        *          This is simple to resolve and behaves like standard linking in
00097        *          that it keeps the implementation that exists.
00098        *
00099        *    -# Both functions have no implementations.
00100        *          The merge will only import a small amount of data like
00101        *          additional locations where its address may have been taken
00102        *          from etc.
00103        *
00104        *    -# Both functions have implementations but both implementations are
00105        *       the same.
00106        *          The merge will only import a small amount of data like
00107        *          additional locations where its address may have been taken
00108        *          from etc. This is normal occurance with functions like
00109        *          template functions that have "vague linkage".
00110        *
00111        *    -# Both functions have implementations but the implementations
00112        *       differ in a resolvable but unrealistic way.
00113        *          This should not occur, but may do so due to bad inputs or the
00114        *          user using certain features of the linker that are not
00115        *          advisable. In this case we merge the implementations such that
00116        *          it is the most restrictive union between the two
00117        *          implementations an we emit an error.
00118        *
00119        *    -# Both functions have implementations but the implementations
00120        *       differ in a way in which they can not be merged.
00121        *          This should never occur.
00122        *    .
00123        *
00124        */
00125       virtual void Merge(const StringIdentifiedObject& right);
00126 
00127       //------------------------------------------------------------------------
00128       /** \brief DictionarySpecific::ReplaceReferences()
00129        */
00130       virtual size_t ReplaceReferences(PStack& stack, 
00131          void* remove, void* replace);
00132 
00133       //------------------------------------------------------------------------
00134       /** \brief See DictionarySpecific::Print()
00135        */
00136       virtual std::ostream& Print(std::ostream& out, 
00137          std::string prefix="") const;
00138 
00139       //------------------------------------------------------------------------
00140       /** \brief See DictionarySpecific::Validate()
00141        */
00142       virtual void Validate(PStack& stack, const Dictionary& dict_in) const;
00143 
00144       //------------------------------------------------------------------------
00145       /** \brief See StringIdentifiedObject::GetRecordType()
00146        */
00147       virtual uint8_t GetRecordType() const;
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155       //------------------------------------------------------------------------
00156       /** \brief Returns a string with the user text that the function was
00157        * declared with.
00158        */
00159       inline std::string GetDeclaredName() const
00160       {
00161          return full_name;
00162       }
00163 
00164       //------------------------------------------------------------------------
00165       /** \brief Sets a string with the user text that the function was
00166        * declared with.
00167        */
00168       inline void SetDeclaredName(std::string name_in)
00169       {
00170          full_name = name_in;
00171       }
00172 
00173       //------------------------------------------------------------------------
00174       /** \brief Returns the unique linker id name (C++ Mangaled name).
00175        */
00176       inline std::string GetNormalisedName() const
00177       {
00178          return link_name;
00179       }
00180       
00181 
00182       //------------------------------------------------------------------------
00183       /** \brief Returns a user readable string with the functions exception
00184        * restriction specification.
00185        *
00186        * This is the throw () string after the function prototype.
00187        */
00188       std::string GetSpecString() const;
00189 
00190       //------------------------------------------------------------------------
00191       /** \brief Returns a user readable string listing all the source files
00192        * that this function has been referenced from within.
00193        *
00194        * Useful for debugging.
00195        */
00196       std::string GetRefInFilesString() const;
00197 
00198       //------------------------------------------------------------------------
00199       /** \brief See Dictionary::ExpandCallGraph()
00200        */
00201       void ExpandCallGraph();
00202 
00203       //------------------------------------------------------------------------
00204       /** \brief Returns a list of all exceptions that propogate from this
00205        * function that have not been suppressed.
00206        *
00207        * Must be called after Dictionary::CalculatePropogatingExceptions()
00208        */
00209       std::list<const PropogatingException*> GetVisiblePropExceptions() const;
00210       
00211       //------------------------------------------------------------------------
00212       /** \brief Returns true if this represents the main function.
00213        */
00214       bool IsMain() const;
00215       
00216       //------------------------------------------------------------------------
00217       /** \brief Returns true if this function is a "Static initializer".
00218        *
00219        * A static initializer function is used to initialize complex static data
00220        * in a translation unit. This called before the main function.
00221        */
00222       bool IsStaticInitialiser() const;
00223       
00224       //------------------------------------------------------------------------
00225       /** \brief Returns true if this represents a destructor for a class.
00226        */
00227       bool IsDestructor() const;
00228       
00229       //------------------------------------------------------------------------
00230       /** \brief Returns a list of pointers to propogating exceptions that can 
00231        * be used by the python wrappers in order to modify the propogating
00232        * exception objects.
00233        */
00234       std::list<EDoc::PropogatingException*> GetPropogatingExceptions();
00235 
00236       //------------------------------------------------------------------------
00237       /** \brief Returns a reference to the subst exception for this function.
00238        *
00239        * The special "substitution" exception is used to represent all 
00240        * exceptions that may propagate out of a function. It is used in 
00241        * particular cases where the list of known exceptions can not be known 
00242        * or calculated until a later date. So when the list of exceptions can 
00243        * be determined this exception instance is replaced with that 
00244        * complete list.
00245        *
00246        * This is primarily used in the calculation of propagating exceptions 
00247        * in recursive functions.
00248        */
00249       Exception& GetSubstException();
00250 
00251       //------------------------------------------------------------------------
00252       /** \brief If this function is part of a circular call graph then
00253        * this function will remove this instance from the circular 
00254        * set: circular.
00255        *
00256        * This is primarily just used for cleaning up on destruction. The
00257        * circular parameter is generally only created by the 
00258        * Dictionary::CalculatePropagatingExceptions()
00259        *
00260        * See "private" member circular
00261        */
00262       void RemoveFromCircular();
00263 
00264       //------------------------------------------------------------------------
00265       /** \brief Returns true if this function participates in a circular
00266        * callgraph.
00267        */
00268       bool IsCircular() const {return circular;}
00269 
00270       //------------------------------------------------------------------------
00271       /** \brief Returns true if this function participates in a circular
00272        * callgraph.
00273        */
00274       const std::set<Function*>& GetCircleSet() const 
00275       {
00276          EDOC_ASSERT(circular, "");
00277          return *circular;
00278       }
00279 
00280       //------------------------------------------------------------------------
00281 
00282 
00283       //------------------------------------------------------------------------
00284       // Public Primary Data values.
00285       //------------------------------------------------------------------------
00286 
00287       //------------------------------------------------------------------------
00288       /** \brief The linker string id used for identifying this function.
00289        *
00290        * When in C++ this is the mangled function name.
00291        */
00292       std::string link_name;
00293 
00294       //------------------------------------------------------------------------
00295       /** \brief The name of the function as declared by the user in the source
00296        * file.
00297        */
00298       std::string full_name;
00299 
00300       //------------------------------------------------------------------------
00301       /** \brief True if this funciton has public scope or false if it is
00302        * private to the translation unit it belongs to.
00303        */
00304       bool is_public;
00305 
00306       //------------------------------------------------------------------------
00307       /** \brief True if this function was inlined at compile time.
00308        *
00309        * Note: Inlined functions are treated a littlelike static functions. They
00310        * can safely have implementation variations between tanslation units.
00311        */
00312       bool is_inline;
00313 
00314       //------------------------------------------------------------------------
00315       /** \brief True if this function was generated implicitly by the compiler 
00316        * and explicitly created by the user.
00317        *
00318        * An example of an implicit function is a Default Constructor created
00319        * when no other constructors are provided.
00320        */
00321       bool is_implicit;
00322 
00323       //------------------------------------------------------------------------
00324       /** \brief True if an exception specification restriction exists for this
00325        * function.
00326        */
00327       bool has_exception_spec;
00328 
00329       //------------------------------------------------------------------------
00330       /** \brief If has_exception_spec is true lists the exception types that
00331        * are allowed to propogate out this function.
00332        */
00333       // @@@Brendon Make a list.
00334       std::vector<Type*> exception_spec;
00335 
00336       //------------------------------------------------------------------------
00337       /** \brief A list of source code locations where the address of this
00338        * function was taken for use with a function pointer etc.
00339        */
00340       // @@@Brendon Make a list.
00341       std::vector<Location> address_taken;
00342 
00343       //------------------------------------------------------------------------
00344       /** \brief The function pointer that represents the type of this funciton.
00345        *
00346        * This is used for matching function pointer calls to functions. See
00347        * FunctionType for more information.
00348        */
00349       FunctionType* function_pointer_type;
00350 
00351       //------------------------------------------------------------------------
00352       /** \brief The location in the source files where this functions prototype
00353        * was declared or its implementation was defined.
00354        */
00355       Location loc;
00356 
00357       //------------------------------------------------------------------------
00358       /** \brief True if this function was compiled in a translation unit where
00359        * exceptions were allowed.
00360        *
00361        * This is true when -fno-exceptions was not specified in C++
00362        * or -fexceptions was specified for C. If false then any exceptions that
00363        * enter or exit this function will cause a program abort.
00364        */
00365       bool exceptions_enabled;
00366 
00367       //------------------------------------------------------------------------
00368       /** \brief Returns the number of implementations of this function have
00369        * been processed.
00370        *
00371        * For most normal functions this should be 1. However for vague linkage
00372        * functions like template functions this may be more than 1. If 0 however
00373        * then there should be no valid data in the implementation member.
00374        */
00375       int processed_implementations;
00376 
00377       //------------------------------------------------------------------------
00378       /** \brief A reference to the unique translation unit instance that this
00379        * function belongs to.
00380        */
00381       TranslationUnit* translation_unit;
00382       
00383       //------------------------------------------------------------------------
00384       /** \brief The implementation for this function.
00385        *
00386        * The CodeBlock describes in a heirarchial format all function calls,
00387        * function pointer calls, and try/catch blocks that make up this
00388        * functions implementation.
00389        *
00390        * This member is not valid unless processed_implementations is not zero.
00391        */
00392       CodeBlock implementation;
00393 
00394 
00395       //------------------------------------------------------------------------
00396       // Public Derived Data values.
00397       //------------------------------------------------------------------------
00398 
00399 
00400       //------------------------------------------------------------------------
00401       /** \brief True if the propogating exceptions for this function have been
00402        * completely calculated.
00403        */
00404       bool calculated_propogating_exceptions;
00405 
00406       //------------------------------------------------------------------------
00407       /** \brief A list of all exceptions that may propogate out this function.
00408        */
00409       std::list<PropogatingException> propogating_exceptions;
00410 
00411       //------------------------------------------------------------------------
00412       /** \brief A list of functions that may be called as a result of a call to
00413        * this function due to them being matching virtuals in derived classes.
00414        *
00415        * List of functions that when this function is called it could result in
00416        * any of the functions in this list being called as they belong in
00417        * derived children and this function is virtual.
00418        *
00419        * \see See also virt_func_fallthrough
00420        */
00421       std::vector<Function*> derived_virtuals;
00422 
00423       //------------------------------------------------------------------------
00424       /** \brief Is a list of exceptions that would have propogated out this
00425        * function had they not been filtered out by the exception spec.
00426        *
00427        * This is a list of exceptions that would be filterested out by the
00428        * throw() specs. There should be an error emitted for each filtered
00429        * exception encountered. They do not propogate.
00430        *
00431        * \see See also exception_spec and has_exception_spec
00432        */
00433       std::vector<PropogatingException> filtered_exceptions;
00434 
00435       //------------------------------------------------------------------------
00436       /** \brief A list of all source files that this function is used from.
00437        */
00438       std::list<File*> referenced_in_files;
00439 
00440 
00441       //------------------------------------------------------------------------
00442       /** \brief True if this function is visible to the user or false if 
00443        * it will never be displayed to the user.
00444        *
00445        * This is used for suppressions.
00446        */
00447       bool visible;
00448 
00449       //------------------------------------------------------------------------
00450       /** \brief The subst exception for this function.
00451        *
00452        * \see GetSubstException()
00453        */
00454       Exception* subst_exception;
00455       
00456       //------------------------------------------------------------------------
00457       // Public Temporary Data values.
00458       //------------------------------------------------------------------------
00459       /** \brief USED ONLY FROM Dictionary::CalculatePropogatingExceptions()
00460        *
00461        * This is used as temporary storage while determining the callgraph
00462        * complexity of all functions. Realistically this data does not belong
00463        * here and should be placed elsewhere but as a speed optimisation it is
00464        * placed here.
00465        */
00466       int total_calls;
00467       
00468       //------------------------------------------------------------------------
00469       /** \brief USED ONLY FROM 
00470        *
00471        * This is used as a temporary cache of information and is calculated
00472        * at the same time as total_calls. If it has a reference to a instance
00473        * then this function is marked as being part of a circular call-graph.
00474        *
00475        * The memory for the instance of the std::set is shared among all 
00476        * Function instances that are part of the circle. Thus when the last of
00477        * the function instances is deleted then the std::set instance is also 
00478        * deleted.
00479        *
00480        * See RemoveFromCircular()
00481        */
00482       std::set<Function*>* circular;
00483 
00484       //------------------------------------------------------------------------
00485       /** \brief Function pointer for callback called after a function 
00486        * has finished having its propogating exceptions calculated.
00487        */
00488       typedef void(*OnProcessedFP)(Function& function, void* data);
00489 
00490       //------------------------------------------------------------------------
00491       /** \brief Set a callback function to be called immediatly after the
00492        * functions set of propogating exceptions have been calculated.
00493        *
00494        * This is generally used for suppressing any exceptions that propogate
00495        * from this function by making the exceptions invisible, without removing
00496        * them entirely. This feature is used by the default suppressions.
00497        *
00498        * \param fp Pointer to function to be called.
00499        *
00500        * \param data Some data to be passed to the function pointer when it 
00501        * is called.
00502        */
00503       void SetOnProcessed(OnProcessedFP fp, void* data)
00504       {
00505          on_processed = fp;
00506          on_processed_data = data;
00507       }
00508       
00509       //------------------------------------------------------------------------
00510       /** \brief Callback function pointer (See SetOnProcessed())
00511        */
00512       OnProcessedFP on_processed;
00513 
00514       //------------------------------------------------------------------------
00515       /** \brief Callback function pointers data (See SetOnProcessed())
00516        */
00517       void* on_processed_data;
00518 
00519       //------------------------------------------------------------------------
00520    };
00521    //===========================================================================
00522    typedef std::map<std::string, EDoc::Function*> FuncPMap;
00523    typedef std::list<EDoc::Function*> FuncPList;
00524    //---------------------------------------------------------------------------
00525 }
00526 
00527 #endif // EDOC_FUNCTION_H

Generated on Tue Jan 20 18:26:07 2009 for EDoc-0.2.1 by  doxygen 1.5.1