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

dtool/src/interrogate/typeManager.cxx

Go to the documentation of this file.
00001 // Filename: typeManager.cxx
00002 // Created by:  drose (14Aug00)
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 #include "typeManager.h"
00020 #include "interrogate.h"
00021 
00022 #include <cppFunctionType.h>
00023 #include <cppFunctionGroup.h>
00024 #include <cppParameterList.h>
00025 #include <cppConstType.h>
00026 #include <cppReferenceType.h>
00027 #include <cppPointerType.h>
00028 #include <cppSimpleType.h>
00029 #include <cppStructType.h>
00030 #include <cppTypeDeclaration.h>
00031 #include <notify.h>
00032 
00033 ////////////////////////////////////////////////////////////////////
00034 //     Function: TypeManager::resolve_type
00035 //       Access: Public, Static
00036 //  Description: A horrible hack around a CPPParser bug.  We don't
00037 //               trust the CPPType pointer we were given; instead, we
00038 //               ask CPPParser to parse a new type of the same name.
00039 //               This has a better chance of fully resolving
00040 //               templates.
00041 ////////////////////////////////////////////////////////////////////
00042 CPPType *TypeManager::
00043 resolve_type(CPPType *type, CPPScope *scope) {
00044   if (scope == (CPPScope *)NULL) {
00045     scope = &parser;
00046   }
00047 
00048   type = type->resolve_type(scope, &parser);
00049   string name = type->get_local_name(&parser);
00050   if (name.empty()) {
00051     // Don't try to resolve unnamed types.
00052     return type;
00053   }
00054 
00055   CPPType *new_type = parser.parse_type(name);
00056   if (new_type == (CPPType *)NULL) {
00057     nout << "Type " << name << " is unknown to parser.\n";
00058   } else {
00059     type = new_type->resolve_type(&parser, &parser);
00060   }
00061 
00062   return type;
00063 }
00064 
00065 ////////////////////////////////////////////////////////////////////
00066 //     Function: TypeManager::is_assignable
00067 //       Access: Public, Static
00068 //  Description: Returns true if the indicated type is something we
00069 //               can legitimately assign a value to, or false
00070 //               otherwise.
00071 ////////////////////////////////////////////////////////////////////
00072 bool TypeManager::
00073 is_assignable(CPPType *type) {
00074   switch (type->get_subtype()) {
00075   case CPPDeclaration::ST_const:
00076   case CPPDeclaration::ST_reference:
00077   case CPPDeclaration::ST_extension:
00078     return false;
00079 
00080   case CPPDeclaration::ST_struct:
00081     // In many cases, this is assignable, but there are some bizarre
00082     // cases where it is not.  Particularly in the event that the
00083     // programmer has defined a private copy assignment operator for
00084     // the class or struct.
00085 
00086     // We could try to figure out whether this has happened, but screw
00087     // it.  Concrete structure objects are not assignable, and so they
00088     // don't get setters synthesized for them.  If you want a setter,
00089     // write it yourself.
00090 
00091     // We'll make an exception for basic_string<char>, however, since
00092     // this is nearly an atomic type.
00093     if (is_basic_string_char(type)) {
00094       return true;
00095     }
00096 
00097     return false;
00098 
00099   default:
00100     return true;
00101   }
00102 }
00103 
00104 ////////////////////////////////////////////////////////////////////
00105 //     Function: TypeManager::is_reference
00106 //       Access: Public, Static
00107 //  Description: Returns true if the indicated type is some kind of a
00108 //               reference or const reference type to something
00109 //               useful, false otherwise.
00110 ////////////////////////////////////////////////////////////////////
00111 bool TypeManager::
00112 is_reference(CPPType *type) {
00113   switch (type->get_subtype()) {
00114   case CPPDeclaration::ST_const:
00115     return is_reference(type->as_const_type()->_wrapped_around);
00116 
00117   case CPPDeclaration::ST_reference:
00118     return is_pointable(type->as_reference_type()->_pointing_at);
00119 
00120   default:
00121     return false;
00122   }
00123 }
00124 
00125 ////////////////////////////////////////////////////////////////////
00126 //     Function: TypeManager::is_ref_to_anything
00127 //       Access: Public, Static
00128 //  Description: Returns true if the indicated type is some kind of a
00129 //               reference or const reference type at all, false
00130 //               otherwise.
00131 ////////////////////////////////////////////////////////////////////
00132 bool TypeManager::
00133 is_ref_to_anything(CPPType *type) {
00134   switch (type->get_subtype()) {
00135   case CPPDeclaration::ST_const:
00136     return is_ref_to_anything(type->as_const_type()->_wrapped_around);
00137 
00138   case CPPDeclaration::ST_reference:
00139     return true;
00140 
00141   default:
00142     return false;
00143   }
00144 }
00145 
00146 ////////////////////////////////////////////////////////////////////
00147 //     Function: TypeManager::is_const_ref_to_anything
00148 //       Access: Public, Static
00149 //  Description: Returns true if the indicated type is a const
00150 //               reference to something, false otherwise.
00151 ////////////////////////////////////////////////////////////////////
00152 bool TypeManager::
00153 is_const_ref_to_anything(CPPType *type) {
00154   switch (type->get_subtype()) {
00155   case CPPDeclaration::ST_const:
00156     return is_const_ref_to_anything(type->as_const_type()->_wrapped_around);
00157 
00158   case CPPDeclaration::ST_reference:
00159     return is_const(type->as_reference_type()->_pointing_at);
00160 
00161   default:
00162     return false;
00163   }
00164 }
00165 
00166 ////////////////////////////////////////////////////////////////////
00167 //     Function: TypeManager::is_pointer
00168 //       Access: Public, Static
00169 //  Description: Returns true if the indicated type is some kind of a
00170 //               pointer or const pointer type, false otherwise.
00171 ////////////////////////////////////////////////////////////////////
00172 bool TypeManager::
00173 is_pointer(CPPType *type) {
00174   switch (type->get_subtype()) {
00175   case CPPDeclaration::ST_const:
00176     return is_pointer(type->as_const_type()->_wrapped_around);
00177 
00178   case CPPDeclaration::ST_pointer:
00179     return is_pointable(type->as_pointer_type()->_pointing_at);
00180 
00181   default:
00182     return false;
00183   }
00184 }
00185 
00186 ////////////////////////////////////////////////////////////////////
00187 //     Function: TypeManager::is_const
00188 //       Access: Public, Static
00189 //  Description: Returns true if the indicated type is some kind of a
00190 //               const type, false otherwise.
00191 ////////////////////////////////////////////////////////////////////
00192 bool TypeManager::
00193 is_const(CPPType *type) {
00194   switch (type->get_subtype()) {
00195   case CPPDeclaration::ST_const:
00196     return true;
00197 
00198   default:
00199     return false;
00200   }
00201 }
00202 
00203 ////////////////////////////////////////////////////////////////////
00204 //     Function: TypeManager::is_struct
00205 //       Access: Public, Static
00206 //  Description: Returns true if the indicated type is a concrete
00207 //               struct, class, or union type, or false otherwise.
00208 ////////////////////////////////////////////////////////////////////
00209 bool TypeManager::
00210 is_struct(CPPType *type) {
00211   switch (type->get_subtype()) {
00212   case CPPDeclaration::ST_const:
00213     return is_struct(type->as_const_type()->_wrapped_around);
00214 
00215   case CPPDeclaration::ST_struct:
00216   case CPPDeclaration::ST_extension:
00217     return true;
00218 
00219   default:
00220     return false;
00221   }
00222 }
00223 
00224 ////////////////////////////////////////////////////////////////////
00225 //     Function: TypeManager::is_enum
00226 //       Access: Public, Static
00227 //  Description: Returns true if the indicated type is some kind of
00228 //               enumerated type, const or otherwise.
00229 ////////////////////////////////////////////////////////////////////
00230 bool TypeManager::
00231 is_enum(CPPType *type) {
00232   switch (type->get_subtype()) {
00233   case CPPDeclaration::ST_enum:
00234     return true;
00235 
00236   case CPPDeclaration::ST_const:
00237     return is_enum(type->as_const_type()->_wrapped_around);
00238 
00239   default:
00240     return false;
00241   }
00242 }
00243 
00244 ////////////////////////////////////////////////////////////////////
00245 //     Function: TypeManager::is_const_enum
00246 //       Access: Public, Static
00247 //  Description: Returns true if the indicated type is a const
00248 //               enumerated type.
00249 ////////////////////////////////////////////////////////////////////
00250 bool TypeManager::
00251 is_const_enum(CPPType *type) {
00252   switch (type->get_subtype()) {
00253   case CPPDeclaration::ST_const:
00254     return is_enum(type->as_const_type()->_wrapped_around);
00255 
00256   default:
00257     return false;
00258   }
00259 }
00260 
00261 ////////////////////////////////////////////////////////////////////
00262 //     Function: TypeManager::is_const_ref_to_enum
00263 //       Access: Public, Static
00264 //  Description: Returns true if the indicated type is a const
00265 //               reference to an enumerated type.
00266 ////////////////////////////////////////////////////////////////////
00267 bool TypeManager::
00268 is_const_ref_to_enum(CPPType *type) {
00269   switch (type->get_subtype()) {
00270   case CPPDeclaration::ST_reference:
00271     return is_const_enum(type->as_reference_type()->_pointing_at);
00272 
00273   default:
00274     return false;
00275   }
00276 }
00277 
00278 ////////////////////////////////////////////////////////////////////
00279 //     Function: TypeManager::is_simple
00280 //       Access: Public, Static
00281 //  Description: Returns true if the indicated type is something that
00282 //               a scripting language can handle directly as a
00283 //               concrete, like an int or float, either const or
00284 //               non-const.
00285 ////////////////////////////////////////////////////////////////////
00286 bool TypeManager::
00287 is_simple(CPPType *type) {
00288   switch (type->get_subtype()) {
00289   case CPPDeclaration::ST_simple:
00290   case CPPDeclaration::ST_enum:
00291     return true;
00292 
00293   case CPPDeclaration::ST_const:
00294     return is_simple(type->as_const_type()->_wrapped_around);
00295 
00296   default:
00297     return false;
00298   }
00299 }
00300 
00301 ////////////////////////////////////////////////////////////////////
00302 //     Function: TypeManager::is_const_simple
00303 //       Access: Public, Static
00304 //  Description: Returns true if the indicated type is a const wrapper
00305 //               around some simple type like int.
00306 ////////////////////////////////////////////////////////////////////
00307 bool TypeManager::
00308 is_const_simple(CPPType *type) {
00309   switch (type->get_subtype()) {
00310   case CPPDeclaration::ST_const:
00311     return is_simple(type->as_const_type()->_wrapped_around);
00312 
00313   default:
00314     return false;
00315   }
00316 }
00317 
00318 ////////////////////////////////////////////////////////////////////
00319 //     Function: TypeManager::is_const_ref_to_simple
00320 //       Access: Public, Static
00321 //  Description: Returns true if the indicated type is a const
00322 //               reference to something that a scripting language can
00323 //               handle directly as a concrete.
00324 ////////////////////////////////////////////////////////////////////
00325 bool TypeManager::
00326 is_const_ref_to_simple(CPPType *type) {
00327   switch (type->get_subtype()) {
00328   case CPPDeclaration::ST_reference:
00329     return is_const_simple(type->as_reference_type()->_pointing_at);
00330 
00331   default:
00332     return false;
00333   }
00334 }
00335 
00336 ////////////////////////////////////////////////////////////////////
00337 //     Function: TypeManager::is_pointable
00338 //       Access: Public, Static
00339 //  Description: Returns true if the indicated type is something
00340 //               ordinary that a scripting language can handle a
00341 //               pointer to, e.g. a class or a structure, but not an
00342 //               int or a function.
00343 ////////////////////////////////////////////////////////////////////
00344 bool TypeManager::
00345 is_pointable(CPPType *type) {
00346   switch (type->get_subtype()) {
00347   case CPPDeclaration::ST_const:
00348     return is_pointable(type->as_const_type()->_wrapped_around);
00349 
00350   case CPPDeclaration::ST_extension:
00351     return (type->as_extension_type()->_type != CPPExtensionType::T_enum);
00352 
00353   case CPPDeclaration::ST_struct:
00354     return true;
00355 
00356   case CPPDeclaration::ST_simple:
00357     return is_char(type);
00358 
00359   default:
00360     return false;
00361   }
00362 }
00363 
00364 ////////////////////////////////////////////////////////////////////
00365 //     Function: TypeManager::is_char
00366 //       Access: Public, Static
00367 //  Description: Returns true if the indicated type is char or const
00368 //               char, but not signed or unsigned char.
00369 ////////////////////////////////////////////////////////////////////
00370 bool TypeManager::
00371 is_char(CPPType *type) {
00372   switch (type->get_subtype()) {
00373   case CPPDeclaration::ST_const:
00374     return is_char(type->as_const_type()->_wrapped_around);
00375 
00376   case CPPDeclaration::ST_simple:
00377     {
00378       CPPSimpleType *simple_type = type->as_simple_type();
00379       if (simple_type != (CPPSimpleType *)NULL) {
00380         return
00381           simple_type->_type == CPPSimpleType::T_char &&
00382           simple_type->_flags == 0;
00383       }
00384     }
00385 
00386   default:
00387     break;
00388   }
00389 
00390   return false;
00391 }
00392 
00393 ////////////////////////////////////////////////////////////////////
00394 //     Function: TypeManager::is_char_pointer
00395 //       Access: Public, Static
00396 //  Description: Returns true if the indicated type is char * or const
00397 //               char * or some such.
00398 ////////////////////////////////////////////////////////////////////
00399 bool TypeManager::
00400 is_char_pointer(CPPType *type) {
00401   switch (type->get_subtype()) {
00402   case CPPDeclaration::ST_const:
00403     return is_char_pointer(type->as_const_type()->_wrapped_around);
00404 
00405   case CPPDeclaration::ST_pointer:
00406     return is_char(type->as_pointer_type()->_pointing_at);
00407 
00408   default:
00409     return false;
00410   }
00411 }
00412 
00413 ////////////////////////////////////////////////////////////////////
00414 //     Function: TypeManager::is_basic_string_char
00415 //       Access: Public, Static
00416 //  Description: Returns true if the type is basic_string<char>.  This
00417 //               is the standard C++ string class.
00418 ////////////////////////////////////////////////////////////////////
00419 bool TypeManager::
00420 is_basic_string_char(CPPType *type) {
00421   CPPType *string_type = get_basic_string_char_type();
00422   if (string_type != (CPPType *)NULL &&
00423       string_type->get_local_name(&parser) == type->get_local_name(&parser)) {
00424     return true;
00425   }
00426 
00427   switch (type->get_subtype()) {
00428   case CPPDeclaration::ST_const:
00429     return is_basic_string_char(type->as_const_type()->_wrapped_around);
00430 
00431   default:
00432     break;
00433   }
00434 
00435   return false;
00436 }
00437 
00438 ////////////////////////////////////////////////////////////////////
00439 //     Function: TypeManager::is_const_basic_string_char
00440 //       Access: Public, Static
00441 //  Description: Returns true if the indicated type is a const wrapper
00442 //               around basic_string<char>.
00443 ////////////////////////////////////////////////////////////////////
00444 bool TypeManager::
00445 is_const_basic_string_char(CPPType *type) {
00446   switch (type->get_subtype()) {
00447   case CPPDeclaration::ST_const:
00448     return is_basic_string_char(type->as_const_type()->_wrapped_around);
00449 
00450   default:
00451     return false;
00452   }
00453 }
00454 
00455 ////////////////////////////////////////////////////////////////////
00456 //     Function: TypeManager::is_const_ref_to_basic_string_char
00457 //       Access: Public, Static
00458 //  Description: Returns true if the indicated type is a const
00459 //               reference to basic_string<char>.
00460 ////////////////////////////////////////////////////////////////////
00461 bool TypeManager::
00462 is_const_ref_to_basic_string_char(CPPType *type) {
00463   switch (type->get_subtype()) {
00464   case CPPDeclaration::ST_reference:
00465     return is_const_basic_string_char(type->as_reference_type()->_pointing_at);
00466 
00467   default:
00468     return false;
00469   }
00470 }
00471 
00472 ////////////////////////////////////////////////////////////////////
00473 //     Function: TypeManager::is_bool
00474 //       Access: Public, Static
00475 //  Description: Returns true if the indicated type is bool, or some
00476 //               trivial variant.
00477 ////////////////////////////////////////////////////////////////////
00478 bool TypeManager::
00479 is_bool(CPPType *type) {
00480   switch (type->get_subtype()) {
00481   case CPPDeclaration::ST_const:
00482     return is_bool(type->as_const_type()->_wrapped_around);
00483 
00484   case CPPDeclaration::ST_simple:
00485     {
00486       CPPSimpleType *simple_type = type->as_simple_type();
00487       if (simple_type != (CPPSimpleType *)NULL) {
00488         return
00489           simple_type->_type == CPPSimpleType::T_bool;
00490       }
00491     }
00492 
00493   default:
00494     break;
00495   }
00496 
00497   return false;
00498 }
00499 
00500 ////////////////////////////////////////////////////////////////////
00501 //     Function: TypeManager::is_integer
00502 //       Access: Public, Static
00503 //  Description: Returns true if the indicated type is one of the
00504 //               basic integer types: bool, char, short, int, or long,
00505 //               signed or unsigned, as well as enumerated types.
00506 ////////////////////////////////////////////////////////////////////
00507 bool TypeManager::
00508 is_integer(CPPType *type) {
00509   switch (type->get_subtype()) {
00510   case CPPDeclaration::ST_const:
00511     return is_integer(type->as_const_type()->_wrapped_around);
00512 
00513   case CPPDeclaration::ST_enum:
00514     return true;
00515 
00516   case CPPDeclaration::ST_simple:
00517     {
00518       CPPSimpleType *simple_type = type->as_simple_type();
00519       if (simple_type != (CPPSimpleType *)NULL) {
00520         return
00521           (simple_type->_type == CPPSimpleType::T_bool ||
00522            simple_type->_type == CPPSimpleType::T_char ||
00523            simple_type->_type == CPPSimpleType::T_int);
00524       }
00525     }
00526 
00527   default:
00528     break;
00529   }
00530 
00531   return false;
00532 }
00533 
00534 ////////////////////////////////////////////////////////////////////
00535 //     Function: TypeManager::is_float
00536 //       Access: Public, Static
00537 //  Description: Returns true if the indicated type is one of the
00538 //               basic floating-point types: float, double, or some
00539 //               similar variant.
00540 ////////////////////////////////////////////////////////////////////
00541 bool TypeManager::
00542 is_float(CPPType *type) {
00543   switch (type->get_subtype()) {
00544   case CPPDeclaration::ST_const:
00545     return is_float(type->as_const_type()->_wrapped_around);
00546 
00547   case CPPDeclaration::ST_simple:
00548     {
00549       CPPSimpleType *simple_type = type->as_simple_type();
00550       if (simple_type != (CPPSimpleType *)NULL) {
00551         return
00552           (simple_type->_type == CPPSimpleType::T_float ||
00553            simple_type->_type == CPPSimpleType::T_double);
00554       }
00555     }
00556 
00557   default:
00558     break;
00559   }
00560 
00561   return false;
00562 }
00563 
00564 ////////////////////////////////////////////////////////////////////
00565 //     Function: TypeManager::is_void
00566 //       Access: Public, Static
00567 //  Description: Returns true if the indicated type is void.  (Not
00568 //               void *, just void.)
00569 ////////////////////////////////////////////////////////////////////
00570 bool TypeManager::
00571 is_void(CPPType *type) {
00572   CPPSimpleType *simple_type = type->as_simple_type();
00573   if (simple_type != (CPPSimpleType *)NULL) {
00574     return
00575       simple_type->_type == CPPSimpleType::T_void &&
00576       simple_type->_flags == 0;
00577   }
00578 
00579   return false;
00580 }
00581 
00582 ////////////////////////////////////////////////////////////////////
00583 //     Function: TypeManager::is_reference_count
00584 //       Access: Public, Static
00585 //  Description: Returns true if the indicated type is some class that
00586 //               derives from ReferenceCount, or false otherwise.
00587 ////////////////////////////////////////////////////////////////////
00588 bool TypeManager::
00589 is_reference_count(CPPType *type) {
00590   CPPType *refcount_type = get_reference_count_type();
00591   if (refcount_type != (CPPType *)NULL &&
00592       refcount_type->get_local_name(&parser) == type->get_local_name(&parser)) {
00593     return true;
00594   }
00595 
00596   switch (type->get_subtype()) {
00597   case CPPDeclaration::ST_const:
00598     return is_reference_count(type->as_const_type()->_wrapped_around);
00599 
00600   case CPPDeclaration::ST_struct:
00601     {
00602       CPPStructType *stype = type->as_struct_type();
00603       CPPStructType::Derivation::const_iterator di;
00604       for (di = stype->_derivation.begin();
00605            di != stype->_derivation.end();
00606            ++di) {
00607         if (is_reference_count((*di)._base)) {
00608           return true;
00609         }
00610       }
00611     }
00612 
00613   default:
00614     return false;
00615   }
00616 }
00617 
00618 ////////////////////////////////////////////////////////////////////
00619 //     Function: TypeManager::is_reference_count_pointer
00620 //       Access: Public, Static
00621 //  Description: Returns true if the indicated type is a pointer to a
00622 //               class that derives from ReferenceCount.
00623 ////////////////////////////////////////////////////////////////////
00624 bool TypeManager::
00625 is_reference_count_pointer(CPPType *type) {
00626   switch (type->get_subtype()) {
00627   case CPPDeclaration::ST_const:
00628     return is_reference_count_pointer(type->as_const_type()->_wrapped_around);
00629 
00630   case CPPDeclaration::ST_pointer:
00631     return is_reference_count(type->as_pointer_type()->_pointing_at);
00632 
00633   default:
00634     return false;
00635   }
00636 }
00637 
00638 ////////////////////////////////////////////////////////////////////
00639 //     Function: TypeManager::is_pointer_to_base
00640 //       Access: Public, Static
00641 //  Description: Returns true if the indicated type is some class that
00642 //               derives from PointerToBase, or false otherwise.
00643 ////////////////////////////////////////////////////////////////////
00644 bool TypeManager::
00645 is_pointer_to_base(CPPType *type) {
00646   // We only check the simple name of the type against PointerToBase,
00647   // since we need to allow for the various template instantiations of
00648   // this thing.
00649 
00650   // We also check explicitly for "PointerTo" and "ConstPointerTo",
00651   // instead of actually checking for PointerToBase, because we don't
00652   // want to consider PointerToArray in this category.
00653   if (type->get_simple_name() == "PointerTo" ||
00654       type->get_simple_name() == "ConstPointerTo") {
00655     return true;
00656   }
00657 
00658   switch (type->get_subtype()) {
00659   case CPPDeclaration::ST_const:
00660     return is_pointer_to_base(type->as_const_type()->_wrapped_around);
00661 
00662   case CPPDeclaration::ST_struct:
00663     {
00664       CPPStructType *stype = type->as_struct_type();
00665       CPPStructType::Derivation::const_iterator di;
00666       for (di = stype->_derivation.begin();
00667            di != stype->_derivation.end();
00668            ++di) {
00669         if (is_pointer_to_base((*di)._base)) {
00670           return true;
00671         }
00672       }
00673     }
00674 
00675   default:
00676     return false;
00677   }
00678 }
00679 
00680 ////////////////////////////////////////////////////////////////////
00681 //     Function: TypeManager::is_const_pointer_to_base
00682 //       Access: Public, Static
00683 //  Description: Returns true if the indicated type is a const
00684 //               PointerToBase or some derivative.
00685 ////////////////////////////////////////////////////////////////////
00686 bool TypeManager::
00687 is_const_pointer_to_base(CPPType *type) {
00688   switch (type->get_subtype()) {
00689   case CPPDeclaration::ST_const:
00690     return is_pointer_to_base(type->as_const_type()->_wrapped_around);
00691 
00692   default:
00693     return false;
00694   }
00695 }
00696 
00697 ////////////////////////////////////////////////////////////////////
00698 //     Function: TypeManager::is_const_ref_to_pointer_to_base
00699 //       Access: Public, Static
00700 //  Description: Returns true if the indicated type is a const
00701 //               reference to a class that derives from PointerToBase.
00702 ////////////////////////////////////////////////////////////////////
00703 bool TypeManager::
00704 is_const_ref_to_pointer_to_base(CPPType *type) {
00705   switch (type->get_subtype()) {
00706   case CPPDeclaration::ST_const:
00707     return is_reference(type->as_const_type()->_wrapped_around);
00708 
00709   case CPPDeclaration::ST_reference:
00710     return is_const_pointer_to_base(type->as_reference_type()->_pointing_at);
00711 
00712   default:
00713     return false;
00714   }
00715 }
00716 
00717 ////////////////////////////////////////////////////////////////////
00718 //     Function: TypeManager::involves_unpublished
00719 //       Access: Public, Static
00720 //  Description: Returns true if the type is an unpublished type,
00721 //               e.g. a protected or private nested class, or simply a
00722 //               type not marked as 'published', or if the type is a
00723 //               pointer or reference to such an unpublished type, or
00724 //               even if the type is a function type that includes a
00725 //               parameter of such an unpublished type.
00726 ////////////////////////////////////////////////////////////////////
00727 bool TypeManager::
00728 involves_unpublished(CPPType *type) {
00729   switch (type->get_subtype()) {
00730   case CPPDeclaration::ST_const:
00731     return involves_unpublished(type->as_const_type()->_wrapped_around);
00732 
00733   case CPPDeclaration::ST_reference:
00734     return involves_unpublished(type->as_reference_type()->_pointing_at);
00735 
00736   case CPPDeclaration::ST_pointer:
00737     return involves_unpublished(type->as_pointer_type()->_pointing_at);
00738 
00739   case CPPDeclaration::ST_struct:
00740     // A struct type is unpublished only if all of its members are
00741     // unpublished.
00742     if (type->_declaration != (CPPTypeDeclaration *)NULL) {
00743       if (type->_declaration->_vis <= min_vis) {
00744         return false;
00745       }
00746     }
00747     {
00748       CPPScope *scope = type->as_struct_type()->_scope;
00749 
00750       bool any_exported = false;
00751       CPPScope::Declarations::const_iterator di;
00752       for (di = scope->_declarations.begin();
00753            di != scope->_declarations.end() && !any_exported;
00754            ++di) {
00755         if ((*di)->_vis <= min_vis) {
00756           any_exported = true;
00757         }
00758       }
00759 
00760       return !any_exported;
00761     }
00762 
00763   case CPPDeclaration::ST_function:
00764     if (type->_declaration != (CPPTypeDeclaration *)NULL) {
00765       if (type->_declaration->_vis <= min_vis) {
00766         return false;
00767       }
00768     }
00769     return true;
00770     /*
00771     {
00772       CPPFunctionType *ftype = type->as_function_type();
00773       if (involves_unpublished(ftype->_return_type)) {
00774         return true;
00775       }
00776       const CPPParameterList::Parameters &params =
00777         ftype->_parameters->_parameters;
00778       CPPParameterList::Parameters::const_iterator pi;
00779       for (pi = params.begin(); pi != params.end(); ++pi) {
00780         if (involves_unpublished((*pi)->_type)) {
00781           return true;
00782         }
00783       }
00784       return false;
00785     }
00786     */
00787 
00788   default:
00789     if (type->_declaration != (CPPTypeDeclaration *)NULL) {
00790       return (type->_declaration->_vis > min_vis);
00791     }
00792     return false;
00793   }
00794 }
00795 
00796 ////////////////////////////////////////////////////////////////////
00797 //     Function: TypeManager::involves_protected
00798 //       Access: Public, Static
00799 //  Description: Returns true if the type is an protected type,
00800 //               e.g. a protected or private nested class, or if the
00801 //               type is a pointer or reference to such a protected
00802 //               type, or even if the type is a function type that
00803 //               includes a parameter of such a protected type.
00804 ////////////////////////////////////////////////////////////////////
00805 bool TypeManager::
00806 involves_protected(CPPType *type) {
00807   switch (type->get_subtype()) {
00808   case CPPDeclaration::ST_const:
00809     return involves_protected(type->as_const_type()->_wrapped_around);
00810 
00811   case CPPDeclaration::ST_reference:
00812     return involves_protected(type->as_reference_type()->_pointing_at);
00813 
00814   case CPPDeclaration::ST_pointer:
00815     return involves_protected(type->as_pointer_type()->_pointing_at);
00816 
00817   case CPPDeclaration::ST_function:
00818     {
00819       CPPFunctionType *ftype = type->as_function_type();
00820       if (involves_protected(ftype->_return_type)) {
00821         return true;
00822       }
00823       const CPPParameterList::Parameters &params =
00824         ftype->_parameters->_parameters;
00825       CPPParameterList::Parameters::const_iterator pi;
00826       for (pi = params.begin(); pi != params.end(); ++pi) {
00827         if (involves_protected((*pi)->_type)) {
00828           return true;
00829         }
00830       }
00831       return false;
00832     }
00833 
00834   default:
00835     if (type->_declaration != (CPPTypeDeclaration *)NULL) {
00836       return (type->_declaration->_vis > V_public);
00837     }
00838     return false;
00839   }
00840 }
00841 
00842 ////////////////////////////////////////////////////////////////////
00843 //     Function: TypeManager::unwrap_pointer
00844 //       Access: Public, Static
00845 //  Description: Returns the type this pointer type points to.
00846 ////////////////////////////////////////////////////////////////////
00847 CPPType *TypeManager::
00848 unwrap_pointer(CPPType *source_type) {
00849   switch (source_type->get_subtype()) {
00850   case CPPDeclaration::ST_const:
00851     return unwrap_pointer(source_type->as_const_type()->_wrapped_around);
00852 
00853   case CPPDeclaration::ST_pointer:
00854     return source_type->as_pointer_type()->_pointing_at;
00855 
00856   default:
00857     return source_type;
00858   }
00859 }
00860 
00861 ////////////////////////////////////////////////////////////////////
00862 //     Function: TypeManager::unwrap_reference
00863 //       Access: Public, Static
00864 //  Description: Returns the type this reference type points to.
00865 ////////////////////////////////////////////////////////////////////
00866 CPPType *TypeManager::
00867 unwrap_reference(CPPType *source_type) {
00868   switch (source_type->get_subtype()) {
00869   case CPPDeclaration::ST_const:
00870     return unwrap_reference(source_type->as_const_type()->_wrapped_around);
00871 
00872   case CPPDeclaration::ST_reference:
00873     return source_type->as_reference_type()->_pointing_at;
00874 
00875   default:
00876     return source_type;
00877   }
00878 }
00879 
00880 ////////////////////////////////////////////////////////////////////
00881 //     Function: TypeManager::unwrap_const
00882 //       Access: Public, Static
00883 //  Description: Removes the const declaration from the outside of the
00884 //               type.
00885 ////////////////////////////////////////////////////////////////////
00886 CPPType *TypeManager::
00887 unwrap_const(CPPType *source_type) {
00888   switch (source_type->get_subtype()) {
00889   case CPPDeclaration::ST_const:
00890     return unwrap_const(source_type->as_const_type()->_wrapped_around);
00891 
00892   default:
00893     return source_type;
00894   }
00895 }
00896 
00897 ////////////////////////////////////////////////////////////////////
00898 //     Function: TypeManager::unwrap_const_reference
00899 //       Access: Public, Static
00900 //  Description: Removes a reference or a const reference from the
00901 //               type.
00902 ////////////////////////////////////////////////////////////////////
00903 CPPType *TypeManager::
00904 unwrap_const_reference(CPPType *source_type) {
00905   switch (source_type->get_subtype()) {
00906   case CPPDeclaration::ST_const:
00907     return unwrap_const_reference(source_type->as_const_type()->_wrapped_around);
00908 
00909   case CPPDeclaration::ST_reference:
00910     return unwrap_const(source_type->as_reference_type()->_pointing_at);
00911 
00912   default:
00913     return source_type;
00914   }
00915 }
00916 
00917 ////////////////////////////////////////////////////////////////////
00918 //     Function: TypeManager::unwrap
00919 //       Access: Public, Static
00920 //  Description: Removes all const, pointer, and reference wrappers,
00921 //               to get to the thing we're talking about.
00922 ////////////////////////////////////////////////////////////////////
00923 CPPType *TypeManager::
00924 unwrap(CPPType *source_type) {
00925   switch (source_type->get_subtype()) {
00926   case CPPDeclaration::ST_const:
00927     return unwrap(source_type->as_const_type()->_wrapped_around);
00928 
00929   case CPPDeclaration::ST_reference:
00930     return unwrap(source_type->as_reference_type()->_pointing_at);
00931 
00932   case CPPDeclaration::ST_pointer:
00933     return unwrap(source_type->as_pointer_type()->_pointing_at);
00934 
00935   default:
00936     return source_type;
00937   }
00938 }
00939 
00940 ////////////////////////////////////////////////////////////////////
00941 //     Function: TypeManager::get_pointer_type
00942 //       Access: Public, Static
00943 //  Description: Returns the type of pointer the given PointerTo class
00944 //               emulates.  Essentially this just checks the return
00945 //               type of the method called 'p()'.  Returns NULL if the
00946 //               PointerTo class has no method p().
00947 ////////////////////////////////////////////////////////////////////
00948 CPPType *TypeManager::
00949 get_pointer_type(CPPStructType *pt_type) {
00950   CPPScope *scope = pt_type->_scope;
00951 
00952   CPPScope::Functions::const_iterator fi;
00953   fi = scope->_functions.find("p");
00954   if (fi != scope->_functions.end()) {
00955     CPPFunctionGroup *fgroup = (*fi).second;
00956 
00957     // These are all the functions named "p".  Now look for one that
00958     // takes no parameters.
00959     CPPFunctionGroup::Instances::iterator ii;
00960     for (ii = fgroup->_instances.begin();
00961          ii != fgroup->_instances.end();
00962          ++ii) {
00963       CPPInstance *function = (*ii);
00964       CPPFunctionType *ftype = function->_type->as_function_type();
00965       assert(ftype != (CPPFunctionType *)NULL);
00966       if (ftype->_parameters->_parameters.empty()) {
00967         // Here's the function p().  What's its return type?
00968         return resolve_type(ftype->_return_type);
00969       }
00970     }
00971   }
00972 
00973   return (CPPType *)NULL;
00974 }
00975 
00976 ////////////////////////////////////////////////////////////////////
00977 //     Function: TypeManager::wrap_pointer
00978 //       Access: Public, Static
00979 //  Description: Returns the type corresponding to a pointer to the
00980 //               given type.
00981 ////////////////////////////////////////////////////////////////////
00982 CPPType *TypeManager::
00983 wrap_pointer(CPPType *source_type) {
00984   return CPPType::new_type(new CPPPointerType(source_type));
00985 }
00986 
00987 ////////////////////////////////////////////////////////////////////
00988 //     Function: TypeManager::wrap_const_pointer
00989 //       Access: Public, Static
00990 //  Description: Returns the type corresponding to a const pointer
00991 //               to the given type.
00992 ////////////////////////////////////////////////////////////////////
00993 CPPType *TypeManager::
00994 wrap_const_pointer(CPPType *source_type) {
00995   if (source_type->as_const_type() != (CPPConstType *)NULL) {
00996     // It's already const.
00997     return
00998       CPPType::new_type(new CPPPointerType(source_type));
00999   } else {
01000     return
01001       CPPType::new_type(new CPPPointerType(new CPPConstType(source_type)));
01002   }
01003 }
01004 
01005 ////////////////////////////////////////////////////////////////////
01006 //     Function: TypeManager::wrap_const_reference
01007 //       Access: Public, Static
01008 //  Description: Returns the type corresponding to a const reference
01009 //               to the given type.
01010 ////////////////////////////////////////////////////////////////////
01011 CPPType *TypeManager::
01012 wrap_const_reference(CPPType *source_type) {
01013   if (source_type->as_const_type() != (CPPConstType *)NULL) {
01014     // It's already const.
01015     return
01016       CPPType::new_type(new CPPReferenceType(source_type));
01017   } else {
01018     return
01019       CPPType::new_type(new CPPReferenceType(new CPPConstType(source_type)));
01020   }
01021 }
01022 
01023 ////////////////////////////////////////////////////////////////////
01024 //     Function: TypeManager::get_basic_string_char_type
01025 //       Access: Public, Static
01026 //  Description: Returns a CPPType that represents basic_string<char>,
01027 //               or NULL if the type is unknown.
01028 ////////////////////////////////////////////////////////////////////
01029 CPPType *TypeManager::
01030 get_basic_string_char_type() {
01031   static bool got_type = false;
01032   static CPPType *type = (CPPType *)NULL;
01033   if (!got_type) {
01034     type = parser.parse_type("basic_string<char>");
01035     got_type = true;
01036   }
01037   return type;
01038 }
01039 
01040 ////////////////////////////////////////////////////////////////////
01041 //     Function: TypeManager::get_reference_count_type
01042 //       Access: Public, Static
01043 //  Description: Returns a CPPType that represents ReferenceCount,
01044 //               or NULL if the type is unknown.
01045 ////////////////////////////////////////////////////////////////////
01046 CPPType *TypeManager::
01047 get_reference_count_type() {
01048   static bool got_type = false;
01049   static CPPType *type = (CPPType *)NULL;
01050   if (!got_type) {
01051     type = parser.parse_type("ReferenceCount");
01052     got_type = true;
01053   }
01054   return type;
01055 }
01056 
01057 ////////////////////////////////////////////////////////////////////
01058 //     Function: TypeManager::get_void_type
01059 //       Access: Public, Static
01060 //  Description: Returns a CPPType that represents void.
01061 ////////////////////////////////////////////////////////////////////
01062 CPPType *TypeManager::
01063 get_void_type() {
01064   static bool got_type = false;
01065   static CPPType *type = (CPPType *)NULL;
01066   if (!got_type) {
01067     type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_void));
01068     got_type = true;
01069   }
01070   return type;
01071 }
01072 
01073 ////////////////////////////////////////////////////////////////////
01074 //     Function: TypeManager::get_int_type
01075 //       Access: Public, Static
01076 //  Description: Returns a CPPType that represents int.
01077 ////////////////////////////////////////////////////////////////////
01078 CPPType *TypeManager::
01079 get_int_type() {
01080   static bool got_type = false;
01081   static CPPType *type = (CPPType *)NULL;
01082   if (!got_type) {
01083     type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int));
01084     got_type = true;
01085   }
01086   return type;
01087 }
01088 
01089 ////////////////////////////////////////////////////////////////////
01090 //     Function: TypeManager::get_function_signature
01091 //       Access: Public, Static
01092 //  Description: Returns a string corresponding to the given function
01093 //               signature.  This is a unique string per each
01094 //               uniquely-callable C++ function or method.  Basically
01095 //               it's the function prototype, sans the return type.
01096 //
01097 //               If num_default_parameters is nonzero, it is the
01098 //               number of parameters to omit from the end of the
01099 //               parameter list.  This in effect gets the function
01100 //               signature for an equivalent function with n
01101 //               parameters assuming default values.
01102 ////////////////////////////////////////////////////////////////////
01103 string TypeManager::
01104 get_function_signature(CPPInstance *function,
01105                        int num_default_parameters) {
01106   CPPFunctionType *ftype = function->_type->as_function_type();
01107   assert(ftype != (CPPFunctionType *)NULL);
01108 
01109   ostringstream out;
01110 
01111   // It's tempting to mark static methods with a different function
01112   // signature than non-static, because a static method doesn't have
01113   // an implicit 'this' parameter.  However, this breaks the lookup
01114   // when we come across a method definition outside of the class
01115   // body; since there's no clue at this point whether the method is
01116   // static or not, we can't successfully look it up.  Bummer.
01117   /*
01118     if ((function->_storage_class & CPPInstance::SC_static) != 0) {
01119     out << "static ";
01120     }
01121   */
01122 
01123   out << function->get_local_name(&parser) << "(";
01124 
01125   const CPPParameterList::Parameters &params =
01126     ftype->_parameters->_parameters;
01127   CPPParameterList::Parameters::const_iterator pi;
01128 
01129   int num_params = params.size() - num_default_parameters;
01130   pi = params.begin();
01131   for (int n = 0; n < num_params; n++) {
01132     assert(pi != params.end());
01133     CPPType *ptype = (*pi)->_type;
01134 
01135     // One exception: if the type is a const reference to something,
01136     // we build the signature with its corresponding concrete.  C++
01137     // can't differentiate these two anyway.
01138     if (is_const_ref_to_anything(ptype)) {
01139       ptype = unwrap_const_reference(ptype);
01140     }
01141 
01142     out << ptype->get_local_name(&parser);
01143 
01144     if (n + 1 < num_params) {
01145       out << ", ";
01146     }
01147 
01148     ++pi;
01149   }
01150   out << ")";
01151 
01152   if (ftype->_flags & CPPFunctionType::F_const_method) {
01153     out << " const";
01154   }
01155 
01156   return out.str();
01157 }
01158 
01159 ////////////////////////////////////////////////////////////////////
01160 //     Function: TypeManager::get_function_name
01161 //       Access: Public, Static
01162 //  Description: Returns a string corresponding to the given function
01163 //               name.  This is not necessarily unique to the
01164 //               particular overloaded function instance, but is
01165 //               common among all overloaded functions of the same
01166 //               name.
01167 ////////////////////////////////////////////////////////////////////
01168 string TypeManager::
01169 get_function_name(CPPInstance *function) {
01170   return function->get_local_name(&parser);
01171 }
01172 
01173 ////////////////////////////////////////////////////////////////////
01174 //     Function: TypeManager::has_protected_destructor
01175 //       Access: Public, Static
01176 //  Description: Returns true if the destructor for the given class or
01177 //               struct is protected or private, or false if the
01178 //               destructor is public or absent.
01179 ////////////////////////////////////////////////////////////////////
01180 bool TypeManager::
01181 has_protected_destructor(CPPType *type) {
01182   CPPStructType *struct_type = type->as_struct_type();
01183   if (struct_type == (CPPStructType *)NULL) {
01184     // It's not even a struct type!
01185     return false;
01186   }
01187 
01188   CPPScope *scope = struct_type->get_scope();
01189 
01190   // Look for the destructor.
01191   CPPScope::Declarations::const_iterator di;
01192   for (di = scope->_declarations.begin();
01193        di != scope->_declarations.end();
01194        ++di) {
01195     if ((*di)->get_subtype() == CPPDeclaration::ST_instance) {
01196       CPPInstance *inst = (*di)->as_instance();
01197       if (inst->_type->get_subtype() == CPPDeclaration::ST_function) {
01198         // Here's a function declaration.
01199         CPPFunctionType *ftype = inst->_type->as_function_type();
01200         assert(ftype != (CPPFunctionType *)NULL);
01201         if ((ftype->_flags & CPPFunctionType::F_destructor) != 0) {
01202           // Here's the destructor!  Is it protected?
01203           return (inst->_vis > V_public);
01204         }
01205       }
01206     }
01207   }
01208 
01209   // No explicit destructor.
01210   return false;
01211 }

Generated on Thu May 1 22:13:04 2003 for DTool by doxygen1.3