cppTemplateParameterList.cxx 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // Filename: cppTemplateParameterList.cxx
  2. // Created by: drose (28Oct99)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://etc.cmu.edu/panda3d/docs/license/ .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "cppTemplateParameterList.h"
  19. #include "cppClassTemplateParameter.h"
  20. #include "cppInstance.h"
  21. #include "cppExpression.h"
  22. ////////////////////////////////////////////////////////////////////
  23. // Function: CPPTemplateParameterList::Constructor
  24. // Access: Public
  25. // Description:
  26. ////////////////////////////////////////////////////////////////////
  27. CPPTemplateParameterList::
  28. CPPTemplateParameterList() {
  29. }
  30. ////////////////////////////////////////////////////////////////////
  31. // Function: CPPTemplateParameterList::Constructor
  32. // Access: Public
  33. // Description:
  34. ////////////////////////////////////////////////////////////////////
  35. string CPPTemplateParameterList::
  36. get_string() const {
  37. ostringstream strname;
  38. strname << "< " << *this << " >";
  39. return strname.str();
  40. }
  41. ////////////////////////////////////////////////////////////////////
  42. // Function: CPPTemplateParameterList::build_subst_decl
  43. // Access: Public
  44. // Description: Matches up the actual parameters one-to-one with the
  45. // formal parameters they are replacing, so the template
  46. // may be instantiated by swapping out each occurrence
  47. // of a template standin type with its appropriate
  48. // replacement.
  49. ////////////////////////////////////////////////////////////////////
  50. void CPPTemplateParameterList::
  51. build_subst_decl(const CPPTemplateParameterList &formal_params,
  52. CPPDeclaration::SubstDecl &subst,
  53. CPPScope *current_scope, CPPScope *global_scope) const {
  54. Parameters::const_iterator pfi, pai;
  55. for (pfi = formal_params._parameters.begin(), pai = _parameters.begin();
  56. pfi != formal_params._parameters.end() && pai != _parameters.end();
  57. ++pfi, ++pai) {
  58. CPPDeclaration *formal = *pfi;
  59. CPPDeclaration *actual = *pai;
  60. if (actual->as_type()) {
  61. actual = actual->as_type()->resolve_type(current_scope, global_scope);
  62. }
  63. if (!(formal == actual)) {
  64. subst.insert(CPPDeclaration::SubstDecl::value_type(formal, actual));
  65. }
  66. }
  67. // Fill in the default template parameters.
  68. while (pfi != formal_params._parameters.end()) {
  69. CPPDeclaration *decl = (*pfi);
  70. if (decl->as_instance()) {
  71. // A value template parameter. Its default is an expression.
  72. CPPInstance *inst = decl->as_instance();
  73. if (inst->_initializer != NULL) {
  74. CPPDeclaration *decl =
  75. inst->_initializer->substitute_decl(subst, current_scope,
  76. global_scope);
  77. if (!(*decl == *inst)) {
  78. subst.insert(CPPDeclaration::SubstDecl::value_type
  79. (inst, decl));
  80. }
  81. }
  82. } else if (decl->as_class_template_parameter()) {
  83. // A class template parameter.
  84. CPPClassTemplateParameter *cparam = decl->as_class_template_parameter();
  85. if (cparam->_default_type != NULL) {
  86. CPPDeclaration *decl =
  87. cparam->_default_type->substitute_decl(subst, current_scope,
  88. global_scope);
  89. if (!(*cparam == *decl)) {
  90. subst.insert(CPPDeclaration::SubstDecl::value_type
  91. (cparam, decl));
  92. }
  93. }
  94. }
  95. ++pfi;
  96. }
  97. }
  98. ////////////////////////////////////////////////////////////////////
  99. // Function: CPPTemplateParameterList::is_fully_specified
  100. // Access: Public
  101. // Description: This function returns true if all the parameters in
  102. // the list are real expressions or classes, and not
  103. // types yet to-be-determined or template parameter
  104. // types. That is, this returns true for a normal
  105. // template instantiation, and false for a template
  106. // instantiation based on template parameters that have
  107. // not yet been specified.
  108. ////////////////////////////////////////////////////////////////////
  109. bool CPPTemplateParameterList::
  110. is_fully_specified() const {
  111. for (int i = 0; i < (int)_parameters.size(); ++i) {
  112. if (!_parameters[i]->is_fully_specified()) {
  113. return false;
  114. }
  115. }
  116. return true;
  117. }
  118. ////////////////////////////////////////////////////////////////////
  119. // Function: CPPTemplateParameterList::is_tbd
  120. // Access: Public
  121. // Description: Returns true if any type within the parameter list is
  122. // a CPPTBDType and thus isn't fully determined right
  123. // now.
  124. ////////////////////////////////////////////////////////////////////
  125. bool CPPTemplateParameterList::
  126. is_tbd() const {
  127. for (int i = 0; i < (int)_parameters.size(); ++i) {
  128. CPPType *type = _parameters[i]->as_type();
  129. if (type != (CPPType *)NULL &&
  130. (type->is_tbd() || type->as_class_template_parameter() != NULL)) {
  131. return true;
  132. }
  133. CPPExpression *expr = _parameters[i]->as_expression();
  134. if (expr != NULL && expr->is_tbd()) {
  135. return true;
  136. }
  137. }
  138. return false;
  139. }
  140. ////////////////////////////////////////////////////////////////////
  141. // Function: CPPTemplateParameterList::Equivalence Operator
  142. // Access: Public
  143. // Description:
  144. ////////////////////////////////////////////////////////////////////
  145. bool CPPTemplateParameterList::
  146. operator == (const CPPTemplateParameterList &other) const {
  147. if (_parameters.size() != other._parameters.size()) {
  148. return false;
  149. }
  150. for (int i = 0; i < (int)_parameters.size(); ++i) {
  151. if (*_parameters[i] != *other._parameters[i]) {
  152. return false;
  153. }
  154. }
  155. return true;
  156. }
  157. ////////////////////////////////////////////////////////////////////
  158. // Function: CPPTemplateParameterList::Nonequivalence Operator
  159. // Access: Public
  160. // Description:
  161. ////////////////////////////////////////////////////////////////////
  162. bool CPPTemplateParameterList::
  163. operator != (const CPPTemplateParameterList &other) const {
  164. return !(*this == other);
  165. }
  166. ////////////////////////////////////////////////////////////////////
  167. // Function: CPPTemplateParameterList::Ordering Operator
  168. // Access: Public
  169. // Description:
  170. ////////////////////////////////////////////////////////////////////
  171. bool CPPTemplateParameterList::
  172. operator < (const CPPTemplateParameterList &other) const {
  173. if (_parameters.size() != other._parameters.size()) {
  174. return _parameters.size() < other._parameters.size();
  175. }
  176. for (int i = 0; i < (int)_parameters.size(); ++i) {
  177. if (*_parameters[i] != *other._parameters[i]) {
  178. return *_parameters[i] < *other._parameters[i];
  179. }
  180. }
  181. return false;
  182. }
  183. ////////////////////////////////////////////////////////////////////
  184. // Function: CPPTemplateParameterList::substitute_decl
  185. // Access: Public
  186. // Description:
  187. ////////////////////////////////////////////////////////////////////
  188. CPPTemplateParameterList *CPPTemplateParameterList::
  189. substitute_decl(CPPDeclaration::SubstDecl &subst,
  190. CPPScope *current_scope, CPPScope *global_scope) {
  191. CPPTemplateParameterList *rep = new CPPTemplateParameterList(*this);
  192. bool anything_changed = false;
  193. for (int i = 0; i < (int)rep->_parameters.size(); ++i) {
  194. rep->_parameters[i] =
  195. _parameters[i]->substitute_decl(subst, current_scope, global_scope);
  196. if (rep->_parameters[i] != _parameters[i]) {
  197. anything_changed = true;
  198. }
  199. }
  200. if (!anything_changed) {
  201. delete rep;
  202. rep = this;
  203. }
  204. return rep;
  205. }
  206. ////////////////////////////////////////////////////////////////////
  207. // Function: CPPTemplateParameterList::output
  208. // Access: Public
  209. // Description:
  210. ////////////////////////////////////////////////////////////////////
  211. void CPPTemplateParameterList::
  212. output(ostream &out, CPPScope *scope) const {
  213. if (!_parameters.empty()) {
  214. Parameters::const_iterator pi = _parameters.begin();
  215. (*pi)->output(out, 0, scope, false);
  216. ++pi;
  217. while (pi != _parameters.end()) {
  218. out << ", ";
  219. (*pi)->output(out, 0, scope, false);
  220. ++pi;
  221. }
  222. }
  223. }
  224. ////////////////////////////////////////////////////////////////////
  225. // Function: CPPTemplateParameterList::write_formal
  226. // Access: Public
  227. // Description: Writes the list as a set of formal parameters for a
  228. // template scope. Includes the keyword "template" and
  229. // the angle brackets, as well as the trailing newline.
  230. ////////////////////////////////////////////////////////////////////
  231. void CPPTemplateParameterList::
  232. write_formal(ostream &out, CPPScope *scope) const {
  233. out << "template<";
  234. if (!_parameters.empty()) {
  235. Parameters::const_iterator pi = _parameters.begin();
  236. (*pi)->output(out, 0, scope, true);
  237. ++pi;
  238. while (pi != _parameters.end()) {
  239. out << ", ";
  240. (*pi)->output(out, 0, scope, true);
  241. ++pi;
  242. }
  243. }
  244. out << ">\n";
  245. }