| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064 |
- // Filename: cppScope.C
- // Created by: drose (21Oct99)
- //
- ////////////////////////////////////////////////////////////////////
- #include "cppScope.h"
- #include "cppDeclaration.h"
- #include "cppNamespace.h"
- #include "cppTypedef.h"
- #include "cppTypeDeclaration.h"
- #include "cppExtensionType.h"
- #include "cppInstance.h"
- #include "cppInstanceIdentifier.h"
- #include "cppIdentifier.h"
- #include "cppStructType.h"
- #include "cppFunctionGroup.h"
- #include "cppPreprocessor.h"
- #include "cppTemplateScope.h"
- #include "cppClassTemplateParameter.h"
- #include "cppFunctionType.h"
- #include "cppUsing.h"
- #include "cppBisonDefs.h"
- #include "indent.h"
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::Constructor
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPScope::
- CPPScope(CPPScope *parent_scope,
- const CPPNameComponent &name, CPPVisibility starting_vis) :
- _name(name),
- _parent_scope(parent_scope),
- _current_vis(starting_vis)
- {
- _struct_type = NULL;
- _is_fully_specified = false;
- _fully_specified_known = false;
- _is_fully_specified_recursive_protect = false;
- _subst_decl_recursive_protect = false;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::Destructor
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPScope::
- ~CPPScope() {
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::set_struct_type
- // Access: Public
- // Description: Sets the struct or class that owns this scope. This
- // should only be done once, when the scope and its
- // associated struct are created. It's provided so the
- // scope can check the struct's ancestry for inherited
- // symbols.
- ////////////////////////////////////////////////////////////////////
- void CPPScope::
- set_struct_type(CPPStructType *struct_type) {
- _struct_type = struct_type;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::get_struct_type
- // Access: Public
- // Description: Returns the class or struct that defines this scope,
- // if any.
- ////////////////////////////////////////////////////////////////////
- CPPStructType *CPPScope::
- get_struct_type() const {
- return _struct_type;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::get_parent_scope
- // Access: Public
- // Description: Returns the parent scope of this scope, if any.
- ////////////////////////////////////////////////////////////////////
- CPPScope *CPPScope::
- get_parent_scope() const {
- return _parent_scope;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::set_current_vis
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPScope::
- set_current_vis(CPPVisibility current_vis) {
- _current_vis = current_vis;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::get_current_vis
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPVisibility CPPScope::
- get_current_vis() const {
- return _current_vis;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::add_declaration
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPScope::
- add_declaration(CPPDeclaration *decl, CPPScope *global_scope,
- CPPPreprocessor *preprocessor, const cppyyltype &pos) {
- decl->_vis = _current_vis;
- // Get the recent comments from the preprocessor. These are the
- // comments that appeared preceding this particular declaration;
- // they might be relevant to the declaration.
- if (decl->_leading_comment == (CPPCommentBlock *)NULL) {
- decl->_leading_comment =
- preprocessor->get_comment_before(pos.first_line, pos.file);
- }
- _declarations.push_back(decl);
- handle_declaration(decl, global_scope);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::add_enum_value
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPScope::
- add_enum_value(CPPInstance *inst) {
- inst->_vis = _current_vis;
- string name = inst->get_simple_name();
- if (!name.empty()) {
- _enum_values[name] = inst;
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::define_extension_type
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPScope::
- define_extension_type(CPPExtensionType *type) {
- assert(type != NULL);
- string name = type->get_simple_name();
- switch (type->_type) {
- case CPPExtensionType::T_class:
- _classes[name] = type;
- break;
- case CPPExtensionType::T_struct:
- _structs[name] = type;
- break;
- case CPPExtensionType::T_union:
- _unions[name] = type;
- case CPPExtensionType::T_enum:
- _enums[name] = type;
- }
- // Create an implicit typedef for the extension.
- CPPIdentifier *ident = new CPPIdentifier(name);
- CPPTypedef *td = new CPPTypedef(new CPPInstance(type, ident), false);
- pair<Typedefs::iterator, bool> result =
- _typedefs.insert(Typedefs::value_type(name, td));
- if (!result.second) {
- // There's already a typedef for this extension. This one
- // overrides if it has template parameters and the other one
- // doesn't.
- CPPType *other_type = (*result.first).second->_type;
- if (type->is_template() && !other_type->is_template()) {
- (*result.first).second = td;
- // Or if the other one is a forward reference.
- } else if (other_type->get_subtype() == CPPDeclaration::ST_extension) {
- (*result.first).second = td;
- }
- }
- if (type->is_template()) {
- _templates.insert(Templates::value_type(name, type));
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::define_namespace
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPScope::
- define_namespace(CPPNamespace *scope) {
- string name = scope->get_simple_name();
- _namespaces[name] = scope;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::add_using
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPScope::
- add_using(CPPUsing *using_decl, CPPScope *global_scope,
- CPPPreprocessor *error_sink) {
- if (using_decl->_full_namespace) {
- CPPScope *scope =
- using_decl->_ident->find_scope(this, global_scope);
- if (scope != NULL) {
- _using.insert(scope);
- } else {
- if (error_sink != NULL) {
- error_sink->warning("Attempt to use undefined namespace: " + using_decl->_ident->get_fully_scoped_name());
- }
- }
- } else {
- CPPDeclaration *decl = using_decl->_ident->find_symbol(this, global_scope);
- if (decl != NULL) {
- handle_declaration(decl, global_scope);
- } else {
- if (error_sink != NULL) {
- error_sink->warning("Attempt to use unknown symbol: " + using_decl->_ident->get_fully_scoped_name());
- }
- }
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::is_fully_specified
- // Access: Public, Virtual
- // Description: Returns true if this declaration is an actual,
- // factual declaration, or false if some part of the
- // declaration depends on a template parameter which has
- // not yet been instantiated.
- ////////////////////////////////////////////////////////////////////
- bool CPPScope::
- is_fully_specified() const {
- if (_fully_specified_known) {
- return _is_fully_specified;
- }
- if (_is_fully_specified_recursive_protect) {
- // We're already executing this block.
- return true;
- }
- ((CPPScope *)this)->_is_fully_specified_recursive_protect = true;
- bool specified = true;
- if (_parent_scope != NULL && !_parent_scope->is_fully_specified()) {
- specified = false;
- }
- Declarations::const_iterator di;
- for (di = _declarations.begin();
- di != _declarations.end() && specified;
- ++di) {
- if (!(*di)->is_fully_specified()) {
- specified = false;
- }
- }
- ((CPPScope *)this)->_fully_specified_known = true;
- ((CPPScope *)this)->_is_fully_specified = specified;
- ((CPPScope *)this)->_is_fully_specified_recursive_protect = false;
- return specified;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::instantiate
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPScope *CPPScope::
- instantiate(const CPPTemplateParameterList *actual_params,
- CPPScope *current_scope, CPPScope *global_scope,
- CPPPreprocessor *error_sink) const {
- CPPScope *this_scope = (CPPScope *)this;
- if (_parent_scope == NULL ||
- _parent_scope->as_template_scope() == NULL) {
- if (error_sink != NULL) {
- error_sink->warning("Ignoring template parameters for scope " +
- get_local_name());
- }
- return this_scope;
- }
- if (is_fully_specified()) {
- return this_scope;
- }
- Instantiations::const_iterator ii;
- ii = _instantiations.find(actual_params);
- if (ii != _instantiations.end()) {
- // We've already instantiated this scope with these parameters.
- // Return that.
- return (*ii).second;
- }
- /*
- cerr << "Instantiating " << get_simple_name()
- << "<" << *actual_params << ">\n";
- */
- // Build the mapping of formal parameters to actual parameters.
- CPPTemplateScope *tscope = _parent_scope->as_template_scope();
- CPPDeclaration::SubstDecl subst;
- actual_params->build_subst_decl(tscope->_parameters, subst,
- current_scope, global_scope);
- CPPScope *scope;
- if (subst.empty()) {
- scope = (CPPScope *)this;
- } else {
- CPPNameComponent name = _name;
- name.set_templ(new CPPTemplateParameterList(*actual_params));
- // scope = new CPPScope(current_scope, name, V_public);
- scope = new CPPScope(_parent_scope, name, V_public);
- copy_substitute_decl(scope, subst, global_scope);
-
- // Also define any new template parameter types, in case we
- // "instantiated" this scope with another template parameter.
- CPPTemplateParameterList::Parameters::const_iterator pi;
- for (pi = actual_params->_parameters.begin();
- pi != actual_params->_parameters.end();
- ++pi) {
- CPPDeclaration *decl = (*pi);
- CPPClassTemplateParameter *ctp = decl->as_class_template_parameter();
- if (ctp != NULL) {
- CPPInstance *inst = new CPPInstance(ctp, ctp->_ident);
- CPPTypedef *td = new CPPTypedef(inst, true);
- scope->_typedefs.insert(Typedefs::value_type
- (ctp->_ident->get_local_name(),
- td));
- }
- }
- }
-
- // Finally, record this particular instantiation for future
- // reference, so we don't have to do this again.
- ((CPPScope *)this)->_instantiations.insert(Instantiations::value_type(actual_params, scope));
- return scope;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::substitute_decl
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPScope *CPPScope::
- substitute_decl(CPPDeclaration::SubstDecl &subst,
- CPPScope *current_scope, CPPScope *global_scope) const {
- CPPScope *this_scope = (CPPScope *)this;
- if (is_fully_specified()) {
- return this_scope;
- }
- if (_subst_decl_recursive_protect) {
- // We're already executing this block.
- return this_scope;
- }
- ((CPPScope *)this)->_subst_decl_recursive_protect = true;
- CPPScope *rep = new CPPScope(current_scope, _name, V_public);
- bool anything_changed;
- if (_parent_scope != NULL &&
- _parent_scope->as_template_scope() != NULL) {
- // If the parent of this scope is a template scope--e.g. this
- // scope has template parameters--then we must first remove any of
- // the template parameters from the subst list. These will later
- // get substituted properly during instantiation.
- const CPPTemplateParameterList &p =
- _parent_scope->as_template_scope()->_parameters;
- CPPDeclaration::SubstDecl new_subst = subst;
- CPPTemplateParameterList::Parameters::const_iterator pi;
- for (pi = p._parameters.begin(); pi != p._parameters.end(); ++pi) {
- new_subst.erase(*pi);
- }
- anything_changed = copy_substitute_decl(rep, new_subst, global_scope);
- } else {
- anything_changed = copy_substitute_decl(rep, subst, global_scope);
- }
- if (!anything_changed && rep->_parent_scope == _parent_scope) {
- delete rep;
- rep = (CPPScope *)this;
- }
- ((CPPScope *)this)->_subst_decl_recursive_protect = false;
- return rep;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::find_type
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPType *CPPScope::
- find_type(const string &name, bool recurse) const {
- Typedefs::const_iterator ti;
- ti = _typedefs.find(name);
- if (ti != _typedefs.end()) {
- return (*ti).second->_type;
- }
- Using::const_iterator ui;
- for (ui = _using.begin(); ui != _using.end(); ++ui) {
- CPPType *type = (*ui)->find_type(name, false);
- if (type != NULL) {
- return type;
- }
- }
- if (_struct_type != NULL) {
- CPPStructType::Derivation::const_iterator di;
- for (di = _struct_type->_derivation.begin();
- di != _struct_type->_derivation.end();
- ++di) {
- CPPStructType *st = (*di)._base->as_struct_type();
- if (st != NULL) {
- CPPType *type = st->_scope->find_type(name, false);
- if (type != NULL) {
- return type;
- }
- }
- }
- }
- if (recurse && _parent_scope != NULL) {
- return _parent_scope->find_type(name);
- }
- return NULL;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::find_type
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPType *CPPScope::
- find_type(const string &name, CPPDeclaration::SubstDecl &subst,
- CPPScope *global_scope, bool recurse) const {
- Typedefs::const_iterator ti;
- ti = _typedefs.find(name);
- if (ti != _typedefs.end()) {
- CPPScope *current_scope = (CPPScope *)this;
- return (*ti).second->_type->substitute_decl
- (subst, current_scope, global_scope)->as_type();
- }
- Using::const_iterator ui;
- for (ui = _using.begin(); ui != _using.end(); ++ui) {
- CPPType *type = (*ui)->find_type(name, subst, global_scope, false);
- if (type != NULL) {
- return type;
- }
- }
- if (_struct_type != NULL) {
- CPPStructType::Derivation::const_iterator di;
- for (di = _struct_type->_derivation.begin();
- di != _struct_type->_derivation.end();
- ++di) {
- CPPStructType *st = (*di)._base->as_struct_type();
- if (st != NULL) {
- CPPType *type = st->_scope->find_type(name, subst, global_scope,
- false);
- if (type != NULL) {
- return type;
- }
- }
- }
- }
- if (recurse && _parent_scope != NULL) {
- return _parent_scope->find_type(name, subst, global_scope);
- }
- return NULL;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::find_scope
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPScope *CPPScope::
- find_scope(const string &name, bool recurse) const {
- Namespaces::const_iterator ni = _namespaces.find(name);
- if (ni != _namespaces.end()) {
- return (*ni).second->get_scope();
- }
- CPPType *type = (CPPType *)NULL;
- Typedefs::const_iterator ti;
- ti = _typedefs.find(name);
- if (ti != _typedefs.end()) {
- type = (*ti).second->_type;
- } else if (_struct_type != NULL) {
- CPPStructType::Derivation::const_iterator di;
- for (di = _struct_type->_derivation.begin();
- di != _struct_type->_derivation.end();
- ++di) {
- CPPStructType *st = (*di)._base->as_struct_type();
- if (st != NULL) {
- type = st->_scope->find_type(name, false);
- }
- }
- }
- if (type != NULL) {
- CPPStructType *st = type->as_struct_type();
- if (st != NULL) {
- return st->_scope;
- }
- }
- Using::const_iterator ui;
- for (ui = _using.begin(); ui != _using.end(); ++ui) {
- CPPScope *scope = (*ui)->find_scope(name, false);
- if (scope != NULL) {
- return scope;
- }
- }
- if (recurse && _parent_scope != NULL) {
- return _parent_scope->find_scope(name);
- }
- return (CPPScope *)NULL;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::find_scope
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPScope *CPPScope::
- find_scope(const string &name, CPPDeclaration::SubstDecl &subst,
- CPPScope *global_scope, bool recurse) const {
- CPPType *type = find_type(name, subst, global_scope, recurse);
- if (type == NULL) {
- return NULL;
- }
- CPPStructType *st = type->as_struct_type();
- if (st == NULL) {
- return NULL;
- }
- return st->_scope;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::find_symbol
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPDeclaration *CPPScope::
- find_symbol(const string &name, bool recurse) const {
- if (_struct_type != NULL && name == get_simple_name()) {
- return _struct_type;
- }
- Typedefs::const_iterator ti;
- ti = _typedefs.find(name);
- if (ti != _typedefs.end()) {
- return (*ti).second->_type;
- }
- Variables::const_iterator vi;
- vi = _variables.find(name);
- if (vi != _variables.end()) {
- return (*vi).second;
- }
- vi = _enum_values.find(name);
- if (vi != _enum_values.end()) {
- return (*vi).second;
- }
- Functions::const_iterator fi;
- fi = _functions.find(name);
- if (fi != _functions.end()) {
- return (*fi).second;
- }
- Using::const_iterator ui;
- for (ui = _using.begin(); ui != _using.end(); ++ui) {
- CPPDeclaration *decl = (*ui)->find_symbol(name, false);
- if (decl != NULL) {
- return decl;
- }
- }
- if (_struct_type != NULL) {
- CPPStructType::Derivation::const_iterator di;
- for (di = _struct_type->_derivation.begin();
- di != _struct_type->_derivation.end();
- ++di) {
- CPPStructType *st = (*di)._base->as_struct_type();
- if (st != NULL) {
- CPPDeclaration *decl = st->_scope->find_symbol(name, false);
- if (decl != NULL) {
- return decl;
- }
- }
- }
- }
- if (recurse && _parent_scope != NULL) {
- return _parent_scope->find_symbol(name);
- }
- return NULL;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::find_template
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPDeclaration *CPPScope::
- find_template(const string &name, bool recurse) const {
- Templates::const_iterator ti;
- ti = _templates.find(name);
- if (ti != _templates.end()) {
- return (*ti).second;
- }
- Using::const_iterator ui;
- for (ui = _using.begin(); ui != _using.end(); ++ui) {
- CPPDeclaration *decl = (*ui)->find_template(name, false);
- if (decl != NULL) {
- return decl;
- }
- }
- if (_struct_type != NULL) {
- CPPStructType::Derivation::const_iterator di;
- for (di = _struct_type->_derivation.begin();
- di != _struct_type->_derivation.end();
- ++di) {
- CPPStructType *st = (*di)._base->as_struct_type();
- if (st != NULL) {
- CPPDeclaration *decl = st->_scope->find_template(name, false);
- if (decl != NULL) {
- return decl;
- }
- }
- }
- }
- if (recurse && _parent_scope != NULL) {
- return _parent_scope->find_template(name);
- }
- return NULL;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::get_simple_name
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- string CPPScope::
- get_simple_name() const {
- /*
- if (_struct_type != (CPPStructType *)NULL) {
- return _struct_type->get_simple_name();
- }
- */
- return _name.get_name();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::get_local_name
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- string CPPScope::
- get_local_name(CPPScope *scope) const {
- /*
- if (_struct_type != (CPPStructType *)NULL) {
- return _struct_type->get_local_name(scope);
- }
- */
- if (scope != NULL && _parent_scope != NULL && _parent_scope != scope) {
- return _parent_scope->get_local_name(scope) + "::" +
- _name.get_name_with_templ();
- } else {
- return _name.get_name_with_templ();
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::get_fully_scoped_name
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- string CPPScope::
- get_fully_scoped_name() const {
- /*
- if (_struct_type != (CPPStructType *)NULL) {
- return _struct_type->get_fully_scoped_name();
- }
- */
- if (_parent_scope != NULL) {
- return _parent_scope->get_fully_scoped_name() + "::" +
- _name.get_name_with_templ();
- } else {
- return _name.get_name_with_templ();
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::output
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPScope::
- output(ostream &out, CPPScope *scope) const {
- // out << get_local_name(scope);
- if (_parent_scope != NULL && _parent_scope != scope) {
- _parent_scope->output(out, scope);
- out << "::";
- }
- out << _name;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::write
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPScope::
- write(ostream &out, int indent_level, CPPScope *scope) const {
- CPPVisibility vis = V_unknown;
- Declarations::const_iterator di;
- for (di = _declarations.begin(); di != _declarations.end(); ++di) {
- CPPDeclaration *cd = (*di);
- if (cd->_vis != vis && indent_level > 0) {
- vis = cd->_vis;
- indent(out, indent_level - 2) << vis << ":\n";
- }
- bool complete = false;
- if (cd->as_typedef() != NULL || cd->as_type() != NULL ||
- cd->as_namespace() != NULL) {
- complete = true;
- }
- indent(out, indent_level);
- cd->output(out, indent_level, scope, complete);
- out << ";\n";
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::get_template_scope
- // Access: Public
- // Description: Returns the nearest ancestor of this scope that is a
- // template scope, or NULL if the scope is fully
- // specified.
- ////////////////////////////////////////////////////////////////////
- CPPTemplateScope *CPPScope::
- get_template_scope() {
- if (as_template_scope()) {
- return as_template_scope();
- }
- if (_parent_scope != NULL) {
- return _parent_scope->get_template_scope();
- }
- return (CPPTemplateScope *)NULL;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::as_template_scope
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPTemplateScope *CPPScope::
- as_template_scope() {
- return (CPPTemplateScope *)NULL;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::copy_substitute_decl
- // Access: Private
- // Description: This is in support of both substitute_decl() and
- // instantiate(). It's similar in purpose to
- // substitute_decl(), but this function assumes the
- // caller has already created a new, empty scope. All
- // of the declarations in this scope are copied to the
- // new scope, filtering through the subst decl.
- //
- // The return value is true if the scope is changed,
- // false if it is not.
- ////////////////////////////////////////////////////////////////////
- bool CPPScope::
- copy_substitute_decl(CPPScope *to_scope, CPPDeclaration::SubstDecl &subst,
- CPPScope *global_scope) const {
- bool anything_changed = false;
- if (_struct_type != NULL) {
- CPPScope *native_scope = (CPPScope *)NULL;
- if (_struct_type->_ident != (CPPIdentifier *)NULL) {
- native_scope = _struct_type->_ident->_native_scope;
- }
- to_scope->_struct_type =
- new CPPStructType(_struct_type->_type,
- new CPPIdentifier(to_scope->_name),
- native_scope, to_scope, _struct_type->_file);
- to_scope->_struct_type->_incomplete = false;
- // Copy the derivation to the new type.
- CPPStructType::Derivation::const_iterator di;
- for (di = _struct_type->_derivation.begin();
- di != _struct_type->_derivation.end();
- ++di) {
- CPPStructType::Base b = (*di);
- b._base =
- (*di)._base->substitute_decl(subst, to_scope, global_scope)->as_type();
- to_scope->_struct_type->_derivation.push_back(b);
- if (b._base != (*di)._base) {
- anything_changed = true;
- }
- }
- }
-
- Declarations::const_iterator di;
- for (di = _declarations.begin(); di != _declarations.end(); ++di) {
- CPPDeclaration *decl =
- (*di)->substitute_decl(subst, to_scope, global_scope);
- to_scope->_declarations.push_back(decl);
- if (decl != (*di)) {
- anything_changed = true;
- }
- }
- ExtensionTypes::const_iterator ei;
- for (ei = _structs.begin(); ei != _structs.end(); ++ei) {
- string name = (*ei).first;
- CPPType *source_type = (*ei).second;
- CPPDeclaration *decl =
- source_type->substitute_decl(subst, to_scope, global_scope);
- assert(decl != NULL);
- CPPType *new_type = decl->as_type();
- assert(new_type != NULL);
- to_scope->_structs.insert(ExtensionTypes::value_type(name, new_type));
- if (new_type != source_type) {
- anything_changed = true;
- }
- }
- for (ei = _classes.begin(); ei != _classes.end(); ++ei) {
- string name = (*ei).first;
- CPPType *source_type = (*ei).second;
- CPPDeclaration *decl =
- source_type->substitute_decl(subst, to_scope, global_scope);
- assert(decl != NULL);
- CPPType *new_type = decl->as_type();
- assert(new_type != NULL);
- to_scope->_classes.insert(ExtensionTypes::value_type(name, new_type));
- if (new_type != source_type) {
- anything_changed = true;
- }
- }
- for (ei = _unions.begin(); ei != _unions.end(); ++ei) {
- string name = (*ei).first;
- CPPType *source_type = (*ei).second;
- CPPDeclaration *decl =
- source_type->substitute_decl(subst, to_scope, global_scope);
- assert(decl != NULL);
- CPPType *new_type = decl->as_type();
- assert(new_type != NULL);
- to_scope->_unions.insert(ExtensionTypes::value_type(name, new_type));
- if (new_type != source_type) {
- anything_changed = true;
- }
- }
- for (ei = _enums.begin(); ei != _enums.end(); ++ei) {
- string name = (*ei).first;
- CPPType *source_type = (*ei).second;
- CPPDeclaration *decl =
- source_type->substitute_decl(subst, to_scope, global_scope);
- assert(decl != NULL);
- CPPType *new_type = decl->as_type();
- assert(new_type != NULL);
- to_scope->_enums.insert(ExtensionTypes::value_type(name, new_type));
- if (new_type != source_type) {
- anything_changed = true;
- }
- }
- Functions::const_iterator fi;
- for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
- CPPFunctionGroup *fgroup = (*fi).second;
- string name = fgroup->_name;
- CPPFunctionGroup *&to_fgroup = to_scope->_functions[name];
- if (to_fgroup == (CPPFunctionGroup *)NULL) {
- to_fgroup = new CPPFunctionGroup(name);
- }
- CPPFunctionGroup::Instances::const_iterator ii;
- for (ii = fgroup->_instances.begin();
- ii != fgroup->_instances.end();
- ++ii) {
- CPPInstance *inst =
- (*ii)->substitute_decl(subst, to_scope, global_scope)->as_instance();
- to_fgroup->_instances.push_back(inst);
- if (inst != (*ii)) {
- anything_changed = true;
- }
- }
- }
-
- Typedefs::const_iterator ti;
- for (ti = _typedefs.begin(); ti != _typedefs.end(); ++ti) {
- CPPTypedef *td =
- (*ti).second->substitute_decl(subst, to_scope, global_scope)->as_typedef();
- to_scope->_typedefs.insert(Typedefs::value_type((*ti).first, td));
- if (td != (*ti).second) {
- anything_changed = true;
- }
- }
- Variables::const_iterator vi;
- for (vi = _variables.begin(); vi != _variables.end(); ++vi) {
- CPPInstance *inst =
- (*vi).second->substitute_decl(subst, to_scope, global_scope)->as_instance();
- to_scope->_variables.insert(Variables::value_type((*vi).first, inst));
- if (inst != (*vi).second) {
- anything_changed = true;
- }
- }
-
- Templates::const_iterator tmi;
- for (tmi = _templates.begin(); tmi != _templates.end(); ++tmi) {
- CPPDeclaration *decl =
- (*tmi).second->substitute_decl(subst, to_scope, global_scope);
- to_scope->_templates.insert(Templates::value_type((*tmi).first, decl));
- if (decl != (*tmi).second) {
- anything_changed = true;
- }
- }
- return anything_changed;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPScope::handle_declaration
- // Access: Private
- // Description: Does the right thing with a newly given declaration:
- // adds it to the typedef list, or variables or
- // functions, or whatever.
- ////////////////////////////////////////////////////////////////////
- void CPPScope::
- handle_declaration(CPPDeclaration *decl, CPPScope *global_scope) {
- CPPTypedef *def = decl->as_typedef();
- if (def != NULL) {
- string name = def->get_simple_name();
- _typedefs[name] = def;
- CPPExtensionType *et = def->_type->as_extension_type();
- if (et != NULL) {
- define_extension_type(et);
- }
- if (!name.empty() && def->get_scope(this, global_scope) == this) {
- // Don't add a new template definition if we already had one
- // by the same name in another scope.
-
- if (find_template(name) == NULL) {
- _templates.insert(Templates::value_type(name, def));
- }
- }
- return;
- }
- CPPTypeDeclaration *typedecl = decl->as_type_declaration();
- if (typedecl != (CPPTypeDeclaration *)NULL) {
- CPPExtensionType *et = typedecl->_type->as_extension_type();
- if (et != NULL) {
- define_extension_type(et);
- }
- return;
- }
- CPPInstance *inst = decl->as_instance();
- if (inst != NULL) {
- inst->check_for_constructor(this, global_scope);
- string name = inst->get_simple_name();
- if (!name.empty() && inst->get_scope(this, global_scope) == this) {
- if (inst->_type->as_function_type()) {
- // This is a function declaration; hence it gets added to
- // the _functions member. But we must be careful to share
- // common-named functions.
- CPPFunctionGroup *fgroup;
- Functions::const_iterator fi;
- fi = _functions.find(name);
- if (fi == _functions.end()) {
- fgroup = new CPPFunctionGroup(name);
- _functions.insert(Functions::value_type(name, fgroup));
- } else {
- fgroup = (*fi).second;
- }
- fgroup->_instances.push_back(inst);
- } else {
- // This is not a function declaration; hence it gets added
- // to the _variables member.
- _variables[name] = inst;
- }
-
- if (inst->is_template()) {
- // Don't add a new template definition if we already had one
- // by the same name in another scope.
- if (find_template(name) == NULL) {
- _templates.insert(Templates::value_type(name, inst));
- }
- /*
- if (inst->_type->as_function_type() == NULL ||
- (inst->_type->as_function_type()->_flags &
- CPPFunctionType::F_constructor) == 0) {
- _templates.insert(Templates::value_type(name, inst));
- }
- */
- }
- }
- return;
- }
- CPPExtensionType *et = decl->as_extension_type();
- if (et != NULL) {
- define_extension_type(et);
- }
- }
|