summaryrefslogtreecommitdiff
path: root/ACE/TAO/TAO_IDL/ast/ast_decl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/TAO/TAO_IDL/ast/ast_decl.cpp')
-rw-r--r--ACE/TAO/TAO_IDL/ast/ast_decl.cpp1561
1 files changed, 1561 insertions, 0 deletions
diff --git a/ACE/TAO/TAO_IDL/ast/ast_decl.cpp b/ACE/TAO/TAO_IDL/ast/ast_decl.cpp
new file mode 100644
index 00000000000..6c7b8682681
--- /dev/null
+++ b/ACE/TAO/TAO_IDL/ast/ast_decl.cpp
@@ -0,0 +1,1561 @@
+// $Id$
+
+/*
+
+COPYRIGHT
+
+Copyright 1992, 1993, 1994 Sun Microsystems, Inc. Printed in the United
+States of America. All Rights Reserved.
+
+This product is protected by copyright and distributed under the following
+license restricting its use.
+
+The Interface Definition Language Compiler Front End (CFE) is made
+available for your use provided that you include this license and copyright
+notice on all media and documentation and the software program in which
+this product is incorporated in whole or part. You may copy and extend
+functionality (but may not remove functionality) of the Interface
+Definition Language CFE without charge, but you are not authorized to
+license or distribute it to anyone else except as part of a product or
+program developed by you or with the express written consent of Sun
+Microsystems, Inc. ("Sun").
+
+The names of Sun Microsystems, Inc. and any of its subsidiaries or
+affiliates may not be used in advertising or publicity pertaining to
+distribution of Interface Definition Language CFE as permitted herein.
+
+This license is effective until terminated by Sun for failure to comply
+with this license. Upon termination, you shall destroy or return all code
+and documentation for the Interface Definition Language CFE.
+
+INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED AS IS WITH NO WARRANTIES OF
+ANY KIND INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS
+FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR ARISING FROM A COURSE OF
+DEALING, USAGE OR TRADE PRACTICE.
+
+INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED WITH NO SUPPORT AND WITHOUT
+ANY OBLIGATION ON THE PART OF Sun OR ANY OF ITS SUBSIDIARIES OR AFFILIATES
+TO ASSIST IN ITS USE, CORRECTION, MODIFICATION OR ENHANCEMENT.
+
+SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES SHALL HAVE NO LIABILITY WITH
+RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY
+INTERFACE DEFINITION LANGUAGE CFE OR ANY PART THEREOF.
+
+IN NO EVENT WILL SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES BE LIABLE FOR
+ANY LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL
+DAMAGES, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+Use, duplication, or disclosure by the government is subject to
+restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
+Technical Data and Computer Software clause at DFARS 252.227-7013 and FAR
+52.227-19.
+
+Sun, Sun Microsystems and the Sun logo are trademarks or registered
+trademarks of Sun Microsystems, Inc.
+
+SunSoft, Inc.
+2550 Garcia Avenue
+Mountain View, California 94043
+
+NOTE:
+
+SunOS, SunSoft, Sun, Solaris, Sun Microsystems or the Sun logo are
+trademarks or registered trademarks of Sun Microsystems, Inc.
+
+*/
+
+/*
+ * AST_Decl is the base class for all AST nodes except AST_Expression.
+ * AST_Decls have a node type (a value from the enum AST_Decl::NodeType)
+ * and a name (a UTL_ScopedName).
+ * Additionally AST_Decl nodes record the scope of definition, the
+ * file name in which they were defined, the line on which they were
+ * defined in that file, and a boolean denoting whether this is the
+ * main file or an #include'd file.
+ */
+
+#include "ast_interface.h"
+#include "ast_module.h"
+#include "ast_array.h"
+#include "ast_field.h"
+#include "ast_structure.h"
+#include "ast_sequence.h"
+#include "ast_string.h"
+#include "ast_typedef.h"
+#include "ast_visitor.h"
+#include "global_extern.h"
+#include "nr_extern.h"
+#include "utl_identifier.h"
+#include "utl_string.h"
+#include "utl_scope.h"
+#include "utl_err.h"
+#include "ace/OS_NS_stdio.h"
+
+// FUZZ: disable check_for_streams_include
+#include "ace/streams.h"
+
+COMMON_Base::COMMON_Base (bool local,
+ bool abstract)
+ : is_local_ (local),
+ is_abstract_ (abstract)
+{
+}
+
+bool
+COMMON_Base::is_local (void)
+{
+ return this->is_local_;
+}
+
+void
+COMMON_Base::is_local (bool val)
+{
+ this->is_local_ = val;
+}
+
+bool
+COMMON_Base::is_abstract (void) const
+{
+ return this->is_abstract_;
+}
+
+void
+COMMON_Base::is_abstract (bool val)
+{
+ this->is_abstract_ = val;
+}
+
+void
+COMMON_Base::destroy (void)
+{
+}
+
+// Constructor(s) and destructor.
+
+AST_Decl::AST_Decl (void)
+ : COMMON_Base (),
+ repoID_ (0),
+ flat_name_ (0),
+ contains_wstring_ (-1),
+ pd_imported (false),
+ pd_in_main_file (false),
+ pd_defined_in (0),
+ pd_node_type (NT_module),
+ pd_line (-1),
+ pd_local_name (0),
+ pd_original_local_name (0),
+ pd_added (false),
+ full_name_ (0),
+ prefix_ (0),
+ version_ (0),
+ anonymous_ (false),
+ typeid_set_ (false),
+ last_referenced_as_ (0),
+ prefix_scope_ (0)
+{
+}
+
+AST_Decl::AST_Decl (NodeType nt,
+ UTL_ScopedName *n,
+ bool anonymous)
+ : COMMON_Base (),
+ repoID_ (0),
+ flat_name_ (0),
+ contains_wstring_ (-1),
+ pd_imported (idl_global->imported ()),
+ pd_in_main_file (idl_global->in_main_file ()),
+ pd_defined_in (idl_global->scopes ().depth () > 0
+ ? idl_global->scopes ().top ()
+ : 0),
+ pd_node_type (nt),
+ pd_line (idl_global->lineno ()),
+ pd_name (0),
+ pd_local_name (n == 0 ? 0 : n->last_component ()->copy ()),
+ pd_original_local_name (0),
+ pd_added (false),
+ full_name_ (0),
+ prefix_ (0),
+ version_ (0),
+ anonymous_ (anonymous),
+ typeid_set_ (false),
+ last_referenced_as_ (0),
+ prefix_scope_ (0)
+{
+ // If this is the root node, the filename won't have been set yet.
+ UTL_String *fn = idl_global->filename ();
+ this->pd_file_name = (fn != 0 ? fn->get_string () : "");
+
+ this->compute_full_name (n);
+
+ char *prefix = 0;
+ idl_global->pragma_prefixes ().top (prefix);
+
+ if (prefix == 0)
+ {
+ this->prefix_ = ACE::strnew ("");
+ }
+ else
+ {
+ this->prefix_ = ACE::strnew (prefix);
+ }
+
+ if (n != 0)
+ {
+ // The function body creates its own copy.
+ this->original_local_name (n->last_component ());
+ }
+
+ this->compute_repoID ();
+}
+
+AST_Decl::~AST_Decl (void)
+{
+}
+
+// Private operations.
+
+// Compute our private UTL_ScopedName member.
+void
+AST_Decl::compute_full_name (UTL_ScopedName *n)
+{
+ // This should happen only when we are a non-void predefined type,
+ // in which case our scoped name has already been created by the
+ // AST_PredefinedType constructor.
+ if (n == 0)
+ {
+ return;
+ }
+
+ UTL_ScopedName *cn = 0;
+ AST_Decl *d = 0;
+
+ // Initialize this name to 0.
+ this->pd_name = 0;
+
+ // Global scope?
+ if (this->defined_in () == 0)
+ {
+ this->pd_name = (UTL_IdList *) n->copy ();
+ return;
+ }
+
+ // OK, not global. So copy name of containing scope, then
+ // smash last cdr of copy with new component
+ d = ScopeAsDecl (this->defined_in ());
+
+ if (d != 0)
+ {
+ cn = d->name ();
+ }
+
+ if (cn != 0)
+ {
+ this->pd_name = (UTL_IdList *) cn->copy ();
+ }
+
+ if (this->pd_local_name != 0)
+ {
+ if (this->pd_name == 0)
+ {
+ ACE_NEW (this->pd_name,
+ UTL_ScopedName (this->pd_local_name->copy (),
+ 0));
+ }
+ else
+ {
+ UTL_ScopedName *conc_name = 0;
+ ACE_NEW (conc_name,
+ UTL_ScopedName (this->pd_local_name->copy (),
+ 0));
+
+ this->pd_name->nconc (conc_name);
+ }
+ }
+}
+
+void
+AST_Decl::set_prefix_with_typeprefix_r (const char *value,
+ UTL_Scope *appeared_in)
+{
+ if (this->typeid_set_)
+ {
+ return;
+ }
+
+ if (this->prefix_scope_ != 0)
+ {
+ AST_Decl *decl = ScopeAsDecl (this->prefix_scope_);
+
+ bool const overridden =
+ decl->has_ancestor (ScopeAsDecl (appeared_in));
+
+ if (overridden)
+ {
+ return;
+ }
+ }
+
+ delete [] this->repoID_;
+ this->repoID_ = 0;
+ this->prefix (value);
+ this->prefix_scope_ = appeared_in;
+
+ UTL_Scope *s = DeclAsScope (this);
+
+ if (s != 0)
+ {
+ AST_Decl *tmp = 0;
+ UTL_Scope *s_tmp = 0;
+
+ for (UTL_ScopeActiveIterator i (s, UTL_Scope::IK_decls);
+ !i.is_done ();
+ i.next ())
+ {
+ tmp = i.item ();
+ s_tmp = DeclAsScope (tmp);
+
+ if (s_tmp == 0)
+ {
+ continue;
+ }
+
+ tmp->set_prefix_with_typeprefix_r (value,
+ appeared_in);
+ }
+ }
+
+ // This will recursively catch all previous openings of a module.
+ if (this->node_type () == AST_Decl::NT_module)
+ {
+ AST_Decl **d = 0;
+ AST_Module *m = AST_Module::narrow_from_decl (this);
+
+ for (ACE_Unbounded_Set_Iterator<AST_Decl *> iter (m->previous ());
+ !iter.done ();
+ iter.advance ())
+ {
+ iter.next (d);
+
+ if ((*d)->node_type () == AST_Decl::NT_pre_defined)
+ {
+ continue;
+ }
+
+ (*d)->set_prefix_with_typeprefix_r (value,
+ appeared_in);
+ }
+ }
+
+ this->compute_repoID ();
+}
+
+// Protected operations.
+
+// Compute stringified fully scoped name.
+void
+AST_Decl::compute_full_name (void)
+{
+ if (this->full_name_ != 0)
+ {
+ return;
+ }
+ else
+ {
+ size_t namelen = 0;
+ long first = true;
+ long second = false;
+ char *name = 0;
+
+ for (UTL_IdListActiveIterator i (this->name ());
+ !i.is_done ();
+ i.next ())
+ {
+ if (!first)
+ {
+ namelen += 2; // for "::"
+ }
+ else if (second)
+ {
+ first = second = false;
+ }
+
+ // Print the identifier.
+ name = i.item ()->get_string ();
+ namelen += ACE_OS::strlen (name);
+
+ if (first)
+ {
+ if (ACE_OS::strcmp (name, "") != 0)
+ {
+ // Does not start with a "".
+ first = false;
+ }
+ else
+ {
+ second = true;
+ }
+ }
+ }
+
+ ACE_NEW (this->full_name_,
+ char[namelen + 1]);
+
+ this->full_name_[0] = '\0';
+ first = true;
+ second = false;
+
+ for (UTL_IdListActiveIterator j (this->name ());
+ !j.is_done ();
+ j.next ())
+ {
+ if (!first)
+ {
+ ACE_OS::strcat (this->full_name_, "::");
+ }
+ else if (second)
+ {
+ first = second = false;
+ }
+
+ // Print the identifier.
+ name = j.item ()->get_string ();
+ ACE_OS::strcat (this->full_name_, name);
+
+ if (first)
+ {
+ if (ACE_OS::strcmp (name, "") != 0)
+ {
+ // Does not start with a "".
+ first = false;
+ }
+ else
+ {
+ second = true;
+ }
+ }
+ }
+ }
+}
+
+// Compute stringified repository ID.
+void
+AST_Decl::compute_repoID (void)
+{
+ if (this->repoID_ != 0)
+ {
+ return;
+ }
+
+ size_t namelen = 4; // for the prefix "IDL:"
+ long first = true;
+ long second = false;
+ char *name = 0;
+ const char *prefix = (this->prefix_ ? this->prefix_ : "");
+ UTL_Scope *scope = this->defined_in ();
+ const char *parent_prefix = 0;
+
+ // If our prefix is empty, we check to see if an ancestor has one.
+ while (ACE_OS::strcmp (prefix, "") == 0 && scope != 0)
+ {
+ AST_Decl *parent = ScopeAsDecl (scope);
+
+ if (parent->node_type () == AST_Decl::NT_root
+ && parent->imported ())
+ {
+ break;
+ }
+
+ parent_prefix = parent->prefix ();
+ prefix = (parent_prefix ? parent_prefix : "");
+ scope = parent->defined_in ();
+ }
+
+ // in the first loop compute the total length
+ namelen += ACE_OS::strlen (prefix) + 1;
+
+ const char *version = this->version_;
+ scope = this->defined_in ();
+
+ // If our version is has not bee set, we use the parent's, if any.
+ while (version == 0 && scope != 0)
+ {
+ AST_Decl *parent = ScopeAsDecl (scope);
+ version = parent->version_;
+ scope = parent->defined_in ();
+ }
+
+ if (version != 0)
+ {
+ // Version member string + ':'
+ namelen += ACE_OS::strlen (version) + 1;
+ }
+ else
+ {
+ // For ":1.0"
+ namelen += 4;
+ }
+
+ for (UTL_IdListActiveIterator i (this->name ());
+ !i.is_done ();
+ i.next ())
+ {
+ if (!first)
+ {
+ namelen += 1; // for "/"
+ }
+ else if (second)
+ {
+ first = second = false;
+ }
+
+ // Print the identifier.
+ name = i.item ()->get_string ();
+ size_t item_len = ACE_OS::strlen (name);
+
+ if (ACE_OS::strstr (name, "_cxx_") == name)
+ {
+ namelen += (item_len - ACE_OS::strlen ("_cxx_"));
+ }
+ else
+ {
+ namelen += item_len;
+ }
+
+ if (first)
+ {
+ if (ACE_OS::strcmp (name, "") != 0)
+ {
+ // Does not start with a "".
+ first = false;
+ }
+ else
+ {
+ second = true;
+ }
+ }
+ }
+
+ ACE_NEW (this->repoID_,
+ char[namelen + 1]);
+
+ this->repoID_[0] = '\0';
+
+ ACE_OS::sprintf (this->repoID_,
+ "%s",
+ "IDL:");
+
+ if (ACE_OS::strcmp (prefix, "") != 0)
+ {
+ ACE_OS::strcat (this->repoID_,
+ prefix);
+
+ ACE_OS::strcat (this->repoID_, "/");
+ }
+
+ first = true;
+ second = false;
+
+ for (UTL_IdListActiveIterator j (this->name ());
+ !j.is_done ();
+ j.next ())
+ {
+ if (!first)
+ {
+ ACE_OS::strcat (this->repoID_, "/");
+ }
+ else if (second)
+ {
+ first = second = false;
+ }
+
+ // Print the identifier.
+ name = j.item ()->get_string ();
+
+ if (ACE_OS::strstr (name, "_cxx_") == name)
+ {
+ ACE_OS::strcat (this->repoID_,
+ name + ACE_OS::strlen ("_cxx_"));
+ }
+ else
+ {
+ ACE_OS::strcat (this->repoID_,
+ name);
+ }
+
+ if (first)
+ {
+ if (ACE_OS::strcmp (name, "") != 0)
+ {
+ // Does not start with a "".
+ first = false;
+ }
+ else
+ {
+ second = true;
+ }
+ }
+ }
+
+ if (version != 0)
+ {
+ ACE_OS::strcat (this->repoID_,
+ ":");
+ ACE_OS::strcat (this->repoID_,
+ version);
+ }
+ else
+ {
+ ACE_OS::strcat (this->repoID_,
+ ":1.0");
+ }
+}
+
+// Public operations.
+
+const char *
+AST_Decl::flat_name (void)
+{
+ if (!this->flat_name_)
+ {
+ this->compute_flat_name ();
+ }
+
+ return this->flat_name_;
+}
+
+// Compute stringified flattened fully scoped name.
+void
+AST_Decl::compute_flat_name (void)
+{
+ if (this->flat_name_ != 0)
+ {
+ return;
+ }
+ else
+ {
+ size_t namelen = 0;
+ long first = true;
+ long second = false;
+ char *item_name = 0;
+
+ // In the first loop, compute the total length.
+ for (UTL_IdListActiveIterator i (this->name ());
+ !i.is_done ();
+ i.next ())
+ {
+ if (!first)
+ {
+ namelen += 1; // for "_"
+ }
+ else if (second)
+ {
+ first = second = false;
+ }
+
+ // Print the identifier, leaving out
+ // _cxx_ prefix, if any.
+ Identifier *tmp = i.item ()->copy ();
+ idl_global->original_local_name (tmp);
+ item_name = tmp->get_string ();
+ namelen += ACE_OS::strlen (item_name);
+
+ if (first)
+ {
+ if (ACE_OS::strcmp (item_name, "") != 0)
+ {
+ // Does not start with a "".
+ first = false;
+ }
+ else
+ {
+ second = true;
+ }
+ }
+
+ tmp->destroy ();
+ delete tmp;
+ tmp = 0;
+ }
+
+ ACE_NEW (this->flat_name_,
+ char[namelen + 1]);
+
+ this->flat_name_[0] = '\0';
+ first = true;
+ second = false;
+
+ for (UTL_IdListActiveIterator j (this->name ());
+ !j.is_done ();
+ j.next ())
+ {
+ if (!first)
+ {
+ ACE_OS::strcat (this->flat_name_, "_");
+ }
+ else if (second)
+ {
+ first = second = false;
+ }
+
+ // Print the identifier, leaving out
+ // _cxx_ prefix, if any.
+ Identifier *tmp = j.item ()->copy ();
+ idl_global->original_local_name (tmp);
+ item_name = tmp->get_string ();
+ ACE_OS::strcat (this->flat_name_, item_name);
+
+ if (first)
+ {
+ if (ACE_OS::strcmp (item_name, "") != 0)
+ {
+ // Does not start with a "".
+ first = false;
+ }
+ else
+ {
+ second = true;
+ }
+ }
+
+ tmp->destroy ();
+ delete tmp;
+ tmp = 0;
+ }
+ }
+}
+
+const char *
+AST_Decl::node_type_to_string (NodeType nt)
+{
+ switch (nt)
+ {
+ case NT_module:
+ return "module";
+ case NT_interface:
+ case NT_interface_fwd:
+ return "interface";
+ case NT_valuetype:
+ case NT_valuetype_fwd:
+ case NT_valuebox:
+ return "valuetype";
+ case NT_const:
+ return "const";
+ case NT_except:
+ return "exception";
+ case NT_attr:
+ return "attribute";
+ case NT_union:
+ case NT_union_fwd:
+ return "union";
+ case NT_struct:
+ case NT_struct_fwd:
+ return "struct";
+ case NT_enum:
+ return "enum";
+ case NT_string:
+ return "string";
+ case NT_wstring:
+ return "wstring";
+ case NT_array:
+ return "array";
+ case NT_sequence:
+ return "sequence";
+ case NT_typedef:
+ return "typedef";
+ case NT_pre_defined:
+ return "primitive";
+ case NT_native:
+ return "native";
+ case NT_factory:
+ return "factory";
+ case NT_component:
+ case NT_component_fwd:
+ return "component";
+ case NT_home:
+ return "home";
+ case NT_eventtype:
+ case NT_eventtype_fwd:
+ return "eventtype";
+ case NT_type:
+ return "typename";
+ case NT_fixed:
+ return "fixed";
+ case NT_porttype:
+ return "porttype";
+ case NT_provides:
+ return "provides";
+ case NT_uses:
+ return "uses";
+ case NT_publishes:
+ return "publishes";
+ case NT_emits:
+ return "emits";
+ case NT_consumes:
+ return "consumes";
+ // No useful output for these.
+ case NT_enum_val:
+ case NT_field:
+ case NT_union_branch:
+ case NT_op:
+ case NT_argument:
+ case NT_root:
+ default:
+ return "";
+ }
+}
+
+// Return TRUE if one of my ancestor scopes is "s"
+// and FALSE otherwise.
+bool
+AST_Decl::has_ancestor (AST_Decl *s)
+{
+ if (this == s)
+ {
+ return true;
+ }
+
+ if (s->node_type () == AST_Decl::NT_module)
+ {
+ UTL_Scope *enclosing = s->defined_in ();
+ AST_Decl *other_opening = s;
+
+ for (int index = 1; other_opening != 0; ++index)
+ {
+ if (this == other_opening)
+ {
+ return true;
+ }
+
+ other_opening = enclosing->lookup_by_name_local (s->local_name (),
+ index);
+ }
+ }
+
+ if (this->pd_defined_in == 0)
+ {
+ return false;
+ }
+
+ return ScopeAsDecl (this->pd_defined_in)->has_ancestor (s);
+}
+
+bool
+AST_Decl::is_child (AST_Decl *s)
+{
+ if (this->defined_in ())
+ {
+ AST_Decl *d = ScopeAsDecl (this->defined_in ());
+
+ if (d == 0)
+ {
+ return 0;
+ }
+
+ if (ACE_OS::strcmp (d->full_name (), s->full_name ()) == 0)
+ {
+ return 1;
+ }
+ }
+
+ return 0; // Not a child.
+}
+
+bool
+AST_Decl::is_nested (void)
+{
+ AST_Decl *d = ScopeAsDecl (this->defined_in ());
+
+ // If we have an outermost scope and if that scope is not that of the Root,
+ // then we are defined at some nesting level.
+ if (d != 0 && d->node_type () != AST_Decl::NT_root)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+// Dump this AST_Decl to the ostream o.
+void
+AST_Decl::dump (ACE_OSTREAM_TYPE &o)
+{
+ this->pd_local_name->dump (o);
+}
+
+void
+AST_Decl::dump_i (ACE_OSTREAM_TYPE &o, const char *s) const
+{
+ // Have to use ACE_CString here to avoid ambiguous overload error, see
+ // SString.h for an the overloaded operator << () methods.
+ o << ACE_CString(s);
+}
+
+int
+AST_Decl::ast_accept (ast_visitor *visitor)
+{
+ return visitor->visit_decl (this);
+}
+
+void
+AST_Decl::destroy (void)
+{
+ // These are not set for the root node.
+ if (this->pd_name != 0)
+ {
+ this->pd_name->destroy ();
+ delete this->pd_name;
+ this->pd_name = 0;
+ }
+
+ if (this->pd_local_name != 0)
+ {
+ this->pd_local_name->destroy ();
+ delete this->pd_local_name;
+ this->pd_local_name = 0;
+ }
+
+ if (this->pd_original_local_name != 0)
+ {
+ this->pd_original_local_name->destroy ();
+ delete this->pd_original_local_name;
+ this->pd_original_local_name = 0;
+ }
+
+ if (this->last_referenced_as_ != 0)
+ {
+ this->last_referenced_as_->destroy ();
+ delete this->last_referenced_as_;
+ this->last_referenced_as_ = 0;
+ }
+
+ delete [] this->full_name_;
+ this->full_name_ = 0;
+
+ delete [] this->repoID_;
+ this->repoID_ = 0;
+
+ delete [] this->prefix_;
+ this->prefix_ = 0;
+
+ delete [] this->version_;
+ this->version_ = 0;
+
+ delete [] this->flat_name_;
+ this->flat_name_ = 0;
+}
+
+// Data accessors.
+
+const char *
+AST_Decl::full_name (void)
+{
+ if (this->full_name_ == 0)
+ {
+ this->compute_full_name ();
+ }
+
+ return this->full_name_;
+}
+
+const char *
+AST_Decl::repoID (void)
+{
+ if (this->pd_node_type == NT_root)
+ {
+ delete [] this->repoID_;
+ this->repoID_ = ACE::strnew ("");
+ }
+
+ if (this->repoID_ == 0)
+ {
+ this->compute_repoID ();
+ }
+
+ return this->repoID_;
+}
+
+void
+AST_Decl::repoID (char *value)
+{
+ if (this->repoID_ != 0)
+ {
+ delete [] this->repoID_;
+ }
+
+ this->repoID_ = value;
+}
+
+const char *
+AST_Decl::prefix (void)
+{
+ return this->prefix_;
+}
+
+void
+AST_Decl::prefix (const char *value)
+{
+ delete [] this->prefix_;
+ this->prefix_ = ACE::strnew (value);
+}
+
+const char *
+AST_Decl::version (void)
+{
+ if (this->version_ == 0)
+ {
+ // Calling the method will compute if necessary.
+ const char *repo_id = this->repoID ();
+
+ // All forms of repo id should contain two colons, the
+ // version coming after the second one.
+ const char *tail1 = 0;
+ const char *tail2 = 0;
+
+ if (repo_id != 0)
+ {
+ tail1 = ACE_OS::strchr (repo_id,
+ ':');
+ }
+
+ if (tail1 != 0)
+ {
+ tail2 = ACE_OS::strchr (tail1 + 1,
+ ':');
+ }
+
+ if (! this->typeid_set_ && tail2 != 0)
+ {
+ this->version_ = ACE::strnew (tail2 + 1);
+ }
+ else
+ {
+ this->version_ = ACE::strnew ("1.0");
+ }
+ }
+
+ return this->version_;
+}
+
+void
+AST_Decl::version (char *value)
+{
+ // Previous #pragma version or #pragma id make this illegal.
+ if ((this->version_ == 0 || ACE_OS::strcmp (this->version_, value) == 0)
+ && ! this->typeid_set_)
+ {
+ delete [] this->version_;
+ this->version_ = value;
+
+ // Repo id is now computed eagerly, so a version set must update
+ // is as well.
+ if (this->repoID_ != 0)
+ {
+ ACE_CString tmp (this->repoID_);
+ ACE_CString::size_type const pos = tmp.rfind (':');
+
+ if (pos != ACE_CString::npos)
+ {
+ tmp = tmp.substr (0, pos + 1) + value;
+ delete [] this->repoID_;
+ this->repoID_ = ACE::strnew (tmp.fast_rep ());
+ }
+ }
+ }
+ else
+ {
+ idl_global->err ()->version_reset_error ();
+ }
+}
+
+bool
+AST_Decl::anonymous (void) const
+{
+ return this->anonymous_;
+}
+
+void
+AST_Decl::anonymous (bool val)
+{
+ this->anonymous_ = val;
+}
+
+bool
+AST_Decl::typeid_set (void) const
+{
+ return this->typeid_set_;
+}
+
+void
+AST_Decl::typeid_set (bool val)
+{
+ this->typeid_set_ = val;
+}
+
+void
+AST_Decl::set_id_with_typeid (char *value)
+{
+ // Can't call 'typeid' twice, even with the same value.
+ if (this->typeid_set ())
+ {
+ idl_global->err ()->error1 (UTL_Error::EIDL_TYPEID_RESET,
+ this);
+ }
+
+ // Are we a legal type for 'typeid'?
+ switch (this->pd_node_type)
+ {
+ case AST_Decl::NT_field:
+ {
+ AST_Decl::NodeType nt =
+ ScopeAsDecl (this->defined_in ())->node_type ();
+
+ if (nt == AST_Decl::NT_valuetype || nt == AST_Decl::NT_eventtype)
+ {
+ break;
+ }
+ else
+ {
+ idl_global->err ()->error1 (UTL_Error::EIDL_INVALID_TYPEID,
+ this);
+
+ return;
+ }
+ }
+ case AST_Decl::NT_module:
+ case AST_Decl::NT_interface:
+ case AST_Decl::NT_const:
+ case AST_Decl::NT_typedef:
+ case AST_Decl::NT_except:
+ case AST_Decl::NT_attr:
+ case AST_Decl::NT_op:
+ case AST_Decl::NT_enum:
+ case AST_Decl::NT_factory:
+ case AST_Decl::NT_component:
+ case AST_Decl::NT_home:
+ case AST_Decl::NT_eventtype:
+ break;
+ default:
+ idl_global->err ()->error1 (UTL_Error::EIDL_INVALID_TYPEID,
+ this);
+
+ return;
+ }
+
+ delete [] this->repoID_;
+ this->repoID_ = 0;
+ this->repoID (ACE::strnew (value));
+ this->typeid_set_ = true;
+}
+
+void
+AST_Decl::set_prefix_with_typeprefix (const char *value)
+{
+ // Are we a legal type for 'typeprefix'? This is checked only at
+ // the top level.
+ switch (this->pd_node_type)
+ {
+ case AST_Decl::NT_module:
+ case AST_Decl::NT_interface:
+ case AST_Decl::NT_valuetype:
+ case AST_Decl::NT_eventtype:
+ case AST_Decl::NT_struct:
+ case AST_Decl::NT_union:
+ case AST_Decl::NT_except:
+ break;
+ default:
+ idl_global->err ()->error1 (UTL_Error::EIDL_INVALID_TYPEPREFIX,
+ this);
+
+ return;
+ }
+
+ this->set_prefix_with_typeprefix_r (value,
+ DeclAsScope (this));
+}
+
+bool
+AST_Decl::imported (void)
+{
+ return this->pd_imported;
+}
+
+void
+AST_Decl::set_imported (bool is_it)
+{
+ this->pd_imported = is_it;
+}
+
+bool
+AST_Decl::in_main_file (void)
+{
+ return this->pd_in_main_file;
+}
+
+void
+AST_Decl::set_in_main_file (bool is_it)
+{
+ this->pd_in_main_file = is_it;
+}
+
+bool
+AST_Decl::added (void)
+{
+ return this->pd_added;
+}
+
+void
+AST_Decl::set_added (bool is_it)
+{
+ this->pd_added = is_it;
+}
+
+UTL_Scope *
+AST_Decl::defined_in (void)
+{
+ return this->pd_defined_in;
+}
+
+void
+AST_Decl::set_defined_in (UTL_Scope *s)
+{
+ this->pd_defined_in = s;
+}
+
+AST_Decl::NodeType
+AST_Decl::node_type (void)
+{
+ return this->pd_node_type;
+}
+
+long
+AST_Decl::line (void)
+{
+ return this->pd_line;
+}
+
+void
+AST_Decl::set_line (long l)
+{
+ this->pd_line = l;
+}
+
+ACE_CString
+AST_Decl::file_name (void)
+{
+ return this->pd_file_name;
+}
+
+void
+AST_Decl::set_file_name (ACE_CString s)
+{
+ this->pd_file_name = s;
+}
+
+UTL_ScopedName *
+AST_Decl::name (void)
+{
+ return this->pd_name;
+}
+
+// @@ Wherever compute_* are called, we should remember to delete them
+// after use.
+
+// Variation of the <name>. Computes scoped name string, applying
+// prefix and suffix to the local name component.
+UTL_ScopedName *
+AST_Decl::compute_name (const char *prefix,
+ const char *suffix)
+{
+ if (prefix == 0 || suffix == 0)
+ {
+ return 0;
+ }
+
+ UTL_ScopedName *result_name = 0;
+
+ // Prepare prefix_<local_name>_suffix string.
+
+ ACE_CString suffix_str (suffix);
+ ACE_CString local_str (this->local_name ()->get_string ());
+
+ ACE_CString result_local_str (prefix);
+ result_local_str += local_str;
+ result_local_str += suffix_str;
+
+ // Identifier for the resulting local name.
+ Identifier *result_local_id = 0;
+ ACE_NEW_RETURN (result_local_id,
+ Identifier (result_local_str.c_str ()),
+ 0);
+
+ // UTL_Scoped name for the resulting local name.
+ UTL_ScopedName *result_local_name = 0;
+ ACE_NEW_RETURN (result_local_name,
+ UTL_ScopedName (result_local_id,
+ 0),
+ 0);
+
+ // Global scope?
+ if (this->defined_in () == 0)
+ {
+ result_name = result_local_name;
+ }
+ else
+ {
+ // OK, not global. So copy name of containing scope, then
+ // smash last cdr of copy with new component.
+
+ AST_Decl *d = ScopeAsDecl (this->defined_in ());
+
+ if (d != 0)
+ {
+ UTL_ScopedName *cn = d->name ();
+
+ if (cn != 0)
+ {
+ result_name = (UTL_ScopedName *) cn->copy ();
+
+ if (result_name == 0)
+ {
+ result_name = result_local_name;
+ }
+ else
+ {
+ result_name->nconc (result_local_name);
+ }
+ }
+ }
+ }
+
+ return result_name;
+}
+
+void
+AST_Decl::set_name (UTL_ScopedName *n)
+{
+ if (this->pd_name == n)
+ {
+ return;
+ }
+
+ if (this->pd_name != 0)
+ {
+ this->pd_name->destroy ();
+ delete this->pd_name;
+ }
+
+ this->pd_name = n;
+
+ if (n != 0)
+ {
+ if (this->pd_local_name != 0)
+ {
+ this->pd_local_name->destroy ();
+ delete this->pd_local_name;
+ }
+
+ this->pd_local_name = n->last_component ()->copy ();
+
+ // The name without _cxx_ prefix removed, if there was any.
+ if (this->pd_original_local_name != 0)
+ {
+ this->pd_original_local_name->destroy ();
+ delete this->pd_original_local_name;
+ }
+
+ this->original_local_name (n->last_component ());
+
+ // These will be recomputed on demand.
+ delete [] this->flat_name_;
+ this->flat_name_ = 0;
+
+ delete [] this->full_name_;
+ this->full_name_ = 0;
+
+ delete [] this->repoID_;
+ this->repoID_ = 0;
+ }
+}
+
+Identifier *
+AST_Decl::local_name (void)
+{
+ return this->pd_local_name;
+}
+
+void
+AST_Decl::local_name (Identifier *id)
+{
+ if (this->pd_local_name != 0)
+ {
+ this->pd_local_name->destroy ();
+ }
+
+ delete this->pd_local_name;
+ this->pd_local_name = id;
+}
+
+Identifier *
+AST_Decl::compute_local_name (const char *prefix,
+ const char *suffix)
+{
+ if (prefix == 0 || suffix == 0)
+ {
+ return 0;
+ }
+
+ // Init the result with prefix.
+ ACE_CString result_str (prefix);
+
+ // Put local.
+ result_str += ACE_CString (this->local_name ()->get_string ());
+
+ // Put suffix.
+ result_str += ACE_CString (suffix);
+
+ // Identifier for the resulting local name.
+ Identifier *result_id = 0;
+ ACE_NEW_RETURN (result_id,
+ Identifier (result_str.c_str ()),
+ 0);
+
+ return result_id;
+}
+
+// If there is _cxx_ in the beginning, we will remove that and keep
+// a copy of the original name. TAO IDL's front end adds _cxx_
+// prefix to the all the reserved keywords. But when we invoke the
+// operation remotely, we should be sending only the name with out
+// "_cxx_" prefix.
+void
+AST_Decl::original_local_name (Identifier *local_name)
+{
+ // Remove _cxx_ if it is present.
+ if (ACE_OS::strstr (local_name->get_string (),
+ "_cxx_")
+ == local_name->get_string ())
+ {
+ // AACE_CString class is good to do this stuff.
+ ACE_CString name_str (local_name->get_string ());
+
+ // Remove _cxx_.
+ name_str = name_str.substr (ACE_OS::strlen ("_cxx_"));
+
+ // Assign to the Identifier variable.
+ ACE_NEW (this->pd_original_local_name,
+ Identifier (name_str.c_str ()));
+ }
+ else
+ {
+ this->pd_original_local_name = local_name->copy ();
+ }
+}
+
+Identifier *
+AST_Decl::original_local_name (void)
+{
+ return this->pd_original_local_name;
+}
+
+UTL_ScopedName *
+AST_Decl::last_referenced_as (void) const
+{
+ return this->last_referenced_as_;
+}
+
+void
+AST_Decl::last_referenced_as (UTL_ScopedName *n)
+{
+ if (this->last_referenced_as_ != 0)
+ {
+ this->last_referenced_as_->destroy ();
+ }
+
+ delete this->last_referenced_as_;
+ this->last_referenced_as_ = n;
+}
+
+UTL_Scope *
+AST_Decl::prefix_scope (void)
+{
+ return this->prefix_scope_;
+}
+
+void
+AST_Decl::prefix_scope (UTL_Scope *s)
+{
+ this->prefix_scope_ = s;
+}
+
+// Container types will override this.
+int
+AST_Decl::contains_wstring (void)
+{
+ if (this->contains_wstring_ == -1)
+ {
+ switch (this->node_type ())
+ {
+ case AST_Decl::NT_array:
+ {
+ AST_Array *a = AST_Array::narrow_from_decl (this);
+ this->contains_wstring_ =
+ a->base_type ()->contains_wstring ();
+ break;
+ }
+ case AST_Decl::NT_except:
+ case AST_Decl::NT_struct:
+ case AST_Decl::NT_union:
+ {
+ AST_Structure *s = AST_Structure::narrow_from_decl (this);
+ this->contains_wstring_ =
+ s->contains_wstring ();
+ break;
+ }
+ case AST_Decl::NT_sequence:
+ {
+ AST_Sequence *s = AST_Sequence::narrow_from_decl (this);
+ this->contains_wstring_ =
+ s->base_type ()->contains_wstring ();
+ break;
+ }
+ case AST_Decl::NT_attr:
+ case AST_Decl::NT_field:
+ case AST_Decl::NT_union_branch:
+ {
+ AST_Field *f = AST_Field::narrow_from_decl (this);
+ this->contains_wstring_ =
+ f->field_type ()->contains_wstring ();
+ break;
+ }
+ case AST_Decl::NT_typedef:
+ {
+ AST_Typedef *td = AST_Typedef::narrow_from_decl (this);
+ this->contains_wstring_ =
+ td->primitive_base_type ()->contains_wstring ();
+ break;
+ }
+ case AST_Decl::NT_wstring:
+ this->contains_wstring_ = 1;
+ break;
+ default:
+ this->contains_wstring_ = 0;
+ break;
+ }
+ }
+
+ return this->contains_wstring_;
+}
+
+// Non-virtual - no need to override this one.
+void
+AST_Decl::contains_wstring (int val)
+{
+ this->contains_wstring_ = val;
+}
+
+//Narrowing methods for AST_Decl.
+
+IMPL_NARROW_FROM_DECL(AST_Decl)
+
+
+