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_CODEBLOCK_H 00020 #define EDOC_CODEBLOCK_H 00021 00022 #include "EDoc/DictionarySpecific.h" 00023 #include "EDoc/FunctionLoc.h" 00024 #include "EDoc/FunctionTypeLoc.h" 00025 #include "EDoc/TryBlock.h" 00026 #include "EDoc/Exception.h" 00027 00028 #include <string> 00029 #include <ostream> 00030 #include <list> 00031 #include <sstream> 00032 00033 namespace EDoc 00034 { 00035 class PersistenceIFace; 00036 class IndexedDictionary; 00037 class Type; 00038 class Dictionary; 00039 class Function; 00040 class PStack; 00041 class Function; 00042 00043 00044 //=========================================================================== 00045 /** \brief Represents a block of code that may call functions, throw 00046 * exceptions or contain try/catch blocks. 00047 * 00048 * A CodeBlock contains a list of: 00049 * - function_calls 00050 * - originating_exceptions 00051 * - function_pointer_calls 00052 * - try_blocks 00053 * . 00054 * 00055 * these are considered "primary" information sources from which the derived 00056 * information source "possible_function_calls" is obtained. 00057 */ 00058 class CodeBlock : public DictionarySpecific 00059 { 00060 public: 00061 00062 //------------------------------------------------------------------------ 00063 /** \brief Create a new instance that belongs to the given dictionary. 00064 * 00065 * \param dict_in See DictionarySpecific::DictionarySpecific() 00066 */ 00067 CodeBlock(Dictionary* dict_in=NULL); 00068 00069 //------------------------------------------------------------------------ 00070 /** \brief Copy constructor. 00071 * 00072 * New object will belong to the same dictionary as the object being 00073 * copied from. 00074 */ 00075 CodeBlock(const CodeBlock& right); 00076 00077 //------------------------------------------------------------------------ 00078 /** \brief Create a new instance as a copy of another instance 00079 * but place this one in a different dictionary. 00080 */ 00081 CodeBlock(const CodeBlock& right, Dictionary& dict_in); 00082 00083 //------------------------------------------------------------------------ 00084 /** \brief Assignment operator. 00085 * 00086 * Can be used to assign from an object that belongs to a different 00087 * dictionary. However you must be careful that the StringIdentifiedObject 00088 * objects that are being copied already exist in this dictionary OR will 00089 * be populated soon after the assignment. 00090 */ 00091 CodeBlock& operator=(const CodeBlock& right); 00092 00093 00094 00095 00096 //------------------------------------------------------------------------ 00097 /** \brief Read the contents of this object data from the given 00098 * file persistence interface. 00099 * 00100 * Use of the PersistenceIFace requires that data be read in the same 00101 * order it was written (Regardless of the fact that we provide a key 00102 * which is primarily used for debugging purposes). 00103 * 00104 * \param file The interface to the file from which we will load the data. 00105 * Using this interface allows us to easily modify the format of the file 00106 * being read/written without having to modify the reading/writing code. 00107 * 00108 * \param idict The IndexedDictionary object being used to load the 00109 * translation units data from the file. See Dictionary::Read() for more 00110 * information on how the IndexedDictionary is used. 00111 */ 00112 void Read(PersistenceIFace& file, IndexedDictionary& idict); 00113 00114 //------------------------------------------------------------------------ 00115 /** \brief Write the contents of this objects data to the given 00116 * file persistence interface. 00117 * 00118 * Use of the PersistenceIFace requires that data be read in the same 00119 * order it was written (Regardless of the fact that we provide a key 00120 * which is primarily used for debugging purposes). 00121 * 00122 * \param file The interface to the file from which we will load the data. 00123 * Using this interface allows us to easily modify the format of the file 00124 * being read/written without having to modify the reading/writing code. 00125 */ 00126 void Write(PersistenceIFace& file) const; 00127 00128 //------------------------------------------------------------------------ 00129 /** \brief Will merge the contents of the given instance into the current 00130 * instance. 00131 * 00132 * GEBERAL INFORMATION ABOUT MERGING 00133 * 00134 * Merging is performed between two instances which MAY or MAY NOT belong 00135 * to different dictionaries. The idea is to create a union of the two 00136 * instances in a way that is meaningful for the particular object type. 00137 * For example merging two Type instances will require that the two 00138 * objects have exactly the same names and throw types, but may have 00139 * different types in the identical/catchable lists. 00140 * 00141 * Merging will usually be performed starting at instances of 00142 * StringIdentifiedObject's when doing a Dictionary::Merge() If two of 00143 * these objects have the same string identifiers it will be eithre 00144 * possible to merge them or will cause a conflict in which case the merge 00145 * will fail and throw a MergeException. 00146 * 00147 * Each type will have specifics about what it means to merge them and 00148 * they are documented in the appropiate types documentation. 00149 * 00150 * 00151 * 00152 * INFORMATION SPECIFIC TO CodeBlock::Merge(): 00153 * 00154 * This merge differs from others in that it will always be successful in 00155 * merging the two CodeBlock instances together, however unlike all other 00156 * Merge() calls this one may return a boolean value indicating if the 00157 * merge did not have to modify anything in order to produce the union 00158 * because the two were already equivilant or will return false to 00159 * indicate that they were not equivilant and the merge was necessary. 00160 * 00161 * This information is used by the Function::Merge() in order to resolve 00162 * linking together multiple implementations of a single function. See 00163 * Function::Merge() for more information (Especially regarding Vague 00164 * Linkage of Functions). 00165 * 00166 * \return Returns true if the blocks differed and right needed to be 00167 * merged into current, or false if the two code blocks were identical 00168 * and no merge needed to take place. 00169 */ 00170 bool Merge(const CodeBlock& right); 00171 00172 //------------------------------------------------------------------------ 00173 /** \brief See DictionarySpecific::ReplaceReferences() 00174 */ 00175 virtual size_t ReplaceReferences(PStack& stack, 00176 void* remove, void* replace); 00177 00178 //------------------------------------------------------------------------ 00179 /** \brief See DictionarySpecific::Print() 00180 */ 00181 virtual std::ostream& Print(std::ostream& out, 00182 std::string prefix="") const; 00183 00184 //------------------------------------------------------------------------ 00185 /** \brief See DictionarySpecific::Validate() 00186 */ 00187 virtual void Validate(PStack& stack, const Dictionary& dict_in) const; 00188 00189 //------------------------------------------------------------------------ 00190 /** \brief Returns true if the contents of the two instances are the same. 00191 * 00192 * This treats two code blocks with the same contents but in a different 00193 * order as the equivilant. 00194 */ 00195 bool operator==(const CodeBlock& right) const; 00196 00197 //------------------------------------------------------------------------ 00198 /** \brief Returns true if the contents of the two instances differ. 00199 * 00200 * \see operator==() 00201 */ 00202 inline bool operator!=(const CodeBlock& right) const 00203 { 00204 return !(*this == right); 00205 } 00206 00207 00208 00209 00210 //------------------------------------------------------------------------ 00211 /** \brief Returns an amalgamated list of all function calls and possible 00212 * function calls. 00213 * 00214 * Note: The FunctionLoc::possible flag is set to true if this is a 00215 * "possible" function call. 00216 */ 00217 std::list<FunctionLoc> AllFunctionCalls(); 00218 00219 //------------------------------------------------------------------------ 00220 /** \brief This will populate the list of "possible_function_calls" from 00221 * this objects list of function_pointer_calls. 00222 * 00223 * A function pointer call is expanded into 0 or more possible function 00224 * calls. Basically every function whose prototype matches the function 00225 * pointer and whose address has been taken at some point in code is added 00226 * as a possible call. I.e. through the function pointer this code block 00227 * may possibly call those functions. 00228 * 00229 * A possible function call is marked as such with the 00230 * FunctionLoc::possible flag being set to true. 00231 * 00232 * Note: the expansion of calls to virtual functions into additional 00233 * possible calls is done in Function::ExpandCallGraph() not here. 00234 */ 00235 void ExpandCallGraph(Function& function); 00236 00237 //------------------------------------------------------------------------ 00238 /** \brief Adds a possible function call to the possible_function_calls 00239 * list. 00240 * 00241 * This is generally used by the ExpandCallGraph() function. 00242 */ 00243 void AddPossCall(FunctionLoc func); 00244 00245 //------------------------------------------------------------------------ 00246 /** \brief Traverses the heirarch of CodeBlock's (Through CatchBlock's 00247 * and TryBlock's) and constructs a flat file list of all CodeBlock's 00248 * within this heirarchy. 00249 * 00250 * This can be used by a function to get a list of all blocks of code 00251 * in the function regardless of the codes heirarchy. This is useful for 00252 * the user to apply suppressions across an entire function. 00253 */ 00254 std::list<CodeBlock*> GetAllCodeBlocks(); 00255 00256 //------------------------------------------------------------------------ 00257 /** \brief Returns a list of originating exceptions as pointers to the 00258 * original Exception objects so that their values can be easily modified. 00259 * 00260 * This us used by the python wrappers in order to apply suppressions 00261 * directly to originating exception objects. 00262 */ 00263 std::list<EDoc::Exception*> GetOriginatingExceptions(); 00264 00265 00266 00267 00268 //------------------------------------------------------------------------ 00269 // Public Primary Data values. 00270 //------------------------------------------------------------------------ 00271 00272 //------------------------------------------------------------------------ 00273 /** \brief A list of functions that this code block makes direct calls to. 00274 */ 00275 std::list<FunctionLoc> function_calls; 00276 00277 //------------------------------------------------------------------------ 00278 /** \brief A list of exceptions that this code block throws directly. 00279 */ 00280 std::list<Exception> originating_exceptions; 00281 00282 //------------------------------------------------------------------------ 00283 /** \brief A list of function pointer types that this code block calls. 00284 */ 00285 std::list<FunctionTypeLoc> function_pointer_calls; 00286 00287 //------------------------------------------------------------------------ 00288 /** \brief A list of try blocks that are within this code block. 00289 */ 00290 std::list<TryBlock> try_blocks; 00291 00292 00293 //------------------------------------------------------------------------ 00294 // Public Derived Data values. 00295 //------------------------------------------------------------------------ 00296 00297 //------------------------------------------------------------------------ 00298 /** \brief A list of functions that may "possibly" be called from this 00299 * code block indirectly. 00300 * 00301 * This is populated when expanding the call graph. It is expanded 00302 * based on virtual function calls and function pointer calls. 00303 */ 00304 std::list<FunctionLoc> possible_function_calls; 00305 00306 //------------------------------------------------------------------------ 00307 }; 00308 //=========================================================================== 00309 typedef CodeBlock* CodeBlockPtr; 00310 typedef std::list<CodeBlock*> CodeBlockPList; 00311 00312 } 00313 00314 #endif // EDOC_CODEBLOCK_H