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 }