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

dtool/src/cppparser/cppFunctionType.cxx

Go to the documentation of this file.
00001 // Filename: cppFunctionType.cxx
00002 // Created by:  drose (21Oct99)
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 "cppFunctionType.h"
00021 #include "cppParameterList.h"
00022 #include "cppSimpleType.h"
00023 #include "cppInstance.h"
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //     Function: CPPFunctionType::Constructor
00027 //       Access: Public
00028 //  Description:
00029 ////////////////////////////////////////////////////////////////////
00030 CPPFunctionType::
00031 CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,
00032                 int flags) :
00033   CPPType(CPPFile()),
00034   _return_type(return_type),
00035   _parameters(parameters),
00036   _flags(flags)
00037 {
00038   _class_owner = NULL;
00039 
00040   // If the parameter list contains just the token "void", it means no
00041   // parameters.
00042   if (_parameters->_parameters.size() == 1 &&
00043       _parameters->_parameters.front()->_type->as_simple_type() != NULL &&
00044       _parameters->_parameters.front()->_type->as_simple_type()->_type ==
00045       CPPSimpleType::T_void &&
00046       _parameters->_parameters.front()->_ident == NULL) {
00047     _parameters->_parameters.clear();
00048   }
00049 }
00050 
00051 ////////////////////////////////////////////////////////////////////
00052 //     Function: CPPFunctionType::Copy Constructor
00053 //       Access: Public
00054 //  Description:
00055 ////////////////////////////////////////////////////////////////////
00056 CPPFunctionType::
00057 CPPFunctionType(const CPPFunctionType &copy) :
00058   CPPType(copy),
00059   _return_type(copy._return_type),
00060   _parameters(copy._parameters),
00061   _flags(copy._flags),
00062   _class_owner(copy._class_owner)
00063 {
00064 }
00065 
00066 ////////////////////////////////////////////////////////////////////
00067 //     Function: CPPFunctionType::Copy Assignment Operator
00068 //       Access: Public
00069 //  Description:
00070 ////////////////////////////////////////////////////////////////////
00071 void CPPFunctionType::
00072 operator = (const CPPFunctionType &copy) {
00073   CPPType::operator = (copy);
00074   _return_type = copy._return_type;
00075   _parameters = copy._parameters;
00076   _flags = copy._flags;
00077   _class_owner = copy._class_owner;
00078 }
00079 
00080 ////////////////////////////////////////////////////////////////////
00081 //     Function: CPPFunctionType::is_fully_specified
00082 //       Access: Public, Virtual
00083 //  Description: Returns true if this declaration is an actual,
00084 //               factual declaration, or false if some part of the
00085 //               declaration depends on a template parameter which has
00086 //               not yet been instantiated.
00087 ////////////////////////////////////////////////////////////////////
00088 bool CPPFunctionType::
00089 is_fully_specified() const {
00090   return CPPType::is_fully_specified() &&
00091     _return_type->is_fully_specified() &&
00092     _parameters->is_fully_specified();
00093 }
00094 
00095 ////////////////////////////////////////////////////////////////////
00096 //     Function: CPPFunctionType::substitute_decl
00097 //       Access: Public, Virtual
00098 //  Description:
00099 ////////////////////////////////////////////////////////////////////
00100 CPPDeclaration *CPPFunctionType::
00101 substitute_decl(CPPDeclaration::SubstDecl &subst,
00102                 CPPScope *current_scope, CPPScope *global_scope) {
00103   SubstDecl::const_iterator si = subst.find(this);
00104   if (si != subst.end()) {
00105     return (*si).second;
00106   }
00107 
00108   CPPFunctionType *rep = new CPPFunctionType(*this);
00109   rep->_return_type =
00110     _return_type->substitute_decl(subst, current_scope, global_scope)
00111     ->as_type();
00112 
00113   rep->_parameters =
00114     _parameters->substitute_decl(subst, current_scope, global_scope);
00115 
00116   if (rep->_return_type == _return_type &&
00117       rep->_parameters == _parameters) {
00118     delete rep;
00119     rep = this;
00120   }
00121   rep = CPPType::new_type(rep)->as_function_type();
00122 
00123   subst.insert(SubstDecl::value_type(this, rep));
00124   return rep;
00125 }
00126 
00127 ////////////////////////////////////////////////////////////////////
00128 //     Function: CPPFunctionType::resolve_type
00129 //       Access: Public, Virtual
00130 //  Description: If this CPPType object is a forward reference or
00131 //               other nonspecified reference to a type that might now
00132 //               be known a real type, returns the real type.
00133 //               Otherwise returns the type itself.
00134 ////////////////////////////////////////////////////////////////////
00135 CPPType *CPPFunctionType::
00136 resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
00137   CPPType *rtype = _return_type->resolve_type(current_scope, global_scope);
00138   CPPParameterList *params =
00139     _parameters->resolve_type(current_scope, global_scope);
00140 
00141   if (rtype != _return_type || params != _parameters) {
00142     CPPFunctionType *rep = new CPPFunctionType(*this);
00143     rep->_return_type = rtype;
00144     rep->_parameters = params;
00145     return CPPType::new_type(rep);
00146   }
00147   return this;
00148 }
00149 
00150 ////////////////////////////////////////////////////////////////////
00151 //     Function: CPPFunctionType::is_tbd
00152 //       Access: Public, Virtual
00153 //  Description: Returns true if the type, or any nested type within
00154 //               the type, is a CPPTBDType and thus isn't fully
00155 //               determined right now.  In this case, calling
00156 //               resolve_type() may or may not resolve the type.
00157 ////////////////////////////////////////////////////////////////////
00158 bool CPPFunctionType::
00159 is_tbd() const {
00160   if (_return_type->is_tbd()) {
00161     return true;
00162   }
00163   return _parameters->is_tbd();
00164 }
00165 
00166 ////////////////////////////////////////////////////////////////////
00167 //     Function: CPPFunctionType::output
00168 //       Access: Public, Virtual
00169 //  Description:
00170 ////////////////////////////////////////////////////////////////////
00171 void CPPFunctionType::
00172 output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
00173   output(out, indent_level, scope, complete, -1);
00174 }
00175 
00176 ////////////////////////////////////////////////////////////////////
00177 //     Function: CPPFunctionType::output
00178 //       Access: Public
00179 //  Description: The additional parameter allows us to specify the
00180 //               number of parameters we wish to show the default
00181 //               values for.  If num_default_parameters is >= 0, it
00182 //               indicates the number of default parameter values to
00183 //               show on output.  Otherwise, all parameter values are
00184 //               shown.
00185 ////////////////////////////////////////////////////////////////////
00186 void CPPFunctionType::
00187 output(ostream &out, int indent_level, CPPScope *scope, bool complete,
00188        int num_default_parameters) const {
00189   _return_type->output(out, indent_level, scope, complete);
00190   out << "(";
00191   _parameters->output(out, scope, true, num_default_parameters);
00192   out << ")";
00193   if (_flags & F_const_method) {
00194     out << " const";
00195   }
00196 }
00197 
00198 ////////////////////////////////////////////////////////////////////
00199 //     Function: CPPFunctionType::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 CPPFunctionType::
00207 output_instance(ostream &out, int indent_level, CPPScope *scope,
00208                 bool complete, const string &prename,
00209                 const string &name) const {
00210   output_instance(out, indent_level, scope, complete, prename, name, -1);
00211 }
00212 
00213 ////////////////////////////////////////////////////////////////////
00214 //     Function: CPPFunctionType::output_instance
00215 //       Access: Public
00216 //  Description: The additional parameter allows us to specify the
00217 //               number of parameters we wish to show the default
00218 //               values for.  If num_default_parameters is >= 0, it
00219 //               indicates the number of default parameter values to
00220 //               show on output.  Otherwise, all parameter values are
00221 //               shown.
00222 ////////////////////////////////////////////////////////////////////
00223 void CPPFunctionType::
00224 output_instance(ostream &out, int indent_level, CPPScope *scope,
00225                 bool complete, const string &prename,
00226                 const string &name, int num_default_parameters) const {
00227   ostringstream parm_string;
00228   parm_string << "(";
00229   _parameters->output(parm_string, scope, true, num_default_parameters);
00230   parm_string << ")";
00231   string str = parm_string.str();
00232 
00233   if (_flags & (F_constructor | F_destructor)) {
00234     // No return type for constructors and destructors.
00235     out << prename << name << str;
00236 
00237   } else {
00238     if (prename.empty()) {
00239       _return_type->output_instance(out, indent_level, scope, complete,
00240                                     "", prename + name + str);
00241     } else {
00242       _return_type->output_instance(out, indent_level, scope, complete,
00243                                     "", "(" + prename + name + ")" + str);
00244     }
00245   }
00246 
00247   if (_flags & F_const_method) {
00248     out << " const";
00249   }
00250 }
00251 
00252 ////////////////////////////////////////////////////////////////////
00253 //     Function: CPPFunctionType::get_num_default_parameters
00254 //       Access: Public
00255 //  Description: Returns the number of parameters in the list that may
00256 //               take default values.
00257 ////////////////////////////////////////////////////////////////////
00258 int CPPFunctionType::
00259 get_num_default_parameters() const {
00260   // The trick is just to count, beginning from the end and working
00261   // towards the front, the number of parameters that have some
00262   // initializer.
00263 
00264   const CPPParameterList::Parameters &params = _parameters->_parameters;
00265   CPPParameterList::Parameters::const_reverse_iterator pi;
00266   int count = 0;
00267   for (pi = params.rbegin();
00268        pi != params.rend() && (*pi)->_initializer != (CPPExpression *)NULL;
00269        ++pi) {
00270     count++;
00271   }
00272 
00273   return count;
00274 }
00275 
00276 ////////////////////////////////////////////////////////////////////
00277 //     Function: CPPFunctionType::get_subtype
00278 //       Access: Public, Virtual
00279 //  Description:
00280 ////////////////////////////////////////////////////////////////////
00281 CPPDeclaration::SubType CPPFunctionType::
00282 get_subtype() const {
00283   return ST_function;
00284 }
00285 
00286 ////////////////////////////////////////////////////////////////////
00287 //     Function: CPPFunctionType::as_function_type
00288 //       Access: Public, Virtual
00289 //  Description:
00290 ////////////////////////////////////////////////////////////////////
00291 CPPFunctionType *CPPFunctionType::
00292 as_function_type() {
00293   return this;
00294 }
00295 
00296 ////////////////////////////////////////////////////////////////////
00297 //     Function: CPPFunctionType::is_equivalent_function
00298 //       Access: Public
00299 //  Description: This is similar to is_equal(), except it is more
00300 //               forgiving: it considers the functions to be
00301 //               equivalent only if the return type and the types of
00302 //               all parameters match.
00303 ////////////////////////////////////////////////////////////////////
00304 bool CPPFunctionType::
00305 is_equivalent_function(const CPPFunctionType &other) const {
00306   if (!_return_type->is_equivalent(*other._return_type)) {
00307     return false;
00308   }
00309 
00310   if (_flags != other._flags) {
00311     return false;
00312   }
00313 
00314   if (!_parameters->is_equivalent(*other._parameters)) {
00315     return false;
00316   }
00317 
00318   return true;
00319 }
00320 
00321 ////////////////////////////////////////////////////////////////////
00322 //     Function: CPPFunctionType::is_equal
00323 //       Access: Protected, Virtual
00324 //  Description: Called by CPPDeclaration() to determine whether this type is
00325 //               equivalent to another type of the same type.
00326 ////////////////////////////////////////////////////////////////////
00327 bool CPPFunctionType::
00328 is_equal(const CPPDeclaration *other) const {
00329   const CPPFunctionType *ot = ((CPPDeclaration *)other)->as_function_type();
00330   assert(ot != NULL);
00331 
00332   if (_return_type != ot->_return_type) {
00333     return false;
00334   }
00335   if (_flags != ot->_flags) {
00336     return false;
00337   }
00338   if (*_parameters != *ot->_parameters) {
00339     return false;
00340   }
00341   return true;
00342 }
00343 
00344 
00345 ////////////////////////////////////////////////////////////////////
00346 //     Function: CPPFunctionType::is_less
00347 //       Access: Protected, Virtual
00348 //  Description: Called by CPPDeclaration() to determine whether this type
00349 //               should be ordered before another type of the same
00350 //               type, in an arbitrary but fixed ordering.
00351 ////////////////////////////////////////////////////////////////////
00352 bool CPPFunctionType::
00353 is_less(const CPPDeclaration *other) const {
00354   const CPPFunctionType *ot = ((CPPDeclaration *)other)->as_function_type();
00355   assert(ot != NULL);
00356 
00357   if (_return_type != ot->_return_type) {
00358     return _return_type < ot->_return_type;
00359   }
00360   if (_flags != ot->_flags) {
00361     return _flags < ot->_flags;
00362   }
00363 
00364   return *_parameters < *ot->_parameters;
00365 }

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