// This file is part of PUMA. // Copyright (C) 1999-2003 The PUMA developer team. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of // the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public // License along with this program; if not, write to the Free // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, // MA 02111-1307 USA #ifndef __ext_gnu_keywords_h__ #define __ext_gnu_keywords_h__ #include "Puma/Config.h" #include "Puma/CLexer.h" #include "Puma/CCLexer.h" #include aspect ExtGnuKeywords { static const unsigned int _config_mask_type_traits = 2; static const unsigned int _config_mask_pic24 = 16; static const unsigned int _config_mask_local_labels = 32; static const unsigned int _config_mask_int128 = 64; advice "Puma::CScanner" : slice class { bool _config_type_traits; bool _config_pic24; bool _config_local_labels; bool _config_int128; }; advice construction("Puma::CScanner") : after () { tjp->that ()->_config_type_traits = false; tjp->that ()->_config_pic24 = false; tjp->that ()->_config_local_labels = false; tjp->that ()->_config_int128 = false; } advice args (config) && execution("void Puma::CScanner::configure (...)"): after (const Puma::Config &config) { tjp->that ()->_config_type_traits = config.Option ("--builtin-type-traits"); tjp->that ()->_config_pic24 = config.Option ("--gnu-pic24"); tjp->that ()->_config_int128 = config.Option ("--gnu-int128"); int gnu_major, gnu_minor, gnu_patchlevel; // call get_gnu_version to check whether --gnu was given if (get_gnu_version (config, gnu_major, gnu_minor, gnu_patchlevel)) { // enabled by default tjp->that ()->_config_local_labels = true; #if defined(__SIZEOF_INT128__) // enabled by default if target supports it tjp->that ()->_config_int128 = true; #endif if (gnu_major == -1 || (gnu_major > 4) || (gnu_major == 4 && gnu_minor >= 3)) { // set the builtin type traits option (implemented by g++ >= 4.3) tjp->that ()->_config_type_traits = true; } } } advice call ("% Puma::CLexer::instance(...)" || "% Puma::CCLexer::instance(...)") && within ("Puma::CScanner"): before () { if (tjp->that ()->_config_type_traits) *tjp->arg<0>() |= _config_mask_type_traits; if (tjp->that ()->_config_pic24) *tjp->arg<0>() |= _config_mask_pic24; if (tjp->that ()->_config_local_labels) *tjp->arg<0>() |= _config_mask_local_labels; if (tjp->that ()->_config_int128) *tjp->arg<0>() |= _config_mask_int128; } advice execution ("% Puma::CCLexer::add_keywords(...)") : after () { if (tjp->that ()->_config_mask & _config_mask_type_traits) { lexertl::rules &rules = *tjp->arg<0>(); // C++ type trait operators rules.push ("__has_nothrow_assign", Puma::TOK_HAS_NOTHROW_ASSIGN, LID(Puma::Token::keyword_id)); rules.push ("__has_nothrow_copy", Puma::TOK_HAS_NOTHROW_COPY, LID(Puma::Token::keyword_id)); rules.push ("__has_nothrow_constructor", Puma::TOK_HAS_NOTHROW_CTOR, LID(Puma::Token::keyword_id)); rules.push ("__has_trivial_assign", Puma::TOK_HAS_TRIVIAL_ASSIGN, LID(Puma::Token::keyword_id)); rules.push ("__has_trivial_copy", Puma::TOK_HAS_TRIVIAL_COPY, LID(Puma::Token::keyword_id)); rules.push ("__has_trivial_constructor", Puma::TOK_HAS_TRIVIAL_CTOR, LID(Puma::Token::keyword_id)); rules.push ("__has_trivial_destructor", Puma::TOK_HAS_TRIVIAL_DTOR, LID(Puma::Token::keyword_id)); rules.push ("__has_virtual_destructor", Puma::TOK_HAS_VIRTUAL_DTOR, LID(Puma::Token::keyword_id)); rules.push ("__is_abstract", Puma::TOK_IS_ABSTRACT, LID(Puma::Token::keyword_id)); rules.push ("__is_base_of", Puma::TOK_IS_BASE_OF, LID(Puma::Token::keyword_id)); rules.push ("__is_class", Puma::TOK_IS_CLASS, LID(Puma::Token::keyword_id)); rules.push ("__is_empty", Puma::TOK_IS_EMPTY, LID(Puma::Token::keyword_id)); rules.push ("__is_enum", Puma::TOK_IS_ENUM, LID(Puma::Token::keyword_id)); rules.push ("__is_pod", Puma::TOK_IS_POD, LID(Puma::Token::keyword_id)); rules.push ("__is_trivial", Puma::TOK_IS_TRIVIAL, LID(Puma::Token::keyword_id)); rules.push ("__is_polymorphic", Puma::TOK_IS_POLYMORPHIC, LID(Puma::Token::keyword_id)); rules.push ("__is_union", Puma::TOK_IS_UNION, LID(Puma::Token::keyword_id)); } } advice execution ("% Puma::CLexer::add_c89_keywords(...)") : after () { lexertl::rules &rules = *tjp->arg<0>(); // C compatibility keywords rules.push ("__asm", Puma::TOK_ASM_2, LID(Puma::Token::keyword_id)); rules.push ("__asm__", Puma::TOK_ASM_3, LID(Puma::Token::keyword_id)); rules.push ("__const", Puma::TOK_CONST_2, LID(Puma::Token::keyword_id)); rules.push ("__const__", Puma::TOK_CONST_3, LID(Puma::Token::keyword_id)); rules.push ("__inline", Puma::TOK_INLINE_2, LID(Puma::Token::keyword_id)); rules.push ("__inline__", Puma::TOK_INLINE_3, LID(Puma::Token::keyword_id)); rules.push ("__signed", Puma::TOK_SIGNED_2, LID(Puma::Token::keyword_id)); rules.push ("__signed__", Puma::TOK_SIGNED_3, LID(Puma::Token::keyword_id)); rules.push ("__volatile", Puma::TOK_VOLATILE_2, LID(Puma::Token::keyword_id)); rules.push ("__volatile__", Puma::TOK_VOLATILE_3, LID(Puma::Token::keyword_id)); rules.push ("__wchar_t", Puma::TOK_WCHAR_T_2, LID(Puma::Token::keyword_id)); rules.push ("__thread", Puma::TOK_THREAD, LID(Puma::Token::keyword_id)); rules.push ("typeof", Puma::TOK_TYPEOF, LID(Puma::Token::keyword_id)); rules.push ("__typeof", Puma::TOK_TYPEOF_2, LID(Puma::Token::keyword_id)); rules.push ("__typeof__", Puma::TOK_TYPEOF_3, LID(Puma::Token::keyword_id)); rules.push ("__decltype", Puma::TOK_TYPEOF_4, LID(Puma::Token::keyword_id)); rules.push ("__alignof", Puma::TOK_ALIGNOF_2, LID(Puma::Token::keyword_id)); rules.push ("__alignof__", Puma::TOK_ALIGNOF_3, LID(Puma::Token::keyword_id)); rules.push ("__builtin_offsetof", Puma::TOK_OFFSETOF, LID(Puma::Token::keyword_id)); rules.push ("__attribute__", Puma::TOK_ATTRIBUTE, LID(Puma::Token::keyword_id)); rules.push ("__extension__", Puma::TOK_EXTENSION, LID(Puma::Token::keyword_id)); rules.push ("__restrict", Puma::TOK_RESTRICT_2, LID(Puma::Token::keyword_id)); rules.push ("__restrict__", Puma::TOK_RESTRICT_3, LID(Puma::Token::keyword_id)); // PIC24/dsPIC CV-qualifiers if (tjp->that ()->_config_mask & _config_mask_pic24) { rules.push ("__psv__", Puma::TOK_PSV, LID(Puma::Token::keyword_id)); rules.push ("__pmp__", Puma::TOK_PMP, LID(Puma::Token::keyword_id)); rules.push ("__external__", Puma::TOK_EXTERNAL, LID(Puma::Token::keyword_id)); } // Local labels if (tjp->that ()->_config_mask & _config_mask_local_labels) { rules.push ("__label__", Puma::TOK_LABEL, LID(Puma::Token::keyword_id)); } // 128-bit integer type if (tjp->that ()->_config_mask & _config_mask_int128) { rules.push ("__int128", Puma::TOK_INT128, LID(Puma::Token::keyword_id)); } } // ---------------------------------------------------- // get the configuration and check whether the GNU mode is enabled // ---------------------------------------------------- bool get_gnu_version (const Puma::Config &config, int &major, int &minor, int &patchlevel) { const Puma::ConfOption *gnu_option = config.Option ("--gnu"); if (!gnu_option) return false; major = -1; minor = -1; patchlevel = -1; const char *gnu_version_str = (gnu_option->Arguments() == 1) ? gnu_option->Argument (0) : 0; if (gnu_version_str) { char sep; std::istringstream in (gnu_version_str); if (in.good()) in >> major; if (in.good()) in >> sep >> minor; if (in.good()) in >> sep >> patchlevel; } return true; } }; #endif /* __ext_gnu_keywords_h__ */