Line data Source code
1 : /*============================================================================= 2 : Boost.Wave: A Standard compliant C++ preprocessor library 3 : 4 : http://www.boost.org/ 5 : 6 : Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost 7 : Software License, Version 1.0. (See accompanying file 8 : LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 : =============================================================================*/ 10 : 11 : #if !defined(MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED) 12 : #define MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED 13 : 14 : #include <vector> 15 : #include <list> 16 : 17 : #include <boost/detail/atomic_count.hpp> 18 : #include <boost/intrusive_ptr.hpp> 19 : 20 : #include <boost/wave/wave_config.hpp> 21 : #if BOOST_WAVE_SERIALIZATION != 0 22 : #include <boost/serialization/serialization.hpp> 23 : #include <boost/serialization/list.hpp> 24 : #include <boost/serialization/vector.hpp> 25 : #endif 26 : 27 : #include <boost/wave/token_ids.hpp> 28 : 29 : // this must occur after all of the includes and before any code appears 30 : #ifdef BOOST_HAS_ABI_HEADERS 31 : #include BOOST_ABI_PREFIX 32 : #endif 33 : 34 : /////////////////////////////////////////////////////////////////////////////// 35 : namespace boost { 36 : namespace wave { 37 : namespace util { 38 : 39 : /////////////////////////////////////////////////////////////////////////////// 40 : // 41 : // macro_definition 42 : // 43 : // This class containes all infos for a defined macro. 44 : // 45 : /////////////////////////////////////////////////////////////////////////////// 46 : template <typename TokenT, typename ContainerT> 47 : struct macro_definition { 48 : 49 : typedef std::vector<TokenT> parameter_container_type; 50 : typedef ContainerT definition_container_type; 51 : 52 : typedef typename parameter_container_type::const_iterator 53 : const_parameter_iterator_t; 54 : typedef typename definition_container_type::const_iterator 55 : const_definition_iterator_t; 56 : 57 0 : macro_definition(TokenT const &token_, bool has_parameters, 58 : bool is_predefined_, long uid_) 59 : : macroname(token_), uid(uid_), is_functionlike(has_parameters), 60 : replaced_parameters(false), is_available_for_replacement(true), 61 : is_predefined(is_predefined_) 62 : #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 63 : , has_ellipsis(false) 64 : #endif 65 0 : , use_count(0) 66 : { 67 0 : } 68 : // generated copy constructor 69 : // generated destructor 70 : // generated assignment operator 71 : 72 : // Replace all occurrences of the parameters throughout the macrodefinition 73 : // with special parameter tokens to simplify later macro replacement. 74 : // Additionally mark all occurrences of the macro name itself throughout 75 : // the macro definition 76 0 : void replace_parameters() 77 : { 78 : using namespace boost::wave; 79 : 80 0 : if (!replaced_parameters) { 81 0 : typename definition_container_type::iterator end = macrodefinition.end(); 82 0 : typename definition_container_type::iterator it = macrodefinition.begin(); 83 : 84 0 : for (/**/; it != end; ++it) { 85 0 : token_id id = *it; 86 : 87 0 : if (T_IDENTIFIER == id || 88 0 : IS_CATEGORY(id, KeywordTokenType) || 89 0 : IS_EXTCATEGORY(id, OperatorTokenType|AltExtTokenType) || 90 : IS_CATEGORY(id, OperatorTokenType)) 91 : { 92 : // may be a parameter to replace 93 0 : const_parameter_iterator_t cend = macroparameters.end(); 94 0 : const_parameter_iterator_t cit = macroparameters.begin(); 95 0 : for (typename parameter_container_type::size_type i = 0; 96 0 : cit != cend; ++cit, ++i) 97 : { 98 0 : if ((*it).get_value() == (*cit).get_value()) { 99 0 : (*it).set_token_id(token_id(T_PARAMETERBASE+i)); 100 : break; 101 : } 102 : #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 103 0 : else if (T_ELLIPSIS == token_id(*cit) && 104 0 : "__VA_ARGS__" == (*it).get_value()) 105 : { 106 : // __VA_ARGS__ requires special handling 107 0 : (*it).set_token_id(token_id(T_EXTPARAMETERBASE+i)); 108 : break; 109 : } 110 : #endif 111 : } 112 : } 113 : } 114 : 115 : #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 116 : // we need to know, if the last of the formal arguments is an ellipsis 117 0 : if (macroparameters.size() > 0 && 118 0 : T_ELLIPSIS == token_id(macroparameters.back())) 119 : { 120 0 : has_ellipsis = true; 121 : } 122 : #endif 123 0 : replaced_parameters = true; // do it only once 124 : } 125 0 : } 126 : 127 : TokenT macroname; // macro name 128 : parameter_container_type macroparameters; // formal parameters 129 : definition_container_type macrodefinition; // macro definition token sequence 130 : long uid; // unique id of this macro 131 : bool is_functionlike; 132 : bool replaced_parameters; 133 : bool is_available_for_replacement; 134 : bool is_predefined; 135 : #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 136 : bool has_ellipsis; 137 : #endif 138 : boost::detail::atomic_count use_count; 139 : 140 : #if BOOST_WAVE_SERIALIZATION != 0 141 : // default constructor is needed for serialization only 142 : macro_definition() 143 : : uid(0), is_functionlike(false), replaced_parameters(false), 144 : is_available_for_replacement(false), is_predefined(false) 145 : #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 146 : , has_ellipsis(false) 147 : #endif 148 : , use_count(0) 149 : {} 150 : 151 : private: 152 : friend class boost::serialization::access; 153 : template<typename Archive> 154 : void serialize(Archive &ar, const unsigned int version) 155 : { 156 : using namespace boost::serialization; 157 : ar & make_nvp("name", macroname); 158 : ar & make_nvp("parameters", macroparameters); 159 : ar & make_nvp("definition", macrodefinition); 160 : ar & make_nvp("uid", uid); 161 : ar & make_nvp("is_functionlike", is_functionlike); 162 : ar & make_nvp("has_replaced_parameters", replaced_parameters); 163 : ar & make_nvp("is_available_for_replacement", is_available_for_replacement); 164 : ar & make_nvp("is_predefined", is_predefined); 165 : #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 166 : ar & make_nvp("has_ellipsis", has_ellipsis); 167 : #endif 168 : } 169 : #endif 170 : }; 171 : 172 : #if BOOST_WAVE_SERIALIZATION == 0 173 : /////////////////////////////////////////////////////////////////////////////// 174 : template <typename TokenT, typename ContainerT> 175 : inline void 176 0 : intrusive_ptr_add_ref(macro_definition<TokenT, ContainerT>* p) 177 : { 178 0 : ++p->use_count; 179 : } 180 : 181 : template <typename TokenT, typename ContainerT> 182 : inline void 183 0 : intrusive_ptr_release(macro_definition<TokenT, ContainerT>* p) 184 : { 185 0 : if (--p->use_count == 0) 186 0 : delete p; 187 0 : } 188 : #endif 189 : 190 : /////////////////////////////////////////////////////////////////////////////// 191 : } // namespace util 192 : } // namespace wave 193 : } // namespace boost 194 : 195 : // the suffix header occurs after all of the code 196 : #ifdef BOOST_HAS_ABI_HEADERS 197 : #include BOOST_ABI_SUFFIX 198 : #endif 199 : 200 : #endif // !defined(MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED)