📄 ast_interface.cpp
字号:
UTL_Scope *s)
{
if (i == 0)
{
return;
}
UTL_Scope *scope = i->defined_in ();
const char *prefix_holder = 0;
// If our prefix is empty, we check to see if an ancestor has one.
while (ACE_OS::strcmp (i->prefix (), "") == 0 && scope != 0)
{
AST_Decl *parent = ScopeAsDecl (scope);
prefix_holder = parent->prefix ();
// We have reached global scope.
if (prefix_holder == 0)
{
break;
}
i->prefix (ACE_const_cast (char *, prefix_holder));
scope = parent->defined_in ();
}
// 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 (),
0);
AST_Interface *fd = 0;
if (d != 0)
{
scope = d->defined_in ();
// If the lookup prefix is empty, we check to see if an ancestor has one.
while (ACE_OS::strcmp (d->prefix (), "") == 0 && scope != 0)
{
AST_Decl *parent = ScopeAsDecl (scope);
prefix_holder = parent->prefix ();
// We have reached global scope.
if (prefix_holder == 0)
{
break;
}
d->prefix (ACE_const_cast (char *, prefix_holder));
scope = parent->defined_in ();
}
// 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_interface_fwd
|| nt == AST_Decl::NT_valuetype_fwd
|| nt == AST_Decl::NT_component_fwd
|| nt == AST_Decl::NT_eventtype_fwd)
{
AST_InterfaceFwd *fwd_def =
AST_InterfaceFwd::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_interface
|| nt == AST_Decl::NT_valuetype
|| nt == AST_Decl::NT_component
|| nt == AST_Decl::NT_eventtype)
{
fd = AST_Interface::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->is_local () != fd->is_local ()
|| i_nt != fd_nt
|| i->is_abstract () != fd->is_abstract ()
)
{
idl_global->err ()->error2 (UTL_Error::EIDL_REDEF,
i,
fd);
return;
}
fd->redefine (i);
// Use full definition node.
delete i;
i = fd;
}
}
}
}
void
AST_Interface::redef_clash_populate_r (AST_Interface *t)
{
if (this->insert_non_dup (t, 0) == 0)
{
return;
}
AST_Interface **parents = t->inherits ();
long n_parents = t->n_inherits ();
long i;
for (i = 0; i < n_parents; ++i)
{
this->redef_clash_populate_r (parents[i]);
}
AST_Decl::NodeType nt = t->node_type ();
if (nt == AST_Decl::NT_valuetype)
{
AST_ValueType *v = AST_ValueType::narrow_from_decl (t);
AST_Interface **supports = v->supports ();
long n_supports = v->n_supports ();
for (i = 0; i < n_supports; ++i)
{
this->redef_clash_populate_r (supports[i]);
}
}
else if (nt == AST_Decl::NT_component)
{
AST_Component *c = AST_Component::narrow_from_decl (t);
AST_Interface **supports = c->supports ();
long n_supports = c->n_supports ();
for (i = 0; i < n_supports; ++i)
{
this->redef_clash_populate_r (supports[i]);
}
}
}
int
AST_Interface::insert_non_dup (AST_Interface *t,
idl_bool abstract_paths_only)
{
// Now check if the dequeued element has any ancestors. If yes, insert
// them inside the queue making sure that there are no duplicates.
// If we are doing a component, the inheritance list is actually a
// supports list.
for (long i = 0; i < t->n_inherits (); ++i)
{
// Retrieve the next parent from which the dequeued element inherits.
AST_Interface *parent = t->inherits ()[i];
if (abstract_paths_only && ! parent->is_abstract ())
{
continue;
}
(void) this->insert_non_dup (parent, abstract_paths_only);
} // end of for loop
const char *full_name = t->full_name ();
// Initialize an iterator to search the queue for duplicates.
for (ACE_Unbounded_Queue_Iterator<AST_Interface *> q_iter (
this->insert_queue
);
!q_iter.done ();
(void) q_iter.advance ())
{
// Queue element.
AST_Interface **temp;
(void) q_iter.next (temp);
if (!ACE_OS::strcmp (full_name,
(*temp)->full_name ()))
{
// We exist in this queue and cannot be inserted.
return 0;
}
}
// Initialize an iterator to search the del_queue for duplicates.
for (ACE_Unbounded_Queue_Iterator<AST_Interface *> del_q_iter (
this->del_queue
);
!del_q_iter.done ();
(void) del_q_iter.advance ())
{
// Queue element.
AST_Interface **temp;
(void) del_q_iter.next (temp);
if (!ACE_OS::strcmp (full_name,
(*temp)->full_name ()))
{
// We exist in this del_queue and cannot be inserted.
return 0;
}
}
// Insert the parent in the queue.
if (this->insert_queue.enqueue_tail (t) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_interface::insert_non_dup - "
"enqueue failed\n"),
0);
}
return 1;
}
// This serves only for interfaces. It is overridden for valuetypes,
// components and eventtypes.
void
AST_Interface::redefine (AST_Interface *from)
{
// 'this' is the full_definition member of a forward
// declared interface. 'from' is the actual full
// definition, which may be in a different scope.
// Since 'this' will replace 'from' upon returning
// from here, we have to update the scope now.
this->pd_inherits = from->pd_inherits;
this->pd_n_inherits = from->pd_n_inherits;
this->pd_inherits_flat = from->pd_inherits_flat;
this->pd_n_inherits_flat = from->pd_n_inherits_flat;
// We've already checked for inconsistent prefixes.
this->prefix (ACE::strnew (from->prefix ()));
this->set_defined_in (from->defined_in ());
this->set_imported (idl_global->imported ());
this->set_in_main_file (idl_global->in_main_file ());
this->set_line (idl_global->lineno ());
this->set_file_name (idl_global->filename ());
this->ifr_added_ = from->ifr_added_;
this->ifr_fwd_added_ = from->ifr_fwd_added_;
}
// Data accessors.
AST_Interface **
AST_Interface::inherits (void) const
{
return this->pd_inherits;
}
long
AST_Interface::n_inherits (void) const
{
return this->pd_n_inherits;
}
AST_Interface **
AST_Interface::inherits_flat (void) const
{
return this->pd_inherits_flat;
}
long
AST_Interface::n_inherits_flat (void) const
{
return pd_n_inherits_flat;
}
ACE_Unbounded_Queue<AST_Interface *> &
AST_Interface::get_insert_queue (void)
{
return this->insert_queue;
}
ACE_Unbounded_Queue<AST_Interface *> &
AST_Interface::get_del_queue (void)
{
return this->del_queue;
}
idl_bool
AST_Interface::redef_clash (void)
{
this->insert_queue.reset ();
this->redef_clash_populate_r (this);
AST_Interface **group1_member = 0;
AST_Interface **group2_member = 0;
AST_Decl *group1_member_item = 0;
AST_Decl *group2_member_item = 0;
int i = 1;
// Now compare all pairs.
for (ACE_Unbounded_Queue_Iterator<AST_Interface *> group1_iter (
this->insert_queue
);
!group1_iter.done ();
(void) group1_iter.advance (), ++i)
{
// Queue element.
(void) group1_iter.next (group1_member);
for (UTL_ScopeActiveIterator group1_member_items (
DeclAsScope (*group1_member),
UTL_Scope::IK_decls
);
!group1_member_items.is_done ();
group1_member_items.next ())
{
group1_member_item = group1_member_items.item ();
AST_Decl::NodeType nt1 = group1_member_item->node_type ();
// Only these member types may cause a clash because
// they can't be redefined.
if (nt1 != AST_Decl::NT_op && nt1 != AST_Decl::NT_attr)
{
continue;
}
Identifier *pid1 = group1_member_item->local_name ();
int j = 0;
for (ACE_Unbounded_Queue_Iterator<AST_Interface *> group2_iter (
this->insert_queue
);
!group2_iter.done ();
(void) group2_iter.advance ())
{
// Since group1 and group2 are the same list, we can start this
// iterator from where the outer one is.
while (j++ < i)
{
group2_iter.advance ();
}
if (group2_iter.done ())
{
break;
}
// Queue element.
(void) group2_iter.next (group2_member);
for (UTL_ScopeActiveIterator group2_member_items (
DeclAsScope (*group2_member),
UTL_Scope::IK_decls
);
!group2_member_items.is_done ();
group2_member_items.next ())
{
group2_member_item = group2_member_items.item ();
AST_Decl::NodeType nt2 = group2_member_item->node_type ();
// Only these member types may cause a clash
// with other parents' member of the same type.
if (nt2 != AST_Decl::NT_op && nt2 != AST_Decl::NT_attr)
{
continue;
}
Identifier *pid2 = group2_member_item->local_name ();
if (pid1->compare (pid2) == I_TRUE)
{
idl_global->err ()->error3 (
UTL_Error::EIDL_REDEF,
*group1_member,
*group2_member,
group2_member_item
);
return 1;
}
else if (pid1->case_compare_quiet (pid2) == I_TRUE)
{
if (idl_global->case_diff_error ())
{
idl_global->err ()->error3 (
UTL_Error::EIDL_NAME_CASE_ERROR,
*group1_member,
group1_member_item,
group2_member_item
);
}
else
{
idl_global->err ()->warning3 (
UTL_Error::EIDL_NAME_CASE_WARNING,
*group1_member,
group1_member_item,
group2_member_item
);
}
return 1;
}
} // end of FOR (group2_member_items)
} // end of FOR (group2_iter)
} // end of FOR (group1_member_items)
} // end of FOR (group1_iter)
return 0;
}
AST_Decl *
AST_Interface::lookup_for_add (AST_Decl *d,
idl_bool /* treat_as_ref */)
{
if (d == 0)
{
return 0;
}
Identifier *id = d->local_name ();
AST_Decl *prev = 0;
AST_Decl::NodeType nt = NT_root;
long nis = -1;
AST_Interface **is = 0;
if (this->idl_keyword_clash (id) != 0)
{
return 0;
}
prev = this->lookup_by_name_local (id,
0);
if (prev != 0)
{
nt = prev->node_type ();
if (nt == AST_Decl::NT_op || nt == AST_Decl::NT_attr)
{
return prev;
}
}
for (nis = this->n_inherits_flat (), is = this->inherits_flat ();
nis > 0;
nis--, is++)
{
prev = (*is)->lookup_by_name_local (id,
0);
if (prev != 0)
{
nt = prev->node_type ();
if (nt == AST_Decl::NT_op || nt == AST_Decl::NT_attr)
{
return prev;
}
}
}
return 0;
}
void
AST_Interface::destroy (void)
{
delete [] this->pd_inherits;
this->pd_inherits = 0;
delete [] this->pd_inherits_flat;
this->pd_inherits_flat = 0;
}
int
AST_Interface::ast_accept (ast_visitor *visitor)
{
return visitor->visit_interface (this);
}
// Narrowing methods.
IMPL_NARROW_METHODS2(AST_Interface, AST_Type, UTL_Scope)
IMPL_NARROW_FROM_DECL(AST_Interface)
IMPL_NARROW_FROM_SCOPE(AST_Interface)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -