00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "cppScope.h"
00021 #include "cppDeclaration.h"
00022 #include "cppNamespace.h"
00023 #include "cppTypedef.h"
00024 #include "cppTypeDeclaration.h"
00025 #include "cppExtensionType.h"
00026 #include "cppInstance.h"
00027 #include "cppInstanceIdentifier.h"
00028 #include "cppIdentifier.h"
00029 #include "cppStructType.h"
00030 #include "cppFunctionGroup.h"
00031 #include "cppPreprocessor.h"
00032 #include "cppTemplateScope.h"
00033 #include "cppClassTemplateParameter.h"
00034 #include "cppFunctionType.h"
00035 #include "cppUsing.h"
00036 #include "cppBisonDefs.h"
00037 #include "indent.h"
00038
00039
00040
00041
00042
00043
00044 CPPScope::
00045 CPPScope(CPPScope *parent_scope,
00046 const CPPNameComponent &name, CPPVisibility starting_vis) :
00047 _name(name),
00048 _parent_scope(parent_scope),
00049 _current_vis(starting_vis)
00050 {
00051 _struct_type = NULL;
00052 _is_fully_specified = false;
00053 _fully_specified_known = false;
00054 _is_fully_specified_recursive_protect = false;
00055 _subst_decl_recursive_protect = false;
00056 }
00057
00058
00059
00060
00061
00062
00063 CPPScope::
00064 ~CPPScope() {
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 void CPPScope::
00077 set_struct_type(CPPStructType *struct_type) {
00078 _struct_type = struct_type;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087 CPPStructType *CPPScope::
00088 get_struct_type() const {
00089 return _struct_type;
00090 }
00091
00092
00093
00094
00095
00096
00097 CPPScope *CPPScope::
00098 get_parent_scope() const {
00099 return _parent_scope;
00100 }
00101
00102
00103
00104
00105
00106
00107 void CPPScope::
00108 set_current_vis(CPPVisibility current_vis) {
00109 _current_vis = current_vis;
00110 }
00111
00112
00113
00114
00115
00116
00117 CPPVisibility CPPScope::
00118 get_current_vis() const {
00119 return _current_vis;
00120 }
00121
00122
00123
00124
00125
00126
00127 void CPPScope::
00128 add_declaration(CPPDeclaration *decl, CPPScope *global_scope,
00129 CPPPreprocessor *preprocessor, const cppyyltype &pos) {
00130 decl->_vis = _current_vis;
00131
00132
00133
00134
00135
00136 if (decl->_leading_comment == (CPPCommentBlock *)NULL) {
00137 decl->_leading_comment =
00138 preprocessor->get_comment_before(pos.first_line, pos.file);
00139 }
00140
00141 _declarations.push_back(decl);
00142
00143 handle_declaration(decl, global_scope);
00144 }
00145
00146
00147
00148
00149
00150
00151 void CPPScope::
00152 add_enum_value(CPPInstance *inst) {
00153 inst->_vis = _current_vis;
00154
00155 string name = inst->get_simple_name();
00156 if (!name.empty()) {
00157 _enum_values[name] = inst;
00158 }
00159 }
00160
00161
00162
00163
00164
00165
00166 void CPPScope::
00167 define_extension_type(CPPExtensionType *type) {
00168 assert(type != NULL);
00169 string name = type->get_simple_name();
00170
00171 switch (type->_type) {
00172 case CPPExtensionType::T_class:
00173 _classes[name] = type;
00174 break;
00175
00176 case CPPExtensionType::T_struct:
00177 _structs[name] = type;
00178 break;
00179
00180 case CPPExtensionType::T_union:
00181 _unions[name] = type;
00182
00183 case CPPExtensionType::T_enum:
00184 _enums[name] = type;
00185 }
00186
00187
00188 CPPIdentifier *ident = new CPPIdentifier(name);
00189 CPPTypedef *td = new CPPTypedef(new CPPInstance(type, ident), false);
00190 pair<Typedefs::iterator, bool> result =
00191 _typedefs.insert(Typedefs::value_type(name, td));
00192
00193 if (!result.second) {
00194
00195
00196
00197 CPPType *other_type = (*result.first).second->_type;
00198 if (type->is_template() && !other_type->is_template()) {
00199 (*result.first).second = td;
00200
00201
00202 } else if (other_type->get_subtype() == CPPDeclaration::ST_extension) {
00203 (*result.first).second = td;
00204 }
00205 }
00206
00207 if (type->is_template()) {
00208 pair<Templates::iterator, bool> result =
00209 _templates.insert(Templates::value_type(name, type));
00210
00211 if (!result.second) {
00212
00213
00214
00215 CPPDeclaration *old_templ = (*result.first).second;
00216 CPPType *old_templ_type = old_templ->as_type();
00217 if (old_templ_type == NULL || old_templ_type->is_incomplete()) {
00218
00219
00220 (*result.first).second = type;
00221 }
00222 }
00223 }
00224 }
00225
00226
00227
00228
00229
00230
00231 void CPPScope::
00232 define_namespace(CPPNamespace *scope) {
00233 string name = scope->get_simple_name();
00234
00235 _namespaces[name] = scope;
00236 }
00237
00238
00239
00240
00241
00242
00243 void CPPScope::
00244 add_using(CPPUsing *using_decl, CPPScope *global_scope,
00245 CPPPreprocessor *error_sink) {
00246 if (using_decl->_full_namespace) {
00247 CPPScope *scope =
00248 using_decl->_ident->find_scope(this, global_scope);
00249 if (scope != NULL) {
00250 _using.insert(scope);
00251 } else {
00252 if (error_sink != NULL) {
00253 error_sink->warning("Attempt to use undefined namespace: " + using_decl->_ident->get_fully_scoped_name());
00254 }
00255 }
00256 } else {
00257 CPPDeclaration *decl = using_decl->_ident->find_symbol(this, global_scope);
00258 if (decl != NULL) {
00259 handle_declaration(decl, global_scope);
00260 } else {
00261 if (error_sink != NULL) {
00262 error_sink->warning("Attempt to use unknown symbol: " + using_decl->_ident->get_fully_scoped_name());
00263 }
00264 }
00265 }
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 bool CPPScope::
00277 is_fully_specified() const {
00278 if (_fully_specified_known) {
00279 return _is_fully_specified;
00280 }
00281
00282 if (_is_fully_specified_recursive_protect) {
00283
00284 return true;
00285 }
00286 ((CPPScope *)this)->_is_fully_specified_recursive_protect = true;
00287
00288 bool specified = true;
00289
00290 if (_parent_scope != NULL && !_parent_scope->is_fully_specified()) {
00291 specified = false;
00292 }
00293
00294 Declarations::const_iterator di;
00295 for (di = _declarations.begin();
00296 di != _declarations.end() && specified;
00297 ++di) {
00298 if (!(*di)->is_fully_specified()) {
00299 specified = false;
00300 }
00301 }
00302
00303 ((CPPScope *)this)->_fully_specified_known = true;
00304 ((CPPScope *)this)->_is_fully_specified = specified;
00305 ((CPPScope *)this)->_is_fully_specified_recursive_protect = false;
00306
00307 return specified;
00308 }
00309
00310
00311
00312
00313
00314
00315 CPPScope *CPPScope::
00316 instantiate(const CPPTemplateParameterList *actual_params,
00317 CPPScope *current_scope, CPPScope *global_scope,
00318 CPPPreprocessor *error_sink) const {
00319 CPPScope *this_scope = (CPPScope *)this;
00320
00321 if (_parent_scope == NULL ||
00322 _parent_scope->as_template_scope() == NULL) {
00323 if (error_sink != NULL) {
00324 error_sink->warning("Ignoring template parameters for scope " +
00325 get_local_name());
00326 }
00327 return this_scope;
00328 }
00329
00330 if (is_fully_specified()) {
00331 return this_scope;
00332 }
00333
00334 Instantiations::const_iterator ii;
00335 ii = _instantiations.find(actual_params);
00336 if (ii != _instantiations.end()) {
00337
00338
00339 return (*ii).second;
00340 }
00341
00342
00343
00344
00345
00346
00347
00348 CPPTemplateScope *tscope = _parent_scope->as_template_scope();
00349 CPPDeclaration::SubstDecl subst;
00350 actual_params->build_subst_decl(tscope->_parameters, subst,
00351 current_scope, global_scope);
00352
00353 CPPScope *scope;
00354 if (subst.empty()) {
00355 scope = (CPPScope *)this;
00356
00357 } else {
00358 CPPNameComponent name = _name;
00359 name.set_templ(new CPPTemplateParameterList(*actual_params));
00360
00361 scope = new CPPScope(_parent_scope, name, V_public);
00362 copy_substitute_decl(scope, subst, global_scope);
00363
00364
00365
00366 CPPTemplateParameterList::Parameters::const_iterator pi;
00367 for (pi = actual_params->_parameters.begin();
00368 pi != actual_params->_parameters.end();
00369 ++pi) {
00370 CPPDeclaration *decl = (*pi);
00371 CPPClassTemplateParameter *ctp = decl->as_class_template_parameter();
00372 if (ctp != NULL) {
00373 CPPInstance *inst = new CPPInstance(ctp, ctp->_ident);
00374 CPPTypedef *td = new CPPTypedef(inst, true);
00375 scope->_typedefs.insert(Typedefs::value_type
00376 (ctp->_ident->get_local_name(),
00377 td));
00378 }
00379 }
00380 }
00381
00382
00383
00384 ((CPPScope *)this)->_instantiations.insert(Instantiations::value_type(actual_params, scope));
00385
00386 return scope;
00387 }
00388
00389
00390
00391
00392
00393
00394 CPPScope *CPPScope::
00395 substitute_decl(CPPDeclaration::SubstDecl &subst,
00396 CPPScope *current_scope, CPPScope *global_scope) const {
00397 CPPScope *this_scope = (CPPScope *)this;
00398
00399 if (is_fully_specified()) {
00400 return this_scope;
00401 }
00402
00403 if (_subst_decl_recursive_protect) {
00404
00405 return this_scope;
00406 }
00407 ((CPPScope *)this)->_subst_decl_recursive_protect = true;
00408
00409 CPPScope *rep = new CPPScope(current_scope, _name, V_public);
00410 bool anything_changed;
00411
00412 if (_parent_scope != NULL &&
00413 _parent_scope->as_template_scope() != NULL) {
00414
00415
00416
00417
00418 const CPPTemplateParameterList &p =
00419 _parent_scope->as_template_scope()->_parameters;
00420
00421 CPPDeclaration::SubstDecl new_subst = subst;
00422 CPPTemplateParameterList::Parameters::const_iterator pi;
00423 for (pi = p._parameters.begin(); pi != p._parameters.end(); ++pi) {
00424 new_subst.erase(*pi);
00425 }
00426 anything_changed = copy_substitute_decl(rep, new_subst, global_scope);
00427 } else {
00428 anything_changed = copy_substitute_decl(rep, subst, global_scope);
00429 }
00430
00431 if (!anything_changed && rep->_parent_scope == _parent_scope) {
00432 delete rep;
00433 rep = (CPPScope *)this;
00434 }
00435 ((CPPScope *)this)->_subst_decl_recursive_protect = false;
00436
00437 return rep;
00438 }
00439
00440
00441
00442
00443
00444
00445 CPPType *CPPScope::
00446 find_type(const string &name, bool recurse) const {
00447 Typedefs::const_iterator ti;
00448 ti = _typedefs.find(name);
00449 if (ti != _typedefs.end()) {
00450 return (*ti).second->_type;
00451 }
00452
00453 Using::const_iterator ui;
00454 for (ui = _using.begin(); ui != _using.end(); ++ui) {
00455 CPPType *type = (*ui)->find_type(name, false);
00456 if (type != NULL) {
00457 return type;
00458 }
00459 }
00460
00461 if (_struct_type != NULL) {
00462 CPPStructType::Derivation::const_iterator di;
00463 for (di = _struct_type->_derivation.begin();
00464 di != _struct_type->_derivation.end();
00465 ++di) {
00466 CPPStructType *st = (*di)._base->as_struct_type();
00467 if (st != NULL) {
00468 CPPType *type = st->_scope->find_type(name, false);
00469 if (type != NULL) {
00470 return type;
00471 }
00472 }
00473 }
00474 }
00475
00476 if (recurse && _parent_scope != NULL) {
00477 return _parent_scope->find_type(name);
00478 }
00479
00480 return NULL;
00481 }
00482
00483
00484
00485
00486
00487
00488 CPPType *CPPScope::
00489 find_type(const string &name, CPPDeclaration::SubstDecl &subst,
00490 CPPScope *global_scope, bool recurse) const {
00491 Typedefs::const_iterator ti;
00492 ti = _typedefs.find(name);
00493 if (ti != _typedefs.end()) {
00494 CPPScope *current_scope = (CPPScope *)this;
00495 return (*ti).second->_type->substitute_decl
00496 (subst, current_scope, global_scope)->as_type();
00497 }
00498
00499 Using::const_iterator ui;
00500 for (ui = _using.begin(); ui != _using.end(); ++ui) {
00501 CPPType *type = (*ui)->find_type(name, subst, global_scope, false);
00502 if (type != NULL) {
00503 return type;
00504 }
00505 }
00506
00507 if (_struct_type != NULL) {
00508 CPPStructType::Derivation::const_iterator di;
00509 for (di = _struct_type->_derivation.begin();
00510 di != _struct_type->_derivation.end();
00511 ++di) {
00512 CPPStructType *st = (*di)._base->as_struct_type();
00513 if (st != NULL) {
00514 CPPType *type = st->_scope->find_type(name, subst, global_scope,
00515 false);
00516 if (type != NULL) {
00517 return type;
00518 }
00519 }
00520 }
00521 }
00522
00523 if (recurse && _parent_scope != NULL) {
00524 return _parent_scope->find_type(name, subst, global_scope);
00525 }
00526
00527 return NULL;
00528 }
00529
00530
00531
00532
00533
00534
00535 CPPScope *CPPScope::
00536 find_scope(const string &name, bool recurse) const {
00537 Namespaces::const_iterator ni = _namespaces.find(name);
00538 if (ni != _namespaces.end()) {
00539 return (*ni).second->get_scope();
00540 }
00541
00542 CPPType *type = (CPPType *)NULL;
00543
00544 Typedefs::const_iterator ti;
00545 ti = _typedefs.find(name);
00546 if (ti != _typedefs.end()) {
00547 type = (*ti).second->_type;
00548
00549 } else if (_struct_type != NULL) {
00550 CPPStructType::Derivation::const_iterator di;
00551 for (di = _struct_type->_derivation.begin();
00552 di != _struct_type->_derivation.end();
00553 ++di) {
00554 CPPStructType *st = (*di)._base->as_struct_type();
00555 if (st != NULL) {
00556 type = st->_scope->find_type(name, false);
00557 }
00558 }
00559 }
00560
00561 if (type != NULL) {
00562 CPPStructType *st = type->as_struct_type();
00563 if (st != NULL) {
00564 return st->_scope;
00565 }
00566 }
00567
00568 Using::const_iterator ui;
00569 for (ui = _using.begin(); ui != _using.end(); ++ui) {
00570 CPPScope *scope = (*ui)->find_scope(name, false);
00571 if (scope != NULL) {
00572 return scope;
00573 }
00574 }
00575
00576 if (recurse && _parent_scope != NULL) {
00577 return _parent_scope->find_scope(name);
00578 }
00579
00580 return (CPPScope *)NULL;
00581 }
00582
00583
00584
00585
00586
00587
00588 CPPScope *CPPScope::
00589 find_scope(const string &name, CPPDeclaration::SubstDecl &subst,
00590 CPPScope *global_scope, bool recurse) const {
00591 CPPType *type = find_type(name, subst, global_scope, recurse);
00592 if (type == NULL) {
00593 return NULL;
00594 }
00595 CPPStructType *st = type->as_struct_type();
00596 if (st == NULL) {
00597 return NULL;
00598 }
00599 return st->_scope;
00600 }
00601
00602
00603
00604
00605
00606
00607 CPPDeclaration *CPPScope::
00608 find_symbol(const string &name, bool recurse) const {
00609 if (_struct_type != NULL && name == get_simple_name()) {
00610 return _struct_type;
00611 }
00612
00613 Typedefs::const_iterator ti;
00614 ti = _typedefs.find(name);
00615 if (ti != _typedefs.end()) {
00616 return (*ti).second->_type;
00617 }
00618
00619 Variables::const_iterator vi;
00620 vi = _variables.find(name);
00621 if (vi != _variables.end()) {
00622 return (*vi).second;
00623 }
00624
00625 vi = _enum_values.find(name);
00626 if (vi != _enum_values.end()) {
00627 return (*vi).second;
00628 }
00629
00630 Functions::const_iterator fi;
00631 fi = _functions.find(name);
00632 if (fi != _functions.end()) {
00633 return (*fi).second;
00634 }
00635
00636 Using::const_iterator ui;
00637 for (ui = _using.begin(); ui != _using.end(); ++ui) {
00638 CPPDeclaration *decl = (*ui)->find_symbol(name, false);
00639 if (decl != NULL) {
00640 return decl;
00641 }
00642 }
00643
00644 if (_struct_type != NULL) {
00645 CPPStructType::Derivation::const_iterator di;
00646 for (di = _struct_type->_derivation.begin();
00647 di != _struct_type->_derivation.end();
00648 ++di) {
00649 CPPStructType *st = (*di)._base->as_struct_type();
00650 if (st != NULL) {
00651 CPPDeclaration *decl = st->_scope->find_symbol(name, false);
00652 if (decl != NULL) {
00653 return decl;
00654 }
00655 }
00656 }
00657 }
00658
00659 if (recurse && _parent_scope != NULL) {
00660 return _parent_scope->find_symbol(name);
00661 }
00662
00663 return NULL;
00664 }
00665
00666
00667
00668
00669
00670
00671 CPPDeclaration *CPPScope::
00672 find_template(const string &name, bool recurse) const {
00673 Templates::const_iterator ti;
00674 ti = _templates.find(name);
00675 if (ti != _templates.end()) {
00676 return (*ti).second;
00677 }
00678
00679 Using::const_iterator ui;
00680 for (ui = _using.begin(); ui != _using.end(); ++ui) {
00681 CPPDeclaration *decl = (*ui)->find_template(name, false);
00682 if (decl != NULL) {
00683 return decl;
00684 }
00685 }
00686
00687 if (_struct_type != NULL) {
00688 CPPStructType::Derivation::const_iterator di;
00689 for (di = _struct_type->_derivation.begin();
00690 di != _struct_type->_derivation.end();
00691 ++di) {
00692 CPPStructType *st = (*di)._base->as_struct_type();
00693 if (st != NULL) {
00694 CPPDeclaration *decl = st->_scope->find_template(name, false);
00695 if (decl != NULL) {
00696 return decl;
00697 }
00698 }
00699 }
00700 }
00701
00702 if (recurse && _parent_scope != NULL) {
00703 return _parent_scope->find_template(name);
00704 }
00705
00706 return NULL;
00707 }
00708
00709
00710
00711
00712
00713
00714 string CPPScope::
00715 get_simple_name() const {
00716
00717
00718
00719
00720
00721 return _name.get_name();
00722 }
00723
00724
00725
00726
00727
00728
00729 string CPPScope::
00730 get_local_name(CPPScope *scope) const {
00731
00732
00733
00734
00735
00736
00737 if (scope != NULL && _parent_scope != NULL && _parent_scope != scope) {
00738 return _parent_scope->get_local_name(scope) + "::" +
00739 _name.get_name_with_templ();
00740 } else {
00741 return _name.get_name_with_templ();
00742 }
00743 }
00744
00745
00746
00747
00748
00749
00750 string CPPScope::
00751 get_fully_scoped_name() const {
00752
00753
00754
00755
00756
00757
00758 if (_parent_scope != NULL) {
00759 return _parent_scope->get_fully_scoped_name() + "::" +
00760 _name.get_name_with_templ();
00761 } else {
00762 return _name.get_name_with_templ();
00763 }
00764 }
00765
00766
00767
00768
00769
00770
00771 void CPPScope::
00772 output(ostream &out, CPPScope *scope) const {
00773
00774 if (_parent_scope != NULL && _parent_scope != scope) {
00775 _parent_scope->output(out, scope);
00776 out << "::";
00777 }
00778 out << _name;
00779 }
00780
00781
00782
00783
00784
00785
00786 void CPPScope::
00787 write(ostream &out, int indent_level, CPPScope *scope) const {
00788 CPPVisibility vis = V_unknown;
00789 Declarations::const_iterator di;
00790 for (di = _declarations.begin(); di != _declarations.end(); ++di) {
00791 CPPDeclaration *cd = (*di);
00792 if (cd->_vis != vis && indent_level > 0) {
00793 vis = cd->_vis;
00794 indent(out, indent_level - 2) << vis << ":\n";
00795 }
00796 bool complete = false;
00797
00798 if (cd->as_typedef() != NULL || cd->as_type() != NULL ||
00799 cd->as_namespace() != NULL) {
00800 complete = true;
00801 }
00802
00803 indent(out, indent_level);
00804 cd->output(out, indent_level, scope, complete);
00805 out << ";\n";
00806 }
00807 }
00808
00809
00810
00811
00812
00813
00814
00815
00816 CPPTemplateScope *CPPScope::
00817 get_template_scope() {
00818 if (as_template_scope()) {
00819 return as_template_scope();
00820 }
00821 if (_parent_scope != NULL) {
00822 return _parent_scope->get_template_scope();
00823 }
00824 return (CPPTemplateScope *)NULL;
00825 }
00826
00827
00828
00829
00830
00831
00832 CPPTemplateScope *CPPScope::
00833 as_template_scope() {
00834 return (CPPTemplateScope *)NULL;
00835 }
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850 bool CPPScope::
00851 copy_substitute_decl(CPPScope *to_scope, CPPDeclaration::SubstDecl &subst,
00852 CPPScope *global_scope) const {
00853 bool anything_changed = false;
00854
00855 if (_struct_type != NULL) {
00856 CPPScope *native_scope = (CPPScope *)NULL;
00857 if (_struct_type->_ident != (CPPIdentifier *)NULL) {
00858 native_scope = _struct_type->_ident->_native_scope;
00859 }
00860 to_scope->_struct_type =
00861 new CPPStructType(_struct_type->_type,
00862 new CPPIdentifier(to_scope->_name),
00863 native_scope, to_scope, _struct_type->_file);
00864 to_scope->_struct_type->_incomplete = false;
00865
00866
00867 CPPStructType::Derivation::const_iterator di;
00868 for (di = _struct_type->_derivation.begin();
00869 di != _struct_type->_derivation.end();
00870 ++di) {
00871 CPPStructType::Base b = (*di);
00872 b._base =
00873 (*di)._base->substitute_decl(subst, to_scope, global_scope)->as_type();
00874 to_scope->_struct_type->_derivation.push_back(b);
00875 if (b._base != (*di)._base) {
00876 anything_changed = true;
00877 }
00878 }
00879 }
00880
00881 Declarations::const_iterator di;
00882 for (di = _declarations.begin(); di != _declarations.end(); ++di) {
00883 CPPDeclaration *decl =
00884 (*di)->substitute_decl(subst, to_scope, global_scope);
00885 to_scope->_declarations.push_back(decl);
00886 if (decl != (*di)) {
00887 anything_changed = true;
00888 }
00889 }
00890
00891 ExtensionTypes::const_iterator ei;
00892 for (ei = _structs.begin(); ei != _structs.end(); ++ei) {
00893 string name = (*ei).first;
00894 CPPType *source_type = (*ei).second;
00895 CPPDeclaration *decl =
00896 source_type->substitute_decl(subst, to_scope, global_scope);
00897 assert(decl != NULL);
00898 CPPType *new_type = decl->as_type();
00899 assert(new_type != NULL);
00900 to_scope->_structs.insert(ExtensionTypes::value_type(name, new_type));
00901 if (new_type != source_type) {
00902 anything_changed = true;
00903 }
00904 }
00905 for (ei = _classes.begin(); ei != _classes.end(); ++ei) {
00906 string name = (*ei).first;
00907 CPPType *source_type = (*ei).second;
00908 CPPDeclaration *decl =
00909 source_type->substitute_decl(subst, to_scope, global_scope);
00910 assert(decl != NULL);
00911 CPPType *new_type = decl->as_type();
00912 assert(new_type != NULL);
00913 to_scope->_classes.insert(ExtensionTypes::value_type(name, new_type));
00914 if (new_type != source_type) {
00915 anything_changed = true;
00916 }
00917 }
00918 for (ei = _unions.begin(); ei != _unions.end(); ++ei) {
00919 string name = (*ei).first;
00920 CPPType *source_type = (*ei).second;
00921 CPPDeclaration *decl =
00922 source_type->substitute_decl(subst, to_scope, global_scope);
00923 assert(decl != NULL);
00924 CPPType *new_type = decl->as_type();
00925 assert(new_type != NULL);
00926 to_scope->_unions.insert(ExtensionTypes::value_type(name, new_type));
00927 if (new_type != source_type) {
00928 anything_changed = true;
00929 }
00930 }
00931 for (ei = _enums.begin(); ei != _enums.end(); ++ei) {
00932 string name = (*ei).first;
00933 CPPType *source_type = (*ei).second;
00934 CPPDeclaration *decl =
00935 source_type->substitute_decl(subst, to_scope, global_scope);
00936 assert(decl != NULL);
00937 CPPType *new_type = decl->as_type();
00938 assert(new_type != NULL);
00939 to_scope->_enums.insert(ExtensionTypes::value_type(name, new_type));
00940 if (new_type != source_type) {
00941 anything_changed = true;
00942 }
00943 }
00944 Functions::const_iterator fi;
00945 for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
00946 CPPFunctionGroup *fgroup = (*fi).second;
00947 string name = fgroup->_name;
00948
00949 CPPFunctionGroup *&to_fgroup = to_scope->_functions[name];
00950 if (to_fgroup == (CPPFunctionGroup *)NULL) {
00951 to_fgroup = new CPPFunctionGroup(name);
00952 }
00953
00954 CPPFunctionGroup::Instances::const_iterator ii;
00955 for (ii = fgroup->_instances.begin();
00956 ii != fgroup->_instances.end();
00957 ++ii) {
00958 CPPInstance *inst =
00959 (*ii)->substitute_decl(subst, to_scope, global_scope)->as_instance();
00960 to_fgroup->_instances.push_back(inst);
00961 if (inst != (*ii)) {
00962 anything_changed = true;
00963 }
00964 }
00965 }
00966
00967 Typedefs::const_iterator ti;
00968 for (ti = _typedefs.begin(); ti != _typedefs.end(); ++ti) {
00969 CPPTypedef *td =
00970 (*ti).second->substitute_decl(subst, to_scope, global_scope)->as_typedef();
00971 to_scope->_typedefs.insert(Typedefs::value_type((*ti).first, td));
00972 if (td != (*ti).second) {
00973 anything_changed = true;
00974 }
00975 }
00976 Variables::const_iterator vi;
00977 for (vi = _variables.begin(); vi != _variables.end(); ++vi) {
00978 CPPInstance *inst =
00979 (*vi).second->substitute_decl(subst, to_scope, global_scope)->as_instance();
00980 to_scope->_variables.insert(Variables::value_type((*vi).first, inst));
00981 if (inst != (*vi).second) {
00982 anything_changed = true;
00983 }
00984 }
00985
00986 Templates::const_iterator tmi;
00987 for (tmi = _templates.begin(); tmi != _templates.end(); ++tmi) {
00988 CPPDeclaration *decl =
00989 (*tmi).second->substitute_decl(subst, to_scope, global_scope);
00990 to_scope->_templates.insert(Templates::value_type((*tmi).first, decl));
00991 if (decl != (*tmi).second) {
00992 anything_changed = true;
00993 }
00994 }
00995
00996 return anything_changed;
00997 }
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007 void CPPScope::
01008 handle_declaration(CPPDeclaration *decl, CPPScope *global_scope) {
01009 CPPTypedef *def = decl->as_typedef();
01010 if (def != NULL) {
01011 string name = def->get_simple_name();
01012 _typedefs[name] = def;
01013
01014 CPPExtensionType *et = def->_type->as_extension_type();
01015 if (et != NULL) {
01016 define_extension_type(et);
01017 }
01018
01019 if (!name.empty() && def->get_scope(this, global_scope) == this) {
01020
01021
01022
01023 if (find_template(name) == NULL) {
01024 _templates.insert(Templates::value_type(name, def));
01025 }
01026 }
01027 return;
01028 }
01029
01030 CPPTypeDeclaration *typedecl = decl->as_type_declaration();
01031 if (typedecl != (CPPTypeDeclaration *)NULL) {
01032 CPPExtensionType *et = typedecl->_type->as_extension_type();
01033 if (et != NULL) {
01034 define_extension_type(et);
01035 }
01036 return;
01037 }
01038
01039 CPPInstance *inst = decl->as_instance();
01040 if (inst != NULL) {
01041 inst->check_for_constructor(this, global_scope);
01042
01043 string name = inst->get_simple_name();
01044 if (!name.empty() && inst->get_scope(this, global_scope) == this) {
01045 if (inst->_type->as_function_type()) {
01046
01047
01048
01049
01050 CPPFunctionGroup *fgroup;
01051 Functions::const_iterator fi;
01052 fi = _functions.find(name);
01053 if (fi == _functions.end()) {
01054 fgroup = new CPPFunctionGroup(name);
01055 _functions.insert(Functions::value_type(name, fgroup));
01056 } else {
01057 fgroup = (*fi).second;
01058 }
01059 fgroup->_instances.push_back(inst);
01060
01061 } else {
01062
01063
01064 _variables[name] = inst;
01065 }
01066
01067 if (inst->is_template()) {
01068
01069
01070
01071 if (find_template(name) == NULL) {
01072 _templates.insert(Templates::value_type(name, inst));
01073 }
01074
01075
01076
01077
01078
01079
01080
01081
01082 }
01083 }
01084 return;
01085 }
01086
01087 CPPExtensionType *et = decl->as_extension_type();
01088 if (et != NULL) {
01089 define_extension_type(et);
01090 }
01091 }