#ifdef WIN32 #pragma warning(disable: 4786) // Stop warnings about truncated identifiers in debug info #endif #include #include "parser.h" #include "parser2.h" #include "../utils/debug.h" namespace parser { #ifdef CMM_MULTIMETHODS void output_node_( static const parser::node_t& node, static parser::outstream_t& out) /* We define default implementation, which can be overridden at runtime. */ { debug0 << debug_PLACE << "output_node_, " << "out is address " << &out << ", type is " << typeid( out).name() << ", node type is " << typeid( node).name() << "\n"; node.output( out); } #else void output_node( const parser::node_t& node, parser::outstream_t& out) { assert( &node); node.output( out); } #endif void simplenode_t::output( outstream_t& out) const { if ( !this->begin || !this->end) { debug0 << typeid( *this).name() << "\n"; } /*debug0 << "Outputing node type " << typeid( *this).name() << ", begin=" << ((void*)begin) << ", end=" << ((void*)end) << "(len=" << end-begin << ")" << ", extra = " << this->extra << "out.output_main=" << out.output_main << "out.output_extra=" << out.output_extra << "out.output_space=" << out.output_space << "\n";*/ assert( this->begin); assert( this->end); const char* c; if ( out.output_main) { for ( c=begin; c!=end; ++c) out.out << *c; } else { c=end; } for ( ; *c && isspace( *c); ++c) { if ( out.output_space) { out.out << *c; } } if ( out.output_extra && extra) { assert( extra->begin >= this->end); scoped_change_t output_main( out.output_main, true); output_node( *extra, out); } else { } } void simplenode_t::output_tech( outstream_t& out) const { out.out << "simplenode_t:["; output_node( *this, out); out.out << "]"; } bool simplenode_t::equal( const node_t& rhs0) const { // just do a plain string comparison. const simplenode_t& rhs = static_cast< const simplenode_t&>( rhs0); bool ret = (rhs.end-rhs.begin==end-begin) && 0==strncmp( begin, rhs.begin, end-begin); return ret; } bool endoffile_t::equal( const node_t& /*rhs*/) { return true; // All instances of endoffile_t are identical. } bool hash_line_t::equal( const node_t& rhs0) { const hash_line_t& rhs = static_cast< const hash_line_t&>( rhs0); return linenumber==rhs.linenumber && filename==rhs.filename; } void string_t::OutputContents( outstream_t& out) const /* Outputs contents with escape characters expanded and no enclosing quotes. doesn't handle octal stuff etc. */ { for ( const char* c=this->begin+1; cend-1; ++c) { if ( c[0]=='\\' && c+1end-1) // trailing '\' is output verbatim - probably wrong... { ++c; if ( 0) ; else if ( *c=='0') out.out << '\0'; else if ( *c=='a') out.out << '\a'; else if ( *c=='b') out.out << '\b'; else if ( *c=='f') out.out << '\f'; else if ( *c=='n') out.out << '\n'; else if ( *c=='r') out.out << '\r'; else if ( *c=='t') out.out << '\t'; else if ( *c=='v') out.out << '\v'; else out.out << *c; } else out.out << c[0]; } } std::string string_t::GetContents() const { std::stringstream temp; outstream_t temp2( temp); this->OutputContents( temp2); return temp.str(); } node_t* logical_namespace_t::GetParentElement( int i) const { assert( i>=0); if ( i==0) return this->leafname; else if ( parent==NULL) return NULL; else return parent->GetParentElement( i-1); } void logical_namespace_t::append_item( node_t* item) { this->items.push_back( item); } void logical_namespace_t::output_complete( outstream_t& out) const { if ( this->parent) { this->parent->output_complete( out); out.out << "::"; } if ( this->leafname) out << *this->leafname; } void namespace_t::append_item( node_t* item) { this->items.push_back( item); } bool namespace_t::equal( const node_t& /*rhs*/) const { throw std::logic_error( "namespace_t::equal not implemented"); } void namespace_t::output( outstream_t& out) const { output_node( *namespac, out); if ( leafname) output_node( *leafname, out); output_node( *opencurly, out); for ( unsigned int i=0; iexter, out); output_node( *this->linkagename, out); if ( opencurly) output_node( *this->opencurly, out); for ( unsigned int i=0; iitems.size(); ++i) output_node( *this->items[i], out); if ( closecurly) output_node( *this->closecurly, out); } void template_specialisation_item_type_t::output( outstream_t& out) const { //if ( this->stati) output_node( *this->stati, out); output_node( *this->declnames, out); if ( this->terminating_comma) output_node( *this->terminating_comma, out); } void template_specialisation_item_expression_t::output( outstream_t& out) const { output_node( *this->expression, out); if ( this->terminating_comma) output_node( *this->terminating_comma, out); } void template_specialisation_t::output( outstream_t& out) const { assert( this->lt); assert( this->gt); output_node( *lt, out); { /* turn off any output decllefts inside the <...> - otherwise we can get declaratorlefts output twice. */ scoped_change_t exclude_declleft( out.include_declleft, false); for ( unsigned int i=0; iitems[i]); output_node( *items[i], out); } } output_node( *gt, out); } void template_specialisation_t::output_tech( outstream_t& out) const { out.out << "template_specialisation_t:" << this->items.size() << ":["; for ( unsigned int i=0; ioutput_tech( out); out.out << ", "; } out.out << "]"; } void templatesingle_itemclasstypename_t::output( outstream_t& out) const { output_node( *this->class_or_typename, out); output_node( *this->identifier, out); if ( this->comma) output_node( *this->comma, out); } void templatesingle_itemother_t::output( outstream_t& out) const { if ( this->class_or_typename) output_node( *this->class_or_typename, out); output_node( *this->declnames, out); } void template_single_t::output( outstream_t& out) const { assert( this->templat); assert( this->lt); assert( this->gt); output_node( *this->templat, out); output_node( *this->lt, out); for ( int i=0; i<(int)this->items.size(); ++i) { assert( this->items[i]); output_node( *this->items[i], out); } output_node( *this->gt, out); } void template_t::output( outstream_t& out) const { for ( unsigned int i=0; i( rhs0); if ( items.size() != rhs.items.size()) { return false; } for ( unsigned int i=0; i( rhs0); return this->items.equal( rhs.items); } void assembler_block_t::output( outstream_t& out) const { output_node( *this->as, out); output_node( *this->items, out); output_node( *this->semicolon, out); } bool assembler_block_t::equal( const node_t& rhs0) const { const assembler_block_t& rhs = static_cast< const assembler_block_t&>( rhs0); return this->items->equal( *rhs.items); } void name_element_t::output_tech( outstream_t& out) const { out.out << "name_element_t:" << typeid( *this).name() << ":["; if ( this->templatespec) { out.out << "tempaltespec="; this->templatespec->output_tech( out); } out.out << "]"; } bool name_element_t::equal( const node_t& rhs0) const { const name_element_t& rhs = static_cast< const name_element_t&>( rhs0); if ( coloncolon==NULL && rhs.coloncolon!=NULL) return false; if ( coloncolon!=NULL && rhs.coloncolon==NULL) return false; if ( !coloncolon && !rhs.coloncolon) return true; return ( *coloncolon == *rhs.coloncolon); } void name_element_member_ptr_t::output( outstream_t& out) const { if ( coloncolon) output_node( *coloncolon, out); output_node( *star, out); if ( templatespec) output_node( *templatespec, out); } void name_element_destructor_t::output( outstream_t& out) const { if ( coloncolon) output_node( *coloncolon, out); output_node( *tilde, out); output_node( *name, out); if ( templatespec) output_node( *templatespec, out); } void name_element_operator_t::output( outstream_t& out) const { if ( coloncolon) output_node( *coloncolon, out); output_node( *operatio, out); output_node( *operation, out); if ( templatespec) output_node( *templatespec, out); } bool name_element_operator_t::equal( const node_t& rhs0) const { const name_element_operator_t& rhs = static_cast< const name_element_operator_t&>( rhs0); if ( !this->name_element_t::equal( rhs)) return false; return ( *operatio == *rhs.operatio) && ( *operation==*rhs.operation); } void nameelement_template_t::output( outstream_t& out) const { if ( coloncolon) output_node( *coloncolon, out); output_node( *templat, out); } void name_element_normal_t::output( outstream_t& out) const { if ( coloncolon) output_node( *coloncolon, out); output_node( *identifier, out); if ( templatespec) output_node( *templatespec, out); } bool name_element_normal_t::equal( const node_t& rhs0) const { const name_element_normal_t& rhs = static_cast< const name_element_normal_t&>( rhs0); bool ret = (*identifier==*rhs.identifier); return ret; } name_t* name_t::MakeName( const char* text0, context_t& context) { std::string* text = new std::string( text0); lexer_t lexer( "", text->c_str(), false, false, false); return get_name( lexer, context); } name_t* name_t::MakeName( identifier_t& identifier, context_t& context) { std::string* text = new std::string( identifier.begin, identifier.end); lexer_t lexer( "", text->c_str(), false, false, false); return get_name( lexer, context); } void name_t::output_tech( outstream_t& out) const { out.out << "name_t:["; for ( unsigned int i=0; ioutput_tech( out); out.out << ","; } out.out << "]"; } void name_t::output( outstream_t& out) const { for ( unsigned int i=0; inamespac) { this->namespac->output_complete( out); out.out << "::"; } output_node( *this, out); } node_t* name_t::GetElement( unsigned int i) const { assert( i>0); if ( ielements.size()) { name_element_normal_t* element = dynamic_cast< name_element_normal_t*>( this->elements[ this->elements.size()-i-1]); assert( element); return element->identifier; } else if ( this->namespac) return this->namespac->GetParentElement( i-this->elements.size()); else return NULL; } bool name_t::equal( const node_t& rhs0) const { // we include the namespace in the comparison. const name_t& rhs = static_cast< const name_t&>( rhs0); if ( *this->elements.back() != *rhs.elements.back()) return false; return NamespacesEq( *this, rhs); } void namespace_eq_t::output( outstream_t& out) const { output_node( *namespac, out); output_node( *name, out); output_node( *eq, out); output_node( *namespacerhs, out); output_node( *semicolon, out); } void enum_t::output( outstream_t& out) const { output_node( *enu, out); if ( identifier) output_node( *identifier, out); output_node( *block, out); output_node( *semicolon, out); } void union_t::output( outstream_t& out) const { output_node( *unio, out); if ( identifier) output_node( *identifier, out); output_node( *block, out); output_node( *semicolon, out); } void using_t::output( outstream_t& out) const { output_node( *usin, out); if ( namespac) output_node( *namespac, out); output_node( *name, out); output_node( *semicolon, out); } void modifiers_t::output( outstream_t& out) const { for ( items_t::const_iterator it=items.begin(); it!=items.end(); ++it) output_node( *(*it), out); } void modifiers_t::OutputLeftSide( outstream_t& out, const char* pos) const { if ( pos==NULL) { std::cerr << "pos==NULL\n"; } assert( pos!=NULL); for ( items_t::const_iterator it=items.begin(); it!=items.end(); ++it) { if ( (*it)->begin > pos) break; output_node( *(*it), out); } } void modifiers_t::OutputRightSide( outstream_t& out, const char* pos) const { assert( pos!=NULL); for ( items_t::const_iterator it=items.begin(); it!=items.end(); ++it) { if ( (*it)->begin < pos) continue; output_node( *(*it), out); } } void modifiers_t::output_tech( outstream_t& out) const { out.out << "modifiers:["; output_node( *this, out); out.out << "]"; } bool modifiers_t::equal( const node_t& rhs0) const { const modifiers_t& rhs = static_cast< const modifiers_t&>( rhs0); //std::cerr << "Comparing modifiers: `" << *this << "' and `" << rhs << "'\n"; if ( items.size() != rhs.items.size()) { //std::cerr << "different num, so false\n"; return false; } for ( items_t::const_iterator it=items.begin(); it!=items.end(); ++it) { // Could use std::find(... std::bind2nd), but it all gets rather messy... items_t::const_iterator rhsit; for ( rhsit=rhs.items.begin(); rhsit!=rhs.items.end(); ++rhsit) { if ( **it == **rhsit) break; } if ( rhsit==rhs.items.end()) { //std::cerr << "couldn't find `" << *it << "', so false\n"; return false; } } //std::cerr << "returning true\n"; return true; } void internal_t::output( outstream_t& out) const { output_node( *identifier, out); output_node( extra0, out); if ( extra) output_node( *extra, out); } void declarator_t::output( outstream_t& out) const { this->output_left( out); this->output_right( out); } void declarator_t::output_left( outstream_t& out) const { if ( leading_internal) output_node( *leading_internal, out); if ( subtype) subtype->output_left( out); } void declarator_t::output_right( outstream_t& out) const { //debug0 << "declarator_t::output_right: trailing_internal=" << trailing_internal << "\n"; if ( subtype) subtype->output_right( out); if ( trailing_internal) output_node( *trailing_internal, out); } bool declarator_t::equal( const node_t& rhs0) const { const declarator_t& rhs = static_cast< const declarator_t&>( rhs0); if ( subtype==NULL && rhs.subtype==NULL) return true; if ( subtype==NULL || rhs.subtype==NULL) return false; return *subtype == *rhs.subtype; } void declarator_t::output_anonymous( outstream_t& out) { output_left( out); output_right( out); } void declarator_t::output_complete( outstream_t& out) const { scoped_change_t include_declleft( out.include_declleft, true); output_left( out); output_right( out); } std::string declarator_t::output_complete_tostring() const { std::stringstream buffer; outstream_t out( buffer); this->output_complete( out); return buffer.str(); } void struct_name_t::output( outstream_t& out) const { output_node( *struc, out); if ( name) output_node( *name, out); if ( block) output_node( *block, out); } bool struct_name_t::equal( const node_t& rhs0) const { const struct_name_t& rhs = static_cast< const struct_name_t&>( rhs0); return *this->name==*rhs.name && *this->block==*rhs.block; } void label_t::output( outstream_t& out) const { assert( this->identifier); assert( this->colon); output_node( *this->identifier, out); output_node( *this->colon, out); } void declarator_left_t::output_left( outstream_t& out) const { if ( out.include_declleft) OutputLeft2( out); } void declarator_left_t::OutputLeft2NoTrailingSpace( outstream_t& out) const { parser::scoped_change_t< bool> output_space( out.output_space, false); scoped_change_t< bool> output_extra( out.output_extra, false); this->OutputLeft2( out); } void declarator_left_t::OutputLeft2( outstream_t& out) const { if ( leading_internal) output_node( *leading_internal, out); if ( modifiers) { if ( name) { if ( !name->begin) { std::cerr << "name->begin=NULL, typeid=" << typeid( *name).name() << ": " << *name << "\n"; } modifiers->OutputLeftSide( out, name->begin); } else { output_node( *modifiers, out); } } if ( typenam) output_node( *typenam, out); if ( name) output_node( *name, out); if ( name && modifiers) modifiers->OutputRightSide( out, name->begin); //if ( trailing_internal) output_node( *trailing_internal, out); // this is done by declarator_t::output_right(). if ( this->is_from_radical_alternative_syntax) out.out << " "; // `x: int;' gets translated to `intx;' otherwise. } void declarator_left_t::output_tech( outstream_t& out) const { out.out << "name:"; if ( name) name->output_tech( out); out.out << "], mods:["; if ( modifiers) modifiers->output_tech( out); out.out << "]"; } bool declarator_left_t::equal( const node_t& rhs0) const { const declarator_left_t& rhs = static_cast< const declarator_left_t&>( rhs0); if ( (name==NULL) != (rhs.name==NULL)) return false; return (( name==NULL) || ( *name == *rhs.name)) && *modifiers == *rhs.modifiers && declarator_t::equal( rhs); } declarator_left_t* declarator_left_t::get_declarator_left() { /*debug << debug_PLACE << "declarator_left_t::get_declarator_left(): returning " << this << "\n";*/ return this; } void default_value_t::output( outstream_t& out) const { output_node( *eq, out); output_node( *value, out); } void declarator_name_t::output_left( outstream_t& out) const { if ( stati) output_node( *stati, out); //debug0 << "declname: subtype=" << *subtype << "\n"; if ( subtype) { subtype->output_left( out); } if ( leading_internal) output_node( *leading_internal, out); } void declarator_name_t::output_right( outstream_t& out) const { //debug0 << "declarator_name_t::output_right: trailing_internal=" << trailing_internal << "\n"; if ( name) output_node( *name, out); if ( trailing_internal) output_node( *trailing_internal, out); if ( constructor_params) output_node( *constructor_params, out); if ( terminator) output_node( *terminator, out); if ( subtype) subtype->output_right( out); } void declarator_name_t::output_tech( outstream_t& out) const { scoped_change_t include_declleft( out.include_declleft, true); out.out << "declaratorname:typeid=" << typeid(*this).name() << ",name=["; if ( name) name->output_tech( out); out.out << "], subtype:["; if ( subtype) subtype->output_tech( out); out.out << "]"; } bool declarator_name_t::equal( const node_t& rhs0) const { const declarator_name_t& rhs = static_cast< const declarator_name_t&>( rhs0); return declarator_t::equal( rhs); } void declarator_terminator_t::output( outstream_t& out) const { output_node( *declarator, out); if ( defaultvalue) output_node( *defaultvalue, out); if ( terminator) output_node( *terminator, out); } void declarator_terminator_t::output_tech( outstream_t& out) const { declarator->output_tech( out); } template< class T> bool PtrEq( const T* a, const T* b) /* Useful when comparing what two pointer point to - checks each for being NULL for example. if_t both non-NULL, calls == on what they point to. */ { if ( a==NULL && b==NULL) return true; if ( a!=NULL && b!=NULL) return ( *a==*b); return false; } bool declarator_terminator_t::equal( const node_t& rhs0) const { const declarator_terminator_t& rhs = static_cast< const declarator_terminator_t&>( rhs0); if ( !PtrEq( this->declarator, rhs.declarator)) return false; if ( !PtrEq( this->terminator, rhs.terminator)) return false; return true; } declarator_left_t* declarator_terminator_t::get_declarator_left() const { for ( declarator_t* decl=this->declarator; ; decl=decl->subtype) { if ( decl->subtype == NULL) { declarator_left_t* declleft = dynamic_cast< declarator_left_t*>( decl); return declleft; } } } void declarator_terminator_t::output_complete( outstream_t& out) const { if ( declarator_left_t* declleft = this->get_declarator_left()) { declleft->OutputLeft2( out); } output_node( *this, out); } void declarator_terminator_t::OutputCompleteDeclOnly( outstream_t& out) const { if ( declarator_left_t* declleft = this->get_declarator_left()) { declleft->OutputLeft2( out); } output_node( *this->declarator, out); } std::string declarator_terminator_t::Output2StringCompleteDeclOnly() const { std::stringstream temp; outstream_t outstream( temp); if ( declarator_left_t* declleft = this->get_declarator_left()) { declleft->OutputLeft2( outstream); } output_node( *this->declarator, outstream); return temp.str(); } void declaratorprefix_t::output( outstream_t& out) const { for ( multiple_nodes_t::items_t::const_iterator it=this->items.items.begin(); it!=this->items.items.end(); ++it) { if ( !out.remove_static_virtual_prefixes || ( typeid( **it) != typeid( keyword_virtual) && typeid( **it) != typeid( keyword_static))) { output_node( *(*it), out); } } } bool declaratorprefix_t::ContainsType( const std::type_info& type) { for ( multiple_nodes_t::items_t::const_iterator it=this->items.items.begin(); it!=this->items.items.end(); ++it) { if ( typeid( **it) == type) return true; } return false; } bool declaratorprefix_t::equal( const node_t& rhs0) const { const declaratorprefix_t& rhs = static_cast< const declaratorprefix_t&>( rhs0); return rhs.items == this->items; } void declarator_names_t::output( outstream_t& out) const { //debug0 << "declarator_names_t::Output called\n"; if ( prefix) output_node( *prefix, out); if ( declleft) declleft->OutputLeft2( out); scoped_change_t include_declleft( out.include_declleft, false); for ( items_t::const_iterator it=items.begin(); it!=items.end(); ++it) output_node( *(*it), out); if ( semicolon) output_node( *semicolon, out); } template< class T> bool PtrContainerEq( const T& a, const T& b) /* Useful when comparing containers of pointers - compares pairs of pointers. Assumes there are no NULL pointers in either container. */ { if ( a.size()!=b.size()) return false; for ( typename T::const_iterator ait=a.begin(), bit=b.begin(); ait!=a.end(); ++ait,++bit) { if ( **ait != **bit) return false; } return true; } void fnbody_t::output( outstream_t& out) const { if ( this->initialisers) output_node( *this->initialisers, out); assert( this->body); output_node( *this->body, out); } bool fnbody_t::equal( const node_t& rhs0) const { const fnbody_t& rhs = static_cast< const fnbody_t&>( rhs0); if ( !PtrEq( this->initialisers, rhs.initialisers)) return false; if ( !PtrEq( this->body, rhs.body)) return false; return true; } bool declarator_names_t::equal( const node_t& rhs0) const { const declarator_names_t& rhs = static_cast< const declarator_names_t&>( rhs0); if ( !PtrEq( this->prefix, rhs.prefix)) return false; if ( !PtrEq( this->declleft, rhs.declleft)) return false; if ( !PtrContainerEq( this->items, rhs.items)) return false; if ( !PtrEq( this->semicolon, rhs.semicolon)) return false; return true; } declarator_left_t* declarator_t::is_simple_reference() { if ( reference_t* ref = dynamic_cast< reference_t*>( this->logical_subtype())) { if ( declarator_left_t* declleft = dynamic_cast< declarator_left_t*>( ref->subtype->logical_subtype())) { return declleft; } } return NULL; } declarator_left_t* declarator_t::is_simple_type() { if ( declarator_left_t* declleft = dynamic_cast< declarator_left_t*>( this->logical_subtype())) { return declleft; } return NULL; } function_t* declarator_t::is_simple_function() { if ( function_t* fn = dynamic_cast< function_t*>( this->logical_subtype())) { return fn; } return NULL; } declarator_t* declarator_t::logical_subtype() { declarator_t* decl = this; if ( dynamic_cast< declarator_name_t*>( decl)) decl = decl->subtype; for ( ; dynamic_cast< bracket_declarator_t*>( decl); decl=decl->subtype) { //debug0 << "skipping bracketdecl\n"; } return decl; } declarator_name_t* declarator_t::is_name() { return dynamic_cast< declarator_name_t*>( this); } declarator_left_t* declarator_t::get_declarator_left() { debug0 << debug_PLACE << ": declarator_t::get_declarator_left(): typeid( *this)=" << typeid( *this).name() << "\n"; if ( !this->subtype) return NULL; return this->subtype->get_declarator_left(); } void function_parameters_t::output( outstream_t& out) const { scoped_change_t include_declleft( out.include_declleft, false); //out.include_declleft = false; output_node( *openround, out); for ( unsigned int i=0; i include_declleft( out.remove_static_virtual_prefixes, true); //params[i]->OutputNoVirtualPrefix( out); output_node( *params[i], out); } else output_node( *params[i], out); } if ( dotdotdot) output_node( *dotdotdot, out); output_node( *closeround, out); } void function_parameters_t::output_tech( outstream_t& out) const { for ( unsigned int i=0; ioutput_tech( out); out.out << "]"; } if ( dotdotdot) dotdotdot->output_tech( out); } bool function_parameters_t::equal( const node_t& rhs0) const { const function_parameters_t& rhs = static_cast< const function_parameters_t&>( rhs0); if ( params.size() != rhs.params.size()) return false; for ( unsigned int i=0; i( rhs0); return *modifiers == *rhs.modifiers && declarator_t::equal( rhs); } void member_pointer_t::output_left( outstream_t& out) const { if ( subtype) subtype->output_left( out); output_node( *clas, out); } void member_pointer_t::output_tech( outstream_t& out) const { out.out << "[member_pointer_t: class:["; clas->output_tech( out); out.out << "]pointee:["; if ( this->subtype) this->subtype->output_tech( out); out.out << "]]"; } bool member_pointer_t::equal( const node_t& rhs0) const { const member_pointer_t& rhs = static_cast< const member_pointer_t&>( rhs0); return *clas==*rhs.clas && declarator_t::equal( rhs); } void pointer_t::output_left( outstream_t& out) const { if ( subtype) subtype->output_left( out); if ( leading_internal) output_node( *leading_internal, out); output_node( *star, out); if ( modifiers) output_node( *modifiers, out); } void pointer_t::output_right( outstream_t& out) const { if ( trailing_internal) output_node( *trailing_internal, out); if ( subtype) subtype->output_right( out); } void pointer_t::output_tech( outstream_t& out) const { out.out << "[pointer_t: mods:["; output_node( *this->modifiers, out); out.out << "], pointee:[ "; if ( this->subtype) this->subtype->output_tech( out); out.out << "]]"; } void reference_t::output_left( outstream_t& out) const { if ( leading_internal) output_node( *leading_internal, out); if ( subtype) { if ( this->modifiers) modifiers->OutputLeftSide( out, subtype->begin); subtype->output_left( out); if ( this->modifiers) modifiers->OutputRightSide( out, subtype->begin); } else { if ( this->modifiers) output_node( *modifiers, out); } output_node( *amp, out); } void reference_t::output_tech( outstream_t& out) const { out.out << "[Ref: mods:["; output_node( *this->modifiers, out); out.out << "] refee:["; if ( this->subtype) this->subtype->output_tech( out); out.out << "]]"; } void bracket_declarator_t::output_left( outstream_t& out) const { if ( subtype) subtype->output_left( out); if ( open) output_node( *open, out); } void bracket_declarator_t::output_right( outstream_t& out) const { if ( close) output_node( *close, out); if ( subtype) subtype->output_right( out); } void bracket_declarator_t::output_tech( outstream_t& out) const { out.out << "bracket_declarator_t:subtype=["; if ( this->subtype) this->subtype->output_tech( out); out.out << "]"; } void throwspec_t::output( outstream_t& out) const { if ( out.exceptiontranslation==exceptionstranslation_PRESERVE) { output_node( *thro, out); output_node( *block, out); } } void throw_expression_t::output( outstream_t& out) const { //std::cerr << "/* exceptiontranslation=" << ((int) out.exceptiontranslation) << "*/\n"; if ( out.exceptiontranslation==exceptionstranslation_EXIT) { if ( !expression) output_node( *semicolon, out); else { out.out << "{ std::cerr << ( ( "; output_node( *this->expression, out); out.out << ").what()) << \"\\n\"; exit( 1)"; output_node( *this->semicolon, out); out.out << "}"; } } else if ( out.exceptiontranslation==exceptionstranslation_FUDGE) { out.out << "Cmm_ExceptionFudge_Throw( "; if ( this->expression) output_node( *this->expression, out); out.out << ")"; output_node( *this->semicolon, out); } else if ( out.exceptiontranslation==exceptionstranslation_PRESERVE) { output_node( *this->thro, out); if ( this->expression) output_node( *this->expression, out); output_node( *this->semicolon, out); } else { assert( 0); } } void array_t::output_left( outstream_t& out) const { if ( subtype) subtype->output_left( out); } void array_t::output_right( outstream_t& out) const { output_node( *open, out); for ( unsigned int i=0; ioutput_right( out); } void bitfield_t::output_left( outstream_t& out) const { if ( subtype) subtype->output_left( out); } void bitfield_t::output_right( outstream_t& out) const { assert( this->colon); assert( this->numberofbits); output_node( *this->colon, out); output_node( *this->numberofbits, out); if ( subtype) subtype->output_right( out); } void function_t::output_left( outstream_t& out) const { if ( subtype) subtype->output_left( out); } void function_t::output_right( outstream_t& out) const { output_node( *parameters, out); output_node( modifiers, out); if ( throwspec) output_node( *throwspec, out); if ( internal) output_node( *internal, out); if ( subtype) subtype->output_right( out); } void function_t::output_tech( outstream_t& out) const { out.out << "function_t: " << parameters->num_virtparams << " virt params"; out.out << ", params:["; parameters->output_tech( out); out.out << "], return:["; if ( subtype) subtype->output_tech( out); out.out << "]"; } bool function_t::equal( const node_t& rhs0) const { const function_t& rhs = static_cast< const function_t&>( rhs0); return *parameters == *rhs.parameters && declarator_t::equal( rhs); } void template_node_t::output( outstream_t& out) const { output_node( *template_spec, out); output_node( *node, out); } bool template_node_t::equal( const node_t& rhs0) const { const template_node_t& rhs = static_cast< const template_node_t&>( rhs0); return PtrEq( template_spec, rhs.template_spec) && PtrEq( node, rhs.node); } void return_t::output( outstream_t& out) const { output_node( *this->retur, out); if ( this->expression) output_node( *this->expression, out); output_node( *this->semicolon, out); } bool return_t::equal( const node_t& rhs0) const { const return_t& rhs = static_cast< const return_t&>( rhs0); return *expression == *rhs.expression; } void while_t::output( outstream_t& out) const { output_node( *whil, out); output_node( *expression, out); output_node( *statement, out); } bool while_t::equal( const node_t& rhs0) const { const while_t& rhs = static_cast< const while_t&>( rhs0); return *expression == *rhs.expression && *statement==*rhs.statement; } bool compound_t::equal( const node_t& rhs0) const { const compound_t& rhs = static_cast< const compound_t&>( rhs0); return items == rhs.items; } bool for_loop_t::equal( const node_t& rhs0) const { const for_loop_t& rhs = static_cast< const for_loop_t&>( rhs0); return PtrEq( expr1, rhs.expr1) && PtrEq( expr2, rhs.expr2) && PtrEq( expr3, rhs.expr3) && PtrEq( contents, rhs.contents); } void if_t::output( outstream_t& out) const { output_node( *kwd_if, out); output_node( *open, out); if ( expression) output_node( *expression, out); output_node( *close, out); output_node( *statement, out); if ( els) output_node( *els, out); if ( else_statement) output_node( *else_statement, out); } bool if_t::equal( const node_t& rhs0) const { const if_t& rhs = static_cast< const if_t&>( rhs0); return PtrEq( expression, rhs.expression) && PtrEq( statement, rhs.statement) && PtrEq( els, rhs.els) && PtrEq( else_statement, rhs.else_statement); } void catch_t::output( outstream_t& out) const { //debug0 << "Ouputing catch\n"; //debug0 << "catch_t::Output: out.remove_exceptioncode=" << out.remove_exceptioncode << "\n"; if ( out.exceptiontranslation==exceptionstranslation_FUDGE) { out.out << "if ( std::exception* cmm_exceptionfudge_exception = Cmm_ExceptionFudge_Get()) { "; if ( declarator_name_t* declname = dynamic_cast< declarator_name_t*>( this->param)) { scoped_change_t include_declleft( out.include_declleft, true); output_node( *declname, out); out.out << " = *cmm_exceptionfudge_exception; "; } output_node( *this->block, out); out.out << "}"; } else { scoped_change_t output_main( out.output_main, (out.exceptiontranslation==exceptionstranslation_EXIT) ? false : true); output_node( *catc, out); output_node( *openround, out); { scoped_change_t include_declleft( out.include_declleft, true); output_node( *this->param, out); } output_node( *closeround, out); output_node( *block, out); } } bool catch_t::equal( const node_t& rhs0) const { const catch_t& rhs = static_cast< const catch_t&>( rhs0); return PtrEq( param, rhs.param) && PtrEq( block, rhs.block); } void try_t::output( outstream_t& out) const { if ( out.exceptiontranslation!=exceptionstranslation_PRESERVE) { scoped_change_t output_main( out.output_main, false); output_node( *tr, out); } else { output_node( *tr, out); } output_node( *block, out); } bool try_t::equal( const node_t& rhs0) const { const try_t& rhs = static_cast< const try_t&>( rhs0); return PtrEq( block, rhs.block) && PtrEq( block, rhs.block); } void case_base_t::output( outstream_t& out) const { for ( statements_t::const_iterator it=statements.begin(); it!=statements.end(); ++it) output_node( *(*it), out); } bool case_base_t::equal( const node_t&) const { throw std::logic_error( "case_base_t::equal not implemented"); } void case_initial_t::output( outstream_t& out) const { case_base_t::output( out); } void case_t::output( outstream_t& out) const { output_node( *cas, out); output_node( *expression, out); output_node( *colon, out); case_base_t::output( out); } void case_default_t::output( outstream_t& out) const { output_node( *defaul, out); output_node( *colon, out); case_base_t::output( out); } void switch_t::output( outstream_t& out) const { output_node( *switc, out); output_node( *expression, out); output_node( *open, out); for ( cases_t::const_iterator it=cases.begin(); it!=cases.end(); ++it) output_node( *(*it), out); output_node( *close, out); } bool switch_t::equal( const node_t& rhs0) const { const switch_t& rhs = static_cast< const switch_t&>( rhs0); return PtrEq( expression, rhs.expression) && cases==rhs.cases; } void do_t::output( outstream_t& out) const { output_node( *d, out); output_node( *statement, out); output_node( *whil, out); output_node( *expression, out); output_node( *semicolon, out); } bool do_t::equal( const node_t& rhs0) const { const do_t& rhs = static_cast< const do_t&>( rhs0); return PtrEq( statement, rhs.statement) && PtrEq( expression, rhs.expression); } bool for_loop_initstatement_t::equal( const node_t& rhs0) const { const for_loop_initstatement_t& rhs = static_cast< const for_loop_initstatement_t&>( rhs0); return PtrEq( expression, rhs.expression) && PtrEq( simpledeclaration, rhs.simpledeclaration); } void baseclass_t::output( outstream_t& out) const { output_node( *pre, out); for ( inheritance_t::const_iterator it=inheritance.begin(); it!=inheritance.end(); ++it) output_node( *(*it), out); output_node( *name, out); } bool baseclass_t::equal( const node_t& rhs0) const { const baseclass_t& rhs = static_cast< const baseclass_t&>( rhs0); if ( !pre != !rhs.pre || *pre != *rhs.pre) return false; if ( inheritance != rhs.inheritance) return false; return *name == *rhs.name; } void baseclasses_t::output( outstream_t& out) const { for ( unsigned int i=0; i( rhs0); if ( items.size() != rhs.items.size()) return false; for ( unsigned int i=0; ienum_or_union, out); if ( this->name) output_node( *this->name, out); if ( this->template_instantiation) output_node( *this->template_instantiation, out); output_node( *this->block, out); } bool enum_or_union_t::equal( const node_t& rhs0) const { const enum_or_union_t& rhs = static_cast< const enum_or_union_t&>( rhs0); if ( !PtrEq( this->enum_or_union, rhs.enum_or_union)) return false; if ( !PtrEq( this->name, rhs.name)) return false; if ( !PtrEq( this->template_instantiation, rhs.template_instantiation)) return false; if ( !PtrEq( this->block, rhs.block)) return false; return true; } void class_t::output( outstream_t& out) const { output_node( *class_or_struct, out); if ( name) output_node( *name, out); if ( template_instantiation) output_node( *template_instantiation, out); if ( baseclasses) output_node( *baseclasses, out); output_node( *block, out); } void class_t::output_tech( outstream_t& out) const { out.out << "class: type["; output_node( *class_or_struct, out); out.out << "], bases:["; baseclasses->output_tech( out); out.out << "], name: ["; if ( name) name->output_tech( out); out.out << "], block:["; output_node( *block, out); out.out << "]"; } bool class_t::equal( const node_t& rhs0) const { const class_t& rhs = static_cast< const class_t&>( rhs0); return *class_or_struct == *rhs.class_or_struct && *baseclasses == *rhs.baseclasses && *name == *rhs.name && *block == *rhs.block; } void class_fwd_t::output( outstream_t& out) const { output_node( *class_or_struct, out); output_node( *name, out); if ( template_instantiation) output_node( *template_instantiation, out); } void class_fwd_t::output_tech( outstream_t& out) const { out.out << "classfwd:["; output_node( *this, out); out.out << "]"; } bool class_fwd_t::equal( const node_t& rhs0) const { const class_fwd_t& rhs = static_cast< const class_fwd_t&>( rhs0); return *class_or_struct == *rhs.class_or_struct && *name == *rhs.name; } void ampersand_node_t::output( outstream_t& out) const { // output only the legal-C++ part. //output_node( *this->ampersand, out); //output_node( *this->name, out); output_node( *this->node, out); } void compilation_unit_t::append_item( node_t* item) { this->items.push_back( item); } void compilation_unit_t::output( outstream_t& out) const { for ( unsigned int i=0; ioutput_tech( out); } bool compilation_unit_t::equal( const node_t& rhs0) const { const compilation_unit_t& rhs = static_cast< const compilation_unit_t&>( rhs0); if ( items.size() != rhs.items.size()) return false; for ( unsigned int i=0; i