This commit is contained in:
Daniel Kirchner 2023-06-23 18:37:58 +02:00
parent 14a34ae088
commit 315270f3bb
15 changed files with 318 additions and 65 deletions

View File

@ -50,6 +50,8 @@ set(sources
analysis/experimental/Analysis.h analysis/experimental/Analysis.h
analysis/experimental/TypeInference.cpp analysis/experimental/TypeInference.cpp
analysis/experimental/TypeInference.h analysis/experimental/TypeInference.h
analysis/experimental/TypeRegistration.cpp
analysis/experimental/TypeRegistration.h
analysis/experimental/SyntaxRestrictor.cpp analysis/experimental/SyntaxRestrictor.cpp
analysis/experimental/SyntaxRestrictor.h analysis/experimental/SyntaxRestrictor.h
ast/AST.cpp ast/AST.cpp

View File

@ -19,26 +19,87 @@
#include <libsolidity/analysis/experimental/SyntaxRestrictor.h> #include <libsolidity/analysis/experimental/SyntaxRestrictor.h>
#include <libsolidity/analysis/experimental/TypeInference.h> #include <libsolidity/analysis/experimental/TypeInference.h>
#include <libsolidity/analysis/experimental/TypeRegistration.h>
using namespace std; using namespace std;
using namespace solidity::langutil; using namespace solidity::langutil;
using namespace solidity::frontend::experimental; using namespace solidity::frontend::experimental;
// TODO: creating all of them for all nodes up front may be wasteful, we should improve the mechanism.
struct Analysis::AnnotationContainer
{
TypeRegistration::Annotation typeRegistrationAnnotation;
TypeInference::Annotation typeInferenceAnnotation;
};
template<>
TypeRegistration::Annotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeRegistration>::get(ASTNode const& _node)
{
return analysis.annotationContainer(_node).typeRegistrationAnnotation;
}
template<>
TypeInference::Annotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeInference>::get(ASTNode const& _node)
{
return analysis.annotationContainer(_node).typeInferenceAnnotation;
}
Analysis::AnnotationContainer& Analysis::annotationContainer(ASTNode const& _node)
{
solAssert(_node.id() > 0);
size_t id = static_cast<size_t>(_node.id());
solAssert(id < m_maxAstId);
return m_annotations[id];
}
Analysis::Analysis(langutil::ErrorReporter& _errorReporter, uint64_t _maxAstId): Analysis::Analysis(langutil::ErrorReporter& _errorReporter, uint64_t _maxAstId):
m_errorReporter(_errorReporter), m_errorReporter(_errorReporter),
m_maxAstId(_maxAstId) m_maxAstId(_maxAstId),
m_annotations(std::make_unique<AnnotationContainer[]>(static_cast<size_t>(_maxAstId)))
{ {
} }
Analysis::~Analysis()
{}
template<size_t... Is>
std::tuple<std::integral_constant<size_t, Is>...> makeIndexTuple(std::index_sequence<Is...>) {
return std::make_tuple( std::integral_constant<size_t, Is>{}...);
}
bool Analysis::check(vector<shared_ptr<SourceUnit const>> const& _sourceUnits) bool Analysis::check(vector<shared_ptr<SourceUnit const>> const& _sourceUnits)
{ {
SyntaxRestrictor syntaxRestrictor{m_errorReporter}; using AnalysisSteps = std::tuple<SyntaxRestrictor, TypeRegistration, TypeInference>;
for (auto source: _sourceUnits)
if (!syntaxRestrictor.check(*source)) return std::apply([&](auto... _indexTuple) {
return false; return ([&](auto&& _step) {
TypeInference typeInference{*this}; for (auto source: _sourceUnits)
for (auto source: _sourceUnits) if (!_step.analyze(*source))
if (!typeInference.analyze(*source)) return false;
return false; return true;
}(std::tuple_element_t<decltype(_indexTuple)::value, AnalysisSteps>{*this}) && ...);
}, makeIndexTuple(std::make_index_sequence<std::tuple_size_v<AnalysisSteps>>{}));
/*
{
SyntaxRestrictor syntaxRestrictor{*this};
for (auto source: _sourceUnits)
if (!syntaxRestrictor.analyze(*source))
return false;
}
{
TypeRegistration typeRegistration{*this};
for (auto source: _sourceUnits)
if (!typeRegistration.analyze(*source))
return false;
}
{
TypeInference typeInference{*this};
for (auto source: _sourceUnits)
if (!typeInference.analyze(*source))
return false;
}
return true; return true;
*/
} }

View File

@ -17,6 +17,8 @@
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
#pragma once #pragma once
#include <libsolidity/ast/experimental/TypeSystem.h>
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <vector> #include <vector>
@ -24,6 +26,7 @@
namespace solidity::frontend namespace solidity::frontend
{ {
class SourceUnit; class SourceUnit;
class ASTNode;
} }
namespace solidity::langutil namespace solidity::langutil
@ -33,19 +36,43 @@ class ErrorReporter;
namespace solidity::frontend::experimental namespace solidity::frontend::experimental
{ {
class TypeSystem;
class Analysis;
namespace detail
{
template<typename Step>
struct AnnotationFetcher
{
Analysis& analysis;
typename Step::Annotation& get(ASTNode const& _node);
};
}
class Analysis class Analysis
{ {
struct AnnotationContainer;
public: public:
Analysis(langutil::ErrorReporter& _errorReporter, uint64_t _maxAstId); Analysis(langutil::ErrorReporter& _errorReporter, uint64_t _maxAstId);
Analysis(Analysis const&) = delete; Analysis(Analysis const&) = delete;
~Analysis();
Analysis const& operator=(Analysis const&) = delete; Analysis const& operator=(Analysis const&) = delete;
bool check(std::vector<std::shared_ptr<SourceUnit const>> const& _sourceUnits); bool check(std::vector<std::shared_ptr<SourceUnit const>> const& _sourceUnits);
langutil::ErrorReporter& errorReporter() { return m_errorReporter; } langutil::ErrorReporter& errorReporter() { return m_errorReporter; }
uint64_t maxAstId() const { return m_maxAstId; } uint64_t maxAstId() const { return m_maxAstId; }
TypeSystem& typeSystem() { return m_typeSystem; }
template<typename Step>
typename Step::Annotation& annotation(ASTNode const& _node)
{
return detail::AnnotationFetcher<Step>{*this}.get(_node);
}
AnnotationContainer& annotationContainer(ASTNode const& _node);
private: private:
langutil::ErrorReporter& m_errorReporter; langutil::ErrorReporter& m_errorReporter;
TypeSystem m_typeSystem;
uint64_t m_maxAstId = 0; uint64_t m_maxAstId = 0;
std::unique_ptr<AnnotationContainer[]> m_annotations;
}; };
} }

View File

@ -18,13 +18,18 @@
#include <libsolidity/analysis/experimental/SyntaxRestrictor.h> #include <libsolidity/analysis/experimental/SyntaxRestrictor.h>
#include <libsolidity/analysis/experimental/Analysis.h>
#include <liblangutil/Exceptions.h> #include <liblangutil/Exceptions.h>
using namespace solidity::frontend; using namespace solidity::frontend;
using namespace solidity::frontend::experimental; using namespace solidity::frontend::experimental;
using namespace solidity::langutil; using namespace solidity::langutil;
bool SyntaxRestrictor::check(ASTNode const& _astRoot) SyntaxRestrictor::SyntaxRestrictor(Analysis& _analysis): m_errorReporter(_analysis.errorReporter())
{}
bool SyntaxRestrictor::analyze(ASTNode const& _astRoot)
{ {
_astRoot.accept(*this); _astRoot.accept(*this);
return !Error::containsErrors(m_errorReporter.errors()); return !Error::containsErrors(m_errorReporter.errors());

View File

@ -24,14 +24,14 @@
namespace solidity::frontend::experimental namespace solidity::frontend::experimental
{ {
class Analysis;
class SyntaxRestrictor: public ASTConstVisitor class SyntaxRestrictor: public ASTConstVisitor
{ {
public: public:
/// @param _errorReporter provides the error logging functionality. SyntaxRestrictor(Analysis& _analysis);
explicit SyntaxRestrictor(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}
bool check(ASTNode const& _astRoot); bool analyze(ASTNode const& _astRoot);
private: private:
/// Default visit will reject all AST nodes that are not explicitly allowed. /// Default visit will reject all AST nodes that are not explicitly allowed.

View File

@ -34,22 +34,12 @@ using namespace solidity::langutil;
TypeInference::TypeInference(Analysis& _analysis): TypeInference::TypeInference(Analysis& _analysis):
m_analysis(_analysis), m_analysis(_analysis),
m_errorReporter(_analysis.errorReporter()) m_errorReporter(_analysis.errorReporter()),
m_typeSystem(_analysis.typeSystem())
{ {
for (auto [type, name, arity]: std::initializer_list<std::tuple<BuiltinType, const char*, uint64_t>> {
{BuiltinType::Void, "void", 0},
{BuiltinType::Function, "fun", 2},
{BuiltinType::Unit, "unit", 0},
{BuiltinType::Pair, "pair", 2},
{BuiltinType::Word, "word", 0},
{BuiltinType::Integer, "integer", 0}
})
m_typeSystem.declareBuiltinType(type, name, arity);
m_voidType = m_typeSystem.builtinType(BuiltinType::Void, {}); m_voidType = m_typeSystem.builtinType(BuiltinType::Void, {});
m_wordType = m_typeSystem.builtinType(BuiltinType::Word, {}); m_wordType = m_typeSystem.builtinType(BuiltinType::Word, {});
m_integerType = m_typeSystem.builtinType(BuiltinType::Integer, {}); m_integerType = m_typeSystem.builtinType(BuiltinType::Integer, {});
m_typeAnnotations.resize(_analysis.maxAstId());
} }
bool TypeInference::analyze(SourceUnit const& _sourceUnit) bool TypeInference::analyze(SourceUnit const& _sourceUnit)
@ -72,7 +62,7 @@ bool TypeInference::visit(FunctionDefinition const& _functionDefinition)
auto typeFromParameterList = [&](ParameterList const* _list) { auto typeFromParameterList = [&](ParameterList const* _list) {
if (!_list) if (!_list)
return m_typeSystem.builtinType(BuiltinType::Unit, {}); return m_typeSystem.builtinType(BuiltinType::Unit, {});
return TypeSystemHelpers{m_typeSystem}.tupleType(_list->parameters() | ranges::view::transform([&](auto _param) { return TypeSystemHelpers{m_typeSystem}.tupleType(_list->parameters() | ranges::views::transform([&](auto _param) {
auto& argAnnotation = annotation(*_param); auto& argAnnotation = annotation(*_param);
solAssert(argAnnotation.type); solAssert(argAnnotation.type);
return *argAnnotation.type; return *argAnnotation.type;
@ -173,7 +163,6 @@ experimental::Type TypeInference::fromTypeName(TypeName const& _typeName)
else else
m_errorReporter.typeError(0000_error, _typeName.location(), "Unsupported type name."); m_errorReporter.typeError(0000_error, _typeName.location(), "Unsupported type name.");
return m_typeSystem.freshTypeVariable(false); return m_typeSystem.freshTypeVariable(false);
} }
void TypeInference::unify(Type _a, Type _b) void TypeInference::unify(Type _a, Type _b)
{ {
@ -256,12 +245,9 @@ void TypeInference::endVisit(Assignment const& _assignment)
assignmentAnnotation.type = m_typeSystem.resolve(*lhsAnnotation.type); assignmentAnnotation.type = m_typeSystem.resolve(*lhsAnnotation.type);
} }
TypeInference::TypeAnnotation& TypeInference::annotation(ASTNode const& _node) TypeInference::Annotation& TypeInference::annotation(ASTNode const& _node)
{ {
auto& annotation = m_typeAnnotations.at(static_cast<size_t>(_node.id())); return m_analysis.annotation<TypeInference>(_node);
if (!annotation)
annotation = make_unique<TypeAnnotation>();
return *annotation;
} }
bool TypeInference::visit(Identifier const& _identifier) bool TypeInference::visit(Identifier const& _identifier)

View File

@ -22,8 +22,6 @@
#include <liblangutil/ErrorReporter.h> #include <liblangutil/ErrorReporter.h>
#include <range/v3/span.hpp>
namespace solidity::frontend::experimental namespace solidity::frontend::experimental
{ {
@ -35,6 +33,12 @@ public:
TypeInference(Analysis& _analysis); TypeInference(Analysis& _analysis);
bool analyze(SourceUnit const& _sourceUnit); bool analyze(SourceUnit const& _sourceUnit);
struct Annotation
{
std::optional<Type> type;
};
private: private:
bool visit(Block const&) override { return true; } bool visit(Block const&) override { return true; }
bool visit(VariableDeclarationStatement const&) override { return true; } bool visit(VariableDeclarationStatement const&) override { return true; }
@ -67,22 +71,15 @@ private:
Type fromTypeName(TypeName const& _typeName); Type fromTypeName(TypeName const& _typeName);
Analysis& m_analysis; Analysis& m_analysis;
langutil::ErrorReporter& m_errorReporter; langutil::ErrorReporter& m_errorReporter;
TypeSystem m_typeSystem; TypeSystem& m_typeSystem;
Type m_voidType; Type m_voidType;
Type m_wordType; Type m_wordType;
Type m_integerType; Type m_integerType;
std::optional<Type> m_currentFunctionType; std::optional<Type> m_currentFunctionType;
struct TypeAnnotation Annotation& annotation(ASTNode const& _node);
{
std::optional<Type> type;
};
TypeAnnotation& annotation(ASTNode const& _node);
void unify(Type _a, Type _b); void unify(Type _a, Type _b);
std::vector<std::unique_ptr<TypeAnnotation>> m_typeAnnotations;
}; };
} }

View File

@ -0,0 +1,102 @@
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
#include <libsolidity/analysis/experimental/TypeRegistration.h>
#include <libsolidity/analysis/experimental/Analysis.h>
#include <liblangutil/Exceptions.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/AsmAnalysisInfo.h>
#include <libyul/AST.h>
using namespace std;
using namespace solidity::frontend;
using namespace solidity::frontend::experimental;
using namespace solidity::langutil;
TypeRegistration::TypeRegistration(Analysis& _analysis):
m_analysis(_analysis),
m_errorReporter(_analysis.errorReporter()),
m_typeSystem(_analysis.typeSystem())
{
for (auto [type, name, arity]: std::initializer_list<std::tuple<BuiltinType, const char*, uint64_t>> {
{BuiltinType::Void, "void", 0},
{BuiltinType::Function, "fun", 2},
{BuiltinType::Unit, "unit", 0},
{BuiltinType::Pair, "pair", 2},
{BuiltinType::Word, "word", 0},
{BuiltinType::Integer, "integer", 0}
})
m_typeSystem.declareBuiltinType(type, name, arity);
}
bool TypeRegistration::analyze(SourceUnit const& _sourceUnit)
{
_sourceUnit.accept(*this);
return !m_errorReporter.hasErrors();
}
bool TypeRegistration::visit(TypeClassDefinition const& _typeClassDefinition)
{
if (!m_visitedClasses.insert(_typeClassDefinition.id()).second)
return false;
return false;
}
bool TypeRegistration::visit(TypeClassInstantiation const& _typeClassInstantiation)
{
auto const* classDefintion = dynamic_cast<TypeClassDefinition const*>(_typeClassInstantiation.sort().annotation().referencedDeclaration);
if (!classDefintion)
m_errorReporter.fatalTypeError(0000_error, _typeClassInstantiation.sort().location(), "Expected a type class.");
classDefintion->accept(*this);
// TypeClass typeClass{classDefintion};
auto fromTypeName = [&](TypeName const& _typeName) -> Type {
if (auto const* elementaryTypeName = dynamic_cast<ElementaryTypeName const*>(&_typeName))
{
switch(elementaryTypeName->typeName().token())
{
case Token::Word:
return m_typeSystem.builtinType(BuiltinType::Word, {});
case Token::Void:
return m_typeSystem.builtinType(BuiltinType::Void, {});
case Token::Integer:
return m_typeSystem.builtinType(BuiltinType::Integer, {});
default:
m_errorReporter.typeError(0000_error, _typeName.location(), "Only elementary types are supported.");
break;
}
}
else
m_errorReporter.typeError(0000_error, _typeName.location(), "Unsupported type name.");
return m_typeSystem.freshTypeVariable(false);
};
auto type = fromTypeName(_typeClassInstantiation.typeConstructor());
_typeClassInstantiation.argumentSorts();
// m_typeSystem.instantiateClass();
return false;
}
TypeRegistration::Annotation& TypeRegistration::annotation(ASTNode const& _node)
{
return m_analysis.annotation<TypeRegistration>(_node);
}

View File

@ -0,0 +1,51 @@
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
#pragma once
#include <libsolidity/ast/ASTVisitor.h>
#include <libsolidity/ast/experimental/TypeSystem.h>
#include <liblangutil/ErrorReporter.h>
namespace solidity::frontend::experimental
{
class Analysis;
class TypeRegistration: public ASTConstVisitor
{
public:
struct Annotation
{
Type type;
};
TypeRegistration(Analysis& _analysis);
bool analyze(SourceUnit const& _sourceUnit);
private:
bool visit(TypeClassDefinition const& _typeClassDefinition) override;
bool visit(TypeClassInstantiation const& _typeClassInstantiation) override;
Annotation& annotation(ASTNode const& _node);
Analysis& m_analysis;
langutil::ErrorReporter& m_errorReporter;
TypeSystem& m_typeSystem;
std::set<int64_t> m_visitedClasses;
};
}

View File

@ -70,7 +70,7 @@ std::string TypeSystem::typeToString(Type const& _type) const
{ {
auto tupleTypes = TypeSystemHelpers{*this}.destTupleType(_type); auto tupleTypes = TypeSystemHelpers{*this}.destTupleType(_type);
stream << "("; stream << "(";
for (auto type: tupleTypes | ranges::view::drop_last(1)) for (auto type: tupleTypes | ranges::views::drop_last(1))
stream << typeToString(type) << ", "; stream << typeToString(type) << ", ";
stream << typeToString(tupleTypes.back()) << ")"; stream << typeToString(tupleTypes.back()) << ")";
break; break;
@ -136,16 +136,16 @@ experimental::Type TypeSystem::freshTypeVariable(bool _generic)
void TypeSystem::instantiate(TypeVariable _variable, Type _type) void TypeSystem::instantiate(TypeVariable _variable, Type _type)
{ {
validate(_variable); validate(_variable);
solAssert(!m_typeVariables.at(_variable.index()).has_value()); solAssert(!m_typeVariables.at(static_cast<size_t>(_variable.index())).has_value());
solAssert(_variable.m_parent == this); solAssert(_variable.m_parent == this);
m_typeVariables[_variable.index()] = _type; m_typeVariables[static_cast<size_t>(_variable.index())] = _type;
} }
experimental::Type TypeSystem::resolve(Type _type) const experimental::Type TypeSystem::resolve(Type _type) const
{ {
Type result = _type; Type result = _type;
while(auto const* var = std::get_if<TypeVariable>(&result)) while(auto const* var = std::get_if<TypeVariable>(&result))
if (auto value = m_typeVariables.at(var->index())) if (auto value = m_typeVariables.at(static_cast<size_t>(var->index())))
result = *value; result = *value;
else else
break; break;
@ -182,7 +182,7 @@ experimental::Type TypeSystem::fresh(Type _type, bool _generalize)
[&](TypeExpression const& _type) -> Type { [&](TypeExpression const& _type) -> Type {
return TypeExpression{ return TypeExpression{
_type.constructor, _type.constructor,
_type.arguments | ranges::view::transform([&](Type _argType) { _type.arguments | ranges::views::transform([&](Type _argType) {
return _recurse(_argType, _generalize, _recurse); return _recurse(_argType, _generalize, _recurse);
}) | ranges::to<vector<Type>> }) | ranges::to<vector<Type>>
}; };
@ -203,6 +203,13 @@ experimental::Type TypeSystem::fresh(Type _type, bool _generalize)
return freshImpl(_type, _generalize, freshImpl); return freshImpl(_type, _generalize, freshImpl);
} }
void TypeSystem::instantiateClass(TypeExpression::Constructor _typeConstructor, vector<TypeClass> _argumentSorts, TypeClass _class)
{
(void)_typeConstructor;
(void)_argumentSorts;
(void)_class;
}
experimental::Type TypeSystemHelpers::tupleType(vector<Type> _elements) const experimental::Type TypeSystemHelpers::tupleType(vector<Type> _elements) const
{ {
if (_elements.empty()) if (_elements.empty())
@ -210,7 +217,7 @@ experimental::Type TypeSystemHelpers::tupleType(vector<Type> _elements) const
if (_elements.size() == 1) if (_elements.size() == 1)
return _elements.front(); return _elements.front();
Type result = _elements.back(); Type result = _elements.back();
for (Type type: _elements | ranges::view::reverse | ranges::view::drop_exactly(1)) for (Type type: _elements | ranges::views::reverse | ranges::views::drop_exactly(1))
result = typeSystem.builtinType(BuiltinType::Pair, {type, result}); result = typeSystem.builtinType(BuiltinType::Pair, {type, result});
return result; return result;
} }

View File

@ -55,7 +55,6 @@ struct TypeExpression
using Constructor = std::variant<BuiltinType, Declaration const*>; using Constructor = std::variant<BuiltinType, Declaration const*>;
Constructor constructor; Constructor constructor;
std::vector<Type> arguments; std::vector<Type> arguments;
}; };
struct TypeVariable struct TypeVariable
@ -71,6 +70,21 @@ private:
TypeVariable(TypeSystem const& _parent, uint64_t _index, bool _generic): m_parent(&_parent), m_index(_index), m_generic(_generic) {} TypeVariable(TypeSystem const& _parent, uint64_t _index, bool _generic): m_parent(&_parent), m_index(_index), m_generic(_generic) {}
}; };
struct TypeClass
{
Declaration const* declaration = nullptr;
};
struct Sort
{
};
struct Arity
{
std::vector<Arity> _argumentSorts;
TypeClass _class;
};
class TypeSystem class TypeSystem
{ {
public: public:
@ -90,6 +104,7 @@ public:
Type fresh(Type _type, bool _generalize); Type fresh(Type _type, bool _generalize);
struct UnificationFailure { Type a; Type b; }; struct UnificationFailure { Type a; Type b; };
[[nodiscard]] std::vector<UnificationFailure> unify(Type _a, Type _b); [[nodiscard]] std::vector<UnificationFailure> unify(Type _a, Type _b);
void instantiateClass(TypeExpression::Constructor _typeConstructor, std::vector<TypeClass> _argumentSorts, TypeClass _class);
private: private:
void instantiate(TypeVariable _variable, Type _type); void instantiate(TypeVariable _variable, Type _type);
void validate(TypeVariable _variable) const; void validate(TypeVariable _variable) const;
@ -101,6 +116,7 @@ private:
}; };
std::map<BuiltinType, TypeConstructorInfo> m_builtinTypes; std::map<BuiltinType, TypeConstructorInfo> m_builtinTypes;
std::vector<std::optional<Type>> m_typeVariables; std::vector<std::optional<Type>> m_typeVariables;
std::map<TypeExpression::Constructor, Sort> m_sorts;
}; };
struct TypeSystemHelpers struct TypeSystemHelpers

View File

@ -100,7 +100,7 @@ string IRGenerator::generate(FunctionDefinition const& _function)
std::stringstream code; std::stringstream code;
code << "function " << IRNames::function(_function) << "("; code << "function " << IRNames::function(_function) << "(";
if (_function.parameters().size() > 1) if (_function.parameters().size() > 1)
for (auto const& arg: _function.parameters() | ranges::view::drop_last(1)) for (auto const& arg: _function.parameters() | ranges::views::drop_last(1))
code << IRNames::localVariable(*arg) << ", "; code << IRNames::localVariable(*arg) << ", ";
if (!_function.parameters().empty()) if (!_function.parameters().empty())
code << IRNames::localVariable(*_function.parameters().back()); code << IRNames::localVariable(*_function.parameters().back());
@ -109,7 +109,7 @@ string IRGenerator::generate(FunctionDefinition const& _function)
{ {
code << " -> "; code << " -> ";
if (_function.returnParameters().size() > 1) if (_function.returnParameters().size() > 1)
for (auto const& arg: _function.returnParameters() | ranges::view::drop_last(1)) for (auto const& arg: _function.returnParameters() | ranges::views::drop_last(1))
code << IRNames::localVariable(*arg) << ", "; code << IRNames::localVariable(*arg) << ", ";
if (!_function.returnParameters().empty()) if (!_function.returnParameters().empty())
code << IRNames::localVariable(*_function.returnParameters().back()); code << IRNames::localVariable(*_function.returnParameters().back());

View File

@ -46,14 +46,14 @@ public:
std::optional<uint8_t> _eofVersion, std::optional<uint8_t> _eofVersion,
RevertStrings /*_revertStrings*/, RevertStrings /*_revertStrings*/,
std::map<std::string, unsigned> /*_sourceIndices*/, std::map<std::string, unsigned> /*_sourceIndices*/,
langutil::DebugInfoSelection const& _debugInfoSelection, langutil::DebugInfoSelection const& /*_debugInfoSelection*/,
langutil::CharStreamProvider const* _soliditySourceProvider, langutil::CharStreamProvider const* /*_soliditySourceProvider*/,
Analysis const& _analysis Analysis const& _analysis
): ):
m_evmVersion(_evmVersion), m_evmVersion(_evmVersion),
m_eofVersion(_eofVersion), m_eofVersion(_eofVersion),
m_debugInfoSelection(_debugInfoSelection), // m_debugInfoSelection(_debugInfoSelection),
m_soliditySourceProvider(_soliditySourceProvider), // m_soliditySourceProvider(_soliditySourceProvider),
m_context{_analysis, {}, {}} m_context{_analysis, {}, {}}
{} {}
@ -69,8 +69,8 @@ private:
langutil::EVMVersion const m_evmVersion; langutil::EVMVersion const m_evmVersion;
std::optional<uint8_t> const m_eofVersion; std::optional<uint8_t> const m_eofVersion;
OptimiserSettings const m_optimiserSettings; OptimiserSettings const m_optimiserSettings;
langutil::DebugInfoSelection m_debugInfoSelection = {}; // langutil::DebugInfoSelection m_debugInfoSelection = {};
langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr; // langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr;
IRGenerationContext m_context; IRGenerationContext m_context;
}; };

View File

@ -145,7 +145,6 @@ void IRGeneratorForStatements::endVisit(Return const& _return)
m_code << IRNames::localVariable(*returnParameters.front()) << " := " << IRNames::localVariable(*value) << "\n"; m_code << IRNames::localVariable(*returnParameters.front()) << " := " << IRNames::localVariable(*value) << "\n";
} }
_return.annotation().functionReturnParameters;
m_code << "leave\n"; m_code << "leave\n";
} }
@ -163,7 +162,7 @@ bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall)
m_code << "let " << IRNames::localVariable(_functionCall) << " := " << IRNames::function(*functionDefinition) << "("; m_code << "let " << IRNames::localVariable(_functionCall) << " := " << IRNames::function(*functionDefinition) << "(";
auto const& arguments = _functionCall.arguments(); auto const& arguments = _functionCall.arguments();
if (arguments.size() > 1) if (arguments.size() > 1)
for (auto arg: arguments | ranges::view::drop_last(1)) for (auto arg: arguments | ranges::views::drop_last(1))
m_code << IRNames::localVariable(*arg) << ", "; m_code << IRNames::localVariable(*arg) << ", ";
if (!arguments.empty()) if (!arguments.empty())
m_code << IRNames::localVariable(*arguments.back()); m_code << IRNames::localVariable(*arguments.back());