*** empty log message ***

This commit is contained in:
David Rose 2001-01-30 00:57:30 +00:00
parent 075518f3fd
commit ca920ace89
3 changed files with 95 additions and 31 deletions

View File

@ -1547,7 +1547,7 @@ get_wrapper(FunctionIndex function_index, WrapperBuilder *wbuilder,
iwrapper._function = function_index;
// We do assume that two different libraries will not has to the
// We do assume that two different libraries will not hash to the
// same name. This is pretty unlikely, although there could be big
// problems if it ever happens. If it does, we'll probably need to
// add an interface so the user can specify a hash offset on a

View File

@ -25,6 +25,7 @@
#include <cppFunctionType.h>
#include <cppParameterList.h>
#include <cppStructType.h>
#include <cppReferenceType.h>
#include <notify.h>
////////////////////////////////////////////////////////////////////
@ -144,6 +145,23 @@ set_function(CPPInstance *function, const string &description,
param._remap = new ParameterRemapThis(_struct_type, is_const);
_parameters.push_back(param);
_has_this = true;
// Also check the name of the function. If it's one of the
// assignment-style operators, flag it as such.
string fname = _function->get_simple_name();
if (fname == "operator =" ||
fname == "operator *=" ||
fname == "operator /=" ||
fname == "operator %=" ||
fname == "operator +=" ||
fname == "operator -=" ||
fname == "operator |=" ||
fname == "operator &=" ||
fname == "operator ^=" ||
fname == "operator <<=" ||
fname == "operator >>=") {
_type = T_assignment_method;
}
}
const CPPParameterList::Parameters &params =
@ -174,7 +192,9 @@ set_function(CPPInstance *function, const string &description,
}
if (_type == T_constructor) {
// Constructors are a special case.
// Constructors are a special case. These appear to return void
// as seen by the parser, but we know they actually return a new
// concrete instance.
if (_struct_type == (CPPStructType *)NULL) {
nout << "Method " << *_function << " has no struct type\n";
@ -184,6 +204,20 @@ set_function(CPPInstance *function, const string &description,
_void_return = false;
}
} else if (_type == T_assignment_method) {
// Assignment-type methods are also a special case. We munge
// these to return *this, which is a semi-standard C++ convention
// anyway. We just enforce it.
if (_struct_type == (CPPStructType *)NULL) {
nout << "Method " << *_function << " has no struct type\n";
_is_valid = false;
} else {
CPPType *ref_type = CPPType::new_type(new CPPReferenceType(_struct_type));
_return_type = make_remap(ref_type);
_void_return = false;
}
} else {
// The normal case.
CPPType *rtype = _ftype->_return_type->resolve_type(&parser, _scope);
@ -573,41 +607,70 @@ call_function(ostream &out, int indent_level, bool convert_result,
return_expr = _return_type->get_return_expr(new_str);
}
} else if (_type == T_constructor) {
// A special case for constructors.
return_expr = "new " + get_call_str(pexprs);
} else if (_type == T_assignment_method) {
// Another special case for assignment operators.
indent(out, indent_level)
<< get_call_str(pexprs) << ";\n";
string this_expr = get_parameter_expr(0, pexprs);
string ref_expr = "*" + this_expr;
if (!convert_result) {
return_expr = ref_expr;
} else {
string new_str =
_return_type->prepare_return_expr(out, indent_level, ref_expr);
return_expr = _return_type->get_return_expr(new_str);
// Now a simple special-case test. Often, we will have converted
// the reference-returning assignment operator to a pointer. In
// this case, we might inadventent generate code like "return
// &(*this)", when "return this" would do. We check for this here
// and undo it as a special case.
// There's no real good reason to do this, other than that it
// feels more satisfying to a casual perusal of the generated
// code. It *is* conceivable that some broken compilers wouldn't
// like "&(*this)", though.
if (return_expr == "&(" + ref_expr + ")" ||
return_expr == "&" + ref_expr) {
return_expr = this_expr;
}
}
} else if (_void_return) {
indent(out, indent_level)
<< get_call_str(pexprs) << ";\n";
} else {
string call = get_call_str(pexprs);
// Now output that call.
if (_type == T_constructor) {
// A special case for constructors.
return_expr = "new " + call;
} else if (_void_return) {
indent(out, indent_level)
<< call << ";\n";
if (!convert_result) {
return_expr = get_call_str(pexprs);
} else {
if (!convert_result) {
return_expr = call;
if (_return_type->return_value_should_be_simple()) {
// We have to assign the result to a temporary first; this makes
// it a bit easier on poor old VC++.
indent(out, indent_level);
_return_type->get_orig_type()->output_instance(out, "result",
&parser);
out << " = " << call << ";\n";
string new_str =
_return_type->prepare_return_expr(out, indent_level, "result");
return_expr = _return_type->get_return_expr(new_str);
} else {
if (_return_type->return_value_should_be_simple()) {
// We have to assign the result to a temporary first; this makes
// it a bit easier on poor old VC++.
indent(out, indent_level);
_return_type->get_orig_type()->output_instance(out, "result",
&parser);
out << " = " << call << ";\n";
string new_str =
_return_type->prepare_return_expr(out, indent_level, "result");
return_expr = _return_type->get_return_expr(new_str);
} else {
// This should be simple enough that we can return it directly.
string new_str =
_return_type->prepare_return_expr(out, indent_level, call);
return_expr = _return_type->get_return_expr(new_str);
}
// This should be simple enough that we can return it directly.
string new_str =
_return_type->prepare_return_expr(out, indent_level, call);
return_expr = _return_type->get_return_expr(new_str);
}
}
}

View File

@ -40,6 +40,7 @@ public:
T_constructor,
T_destructor,
T_typecast_method,
T_assignment_method,
T_typecast,
T_getter,
T_setter