cppTypedefType.cxx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  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 cppTypedefType.cxx
  10. * @author rdb
  11. * @date 2014-08-01
  12. */
  13. #include "cppTypedefType.h"
  14. #include "cppIdentifier.h"
  15. #include "cppInstanceIdentifier.h"
  16. #include "cppTemplateScope.h"
  17. #include "indent.h"
  18. /**
  19. *
  20. */
  21. CPPTypedefType::
  22. CPPTypedefType(CPPType *type, const string &name, CPPScope *current_scope) :
  23. CPPType(CPPFile()),
  24. _type(type),
  25. _ident(new CPPIdentifier(name)),
  26. _using(false)
  27. {
  28. if (_ident != NULL) {
  29. _ident->_native_scope = current_scope;
  30. }
  31. _subst_decl_recursive_protect = false;
  32. // assert(_type != NULL); if (global) { _type->_typedefs.push_back(this);
  33. // CPPType::record_alt_name_for(_type, inst->get_local_name()); }
  34. }
  35. /**
  36. *
  37. */
  38. CPPTypedefType::
  39. CPPTypedefType(CPPType *type, CPPIdentifier *ident, CPPScope *current_scope) :
  40. CPPType(CPPFile()),
  41. _type(type),
  42. _ident(ident),
  43. _using(false)
  44. {
  45. if (_ident != NULL) {
  46. _ident->_native_scope = current_scope;
  47. }
  48. _subst_decl_recursive_protect = false;
  49. }
  50. /**
  51. * Constructs a new CPPTypedefType object that defines a typedef to the
  52. * indicated type according to the type and the InstanceIdentifier. The
  53. * InstanceIdentifier pointer is deallocated.
  54. */
  55. CPPTypedefType::
  56. CPPTypedefType(CPPType *type, CPPInstanceIdentifier *ii,
  57. CPPScope *current_scope, const CPPFile &file) :
  58. CPPType(file),
  59. _using(false)
  60. {
  61. assert(ii != NULL);
  62. _type = ii->unroll_type(type);
  63. _ident = ii->_ident;
  64. ii->_ident = NULL;
  65. delete ii;
  66. if (_ident != NULL) {
  67. _ident->_native_scope = current_scope;
  68. }
  69. _subst_decl_recursive_protect = false;
  70. }
  71. /**
  72. *
  73. */
  74. bool CPPTypedefType::
  75. is_scoped() const {
  76. if (_ident == NULL) {
  77. return false;
  78. } else {
  79. return _ident->is_scoped();
  80. }
  81. }
  82. /**
  83. *
  84. */
  85. CPPScope *CPPTypedefType::
  86. get_scope(CPPScope *current_scope, CPPScope *global_scope,
  87. CPPPreprocessor *error_sink) const {
  88. if (_ident == NULL) {
  89. return current_scope;
  90. } else {
  91. return _ident->get_scope(current_scope, global_scope, error_sink);
  92. }
  93. }
  94. /**
  95. *
  96. */
  97. string CPPTypedefType::
  98. get_simple_name() const {
  99. if (_ident == NULL) {
  100. return "";
  101. }
  102. return _ident->get_simple_name();
  103. }
  104. /**
  105. *
  106. */
  107. string CPPTypedefType::
  108. get_local_name(CPPScope *scope) const {
  109. if (_ident == NULL) {
  110. return "";
  111. }
  112. return _ident->get_local_name(scope);
  113. }
  114. /**
  115. *
  116. */
  117. string CPPTypedefType::
  118. get_fully_scoped_name() const {
  119. if (_ident == NULL) {
  120. return "";
  121. }
  122. return _ident->get_fully_scoped_name();
  123. }
  124. /**
  125. * Returns true if the type has not yet been fully specified, false if it has.
  126. */
  127. bool CPPTypedefType::
  128. is_incomplete() const {
  129. return false;
  130. // return _type->is_incomplete();
  131. }
  132. /**
  133. * Returns true if the type, or any nested type within the type, is a
  134. * CPPTBDType and thus isn't fully determined right now. In this case,
  135. * calling resolve_type() may or may not resolve the type.
  136. */
  137. bool CPPTypedefType::
  138. is_tbd() const {
  139. if (_ident != NULL && _ident->is_tbd()) {
  140. return true;
  141. }
  142. return _type->is_tbd();
  143. }
  144. /**
  145. * Returns true if the type is considered a fundamental type.
  146. */
  147. bool CPPTypedefType::
  148. is_fundamental() const {
  149. return _type->is_fundamental();
  150. }
  151. /**
  152. * Returns true if the type is considered a standard layout type.
  153. */
  154. bool CPPTypedefType::
  155. is_standard_layout() const {
  156. return _type->is_standard_layout();
  157. }
  158. /**
  159. * Returns true if the type is considered a Plain Old Data (POD) type.
  160. */
  161. bool CPPTypedefType::
  162. is_trivial() const {
  163. return _type->is_trivial();
  164. }
  165. /**
  166. * Returns true if the type can be constructed using the given argument.
  167. */
  168. bool CPPTypedefType::
  169. is_constructible(const CPPType *given_type) const {
  170. return _type->is_constructible(given_type);
  171. }
  172. /**
  173. * Returns true if the type is default-constructible.
  174. */
  175. bool CPPTypedefType::
  176. is_default_constructible() const {
  177. return _type->is_default_constructible();
  178. }
  179. /**
  180. * Returns true if the type is copy-constructible.
  181. */
  182. bool CPPTypedefType::
  183. is_copy_constructible() const {
  184. return _type->is_copy_constructible();
  185. }
  186. /**
  187. * Returns true if the type is copy-assignable.
  188. */
  189. bool CPPTypedefType::
  190. is_copy_assignable() const {
  191. return _type->is_copy_assignable();
  192. }
  193. /**
  194. * Returns true if the type is destructible.
  195. */
  196. bool CPPTypedefType::
  197. is_destructible() const {
  198. return _type->is_destructible();
  199. }
  200. /**
  201. * Returns true if this declaration is an actual, factual declaration, or
  202. * false if some part of the declaration depends on a template parameter which
  203. * has not yet been instantiated.
  204. */
  205. bool CPPTypedefType::
  206. is_fully_specified() const {
  207. if (_ident != NULL && !_ident->is_fully_specified()) {
  208. return false;
  209. }
  210. return CPPDeclaration::is_fully_specified() &&
  211. _type->is_fully_specified();
  212. }
  213. /**
  214. *
  215. */
  216. CPPDeclaration *CPPTypedefType::
  217. instantiate(const CPPTemplateParameterList *actual_params,
  218. CPPScope *current_scope, CPPScope *global_scope,
  219. CPPPreprocessor *error_sink) const {
  220. return _type->instantiate(actual_params, current_scope, global_scope, error_sink);
  221. }
  222. /**
  223. *
  224. */
  225. CPPDeclaration *CPPTypedefType::
  226. substitute_decl(CPPDeclaration::SubstDecl &subst,
  227. CPPScope *current_scope, CPPScope *global_scope) {
  228. if (_ident != NULL && _ident->get_scope(current_scope, global_scope) == global_scope) {
  229. // Hack... I know that size_t etc is supposed to work fine, so preserve
  230. // these top-level typedefs.
  231. CPPDeclaration *top =
  232. CPPType::substitute_decl(subst, current_scope, global_scope);
  233. if (top != this) {
  234. return top;
  235. }
  236. top = new CPPTypedefType(*this);
  237. subst.insert(SubstDecl::value_type(this, top));
  238. return top;
  239. }
  240. return _type->substitute_decl(subst, current_scope, global_scope);
  241. // Bah, this doesn't seem to work, and I can't figure out why. Well, for
  242. // now, let's just substitute it with the type we're pointing to. This is
  243. // not a huge deal for now, until we find that we need to preserve these
  244. // typedefs.
  245. /*
  246. CPPDeclaration *top =
  247. CPPType::substitute_decl(subst, current_scope, global_scope);
  248. if (top != this) {
  249. return top;
  250. }
  251. if (_subst_decl_recursive_protect) {
  252. // We're already executing this block; we'll have to return a proxy to the
  253. // type which we'll define later.
  254. CPPTypeProxy *proxy = new CPPTypeProxy;
  255. _proxies.push_back(proxy);
  256. assert(proxy != NULL);
  257. return proxy;
  258. }
  259. _subst_decl_recursive_protect = true;
  260. CPPTypedefType *rep = new CPPTypedefType(*this);
  261. CPPDeclaration *new_type =
  262. _type->substitute_decl(subst, current_scope, global_scope);
  263. rep->_type = new_type->as_type();
  264. if (rep->_type == NULL) {
  265. rep->_type = _type;
  266. }
  267. if (_ident != NULL) {
  268. rep->_ident =
  269. _ident->substitute_decl(subst, current_scope, global_scope);
  270. }
  271. if (rep->_type == _type && rep->_ident == _ident) {
  272. delete rep;
  273. rep = this;
  274. }
  275. rep = CPPType::new_type(rep)->as_typedef_type();
  276. subst.insert(SubstDecl::value_type(this, rep));
  277. _subst_decl_recursive_protect = false;
  278. // Now fill in all the proxies we created for our recursive references.
  279. Proxies::iterator pi;
  280. for (pi = _proxies.begin(); pi != _proxies.end(); ++pi) {
  281. (*pi)->_actual_type = rep;
  282. }
  283. return rep; */
  284. }
  285. /**
  286. * If this CPPType object is a forward reference or other nonspecified
  287. * reference to a type that might now be known a real type, returns the real
  288. * type. Otherwise returns the type itself.
  289. */
  290. CPPType *CPPTypedefType::
  291. resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
  292. CPPType *ptype = _type->resolve_type(current_scope, global_scope);
  293. if (ptype != _type) {
  294. CPPTypedefType *rep = new CPPTypedefType(*this);
  295. rep->_type = ptype;
  296. return CPPType::new_type(rep);
  297. }
  298. return this;
  299. }
  300. /**
  301. * Returns true if variables of this type may be implicitly converted to
  302. * the other type.
  303. */
  304. bool CPPTypedefType::
  305. is_convertible_to(const CPPType *other) const {
  306. return _type->is_convertible_to(other);
  307. }
  308. /**
  309. * This is a little more forgiving than is_equal(): it returns true if the
  310. * types appear to be referring to the same thing, even if they may have
  311. * different pointers or somewhat different definitions. It's useful for
  312. * parameter matching, etc.
  313. */
  314. bool CPPTypedefType::
  315. is_equivalent(const CPPType &other) const {
  316. CPPType *ot = (CPPType *)&other;
  317. // Unwrap all the typedefs to get to where it is pointing.
  318. while (ot->get_subtype() == ST_typedef) {
  319. ot = ot->as_typedef_type()->_type;
  320. }
  321. // Compare the unwrapped type to what we are pointing to. If we are
  322. // pointing to a typedef ourselves, then this will automatically recurse.
  323. return _type->is_equivalent(*ot);
  324. }
  325. /**
  326. *
  327. */
  328. void CPPTypedefType::
  329. output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
  330. string name;
  331. if (_ident != NULL) {
  332. name = _ident->get_local_name(scope);
  333. }
  334. if (complete) {
  335. if (_using) {
  336. // It was declared using the "using" keyword.
  337. if (is_template()) {
  338. get_template_scope()->_parameters.write_formal(out, scope);
  339. indent(out, indent_level);
  340. }
  341. out << "using " << name << " = ";
  342. _type->output(out, 0, scope, false);
  343. } else {
  344. out << "typedef ";
  345. _type->output_instance(out, indent_level, scope, false, "", name);
  346. }
  347. } else {
  348. out << name;
  349. }
  350. }
  351. /**
  352. *
  353. */
  354. CPPDeclaration::SubType CPPTypedefType::
  355. get_subtype() const {
  356. return ST_typedef;
  357. }
  358. /**
  359. *
  360. */
  361. CPPTypedefType *CPPTypedefType::
  362. as_typedef_type() {
  363. return this;
  364. }
  365. /**
  366. * Called by CPPDeclaration() to determine whether this type is equivalent to
  367. * another type of the same type.
  368. */
  369. bool CPPTypedefType::
  370. is_equal(const CPPDeclaration *other) const {
  371. const CPPTypedefType *ot = ((CPPDeclaration *)other)->as_typedef_type();
  372. assert(ot != NULL);
  373. return (*_type == *ot->_type) && (*_ident == *ot->_ident) && (_using == ot->_using);
  374. }
  375. /**
  376. * Called by CPPDeclaration() to determine whether this type should be ordered
  377. * before another type of the same type, in an arbitrary but fixed ordering.
  378. */
  379. bool CPPTypedefType::
  380. is_less(const CPPDeclaration *other) const {
  381. return CPPDeclaration::is_less(other);
  382. // The below code causes a crash for unknown reasons.
  383. /*
  384. const CPPTypedefType *ot = ((CPPDeclaration *)other)->as_typedef_type();
  385. assert(ot != NULL);
  386. if (_type != ot->_type) {
  387. return _type < ot->_type;
  388. }
  389. if (*_ident != *ot->_ident) {
  390. return *_ident < *ot->_ident;
  391. }
  392. return false; */
  393. }