From 91d4e8e0bab6f5285103af6ef84a7813cfbb61a2 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 2 Dec 2016 16:24:53 +0100 Subject: analysis: changes necessary to compile std/StandardToken.sol --- libsolidity/analysis/DeclarationContainer.cpp | 13 +++++++-- libsolidity/analysis/NameAndTypeResolver.cpp | 38 +++++++++++++++++++++------ libsolidity/analysis/TypeChecker.cpp | 19 ++++++++++++-- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/libsolidity/analysis/DeclarationContainer.cpp b/libsolidity/analysis/DeclarationContainer.cpp index 1599b83a..f8c12c5b 100644 --- a/libsolidity/analysis/DeclarationContainer.cpp +++ b/libsolidity/analysis/DeclarationContainer.cpp @@ -44,10 +44,19 @@ Declaration const* DeclarationContainer::conflictingDeclaration( if (dynamic_cast(&_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) - if (!dynamic_cast(declaration)) + { + if (dynamic_cast(declaration)) + continue; + if (auto variableDeclaration = dynamic_cast(declaration)) + { + if (variableDeclaration->isStateVariable() && !variableDeclaration->isConstant() && variableDeclaration->isPublic()) + continue; return declaration; + } + return declaration; + } } else if (declarations.size() == 1 && declarations.front() == &_declaration) return nullptr; diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 002ff811..ee05910c 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -260,20 +260,42 @@ vector NameAndTypeResolver::cleanedDeclarations( for (auto it = _declarations.begin(); it != _declarations.end(); ++it) { solAssert(*it, ""); - // the declaration is functionDefinition while declarations > 1 - FunctionDefinition const& functionDefinition = dynamic_cast(**it); - FunctionType functionType(functionDefinition); - for (auto parameter: functionType.parameterTypes() + functionType.returnParameterTypes()) - if (!parameter) - reportFatalDeclarationError(_identifier.location(), "Function type can not be used in this context"); + // the declaration is functionDefinition or a VariableDeclaration while declarations > 1 + solAssert(dynamic_cast(*it) || dynamic_cast(*it), + "Found overloading involving something not a function or a variable"); + + shared_ptr functionType {}; + + if (FunctionDefinition const* functionDefinition = dynamic_cast(*it)) + { + functionType = make_shared(*functionDefinition); + for (auto parameter: functionType->parameterTypes() + functionType->returnParameterTypes()) + if (!parameter) + reportFatalDeclarationError(_identifier.location(), "Function type can not be used in this context"); + } + else + { + VariableDeclaration const* variableDeclaration = dynamic_cast(*it); + functionType = make_shared(*variableDeclaration); + } + solAssert(functionType, "failed to determine the function type of the overloaded"); if (uniqueFunctions.end() == find_if( uniqueFunctions.begin(), uniqueFunctions.end(), [&](Declaration const* d) { - FunctionType newFunctionType(dynamic_cast(*d)); - return functionType.hasEqualArgumentTypes(newFunctionType); + if (FunctionDefinition const* functionDefinition = dynamic_cast(d)) + { + FunctionType const newFunctionType(*functionDefinition); + return functionType->hasEqualArgumentTypes(newFunctionType); + } + else if (VariableDeclaration const* variableDeclaration = dynamic_cast(d)) + { + FunctionType const newFunctionType(*variableDeclaration); + return functionType->hasEqualArgumentTypes(newFunctionType); + } + return false; // to make compiler happy } )) uniqueFunctions.push_back(*it); diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index e414e27c..67c8ac17 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1500,8 +1500,23 @@ bool TypeChecker::visit(Identifier const& _identifier) if (!annotation.referencedDeclaration) { 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 candidates; + + for (Declaration const* declaration: annotation.overloadedDeclarations) + { + if (VariableDeclaration const* variableDeclaration = dynamic_cast(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."); else if (annotation.overloadedDeclarations.size() == 1) annotation.referencedDeclaration = *annotation.overloadedDeclarations.begin(); -- cgit v1.2.3