cppTypedefType.cxx 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  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 Plain Old Data (POD) type.
  146. */
  147. bool CPPTypedefType::
  148. is_trivial() const {
  149. return _type->is_trivial();
  150. }
  151. /**
  152. * Returns true if the type is default-constructible.
  153. */
  154. bool CPPTypedefType::
  155. is_default_constructible() const {
  156. return _type->is_default_constructible();
  157. }
  158. /**
  159. * Returns true if the type is copy-constructible.
  160. */
  161. bool CPPTypedefType::
  162. is_copy_constructible() const {
  163. return _type->is_copy_constructible();
  164. }
  165. /**
  166. * Returns true if this declaration is an actual, factual declaration, or
  167. * false if some part of the declaration depends on a template parameter which
  168. * has not yet been instantiated.
  169. */
  170. bool CPPTypedefType::
  171. is_fully_specified() const {
  172. if (_ident != NULL && !_ident->is_fully_specified()) {
  173. return false;
  174. }
  175. return CPPDeclaration::is_fully_specified() &&
  176. _type->is_fully_specified();
  177. }
  178. /**
  179. *
  180. */
  181. CPPDeclaration *CPPTypedefType::
  182. instantiate(const CPPTemplateParameterList *actual_params,
  183. CPPScope *current_scope, CPPScope *global_scope,
  184. CPPPreprocessor *error_sink) const {
  185. return _type->instantiate(actual_params, current_scope, global_scope, error_sink);
  186. }
  187. /**
  188. *
  189. */
  190. CPPDeclaration *CPPTypedefType::
  191. substitute_decl(CPPDeclaration::SubstDecl &subst,
  192. CPPScope *current_scope, CPPScope *global_scope) {
  193. if (_ident != NULL && _ident->get_scope(current_scope, global_scope) == global_scope) {
  194. // Hack... I know that size_t etc is supposed to work fine, so preserve
  195. // these top-level typedefs.
  196. CPPDeclaration *top =
  197. CPPType::substitute_decl(subst, current_scope, global_scope);
  198. if (top != this) {
  199. return top;
  200. }
  201. top = new CPPTypedefType(*this);
  202. subst.insert(SubstDecl::value_type(this, top));
  203. return top;
  204. }
  205. return _type->substitute_decl(subst, current_scope, global_scope);
  206. // Bah, this doesn't seem to work, and I can't figure out why. Well, for
  207. // now, let's just substitute it with the type we're pointing to. This is
  208. // not a huge deal for now, until we find that we need to preserve these
  209. // typedefs.
  210. /*
  211. CPPDeclaration *top =
  212. CPPType::substitute_decl(subst, current_scope, global_scope);
  213. if (top != this) {
  214. return top;
  215. }
  216. if (_subst_decl_recursive_protect) {
  217. // We're already executing this block; we'll have to return a proxy to the
  218. // type which we'll define later.
  219. CPPTypeProxy *proxy = new CPPTypeProxy;
  220. _proxies.push_back(proxy);
  221. assert(proxy != NULL);
  222. return proxy;
  223. }
  224. _subst_decl_recursive_protect = true;
  225. CPPTypedefType *rep = new CPPTypedefType(*this);
  226. CPPDeclaration *new_type =
  227. _type->substitute_decl(subst, current_scope, global_scope);
  228. rep->_type = new_type->as_type();
  229. if (rep->_type == NULL) {
  230. rep->_type = _type;
  231. }
  232. if (_ident != NULL) {
  233. rep->_ident =
  234. _ident->substitute_decl(subst, current_scope, global_scope);
  235. }
  236. if (rep->_type == _type && rep->_ident == _ident) {
  237. delete rep;
  238. rep = this;
  239. }
  240. rep = CPPType::new_type(rep)->as_typedef_type();
  241. subst.insert(SubstDecl::value_type(this, rep));
  242. _subst_decl_recursive_protect = false;
  243. // Now fill in all the proxies we created for our recursive references.
  244. Proxies::iterator pi;
  245. for (pi = _proxies.begin(); pi != _proxies.end(); ++pi) {
  246. (*pi)->_actual_type = rep;
  247. }
  248. return rep; */
  249. }
  250. /**
  251. * If this CPPType object is a forward reference or other nonspecified
  252. * reference to a type that might now be known a real type, returns the real
  253. * type. Otherwise returns the type itself.
  254. */
  255. CPPType *CPPTypedefType::
  256. resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
  257. CPPType *ptype = _type->resolve_type(current_scope, global_scope);
  258. if (ptype != _type) {
  259. CPPTypedefType *rep = new CPPTypedefType(*this);
  260. rep->_type = ptype;
  261. return CPPType::new_type(rep);
  262. }
  263. return this;
  264. }
  265. /**
  266. * This is a little more forgiving than is_equal(): it returns true if the
  267. * types appear to be referring to the same thing, even if they may have
  268. * different pointers or somewhat different definitions. It's useful for
  269. * parameter matching, etc.
  270. */
  271. bool CPPTypedefType::
  272. is_equivalent(const CPPType &other) const {
  273. CPPType *ot = (CPPType *)&other;
  274. // Unwrap all the typedefs to get to where it is pointing.
  275. while (ot->get_subtype() == ST_typedef) {
  276. ot = ot->as_typedef_type()->_type;
  277. }
  278. // Compare the unwrapped type to what we are pointing to. If we are
  279. // pointing to a typedef ourselves, then this will automatically recurse.
  280. return _type->is_equivalent(*ot);
  281. }
  282. /**
  283. *
  284. */
  285. void CPPTypedefType::
  286. output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
  287. string name;
  288. if (_ident != NULL) {
  289. name = _ident->get_local_name(scope);
  290. }
  291. if (complete) {
  292. if (_using) {
  293. // It was declared using the "using" keyword.
  294. if (is_template()) {
  295. get_template_scope()->_parameters.write_formal(out, scope);
  296. indent(out, indent_level);
  297. }
  298. out << "using " << name << " = ";
  299. _type->output(out, 0, scope, false);
  300. } else {
  301. out << "typedef ";
  302. _type->output_instance(out, indent_level, scope, false, "", name);
  303. }
  304. } else {
  305. out << name;
  306. }
  307. }
  308. /**
  309. *
  310. */
  311. CPPDeclaration::SubType CPPTypedefType::
  312. get_subtype() const {
  313. return ST_typedef;
  314. }
  315. /**
  316. *
  317. */
  318. CPPTypedefType *CPPTypedefType::
  319. as_typedef_type() {
  320. return this;
  321. }
  322. /**
  323. * Called by CPPDeclaration() to determine whether this type is equivalent to
  324. * another type of the same type.
  325. */
  326. bool CPPTypedefType::
  327. is_equal(const CPPDeclaration *other) const {
  328. const CPPTypedefType *ot = ((CPPDeclaration *)other)->as_typedef_type();
  329. assert(ot != NULL);
  330. return (*_type == *ot->_type) && (*_ident == *ot->_ident) && (_using == ot->_using);
  331. }
  332. /**
  333. * Called by CPPDeclaration() to determine whether this type should be ordered
  334. * before another type of the same type, in an arbitrary but fixed ordering.
  335. */
  336. bool CPPTypedefType::
  337. is_less(const CPPDeclaration *other) const {
  338. return CPPDeclaration::is_less(other);
  339. // The below code causes a crash for unknown reasons.
  340. /*
  341. const CPPTypedefType *ot = ((CPPDeclaration *)other)->as_typedef_type();
  342. assert(ot != NULL);
  343. if (_type != ot->_type) {
  344. return _type < ot->_type;
  345. }
  346. if (*_ident != *ot->_ident) {
  347. return *_ident < *ot->_ident;
  348. }
  349. return false; */
  350. }