cppIdentifier.cxx 18 KB

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