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 /*! \file 00029 \brief Storage of defined macros. 00030 00031 Definition of macro_storage class representing defined macros. 00032 \author pt 00033 */ 00034 #include <lestes/common.hh> 00035 #include <lestes/equality.hh> 00036 #include <lestes/lang/cplus/lex/macro_storage.hh> 00037 #include <lestes/lang/cplus/lex/macro_storage.m.hh> 00038 #include <lestes/lang/cplus/lex/macro.hh> 00039 #include <lestes/lang/cplus/lex/pp_token.hh> 00040 #include <lestes/lang/cplus/lex/token_value.hh> 00041 #include <lestes/std/map.hh> 00042 00043 package(lestes); 00044 package(lang); 00045 package(cplus); 00046 package(lex); 00047 00048 using namespace ::std; 00049 00050 /*! 00051 Constructs empty object. 00052 */ 00053 macro_storage::macro_storage(void): 00054 storage(storage_type::create()) 00055 { 00056 // TODO pt add predefined 00057 } 00058 00059 /*! 00060 Defines new macro, checks for redefinition. 00061 \pre a_macro != NULL 00062 \param a_macro The macro to be defined. 00063 */ 00064 void macro_storage::define(const ptr<macro> &a_macro) 00065 { 00066 lassert(a_macro); 00067 00068 ptr<token_value> name = a_macro->name_get(); 00069 00070 storage_type::iterator it = storage->find(name); 00071 if (it == storage->end()) { 00072 storage->insert(make_pair(name,a_macro)); 00073 return; 00074 } 00075 00076 ptr<macro> orig = (*it).second; 00077 if (orig->predefined_get()) { 00078 // redefinition of predefined internal macro 00079 report << predefined_macro_redefined << name->content_get() << a_macro->location_get(); 00080 return; 00081 } 00082 00083 // redefinition is equivalent, do nothing 00084 if (is_equal(a_macro,orig)) return; 00085 00086 // macro redefinition is different 00087 report << macro_redefinition_different << name->content_get() << a_macro->location_get(); 00088 // this is the location of the previous definition 00089 report << previous_definition << orig->location_get(); 00090 } 00091 00092 00093 /*! 00094 Undefines macro, checks whether was defined. 00095 \pre tok != NULL 00096 \param tok The token with name of macro to undefine. 00097 */ 00098 void macro_storage::undef(const ptr<pp_token> &tok) 00099 { 00100 lassert(tok); 00101 00102 if (!tok->is_name()) { 00103 // expected name of macro to undefine 00104 report << expected_macro_name << tok->location_get(); 00105 return; 00106 } 00107 00108 ptr<token_value> name = tok->value_get(); 00109 00110 storage_type::iterator it = storage->find(name); 00111 if (it == storage->end()) return; 00112 00113 ptr<macro> m = (*it).second; 00114 00115 if (m->predefined_get()) { 00116 // undefining predefined macro 00117 report << predefined_macro_undefined << name->content_get() << tok->location_get(); 00118 return; 00119 } 00120 00121 storage->erase(it); 00122 } 00123 00124 /*! 00125 Tests whether macro of the given name is currently defined. 00126 \pre tok != NULL 00127 \param tok The token containing macro name to test. 00128 \return true If the macro of this name is defined. 00129 */ 00130 bool macro_storage::defined(const ptr<pp_token> &tok) 00131 { 00132 lassert(tok); 00133 00134 if (!tok->is_name()) { 00135 // expected name of macro 00136 report << expected_macro_name << tok->location_get(); 00137 // such macro is not defined 00138 return false; 00139 } 00140 00141 ptr<token_value> name = tok->value_get(); 00142 00143 return storage->find(name) != storage->end(); 00144 } 00145 00146 /*! 00147 Searches for macro of given name. 00148 \todo pt return special values for __LINE__ etc 00149 \pre name != NULL 00150 \param name The name of the searched macro. 00151 \return The macro of the given name, or NULL if such macro is not defined. 00152 */ 00153 ptr<macro> macro_storage::lookup(const ptr<token_value> &name) 00154 { 00155 lassert(name); 00156 00157 // TODO check special names (__LINE__) etc 00158 storage_type::iterator it = storage->find(name); 00159 if (it == storage->end()) return NULL; 00160 return (*it).second; 00161 } 00162 00163 /*! 00164 Marks the object. 00165 */ 00166 void macro_storage::gc_mark(void) 00167 { 00168 storage.gc_mark(); 00169 ::lestes::std::object::gc_mark(); 00170 } 00171 00172 /*! 00173 Returns new instance of the class. 00174 \return The new storage. 00175 */ 00176 ptr<macro_storage> macro_storage::create(void) 00177 { 00178 return new macro_storage(); 00179 } 00180 00181 end_package(lex); 00182 end_package(cplus); 00183 end_package(lang); 00184 end_package(lestes); 00185 /* vim: set ft=lestes : */
1.5.1-20070107