00001 /* 00002 The lestes compiler suite 00003 Copyright (C) 2002, 2003, 2004, 2005 Miroslav Tichy 00004 Copyright (C) 2002, 2003, 2004, 2005 Petr Zika 00005 Copyright (C) 2002, 2003, 2004, 2005 Vojtech Hala 00006 Copyright (C) 2002, 2003, 2004, 2005 Jiri Kosina 00007 Copyright (C) 2002, 2003, 2004, 2005 Pavel Sanda 00008 Copyright (C) 2002, 2003, 2004, 2005 Jan Zouhar 00009 Copyright (C) 2002, 2003, 2004, 2005 Rudolf Thomas 00010 00011 This program is free software; you can redistribute it and/or modify 00012 it under the terms of the GNU General Public License as published by 00013 the Free Software Foundation; version 2 of the License. 00014 00015 This program is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU General Public License for more details. 00019 00020 See the full text of the GNU General Public License version 2, and 00021 the limitations in the file doc/LICENSE. 00022 00023 By accepting the license the licensee waives any and all claims 00024 against the copyright holder(s) related in whole or in part to the 00025 work, its use, and/or the inability to use it. 00026 00027 */ 00028 // needed by ss_statement, oh the horror... headers that are not self-contained 00029 #include <lestes/std/list.hh> 00030 #include <lestes/lang/cplus/sem/ss_expression.g.hh> 00031 #include <lestes/lang/cplus/sem/ss_statement.g.hh> 00032 #include <lestes/lang/cplus/sem/ss_misc.g.hh> 00033 #include <lestes/std/source_location.hh> 00034 #include <lestes/std/file_info.hh> 00035 #include <iostream> 00036 00037 package(lestes); 00038 package(lang); 00039 package(cplus); 00040 package(sem); 00041 00042 static bool hack_used = false; 00043 00044 /*! 00045 * As we currently do not have protected setters, a setter for the parent field is not provided. 00046 * However, when constructing the "global" ss_compound_stmt, which is derived from ss_statement, 00047 * the parent field has to be set to point to the instance itself, which is impossible to achieve 00048 * using the factory method. 00049 * 00050 * Therefore, this hack is provided. It exists solely for the purpose above. 00051 * Normal code MUST NOT call it, or it will explode :) 00052 */ 00053 void ss_statement::parent_set_once_hack( ptr<ss_compound_stmt> a_parent ) 00054 { 00055 lassert2( !hack_used, "This method is not meant to be called twice." ); 00056 hack_used = true; 00057 parent = a_parent; 00058 } 00059 00060 /*! 00061 * When called for the first time, constructs the grandparent of all instances 00062 * of ss_compound_stmt. This means that you can simply recognize it, just 00063 * compare your ptr to the return value of this method. 00064 * 00065 * Note that the instance is its own parent. Also note that when creating it, 00066 * root ss_decl_seq must be created too. This is achieved by calling 00067 * ss_decl_seq::root_instance(), which might in turn call us back. The code is 00068 * prepared for this. You can choose which of the two methods you call first. 00069 * 00070 * \return Pointer to the instance of root ss_compound_stmt. 00071 */ 00072 ptr<ss_compound_stmt> ss_compound_stmt::root_instance() 00073 { 00074 if (!the_root_instance) { 00075 /* this calls us recursively */ 00076 ptr < ss_decl_seq > root_decl_seq = ss_decl_seq::root_instance(); 00077 00078 /* It is somewhat complicated to tell when the control flow 00079 * reaches the following statement. 00080 * 00081 * Firstly, someone from the ``outer world'' might call 00082 * ss_decl_seq::root_instance(). Then the root instance object 00083 * of the type ss_decl_seq gets constructed and we get called 00084 * after the ss_decl_seq root object already exists. Therefore 00085 * it is safe to call ss_decl_seq::root_instance() to get that 00086 * object, because the function will return immediately with 00087 * the allready constucted, albeit incompletelly initialized 00088 * object. 00089 * 00090 * Secondly, someone from the ``outer world'' might call us in 00091 * the first place. Then We would initiate the first ever 00092 * ss_decl_seq::root_instance() call. The same applies as for 00093 * the first case. 00094 * 00095 * It is perhaps easiest to state the invariants. 00096 * \invariant If ss_decl_seq::root_instance() is called first, 00097 * then the ss_decl_seq::the_root_instance is created but not 00098 * fully initialized before ss_statement::root_instance() is 00099 * called for the first time. 00100 * \invariant The ss_decl_seq::root_instance() function will 00101 * call ss_statement::root_instance() on its first invocation 00102 * only. 00103 * 00104 * Therefore, it can be concluded, that the following statement 00105 * will be executed only after the second (and not necessarily 00106 * the first) invocation of ss_decl_seq::root_instance() has 00107 * finished. 00108 * 00109 * The only remaining question is in what state will be the 00110 * following statement encountered. The 00111 * ss_decl_seq::root_instance() will return a partially 00112 * initialized ss_decl_seq instance. If the 00113 * ss_decl_seq::root_instance() was called in the first place, 00114 * the statement will be executed only once. If, however, the 00115 * ss_statement::root_instance() was called in the first place, 00116 * then the statement will be encountered twice. The condition 00117 * will evaluate to false in the first encounter, so the 00118 * control flow will proceed to the ss_statement root instance 00119 * creation. The condition will evaluate to true on the second 00120 * encounter, because the root instance was created after the 00121 * first encounter. 00122 */ 00123 if (the_root_instance) 00124 return the_root_instance; 00125 00126 /* A non-null location is needed. We can obtain the location 00127 * from the ss_decl_seq's root instance */ 00128 ptr < source_location > loc = root_decl_seq->location_get(); 00129 /* create some sequence points */ 00130 ptr < ss_sp > psp = ss_sp::create(loc, NULL, NULL, 0), 00131 nsp = ss_sp::create(loc, NULL, NULL, 0), 00132 dsp = ss_sp::create(loc, NULL, NULL, 0); 00133 /* link them together */ 00134 psp->nsp_set(dsp); 00135 dsp->nsp_set(nsp); 00136 dsp->psp_set(psp); 00137 nsp->psp_set(dsp); 00138 the_root_instance = new ss_compound_stmt( 00139 loc, 00140 list< srp<ss_label> >::create(), NULL, psp, nsp, 00141 list< srp<ss_sp> >::create(), 00142 root_decl_seq, 00143 list< srp<ss_statement> >::create(), dsp, 00144 NORMAL 00145 ); 00146 /* insert sequence points to the list */ 00147 the_root_instance->sequence_points_get()->push_back(psp); 00148 the_root_instance->sequence_points_get()->push_back(nsp); 00149 the_root_instance->sequence_points_get()->push_back(dsp); 00150 /* See documentation for the method above... */ 00151 the_root_instance->parent_set_once_hack( the_root_instance ); 00152 /* we do not set decl_seq when calling new above, as the root decl_seq might not 00153 * be created yet. it calls us back, so we avoid recursion by setting it here 00154 */ 00155 //the_root_instance->decl_seq = ss_decl_seq::root_instance(); 00156 } 00157 return the_root_instance; 00158 } 00159 00160 end_package(sem); 00161 end_package(cplus); 00162 end_package(lang); 00163 end_package(lestes);
1.5.1-20070107