aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLu Guanqun <guanqun.lu@gmail.com>2015-03-06 13:02:35 +0800
committerLu Guanqun <guanqun.lu@gmail.com>2015-03-08 22:50:54 +0800
commit40336154641da903f5721c3f2a3d136971236ed3 (patch)
treec6ecb37a98c2ef8fcfe30c3dd01112b6262c5812
parentddcfd441f304e02203f9fbed2477d69d3e48328f (diff)
downloaddexon-solidity-40336154641da903f5721c3f2a3d136971236ed3.tar
dexon-solidity-40336154641da903f5721c3f2a3d136971236ed3.tar.gz
dexon-solidity-40336154641da903f5721c3f2a3d136971236ed3.tar.bz2
dexon-solidity-40336154641da903f5721c3f2a3d136971236ed3.tar.lz
dexon-solidity-40336154641da903f5721c3f2a3d136971236ed3.tar.xz
dexon-solidity-40336154641da903f5721c3f2a3d136971236ed3.tar.zst
dexon-solidity-40336154641da903f5721c3f2a3d136971236ed3.zip
make it work for var x = f;
-rw-r--r--AST.cpp29
-rw-r--r--AST.h2
-rw-r--r--ExpressionCompiler.cpp13
-rw-r--r--Types.h9
4 files changed, 32 insertions, 21 deletions
diff --git a/AST.cpp b/AST.cpp
index 2aa57d7e..2fd60f7b 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -674,15 +674,23 @@ void FunctionCall::checkTypeRequirements()
else if (OverloadedFunctionType const* overloadedTypes = dynamic_cast<OverloadedFunctionType const*>(expressionType))
{
// this only applies to "x(3)" where x is assigned by "var x = f;" where f is an overloaded functions.
- overloadedTypes->m_identifier->overloadResolution(*this);
- FunctionType const* functionType = dynamic_cast<FunctionType const*>(overloadedTypes->m_identifier->getType().get());
+ auto identifier = dynamic_cast<Identifier*>(m_expression.get());
+ solAssert(identifier, "only applies to 'var x = f;'");
+
+ Declaration const* function = overloadedTypes->getIdentifier()->overloadResolution(*this);
+ if (!function)
+ BOOST_THROW_EXCEPTION(createTypeError("Can't resolve declarations"));
+
+ identifier->setReferencedDeclaration(*function);
+ identifier->checkTypeRequirements();
+
+ TypePointer type = identifier->getType();
+ FunctionType const* functionType = dynamic_cast<FunctionType const*>(type.get());
- // @todo actually the return type should be an anonymous struct,
- // but we change it to the type of the first return value until we have structs
if (functionType->getReturnParameterTypes().empty())
m_type = make_shared<VoidType>();
else
- m_type = functionType->getReturnParameterTypes().front();
+ m_type = functionType->getReturnParameterTypes().front();
}
else
BOOST_THROW_EXCEPTION(createTypeError("Type is not callable."));
@@ -781,7 +789,7 @@ void Identifier::checkTypeRequirementsWithFunctionCall(FunctionCall const& _func
solAssert(m_referencedDeclaration || !m_overloadedDeclarations.empty(), "Identifier not resolved.");
if (!m_referencedDeclaration)
- overloadResolution(_functionCall);
+ setReferencedDeclaration(*overloadResolution(_functionCall));
checkTypeRequirements();
}
@@ -791,7 +799,7 @@ void Identifier::checkTypeRequirementsFromVariableDeclaration()
solAssert(m_referencedDeclaration || !m_overloadedDeclarations.empty(), "Identifier not resolved.");
if (!m_referencedDeclaration)
- m_type = make_shared<OverloadedFunctionType>(m_overloadedDeclarations, this);
+ m_type = make_shared<OverloadedFunctionType>(this);
else
checkTypeRequirements();
@@ -808,13 +816,11 @@ void Identifier::checkTypeRequirements()
BOOST_THROW_EXCEPTION(createTypeError("Declaration referenced before type could be determined."));
}
-void Identifier::overloadResolution(FunctionCall const& _functionCall)
+Declaration const* Identifier::overloadResolution(FunctionCall const& _functionCall)
{
solAssert(m_overloadedDeclarations.size() > 1, "FunctionIdentifier not resolved.");
solAssert(!m_referencedDeclaration, "Referenced declaration should be null before overload resolution.");
- bool resolved = false;
-
std::vector<ASTPointer<Expression const>> arguments = _functionCall.getArguments();
std::vector<ASTPointer<ASTString>> const& argumentNames = _functionCall.getNames();
@@ -844,7 +850,7 @@ void Identifier::overloadResolution(FunctionCall const& _functionCall)
{
return declaration->getScope() == possibles.front()->getScope();
}))
- setReferencedDeclaration(*possibles.front());
+ return possibles.front();
else
BOOST_THROW_EXCEPTION(createTypeError("Can't resolve identifier"));
}
@@ -852,6 +858,7 @@ void Identifier::overloadResolution(FunctionCall const& _functionCall)
// named arguments
// TODO: don't support right now
BOOST_THROW_EXCEPTION(createTypeError("Named arguments with overloaded functions are not supported yet."));
+ return nullptr;
}
void ElementaryTypeNameExpression::checkTypeRequirements()
diff --git a/AST.h b/AST.h
index fa1d4a92..6cc7f742 100644
--- a/AST.h
+++ b/AST.h
@@ -1157,7 +1157,7 @@ public:
void checkTypeRequirementsWithFunctionCall(FunctionCall const& _functionCall);
void checkTypeRequirementsFromVariableDeclaration();
- void overloadResolution(FunctionCall const& _functionCall);
+ Declaration const* overloadResolution(FunctionCall const& _functionCall);
private:
ASTPointer<ASTString> m_name;
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 5e5442ba..4be461b2 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -822,11 +822,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
void ExpressionCompiler::endVisit(Identifier const& _identifier)
{
Declaration const* declaration = _identifier.getReferencedDeclaration();
- if (declaration == nullptr)
- {
- // no-op
- }
- else if (MagicVariableDeclaration const* magicVar = dynamic_cast<MagicVariableDeclaration const*>(declaration))
+ if (MagicVariableDeclaration const* magicVar = dynamic_cast<MagicVariableDeclaration const*>(declaration))
{
if (magicVar->getType()->getCategory() == Type::Category::Contract)
// "this" or "super"
@@ -849,6 +845,13 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
{
// no-op
}
+ else if (declaration == nullptr && _identifier.getOverloadedDeclarations().size() > 1)
+ {
+ // var x = f;
+ declaration = *_identifier.getOverloadedDeclarations().begin();
+ FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration);
+ m_context << m_context.getVirtualFunctionEntryLabel(*functionDef).pushTag();
+ }
else
{
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier type not expected in expression context."));
diff --git a/Types.h b/Types.h
index 5dd742ad..b19f7540 100644
--- a/Types.h
+++ b/Types.h
@@ -527,13 +527,14 @@ private:
class OverloadedFunctionType: public Type
{
public:
- explicit OverloadedFunctionType(std::set<Declaration const*> const& _overloadedDeclarations, Identifier* _identifier):
- m_overloadedDeclarations(_overloadedDeclarations), m_identifier(_identifier) {}
+ explicit OverloadedFunctionType(Identifier* _identifier): m_identifier(_identifier) {}
+
virtual Category getCategory() const override { return Category::OverloadedFunctions; }
virtual std::string toString() const override { return "OverloadedFunctions"; }
-// private:
- std::set<Declaration const*> m_overloadedDeclarations;
+ Identifier* getIdentifier() const { return m_identifier; }
+
+private:
Identifier * m_identifier;
};