Merge pull request #636 from chriseth/sol_fix_foreignFunctions

Fix: Resolve function types of all contracts before checking types inside functions.
This commit is contained in:
Gav Wood 2014-12-17 13:49:31 +01:00
commit cb43022d7a
3 changed files with 18 additions and 6 deletions

View File

@ -73,6 +73,15 @@ void CompilerStack::parse()
resolver.resolveNamesAndTypes(*contract);
m_contracts[contract->getName()].contract = contract;
}
for (Source const* source: m_sourceOrder)
for (ASTPointer<ASTNode> const& node: source->ast->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
m_globalContext->setCurrentContract(*contract);
resolver.updateDeclaration(*m_globalContext->getCurrentThis());
resolver.checkTypeRequirements(*contract);
m_contracts[contract->getName()].contract = contract;
}
m_parseSuccessful = true;
}

View File

@ -49,8 +49,6 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
m_currentScope = &m_scopes[&_contract];
for (ASTPointer<StructDefinition> const& structDef: _contract.getDefinedStructs())
ReferencesResolver resolver(*structDef, *this, nullptr);
for (ASTPointer<StructDefinition> const& structDef: _contract.getDefinedStructs())
structDef->checkValidityOfMembers();
for (ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables())
ReferencesResolver resolver(*variable, *this, nullptr);
for (ASTPointer<FunctionDefinition> const& function: _contract.getDefinedFunctions())
@ -59,13 +57,16 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
ReferencesResolver referencesResolver(*function, *this,
function->getReturnParameterList().get());
}
// First, the parameter types of all functions need to be resolved before we can check
// the types, since it is possible to call functions that are only defined later
// in the source.
_contract.checkTypeRequirements();
m_currentScope = &m_scopes[nullptr];
}
void NameAndTypeResolver::checkTypeRequirements(ContractDefinition& _contract)
{
for (ASTPointer<StructDefinition> const& structDef: _contract.getDefinedStructs())
structDef->checkValidityOfMembers();
_contract.checkTypeRequirements();
}
void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration)
{
m_scopes[nullptr].registerDeclaration(_declaration, true);

View File

@ -46,6 +46,8 @@ public:
void registerDeclarations(SourceUnit& _sourceUnit);
/// Resolves all names and types referenced from the given contract.
void resolveNamesAndTypes(ContractDefinition& _contract);
/// Check all type requirements in the given contract.
void checkTypeRequirements(ContractDefinition& _contract);
/// Updates the given global declaration (used for "this"). Not to be used with declarations
/// that create their own scope.
void updateDeclaration(Declaration const& _declaration);