cppIdentifier.cxx 18 KB

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