Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

dtool/src/cppparser/cppScope.cxx

Go to the documentation of this file.
00001 // Filename: cppScope.cxx
00002 // Created by:  drose (21Oct99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
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 //     Function: CPPScope::Constructor
00041 //       Access: Public
00042 //  Description:
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 //     Function: CPPScope::Destructor
00060 //       Access: Public, Virtual
00061 //  Description:
00062 ////////////////////////////////////////////////////////////////////
00063 CPPScope::
00064 ~CPPScope() {
00065 }
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: CPPScope::set_struct_type
00069 //       Access: Public
00070 //  Description: Sets the struct or class that owns this scope.  This
00071 //               should only be done once, when the scope and its
00072 //               associated struct are created.  It's provided so the
00073 //               scope can check the struct's ancestry for inherited
00074 //               symbols.
00075 ////////////////////////////////////////////////////////////////////
00076 void CPPScope::
00077 set_struct_type(CPPStructType *struct_type) {
00078   _struct_type = struct_type;
00079 }
00080 
00081 ////////////////////////////////////////////////////////////////////
00082 //     Function: CPPScope::get_struct_type
00083 //       Access: Public
00084 //  Description: Returns the class or struct that defines this scope,
00085 //               if any.
00086 ////////////////////////////////////////////////////////////////////
00087 CPPStructType *CPPScope::
00088 get_struct_type() const {
00089   return _struct_type;
00090 }
00091 
00092 ////////////////////////////////////////////////////////////////////
00093 //     Function: CPPScope::get_parent_scope
00094 //       Access: Public
00095 //  Description: Returns the parent scope of this scope, if any.
00096 ////////////////////////////////////////////////////////////////////
00097 CPPScope *CPPScope::
00098 get_parent_scope() const {
00099   return _parent_scope;
00100 }
00101 
00102 ////////////////////////////////////////////////////////////////////
00103 //     Function: CPPScope::set_current_vis
00104 //       Access: Public
00105 //  Description:
00106 ////////////////////////////////////////////////////////////////////
00107 void CPPScope::
00108 set_current_vis(CPPVisibility current_vis) {
00109   _current_vis = current_vis;
00110 }
00111 
00112 ////////////////////////////////////////////////////////////////////
00113 //     Function: CPPScope::get_current_vis
00114 //       Access: Public
00115 //  Description:
00116 ////////////////////////////////////////////////////////////////////
00117 CPPVisibility CPPScope::
00118 get_current_vis() const {
00119   return _current_vis;
00120 }
00121 
00122 ////////////////////////////////////////////////////////////////////
00123 //     Function: CPPScope::add_declaration
00124 //       Access: Public, Virtual
00125 //  Description:
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   // Get the recent comments from the preprocessor.  These are the
00133   // comments that appeared preceding this particular declaration;
00134   // they might be relevant to the declaration.
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 //     Function: CPPScope::add_enum_value
00148 //       Access: Public, Virtual
00149 //  Description:
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 //     Function: CPPScope::define_extension_type
00163 //       Access: Public, Virtual
00164 //  Description:
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   // Create an implicit typedef for the extension.
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     // There's already a typedef for this extension.  This one
00195     // overrides if it has template parameters and the other one
00196     // doesn't.
00197     CPPType *other_type = (*result.first).second->_type;
00198     if (type->is_template() && !other_type->is_template()) {
00199       (*result.first).second = td;
00200 
00201       // Or if the other one is a forward reference.
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       // The template was not inserted because we already had a
00213       // template definition with the given name.  If the previous
00214       // definition was incomplete, replace it.
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         // The previous template definition was incomplete, maybe a
00219         // forward reference; replace it with the good one.
00220         (*result.first).second = type;
00221       }
00222     }
00223   }
00224 }
00225 
00226 ////////////////////////////////////////////////////////////////////
00227 //     Function: CPPScope::define_namespace
00228 //       Access: Public, Virtual
00229 //  Description:
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 //     Function: CPPScope::add_using
00240 //       Access: Public, Virtual
00241 //  Description:
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 //     Function: CPPScope::is_fully_specified
00270 //       Access: Public, Virtual
00271 //  Description: Returns true if this declaration is an actual,
00272 //               factual declaration, or false if some part of the
00273 //               declaration depends on a template parameter which has
00274 //               not yet been instantiated.
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     // We're already executing this block.
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 //     Function: CPPScope::instantiate
00312 //       Access: Public
00313 //  Description:
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     // We've already instantiated this scope with these parameters.
00338     // Return that.
00339     return (*ii).second;
00340   }
00341 
00342   /*
00343     cerr << "Instantiating " << get_simple_name()
00344          << "<" << *actual_params << ">\n";
00345   */
00346 
00347   // Build the mapping of formal parameters to actual parameters.
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     //    scope = new CPPScope(current_scope, name, V_public);
00361     scope = new CPPScope(_parent_scope, name, V_public);
00362     copy_substitute_decl(scope, subst, global_scope);
00363 
00364     // Also define any new template parameter types, in case we
00365     // "instantiated" this scope with another template parameter.
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   // Finally, record this particular instantiation for future
00383   // reference, so we don't have to do this again.
00384   ((CPPScope *)this)->_instantiations.insert(Instantiations::value_type(actual_params, scope));
00385 
00386   return scope;
00387 }
00388 
00389 ////////////////////////////////////////////////////////////////////
00390 //     Function: CPPScope::substitute_decl
00391 //       Access: Public, Virtual
00392 //  Description:
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     // We're already executing this block.
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     // If the parent of this scope is a template scope--e.g. this
00415     // scope has template parameters--then we must first remove any of
00416     // the template parameters from the subst list.  These will later
00417     // get substituted properly during instantiation.
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 //     Function: CPPScope::find_type
00442 //       Access: Public
00443 //  Description:
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 //     Function: CPPScope::find_type
00485 //       Access: Public
00486 //  Description:
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 //     Function: CPPScope::find_scope
00532 //       Access: Public
00533 //  Description:
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 //     Function: CPPScope::find_scope
00585 //       Access: Public
00586 //  Description:
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 //     Function: CPPScope::find_symbol
00604 //       Access: Public
00605 //  Description:
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 //     Function: CPPScope::find_template
00668 //       Access: Public
00669 //  Description:
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 //     Function: CPPScope::get_simple_name
00711 //       Access: Public, Virtual
00712 //  Description:
00713 ////////////////////////////////////////////////////////////////////
00714 string CPPScope::
00715 get_simple_name() const {
00716   /*
00717   if (_struct_type != (CPPStructType *)NULL) {
00718     return _struct_type->get_simple_name();
00719   }
00720   */
00721   return _name.get_name();
00722 }
00723 
00724 ////////////////////////////////////////////////////////////////////
00725 //     Function: CPPScope::get_local_name
00726 //       Access: Public, Virtual
00727 //  Description:
00728 ////////////////////////////////////////////////////////////////////
00729 string CPPScope::
00730 get_local_name(CPPScope *scope) const {
00731   /*
00732   if (_struct_type != (CPPStructType *)NULL) {
00733     return _struct_type->get_local_name(scope);
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 //     Function: CPPScope::get_fully_scoped_name
00747 //       Access: Public, Virtual
00748 //  Description:
00749 ////////////////////////////////////////////////////////////////////
00750 string CPPScope::
00751 get_fully_scoped_name() const {
00752   /*
00753   if (_struct_type != (CPPStructType *)NULL) {
00754     return _struct_type->get_fully_scoped_name();
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 //     Function: CPPScope::output
00768 //       Access: Public, Virtual
00769 //  Description:
00770 ////////////////////////////////////////////////////////////////////
00771 void CPPScope::
00772 output(ostream &out, CPPScope *scope) const {
00773   //  out << get_local_name(scope);
00774   if (_parent_scope != NULL && _parent_scope != scope) {
00775     _parent_scope->output(out, scope);
00776     out << "::";
00777   }
00778   out << _name;
00779 }
00780 
00781 ////////////////////////////////////////////////////////////////////
00782 //     Function: CPPScope::write
00783 //       Access: Public
00784 //  Description:
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 //     Function: CPPScope::get_template_scope
00811 //       Access: Public
00812 //  Description: Returns the nearest ancestor of this scope that is a
00813 //               template scope, or NULL if the scope is fully
00814 //               specified.
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 //     Function: CPPScope::as_template_scope
00829 //       Access: Public, Virtual
00830 //  Description:
00831 ////////////////////////////////////////////////////////////////////
00832 CPPTemplateScope *CPPScope::
00833 as_template_scope() {
00834   return (CPPTemplateScope *)NULL;
00835 }
00836 
00837 ////////////////////////////////////////////////////////////////////
00838 //     Function: CPPScope::copy_substitute_decl
00839 //       Access: Private
00840 //  Description: This is in support of both substitute_decl() and
00841 //               instantiate().  It's similar in purpose to
00842 //               substitute_decl(), but this function assumes the
00843 //               caller has already created a new, empty scope.  All
00844 //               of the declarations in this scope are copied to the
00845 //               new scope, filtering through the subst decl.
00846 //
00847 //               The return value is true if the scope is changed,
00848 //               false if it is not.
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     // Copy the derivation to the new type.
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 //     Function: CPPScope::handle_declaration
01002 //       Access: Private
01003 //  Description: Does the right thing with a newly given declaration:
01004 //               adds it to the typedef list, or variables or
01005 //               functions, or whatever.
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       // Don't add a new template definition if we already had one
01021       // by the same name in another scope.
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         // This is a function declaration; hence it gets added to
01047         // the _functions member.  But we must be careful to share
01048         // common-named functions.
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         // This is not a function declaration; hence it gets added
01063         // to the _variables member.
01064         _variables[name] = inst;
01065       }
01066 
01067       if (inst->is_template()) {
01068         // Don't add a new template definition if we already had one
01069         // by the same name in another scope.
01070 
01071         if (find_template(name) == NULL) {
01072           _templates.insert(Templates::value_type(name, inst));
01073         }
01074 
01075         /*
01076         if (inst->_type->as_function_type() == NULL ||
01077             (inst->_type->as_function_type()->_flags &
01078              CPPFunctionType::F_constructor) == 0) {
01079           _templates.insert(Templates::value_type(name, inst));
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 }

Generated on Thu May 1 22:12:55 2003 for DTool by doxygen1.3