00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "cppIdentifier.h"
00021 #include "cppScope.h"
00022 #include "cppTemplateScope.h"
00023 #include "cppPreprocessor.h"
00024 #include "cppTemplateParameterList.h"
00025 #include "cppTBDType.h"
00026 #include "cppStructType.h"
00027
00028
00029
00030
00031
00032
00033
00034 CPPIdentifier::
00035 CPPIdentifier(const string &name, const CPPFile &file) : _file(file) {
00036 _names.push_back(CPPNameComponent(name));
00037 _native_scope = (CPPScope *)NULL;
00038 }
00039
00040
00041
00042
00043
00044
00045 CPPIdentifier::
00046 CPPIdentifier(const CPPNameComponent &name) {
00047 _names.push_back(name);
00048 _native_scope = (CPPScope *)NULL;
00049 }
00050
00051
00052
00053
00054
00055
00056 void CPPIdentifier::
00057 add_name(const string &name) {
00058 _names.push_back(CPPNameComponent(name));
00059 }
00060
00061
00062
00063
00064
00065
00066 void CPPIdentifier::
00067 add_name(const CPPNameComponent &name) {
00068 _names.push_back(name);
00069 }
00070
00071
00072
00073
00074
00075
00076 bool CPPIdentifier::
00077 operator == (const CPPIdentifier &other) const {
00078 if (_names.size() != other._names.size()) {
00079 return false;
00080 }
00081 for (int i = 0; i < (int)_names.size(); i++) {
00082 if (_names[i] != other._names[i]) {
00083 return false;
00084 }
00085 }
00086
00087 return true;
00088 }
00089
00090
00091
00092
00093
00094
00095 bool CPPIdentifier::
00096 operator != (const CPPIdentifier &other) const {
00097 return !(*this == other);
00098 }
00099
00100
00101
00102
00103
00104
00105 bool CPPIdentifier::
00106 operator < (const CPPIdentifier &other) const {
00107 if (_names.size() != other._names.size()) {
00108 return _names.size() < other._names.size();
00109 }
00110 for (int i = 0; i < (int)_names.size(); i++) {
00111 if (_names[i] != other._names[i]) {
00112 return _names[i] < other._names[i];
00113 }
00114 }
00115
00116 return false;
00117 }
00118
00119
00120
00121
00122
00123
00124 bool CPPIdentifier::
00125 is_scoped() const {
00126 return _names.size() > 1;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135 string CPPIdentifier::
00136 get_simple_name() const {
00137 return _names.back().get_name();
00138 }
00139
00140
00141
00142
00143
00144
00145 string CPPIdentifier::
00146 get_local_name(CPPScope *scope) const {
00147 assert(!_names.empty());
00148
00149 string result;
00150
00151 if (scope == NULL || (_native_scope == NULL && _names.size() == 1)) {
00152 result = _names.back().get_name_with_templ(scope);
00153 } else if (_names.front().empty()) {
00154 result = get_fully_scoped_name();
00155 } else {
00156
00157
00158 CPPScope *my_scope = get_scope(scope, NULL);
00159
00160 if (my_scope == NULL) {
00161 result = get_fully_scoped_name();
00162 } else if (my_scope == scope) {
00163 return _names.back().get_name_with_templ(scope);
00164 } else {
00165 result = my_scope->get_local_name(scope);
00166 if (!result.empty()) {
00167 result += "::";
00168 }
00169 result += _names.back().get_name_with_templ(scope);
00170 }
00171 }
00172 return result;
00173 }
00174
00175
00176
00177
00178
00179
00180 string CPPIdentifier::
00181 get_fully_scoped_name() const {
00182 assert(!_names.empty());
00183 Names::const_iterator ni = _names.begin();
00184 string name = (*ni).get_name_with_templ();
00185 ++ni;
00186 while (ni != _names.end()) {
00187 name += "::" + (*ni).get_name_with_templ();
00188 ++ni;
00189 }
00190 return name;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 bool CPPIdentifier::
00202 is_fully_specified() const {
00203 Names::const_iterator ni;
00204 for (ni = _names.begin(); ni != _names.end(); ++ni) {
00205 if ((*ni).has_templ() && !(*ni).get_templ()->is_fully_specified()) {
00206 return false;
00207 }
00208 }
00209
00210 return true;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220 bool CPPIdentifier::
00221 is_tbd() const {
00222 Names::const_iterator ni;
00223 for (ni = _names.begin(); ni != _names.end(); ++ni) {
00224 if ((*ni).is_tbd()) {
00225 return true;
00226 }
00227 }
00228
00229 return false;
00230 }
00231
00232
00233
00234
00235
00236
00237 CPPScope *CPPIdentifier::
00238 get_scope(CPPScope *current_scope, CPPScope *global_scope,
00239 CPPPreprocessor *error_sink) const {
00240 assert(!_names.empty());
00241
00242 CPPScope *scope = _native_scope;
00243 if (scope == (CPPScope *)NULL) {
00244 scope = current_scope;
00245 }
00246 int i = 0;
00247
00248 if (_names[i].empty()) {
00249
00250
00251 scope = global_scope;
00252 i++;
00253 }
00254
00255 while (i + 1 < (int)_names.size() && scope != NULL) {
00256 CPPScope *next_scope = scope->find_scope(_names[i].get_name());
00257 if (next_scope == (CPPScope *)NULL) {
00258 if (error_sink != NULL) {
00259 error_sink->error("Symbol " + _names[i].get_name() +
00260 " is not a known scope in " +
00261 scope->get_fully_scoped_name());
00262 }
00263 return (CPPScope *)NULL;
00264 }
00265 if (_names[i].has_templ()) {
00266 next_scope = next_scope->instantiate(_names[i].get_templ(),
00267 current_scope, global_scope);
00268 }
00269 scope = next_scope;
00270 i++;
00271 }
00272
00273 return scope;
00274 }
00275
00276
00277
00278
00279
00280
00281 CPPScope *CPPIdentifier::
00282 get_scope(CPPScope *current_scope, CPPScope *global_scope,
00283 CPPDeclaration::SubstDecl &subst,
00284 CPPPreprocessor *error_sink) const {
00285 assert(!_names.empty());
00286
00287 CPPScope *scope = _native_scope;
00288 if (scope == (CPPScope *)NULL) {
00289 scope = current_scope;
00290 }
00291 int i = 0;
00292
00293 if (_names[i].empty()) {
00294
00295
00296 scope = global_scope;
00297 i++;
00298 }
00299
00300 while (i + 1 < (int)_names.size() && scope != NULL) {
00301 CPPScope *next_scope = scope->find_scope(_names[i].get_name(), subst,
00302 global_scope);
00303 if (next_scope == (CPPScope *)NULL) {
00304 if (error_sink != NULL) {
00305 error_sink->error("Symbol " + _names[i].get_name() +
00306 " is not a known scope in " +
00307 scope->get_fully_scoped_name());
00308 }
00309 return (CPPScope *)NULL;
00310 }
00311 if (_names[i].has_templ()) {
00312 next_scope = next_scope->instantiate(_names[i].get_templ(),
00313 current_scope, global_scope);
00314 }
00315 scope = next_scope;
00316 i++;
00317 }
00318
00319 return scope;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 CPPType *CPPIdentifier::
00336 find_type(CPPScope *current_scope, CPPScope *global_scope,
00337 bool force_instantiate,
00338 CPPPreprocessor *error_sink) const {
00339 CPPScope *scope = get_scope(current_scope, global_scope, error_sink);
00340 if (scope == NULL) {
00341 return NULL;
00342 }
00343
00344 CPPType *type = NULL;
00345 if (!_names.back().has_templ()) {
00346 type = scope->find_type(get_simple_name());
00347
00348 } else {
00349 CPPDeclaration *decl = find_symbol(current_scope, global_scope, error_sink);
00350 type = decl->as_type();
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 }
00371 return type;
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381 CPPType *CPPIdentifier::
00382 find_type(CPPScope *current_scope, CPPScope *global_scope,
00383 CPPDeclaration::SubstDecl &subst,
00384 CPPPreprocessor *error_sink) const {
00385 CPPScope *scope = get_scope(current_scope, global_scope, subst, error_sink);
00386 if (scope == NULL) {
00387 return NULL;
00388 }
00389 CPPType *type = scope->find_type(get_simple_name(), subst, global_scope);
00390 if (type != NULL && _names.back().has_templ()) {
00391
00392
00393 if (is_fully_specified()) {
00394
00395
00396 CPPDeclaration *decl =
00397 type->instantiate(_names.back().get_templ(),
00398 current_scope, global_scope,
00399 error_sink);
00400 assert(decl != NULL);
00401 CPPType *new_type = decl->as_type();
00402 assert(new_type != NULL);
00403 if (new_type == type) {
00404 type = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
00405
00406 } else {
00407 type = new_type;
00408 }
00409 } else {
00410
00411 type = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
00412 }
00413
00414 }
00415 return type;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424 CPPDeclaration *CPPIdentifier::
00425 find_symbol(CPPScope *current_scope, CPPScope *global_scope,
00426 CPPPreprocessor *error_sink) const {
00427 CPPScope *scope = get_scope(current_scope, global_scope, error_sink);
00428 if (scope == NULL) {
00429 return NULL;
00430 }
00431 CPPDeclaration *sym;
00432 if (!_names.back().has_templ()) {
00433 sym = scope->find_symbol(get_simple_name());
00434
00435 } else {
00436 sym = scope->find_template(get_simple_name());
00437 if (sym != NULL) {
00438 CPPType *type = sym->as_type();
00439 if (type != NULL && type->is_incomplete()) {
00440
00441 sym = CPPType::new_type(new CPPTBDType((CPPIdentifier *)this));
00442 } else {
00443
00444 sym = sym->instantiate(_names.back().get_templ(), current_scope,
00445 global_scope, error_sink);
00446 }
00447 }
00448 }
00449
00450 return sym;
00451 }
00452
00453
00454
00455
00456
00457
00458 CPPDeclaration *CPPIdentifier::
00459 find_template(CPPScope *current_scope, CPPScope *global_scope,
00460 CPPPreprocessor *error_sink) const {
00461 CPPScope *scope = get_scope(current_scope, global_scope, error_sink);
00462 if (scope == NULL) {
00463 return NULL;
00464 }
00465 return scope->find_template(get_simple_name());
00466 }
00467
00468
00469
00470
00471
00472
00473 CPPScope *CPPIdentifier::
00474 find_scope(CPPScope *current_scope, CPPScope *global_scope,
00475 CPPPreprocessor *error_sink) const {
00476 CPPScope *scope = get_scope(current_scope, global_scope, error_sink);
00477 if (scope == NULL) {
00478 return NULL;
00479 }
00480 return scope->find_scope(get_simple_name());
00481 }
00482
00483
00484
00485
00486
00487
00488
00489 CPPIdentifier *CPPIdentifier::
00490 substitute_decl(CPPDeclaration::SubstDecl &subst,
00491 CPPScope *current_scope, CPPScope *global_scope) {
00492 CPPIdentifier *rep = new CPPIdentifier(*this);
00493
00494 bool anything_changed = false;
00495 for (int i = 0; i < (int)rep->_names.size(); i++) {
00496 if (_names[i].has_templ()) {
00497 rep->_names[i].set_templ
00498 (_names[i].get_templ()->substitute_decl(subst, current_scope, global_scope));
00499 if (rep->_names[i].get_templ() != _names[i].get_templ()) {
00500 anything_changed = true;
00501 }
00502 }
00503 }
00504
00505 if (!anything_changed) {
00506 delete rep;
00507 rep = this;
00508 }
00509
00510 return rep;
00511 }
00512
00513
00514
00515
00516
00517
00518 void CPPIdentifier::
00519 output(ostream &out, CPPScope *scope) const {
00520 if (scope == NULL) {
00521 output_fully_scoped_name(out);
00522 } else {
00523 output_local_name(out, scope);
00524 }
00525 }
00526
00527
00528
00529
00530
00531
00532
00533 void CPPIdentifier::
00534 output_local_name(ostream &out, CPPScope *scope) const {
00535 assert(!_names.empty());
00536
00537 if (scope == NULL || (_native_scope == NULL && _names.size() == 1)) {
00538 out << _names.back();
00539 } else if (_names.front().empty()) {
00540 output_fully_scoped_name(out);
00541 } else {
00542
00543
00544 CPPScope *my_scope = get_scope(scope, NULL);
00545
00546 if (my_scope == NULL) {
00547 output_fully_scoped_name(out);
00548 } else {
00549 out << my_scope->get_local_name(scope) << "::" << _names.back();
00550 }
00551 }
00552 }
00553
00554
00555
00556
00557
00558
00559 void CPPIdentifier::
00560 output_fully_scoped_name(ostream &out) const {
00561 if (_native_scope != NULL) {
00562 _native_scope->output(out, (CPPScope *)NULL);
00563 out << "::";
00564 }
00565 Names::const_iterator ni = _names.begin();
00566 out << (*ni);
00567 ++ni;
00568 while (ni != _names.end()) {
00569 out << "::" << (*ni);
00570 ++ni;
00571 }
00572 }
00573