// We don't actually want the forward declaration, // but want to return the full definition member, // whether defined yet or not. AST_Decl * AST_StructureFwd::adjust_found ( bool ignore_fwd, bool full_def_only) { if (ignore_fwd) { AST_Structure *s = this->full_definition (); return (full_def_only && !s->is_defined () ? 0 : s); } return this; }
AST_Structure * AST_Module::fe_add_structure (AST_Structure * s) { AST_Decl * d = lookup_for_add (s); if (d) { /* Check for existing declaration or pre-declaration */ if (d->node_type () == AST_Decl::NT_struct) { AST_Structure * fwd = AST_Structure::narrow_from_decl (d); if (fwd->is_defined () && s->is_defined ()) { /* Invalid duplicate declaration */ idl_global->err()->error3 (UTL_Error::EIDL_REDEF, s, this, d); } else { if (! fwd->is_defined () && s->is_defined ()) { reorder (d); } // Return existing delete s; s = fwd; } } else { idl_global->err()->error3 (UTL_Error::EIDL_REDEF, s, this, d); } } else { add_to_scope (s); add_to_referenced (s, false); } return s; }
bool FE_Utils::can_be_redefined (AST_Decl *prev_decl, AST_Decl *curr_decl) { AST_Decl::NodeType pnt = prev_decl->node_type (); AST_Decl::NodeType cnt = curr_decl->node_type (); switch (cnt) { /// For these, any non-zero previous decl /// is an error. case AST_Decl::NT_attr: case AST_Decl::NT_op: case AST_Decl::NT_ext_port: case AST_Decl::NT_mirror_port: case AST_Decl::NT_provides: case AST_Decl::NT_publishes: case AST_Decl::NT_consumes: case AST_Decl::NT_uses: return false; default: break; } UTL_Scope *prev_scope = prev_decl->defined_in (); UTL_Scope *curr_scope = curr_decl->defined_in (); AST_Structure *s = 0; AST_StructureFwd *s_fwd = 0; AST_Template_Module *ptm = 0; AST_Template_Module *ctm = 0; bool nt_eq = (pnt == cnt); bool s_eq = (prev_scope == curr_scope); switch (pnt) { case AST_Decl::NT_module: /// Need to check that both are modules. if (cnt != AST_Decl::NT_module) { return false; } /// Neither can be a template module. ptm = AST_Template_Module::narrow_from_decl (prev_decl); ctm = AST_Template_Module::narrow_from_decl (curr_decl); return (ptm == 0 && ctm == 0); /// For the *_fwd types, if scopes aren't related, it's ok. /// If they are related, then we need another fwd or a full decl. case AST_Decl::NT_component_fwd: return (!s_eq || (nt_eq || cnt == AST_Decl::NT_component)); case AST_Decl::NT_eventtype_fwd: return (!s_eq || (nt_eq || cnt == AST_Decl::NT_eventtype)); case AST_Decl::NT_interface_fwd: return (!s_eq || (nt_eq || cnt == AST_Decl::NT_interface)); case AST_Decl::NT_struct_fwd: return (!s_eq || (nt_eq || cnt == AST_Decl::NT_struct)); case AST_Decl::NT_union_fwd: return (!s_eq || (nt_eq || cnt == AST_Decl::NT_union)); case AST_Decl::NT_valuetype_fwd: return (!s_eq || (nt_eq || cnt == AST_Decl::NT_valuetype)); /// If scopes aren't related, it's ok. If they are, check /// if the previous is a dummy for a fwd decl. Even a redef /// in a derived interface type is ok. case AST_Decl::NT_struct: case AST_Decl::NT_union: s = AST_Structure::narrow_from_decl (prev_decl); s_fwd = (s == 0 ? 0 : s->fwd_decl ()); return (!s_eq || s_fwd != 0); /// Only 2 or more full definitions in the same scope are illegal, /// and that is caught elsewhere. case AST_Decl::NT_interface: case AST_Decl::NT_component: case AST_Decl::NT_eventtype: case AST_Decl::NT_valuetype: return true; /// For connectors, factories, exceptions, constants and types, even a /// redef in a derived interface type is ok. Checking for /// unequal scopes covers boxed valuetypes as well. case AST_Decl::NT_connector: case AST_Decl::NT_valuebox: case AST_Decl::NT_except: case AST_Decl::NT_typedef: case AST_Decl::NT_const: case AST_Decl::NT_factory: case AST_Decl::NT_type: case AST_Decl::NT_enum: case AST_Decl::NT_enum_val: { return !s_eq; } /// What's left are the case from the previous switch statement. /// Same rule applies - no overrides or redefs, ever. default: return false; } }
// Specialized visit_scope method for stucts only. int ifr_adding_visitor_structure::visit_scope (UTL_Scope *node) { // If the struct has members that are scopes but not structs, // the regular visit_scope method should be called instead. if (node->scope_node_type () != AST_Decl::NT_struct) { return ifr_adding_visitor::visit_scope (node); } AST_Structure *s = AST_Structure::narrow_from_scope (node); CORBA::ULong nfields = static_cast<CORBA::ULong> (s->nfields ()); this->members_.length (nfields); AST_Field **f = 0; try { // Visit each field. for (CORBA::ULong i = 0; i < nfields; ++i) { if (s->field (f, i) != 0) { ORBSVCS_ERROR_RETURN (( LM_ERROR, ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::") ACE_TEXT ("visit_scope -") ACE_TEXT (" field node access failed\n")), -1); } AST_Type *ft = (*f)->field_type (); bool defined_here = ft->is_child (this->scope_); // If the struct member is defined in the struct, we have to // do some visiting - otherwise we can just look up the entry. if (defined_here) { if (ft->node_type () == AST_Decl::NT_struct) { // Since the enclosing scope hasn't been created yet, // we make a special visitor to create this member // at global scope and move it into the struct later. ifr_adding_visitor_structure visitor (ft); if (ft->ast_accept (&visitor) == -1) { ORBSVCS_ERROR_RETURN (( LM_ERROR, ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::") ACE_TEXT ("visit_scope -") ACE_TEXT (" failed to accept visitor\n")), -1); } this->ir_current_ = CORBA::IDLType::_duplicate (visitor.ir_current ()); } else { if (ft->ast_accept (this) == -1) { ORBSVCS_ERROR_RETURN (( LM_ERROR, ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::") ACE_TEXT ("visit_scope -") ACE_TEXT (" failed to accept visitor\n")), -1); } } } else { // Updates ir_current_. this->get_referenced_type (ft); } this->members_[i].name = CORBA::string_dup ((*f)->local_name ()->get_string ()); // IfR method create_struct does not use this - it just needs // to be non-zero for marshaling. this->members_[i].type = CORBA::TypeCode::_duplicate (CORBA::_tc_void); this->members_[i].type_def = CORBA::IDLType::_duplicate (this->ir_current_.in ()); } } catch (const CORBA::Exception& ex) { ex._tao_print_exception ( ACE_TEXT ( "ifr_adding_visitor_structure::visit_scope")); return -1; } return 0; }
// This serves for structs and unions. void AST_Structure::fwd_redefinition_helper (AST_Structure *&i, UTL_Scope *s) { if (i == 0) { return; } // Fwd redefinition should be in the same scope, so local // lookup is all that's needed. AST_Decl *d = s->lookup_by_name_local (i->local_name (), false); AST_Structure *fd = 0; if (d != 0) { // Full definition must have the same prefix as the forward declaration. if (ACE_OS::strcmp (i->prefix (), d->prefix ()) != 0) { idl_global->err ()->error1 (UTL_Error::EIDL_PREFIX_CONFLICT, i); return; } AST_Decl::NodeType nt = d->node_type (); // If this interface has been forward declared in a previous opening // of the module it's defined in, the lookup will find the // forward declaration. if (nt == AST_Decl::NT_struct_fwd || nt == AST_Decl::NT_union_fwd) { AST_StructureFwd *fwd_def = AST_StructureFwd::narrow_from_decl (d); fd = fwd_def->full_definition (); } // In all other cases, the lookup will find an interface node. else if (nt == AST_Decl::NT_struct || nt == AST_Decl::NT_union) { fd = AST_Structure::narrow_from_decl (d); } // Successful? if (fd == 0) { // Should we give an error here? // No, look in fe_add_interface. } // If it is a forward declared interface.. else if (!fd->is_defined ()) { // Check if redefining in same scope. If a module is reopened, // a new pointer in created, and the first term below will be // true. In that case, the scoped names must be compared. if (fd->defined_in () != s && i->name ()->compare (fd->name ()) != 0) { idl_global->err ()->error2 (UTL_Error::EIDL_SCOPE_CONFLICT, i, fd); } // All OK, do the redefinition. else { AST_Decl::NodeType fd_nt = fd->node_type (); AST_Decl::NodeType i_nt = i->node_type (); // Only redefinition of the same kind. if (i_nt != fd_nt) { idl_global->err ()->error2 (UTL_Error::EIDL_REDEF, i, fd); return; } fd->redefine (i); AST_StructureFwd *fwd = fd->fwd_decl (); if (0 != fwd) { // So the fwd decl won't destroy us at cleanup time. // Unlike interfaces, valuetypes and components, it's // ok to do this here, since fwd declared structs // and unions must be defined in the same translation // unit. fwd->set_as_defined (); } // Use full definition node. i->destroy (); delete i; i = fd; } } } }