00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "cppFunctionType.h"
00021 #include "cppParameterList.h"
00022 #include "cppSimpleType.h"
00023 #include "cppInstance.h"
00024
00025
00026
00027
00028
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
00041
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
00053
00054
00055
00056 CPPFunctionType::
00057 CPPFunctionType(const CPPFunctionType ©) :
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
00068
00069
00070
00071 void CPPFunctionType::
00072 operator = (const CPPFunctionType ©) {
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
00082
00083
00084
00085
00086
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
00097
00098
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
00129
00130
00131
00132
00133
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
00152
00153
00154
00155
00156
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
00168
00169
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
00178
00179
00180
00181
00182
00183
00184
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
00200
00201
00202
00203
00204
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
00215
00216
00217
00218
00219
00220
00221
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
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
00254
00255
00256
00257
00258 int CPPFunctionType::
00259 get_num_default_parameters() const {
00260
00261
00262
00263
00264 const CPPParameterList::Parameters ¶ms = _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
00278
00279
00280
00281 CPPDeclaration::SubType CPPFunctionType::
00282 get_subtype() const {
00283 return ST_function;
00284 }
00285
00286
00287
00288
00289
00290
00291 CPPFunctionType *CPPFunctionType::
00292 as_function_type() {
00293 return this;
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
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
00323
00324
00325
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
00347
00348
00349
00350
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 }