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