cppInstanceIdentifier.cxx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. // Filename: cppInstanceIdentifier.cxx
  2. // Created by: drose (21Oct99)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) Carnegie Mellon University. All rights reserved.
  8. //
  9. // All use of this software is subject to the terms of the revised BSD
  10. // license. You should have received a copy of this license along
  11. // with this source code in a file named "LICENSE."
  12. //
  13. ////////////////////////////////////////////////////////////////////
  14. #include "cppInstanceIdentifier.h"
  15. #include "cppPointerType.h"
  16. #include "cppReferenceType.h"
  17. #include "cppArrayType.h"
  18. #include "cppConstType.h"
  19. #include "cppFunctionType.h"
  20. #include "cppParameterList.h"
  21. #include "cppIdentifier.h"
  22. ////////////////////////////////////////////////////////////////////
  23. // Function: CPPInstanceIdentifier::Modifier::Constructor
  24. // Access: Public
  25. // Description:
  26. ////////////////////////////////////////////////////////////////////
  27. CPPInstanceIdentifier::Modifier::
  28. Modifier(CPPInstanceIdentifierType type) :
  29. _type(type)
  30. {
  31. _func_params = NULL;
  32. _func_flags = 0;
  33. _scoping = NULL;
  34. _expr = NULL;
  35. }
  36. ////////////////////////////////////////////////////////////////////
  37. // Function: CPPInstanceIdentifier::Modifier::named func_type constructor
  38. // Access: Public, Static
  39. // Description:
  40. ////////////////////////////////////////////////////////////////////
  41. CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
  42. func_type(CPPParameterList *params, int flags, CPPType *trailing_return_type) {
  43. Modifier mod(IIT_func);
  44. mod._func_params = params;
  45. mod._func_flags = flags;
  46. mod._trailing_return_type = trailing_return_type;
  47. return mod;
  48. }
  49. ////////////////////////////////////////////////////////////////////
  50. // Function: CPPInstanceIdentifier::Modifier::named array_type constructor
  51. // Access: Public, Static
  52. // Description:
  53. ////////////////////////////////////////////////////////////////////
  54. CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
  55. array_type(CPPExpression *expr) {
  56. Modifier mod(IIT_array);
  57. mod._expr = expr;
  58. return mod;
  59. }
  60. ////////////////////////////////////////////////////////////////////
  61. // Function: CPPInstanceIdentifier::Modifier::named scoped_pointer_type
  62. // Access: Public, Static
  63. // Description:
  64. ////////////////////////////////////////////////////////////////////
  65. CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
  66. scoped_pointer_type(CPPIdentifier *scoping) {
  67. Modifier mod(IIT_scoped_pointer);
  68. mod._scoping = scoping;
  69. return mod;
  70. }
  71. ////////////////////////////////////////////////////////////////////
  72. // Function: CPPInstanceIdentifier::Modifier::named initializer_type constructor
  73. // Access: Public, Static
  74. // Description: This is used only for instance declarations that turn
  75. // out to be have a parameter list for an initializer.
  76. ////////////////////////////////////////////////////////////////////
  77. CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
  78. initializer_type(CPPParameterList *params) {
  79. Modifier mod(IIT_initializer);
  80. mod._func_params = params;
  81. return mod;
  82. }
  83. ////////////////////////////////////////////////////////////////////
  84. // Function: CPPInstanceIdentifier::Constructor
  85. // Access: Public
  86. // Description:
  87. ////////////////////////////////////////////////////////////////////
  88. CPPInstanceIdentifier::
  89. CPPInstanceIdentifier(CPPIdentifier *ident) :
  90. _ident(ident),
  91. _bit_width(-1) {
  92. }
  93. ////////////////////////////////////////////////////////////////////
  94. // Function: CPPInstanceIdentifier::unroll_type
  95. // Access: Public
  96. // Description: Unrolls the list of type punctuation on either side
  97. // of the identifier to determine the actual type
  98. // represented by the identifier, given the indicated
  99. // starting type (that is, the type name written to the
  100. // left of the identifier).
  101. ////////////////////////////////////////////////////////////////////
  102. CPPType *CPPInstanceIdentifier::
  103. unroll_type(CPPType *start_type) {
  104. CPPType *result = r_unroll_type(start_type, _modifiers.begin());
  105. return result;
  106. }
  107. ////////////////////////////////////////////////////////////////////
  108. // Function: CPPInstanceIdentifier::add_modifier
  109. // Access: Public
  110. // Description:
  111. ////////////////////////////////////////////////////////////////////
  112. void CPPInstanceIdentifier::
  113. add_modifier(CPPInstanceIdentifierType type) {
  114. _modifiers.push_back(Modifier(type));
  115. }
  116. ////////////////////////////////////////////////////////////////////
  117. // Function: CPPInstanceIdentifier::add_func_modifier
  118. // Access: Public
  119. // Description:
  120. ////////////////////////////////////////////////////////////////////
  121. void CPPInstanceIdentifier::
  122. add_func_modifier(CPPParameterList *params, int flags, CPPType *trailing_return_type) {
  123. // As a special hack, if we added a parameter list to an operator
  124. // function, check if the parameter list is empty. If it is, this
  125. // is really a unary operator, so set the unary_op flag. Operators
  126. // () and [] are never considered unary operators.
  127. if (_ident != NULL &&
  128. _ident->get_simple_name().substr(0, 9) == "operator ") {
  129. if (_ident->get_simple_name() != string("operator ()") &&
  130. _ident->get_simple_name() != string("operator []")) {
  131. if (params->_parameters.empty()) {
  132. flags |= CPPFunctionType::F_unary_op;
  133. }
  134. }
  135. flags |= CPPFunctionType::F_operator;
  136. }
  137. if (trailing_return_type != NULL) {
  138. // Remember whether trailing return type notation was used.
  139. flags |= CPPFunctionType::F_trailing_return_type;
  140. }
  141. _modifiers.push_back(Modifier::func_type(params, flags, trailing_return_type));
  142. }
  143. ////////////////////////////////////////////////////////////////////
  144. // Function: CPPInstanceIdentifier::add_scoped_pointer_modifier
  145. // Access: Public
  146. // Description:
  147. ////////////////////////////////////////////////////////////////////
  148. void CPPInstanceIdentifier::
  149. add_scoped_pointer_modifier(CPPIdentifier *scoping) {
  150. _modifiers.push_back(Modifier::scoped_pointer_type(scoping));
  151. }
  152. ////////////////////////////////////////////////////////////////////
  153. // Function: CPPInstanceIdentifier::add_array_modifier
  154. // Access: Public
  155. // Description:
  156. ////////////////////////////////////////////////////////////////////
  157. void CPPInstanceIdentifier::
  158. add_array_modifier(CPPExpression *expr) {
  159. // Special case for operator new[] and delete[]. We're not really
  160. // adding an array modifier to them, but appending [] to the
  161. // identifier. This is to work around a parser ambiguity.
  162. if (_ident != NULL && (_ident->get_simple_name() == "operator delete" ||
  163. _ident->get_simple_name() == "operator new")) {
  164. _ident->_names.back().append_name("[]");
  165. } else {
  166. _modifiers.push_back(Modifier::array_type(expr));
  167. }
  168. }
  169. ////////////////////////////////////////////////////////////////////
  170. // Function: CPPInstanceIdentifier::add_initializer_modifier
  171. // Access: Public
  172. // Description:
  173. ////////////////////////////////////////////////////////////////////
  174. void CPPInstanceIdentifier::
  175. add_initializer_modifier(CPPParameterList *params) {
  176. _modifiers.push_back(Modifier::initializer_type(params));
  177. }
  178. ////////////////////////////////////////////////////////////////////
  179. // Function: CPPInstanceIdentifier::add_trailing_return_type
  180. // Access: Public
  181. // Description:
  182. ////////////////////////////////////////////////////////////////////
  183. void CPPInstanceIdentifier::
  184. add_trailing_return_type(CPPType *type) {
  185. // This is an awkward hack. Improve in the future.
  186. if (!_modifiers.empty()) {
  187. Modifier &mod = _modifiers.back();
  188. if (mod._type == IIT_func) {
  189. mod._trailing_return_type = type;
  190. mod._func_flags |= CPPFunctionType::F_trailing_return_type;
  191. return;
  192. }
  193. }
  194. cerr << "trailing return type can only be added to a function\n";
  195. }
  196. ////////////////////////////////////////////////////////////////////
  197. // Function: CPPInstanceIdentifier::get_initializer
  198. // Access: Public
  199. // Description: Returns the initializer parameter list that was set
  200. // for this particular instance, e.g. if the instance
  201. // were:
  202. //
  203. // int foo(0);
  204. //
  205. // this would return the parameter list (0). Returns
  206. // NULL if the instance did not use a parameter list
  207. // initializer.
  208. ////////////////////////////////////////////////////////////////////
  209. CPPParameterList *CPPInstanceIdentifier::
  210. get_initializer() const {
  211. Modifiers::const_iterator mi;
  212. for (mi = _modifiers.begin(); mi != _modifiers.end(); ++mi) {
  213. const Modifier &mod = (*mi);
  214. if (mod._type == IIT_initializer) {
  215. return mod._func_params;
  216. }
  217. }
  218. return NULL;
  219. }
  220. ////////////////////////////////////////////////////////////////////
  221. // Function: CPPInstanceIdentifier::get_scope
  222. // Access: Public
  223. // Description:
  224. ////////////////////////////////////////////////////////////////////
  225. CPPScope *CPPInstanceIdentifier::
  226. get_scope(CPPScope *current_scope, CPPScope *global_scope,
  227. CPPPreprocessor *error_sink) const {
  228. if (_ident == NULL) {
  229. return current_scope;
  230. } else {
  231. return _ident->get_scope(current_scope, global_scope, error_sink);
  232. }
  233. }
  234. ////////////////////////////////////////////////////////////////////
  235. // Function: CPPInstanceIdentifier::r_unroll_type
  236. // Access: Private
  237. // Description: The recursive implementation of unroll_type().
  238. ////////////////////////////////////////////////////////////////////
  239. CPPType *CPPInstanceIdentifier::
  240. r_unroll_type(CPPType *start_type,
  241. CPPInstanceIdentifier::Modifiers::const_iterator mi) {
  242. assert(start_type != NULL);
  243. start_type = CPPType::new_type(start_type);
  244. if (mi == _modifiers.end()) {
  245. return start_type;
  246. }
  247. const Modifier &mod = (*mi);
  248. ++mi;
  249. CPPType *result = NULL;
  250. switch (mod._type) {
  251. case IIT_pointer:
  252. result = new CPPPointerType(r_unroll_type(start_type, mi));
  253. break;
  254. case IIT_reference:
  255. result = new CPPReferenceType(r_unroll_type(start_type, mi),
  256. CPPReferenceType::VC_lvalue);
  257. break;
  258. case IIT_rvalue_reference:
  259. result = new CPPReferenceType(r_unroll_type(start_type, mi),
  260. CPPReferenceType::VC_rvalue);
  261. break;
  262. case IIT_scoped_pointer:
  263. {
  264. CPPType *type = r_unroll_type(start_type, mi);
  265. CPPFunctionType *ftype = type->as_function_type();
  266. if (ftype != NULL) {
  267. ftype = new CPPFunctionType(*ftype);
  268. ftype->_class_owner = mod._scoping;
  269. ftype->_flags |= CPPFunctionType::F_method_pointer;
  270. type = ftype;
  271. }
  272. result = new CPPPointerType(type);
  273. }
  274. break;
  275. case IIT_array:
  276. result = new CPPArrayType(r_unroll_type(start_type, mi),
  277. mod._expr);
  278. break;
  279. case IIT_const:
  280. result = new CPPConstType(r_unroll_type(start_type, mi));
  281. break;
  282. case IIT_volatile:
  283. // Just pass it through for now.
  284. result = r_unroll_type(start_type, mi);
  285. break;
  286. case IIT_paren:
  287. result = r_unroll_type(start_type, mi);
  288. break;
  289. case IIT_func:
  290. {
  291. CPPType *return_type = r_unroll_type(start_type, mi);
  292. if (mod._trailing_return_type != (CPPType *)NULL) {
  293. CPPSimpleType *simple_type = return_type->as_simple_type();
  294. if (simple_type != NULL && simple_type->_type == CPPSimpleType::T_auto) {
  295. return_type = mod._trailing_return_type;
  296. } else {
  297. cerr << "function with trailing return type needs auto\n";
  298. }
  299. }
  300. result = new CPPFunctionType(return_type, mod._func_params,
  301. mod._func_flags);
  302. }
  303. break;
  304. case IIT_initializer:
  305. // In this case, we have parsed an instance declaration with a set
  306. // of initializers as a parameter list. We lose the initializers
  307. // at this point, but the instance will put it back again.
  308. result = start_type;
  309. break;
  310. default:
  311. cerr << "Internal error--invalid CPPInstanceIdentifier\n";
  312. abort();
  313. }
  314. return CPPType::new_type(result);
  315. }