analysis: changes necessary to compile std/StandardToken.sol

This commit is contained in:
Yoichi Hirai 2016-12-02 16:24:53 +01:00
parent 42b6726173
commit 91d4e8e0ba
No known key found for this signature in database
GPG Key ID: E7B75D080FCF7992
3 changed files with 58 additions and 12 deletions

View File

@ -44,11 +44,20 @@ Declaration const* DeclarationContainer::conflictingDeclaration(
if (dynamic_cast<FunctionDefinition const*>(&_declaration)) if (dynamic_cast<FunctionDefinition const*>(&_declaration))
{ {
// check that all other declarations with the same name are functions // check that all other declarations with the same name are functions or a public state variable
for (Declaration const* declaration: declarations) for (Declaration const* declaration: declarations)
if (!dynamic_cast<FunctionDefinition const*>(declaration)) {
if (dynamic_cast<FunctionDefinition const*>(declaration))
continue;
if (auto variableDeclaration = dynamic_cast<VariableDeclaration const*>(declaration))
{
if (variableDeclaration->isStateVariable() && !variableDeclaration->isConstant() && variableDeclaration->isPublic())
continue;
return declaration; return declaration;
} }
return declaration;
}
}
else if (declarations.size() == 1 && declarations.front() == &_declaration) else if (declarations.size() == 1 && declarations.front() == &_declaration)
return nullptr; return nullptr;
else if (!declarations.empty()) else if (!declarations.empty())

View File

@ -260,20 +260,42 @@ vector<Declaration const*> NameAndTypeResolver::cleanedDeclarations(
for (auto it = _declarations.begin(); it != _declarations.end(); ++it) for (auto it = _declarations.begin(); it != _declarations.end(); ++it)
{ {
solAssert(*it, ""); solAssert(*it, "");
// the declaration is functionDefinition while declarations > 1 // the declaration is functionDefinition or a VariableDeclaration while declarations > 1
FunctionDefinition const& functionDefinition = dynamic_cast<FunctionDefinition const&>(**it); solAssert(dynamic_cast<FunctionDefinition const*>(*it) || dynamic_cast<VariableDeclaration const*>(*it),
FunctionType functionType(functionDefinition); "Found overloading involving something not a function or a variable");
for (auto parameter: functionType.parameterTypes() + functionType.returnParameterTypes())
shared_ptr<FunctionType const> functionType {};
if (FunctionDefinition const* functionDefinition = dynamic_cast<FunctionDefinition const*>(*it))
{
functionType = make_shared<FunctionType const>(*functionDefinition);
for (auto parameter: functionType->parameterTypes() + functionType->returnParameterTypes())
if (!parameter) if (!parameter)
reportFatalDeclarationError(_identifier.location(), "Function type can not be used in this context"); reportFatalDeclarationError(_identifier.location(), "Function type can not be used in this context");
}
else
{
VariableDeclaration const* variableDeclaration = dynamic_cast<VariableDeclaration const*>(*it);
functionType = make_shared<FunctionType const>(*variableDeclaration);
}
solAssert(functionType, "failed to determine the function type of the overloaded");
if (uniqueFunctions.end() == find_if( if (uniqueFunctions.end() == find_if(
uniqueFunctions.begin(), uniqueFunctions.begin(),
uniqueFunctions.end(), uniqueFunctions.end(),
[&](Declaration const* d) [&](Declaration const* d)
{ {
FunctionType newFunctionType(dynamic_cast<FunctionDefinition const&>(*d)); if (FunctionDefinition const* functionDefinition = dynamic_cast<FunctionDefinition const*>(d))
return functionType.hasEqualArgumentTypes(newFunctionType); {
FunctionType const newFunctionType(*functionDefinition);
return functionType->hasEqualArgumentTypes(newFunctionType);
}
else if (VariableDeclaration const* variableDeclaration = dynamic_cast<VariableDeclaration const*>(d))
{
FunctionType const newFunctionType(*variableDeclaration);
return functionType->hasEqualArgumentTypes(newFunctionType);
}
return false; // to make compiler happy
} }
)) ))
uniqueFunctions.push_back(*it); uniqueFunctions.push_back(*it);

View File

@ -1500,8 +1500,23 @@ bool TypeChecker::visit(Identifier const& _identifier)
if (!annotation.referencedDeclaration) if (!annotation.referencedDeclaration)
{ {
if (!annotation.argumentTypes) if (!annotation.argumentTypes)
fatalTypeError(_identifier.location(), "Unable to determine overloaded type."); {
if (annotation.overloadedDeclarations.empty()) // The identifier should be a public state variable shadowing other functions
vector<Declaration const*> candidates;
for (Declaration const* declaration: annotation.overloadedDeclarations)
{
if (VariableDeclaration const* variableDeclaration = dynamic_cast<decltype(variableDeclaration)>(declaration))
candidates.push_back(declaration);
}
if (candidates.empty())
fatalTypeError(_identifier.location(), "No matching declaration found after variable lookup.");
else if (candidates.size() == 1)
annotation.referencedDeclaration = candidates.front();
else
fatalTypeError(_identifier.location(), "No unique declaration found after variable lookup.");
}
else if (annotation.overloadedDeclarations.empty())
fatalTypeError(_identifier.location(), "No candidates for overload resolution found."); fatalTypeError(_identifier.location(), "No candidates for overload resolution found.");
else if (annotation.overloadedDeclarations.size() == 1) else if (annotation.overloadedDeclarations.size() == 1)
annotation.referencedDeclaration = *annotation.overloadedDeclarations.begin(); annotation.referencedDeclaration = *annotation.overloadedDeclarations.begin();