Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

dtool/src/cppparser/cppType.cxx

Go to the documentation of this file.
00001 // Filename: cppType.cxx
00002 // Created by:  drose (19Oct99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 
00020 #include "cppType.h"
00021 #include "cppTypedef.h"
00022 
00023 CPPType::Types CPPType::_types;
00024 CPPType::PreferredNames CPPType::_preferred_names;
00025 
00026 bool CPPTypeCompare::
00027 operator () (CPPType *a, CPPType *b) const {
00028   return (*a) < (*b);
00029 }
00030 
00031 ////////////////////////////////////////////////////////////////////
00032 //     Function: CPPType::Constructor
00033 //       Access: Public
00034 //  Description:
00035 ////////////////////////////////////////////////////////////////////
00036 CPPType::
00037 CPPType(const CPPFile &file) :
00038   CPPDeclaration(file)
00039 {
00040   _declaration = (CPPTypeDeclaration *)NULL;
00041 }
00042 
00043 ////////////////////////////////////////////////////////////////////
00044 //     Function: CPPType::resolve_type
00045 //       Access: Public, Virtual
00046 //  Description: If this CPPType object is a forward reference or
00047 //               other nonspecified reference to a type that might now
00048 //               be known a real type, returns the real type.
00049 //               Otherwise returns the type itself.
00050 ////////////////////////////////////////////////////////////////////
00051 CPPType *CPPType::
00052 resolve_type(CPPScope *, CPPScope *) {
00053   return this;
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: CPPType::is_tbd
00058 //       Access: Public, Virtual
00059 //  Description: Returns true if the type, or any nested type within
00060 //               the type, is a CPPTBDType and thus isn't fully
00061 //               determined right now.  In this case, calling
00062 //               resolve_type() may or may not resolve the type.
00063 ////////////////////////////////////////////////////////////////////
00064 bool CPPType::
00065 is_tbd() const {
00066   return false;
00067 }
00068 
00069 ////////////////////////////////////////////////////////////////////
00070 //     Function: CPPType::has_typedef_name
00071 //       Access: Public
00072 //  Description: Returns true if the type has even been typedef'ed and
00073 //               therefore has a simple name available to stand for
00074 //               it.  Extension types are all implicitly typedef'ed on
00075 //               declaration.
00076 ////////////////////////////////////////////////////////////////////
00077 bool CPPType::
00078 has_typedef_name() const {
00079   return !_typedefs.empty();
00080 }
00081 
00082 ////////////////////////////////////////////////////////////////////
00083 //     Function: CPPType::get_typedef_name
00084 //       Access: Public
00085 //  Description: Returns a string that can be used to name the type,
00086 //               if has_typedef_name() returned true.  This will be
00087 //               the first typedef name applied to the type.
00088 ////////////////////////////////////////////////////////////////////
00089 string CPPType::
00090 get_typedef_name(CPPScope *scope) const {
00091   if (_typedefs.empty()) {
00092     return string();
00093   } else {
00094     return _typedefs.front()->get_local_name(scope);
00095   }
00096 }
00097 
00098 ////////////////////////////////////////////////////////////////////
00099 //     Function: CPPType::get_simple_name
00100 //       Access: Public, Virtual
00101 //  Description: Returns a fundametal one-word name for the type.
00102 //               This name will not include any scoping operators or
00103 //               template parameters, so it may not be a compilable
00104 //               reference to the type.
00105 ////////////////////////////////////////////////////////////////////
00106 string CPPType::
00107 get_simple_name() const {
00108   return get_local_name();
00109 }
00110 
00111 ////////////////////////////////////////////////////////////////////
00112 //     Function: CPPType::get_local_name
00113 //       Access: Public, Virtual
00114 //  Description: Returns the compilable, correct name for this type
00115 //               within the indicated scope.  If the scope is NULL,
00116 //               within the scope the type is declared in.
00117 ////////////////////////////////////////////////////////////////////
00118 string CPPType::
00119 get_local_name(CPPScope *scope) const {
00120   ostringstream ostrm;
00121   output(ostrm, 0, scope, false);
00122   return ostrm.str();
00123 }
00124 
00125 ////////////////////////////////////////////////////////////////////
00126 //     Function: CPPType::get_fully_scoped_name
00127 //       Access: Public, Virtual
00128 //  Description: Returns the compilable, correct name for the type,
00129 //               with completely explicit scoping.
00130 ////////////////////////////////////////////////////////////////////
00131 string CPPType::
00132 get_fully_scoped_name() const {
00133   return get_local_name();
00134 }
00135 
00136 ////////////////////////////////////////////////////////////////////
00137 //     Function: CPPType::get_preferred_name
00138 //       Access: Public, Virtual
00139 //  Description: Returns the best name to use for the type from a
00140 //               programmer's point of view.  This will typically be a
00141 //               typedef name if one is available, or the full C++
00142 //               name if it is not.  The typedef may or may not be
00143 //               visible within the current scope, so this type name
00144 //               may not be compilable.
00145 ////////////////////////////////////////////////////////////////////
00146 string CPPType::
00147 get_preferred_name() const {
00148   string preferred_name = get_preferred_name_for(this);
00149   if (!preferred_name.empty()) {
00150     return preferred_name;
00151   }
00152   return get_local_name();
00153 }
00154 
00155 
00156 ////////////////////////////////////////////////////////////////////
00157 //     Function: CPPType::is_incomplete
00158 //       Access: Public, Virtual
00159 //  Description: Returns true if the type has not yet been fully
00160 //               specified, false if it has.
00161 ////////////////////////////////////////////////////////////////////
00162 bool CPPType::
00163 is_incomplete() const {
00164   return false;
00165 }
00166 
00167 ////////////////////////////////////////////////////////////////////
00168 //     Function: CPPType::is_equivalent
00169 //       Access: Public, Virtual
00170 //  Description: This is a little more forgiving than is_equal(): it
00171 //               returns true if the types appear to be referring to
00172 //               the same thing, even if they may have different
00173 //               pointers or somewhat different definitions.  It's
00174 //               useful for parameter matching, etc.
00175 ////////////////////////////////////////////////////////////////////
00176 bool CPPType::
00177 is_equivalent(const CPPType &other) const {
00178   if (get_subtype() != other.get_subtype()) {
00179     return false;
00180   }
00181   return is_equal(&other);
00182 }
00183 
00184 
00185 ////////////////////////////////////////////////////////////////////
00186 //     Function: CPPType::output_instance
00187 //       Access: Public, Virtual
00188 //  Description: Formats a C++-looking line that defines an instance
00189 //               of the given type, with the indicated name.  In most
00190 //               cases this will be "type name", but some types have
00191 //               special exceptions.
00192 ////////////////////////////////////////////////////////////////////
00193 void CPPType::
00194 output_instance(ostream &out, const string &name, CPPScope *scope) const {
00195   output_instance(out, 0, scope, false, "", name);
00196 }
00197 
00198 ////////////////////////////////////////////////////////////////////
00199 //     Function: CPPType::output_instance
00200 //       Access: Public, Virtual
00201 //  Description: Formats a C++-looking line that defines an instance
00202 //               of the given type, with the indicated name.  In most
00203 //               cases this will be "type name", but some types have
00204 //               special exceptions.
00205 ////////////////////////////////////////////////////////////////////
00206 void CPPType::
00207 output_instance(ostream &out, int indent_level, CPPScope *scope,
00208                 bool complete, const string &prename,
00209                 const string &name) const {
00210   output(out, indent_level, scope, complete);
00211   out << " " << prename << name;
00212 }
00213 
00214 
00215 ////////////////////////////////////////////////////////////////////
00216 //     Function: CPPType::as_type
00217 //       Access: Public, Virtual
00218 //  Description:
00219 ////////////////////////////////////////////////////////////////////
00220 CPPType *CPPType::
00221 as_type() {
00222   return this;
00223 }
00224 
00225 
00226 ////////////////////////////////////////////////////////////////////
00227 //     Function: CPPType::new_type
00228 //       Access: Public, Static
00229 //  Description: This should be called whenever a new CPPType object
00230 //               is created.  It will uniquify the type pointers by
00231 //               checking to see if some equivalent CPPType object has
00232 //               previously been created; if it has, it returns the
00233 //               old object and deletes the new one.  Otherwise, it
00234 //               stores the new one and returns it.
00235 ////////////////////////////////////////////////////////////////////
00236 CPPType *CPPType::
00237 new_type(CPPType *type) {
00238   pair<Types::iterator, bool> result = _types.insert(type);
00239   if (result.second) {
00240     // The insertion has taken place; thus, this is the first time
00241     // this type has been declared.
00242     assert(*result.first == type);
00243     return type;
00244   }
00245 
00246   // The insertion has not taken place; thus, there was previously
00247   // another equivalent type declared.
00248   if (*result.first != type) {
00249     // *** Something wrong here.  Deleting this should always be safe;
00250     // however, it's not.  Thus, someone failed to call new_type() on
00251     // a type pointer before saving it somewhere.  Fix me soon.  ****
00252 
00253     //delete type;
00254   }
00255   return *result.first;
00256 }
00257 
00258 ////////////////////////////////////////////////////////////////////
00259 //     Function: CPPType::record_preferred_name_for
00260 //       Access: Public, Static
00261 //  Description: Records a global typedef name associated with the
00262 //               indicated Type.  This will be taken as the
00263 //               "preferred" name for this class, should anyone ask.
00264 ////////////////////////////////////////////////////////////////////
00265 void CPPType::
00266 record_preferred_name_for(const CPPType *type, const string &name) {
00267   if (!name.empty()) {
00268     string tname = type->get_fully_scoped_name();
00269     if (!tname.empty()) {
00270       _preferred_names.insert(PreferredNames::value_type(tname, name));
00271     }
00272   }
00273 }
00274 
00275 ////////////////////////////////////////////////////////////////////
00276 //     Function: CPPType::get_preferred_name_for
00277 //       Access: Public, Static
00278 //  Description: Returns the previously-stored "preferred" name
00279 //               associated with the type, if any, or empty string if
00280 //               no name is associated.
00281 ////////////////////////////////////////////////////////////////////
00282 string CPPType::
00283 get_preferred_name_for(const CPPType *type) {
00284   // We do a lookup based on the type's name, instead of its pointer,
00285   // so we can resolve different expansions of the same type.
00286   string tname = type->get_fully_scoped_name();
00287 
00288   if (!tname.empty()) {
00289     PreferredNames::const_iterator pi;
00290     pi = _preferred_names.find(tname);
00291     if (pi != _preferred_names.end()) {
00292       return (*pi).second;
00293     }
00294   }
00295 
00296   return string();
00297 }

Generated on Thu May 1 22:12:56 2003 for DTool by doxygen1.3