mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
240 lines
5.8 KiB
C++
240 lines
5.8 KiB
C++
/**
|
|
* PANDA 3D SOFTWARE
|
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
*
|
|
* All use of this software is subject to the terms of the revised BSD
|
|
* license. You should have received a copy of this license along
|
|
* with this source code in a file named "LICENSE."
|
|
*
|
|
* @file cppParameterList.cxx
|
|
* @author drose
|
|
* @date 1999-10-21
|
|
*/
|
|
|
|
#include "cppParameterList.h"
|
|
#include "cppInstance.h"
|
|
|
|
/**
|
|
*
|
|
*/
|
|
CPPParameterList::
|
|
CPPParameterList() {
|
|
_includes_ellipsis = false;
|
|
}
|
|
|
|
/**
|
|
* This is similar to operator == except it is more forgiving: it is true if
|
|
* only the length and order of types is the same, never minding the instance
|
|
* names or initial values.
|
|
*/
|
|
bool CPPParameterList::
|
|
is_equivalent(const CPPParameterList &other) const {
|
|
if (_includes_ellipsis != other._includes_ellipsis) {
|
|
return false;
|
|
}
|
|
if (_parameters.size() != other._parameters.size()) {
|
|
return false;
|
|
}
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
if (!_parameters[i]->_type->is_equivalent(*other._parameters[i]->_type)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
bool CPPParameterList::
|
|
operator == (const CPPParameterList &other) const {
|
|
if (_includes_ellipsis != other._includes_ellipsis) {
|
|
return false;
|
|
}
|
|
if (_parameters.size() != other._parameters.size()) {
|
|
return false;
|
|
}
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
if (*_parameters[i] != *other._parameters[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
bool CPPParameterList::
|
|
operator != (const CPPParameterList &other) const {
|
|
return !(*this == other);
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
bool CPPParameterList::
|
|
operator < (const CPPParameterList &other) const {
|
|
if (_includes_ellipsis != other._includes_ellipsis) {
|
|
return _includes_ellipsis < other._includes_ellipsis;
|
|
}
|
|
if (_parameters.size() != other._parameters.size()) {
|
|
return _parameters.size() < other._parameters.size();
|
|
}
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
if (*_parameters[i] != *other._parameters[i]) {
|
|
return *_parameters[i] < *other._parameters[i];
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns true if any of the types in the parameter list are base on
|
|
* CPPTBDType.
|
|
*/
|
|
bool CPPParameterList::
|
|
is_tbd() const {
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
if (_parameters[i]->_type->is_tbd()) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns true if any of the types in the parameter list turns out to be a
|
|
* constant expression, which is a clue that this parameter list is actually
|
|
* intended to be an instance declaration.
|
|
*/
|
|
bool CPPParameterList::
|
|
is_parameter_expr() const {
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
if (_parameters[i]->_type->is_parameter_expr()) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* 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 CPPParameterList::
|
|
is_fully_specified() const {
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
if (!_parameters[i]->is_fully_specified()) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
CPPParameterList *CPPParameterList::
|
|
substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|
CPPScope *current_scope, CPPScope *global_scope) {
|
|
CPPParameterList *rep = new CPPParameterList;
|
|
bool any_changed = false;
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
CPPInstance *inst =
|
|
_parameters[i]->substitute_decl(subst, current_scope, global_scope)
|
|
->as_instance();
|
|
if (inst != _parameters[i]) {
|
|
any_changed = true;
|
|
}
|
|
rep->_parameters.push_back(inst);
|
|
}
|
|
|
|
if (!any_changed) {
|
|
delete rep;
|
|
rep = this;
|
|
}
|
|
return rep;
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns an equivalent CPPParameterList, in which all of the individual
|
|
* types have been resolved.
|
|
*/
|
|
CPPParameterList *CPPParameterList::
|
|
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
|
|
CPPParameterList *rep = new CPPParameterList;
|
|
bool any_changed = false;
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
CPPInstance *inst = _parameters[i];
|
|
CPPType *new_type = inst->_type;
|
|
if (new_type->is_tbd()) {
|
|
new_type = new_type->resolve_type(current_scope, global_scope);
|
|
}
|
|
|
|
if (new_type != inst->_type) {
|
|
any_changed = true;
|
|
CPPInstance *new_inst = new CPPInstance(*inst);
|
|
new_inst->_type = new_type;
|
|
rep->_parameters.push_back(new_inst);
|
|
} else {
|
|
rep->_parameters.push_back(inst);
|
|
}
|
|
}
|
|
|
|
if (!any_changed) {
|
|
delete rep;
|
|
rep = this;
|
|
}
|
|
return rep;
|
|
}
|
|
|
|
/**
|
|
* If num_default_parameters is >= 0, it indicates the number of default
|
|
* parameter values to show on output. Otherwise, all parameter values are
|
|
* shown.
|
|
*/
|
|
void CPPParameterList::
|
|
output(ostream &out, CPPScope *scope, bool parameter_names,
|
|
int num_default_parameters) const {
|
|
if (!_parameters.empty()) {
|
|
for (int i = 0; i < (int)_parameters.size(); ++i) {
|
|
if (i != 0) {
|
|
out << ", ";
|
|
}
|
|
|
|
// Save the default value expression; we might be about to temporarily
|
|
// clear it.
|
|
CPPExpression *expr = _parameters[i]->_initializer;
|
|
|
|
if (num_default_parameters >= 0 &&
|
|
i < (int)_parameters.size() - num_default_parameters) {
|
|
// Don't show the default value for this parameter.
|
|
_parameters[i]->_initializer = (CPPExpression *)NULL;
|
|
}
|
|
|
|
if (parameter_names) {
|
|
_parameters[i]->output(out, 0, scope, false);
|
|
} else {
|
|
_parameters[i]->_type->output(out, 0, scope, false);
|
|
}
|
|
|
|
// Restore the default value expression.
|
|
_parameters[i]->_initializer = expr;
|
|
}
|
|
if (_includes_ellipsis) {
|
|
out << ", ...";
|
|
}
|
|
|
|
} else if (_includes_ellipsis) {
|
|
out << "...";
|
|
|
|
} else {
|
|
// No parameters.
|
|
out << "void";
|
|
}
|
|
}
|