cppIdentifier.cxx 15 KB

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