cppInstance.cxx 16 KB

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