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