/*============================================================================= Boost.Wave: A Standard compliant C++ preprocessor library http://www.boost.org/ Copyright (c) 2001-2007 Hartmut Kaiser. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #if !defined(MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED) #define MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED #include #include #include #if BOOST_WAVE_SERIALIZATION != 0 #include #include #include #endif #include // this must occur after all of the includes and before any code appears #ifdef BOOST_HAS_ABI_HEADERS #include BOOST_ABI_PREFIX #endif /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace wave { namespace util { /////////////////////////////////////////////////////////////////////////////// // // macro_definition // // This class containes all infos for a defined macro. // /////////////////////////////////////////////////////////////////////////////// template struct macro_definition { typedef std::vector parameter_container_type; typedef ContainerT definition_container_type; typedef typename parameter_container_type::const_iterator const_parameter_iterator_t; typedef typename definition_container_type::const_iterator const_definition_iterator_t; macro_definition(TokenT const &token_, bool has_parameters, bool is_predefined_, long uid_) : macroname(token_), uid(uid_), is_functionlike(has_parameters), replaced_parameters(false), is_available_for_replacement(true), is_predefined(is_predefined_) #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 , has_ellipsis(false) #endif { } // generated copy constructor // generated destructor // generated assignment operator // Replace all occurrences of the parameters throughout the macrodefinition // with special parameter tokens to simplify later macro replacement. // Additionally mark all occurrences of the macro name itself throughout // the macro definition void replace_parameters() { using namespace boost::wave; if (!replaced_parameters) { typename definition_container_type::iterator end = macrodefinition.end(); typename definition_container_type::iterator it = macrodefinition.begin(); for (/**/; it != end; ++it) { token_id id = *it; if (T_IDENTIFIER == id || IS_CATEGORY(id, KeywordTokenType) || IS_EXTCATEGORY(id, OperatorTokenType|AltExtTokenType) || IS_CATEGORY(id, OperatorTokenType)) { // may be a parameter to replace const_parameter_iterator_t cend = macroparameters.end(); const_parameter_iterator_t cit = macroparameters.begin(); for (typename parameter_container_type::size_type i = 0; cit != cend; ++cit, ++i) { if ((*it).get_value() == (*cit).get_value()) { (*it).set_token_id(token_id(T_PARAMETERBASE+i)); break; } #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 else if (T_ELLIPSIS == token_id(*cit) && "__VA_ARGS__" == (*it).get_value()) { // __VA_ARGS__ requires special handling (*it).set_token_id(token_id(T_EXTPARAMETERBASE+i)); break; } #endif } } } #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 // we need to know, if the last of the formal arguments is an ellipsis if (macroparameters.size() > 0 && T_ELLIPSIS == token_id(macroparameters.back())) { has_ellipsis = true; } #endif replaced_parameters = true; // do it only once } } TokenT macroname; // macro name parameter_container_type macroparameters; // formal parameters definition_container_type macrodefinition; // macro definition token sequence long uid; // unique id of this macro bool is_functionlike; bool replaced_parameters; bool is_available_for_replacement; bool is_predefined; #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 bool has_ellipsis; #endif #if BOOST_WAVE_SERIALIZATION != 0 // default constructor is needed for serialization only macro_definition() : uid(0), is_functionlike(false), replaced_parameters(false), is_available_for_replacement(false), is_predefined(false) #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 , has_ellipsis(false) #endif {} private: friend class boost::serialization::access; template void serialize(Archive &ar, const unsigned int version) { ar & macroname; ar & macroparameters; ar & macrodefinition; ar & uid; ar & is_functionlike; ar & replaced_parameters; ar & is_available_for_replacement; ar & is_predefined; #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 ar & has_ellipsis; #endif } #endif }; /////////////////////////////////////////////////////////////////////////////// } // namespace util } // namespace wave } // namespace boost // the suffix header occurs after all of the code #ifdef BOOST_HAS_ABI_HEADERS #include BOOST_ABI_SUFFIX #endif #endif // !defined(MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED)