cppIdentifier.cxx 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. // Filename: cppIdentifier.cxx
  2. // Created by: drose (26Oct99)
  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 "cppIdentifier.h"
  15. #include "cppScope.h"
  16. #include "cppTemplateScope.h"
  17. #include "cppPreprocessor.h"
  18. #include "cppTemplateParameterList.h"
  19. #include "cppTBDType.h"
  20. #include "cppStructType.h"
  21. ////////////////////////////////////////////////////////////////////
  22. // Function: CPPIdentifier::Constructor
  23. // Access: Public
  24. // Description:
  25. ////////////////////////////////////////////////////////////////////
  26. CPPIdentifier::
  27. CPPIdentifier(const string &name, const CPPFile &file) {
  28. _names.push_back(CPPNameComponent(name));
  29. _native_scope = (CPPScope *)NULL;
  30. _loc.first_line = 0;
  31. _loc.first_column = 0;
  32. _loc.last_line = 0;
  33. _loc.last_column = 0;
  34. _loc.file = file;
  35. }
  36. ////////////////////////////////////////////////////////////////////
  37. // Function: CPPIdentifier::Constructor
  38. // Access: Public
  39. // Description:
  40. ////////////////////////////////////////////////////////////////////
  41. CPPIdentifier::
  42. CPPIdentifier(const CPPNameComponent &name, const CPPFile &file) {
  43. _names.push_back(name);
  44. _native_scope = (CPPScope *)NULL;
  45. _loc.first_line = 0;
  46. _loc.first_column = 0;
  47. _loc.last_line = 0;
  48. _loc.last_column = 0;
  49. _loc.file = file;
  50. }
  51. ////////////////////////////////////////////////////////////////////
  52. // Function: CPPIdentifier::Constructor
  53. // Access: Public
  54. // Description:
  55. ////////////////////////////////////////////////////////////////////
  56. CPPIdentifier::
  57. CPPIdentifier(const string &name, const cppyyltype &loc) : _loc(loc) {
  58. _names.push_back(CPPNameComponent(name));
  59. _native_scope = (CPPScope *)NULL;
  60. }
  61. ////////////////////////////////////////////////////////////////////
  62. // Function: CPPIdentifier::Constructor
  63. // Access: Public
  64. // Description:
  65. ////////////////////////////////////////////////////////////////////
  66. CPPIdentifier::
  67. CPPIdentifier(const CPPNameComponent &name, const cppyyltype &loc) : _loc(loc) {
  68. _names.push_back(name);
  69. _native_scope = (CPPScope *)NULL;
  70. }
  71. ////////////////////////////////////////////////////////////////////
  72. // Function: CPPIdentifier::add_name
  73. // Access: Public
  74. // Description:
  75. ////////////////////////////////////////////////////////////////////
  76. void CPPIdentifier::
  77. add_name(const string &name) {
  78. _names.push_back(CPPNameComponent(name));
  79. }
  80. ////////////////////////////////////////////////////////////////////
  81. // Function: CPPIdentifier::add_name
  82. // Access: Public
  83. // Description:
  84. ////////////////////////////////////////////////////////////////////
  85. void CPPIdentifier::
  86. add_name(const CPPNameComponent &name) {
  87. _names.push_back(name);
  88. }
  89. ////////////////////////////////////////////////////////////////////
  90. // Function: CPPIdentifier::Equivalence Operator
  91. // Access: Public
  92. // Description:
  93. ////////////////////////////////////////////////////////////////////
  94. bool CPPIdentifier::
  95. operator == (const CPPIdentifier &other) const {
  96. if (_names.size() != other._names.size()) {
  97. return false;
  98. }
  99. for (int i = 0; i < (int)_names.size(); ++i) {
  100. if (_names[i] != other._names[i]) {
  101. return false;
  102. }
  103. }
  104. return true;
  105. }
  106. ////////////////////////////////////////////////////////////////////
  107. // Function: CPPIdentifier::Nonequivalence Operator
  108. // Access: Public
  109. // Description:
  110. ////////////////////////////////////////////////////////////////////
  111. bool CPPIdentifier::
  112. operator != (const CPPIdentifier &other) const {
  113. return !(*this == other);
  114. }
  115. ////////////////////////////////////////////////////////////////////
  116. // Function: CPPIdentifier::Ordering Operator
  117. // Access: Public
  118. // Description:
  119. ////////////////////////////////////////////////////////////////////
  120. bool CPPIdentifier::
  121. operator < (const CPPIdentifier &other) const {
  122. if (_names.size() != other._names.size()) {
  123. return _names.size() < other._names.size();
  124. }
  125. for (int i = 0; i < (int)_names.size(); ++i) {
  126. if (_names[i] != other._names[i]) {
  127. return _names[i] < other._names[i];
  128. }
  129. }
  130. return false;
  131. }
  132. ////////////////////////////////////////////////////////////////////
  133. // Function: CPPIdentifier::is_scoped
  134. // Access: Public
  135. // Description:
  136. ////////////////////////////////////////////////////////////////////
  137. bool CPPIdentifier::
  138. is_scoped() const {
  139. return _names.size() > 1;
  140. }
  141. ////////////////////////////////////////////////////////////////////
  142. // Function: CPPIdentifier::get_simple_name
  143. // Access: Public
  144. // Description:
  145. ////////////////////////////////////////////////////////////////////
  146. string CPPIdentifier::
  147. get_simple_name() const {
  148. return _names.back().get_name();
  149. }
  150. ////////////////////////////////////////////////////////////////////
  151. // Function: CPPIdentifier::get_local_name
  152. // Access: Public
  153. // Description:
  154. ////////////////////////////////////////////////////////////////////
  155. string CPPIdentifier::
  156. get_local_name(CPPScope *scope) const {
  157. assert(!_names.empty());
  158. string result;
  159. if (scope == NULL || (_native_scope == NULL && _names.size() == 1)) {
  160. result = _names.back().get_name_with_templ(scope);
  161. } else if (_names.front().empty()) {
  162. result = get_fully_scoped_name();
  163. } else {
  164. // Determine the scope of everything up until but not including the
  165. // last name.
  166. CPPScope *my_scope = get_scope(scope, NULL);
  167. // Strip off template scopes, since they don't add anything
  168. // particularly meaningful to the local name.
  169. while (my_scope != NULL && my_scope->as_template_scope() != NULL) {
  170. my_scope = my_scope->get_parent_scope();
  171. }
  172. if (my_scope == NULL) {
  173. result = get_fully_scoped_name();
  174. } else if (my_scope == scope) {
  175. return _names.back().get_name_with_templ(scope);
  176. } else {
  177. result = my_scope->get_local_name(scope);
  178. if (!result.empty()) {
  179. result += "::";
  180. }
  181. result += _names.back().get_name_with_templ(scope);
  182. }
  183. }
  184. return result;
  185. }
  186. ////////////////////////////////////////////////////////////////////
  187. // Function: CPPIdentifier::get_fully_scoped_name
  188. // Access: Public
  189. // Description:
  190. ////////////////////////////////////////////////////////////////////
  191. string CPPIdentifier::
  192. get_fully_scoped_name() const {
  193. assert(!_names.empty());
  194. Names::const_iterator ni = _names.begin();
  195. string name = (*ni).get_name_with_templ();
  196. ++ni;
  197. while (ni != _names.end()) {
  198. name += "::" + (*ni).get_name_with_templ();
  199. ++ni;
  200. }
  201. return name;
  202. }
  203. ////////////////////////////////////////////////////////////////////
  204. // Function: CPPIdentifier::is_fully_specified
  205. // Access: Public
  206. // Description: Returns true if this declaration is an actual,
  207. // factual declaration, or false if some part of the
  208. // declaration depends on a template parameter which has
  209. // not yet been instantiated.
  210. ////////////////////////////////////////////////////////////////////
  211. bool CPPIdentifier::
  212. is_fully_specified() const {
  213. Names::const_iterator ni;
  214. for (ni = _names.begin(); ni != _names.end(); ++ni) {
  215. if ((*ni).has_templ() && !(*ni).get_templ()->is_fully_specified()) {
  216. return false;
  217. }
  218. }
  219. return true;
  220. }
  221. ////////////////////////////////////////////////////////////////////
  222. // Function: CPPIdentifier::is_tbd
  223. // Access: Public
  224. // Description: Returns true if the identifier includes a
  225. // template parameter list that includes some
  226. // not-yet-defined type.
  227. ////////////////////////////////////////////////////////////////////
  228. bool CPPIdentifier::
  229. is_tbd() const {
  230. Names::const_iterator ni;
  231. for (ni = _names.begin(); ni != _names.end(); ++ni) {
  232. if ((*ni).is_tbd()) {
  233. return true;
  234. }
  235. }
  236. return false;
  237. }
  238. ////////////////////////////////////////////////////////////////////
  239. // Function: CPPIdentifier::get_scope
  240. // Access: Public
  241. // Description:
  242. ////////////////////////////////////////////////////////////////////
  243. CPPScope *CPPIdentifier::
  244. get_scope(CPPScope *current_scope, CPPScope *global_scope,
  245. CPPPreprocessor *error_sink) const {
  246. assert(!_names.empty());
  247. CPPScope *scope = _native_scope;
  248. if (scope == (CPPScope *)NULL) {
  249. scope = current_scope;
  250. }
  251. int i = 0;
  252. if (_names[i].empty()) {
  253. // This identifier starts with a ::, thus it begins at the global
  254. // scope.
  255. scope = global_scope;
  256. i++;
  257. }
  258. while (i + 1 < (int)_names.size() && scope != NULL) {
  259. CPPScope *next_scope = scope->find_scope(_names[i].get_name());
  260. if (next_scope == (CPPScope *)NULL) {
  261. if (error_sink != NULL) {
  262. error_sink->error("Symbol " + _names[i].get_name() +
  263. " is not a known scope in " +
  264. scope->get_fully_scoped_name(),
  265. _loc);
  266. }
  267. return (CPPScope *)NULL;
  268. }
  269. if (_names[i].has_templ()) {
  270. next_scope = next_scope->instantiate(_names[i].get_templ(),
  271. current_scope, global_scope);
  272. }
  273. scope = next_scope;
  274. i++;
  275. }
  276. return scope;
  277. }
  278. ////////////////////////////////////////////////////////////////////
  279. // Function: CPPIdentifier::get_scope
  280. // Access: Public
  281. // Description:
  282. ////////////////////////////////////////////////////////////////////
  283. CPPScope *CPPIdentifier::
  284. get_scope(CPPScope *current_scope, CPPScope *global_scope,
  285. CPPDeclaration::SubstDecl &subst,
  286. CPPPreprocessor *error_sink) const {
  287. assert(!_names.empty());
  288. CPPScope *scope = _native_scope;
  289. if (scope == (CPPScope *)NULL) {
  290. scope = current_scope;
  291. }
  292. int i = 0;
  293. if (_names[i].empty()) {
  294. // This identifier starts with a ::, thus it begins at the global
  295. // scope.
  296. scope = global_scope;
  297. i++;
  298. }
  299. while (i + 1 < (int)_names.size() && scope != NULL) {
  300. CPPScope *next_scope = scope->find_scope(_names[i].get_name(), subst,
  301. global_scope);
  302. if (next_scope == (CPPScope *)NULL) {
  303. if (error_sink != NULL) {
  304. error_sink->error("Symbol " + _names[i].get_name() +
  305. " is not a known scope in " +
  306. scope->get_fully_scoped_name(),
  307. _loc);
  308. }
  309. return (CPPScope *)NULL;
  310. }
  311. if (_names[i].has_templ()) {
  312. next_scope = next_scope->instantiate(_names[i].get_templ(),
  313. current_scope, global_scope);
  314. }
  315. scope = next_scope;
  316. i++;
  317. }
  318. return scope;
  319. }
  320. ////////////////////////////////////////////////////////////////////
  321. // Function: CPPIdentifier::find_type
  322. // Access: Public
  323. // Description: Looks up the identifier in the current and/or global
  324. // scopes, and returns a CPPType pointer if it seems to
  325. // refer to a type, or NULL if it does not. If
  326. // force_instantiate is true, the type will be
  327. // instantiated as fully as possible right now, even if
  328. // it means instantiating it into an identical template
  329. // type. Otherwise, the instantiation may be delayed
  330. // for optimization reasons, and a CPPTBDType
  331. // placeholder may be returned instead.
  332. ////////////////////////////////////////////////////////////////////
  333. CPPType *CPPIdentifier::
  334. find_type(CPPScope *current_scope, CPPScope *global_scope,
  335. bool force_instantiate,
  336. CPPPreprocessor *error_sink) const {
  337. CPPScope *scope = get_scope(current_scope, global_scope, error_sink);
  338. if (scope == NULL) {
  339. return NULL;
  340. }
  341. CPPType *type = NULL;
  342. if (!_names.back().has_templ()) {
  343. type = scope->find_type(get_simple_name());
  344. } else {
  345. CPPDeclaration *decl = find_symbol(current_scope, global_scope, error_sink);
  346. type = decl->as_type();
  347. /*
  348. if (type != NULL) {
  349. if (!type->is_incomplete() || force_instantiate) {
  350. type = type->instantiate(_names.back().get_templ(),
  351. current_scope, global_scope,
  352. error_sink)->as_type();
  353. // If we ended up with another template, instantiate later.
  354. if (type->is_template() && !force_instantiate) {
  355. type = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
  356. }
  357. } else {
  358. // Otherwise, we'll have to instantiate the type later.
  359. type = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
  360. }
  361. // type->_file.replace_nearer(_file);
  362. }
  363. */
  364. }
  365. return type;
  366. }
  367. ////////////////////////////////////////////////////////////////////
  368. // Function: CPPIdentifier::find_type
  369. // Access: Public
  370. // Description: This flavor of find_type() will instantiate any scope
  371. // names in the identifier. It's useful for fully
  372. // defining a type while instantiating a class.
  373. ////////////////////////////////////////////////////////////////////
  374. CPPType *CPPIdentifier::
  375. find_type(CPPScope *current_scope, CPPScope *global_scope,
  376. CPPDeclaration::SubstDecl &subst,
  377. CPPPreprocessor *error_sink) const {
  378. CPPScope *scope = get_scope(current_scope, global_scope, subst, error_sink);
  379. if (scope == NULL) {
  380. return NULL;
  381. }
  382. CPPType *type = scope->find_type(get_simple_name(), subst, global_scope);
  383. if (type != NULL && _names.back().has_templ()) {
  384. // This is a template type.
  385. if (is_fully_specified()) {
  386. // If our identifier fully specifies the instantiation, then
  387. // apply it.
  388. CPPDeclaration *decl =
  389. type->instantiate(_names.back().get_templ(),
  390. current_scope, global_scope,
  391. error_sink);
  392. assert(decl != NULL);
  393. CPPType *new_type = decl->as_type();
  394. assert(new_type != NULL);
  395. if (new_type == type) {
  396. type = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
  397. } else {
  398. type = new_type;
  399. }
  400. } else {
  401. // Otherwise, we'll have to instantiate the type later.
  402. type = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
  403. }
  404. // type->_file.replace_nearer(_file);
  405. }
  406. return type;
  407. }
  408. ////////////////////////////////////////////////////////////////////
  409. // Function: CPPIdentifier::find_symbol
  410. // Access: Public
  411. // Description:
  412. ////////////////////////////////////////////////////////////////////
  413. CPPDeclaration *CPPIdentifier::
  414. find_symbol(CPPScope *current_scope, CPPScope *global_scope,
  415. CPPPreprocessor *error_sink) const {
  416. CPPScope *scope = get_scope(current_scope, global_scope, error_sink);
  417. if (scope == NULL) {
  418. return NULL;
  419. }
  420. CPPDeclaration *sym;
  421. if (!_names.back().has_templ()) {
  422. if (_names.size() > 1 && scope->get_simple_name() == get_simple_name()) {
  423. // An identifier like Class::Class always refers to the class constructor.
  424. sym = scope->get_struct_type()->get_constructor();
  425. } else {
  426. sym = scope->find_symbol(get_simple_name());
  427. }
  428. } else {
  429. sym = scope->find_template(get_simple_name());
  430. if (sym != NULL) {
  431. CPPType *type = sym->as_type();
  432. if (type != NULL && type->is_incomplete()) {
  433. // We can't instantiate an incomplete type.
  434. sym = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
  435. } else {
  436. // Instantiate the symbol.
  437. sym = sym->instantiate(_names.back().get_templ(), current_scope,
  438. global_scope, error_sink);
  439. }
  440. }
  441. }
  442. return sym;
  443. }
  444. ////////////////////////////////////////////////////////////////////
  445. // Function: CPPIdentifier::find_symbol
  446. // Access: Public
  447. // Description:
  448. ////////////////////////////////////////////////////////////////////
  449. CPPDeclaration *CPPIdentifier::
  450. find_symbol(CPPScope *current_scope, CPPScope *global_scope,
  451. CPPDeclaration::SubstDecl &subst,
  452. CPPPreprocessor *error_sink) const {
  453. CPPScope *scope = get_scope(current_scope, global_scope, subst, error_sink);
  454. if (scope == NULL) {
  455. return NULL;
  456. }
  457. CPPDeclaration *sym;
  458. if (!_names.back().has_templ()) {
  459. if (_names.size() > 1 && scope->get_simple_name() == get_simple_name()) {
  460. // An identifier like Class::Class always refers to the class constructor.
  461. sym = scope->get_struct_type()->get_constructor();
  462. } else {
  463. sym = scope->find_symbol(get_simple_name());
  464. }
  465. } else {
  466. sym = scope->find_template(get_simple_name());
  467. if (sym != NULL) {
  468. CPPType *type = sym->as_type();
  469. if (type != NULL && type->is_incomplete()) {
  470. // We can't instantiate an incomplete type.
  471. sym = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
  472. } else {
  473. // Instantiate the symbol.
  474. sym = sym->instantiate(_names.back().get_templ(), current_scope,
  475. global_scope, error_sink);
  476. }
  477. }
  478. }
  479. return sym;
  480. }
  481. ////////////////////////////////////////////////////////////////////
  482. // Function: CPPIdentifier::find_template
  483. // Access: Public
  484. // Description:
  485. ////////////////////////////////////////////////////////////////////
  486. CPPDeclaration *CPPIdentifier::
  487. find_template(CPPScope *current_scope, CPPScope *global_scope,
  488. CPPPreprocessor *error_sink) const {
  489. CPPScope *scope = get_scope(current_scope, global_scope, error_sink);
  490. if (scope == NULL) {
  491. return NULL;
  492. }
  493. return scope->find_template(get_simple_name());
  494. }
  495. ////////////////////////////////////////////////////////////////////
  496. // Function: CPPIdentifier::find_scope
  497. // Access: Public
  498. // Description:
  499. ////////////////////////////////////////////////////////////////////
  500. CPPScope *CPPIdentifier::
  501. find_scope(CPPScope *current_scope, CPPScope *global_scope,
  502. CPPPreprocessor *error_sink) const {
  503. CPPScope *scope = get_scope(current_scope, global_scope, error_sink);
  504. if (scope == NULL) {
  505. return NULL;
  506. }
  507. return scope->find_scope(get_simple_name());
  508. }
  509. ////////////////////////////////////////////////////////////////////
  510. // Function: CPPIdentifier::substitute_decl
  511. // Access: Public
  512. // Description:
  513. ////////////////////////////////////////////////////////////////////
  514. CPPIdentifier *CPPIdentifier::
  515. substitute_decl(CPPDeclaration::SubstDecl &subst,
  516. CPPScope *current_scope, CPPScope *global_scope) {
  517. CPPIdentifier *rep = new CPPIdentifier(*this);
  518. bool anything_changed = false;
  519. for (int i = 0; i < (int)rep->_names.size(); ++i) {
  520. if (_names[i].has_templ()) {
  521. rep->_names[i].set_templ
  522. (_names[i].get_templ()->substitute_decl(subst, current_scope, global_scope));
  523. if (rep->_names[i].get_templ() != _names[i].get_templ()) {
  524. anything_changed = true;
  525. }
  526. }
  527. }
  528. if (!anything_changed) {
  529. delete rep;
  530. rep = this;
  531. }
  532. return rep;
  533. }
  534. ////////////////////////////////////////////////////////////////////
  535. // Function: CPPIdentifier::output
  536. // Access: Public
  537. // Description:
  538. ////////////////////////////////////////////////////////////////////
  539. void CPPIdentifier::
  540. output(ostream &out, CPPScope *scope) const {
  541. if (scope == NULL) {
  542. output_fully_scoped_name(out);
  543. } else {
  544. output_local_name(out, scope);
  545. }
  546. }
  547. ////////////////////////////////////////////////////////////////////
  548. // Function: CPPIdentifier::output_local_name
  549. // Access: Public
  550. // Description:
  551. ////////////////////////////////////////////////////////////////////
  552. void CPPIdentifier::
  553. output_local_name(ostream &out, CPPScope *scope) const {
  554. assert(!_names.empty());
  555. if (scope == NULL || (_native_scope == NULL && _names.size() == 1)) {
  556. out << _names.back();
  557. } else if (_names.front().empty()) {
  558. output_fully_scoped_name(out);
  559. } else {
  560. // Determine the scope of everything up until but not including the
  561. // last name.
  562. CPPScope *my_scope = get_scope(scope, NULL);
  563. if (my_scope == NULL) {
  564. output_fully_scoped_name(out);
  565. } else {
  566. out << my_scope->get_local_name(scope) << "::" << _names.back();
  567. }
  568. }
  569. }
  570. ////////////////////////////////////////////////////////////////////
  571. // Function: CPPIdentifier::output_fully_scoped_name
  572. // Access: Public
  573. // Description:
  574. ////////////////////////////////////////////////////////////////////
  575. void CPPIdentifier::
  576. output_fully_scoped_name(ostream &out) const {
  577. if (_native_scope != NULL) {
  578. _native_scope->output(out, (CPPScope *)NULL);
  579. out << "::";
  580. }
  581. Names::const_iterator ni = _names.begin();
  582. out << (*ni);
  583. ++ni;
  584. while (ni != _names.end()) {
  585. out << "::" << (*ni);
  586. ++ni;
  587. }
  588. }