cppTypedefType.cxx 14 KB

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