cppReferenceType.cxx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file cppReferenceType.cxx
  10. * @author drose
  11. * @date 1999-10-19
  12. */
  13. #include "cppReferenceType.h"
  14. #include "cppFile.h"
  15. #include "cppStructType.h"
  16. /**
  17. *
  18. */
  19. CPPReferenceType::
  20. CPPReferenceType(CPPType *pointing_at, ValueCategory vcat) :
  21. CPPType(CPPFile()),
  22. _pointing_at(pointing_at),
  23. _value_category(vcat)
  24. {
  25. }
  26. /**
  27. * Returns true if this declaration is an actual, factual declaration, or
  28. * false if some part of the declaration depends on a template parameter which
  29. * has not yet been instantiated.
  30. */
  31. bool CPPReferenceType::
  32. is_fully_specified() const {
  33. return CPPType::is_fully_specified() &&
  34. _pointing_at->is_fully_specified();
  35. }
  36. /**
  37. *
  38. */
  39. CPPDeclaration *CPPReferenceType::
  40. substitute_decl(CPPDeclaration::SubstDecl &subst,
  41. CPPScope *current_scope, CPPScope *global_scope) {
  42. SubstDecl::const_iterator si = subst.find(this);
  43. if (si != subst.end()) {
  44. return (*si).second;
  45. }
  46. CPPReferenceType *rep = new CPPReferenceType(*this);
  47. rep->_pointing_at =
  48. _pointing_at->substitute_decl(subst, current_scope, global_scope)
  49. ->as_type();
  50. if (rep->_pointing_at == _pointing_at) {
  51. delete rep;
  52. rep = this;
  53. }
  54. rep = CPPType::new_type(rep)->as_reference_type();
  55. subst.insert(SubstDecl::value_type(this, rep));
  56. return rep;
  57. }
  58. /**
  59. * If this CPPType object is a forward reference or other nonspecified
  60. * reference to a type that might now be known a real type, returns the real
  61. * type. Otherwise returns the type itself.
  62. */
  63. CPPType *CPPReferenceType::
  64. resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
  65. CPPType *ptype = _pointing_at->resolve_type(current_scope, global_scope);
  66. if (ptype != _pointing_at) {
  67. CPPReferenceType *rep = new CPPReferenceType(*this);
  68. rep->_pointing_at = ptype;
  69. return CPPType::new_type(rep);
  70. }
  71. return this;
  72. }
  73. /**
  74. * Returns true if the type, or any nested type within the type, is a
  75. * CPPTBDType and thus isn't fully determined right now. In this case,
  76. * calling resolve_type() may or may not resolve the type.
  77. */
  78. bool CPPReferenceType::
  79. is_tbd() const {
  80. return _pointing_at->is_tbd();
  81. }
  82. /**
  83. * Returns true if the type is considered a standard layout type.
  84. */
  85. bool CPPReferenceType::
  86. is_standard_layout() const {
  87. return false;
  88. }
  89. /**
  90. * Returns true if the type is considered a Plain Old Data (POD) type.
  91. */
  92. bool CPPReferenceType::
  93. is_trivial() const {
  94. return false;
  95. }
  96. /**
  97. * Returns true if the type can be constructed using the given argument.
  98. */
  99. bool CPPReferenceType::
  100. is_constructible(const CPPType *given_type) const {
  101. const CPPType *a;
  102. const CPPType *b;
  103. CPPReferenceType *ref_type = ((CPPType *)given_type)->as_reference_type();
  104. if (ref_type != nullptr) {
  105. if (ref_type->_value_category == VC_rvalue) {
  106. return is_constructible(ref_type->_pointing_at);
  107. }
  108. if (_value_category == VC_rvalue) {
  109. // Can never initialize an rvalue ref from an lvalue ref.
  110. return false;
  111. }
  112. if (!_pointing_at->is_const()) {
  113. // Cannot initialize a non-const reference using a const one.
  114. if (ref_type->_pointing_at->is_const()) {
  115. return false;
  116. }
  117. }
  118. a = _pointing_at->remove_cv();
  119. b = ref_type->_pointing_at->remove_cv();
  120. } else {
  121. // Initializing using an rvalue.
  122. if (!_pointing_at->is_const()) {
  123. // Cannot initialize a non-const reference using a const one.
  124. if (given_type->is_const()) {
  125. return false;
  126. }
  127. // Cannot initalise a non-const lvalue reference with an rvalue ref.
  128. if (_value_category == VC_lvalue) {
  129. return false;
  130. }
  131. }
  132. a = _pointing_at->remove_cv();
  133. b = ((CPPType *)given_type)->remove_cv();
  134. }
  135. if (a == b || *a == *b) {
  136. return true;
  137. }
  138. // Can initialize from derived class pointer.
  139. const CPPStructType *a_struct = a->as_struct_type();
  140. const CPPStructType *b_struct = b->as_struct_type();
  141. if (a_struct != nullptr && b_struct != nullptr) {
  142. return a_struct->is_base_of(b_struct);
  143. }
  144. return false;
  145. }
  146. /**
  147. * Returns true if the type is default-constructible.
  148. */
  149. bool CPPReferenceType::
  150. is_default_constructible() const {
  151. return false;
  152. }
  153. /**
  154. * Returns true if the type is copy-constructible.
  155. */
  156. bool CPPReferenceType::
  157. is_copy_constructible() const {
  158. return (_value_category == VC_lvalue);
  159. }
  160. /**
  161. * Returns true if the type is destructible.
  162. */
  163. bool CPPReferenceType::
  164. is_destructible() const {
  165. return false;
  166. }
  167. /**
  168. * This is a little more forgiving than is_equal(): it returns true if the
  169. * types appear to be referring to the same thing, even if they may have
  170. * different pointers or somewhat different definitions. It's useful for
  171. * parameter matching, etc.
  172. */
  173. bool CPPReferenceType::
  174. is_equivalent(const CPPType &other) const {
  175. const CPPReferenceType *ot = ((CPPType *)&other)->as_reference_type();
  176. if (ot == nullptr) {
  177. return CPPType::is_equivalent(other);
  178. }
  179. return _pointing_at->is_equivalent(*ot->_pointing_at);
  180. }
  181. /**
  182. *
  183. */
  184. void CPPReferenceType::
  185. output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
  186. /*
  187. _pointing_at->output(out, indent_level, scope, complete);
  188. out << " &";
  189. */
  190. output_instance(out, indent_level, scope, complete, "", "");
  191. }
  192. /**
  193. * Formats a C++-looking line that defines an instance of the given type, with
  194. * the indicated name. In most cases this will be "type name", but some types
  195. * have special exceptions.
  196. */
  197. void CPPReferenceType::
  198. output_instance(std::ostream &out, int indent_level, CPPScope *scope,
  199. bool complete, const std::string &prename,
  200. const std::string &name) const {
  201. if (_value_category == VC_rvalue) {
  202. _pointing_at->output_instance(out, indent_level, scope, complete,
  203. "&&" + prename, name);
  204. } else {
  205. _pointing_at->output_instance(out, indent_level, scope, complete,
  206. "&" + prename, name);
  207. }
  208. }
  209. /**
  210. *
  211. */
  212. CPPDeclaration::SubType CPPReferenceType::
  213. get_subtype() const {
  214. return ST_reference;
  215. }
  216. /**
  217. *
  218. */
  219. CPPReferenceType *CPPReferenceType::
  220. as_reference_type() {
  221. return this;
  222. }
  223. /**
  224. * Called by CPPDeclaration() to determine whether this type is equivalent to
  225. * another type of the same type.
  226. */
  227. bool CPPReferenceType::
  228. is_equal(const CPPDeclaration *other) const {
  229. const CPPReferenceType *ot = ((CPPDeclaration *)other)->as_reference_type();
  230. assert(ot != nullptr);
  231. return (_pointing_at == ot->_pointing_at) &&
  232. (_value_category == ot->_value_category);
  233. }
  234. /**
  235. * Called by CPPDeclaration() to determine whether this type should be ordered
  236. * before another type of the same type, in an arbitrary but fixed ordering.
  237. */
  238. bool CPPReferenceType::
  239. is_less(const CPPDeclaration *other) const {
  240. const CPPReferenceType *ot = ((CPPDeclaration *)other)->as_reference_type();
  241. assert(ot != nullptr);
  242. if (_value_category != ot->_value_category) {
  243. return (_value_category < ot->_value_category);
  244. }
  245. return _pointing_at < ot->_pointing_at;
  246. }