[r1]: trunk / Cm / Cm.Core / Function.cpp  Maximize  Restore  History

Download this file

102 lines (94 with data), 3.3 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
#include <Cm.Core/Function.hpp>
#include <Cm.Core/Assert.hpp>
#include <Cm.Core/ConversionTable.hpp>
#include <Cm.Core/TypeChecker.hpp>
#include <iostream>
namespace Cm { namespace Core {
Function::Function(const String& name_, const Position& pos_, const ScopePtr& parentScope_, const String& functionSetName_,
const EntityPtr& returnTypeExpr_, const ParameterListPtr& parameters_, const CompoundStatementPtr& body_):
Entity(name_, pos_, parentScope_), functionSetName(functionSetName_), returnTypeExpr(returnTypeExpr_), parameters(parameters_),
conversion(IMPLICIT_CONVERSION), body(body_), called(false)
{
}
void Function::TypeCheck()
{
if (!TypeChecked())
{
Entity::TypeCheck();
if (returnTypeExpr)
{
TypeChecker::TypeCheck(returnTypeExpr);
returnType = returnTypeExpr->GetType();
}
parameters->TypeCheck();
body->TypeCheck();
}
}
void Function::AddToScope()
{
ParentScope()->AddFunction(boost::static_pointer_cast<Function>(shared_from_this()));
}
bool Function::IsConversion() const
{
return IsConstructor() && conversion == IMPLICIT_CONVERSION && Parameters().Count() == 2 &&
Parameters()[0]->TypeExpr()->FullName() != Parameters()[1]->TypeExpr()->FullName();
}
bool Function::FindConversions(const ArgumentVector& arguments, ResolutionOption resolutionOption, FunctionListPtr& conversions, int& numConversions)
{
TypeCheck();
CM_CORE_ASSERT(Parameters().Count() == arguments.size());
int n = Parameters().Count();
for (int i = 0; i < n; ++i)
{
Argument sourceArgument = arguments[i];
TypePtr sourceArgumentType = sourceArgument.Type();
if (sourceArgumentType->IsFunctionSetType())
{
conversions->Append(FunctionPtr());
continue;
}
String sourceTypeName = sourceArgumentType->FullName();
TypePtr targetType = Parameters()[i]->GetType();
if (!targetType)
{
int x = 0;
}
CM_CORE_ASSERT(targetType);
String targetTypeName = targetType->FullName();
if (sourceTypeName == targetTypeName)
{
if (targetType->IsReferenceType() && sourceArgument.Category() != LVALUE)
{
return false;
}
if (targetType->IsConstType() && sourceArgument.Category() == LVALUE)
{
//++numConversions; // do not count lvalue to rvalue conversion
}
conversions->Append(FunctionPtr());
}
else
{
if (resolutionOption == ALLOW_TRIVIAL_CONVERSIONS || resolutionOption == DENY_LEFT_CONVERSION && i == 0)
{
return false;
}
FunctionPtr conversion = ConversionTable::Instance()->GetConversion(sourceTypeName, targetTypeName);
if (conversion)
{
conversions->Append(conversion);
++numConversions;
}
else
{
return false;
}
}
}
return true;
}
void Function::MarkCalledFunctions()
{
body->MarkCalledFunctions();
}
} } // namespace Cm::Core