cppParameterList.cxx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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 cppParameterList.cxx
  10. * @author drose
  11. * @date 1999-10-21
  12. */
  13. #include "cppParameterList.h"
  14. #include "cppInstance.h"
  15. /**
  16. *
  17. */
  18. CPPParameterList::
  19. CPPParameterList() {
  20. _includes_ellipsis = false;
  21. }
  22. /**
  23. * This is similar to operator == except it is more forgiving: it is true if
  24. * only the length and order of types is the same, never minding the instance
  25. * names or initial values.
  26. */
  27. bool CPPParameterList::
  28. is_equivalent(const CPPParameterList &other) const {
  29. if (_includes_ellipsis != other._includes_ellipsis) {
  30. return false;
  31. }
  32. if (_parameters.size() != other._parameters.size()) {
  33. return false;
  34. }
  35. for (int i = 0; i < (int)_parameters.size(); ++i) {
  36. if (!_parameters[i]->_type->is_equivalent(*other._parameters[i]->_type)) {
  37. return false;
  38. }
  39. }
  40. return true;
  41. }
  42. /**
  43. *
  44. */
  45. bool CPPParameterList::
  46. operator == (const CPPParameterList &other) const {
  47. if (_includes_ellipsis != other._includes_ellipsis) {
  48. return false;
  49. }
  50. if (_parameters.size() != other._parameters.size()) {
  51. return false;
  52. }
  53. for (int i = 0; i < (int)_parameters.size(); ++i) {
  54. if (*_parameters[i] != *other._parameters[i]) {
  55. return false;
  56. }
  57. }
  58. return true;
  59. }
  60. /**
  61. *
  62. */
  63. bool CPPParameterList::
  64. operator != (const CPPParameterList &other) const {
  65. return !(*this == other);
  66. }
  67. /**
  68. *
  69. */
  70. bool CPPParameterList::
  71. operator < (const CPPParameterList &other) const {
  72. if (_includes_ellipsis != other._includes_ellipsis) {
  73. return _includes_ellipsis < other._includes_ellipsis;
  74. }
  75. if (_parameters.size() != other._parameters.size()) {
  76. return _parameters.size() < other._parameters.size();
  77. }
  78. for (int i = 0; i < (int)_parameters.size(); ++i) {
  79. if (*_parameters[i] != *other._parameters[i]) {
  80. return *_parameters[i] < *other._parameters[i];
  81. }
  82. }
  83. return false;
  84. }
  85. /**
  86. * Returns true if any of the types in the parameter list are base on
  87. * CPPTBDType.
  88. */
  89. bool CPPParameterList::
  90. is_tbd() const {
  91. for (int i = 0; i < (int)_parameters.size(); ++i) {
  92. if (_parameters[i]->_type->is_tbd()) {
  93. return true;
  94. }
  95. }
  96. return false;
  97. }
  98. /**
  99. * Returns true if any of the types in the parameter list turns out to be a
  100. * constant expression, which is a clue that this parameter list is actually
  101. * intended to be an instance declaration.
  102. */
  103. bool CPPParameterList::
  104. is_parameter_expr() const {
  105. for (int i = 0; i < (int)_parameters.size(); ++i) {
  106. if (_parameters[i]->_type->is_parameter_expr()) {
  107. return true;
  108. }
  109. }
  110. return false;
  111. }
  112. /**
  113. * Returns true if this declaration is an actual, factual declaration, or
  114. * false if some part of the declaration depends on a template parameter which
  115. * has not yet been instantiated.
  116. */
  117. bool CPPParameterList::
  118. is_fully_specified() const {
  119. for (int i = 0; i < (int)_parameters.size(); ++i) {
  120. if (!_parameters[i]->is_fully_specified()) {
  121. return false;
  122. }
  123. }
  124. return true;
  125. }
  126. /**
  127. *
  128. */
  129. CPPParameterList *CPPParameterList::
  130. substitute_decl(CPPDeclaration::SubstDecl &subst,
  131. CPPScope *current_scope, CPPScope *global_scope) {
  132. CPPParameterList *rep = new CPPParameterList;
  133. bool any_changed = false;
  134. for (int i = 0; i < (int)_parameters.size(); ++i) {
  135. CPPInstance *inst =
  136. _parameters[i]->substitute_decl(subst, current_scope, global_scope)
  137. ->as_instance();
  138. if (inst != _parameters[i]) {
  139. any_changed = true;
  140. }
  141. rep->_parameters.push_back(inst);
  142. }
  143. if (!any_changed) {
  144. delete rep;
  145. rep = this;
  146. }
  147. return rep;
  148. }
  149. /**
  150. * Returns an equivalent CPPParameterList, in which all of the individual
  151. * types have been resolved.
  152. */
  153. CPPParameterList *CPPParameterList::
  154. resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
  155. CPPParameterList *rep = new CPPParameterList;
  156. bool any_changed = false;
  157. for (int i = 0; i < (int)_parameters.size(); ++i) {
  158. CPPInstance *inst = _parameters[i];
  159. CPPType *new_type = inst->_type;
  160. if (new_type->is_tbd()) {
  161. new_type = new_type->resolve_type(current_scope, global_scope);
  162. }
  163. if (new_type != inst->_type) {
  164. any_changed = true;
  165. CPPInstance *new_inst = new CPPInstance(*inst);
  166. new_inst->_type = new_type;
  167. rep->_parameters.push_back(new_inst);
  168. } else {
  169. rep->_parameters.push_back(inst);
  170. }
  171. }
  172. if (!any_changed) {
  173. delete rep;
  174. rep = this;
  175. }
  176. return rep;
  177. }
  178. /**
  179. * If num_default_parameters is >= 0, it indicates the number of default
  180. * parameter values to show on output. Otherwise, all parameter values are
  181. * shown.
  182. */
  183. void CPPParameterList::
  184. output(std::ostream &out, CPPScope *scope, bool parameter_names,
  185. int num_default_parameters) const {
  186. if (!_parameters.empty()) {
  187. for (int i = 0; i < (int)_parameters.size(); ++i) {
  188. if (i != 0) {
  189. out << ", ";
  190. }
  191. // Save the default value expression; we might be about to temporarily
  192. // clear it.
  193. CPPExpression *expr = _parameters[i]->_initializer;
  194. if (num_default_parameters >= 0 &&
  195. i < (int)_parameters.size() - num_default_parameters) {
  196. // Don't show the default value for this parameter.
  197. _parameters[i]->_initializer = nullptr;
  198. }
  199. if (parameter_names) {
  200. _parameters[i]->output(out, 0, scope, false);
  201. } else {
  202. _parameters[i]->_type->output(out, 0, scope, false);
  203. }
  204. // Restore the default value expression.
  205. _parameters[i]->_initializer = expr;
  206. }
  207. if (_includes_ellipsis) {
  208. out << ", ...";
  209. }
  210. } else if (_includes_ellipsis) {
  211. out << "...";
  212. } else {
  213. // No parameters.
  214. out << "void";
  215. }
  216. }