aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AST.h8
-rw-r--r--DeclarationContainer.cpp10
-rw-r--r--DeclarationContainer.h8
-rw-r--r--NameAndTypeResolver.cpp69
-rw-r--r--NameAndTypeResolver.h13
-rw-r--r--Types.h1
6 files changed, 55 insertions, 54 deletions
diff --git a/AST.h b/AST.h
index fde0b71b..be118be3 100644
--- a/AST.h
+++ b/AST.h
@@ -1217,10 +1217,10 @@ public:
}
Declaration const& getReferencedDeclaration() const;
- /// Stores a set of possible declarations referenced by this identifier. Has to be resolved
+ /// Stores a possible declarations referenced by this identifier. Has to be resolved
/// providing argument types using overloadResolution before the referenced declaration
/// is accessed.
- void setOverloadedDeclarations(std::set<Declaration const*> const& _declarations)
+ void setOverloadedDeclarations(std::vector<Declaration const*> const& _declarations)
{
m_overloadedDeclarations = _declarations;
}
@@ -1237,8 +1237,8 @@ private:
/// Stores a reference to the current contract. This is needed because types of base contracts
/// change depending on the context.
ContractDefinition const* m_currentContract = nullptr;
- /// A set of overloaded declarations, right now only FunctionDefinition has overloaded declarations.
- std::set<Declaration const*> m_overloadedDeclarations;
+ /// A vector of overloaded declarations, right now only FunctionDefinition has overloaded declarations.
+ std::vector<Declaration const*> m_overloadedDeclarations;
};
/**
diff --git a/DeclarationContainer.cpp b/DeclarationContainer.cpp
index c836663c..ec8a59bb 100644
--- a/DeclarationContainer.cpp
+++ b/DeclarationContainer.cpp
@@ -37,6 +37,7 @@ Declaration const* DeclarationContainer::conflictingDeclaration(Declaration cons
declarations += m_declarations.at(name);
if (m_invisibleDeclarations.count(name))
declarations += m_invisibleDeclarations.at(name);
+
if (dynamic_cast<FunctionDefinition const*>(&_declaration))
{
// check that all other declarations with the same name are functions
@@ -66,14 +67,13 @@ bool DeclarationContainer::registerDeclaration(Declaration const& _declaration,
return false;
if (_invisible)
- m_invisibleDeclarations[name].insert(&_declaration);
+ m_invisibleDeclarations[name].push_back(&_declaration);
else
- m_declarations[name].insert(&_declaration);
-
+ m_declarations[name].push_back(&_declaration);
return true;
}
-set<Declaration const*> DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const
+std::vector<const Declaration *> DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const
{
solAssert(!_name.empty(), "Attempt to resolve empty name.");
auto result = m_declarations.find(_name);
@@ -81,5 +81,5 @@ set<Declaration const*> DeclarationContainer::resolveName(ASTString const& _name
return result->second;
if (_recursive && m_enclosingContainer)
return m_enclosingContainer->resolveName(_name, true);
- return set<Declaration const*>({});
+ return vector<Declaration const*>({});
}
diff --git a/DeclarationContainer.h b/DeclarationContainer.h
index 94545eef..0f0b5717 100644
--- a/DeclarationContainer.h
+++ b/DeclarationContainer.h
@@ -48,17 +48,17 @@ public:
/// @param _update if true, replaces a potential declaration that is already present
/// @returns false if the name was already declared.
bool registerDeclaration(Declaration const& _declaration, bool _invisible = false, bool _update = false);
- std::set<Declaration const*> resolveName(ASTString const& _name, bool _recursive = false) const;
+ std::vector<Declaration const*> resolveName(ASTString const& _name, bool _recursive = false) const;
Declaration const* getEnclosingDeclaration() const { return m_enclosingDeclaration; }
- std::map<ASTString, std::set<Declaration const*>> const& getDeclarations() const { return m_declarations; }
+ std::map<ASTString, std::vector<Declaration const*>> const& getDeclarations() const { return m_declarations; }
/// @returns whether declaration is valid, and if not also returns previous declaration.
Declaration const* conflictingDeclaration(Declaration const& _declaration) const;
private:
Declaration const* m_enclosingDeclaration;
DeclarationContainer const* m_enclosingContainer;
- std::map<ASTString, std::set<Declaration const*>> m_declarations;
- std::map<ASTString, std::set<Declaration const*>> m_invisibleDeclarations;
+ std::map<ASTString, std::vector<Declaration const*>> m_declarations;
+ std::map<ASTString, std::vector<Declaration const*>> m_invisibleDeclarations;
};
}
diff --git a/NameAndTypeResolver.cpp b/NameAndTypeResolver.cpp
index 9aebbf05..4d33048d 100644
--- a/NameAndTypeResolver.cpp
+++ b/NameAndTypeResolver.cpp
@@ -53,9 +53,13 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
m_currentScope = &m_scopes[&_contract];
linearizeBaseContracts(_contract);
- // we first import non-functions only as we do not yet know the argument types
- for (ContractDefinition const* base: _contract.getLinearizedBaseContracts())
- importInheritedScope(*base, false); // import non-functions
+ std::vector<ContractDefinition const*> realBases(
+ ++_contract.getLinearizedBaseContracts().begin(),
+ _contract.getLinearizedBaseContracts().end()
+ );
+
+ for (ContractDefinition const* base: realBases)
+ importInheritedScope(*base);
for (ASTPointer<StructDefinition> const& structDef: _contract.getDefinedStructs())
ReferencesResolver resolver(*structDef, *this, &_contract, nullptr);
@@ -80,8 +84,6 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
}
m_currentScope = &m_scopes[&_contract];
- for (ContractDefinition const* base: _contract.getLinearizedBaseContracts())
- importInheritedScope(*base, true); // import functions
// now resolve references inside the code
for (ASTPointer<ModifierDefinition> const& modifier: _contract.getFunctionModifiers())
@@ -115,20 +117,41 @@ void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration)
solAssert(_declaration.getScope() == nullptr, "Updated declaration outside global scope.");
}
-set<Declaration const*> NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const
+vector<Declaration const*> NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const
{
auto iterator = m_scopes.find(_scope);
if (iterator == end(m_scopes))
- return set<Declaration const*>({});
+ return vector<Declaration const*>({});
return iterator->second.resolveName(_name, false);
}
-set<Declaration const*> NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name, bool _recursive)
+vector<Declaration const*> NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name, bool _recursive)
{
return m_currentScope->resolveName(_name, _recursive);
}
-void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base, bool _importFunctions)
+vector<Declaration const*> NameAndTypeResolver::cleanupedDeclarations(Identifier const& _identifier)
+{
+ vector<Declaration const*> result;
+ for (auto declaration : m_currentScope->resolveName(_identifier.getName()))
+ {
+ solAssert(declaration, "");
+ // the declaration is functionDefinition while declarations > 1
+ FunctionDefinition const& functionDefinition = dynamic_cast<FunctionDefinition const&>(*declaration);
+ FunctionType functionType(functionDefinition);
+ for(auto parameter: functionType.getParameterTypes() + functionType.getReturnParameterTypes())
+ if (!parameter)
+ BOOST_THROW_EXCEPTION(
+ DeclarationError() <<
+ errinfo_sourceLocation(_identifier.getLocation()) <<
+ errinfo_comment("Function type can not be used in this context")
+ );
+ //////////delete repitations. check by hasequalparameter types of function type
+ }
+ return result;
+}
+
+void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base)
{
auto iterator = m_scopes.find(&_base);
solAssert(iterator != end(m_scopes), "");
@@ -136,30 +159,7 @@ void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base,
for (auto const& declaration: nameAndDeclaration.second)
// Import if it was declared in the base, is not the constructor and is visible in derived classes
if (declaration->getScope() == &_base && declaration->isVisibleInDerivedContracts())
- {
- auto function = dynamic_cast<FunctionDefinition const*>(declaration);
- if ((function == nullptr) == _importFunctions)
- continue;
- if (!!function)
- {
- FunctionType functionType(*function);
- // only import if a function with the same arguments does not exist yet
- bool functionWithEqualArgumentsFound = false;
- for (auto knownDeclaration: m_currentScope->resolveName(nameAndDeclaration.first))
- {
- auto knownFunction = dynamic_cast<FunctionDefinition const*>(knownDeclaration);
- if (!knownFunction)
- continue; // this is not legal, but will be caught later
- if (!FunctionType(*knownFunction).hasEqualArgumentTypes(functionType))
- continue;
- functionWithEqualArgumentsFound = true;
- break;
- }
- if (functionWithEqualArgumentsFound)
- continue;
- }
m_currentScope->registerDeclaration(*declaration);
- }
}
void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) const
@@ -465,10 +465,9 @@ bool ReferencesResolver::visit(Identifier& _identifier)
errinfo_comment("Undeclared identifier.")
);
else if (declarations.size() == 1)
- _identifier.setReferencedDeclaration(**declarations.begin(), m_currentContract);
+ _identifier.setReferencedDeclaration(*declarations.front(), m_currentContract);
else
- // Duplicate declaration will be checked in checkTypeRequirements()
- _identifier.setOverloadedDeclarations(declarations);
+ _identifier.setOverloadedDeclarations(m_resolver.cleanupedDeclarations(_identifier));
return false;
}
diff --git a/NameAndTypeResolver.h b/NameAndTypeResolver.h
index 6528bbef..21857352 100644
--- a/NameAndTypeResolver.h
+++ b/NameAndTypeResolver.h
@@ -56,19 +56,20 @@ public:
/// Resolves the given @a _name inside the scope @a _scope. If @a _scope is omitted,
/// the global scope is used (i.e. the one containing only the contract).
/// @returns a pointer to the declaration on success or nullptr on failure.
- std::set<Declaration const*> resolveName(ASTString const& _name, Declaration const* _scope = nullptr) const;
+ std::vector<const Declaration *> resolveName(ASTString const& _name, Declaration const* _scope = nullptr) const;
/// Resolves a name in the "current" scope. Should only be called during the initial
/// resolving phase.
- std::set<Declaration const*> getNameFromCurrentScope(ASTString const& _name, bool _recursive = true);
+ std::vector<Declaration const*> getNameFromCurrentScope(ASTString const& _name, bool _recursive = true);
+
+ std::vector<Declaration const*> cleanupedDeclarations(Identifier const& _identifier);
private:
void reset();
- /// Either imports all non-function members or all function members declared directly in the
- /// given contract (i.e. does not import inherited members) into the current scope if they are
- ///not present already.
- void importInheritedScope(ContractDefinition const& _base, bool _importFunctions);
+ /// Imports all members declared directly in the given contract (i.e. does not import inherited members)
+ /// into the current scope if they are not present already.
+ void importInheritedScope(ContractDefinition const& _base);
/// Computes "C3-Linearization" of base contracts and stores it inside the contract.
void linearizeBaseContracts(ContractDefinition& _contract) const;
diff --git a/Types.h b/Types.h
index 65a6867d..5b95e556 100644
--- a/Types.h
+++ b/Types.h
@@ -617,6 +617,7 @@ public:
/// @returns true if this function can take the given argument types (possibly
/// after implicit conversion).
bool canTakeArguments(TypePointers const& _arguments) const;
+ /// @returns true if the types of parameters are equal(does't check return parameter types)
bool hasEqualArgumentTypes(FunctionType const& _other) const;
Location const& getLocation() const { return m_location; }