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 ¶ms = 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 ¶ms = 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 ¶ms = 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 }