cppType.cxx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. // Filename: cppType.C
  2. // Created by: drose (19Oct99)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. #include "cppType.h"
  6. #include "cppTypedef.h"
  7. CPPType::Types CPPType::_types;
  8. CPPType::PreferredNames CPPType::_preferred_names;
  9. bool CPPTypeCompare::
  10. operator () (CPPType *a, CPPType *b) const {
  11. return (*a) < (*b);
  12. }
  13. ////////////////////////////////////////////////////////////////////
  14. // Function: CPPType::Constructor
  15. // Access: Public
  16. // Description:
  17. ////////////////////////////////////////////////////////////////////
  18. CPPType::
  19. CPPType(const CPPFile &file) :
  20. CPPDeclaration(file)
  21. {
  22. _declaration = (CPPTypeDeclaration *)NULL;
  23. }
  24. ////////////////////////////////////////////////////////////////////
  25. // Function: CPPType::resolve_type
  26. // Access: Public, Virtual
  27. // Description: If this CPPType object is a forward reference or
  28. // other nonspecified reference to a type that might now
  29. // be known a real type, returns the real type.
  30. // Otherwise returns the type itself.
  31. ////////////////////////////////////////////////////////////////////
  32. CPPType *CPPType::
  33. resolve_type(CPPScope *, CPPScope *) {
  34. return this;
  35. }
  36. ////////////////////////////////////////////////////////////////////
  37. // Function: CPPType::is_tbd
  38. // Access: Public, Virtual
  39. // Description: Returns true if the type, or any nested type within
  40. // the type, is a CPPTBDType and thus isn't fully
  41. // determined right now. In this case, calling
  42. // resolve_type() may or may not resolve the type.
  43. ////////////////////////////////////////////////////////////////////
  44. bool CPPType::
  45. is_tbd() const {
  46. return false;
  47. }
  48. ////////////////////////////////////////////////////////////////////
  49. // Function: CPPType::has_typedef_name
  50. // Access: Public
  51. // Description: Returns true if the type has even been typedef'ed and
  52. // therefore has a simple name available to stand for
  53. // it. Extension types are all implicitly typedef'ed on
  54. // declaration.
  55. ////////////////////////////////////////////////////////////////////
  56. bool CPPType::
  57. has_typedef_name() const {
  58. return !_typedefs.empty();
  59. }
  60. ////////////////////////////////////////////////////////////////////
  61. // Function: CPPType::get_typedef_name
  62. // Access: Public
  63. // Description: Returns a string that can be used to name the type,
  64. // if has_typedef_name() returned true. This will be
  65. // the first typedef name applied to the type.
  66. ////////////////////////////////////////////////////////////////////
  67. string CPPType::
  68. get_typedef_name(CPPScope *scope) const {
  69. if (_typedefs.empty()) {
  70. return string();
  71. } else {
  72. return _typedefs.front()->get_local_name(scope);
  73. }
  74. }
  75. ////////////////////////////////////////////////////////////////////
  76. // Function: CPPType::get_simple_name
  77. // Access: Public, Virtual
  78. // Description: Returns a fundametal one-word name for the type.
  79. // This name will not include any scoping operators or
  80. // template parameters, so it may not be a compilable
  81. // reference to the type.
  82. ////////////////////////////////////////////////////////////////////
  83. string CPPType::
  84. get_simple_name() const {
  85. return get_local_name();
  86. }
  87. ////////////////////////////////////////////////////////////////////
  88. // Function: CPPType::get_local_name
  89. // Access: Public, Virtual
  90. // Description: Returns the compilable, correct name for this type
  91. // within the indicated scope. If the scope is NULL,
  92. // within the scope the type is declared in.
  93. ////////////////////////////////////////////////////////////////////
  94. string CPPType::
  95. get_local_name(CPPScope *scope) const {
  96. ostringstream ostrm;
  97. output(ostrm, 0, scope, false);
  98. return ostrm.str();
  99. }
  100. ////////////////////////////////////////////////////////////////////
  101. // Function: CPPType::get_fully_scoped_name
  102. // Access: Public, Virtual
  103. // Description: Returns the compilable, correct name for the type,
  104. // with completely explicit scoping.
  105. ////////////////////////////////////////////////////////////////////
  106. string CPPType::
  107. get_fully_scoped_name() const {
  108. return get_local_name();
  109. }
  110. ////////////////////////////////////////////////////////////////////
  111. // Function: CPPType::get_preferred_name
  112. // Access: Public, Virtual
  113. // Description: Returns the best name to use for the type from a
  114. // programmer's point of view. This will typically be a
  115. // typedef name if one is available, or the full C++
  116. // name if it is not. The typedef may or may not be
  117. // visible within the current scope, so this type name
  118. // may not be compilable.
  119. ////////////////////////////////////////////////////////////////////
  120. string CPPType::
  121. get_preferred_name() const {
  122. string preferred_name = get_preferred_name_for(this);
  123. if (!preferred_name.empty()) {
  124. return preferred_name;
  125. }
  126. return get_local_name();
  127. }
  128. ////////////////////////////////////////////////////////////////////
  129. // Function: CPPType::is_incomplete
  130. // Access: Public, Virtual
  131. // Description: Returns true if the type has not yet been fully
  132. // specified, false if it has.
  133. ////////////////////////////////////////////////////////////////////
  134. bool CPPType::
  135. is_incomplete() const {
  136. return false;
  137. }
  138. ////////////////////////////////////////////////////////////////////
  139. // Function: CPPType::is_equivalent
  140. // Access: Public, Virtual
  141. // Description: This is a little more forgiving than is_equal(): it
  142. // returns true if the types appear to be referring to
  143. // the same thing, even if they may have different
  144. // pointers or somewhat different definitions. It's
  145. // useful for parameter matching, etc.
  146. ////////////////////////////////////////////////////////////////////
  147. bool CPPType::
  148. is_equivalent(const CPPType &other) const {
  149. if (get_subtype() != other.get_subtype()) {
  150. return false;
  151. }
  152. return is_equal(&other);
  153. }
  154. ////////////////////////////////////////////////////////////////////
  155. // Function: CPPType::output_instance
  156. // Access: Public, Virtual
  157. // Description: Formats a C++-looking line that defines an instance
  158. // of the given type, with the indicated name. In most
  159. // cases this will be "type name", but some types have
  160. // special exceptions.
  161. ////////////////////////////////////////////////////////////////////
  162. void CPPType::
  163. output_instance(ostream &out, const string &name, CPPScope *scope) const {
  164. output_instance(out, 0, scope, false, "", name);
  165. }
  166. ////////////////////////////////////////////////////////////////////
  167. // Function: CPPType::output_instance
  168. // Access: Public, Virtual
  169. // Description: Formats a C++-looking line that defines an instance
  170. // of the given type, with the indicated name. In most
  171. // cases this will be "type name", but some types have
  172. // special exceptions.
  173. ////////////////////////////////////////////////////////////////////
  174. void CPPType::
  175. output_instance(ostream &out, int indent_level, CPPScope *scope,
  176. bool complete, const string &prename,
  177. const string &name) const {
  178. output(out, indent_level, scope, complete);
  179. out << " " << prename << name;
  180. }
  181. ////////////////////////////////////////////////////////////////////
  182. // Function: CPPType::as_type
  183. // Access: Public, Virtual
  184. // Description:
  185. ////////////////////////////////////////////////////////////////////
  186. CPPType *CPPType::
  187. as_type() {
  188. return this;
  189. }
  190. ////////////////////////////////////////////////////////////////////
  191. // Function: CPPType::new_type
  192. // Access: Public, Static
  193. // Description: This should be called whenever a new CPPType object
  194. // is created. It will uniquify the type pointers by
  195. // checking to see if some equivalent CPPType object has
  196. // previously been created; if it has, it returns the
  197. // old object and deletes the new one. Otherwise, it
  198. // stores the new one and returns it.
  199. ////////////////////////////////////////////////////////////////////
  200. CPPType *CPPType::
  201. new_type(CPPType *type) {
  202. pair<Types::iterator, bool> result = _types.insert(type);
  203. if (result.second) {
  204. // The insertion has taken place; thus, this is the first time
  205. // this type has been declared.
  206. assert(*result.first == type);
  207. return type;
  208. }
  209. // The insertion has not taken place; thus, there was previously
  210. // another equivalent type declared.
  211. if (*result.first != type) {
  212. // *** Something wrong here. Deleting this should always be safe;
  213. // however, it's not. Thus, someone failed to call new_type() on
  214. // a type pointer before saving it somewhere. Fix me soon. ****
  215. //delete type;
  216. }
  217. return *result.first;
  218. }
  219. ////////////////////////////////////////////////////////////////////
  220. // Function: CPPType::record_preferred_name_for
  221. // Access: Public, Static
  222. // Description: Records a global typedef name associated with the
  223. // indicated Type. This will be taken as the
  224. // "preferred" name for this class, should anyone ask.
  225. ////////////////////////////////////////////////////////////////////
  226. void CPPType::
  227. record_preferred_name_for(const CPPType *type, const string &name) {
  228. if (!name.empty()) {
  229. string tname = type->get_fully_scoped_name();
  230. if (!tname.empty()) {
  231. _preferred_names.insert(PreferredNames::value_type(tname, name));
  232. }
  233. }
  234. }
  235. ////////////////////////////////////////////////////////////////////
  236. // Function: CPPType::get_preferred_name_for
  237. // Access: Public, Static
  238. // Description: Returns the previously-stored "preferred" name
  239. // associated with the type, if any, or empty string if
  240. // no name is associated.
  241. ////////////////////////////////////////////////////////////////////
  242. string CPPType::
  243. get_preferred_name_for(const CPPType *type) {
  244. // We do a lookup based on the type's name, instead of its pointer,
  245. // so we can resolve different expansions of the same type.
  246. string tname = type->get_fully_scoped_name();
  247. if (!tname.empty()) {
  248. PreferredNames::const_iterator pi;
  249. pi = _preferred_names.find(tname);
  250. if (pi != _preferred_names.end()) {
  251. return (*pi).second;
  252. }
  253. }
  254. return string();
  255. }