cppInstance.cxx 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. // Filename: cppInstance.cxx
  2. // Created by: drose (19Oct99)
  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 "cppInstance.h"
  15. #include "cppInstanceIdentifier.h"
  16. #include "cppIdentifier.h"
  17. #include "cppTemplateScope.h"
  18. #include "cppFunctionType.h"
  19. #include "cppSimpleType.h"
  20. #include "cppExpression.h"
  21. #include "cppPreprocessor.h"
  22. #include "cppParameterList.h"
  23. #include "cppReferenceType.h"
  24. #include "cppConstType.h"
  25. #include "indent.h"
  26. #include <algorithm>
  27. ////////////////////////////////////////////////////////////////////
  28. // Function: CPPInstance::Constructor
  29. // Access: Public
  30. // Description:
  31. ////////////////////////////////////////////////////////////////////
  32. CPPInstance::
  33. CPPInstance(CPPType *type, const string &name, int storage_class) :
  34. CPPDeclaration(CPPFile()),
  35. _type(type),
  36. _ident(new CPPIdentifier(name)),
  37. _storage_class(storage_class)
  38. {
  39. _initializer = NULL;
  40. }
  41. ////////////////////////////////////////////////////////////////////
  42. // Function: CPPInstance::Constructor
  43. // Access: Public
  44. // Description:
  45. ////////////////////////////////////////////////////////////////////
  46. CPPInstance::
  47. CPPInstance(CPPType *type, CPPIdentifier *ident, int storage_class) :
  48. CPPDeclaration(CPPFile()),
  49. _type(type),
  50. _ident(ident),
  51. _storage_class(storage_class)
  52. {
  53. _initializer = NULL;
  54. }
  55. ////////////////////////////////////////////////////////////////////
  56. // Function: CPPInstance::Constructor
  57. // Access: Public
  58. // Description: Constructs a new CPPInstance object that defines a
  59. // variable of the indicated type according to the type
  60. // and the InstanceIdentifier. The InstanceIdentifier
  61. // pointer is deallocated.
  62. ////////////////////////////////////////////////////////////////////
  63. CPPInstance::
  64. CPPInstance(CPPType *type, CPPInstanceIdentifier *ii, int storage_class,
  65. const CPPFile &file) :
  66. CPPDeclaration(file)
  67. {
  68. _type = ii->unroll_type(type);
  69. _ident = ii->_ident;
  70. ii->_ident = NULL;
  71. _storage_class = storage_class;
  72. _initializer = NULL;
  73. CPPParameterList *params = ii->get_initializer();
  74. if (params != (CPPParameterList *)NULL) {
  75. // In this case, the instance has a parameter-list initializer, e.g.:
  76. //
  77. // int foo(0);
  78. //
  79. // We really should save this initializer in the instance object.
  80. // But we don't for now, since no one really cares about
  81. // initializers anyway.
  82. }
  83. delete ii;
  84. }
  85. ////////////////////////////////////////////////////////////////////
  86. // Function: CPPInstance::Copy Constructor
  87. // Access: Public
  88. // Description:
  89. ////////////////////////////////////////////////////////////////////
  90. CPPInstance::
  91. CPPInstance(const CPPInstance &copy) :
  92. CPPDeclaration(copy),
  93. _type(copy._type),
  94. _ident(copy._ident),
  95. _initializer(copy._initializer),
  96. _storage_class(copy._storage_class)
  97. {
  98. assert(_type != NULL);
  99. }
  100. ////////////////////////////////////////////////////////////////////
  101. // Function: CPPInstance::Destructor
  102. // Access: Public
  103. // Description:
  104. ////////////////////////////////////////////////////////////////////
  105. CPPInstance::
  106. ~CPPInstance() {
  107. // Can't delete the identifier. Don't try.
  108. }
  109. ////////////////////////////////////////////////////////////////////
  110. // Function: CPPInstance::make_typecast_function
  111. // Access: Public, Static
  112. // Description: Constructs and returns a new CPPInstance object that
  113. // corresponds to a function prototype declaration for a
  114. // typecast method, whose return type is implicit in the
  115. // identifier type.
  116. ////////////////////////////////////////////////////////////////////
  117. CPPInstance *CPPInstance::
  118. make_typecast_function(CPPInstance *inst, CPPIdentifier *ident,
  119. CPPParameterList *parameters, int function_flags) {
  120. CPPType *type = CPPType::new_type(inst->_type);
  121. delete inst;
  122. function_flags |= (int)CPPFunctionType::F_operator_typecast;
  123. CPPType *ft =
  124. CPPType::new_type(new CPPFunctionType(type, parameters, function_flags));
  125. return new CPPInstance(ft, ident);
  126. }
  127. ////////////////////////////////////////////////////////////////////
  128. // Function: CPPInstance::Equivalence Operator
  129. // Access: Public
  130. // Description:
  131. ////////////////////////////////////////////////////////////////////
  132. bool CPPInstance::
  133. operator == (const CPPInstance &other) const {
  134. if (_type != other._type) {
  135. return false;
  136. }
  137. if (_storage_class != other._storage_class) {
  138. return false;
  139. }
  140. // We *do* care about the identifier. We need to differentiate
  141. // types of function variables, among possibly other things, based
  142. // on the identifier.
  143. if ((_ident == NULL && other._ident != NULL) ||
  144. (_ident != NULL && other._ident == NULL) ||
  145. (_ident != NULL && other._ident != NULL && *_ident != *other._ident))
  146. {
  147. return false;
  148. }
  149. // We similarly care about the initializer.
  150. if ((_initializer == NULL && other._initializer != NULL) ||
  151. (_initializer != NULL && other._initializer == NULL) ||
  152. (_initializer != NULL && other._initializer != NULL &&
  153. *_initializer != *other._initializer))
  154. {
  155. return false;
  156. }
  157. return true;
  158. }
  159. ////////////////////////////////////////////////////////////////////
  160. // Function: CPPInstance::Nonequivalence Operator
  161. // Access: Public
  162. // Description:
  163. ////////////////////////////////////////////////////////////////////
  164. bool CPPInstance::
  165. operator != (const CPPInstance &other) const {
  166. return !operator == (other);
  167. }
  168. ////////////////////////////////////////////////////////////////////
  169. // Function: CPPInstance::Ordering Operator
  170. // Access: Public
  171. // Description:
  172. ////////////////////////////////////////////////////////////////////
  173. bool CPPInstance::
  174. operator < (const CPPInstance &other) const {
  175. if (_type != other._type) {
  176. return _type < other._type;
  177. }
  178. if (_storage_class != other._storage_class) {
  179. return _storage_class < other._storage_class;
  180. }
  181. // We *do* care about the identifier. We need to differentiate
  182. // types of function variables, among possibly other things, based
  183. // on the identifier.
  184. if ((_ident == NULL && other._ident != NULL) ||
  185. (_ident != NULL && other._ident == NULL) ||
  186. (_ident != NULL && other._ident != NULL && *_ident != *other._ident))
  187. {
  188. if (_ident == NULL || other._ident == NULL) {
  189. return _ident < other._ident;
  190. }
  191. return *_ident < *other._ident;
  192. }
  193. // We similarly care about the initializer.
  194. if ((_initializer == NULL && other._initializer != NULL) ||
  195. (_initializer != NULL && other._initializer == NULL) ||
  196. (_initializer != NULL && other._initializer != NULL &&
  197. *_initializer != *other._initializer))
  198. {
  199. if (_initializer == NULL || other._initializer == NULL) {
  200. return _initializer < other._initializer;
  201. }
  202. return *_initializer < *other._initializer;
  203. }
  204. return false;
  205. }
  206. ////////////////////////////////////////////////////////////////////
  207. // Function: CPPInstance::set_initializer
  208. // Access: Public
  209. // Description: Sets the value of the expression that is used to
  210. // initialize the variable, or the default value for a
  211. // parameter. If a non-null expression is set on a
  212. // function declaration, it implies that the function is
  213. // pure virtual.
  214. ////////////////////////////////////////////////////////////////////
  215. void CPPInstance::
  216. set_initializer(CPPExpression *initializer) {
  217. if (_type->as_function_type() != (CPPFunctionType *)NULL) {
  218. // This is a function declaration.
  219. if (initializer == (CPPExpression *)NULL) {
  220. _storage_class &= ~SC_pure_virtual;
  221. } else {
  222. _storage_class |= SC_pure_virtual;
  223. }
  224. _initializer = (CPPExpression *)NULL;
  225. } else {
  226. _initializer = initializer;
  227. }
  228. }
  229. ////////////////////////////////////////////////////////////////////
  230. // Function: CPPInstance::is_scoped
  231. // Access: Public
  232. // Description:
  233. ////////////////////////////////////////////////////////////////////
  234. bool CPPInstance::
  235. is_scoped() const {
  236. if (_ident == NULL) {
  237. return false;
  238. } else {
  239. return _ident->is_scoped();
  240. }
  241. }
  242. ////////////////////////////////////////////////////////////////////
  243. // Function: CPPInstance::get_scope
  244. // Access: Public
  245. // Description:
  246. ////////////////////////////////////////////////////////////////////
  247. CPPScope *CPPInstance::
  248. get_scope(CPPScope *current_scope, CPPScope *global_scope,
  249. CPPPreprocessor *error_sink) const {
  250. if (_ident == NULL) {
  251. return current_scope;
  252. } else {
  253. return _ident->get_scope(current_scope, global_scope, error_sink);
  254. }
  255. }
  256. ////////////////////////////////////////////////////////////////////
  257. // Function: CPPInstance::get_simple_name
  258. // Access: Public
  259. // Description:
  260. ////////////////////////////////////////////////////////////////////
  261. string CPPInstance::
  262. get_simple_name() const {
  263. if (_ident == NULL) {
  264. return "";
  265. } else {
  266. return _ident->get_simple_name();
  267. }
  268. }
  269. ////////////////////////////////////////////////////////////////////
  270. // Function: CPPInstance::get_local_name
  271. // Access: Public
  272. // Description:
  273. ////////////////////////////////////////////////////////////////////
  274. string CPPInstance::
  275. get_local_name(CPPScope *scope) const {
  276. if (_ident == NULL) {
  277. return "";
  278. } else {
  279. return _ident->get_local_name(scope);
  280. }
  281. }
  282. ////////////////////////////////////////////////////////////////////
  283. // Function: CPPInstance::get_fully_scoped_name
  284. // Access: Public
  285. // Description:
  286. ////////////////////////////////////////////////////////////////////
  287. string CPPInstance::
  288. get_fully_scoped_name() const {
  289. if (_ident == NULL) {
  290. return "";
  291. } else {
  292. return _ident->get_fully_scoped_name();
  293. }
  294. }
  295. ////////////////////////////////////////////////////////////////////
  296. // Function: CPPInstance::check_for_constructor
  297. // Access: Public
  298. // Description: If this is a function type instance, checks whether
  299. // the function name matches the class name (or ~name),
  300. // and if so, flags it as a constructor (or destructor).
  301. ////////////////////////////////////////////////////////////////////
  302. void CPPInstance::
  303. check_for_constructor(CPPScope *current_scope, CPPScope *global_scope) {
  304. CPPScope *scope = get_scope(current_scope, global_scope);
  305. if (scope == NULL) {
  306. scope = current_scope;
  307. }
  308. CPPFunctionType *func = _type->as_function_type();
  309. if (func != NULL) {
  310. string method_name = get_local_name(scope);
  311. string class_name = scope->get_local_name();
  312. if (!method_name.empty() && !class_name.empty()) {
  313. if (method_name == class_name) {
  314. CPPType *void_type = CPPType::new_type
  315. (new CPPSimpleType(CPPSimpleType::T_void));
  316. int flags = func->_flags | CPPFunctionType::F_constructor;
  317. // Check if it might be a copy or move constructor.
  318. CPPParameterList *params = func->_parameters;
  319. if (params->_parameters.size() == 1 && !params->_includes_ellipsis) {
  320. CPPType *param_type = params->_parameters[0]->_type;
  321. CPPReferenceType *ref_type = param_type->as_reference_type();
  322. if (ref_type != NULL) {
  323. param_type = ref_type->_pointing_at;
  324. if (param_type->get_subtype() == CPPDeclaration::ST_const) {
  325. param_type = param_type->as_const_type()->_wrapped_around;
  326. }
  327. if (class_name == param_type->get_simple_name()) {
  328. if (ref_type->_value_category == CPPReferenceType::VC_rvalue) {
  329. flags |= CPPFunctionType::F_move_constructor;
  330. } else {
  331. flags |= CPPFunctionType::F_copy_constructor;
  332. }
  333. }
  334. }
  335. }
  336. _type = CPPType::new_type
  337. (new CPPFunctionType(void_type, func->_parameters, flags));
  338. } else if (method_name == "~" + class_name) {
  339. CPPType *void_type = CPPType::new_type
  340. (new CPPSimpleType(CPPSimpleType::T_void));
  341. _type = CPPType::new_type
  342. (new CPPFunctionType(void_type, func->_parameters,
  343. func->_flags | CPPFunctionType::F_destructor));
  344. }
  345. }
  346. }
  347. }
  348. ////////////////////////////////////////////////////////////////////
  349. // Function: CPPInstance::instantiate
  350. // Access: Public
  351. // Description:
  352. ////////////////////////////////////////////////////////////////////
  353. CPPDeclaration *CPPInstance::
  354. instantiate(const CPPTemplateParameterList *actual_params,
  355. CPPScope *current_scope, CPPScope *global_scope,
  356. CPPPreprocessor *error_sink) const {
  357. if (!is_template()) {
  358. if (error_sink != NULL) {
  359. error_sink->warning("Ignoring template parameters for instance " +
  360. _ident->get_local_name());
  361. }
  362. return (CPPInstance *)this;
  363. }
  364. Instantiations::const_iterator ii;
  365. ii = _instantiations.find(actual_params);
  366. if (ii != _instantiations.end()) {
  367. // We've already instantiated this instance with these parameters.
  368. // Return that.
  369. return (*ii).second;
  370. }
  371. CPPTemplateScope *tscope = get_template_scope();
  372. CPPDeclaration::SubstDecl subst;
  373. actual_params->build_subst_decl(tscope->_parameters, subst,
  374. current_scope, global_scope);
  375. CPPInstance *inst =
  376. ((CPPInstance *)this)->substitute_decl(subst, current_scope, global_scope)
  377. ->as_instance();
  378. if (inst == this) {
  379. // Hmm, nothing to substitute. Make a new instance anyway, so we
  380. // can change the name.
  381. inst = new CPPInstance(*this);
  382. }
  383. assert(inst != NULL);
  384. inst->_ident = inst->_ident->substitute_decl(subst, current_scope, global_scope);
  385. if (inst->_ident == _ident) {
  386. inst->_ident = new CPPIdentifier(*inst->_ident);
  387. }
  388. inst->_ident->_names.back().set_templ
  389. (new CPPTemplateParameterList(*actual_params));
  390. inst->_template_scope = NULL;
  391. ((CPPInstance *)this)->_instantiations.insert(Instantiations::value_type(actual_params, inst));
  392. return inst;
  393. }
  394. ////////////////////////////////////////////////////////////////////
  395. // Function: CPPInstance::is_fully_specified
  396. // Access: Public, Virtual
  397. // Description: Returns true if this declaration is an actual,
  398. // factual declaration, or false if some part of the
  399. // declaration depends on a template parameter which has
  400. // not yet been instantiated.
  401. ////////////////////////////////////////////////////////////////////
  402. bool CPPInstance::
  403. is_fully_specified() const {
  404. if (_ident != NULL && !_ident->is_fully_specified()) {
  405. return false;
  406. }
  407. if (_initializer != NULL && !_initializer->is_fully_specified()) {
  408. return false;
  409. }
  410. return CPPDeclaration::is_fully_specified() &&
  411. _type->is_fully_specified();
  412. }
  413. ////////////////////////////////////////////////////////////////////
  414. // Function: CPPInstance::substitute_decl
  415. // Access: Public, Virtual
  416. // Description:
  417. ////////////////////////////////////////////////////////////////////
  418. CPPDeclaration *CPPInstance::
  419. substitute_decl(CPPDeclaration::SubstDecl &subst,
  420. CPPScope *current_scope, CPPScope *global_scope) {
  421. CPPDeclaration *top =
  422. CPPDeclaration::substitute_decl(subst, current_scope, global_scope);
  423. if (top != this) {
  424. return top;
  425. }
  426. CPPInstance *rep = new CPPInstance(*this);
  427. CPPDeclaration *new_type =
  428. _type->substitute_decl(subst, current_scope, global_scope);
  429. rep->_type = new_type->as_type();
  430. if (rep->_type == NULL) {
  431. rep->_type = _type;
  432. }
  433. if (_initializer != NULL) {
  434. rep->_initializer =
  435. _initializer->substitute_decl(subst, current_scope, global_scope)
  436. ->as_expression();
  437. }
  438. if (rep->_type == _type &&
  439. rep->_initializer == _initializer) {
  440. delete rep;
  441. rep = this;
  442. }
  443. subst.insert(SubstDecl::value_type(this, rep));
  444. return rep;
  445. }
  446. ////////////////////////////////////////////////////////////////////
  447. // Function: CPPInstance::output
  448. // Access: Public, Virtual
  449. // Description:
  450. ////////////////////////////////////////////////////////////////////
  451. void CPPInstance::
  452. output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
  453. output(out, indent_level, scope, complete, -1);
  454. }
  455. ////////////////////////////////////////////////////////////////////
  456. // Function: CPPInstance::output
  457. // Access: Public
  458. // Description: The extra parameter comes into play only when we
  459. // happen to be outputting a function prototype. See
  460. // CPPFunctionType::output().
  461. ////////////////////////////////////////////////////////////////////
  462. void CPPInstance::
  463. output(ostream &out, int indent_level, CPPScope *scope, bool complete,
  464. int num_default_parameters) const {
  465. assert(_type != NULL);
  466. if (_type->is_parameter_expr()) {
  467. // In this case, the whole thing is really an expression, and not
  468. // an instance at all. This can only happen if we parsed an
  469. // instance declaration while we thought we were parsing a
  470. // function prototype.
  471. out << *_initializer;
  472. return;
  473. }
  474. if (is_template()) {
  475. get_template_scope()->_parameters.write_formal(out, scope);
  476. indent(out, indent_level);
  477. }
  478. if (_storage_class & SC_static) {
  479. out << "static ";
  480. }
  481. if (_storage_class & SC_extern) {
  482. out << "extern ";
  483. }
  484. if (_storage_class & SC_c_binding) {
  485. out << "\"C\" ";
  486. }
  487. if (_storage_class & SC_virtual) {
  488. out << "virtual ";
  489. }
  490. if (_storage_class & SC_inline) {
  491. out << "inline ";
  492. }
  493. if (_storage_class & SC_explicit) {
  494. out << "explicit ";
  495. }
  496. if (_storage_class & SC_register) {
  497. out << "register ";
  498. }
  499. if (_storage_class & SC_volatile) {
  500. out << "volatile ";
  501. }
  502. if (_storage_class & SC_mutable) {
  503. out << "mutable ";
  504. }
  505. string name;
  506. if (_ident != NULL) {
  507. name = _ident->get_local_name(scope);
  508. }
  509. if (_type->as_function_type()) {
  510. _type->as_function_type()->
  511. output_instance(out, indent_level, scope, complete, "", name,
  512. num_default_parameters);
  513. } else {
  514. _type->output_instance(out, indent_level, scope, complete, "", name);
  515. }
  516. if (_storage_class & SC_pure_virtual) {
  517. out << " = 0";
  518. }
  519. if (_initializer != NULL) {
  520. out << " = " << *_initializer;
  521. }
  522. }
  523. ////////////////////////////////////////////////////////////////////
  524. // Function: CPPInstance::get_subtype
  525. // Access: Public, Virtual
  526. // Description:
  527. ////////////////////////////////////////////////////////////////////
  528. CPPDeclaration::SubType CPPInstance::
  529. get_subtype() const {
  530. return ST_instance;
  531. }
  532. ////////////////////////////////////////////////////////////////////
  533. // Function: CPPInstance::as_instance
  534. // Access: Public, Virtual
  535. // Description:
  536. ////////////////////////////////////////////////////////////////////
  537. CPPInstance *CPPInstance::
  538. as_instance() {
  539. return this;
  540. }