00001 // Filename: cppArrayType.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 "cppArrayType.h" 00021 #include "cppExpression.h" 00022 00023 //////////////////////////////////////////////////////////////////// 00024 // Function: CPPArrayType::Constructor 00025 // Access: Public 00026 // Description: 00027 //////////////////////////////////////////////////////////////////// 00028 CPPArrayType:: 00029 CPPArrayType(CPPType *element_type, CPPExpression *bounds) : 00030 CPPType(CPPFile()), 00031 _element_type(element_type), 00032 _bounds(bounds) 00033 { 00034 } 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Function: CPPArrayType::is_fully_specified 00038 // Access: Public, Virtual 00039 // Description: Returns true if this declaration is an actual, 00040 // factual declaration, or false if some part of the 00041 // declaration depends on a template parameter which has 00042 // not yet been instantiated. 00043 //////////////////////////////////////////////////////////////////// 00044 bool CPPArrayType:: 00045 is_fully_specified() const { 00046 return CPPType::is_fully_specified() && 00047 _element_type->is_fully_specified(); 00048 } 00049 00050 //////////////////////////////////////////////////////////////////// 00051 // Function: CPPArrayType::resolve_type 00052 // Access: Public, Virtual 00053 // Description: If this CPPType object is a forward reference or 00054 // other nonspecified reference to a type that might now 00055 // be known a real type, returns the real type. 00056 // Otherwise returns the type itself. 00057 //////////////////////////////////////////////////////////////////// 00058 CPPType *CPPArrayType:: 00059 resolve_type(CPPScope *current_scope, CPPScope *global_scope) { 00060 CPPType *ptype = _element_type->resolve_type(current_scope, global_scope); 00061 00062 if (ptype != _element_type) { 00063 CPPArrayType *rep = new CPPArrayType(*this); 00064 rep->_element_type = ptype; 00065 return CPPType::new_type(rep); 00066 } 00067 return this; 00068 } 00069 00070 //////////////////////////////////////////////////////////////////// 00071 // Function: CPPArrayType::is_tbd 00072 // Access: Public, Virtual 00073 // Description: Returns true if the type, or any nested type within 00074 // the type, is a CPPTBDType and thus isn't fully 00075 // determined right now. In this case, calling 00076 // resolve_type() may or may not resolve the type. 00077 //////////////////////////////////////////////////////////////////// 00078 bool CPPArrayType:: 00079 is_tbd() const { 00080 return _element_type->is_tbd(); 00081 } 00082 00083 //////////////////////////////////////////////////////////////////// 00084 // Function: CPPArrayType::is_equivalent 00085 // Access: Public, Virtual 00086 // Description: This is a little more forgiving than is_equal(): it 00087 // returns true if the types appear to be referring to 00088 // the same thing, even if they may have different 00089 // pointers or somewhat different definitions. It's 00090 // useful for parameter matching, etc. 00091 //////////////////////////////////////////////////////////////////// 00092 bool CPPArrayType:: 00093 is_equivalent(const CPPType &other) const { 00094 const CPPArrayType *ot = ((CPPType *)&other)->as_array_type(); 00095 if (ot == (CPPArrayType *)NULL) { 00096 return CPPType::is_equivalent(other); 00097 } 00098 00099 return _element_type->is_equivalent(*ot->_element_type); 00100 } 00101 00102 //////////////////////////////////////////////////////////////////// 00103 // Function: CPPArrayType::substitute_decl 00104 // Access: Public, Virtual 00105 // Description: 00106 //////////////////////////////////////////////////////////////////// 00107 CPPDeclaration *CPPArrayType:: 00108 substitute_decl(CPPDeclaration::SubstDecl &subst, 00109 CPPScope *current_scope, CPPScope *global_scope) { 00110 SubstDecl::const_iterator si = subst.find(this); 00111 if (si != subst.end()) { 00112 return (*si).second; 00113 } 00114 00115 CPPArrayType *rep = new CPPArrayType(*this); 00116 rep->_element_type = 00117 _element_type->substitute_decl(subst, current_scope, global_scope) 00118 ->as_type(); 00119 00120 if (_bounds != NULL) { 00121 rep->_bounds = 00122 _bounds->substitute_decl(subst, current_scope, global_scope) 00123 ->as_expression(); 00124 } 00125 00126 if (rep->_element_type == _element_type && 00127 rep->_bounds == _bounds) { 00128 delete rep; 00129 rep = this; 00130 } 00131 rep = CPPType::new_type(rep)->as_array_type(); 00132 subst.insert(SubstDecl::value_type(this, rep)); 00133 return rep; 00134 } 00135 00136 //////////////////////////////////////////////////////////////////// 00137 // Function: CPPArrayType::output 00138 // Access: Public, Virtual 00139 // Description: 00140 //////////////////////////////////////////////////////////////////// 00141 void CPPArrayType:: 00142 output(ostream &out, int indent_level, CPPScope *scope, bool complete) const { 00143 /* 00144 _element_type->output(out, indent_level, scope, complete); 00145 out << "["; 00146 if (_bounds != NULL) { 00147 out << *_bounds; 00148 } 00149 out << "]"; 00150 */ 00151 output_instance(out, indent_level, scope, complete, "", ""); 00152 } 00153 00154 //////////////////////////////////////////////////////////////////// 00155 // Function: CPPArrayType::output_instance 00156 // Access: Public, Virtual 00157 // Description: Formats a C++-looking line that defines an instance 00158 // of the given type, with the indicated name. In most 00159 // cases this will be "type name", but some types have 00160 // special exceptions. 00161 //////////////////////////////////////////////////////////////////// 00162 void CPPArrayType:: 00163 output_instance(ostream &out, int indent_level, CPPScope *scope, 00164 bool complete, const string &prename, 00165 const string &name) const { 00166 ostringstream brackets; 00167 brackets << "["; 00168 if (_bounds != NULL) { 00169 brackets << *_bounds; 00170 } 00171 brackets << "]"; 00172 string bracketsstr = brackets.str(); 00173 00174 _element_type->output_instance(out, indent_level, scope, complete, 00175 prename, name + bracketsstr); 00176 } 00177 00178 //////////////////////////////////////////////////////////////////// 00179 // Function: CPPArrayType::get_subtype 00180 // Access: Public, Virtual 00181 // Description: 00182 //////////////////////////////////////////////////////////////////// 00183 CPPDeclaration::SubType CPPArrayType:: 00184 get_subtype() const { 00185 return ST_array; 00186 } 00187 00188 //////////////////////////////////////////////////////////////////// 00189 // Function: CPPArrayType::as_array_type 00190 // Access: Public, Virtual 00191 // Description: 00192 //////////////////////////////////////////////////////////////////// 00193 CPPArrayType *CPPArrayType:: 00194 as_array_type() { 00195 return this; 00196 } 00197 00198 //////////////////////////////////////////////////////////////////// 00199 // Function: CPPArrayType::is_equal 00200 // Access: Protected, Virtual 00201 // Description: Called by CPPDeclaration() to determine whether this type is 00202 // equivalent to another type of the same type. 00203 //////////////////////////////////////////////////////////////////// 00204 bool CPPArrayType:: 00205 is_equal(const CPPDeclaration *other) const { 00206 const CPPArrayType *ot = ((CPPDeclaration *)other)->as_array_type(); 00207 assert(ot != NULL); 00208 00209 if (_bounds != NULL && ot->_bounds != NULL) { 00210 if (*_bounds != *ot->_bounds) { 00211 return false; 00212 } 00213 } else if (_bounds == NULL || ot->_bounds == NULL) { 00214 return false; 00215 } 00216 00217 return _element_type == ot->_element_type; 00218 } 00219 00220 00221 //////////////////////////////////////////////////////////////////// 00222 // Function: CPPArrayType::is_less 00223 // Access: Protected, Virtual 00224 // Description: Called by CPPDeclaration() to determine whether this type 00225 // should be ordered before another type of the same 00226 // type, in an arbitrary but fixed ordering. 00227 //////////////////////////////////////////////////////////////////// 00228 bool CPPArrayType:: 00229 is_less(const CPPDeclaration *other) const { 00230 const CPPArrayType *ot = ((CPPDeclaration *)other)->as_array_type(); 00231 assert(ot != NULL); 00232 00233 if (_bounds != NULL && ot->_bounds != NULL) { 00234 if (*_bounds != *ot->_bounds) { 00235 return *_bounds < *ot->_bounds; 00236 } 00237 } else if (_bounds == NULL || ot->_bounds == NULL) { 00238 return _bounds < ot->_bounds; 00239 } 00240 00241 return _element_type < ot->_element_type; 00242 } 00243