aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/analysis/ConstantEvaluator.cpp8
-rw-r--r--libsolidity/analysis/ConstantEvaluator.h8
-rw-r--r--libsolidity/analysis/DeclarationContainer.cpp8
-rw-r--r--libsolidity/analysis/DeclarationContainer.h8
-rw-r--r--libsolidity/analysis/DocStringAnalyser.cpp8
-rw-r--r--libsolidity/analysis/DocStringAnalyser.h8
-rw-r--r--libsolidity/analysis/GlobalContext.cpp8
-rw-r--r--libsolidity/analysis/GlobalContext.h8
-rw-r--r--libsolidity/analysis/NameAndTypeResolver.cpp8
-rw-r--r--libsolidity/analysis/NameAndTypeResolver.h8
-rw-r--r--libsolidity/analysis/ReferencesResolver.cpp33
-rw-r--r--libsolidity/analysis/ReferencesResolver.h9
-rw-r--r--libsolidity/analysis/SemVerHandler.cpp8
-rw-r--r--libsolidity/analysis/SemVerHandler.h8
-rw-r--r--libsolidity/analysis/StaticAnalyzer.cpp78
-rw-r--r--libsolidity/analysis/StaticAnalyzer.h72
-rw-r--r--libsolidity/analysis/SyntaxChecker.cpp8
-rw-r--r--libsolidity/analysis/SyntaxChecker.h8
-rw-r--r--libsolidity/analysis/TypeChecker.cpp20
-rw-r--r--libsolidity/analysis/TypeChecker.h9
-rw-r--r--libsolidity/ast/AST.cpp25
-rw-r--r--libsolidity/ast/AST.h68
-rw-r--r--libsolidity/ast/ASTAnnotations.cpp8
-rw-r--r--libsolidity/ast/ASTAnnotations.h8
-rw-r--r--libsolidity/ast/ASTForward.h9
-rw-r--r--libsolidity/ast/ASTJsonConverter.cpp40
-rw-r--r--libsolidity/ast/ASTJsonConverter.h10
-rw-r--r--libsolidity/ast/ASTPrinter.cpp22
-rw-r--r--libsolidity/ast/ASTPrinter.h10
-rw-r--r--libsolidity/ast/ASTUtils.cpp8
-rw-r--r--libsolidity/ast/ASTUtils.h8
-rw-r--r--libsolidity/ast/ASTVisitor.h12
-rw-r--r--libsolidity/ast/AST_accept.h28
-rw-r--r--libsolidity/ast/Types.cpp167
-rw-r--r--libsolidity/ast/Types.h30
-rw-r--r--libsolidity/codegen/ArrayUtils.cpp12
-rw-r--r--libsolidity/codegen/ArrayUtils.h8
-rw-r--r--libsolidity/codegen/Compiler.cpp35
-rw-r--r--libsolidity/codegen/Compiler.h19
-rw-r--r--libsolidity/codegen/CompilerContext.cpp43
-rw-r--r--libsolidity/codegen/CompilerContext.h96
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp161
-rw-r--r--libsolidity/codegen/CompilerUtils.h24
-rw-r--r--libsolidity/codegen/ContractCompiler.cpp113
-rw-r--r--libsolidity/codegen/ContractCompiler.h21
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp60
-rw-r--r--libsolidity/codegen/ExpressionCompiler.h8
-rw-r--r--libsolidity/codegen/LValue.cpp78
-rw-r--r--libsolidity/codegen/LValue.h8
-rw-r--r--libsolidity/formal/Why3Translator.cpp18
-rw-r--r--libsolidity/formal/Why3Translator.h8
-rw-r--r--libsolidity/grammar.txt106
-rw-r--r--libsolidity/inlineasm/AsmCodeGen.cpp30
-rw-r--r--libsolidity/inlineasm/AsmCodeGen.h8
-rw-r--r--libsolidity/inlineasm/AsmData.h8
-rw-r--r--libsolidity/inlineasm/AsmParser.cpp8
-rw-r--r--libsolidity/inlineasm/AsmParser.h8
-rw-r--r--libsolidity/inlineasm/AsmStack.cpp8
-rw-r--r--libsolidity/inlineasm/AsmStack.h8
-rw-r--r--libsolidity/interface/CompilerStack.cpp152
-rw-r--r--libsolidity/interface/CompilerStack.h44
-rw-r--r--libsolidity/interface/Exceptions.cpp8
-rw-r--r--libsolidity/interface/Exceptions.h9
-rw-r--r--libsolidity/interface/GasEstimator.cpp8
-rw-r--r--libsolidity/interface/GasEstimator.h8
-rw-r--r--libsolidity/interface/InterfaceHandler.cpp21
-rw-r--r--libsolidity/interface/InterfaceHandler.h24
-rw-r--r--libsolidity/interface/SourceReferenceFormatter.cpp8
-rw-r--r--libsolidity/interface/SourceReferenceFormatter.h8
-rw-r--r--libsolidity/interface/Utils.h14
-rw-r--r--libsolidity/interface/Version.cpp8
-rw-r--r--libsolidity/interface/Version.h8
-rw-r--r--libsolidity/parsing/DocStringParser.h8
-rw-r--r--libsolidity/parsing/Parser.cpp202
-rw-r--r--libsolidity/parsing/Parser.h25
-rw-r--r--libsolidity/parsing/ParserBase.cpp8
-rw-r--r--libsolidity/parsing/ParserBase.h8
-rw-r--r--libsolidity/parsing/Scanner.cpp15
-rw-r--r--libsolidity/parsing/Scanner.h12
-rw-r--r--libsolidity/parsing/Token.cpp8
-rw-r--r--libsolidity/parsing/Token.h12
81 files changed, 1551 insertions, 749 deletions
diff --git a/libsolidity/analysis/ConstantEvaluator.cpp b/libsolidity/analysis/ConstantEvaluator.cpp
index bdd8f61e..7057eab7 100644
--- a/libsolidity/analysis/ConstantEvaluator.cpp
+++ b/libsolidity/analysis/ConstantEvaluator.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/analysis/ConstantEvaluator.h b/libsolidity/analysis/ConstantEvaluator.h
index f311efbf..9ec04ebe 100644
--- a/libsolidity/analysis/ConstantEvaluator.h
+++ b/libsolidity/analysis/ConstantEvaluator.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/analysis/DeclarationContainer.cpp b/libsolidity/analysis/DeclarationContainer.cpp
index 042b7a6a..1599b83a 100644
--- a/libsolidity/analysis/DeclarationContainer.cpp
+++ b/libsolidity/analysis/DeclarationContainer.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/analysis/DeclarationContainer.h b/libsolidity/analysis/DeclarationContainer.h
index 5862f7a5..9c7c89e7 100644
--- a/libsolidity/analysis/DeclarationContainer.h
+++ b/libsolidity/analysis/DeclarationContainer.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/analysis/DocStringAnalyser.cpp b/libsolidity/analysis/DocStringAnalyser.cpp
index 4f75f03d..58261144 100644
--- a/libsolidity/analysis/DocStringAnalyser.cpp
+++ b/libsolidity/analysis/DocStringAnalyser.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/analysis/DocStringAnalyser.h b/libsolidity/analysis/DocStringAnalyser.h
index cdf297e3..bfc8befc 100644
--- a/libsolidity/analysis/DocStringAnalyser.h
+++ b/libsolidity/analysis/DocStringAnalyser.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/analysis/GlobalContext.cpp b/libsolidity/analysis/GlobalContext.cpp
index d075949e..e46868be 100644
--- a/libsolidity/analysis/GlobalContext.cpp
+++ b/libsolidity/analysis/GlobalContext.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/analysis/GlobalContext.h b/libsolidity/analysis/GlobalContext.h
index 482391d3..4ed08711 100644
--- a/libsolidity/analysis/GlobalContext.h
+++ b/libsolidity/analysis/GlobalContext.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp
index 26d38cfe..2a33a501 100644
--- a/libsolidity/analysis/NameAndTypeResolver.cpp
+++ b/libsolidity/analysis/NameAndTypeResolver.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/analysis/NameAndTypeResolver.h b/libsolidity/analysis/NameAndTypeResolver.h
index 89b9818b..68c3ffa1 100644
--- a/libsolidity/analysis/NameAndTypeResolver.h
+++ b/libsolidity/analysis/NameAndTypeResolver.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp
index a7b9e8b8..66bf1d0e 100644
--- a/libsolidity/analysis/ReferencesResolver.cpp
+++ b/libsolidity/analysis/ReferencesResolver.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -83,6 +83,31 @@ void ReferencesResolver::endVisit(UserDefinedTypeName const& _typeName)
fatalTypeError(_typeName.location(), "Name has to refer to a struct, enum or contract.");
}
+void ReferencesResolver::endVisit(FunctionTypeName const& _typeName)
+{
+ switch (_typeName.visibility())
+ {
+ case VariableDeclaration::Visibility::Default:
+ case VariableDeclaration::Visibility::Internal:
+ case VariableDeclaration::Visibility::External:
+ break;
+ default:
+ typeError(_typeName.location(), "Invalid visibility, can only be \"external\" or \"internal\".");
+ }
+
+ if (_typeName.isPayable() && _typeName.visibility() != VariableDeclaration::Visibility::External)
+ fatalTypeError(_typeName.location(), "Only external function types can be payable.");
+ if (_typeName.visibility() == VariableDeclaration::Visibility::External)
+ for (auto const& t: _typeName.parameterTypes() + _typeName.returnParameterTypes())
+ {
+ solAssert(t->annotation().type, "Type not set for parameter.");
+ if (!t->annotation().type->canBeUsedExternally(false))
+ fatalTypeError(t->location(), "Internal type cannot be used for external function type.");
+ }
+
+ _typeName.annotation().type = make_shared<FunctionType>(_typeName);
+}
+
void ReferencesResolver::endVisit(Mapping const& _typeName)
{
TypePointer keyType = _typeName.keyType().annotation().type;
diff --git a/libsolidity/analysis/ReferencesResolver.h b/libsolidity/analysis/ReferencesResolver.h
index 1986b2bb..caa3a78f 100644
--- a/libsolidity/analysis/ReferencesResolver.h
+++ b/libsolidity/analysis/ReferencesResolver.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -62,6 +62,7 @@ private:
virtual bool visit(Identifier const& _identifier) override;
virtual bool visit(ElementaryTypeName const& _typeName) override;
virtual void endVisit(UserDefinedTypeName const& _typeName) override;
+ virtual void endVisit(FunctionTypeName const& _typeName) override;
virtual void endVisit(Mapping const& _typeName) override;
virtual void endVisit(ArrayTypeName const& _typeName) override;
virtual bool visit(InlineAssembly const& _inlineAssembly) override;
diff --git a/libsolidity/analysis/SemVerHandler.cpp b/libsolidity/analysis/SemVerHandler.cpp
index c7b212b2..42186396 100644
--- a/libsolidity/analysis/SemVerHandler.cpp
+++ b/libsolidity/analysis/SemVerHandler.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <chris@ethereum.org>
diff --git a/libsolidity/analysis/SemVerHandler.h b/libsolidity/analysis/SemVerHandler.h
index e3b642db..fae0a764 100644
--- a/libsolidity/analysis/SemVerHandler.h
+++ b/libsolidity/analysis/SemVerHandler.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <chris@ethereum.org>
diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp
new file mode 100644
index 00000000..c39f874e
--- /dev/null
+++ b/libsolidity/analysis/StaticAnalyzer.cpp
@@ -0,0 +1,78 @@
+/*
+ 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/>.
+*/
+/**
+ * @author Federico Bond <federicobond@gmail.com>
+ * @date 2016
+ * Static analyzer and checker.
+ */
+
+#include <libsolidity/analysis/StaticAnalyzer.h>
+#include <memory>
+#include <libsolidity/ast/AST.h>
+
+using namespace std;
+using namespace dev;
+using namespace dev::solidity;
+
+
+bool StaticAnalyzer::analyze(SourceUnit const& _sourceUnit)
+{
+ _sourceUnit.accept(*this);
+ return Error::containsOnlyWarnings(m_errors);
+}
+
+bool StaticAnalyzer::visit(ContractDefinition const& _contract)
+{
+ m_library = _contract.isLibrary();
+ return true;
+}
+
+void StaticAnalyzer::endVisit(ContractDefinition const&)
+{
+ m_library = false;
+}
+
+bool StaticAnalyzer::visit(FunctionDefinition const& _function)
+{
+ m_nonPayablePublic = _function.isPublic() && !_function.isPayable();
+ return true;
+}
+
+void StaticAnalyzer::endVisit(FunctionDefinition const&)
+{
+ m_nonPayablePublic = false;
+}
+
+bool StaticAnalyzer::visit(MemberAccess const& _memberAccess)
+{
+ if (m_nonPayablePublic && !m_library)
+ if (MagicType const* type = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type.get()))
+ if (type->kind() == MagicType::Kind::Message && _memberAccess.memberName() == "value")
+ warning(_memberAccess.location(), "\"msg.value\" used in non-payable function. Do you want to add the \"payable\" modifier to this function?");
+
+ return true;
+}
+
+void StaticAnalyzer::warning(SourceLocation const& _location, string const& _description)
+{
+ auto err = make_shared<Error>(Error::Type::Warning);
+ *err <<
+ errinfo_sourceLocation(_location) <<
+ errinfo_comment(_description);
+
+ m_errors.push_back(err);
+}
diff --git a/libsolidity/analysis/StaticAnalyzer.h b/libsolidity/analysis/StaticAnalyzer.h
new file mode 100644
index 00000000..b6cf783e
--- /dev/null
+++ b/libsolidity/analysis/StaticAnalyzer.h
@@ -0,0 +1,72 @@
+/*
+ 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/>.
+*/
+/**
+ * @author Federico Bond <federicobond@gmail.com>
+ * @date 2016
+ * Static analyzer and checker.
+ */
+
+#pragma once
+
+#include <libsolidity/analysis/TypeChecker.h>
+#include <libsolidity/ast/Types.h>
+#include <libsolidity/ast/ASTAnnotations.h>
+#include <libsolidity/ast/ASTForward.h>
+#include <libsolidity/ast/ASTVisitor.h>
+
+namespace dev
+{
+namespace solidity
+{
+
+
+/**
+ * The module that performs static analysis on the AST.
+ */
+class StaticAnalyzer: private ASTConstVisitor
+{
+public:
+ /// @param _errors the reference to the list of errors and warnings to add them found during static analysis.
+ explicit StaticAnalyzer(ErrorList& _errors): m_errors(_errors) {}
+
+ /// Performs static analysis on the given source unit and all of its sub-nodes.
+ /// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings
+ bool analyze(SourceUnit const& _sourceUnit);
+
+private:
+ /// Adds a new warning to the list of errors.
+ void warning(SourceLocation const& _location, std::string const& _description);
+
+ virtual bool visit(ContractDefinition const& _contract) override;
+ virtual void endVisit(ContractDefinition const& _contract) override;
+
+ virtual bool visit(FunctionDefinition const& _function) override;
+ virtual void endVisit(FunctionDefinition const& _function) override;
+
+ virtual bool visit(MemberAccess const& _memberAccess) override;
+
+ ErrorList& m_errors;
+
+ /// Flag that indicates whether the current contract definition is a library.
+ bool m_library = false;
+
+ /// Flag that indicates whether a public function does not contain the "payable" modifier.
+ bool m_nonPayablePublic = false;
+};
+
+}
+}
diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp
index dbaa15ed..0a4943fe 100644
--- a/libsolidity/analysis/SyntaxChecker.cpp
+++ b/libsolidity/analysis/SyntaxChecker.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libsolidity/analysis/SyntaxChecker.h>
diff --git a/libsolidity/analysis/SyntaxChecker.h b/libsolidity/analysis/SyntaxChecker.h
index ac8ed872..c24bae09 100644
--- a/libsolidity/analysis/SyntaxChecker.h
+++ b/libsolidity/analysis/SyntaxChecker.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 46f4f7f6..7235b57a 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -574,6 +574,14 @@ bool TypeChecker::visit(EventDefinition const& _eventDef)
return false;
}
+void TypeChecker::endVisit(FunctionTypeName const& _funType)
+{
+ FunctionType const& fun = dynamic_cast<FunctionType const&>(*_funType.annotation().type);
+ if (fun.location() == FunctionType::Location::External)
+ if (!fun.canBeUsedExternally(false))
+ typeError(_funType.location(), "External function type uses internal types.");
+}
+
bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{
// Inline assembly does not have its own type-checking phase, so we just run the
@@ -996,9 +1004,9 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
fatalTypeError(components[i]->location(), "Invalid mobile type.");
if (i == 0)
- inlineArrayType = types[i]->mobileType();
+ inlineArrayType = types[i];
else if (inlineArrayType)
- inlineArrayType = Type::commonType(inlineArrayType, types[i]->mobileType());
+ inlineArrayType = Type::commonType(inlineArrayType, types[i]);
}
}
else
diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h
index be1e02be..143b15b2 100644
--- a/libsolidity/analysis/TypeChecker.h
+++ b/libsolidity/analysis/TypeChecker.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -87,6 +87,7 @@ private:
/// case this is a base constructor call.
void visitManually(ModifierInvocation const& _modifier, std::vector<ContractDefinition const*> const& _bases);
virtual bool visit(EventDefinition const& _eventDef) override;
+ virtual void endVisit(FunctionTypeName const& _funType) override;
virtual bool visit(InlineAssembly const& _inlineAssembly) override;
virtual bool visit(IfStatement const& _ifStatement) override;
virtual bool visit(WhileStatement const& _whileStatement) override;
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index 695d9881..3cd1dfbe 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -63,6 +63,15 @@ SourceUnitAnnotation& SourceUnit::annotation() const
return static_cast<SourceUnitAnnotation&>(*m_annotation);
}
+string Declaration::sourceUnitName() const
+{
+ solAssert(!!m_scope, "");
+ ASTNode const* scope = m_scope;
+ while (dynamic_cast<Declaration const*>(scope) && dynamic_cast<Declaration const*>(scope)->m_scope)
+ scope = dynamic_cast<Declaration const*>(scope)->m_scope;
+ return dynamic_cast<SourceUnit const&>(*scope).annotation().path;
+}
+
ImportAnnotation& ImportDirective::annotation() const
{
if (!m_annotation)
@@ -160,22 +169,22 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::inter
return *m_interfaceFunctionList;
}
-string const& ContractDefinition::devDocumentation() const
+Json::Value const& ContractDefinition::devDocumentation() const
{
return m_devDocumentation;
}
-string const& ContractDefinition::userDocumentation() const
+Json::Value const& ContractDefinition::userDocumentation() const
{
return m_userDocumentation;
}
-void ContractDefinition::setDevDocumentation(string const& _devDocumentation)
+void ContractDefinition::setDevDocumentation(Json::Value const& _devDocumentation)
{
m_devDocumentation = _devDocumentation;
}
-void ContractDefinition::setUserDocumentation(string const& _userDocumentation)
+void ContractDefinition::setUserDocumentation(Json::Value const& _userDocumentation)
{
m_userDocumentation = _userDocumentation;
}
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index 7ed4ddce..ab4be1ea 100644
--- a/libsolidity/ast/AST.h
+++ b/libsolidity/ast/AST.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -35,6 +35,7 @@
#include <libsolidity/ast/Types.h>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/ast/ASTAnnotations.h>
+#include <json/json.h>
namespace dev
{
@@ -157,6 +158,10 @@ public:
ASTNode const* scope() const { return m_scope; }
void setScope(ASTNode const* _scope) { m_scope = _scope; }
+ /// @returns the source name this declaration is present in.
+ /// Can be combined with annotation().canonicalName to form a globally unique name.
+ std::string sourceUnitName() const;
+
virtual bool isLValue() const { return false; }
virtual bool isPartOfExternalInterface() const { return false; }
@@ -343,11 +348,11 @@ public:
/// Returns the fallback function or nullptr if no fallback function was specified.
FunctionDefinition const* fallbackFunction() const;
- std::string const& userDocumentation() const;
- void setUserDocumentation(std::string const& _userDocumentation);
+ Json::Value const& userDocumentation() const;
+ void setUserDocumentation(Json::Value const& _userDocumentation);
- std::string const& devDocumentation() const;
- void setDevDocumentation(std::string const& _devDocumentation);
+ Json::Value const& devDocumentation() const;
+ void setDevDocumentation(Json::Value const& _devDocumentation);
virtual TypePointer type() const override;
@@ -359,8 +364,8 @@ private:
bool m_isLibrary;
// parsed Natspec documentation of the contract.
- std::string m_userDocumentation;
- std::string m_devDocumentation;
+ Json::Value m_userDocumentation;
+ Json::Value m_devDocumentation;
std::vector<ContractDefinition const*> m_linearizedBaseContracts;
mutable std::unique_ptr<std::vector<std::pair<FixedHash<4>, FunctionTypePointer>>> m_interfaceFunctionList;
@@ -822,6 +827,41 @@ private:
};
/**
+ * A literal function type. Its source form is "function (paramType1, paramType2) internal / external returns (retType1, retType2)"
+ */
+class FunctionTypeName: public TypeName
+{
+public:
+ FunctionTypeName(
+ SourceLocation const& _location,
+ ASTPointer<ParameterList> const& _parameterTypes,
+ ASTPointer<ParameterList> const& _returnTypes,
+ Declaration::Visibility _visibility,
+ bool _isDeclaredConst,
+ bool _isPayable
+ ):
+ TypeName(_location), m_parameterTypes(_parameterTypes), m_returnTypes(_returnTypes),
+ m_visibility(_visibility), m_isDeclaredConst(_isDeclaredConst), m_isPayable(_isPayable)
+ {}
+ virtual void accept(ASTVisitor& _visitor) override;
+ virtual void accept(ASTConstVisitor& _visitor) const override;
+
+ std::vector<ASTPointer<VariableDeclaration>> const& parameterTypes() const { return m_parameterTypes->parameters(); }
+ std::vector<ASTPointer<VariableDeclaration>> const& returnParameterTypes() const { return m_returnTypes->parameters(); }
+
+ Declaration::Visibility visibility() const { return m_visibility; }
+ bool isDeclaredConst() const { return m_isDeclaredConst; }
+ bool isPayable() const { return m_isPayable; }
+
+private:
+ ASTPointer<ParameterList> m_parameterTypes;
+ ASTPointer<ParameterList> m_returnTypes;
+ Declaration::Visibility m_visibility;
+ bool m_isDeclaredConst;
+ bool m_isPayable;
+};
+
+/**
* A mapping type. Its source form is "mapping('keyType' => 'valueType')"
*/
class Mapping: public TypeName
@@ -1005,18 +1045,22 @@ public:
SourceLocation const& _location,
ASTPointer<ASTString> const& _docString,
ASTPointer<Expression> const& _condition,
- ASTPointer<Statement> const& _body
+ ASTPointer<Statement> const& _body,
+ bool _isDoWhile
):
- BreakableStatement(_location, _docString), m_condition(_condition), m_body(_body) {}
+ BreakableStatement(_location, _docString), m_condition(_condition), m_body(_body),
+ m_isDoWhile(_isDoWhile) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
Expression const& condition() const { return *m_condition; }
Statement const& body() const { return *m_body; }
+ bool isDoWhile() const { return m_isDoWhile; }
private:
ASTPointer<Expression> m_condition;
ASTPointer<Statement> m_body;
+ bool m_isDoWhile;
};
/**
diff --git a/libsolidity/ast/ASTAnnotations.cpp b/libsolidity/ast/ASTAnnotations.cpp
index 416e6b44..0f958a38 100644
--- a/libsolidity/ast/ASTAnnotations.cpp
+++ b/libsolidity/ast/ASTAnnotations.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h
index 2a192e47..768e56db 100644
--- a/libsolidity/ast/ASTAnnotations.h
+++ b/libsolidity/ast/ASTAnnotations.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/ast/ASTForward.h b/libsolidity/ast/ASTForward.h
index 59fc1b57..cfeeaa58 100644
--- a/libsolidity/ast/ASTForward.h
+++ b/libsolidity/ast/ASTForward.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -54,6 +54,7 @@ class MagicVariableDeclaration;
class TypeName;
class ElementaryTypeName;
class UserDefinedTypeName;
+class FunctionTypeName;
class Mapping;
class ArrayTypeName;
class Statement;
diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp
index b573feda..493707b9 100644
--- a/libsolidity/ast/ASTJsonConverter.cpp
+++ b/libsolidity/ast/ASTJsonConverter.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Lefteris <lefteris@ethdev.com>
@@ -226,6 +226,20 @@ bool ASTJsonConverter::visit(UserDefinedTypeName const& _node)
return true;
}
+bool ASTJsonConverter::visit(FunctionTypeName const& _node)
+{
+ string visibility = "internal";
+ if (_node.visibility() == Declaration::Visibility::External)
+ visibility = "external";
+
+ addJsonNode(_node, "FunctionTypeName", {
+ make_pair("payable", _node.isPayable()),
+ make_pair("visibility", visibility),
+ make_pair("constant", _node.isDeclaredConst())
+ }, true);
+ return true;
+}
+
bool ASTJsonConverter::visit(Mapping const& _node)
{
addJsonNode(_node, "Mapping", {}, true);
@@ -264,7 +278,11 @@ bool ASTJsonConverter::visit(IfStatement const& _node)
bool ASTJsonConverter::visit(WhileStatement const& _node)
{
- addJsonNode(_node, "WhileStatement", {}, true);
+ addJsonNode(
+ _node,
+ _node.isDoWhile() ? "DoWhileStatement" : "WhileStatement",
+ {},
+ true);
return true;
}
@@ -300,7 +318,7 @@ bool ASTJsonConverter::visit(Throw const& _node)
bool ASTJsonConverter::visit(VariableDeclarationStatement const& _node)
{
- addJsonNode(_node, "VariableDefinitionStatement", {}, true);
+ addJsonNode(_node, "VariableDeclarationStatement", {}, true);
return true;
}
@@ -389,7 +407,7 @@ bool ASTJsonConverter::visit(Identifier const& _node)
bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node)
{
- addJsonNode(_node, "ElementaryTypenameExpression", {
+ addJsonNode(_node, "ElementaryTypeNameExpression", {
make_pair("value", _node.typeName().toString()),
make_pair("type", type(_node))
});
@@ -399,9 +417,8 @@ bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node)
bool ASTJsonConverter::visit(Literal const& _node)
{
char const* tokenString = Token::toString(_node.token());
- size_t invalidPos = 0;
Json::Value value{_node.value()};
- if (!dev::validate(_node.value(), invalidPos))
+ if (!dev::validateUTF8(_node.value()))
value = Json::nullValue;
Token::Value subdenomination = Token::Value(_node.subDenomination());
addJsonNode(_node, "Literal", {
@@ -503,6 +520,11 @@ void ASTJsonConverter::endVisit(UserDefinedTypeName const&)
{
}
+void ASTJsonConverter::endVisit(FunctionTypeName const&)
+{
+ goUp();
+}
+
void ASTJsonConverter::endVisit(Mapping const&)
{
goUp();
diff --git a/libsolidity/ast/ASTJsonConverter.h b/libsolidity/ast/ASTJsonConverter.h
index 7c7b37f8..277476d5 100644
--- a/libsolidity/ast/ASTJsonConverter.h
+++ b/libsolidity/ast/ASTJsonConverter.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Lefteris <lefteris@ethdev.com>
@@ -69,6 +69,7 @@ public:
bool visit(TypeName const& _node) override;
bool visit(ElementaryTypeName const& _node) override;
bool visit(UserDefinedTypeName const& _node) override;
+ bool visit(FunctionTypeName const& _node) override;
bool visit(Mapping const& _node) override;
bool visit(ArrayTypeName const& _node) override;
bool visit(InlineAssembly const& _node) override;
@@ -114,6 +115,7 @@ public:
void endVisit(TypeName const&) override;
void endVisit(ElementaryTypeName const&) override;
void endVisit(UserDefinedTypeName const&) override;
+ void endVisit(FunctionTypeName const&) override;
void endVisit(Mapping const&) override;
void endVisit(ArrayTypeName const&) override;
void endVisit(InlineAssembly const&) override;
diff --git a/libsolidity/ast/ASTPrinter.cpp b/libsolidity/ast/ASTPrinter.cpp
index a9de457a..23eb3b64 100644
--- a/libsolidity/ast/ASTPrinter.cpp
+++ b/libsolidity/ast/ASTPrinter.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -164,6 +164,13 @@ bool ASTPrinter::visit(UserDefinedTypeName const& _node)
return goDeeper();
}
+bool ASTPrinter::visit(FunctionTypeName const& _node)
+{
+ writeLine("FunctionTypeName");
+ printSourcePart(_node);
+ return goDeeper();
+}
+
bool ASTPrinter::visit(Mapping const& _node)
{
writeLine("Mapping");
@@ -208,7 +215,7 @@ bool ASTPrinter::visit(IfStatement const& _node)
bool ASTPrinter::visit(WhileStatement const& _node)
{
- writeLine("WhileStatement");
+ writeLine(_node.isDoWhile() ? "DoWhileStatement" : "WhileStatement");
printSourcePart(_node);
return goDeeper();
}
@@ -442,6 +449,11 @@ void ASTPrinter::endVisit(UserDefinedTypeName const&)
m_indentation--;
}
+void ASTPrinter::endVisit(FunctionTypeName const&)
+{
+ m_indentation--;
+}
+
void ASTPrinter::endVisit(Mapping const&)
{
m_indentation--;
diff --git a/libsolidity/ast/ASTPrinter.h b/libsolidity/ast/ASTPrinter.h
index f0ab1098..4a37f17f 100644
--- a/libsolidity/ast/ASTPrinter.h
+++ b/libsolidity/ast/ASTPrinter.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -63,6 +63,7 @@ public:
bool visit(TypeName const& _node) override;
bool visit(ElementaryTypeName const& _node) override;
bool visit(UserDefinedTypeName const& _node) override;
+ bool visit(FunctionTypeName const& _node) override;
bool visit(Mapping const& _node) override;
bool visit(ArrayTypeName const& _node) override;
bool visit(InlineAssembly const& _node) override;
@@ -106,6 +107,7 @@ public:
void endVisit(TypeName const&) override;
void endVisit(ElementaryTypeName const&) override;
void endVisit(UserDefinedTypeName const&) override;
+ void endVisit(FunctionTypeName const&) override;
void endVisit(Mapping const&) override;
void endVisit(ArrayTypeName const&) override;
void endVisit(InlineAssembly const&) override;
diff --git a/libsolidity/ast/ASTUtils.cpp b/libsolidity/ast/ASTUtils.cpp
index e9b70b62..7d180490 100644
--- a/libsolidity/ast/ASTUtils.cpp
+++ b/libsolidity/ast/ASTUtils.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/ast/ASTUtils.h b/libsolidity/ast/ASTUtils.h
index 237537ec..f7cacf3e 100644
--- a/libsolidity/ast/ASTUtils.h
+++ b/libsolidity/ast/ASTUtils.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h
index 3a1b55d3..20be634b 100644
--- a/libsolidity/ast/ASTVisitor.h
+++ b/libsolidity/ast/ASTVisitor.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -61,6 +61,7 @@ public:
virtual bool visit(TypeName& _node) { return visitNode(_node); }
virtual bool visit(ElementaryTypeName& _node) { return visitNode(_node); }
virtual bool visit(UserDefinedTypeName& _node) { return visitNode(_node); }
+ virtual bool visit(FunctionTypeName& _node) { return visitNode(_node); }
virtual bool visit(Mapping& _node) { return visitNode(_node); }
virtual bool visit(ArrayTypeName& _node) { return visitNode(_node); }
virtual bool visit(InlineAssembly& _node) { return visitNode(_node); }
@@ -106,6 +107,7 @@ public:
virtual void endVisit(TypeName& _node) { endVisitNode(_node); }
virtual void endVisit(ElementaryTypeName& _node) { endVisitNode(_node); }
virtual void endVisit(UserDefinedTypeName& _node) { endVisitNode(_node); }
+ virtual void endVisit(FunctionTypeName& _node) { endVisitNode(_node); }
virtual void endVisit(Mapping& _node) { endVisitNode(_node); }
virtual void endVisit(ArrayTypeName& _node) { endVisitNode(_node); }
virtual void endVisit(InlineAssembly& _node) { endVisitNode(_node); }
@@ -163,6 +165,7 @@ public:
virtual bool visit(TypeName const& _node) { return visitNode(_node); }
virtual bool visit(ElementaryTypeName const& _node) { return visitNode(_node); }
virtual bool visit(UserDefinedTypeName const& _node) { return visitNode(_node); }
+ virtual bool visit(FunctionTypeName const& _node) { return visitNode(_node); }
virtual bool visit(Mapping const& _node) { return visitNode(_node); }
virtual bool visit(ArrayTypeName const& _node) { return visitNode(_node); }
virtual bool visit(Block const& _node) { return visitNode(_node); }
@@ -208,6 +211,7 @@ public:
virtual void endVisit(TypeName const& _node) { endVisitNode(_node); }
virtual void endVisit(ElementaryTypeName const& _node) { endVisitNode(_node); }
virtual void endVisit(UserDefinedTypeName const& _node) { endVisitNode(_node); }
+ virtual void endVisit(FunctionTypeName const& _node) { endVisitNode(_node); }
virtual void endVisit(Mapping const& _node) { endVisitNode(_node); }
virtual void endVisit(ArrayTypeName const& _node) { endVisitNode(_node); }
virtual void endVisit(Block const& _node) { endVisitNode(_node); }
diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h
index b5a3806b..7c1c64b0 100644
--- a/libsolidity/ast/AST_accept.h
+++ b/libsolidity/ast/AST_accept.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -327,6 +327,26 @@ void UserDefinedTypeName::accept(ASTConstVisitor& _visitor) const
_visitor.endVisit(*this);
}
+void FunctionTypeName::accept(ASTVisitor& _visitor)
+{
+ if (_visitor.visit(*this))
+ {
+ m_parameterTypes->accept(_visitor);
+ m_returnTypes->accept(_visitor);
+ }
+ _visitor.endVisit(*this);
+}
+
+void FunctionTypeName::accept(ASTConstVisitor& _visitor) const
+{
+ if (_visitor.visit(*this))
+ {
+ m_parameterTypes->accept(_visitor);
+ m_returnTypes->accept(_visitor);
+ }
+ _visitor.endVisit(*this);
+}
+
void Mapping::accept(ASTVisitor& _visitor)
{
if (_visitor.visit(*this))
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 7fe97fa7..d9660bc0 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -200,10 +200,10 @@ TypePointer Type::commonType(TypePointer const& _a, TypePointer const& _b)
{
if (!_a || !_b)
return TypePointer();
- else if (_b->isImplicitlyConvertibleTo(*_a))
- return _a;
- else if (_a->isImplicitlyConvertibleTo(*_b))
- return _b;
+ else if (_b->isImplicitlyConvertibleTo(*_a->mobileType()))
+ return _a->mobileType();
+ else if (_a->isImplicitlyConvertibleTo(*_b->mobileType()))
+ return _b->mobileType();
else
return TypePointer();
}
@@ -879,7 +879,8 @@ bool StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const
else if (auto arrayType = dynamic_cast<ArrayType const*>(&_convertTo))
return
arrayType->isByteArray() &&
- !(arrayType->dataStoredIn(DataLocation::Storage) && arrayType->isPointer());
+ !(arrayType->dataStoredIn(DataLocation::Storage) && arrayType->isPointer()) &&
+ !(arrayType->isString() && !isValidUTF8());
else
return false;
}
@@ -895,7 +896,7 @@ std::string StringLiteralType::toString(bool) const
{
size_t invalidSequence;
- if (!dev::validate(m_value, invalidSequence))
+ if (!dev::validateUTF8(m_value, invalidSequence))
return "literal_string (contains invalid UTF-8 sequence at position " + dev::toString(invalidSequence) + ")";
return "literal_string \"" + m_value + "\"";
@@ -906,6 +907,11 @@ TypePointer StringLiteralType::mobileType() const
return make_shared<ArrayType>(DataLocation::Memory, true);
}
+bool StringLiteralType::isValidUTF8() const
+{
+ return dev::validateUTF8(m_value);
+}
+
shared_ptr<FixedBytesType> FixedBytesType::smallestTypeForLiteral(string const& _literal)
{
if (_literal.length() <= 32)
@@ -1265,6 +1271,7 @@ TypePointer ArrayType::decodingType() const
TypePointer ArrayType::interfaceType(bool _inLibrary) const
{
+ // Note: This has to fulfill canBeUsedExternally(_inLibrary) == !!interfaceType(_inLibrary)
if (_inLibrary && location() == DataLocation::Storage)
return shared_from_this();
@@ -1282,6 +1289,21 @@ TypePointer ArrayType::interfaceType(bool _inLibrary) const
return make_shared<ArrayType>(DataLocation::Memory, baseExt, m_length);
}
+bool ArrayType::canBeUsedExternally(bool _inLibrary) const
+{
+ // Note: This has to fulfill canBeUsedExternally(_inLibrary) == !!interfaceType(_inLibrary)
+ if (_inLibrary && location() == DataLocation::Storage)
+ return true;
+ else if (m_arrayKind != ArrayKind::Ordinary)
+ return true;
+ else if (!m_baseType->canBeUsedExternally(_inLibrary))
+ return false;
+ else if (m_baseType->category() == Category::Array && m_baseType->isDynamicallySized())
+ return false;
+ else
+ return true;
+}
+
u256 ArrayType::memorySize() const
{
solAssert(!isDynamicallySized(), "");
@@ -1451,7 +1473,7 @@ u256 StructType::storageSize() const
string StructType::toString(bool _short) const
{
- string ret = "struct " + m_struct.name();
+ string ret = "struct " + m_struct.annotation().canonicalName;
if (!_short)
ret += " " + stringForReferencePart();
return ret;
@@ -1561,7 +1583,7 @@ bool EnumType::operator==(Type const& _other) const
unsigned EnumType::storageBytes() const
{
- size_t elements = m_enum.members().size();
+ size_t elements = numberOfMembers();
if (elements <= 1)
return 1;
else
@@ -1570,7 +1592,7 @@ unsigned EnumType::storageBytes() const
string EnumType::toString(bool) const
{
- return string("enum ") + m_enum.name();
+ return string("enum ") + m_enum.annotation().canonicalName;
}
string EnumType::canonicalName(bool) const
@@ -1578,9 +1600,14 @@ string EnumType::canonicalName(bool) const
return m_enum.annotation().canonicalName;
}
+size_t EnumType::numberOfMembers() const
+{
+ return m_enum.members().size();
+};
+
bool EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
- return _convertTo.category() == category() || _convertTo.category() == Category::Integer;
+ return _convertTo == *this || _convertTo.category() == Category::Integer;
}
unsigned EnumType::memberValue(ASTString const& _member) const
@@ -1699,7 +1726,7 @@ TypePointer TupleType::closestTemporaryType(TypePointer const& _targetType) cons
FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal):
m_location(_isInternal ? Location::Internal : Location::External),
m_isConstant(_function.isDeclaredConst()),
- m_isPayable(_function.isPayable()),
+ m_isPayable(_isInternal ? false : _function.isPayable()),
m_declaration(&_function)
{
TypePointers params;
@@ -1800,6 +1827,38 @@ FunctionType::FunctionType(EventDefinition const& _event):
swap(paramNames, m_parameterNames);
}
+FunctionType::FunctionType(FunctionTypeName const& _typeName):
+ m_location(_typeName.visibility() == VariableDeclaration::Visibility::External ? Location::External : Location::Internal),
+ m_isConstant(_typeName.isDeclaredConst()),
+ m_isPayable(_typeName.isPayable())
+{
+ if (_typeName.isPayable())
+ {
+ solAssert(m_location == Location::External, "Internal payable function type used.");
+ solAssert(!m_isConstant, "Payable constant function");
+ }
+ for (auto const& t: _typeName.parameterTypes())
+ {
+ solAssert(t->annotation().type, "Type not set for parameter.");
+ if (m_location == Location::External)
+ solAssert(
+ t->annotation().type->canBeUsedExternally(false),
+ "Internal type used as parameter for external function."
+ );
+ m_parameterTypes.push_back(t->annotation().type);
+ }
+ for (auto const& t: _typeName.returnParameterTypes())
+ {
+ solAssert(t->annotation().type, "Type not set for return parameter.");
+ if (m_location == Location::External)
+ solAssert(
+ t->annotation().type->canBeUsedExternally(false),
+ "Internal type used as return parameter for external function."
+ );
+ m_returnParameterTypes.push_back(t->annotation().type);
+ }
+}
+
FunctionTypePointer FunctionType::newExpressionType(ContractDefinition const& _contract)
{
FunctionDefinition const* constructor = _contract.constructor();
@@ -1875,22 +1934,69 @@ bool FunctionType::operator==(Type const& _other) const
return true;
}
+TypePointer FunctionType::unaryOperatorResult(Token::Value _operator) const
+{
+ if (_operator == Token::Value::Delete)
+ return make_shared<TupleType>();
+ return TypePointer();
+}
+
+string FunctionType::canonicalName(bool) const
+{
+ solAssert(m_location == Location::External, "");
+ return "function";
+}
+
string FunctionType::toString(bool _short) const
{
string name = "function (";
for (auto it = m_parameterTypes.begin(); it != m_parameterTypes.end(); ++it)
name += (*it)->toString(_short) + (it + 1 == m_parameterTypes.end() ? "" : ",");
- name += ") returns (";
- for (auto it = m_returnParameterTypes.begin(); it != m_returnParameterTypes.end(); ++it)
- name += (*it)->toString(_short) + (it + 1 == m_returnParameterTypes.end() ? "" : ",");
- return name + ")";
+ name += ")";
+ if (m_isConstant)
+ name += " constant";
+ if (m_isPayable)
+ name += " payable";
+ if (m_location == Location::External)
+ name += " external";
+ if (!m_returnParameterTypes.empty())
+ {
+ name += " returns (";
+ for (auto it = m_returnParameterTypes.begin(); it != m_returnParameterTypes.end(); ++it)
+ name += (*it)->toString(_short) + (it + 1 == m_returnParameterTypes.end() ? "" : ",");
+ name += ")";
+ }
+ return name;
+}
+
+unsigned FunctionType::calldataEncodedSize(bool _padded) const
+{
+ unsigned size = storageBytes();
+ if (_padded)
+ size = ((size + 31) / 32) * 32;
+ return size;
}
u256 FunctionType::storageSize() const
{
- BOOST_THROW_EXCEPTION(
- InternalCompilerError()
- << errinfo_comment("Storage size of non-storable function type requested."));
+ if (m_location == Location::External || m_location == Location::Internal)
+ return 1;
+ else
+ BOOST_THROW_EXCEPTION(
+ InternalCompilerError()
+ << errinfo_comment("Storage size of non-storable function type requested."));
+}
+
+unsigned FunctionType::storageBytes() const
+{
+ if (m_location == Location::External)
+ return 20 + 4;
+ else if (m_location == Location::Internal)
+ return 8; // it should really not be possible to create larger programs
+ else
+ BOOST_THROW_EXCEPTION(
+ InternalCompilerError()
+ << errinfo_comment("Storage size of non-storable function type requested."));
}
unsigned FunctionType::sizeOnStack() const
@@ -2013,6 +2119,23 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con
}
}
+TypePointer FunctionType::encodingType() const
+{
+ // Only external functions can be encoded, internal functions cannot leave code boundaries.
+ if (m_location == Location::External)
+ return shared_from_this();
+ else
+ return TypePointer();
+}
+
+TypePointer FunctionType::interfaceType(bool /*_inLibrary*/) const
+{
+ if (m_location == Location::External)
+ return shared_from_this();
+ else
+ return TypePointer();
+}
+
bool FunctionType::canTakeArguments(TypePointers const& _argumentTypes, TypePointer const& _selfType) const
{
solAssert(!bound() || _selfType, "");
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index 3f94d11a..26e2b8f2 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -254,6 +254,9 @@ public:
/// @param _inLibrary if set, returns types as used in a library, e.g. struct and contract types
/// are returned without modification.
virtual TypePointer interfaceType(bool /*_inLibrary*/) const { return TypePointer(); }
+ /// @returns true iff this type can be passed on via calls (to libraries if _inLibrary is true),
+ /// should be have identical to !!interfaceType(_inLibrary) but might do optimizations.
+ virtual bool canBeUsedExternally(bool _inLibrary) const { return !!interfaceType(_inLibrary); }
private:
/// @returns a member list containing all members added to this type by `using for` directives.
@@ -422,6 +425,8 @@ public:
virtual std::string toString(bool) const override;
virtual TypePointer mobileType() const override;
+ bool isValidUTF8() const;
+
std::string const& value() const { return m_value; }
private:
@@ -580,6 +585,7 @@ public:
virtual TypePointer encodingType() const override;
virtual TypePointer decodingType() const override;
virtual TypePointer interfaceType(bool _inLibrary) const override;
+ virtual bool canBeUsedExternally(bool _inLibrary) const override;
/// @returns true if this is a byte array or a string
bool isByteArray() const { return m_arrayKind != ArrayKind::Ordinary; }
@@ -738,6 +744,7 @@ public:
EnumDefinition const& enumDefinition() const { return m_enum; }
/// @returns the value that the string has in the Enum
unsigned int memberValue(ASTString const& _member) const;
+ size_t numberOfMembers() const;
private:
EnumDefinition const& m_enum;
@@ -820,6 +827,8 @@ public:
explicit FunctionType(VariableDeclaration const& _varDecl);
/// Creates the function type of an event.
explicit FunctionType(EventDefinition const& _event);
+ /// Creates the type of a function type name.
+ explicit FunctionType(FunctionTypeName const& _typeName);
/// Function type constructor to be used for a plain type (not derived from a declaration).
FunctionType(
strings const& _parameterTypes,
@@ -889,12 +898,19 @@ public:
TypePointer selfType() const;
virtual bool operator==(Type const& _other) const override;
+ virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
+ virtual std::string canonicalName(bool /*_addDataLocation*/) const override;
virtual std::string toString(bool _short) const override;
- virtual bool canBeStored() const override { return false; }
+ virtual unsigned calldataEncodedSize(bool _padded) const override;
+ virtual bool canBeStored() const override { return m_location == Location::Internal || m_location == Location::External; }
virtual u256 storageSize() const override;
- virtual bool canLiveOutsideStorage() const override { return false; }
+ virtual unsigned storageBytes() const override;
+ virtual bool isValueType() const override { return true; }
+ virtual bool canLiveOutsideStorage() const override { return m_location == Location::Internal || m_location == Location::External; }
virtual unsigned sizeOnStack() const override;
virtual MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
+ virtual TypePointer encodingType() const override;
+ virtual TypePointer interfaceType(bool _inLibrary) const override;
/// @returns TypePointer of a new FunctionType object. All input/return parameters are an
/// appropriate external types (i.e. the interfaceType()s) of input/return parameters of
@@ -1101,6 +1117,8 @@ public:
virtual std::string toString(bool _short) const override;
+ Kind kind() const { return m_kind; }
+
private:
Kind m_kind;
};
diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp
index e7e8a98e..2c982982 100644
--- a/libsolidity/codegen/ArrayUtils.cpp
+++ b/libsolidity/codegen/ArrayUtils.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -200,7 +200,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
else if (sourceBaseType->isValueType())
CompilerUtils(m_context).loadFromMemoryDynamic(*sourceBaseType, fromCalldata, true, false);
else
- solAssert(false, "Copying of type " + _sourceType.toString(false) + " to storage not yet supported.");
+ solUnimplemented("Copying of type " + _sourceType.toString(false) + " to storage not yet supported.");
// stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] <source_value>...
solAssert(
2 + byteOffsetSize + sourceBaseType->sizeOnStack() <= 16,
@@ -270,7 +270,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWordBoundaries) const
{
- solAssert(
+ solUnimplementedAssert(
!_sourceType.baseType()->isDynamicallySized(),
"Nested dynamic arrays not implemented here."
);
diff --git a/libsolidity/codegen/ArrayUtils.h b/libsolidity/codegen/ArrayUtils.h
index 53d36c14..d0ba2892 100644
--- a/libsolidity/codegen/ArrayUtils.h
+++ b/libsolidity/codegen/ArrayUtils.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/codegen/Compiler.cpp b/libsolidity/codegen/Compiler.cpp
index 1ae5dda9..44264a07 100644
--- a/libsolidity/codegen/Compiler.cpp
+++ b/libsolidity/codegen/Compiler.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -30,23 +30,20 @@ using namespace dev::solidity;
void Compiler::compileContract(
ContractDefinition const& _contract,
- std::map<const ContractDefinition*, eth::Assembly const*> const& _contracts
+ std::map<const ContractDefinition*, eth::Assembly const*> const& _contracts,
+ bytes const& _metadata
)
{
- ContractCompiler runtimeCompiler(m_runtimeContext, m_optimize);
+ ContractCompiler runtimeCompiler(nullptr, m_runtimeContext, m_optimize);
runtimeCompiler.compileContract(_contract, _contracts);
+ m_runtimeContext.appendAuxiliaryData(_metadata);
- ContractCompiler creationCompiler(m_context, m_optimize);
- m_runtimeSub = creationCompiler.compileConstructor(m_runtimeContext, _contract, _contracts);
+ // This might modify m_runtimeContext because it can access runtime functions at
+ // creation time.
+ ContractCompiler creationCompiler(&runtimeCompiler, m_context, m_optimize);
+ m_runtimeSub = creationCompiler.compileConstructor(_contract, _contracts);
- if (m_optimize)
- m_context.optimise(m_optimizeRuns);
-
- if (_contract.isLibrary())
- {
- solAssert(m_runtimeSub != size_t(-1), "");
- m_context.injectVersionStampIntoSub(m_runtimeSub);
- }
+ m_context.optimise(m_optimize, m_optimizeRuns);
}
void Compiler::compileClone(
@@ -54,11 +51,11 @@ void Compiler::compileClone(
map<ContractDefinition const*, eth::Assembly const*> const& _contracts
)
{
- ContractCompiler cloneCompiler(m_context, m_optimize);
+ ContractCompiler runtimeCompiler(nullptr, m_runtimeContext, m_optimize);
+ ContractCompiler cloneCompiler(&runtimeCompiler, m_context, m_optimize);
m_runtimeSub = cloneCompiler.compileClone(_contract, _contracts);
- if (m_optimize)
- m_context.optimise(m_optimizeRuns);
+ m_context.optimise(m_optimize, m_optimizeRuns);
}
eth::AssemblyItem Compiler::functionEntryLabel(FunctionDefinition const& _function) const
diff --git a/libsolidity/codegen/Compiler.h b/libsolidity/codegen/Compiler.h
index fccb68a9..eef078c1 100644
--- a/libsolidity/codegen/Compiler.h
+++ b/libsolidity/codegen/Compiler.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -35,12 +35,15 @@ class Compiler
public:
explicit Compiler(bool _optimize = false, unsigned _runs = 200):
m_optimize(_optimize),
- m_optimizeRuns(_runs)
+ m_optimizeRuns(_runs),
+ m_runtimeContext(),
+ m_context(&m_runtimeContext)
{ }
void compileContract(
ContractDefinition const& _contract,
- std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts
+ std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts,
+ bytes const& _metadata
);
/// Compiles a contract that uses DELEGATECALL to call into a pre-deployed version of the given
/// contract at runtime, but contains the full creation-time code.
@@ -69,9 +72,9 @@ public:
private:
bool const m_optimize;
unsigned const m_optimizeRuns;
- CompilerContext m_context;
- size_t m_runtimeSub = size_t(-1); ///< Identifier of the runtime sub-assembly, if present.
CompilerContext m_runtimeContext;
+ size_t m_runtimeSub = size_t(-1); ///< Identifier of the runtime sub-assembly, if present.
+ CompilerContext m_context;
};
}
diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp
index 3ac5bd3c..2de5a3ec 100644
--- a/libsolidity/codegen/CompilerContext.cpp
+++ b/libsolidity/codegen/CompilerContext.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -60,8 +60,8 @@ void CompilerContext::startFunction(Declaration const& _function)
void CompilerContext::addVariable(VariableDeclaration const& _declaration,
unsigned _offsetToCurrent)
{
- solAssert(m_asm.deposit() >= 0 && unsigned(m_asm.deposit()) >= _offsetToCurrent, "");
- m_localVariables[&_declaration] = unsigned(m_asm.deposit()) - _offsetToCurrent;
+ solAssert(m_asm->deposit() >= 0 && unsigned(m_asm->deposit()) >= _offsetToCurrent, "");
+ m_localVariables[&_declaration] = unsigned(m_asm->deposit()) - _offsetToCurrent;
}
void CompilerContext::removeVariable(VariableDeclaration const& _declaration)
@@ -92,22 +92,22 @@ eth::AssemblyItem CompilerContext::functionEntryLabelIfExists(Declaration const&
return m_functionCompilationQueue.entryLabelIfExists(_declaration);
}
-eth::AssemblyItem CompilerContext::virtualFunctionEntryLabel(FunctionDefinition const& _function)
+FunctionDefinition const& CompilerContext::resolveVirtualFunction(FunctionDefinition const& _function)
{
// Libraries do not allow inheritance and their functions can be inlined, so we should not
// search the inheritance hierarchy (which will be the wrong one in case the function
// is inlined).
if (auto scope = dynamic_cast<ContractDefinition const*>(_function.scope()))
if (scope->isLibrary())
- return functionEntryLabel(_function);
+ return _function;
solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set.");
- return virtualFunctionEntryLabel(_function, m_inheritanceHierarchy.begin());
+ return resolveVirtualFunction(_function, m_inheritanceHierarchy.begin());
}
-eth::AssemblyItem CompilerContext::superFunctionEntryLabel(FunctionDefinition const& _function, ContractDefinition const& _base)
+FunctionDefinition const& CompilerContext::superFunction(FunctionDefinition const& _function, ContractDefinition const& _base)
{
solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set.");
- return virtualFunctionEntryLabel(_function, superContract(_base));
+ return resolveVirtualFunction(_function, superContract(_base));
}
FunctionDefinition const* CompilerContext::nextConstructor(ContractDefinition const& _contract) const
@@ -145,12 +145,12 @@ unsigned CompilerContext::baseStackOffsetOfVariable(Declaration const& _declarat
unsigned CompilerContext::baseToCurrentStackOffset(unsigned _baseOffset) const
{
- return m_asm.deposit() - _baseOffset - 1;
+ return m_asm->deposit() - _baseOffset - 1;
}
unsigned CompilerContext::currentToBaseStackOffset(unsigned _offset) const
{
- return m_asm.deposit() - _offset - 1;
+ return m_asm->deposit() - _offset - 1;
}
pair<u256, unsigned> CompilerContext::storageLocationOfVariable(const Declaration& _declaration) const
@@ -217,17 +217,10 @@ void CompilerContext::appendInlineAssembly(
return true;
};
- solAssert(assembly::InlineAssemblyStack().parseAndAssemble(*assembly, m_asm, identifierAccess), "");
+ solAssert(assembly::InlineAssemblyStack().parseAndAssemble(*assembly, *m_asm, identifierAccess), "");
}
-void CompilerContext::injectVersionStampIntoSub(size_t _subIndex)
-{
- eth::Assembly& sub = m_asm.sub(_subIndex);
- sub.injectStart(Instruction::POP);
- sub.injectStart(fromBigEndian<u256>(binaryVersion()));
-}
-
-eth::AssemblyItem CompilerContext::virtualFunctionEntryLabel(
+FunctionDefinition const& CompilerContext::resolveVirtualFunction(
FunctionDefinition const& _function,
vector<ContractDefinition const*>::const_iterator _searchStart
)
@@ -242,9 +235,9 @@ eth::AssemblyItem CompilerContext::virtualFunctionEntryLabel(
!function->isConstructor() &&
FunctionType(*function).hasEqualArgumentTypes(functionType)
)
- return functionEntryLabel(*function);
+ return *function;
solAssert(false, "Super function " + name + " not found.");
- return m_asm.newTag(); // not reached
+ return _function; // not reached
}
vector<ContractDefinition const*>::const_iterator CompilerContext::superContract(ContractDefinition const& _contract) const
@@ -257,7 +250,7 @@ vector<ContractDefinition const*>::const_iterator CompilerContext::superContract
void CompilerContext::updateSourceLocation()
{
- m_asm.setSourceLocation(m_visitedNodes.empty() ? SourceLocation() : m_visitedNodes.top()->location());
+ m_asm->setSourceLocation(m_visitedNodes.empty() ? SourceLocation() : m_visitedNodes.top()->location());
}
eth::AssemblyItem CompilerContext::FunctionCompilationQueue::entryLabel(
diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h
index 0c1500b0..80671528 100644
--- a/libsolidity/codegen/CompilerContext.h
+++ b/libsolidity/codegen/CompilerContext.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -44,6 +44,14 @@ namespace solidity {
class CompilerContext
{
public:
+ CompilerContext(CompilerContext* _runtimeContext = nullptr):
+ m_asm(std::make_shared<eth::Assembly>()),
+ m_runtimeContext(_runtimeContext)
+ {
+ if (m_runtimeContext)
+ m_runtimeSub = size_t(m_asm->newSub(m_runtimeContext->m_asm).data());
+ }
+
void addMagicGlobal(MagicVariableDeclaration const& _declaration);
void addStateVariable(VariableDeclaration const& _declaration, u256 const& _storageOffset, unsigned _byteOffset);
void addVariable(VariableDeclaration const& _declaration, unsigned _offsetToCurrent = 0);
@@ -52,9 +60,9 @@ public:
void setCompiledContracts(std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts) { m_compiledContracts = _contracts; }
eth::Assembly const& compiledContract(ContractDefinition const& _contract) const;
- void setStackOffset(int _offset) { m_asm.setDeposit(_offset); }
- void adjustStackOffset(int _adjustment) { m_asm.adjustDeposit(_adjustment); }
- unsigned stackHeight() const { solAssert(m_asm.deposit() >= 0, ""); return unsigned(m_asm.deposit()); }
+ void setStackOffset(int _offset) { m_asm->setDeposit(_offset); }
+ void adjustStackOffset(int _adjustment) { m_asm->adjustDeposit(_adjustment); }
+ unsigned stackHeight() const { solAssert(m_asm->deposit() >= 0, ""); return unsigned(m_asm->deposit()); }
bool isMagicGlobal(Declaration const* _declaration) const { return m_magicGlobals.count(_declaration) != 0; }
bool isLocalVariable(Declaration const* _declaration) const;
@@ -67,10 +75,10 @@ public:
eth::AssemblyItem functionEntryLabelIfExists(Declaration const& _declaration) const;
void setInheritanceHierarchy(std::vector<ContractDefinition const*> const& _hierarchy) { m_inheritanceHierarchy = _hierarchy; }
/// @returns the entry label of the given function and takes overrides into account.
- eth::AssemblyItem virtualFunctionEntryLabel(FunctionDefinition const& _function);
- /// @returns the entry label of a function that overrides the given declaration from the most derived class just
+ FunctionDefinition const& resolveVirtualFunction(FunctionDefinition const& _function);
+ /// @returns the function that overrides the given declaration from the most derived class just
/// above _base in the current inheritance hierarchy.
- eth::AssemblyItem superFunctionEntryLabel(FunctionDefinition const& _function, ContractDefinition const& _base);
+ FunctionDefinition const& superFunction(FunctionDefinition const& _function, ContractDefinition const& _base);
FunctionDefinition const* nextConstructor(ContractDefinition const& _contract) const;
/// @returns the next function in the queue of functions that are still to be compiled
@@ -95,30 +103,33 @@ public:
std::pair<u256, unsigned> storageLocationOfVariable(Declaration const& _declaration) const;
/// Appends a JUMPI instruction to a new tag and @returns the tag
- eth::AssemblyItem appendConditionalJump() { return m_asm.appendJumpI().tag(); }
+ eth::AssemblyItem appendConditionalJump() { return m_asm->appendJumpI().tag(); }
/// Appends a JUMPI instruction to @a _tag
- CompilerContext& appendConditionalJumpTo(eth::AssemblyItem const& _tag) { m_asm.appendJumpI(_tag); return *this; }
+ CompilerContext& appendConditionalJumpTo(eth::AssemblyItem const& _tag) { m_asm->appendJumpI(_tag); return *this; }
/// Appends a JUMP to a new tag and @returns the tag
- eth::AssemblyItem appendJumpToNew() { return m_asm.appendJump().tag(); }
+ eth::AssemblyItem appendJumpToNew() { return m_asm->appendJump().tag(); }
/// Appends a JUMP to a tag already on the stack
CompilerContext& appendJump(eth::AssemblyItem::JumpType _jumpType = eth::AssemblyItem::JumpType::Ordinary);
/// Returns an "ErrorTag"
- eth::AssemblyItem errorTag() { return m_asm.errorTag(); }
+ eth::AssemblyItem errorTag() { return m_asm->errorTag(); }
/// Appends a JUMP to a specific tag
- CompilerContext& appendJumpTo(eth::AssemblyItem const& _tag) { m_asm.appendJump(_tag); return *this; }
+ CompilerContext& appendJumpTo(eth::AssemblyItem const& _tag) { m_asm->appendJump(_tag); return *this; }
/// Appends pushing of a new tag and @returns the new tag.
- eth::AssemblyItem pushNewTag() { return m_asm.append(m_asm.newPushTag()).tag(); }
+ eth::AssemblyItem pushNewTag() { return m_asm->append(m_asm->newPushTag()).tag(); }
/// @returns a new tag without pushing any opcodes or data
- eth::AssemblyItem newTag() { return m_asm.newTag(); }
+ eth::AssemblyItem newTag() { return m_asm->newTag(); }
/// Adds a subroutine to the code (in the data section) and pushes its size (via a tag)
- /// on the stack. @returns the assembly item corresponding to the pushed subroutine, i.e. its offset.
- eth::AssemblyItem addSubroutine(eth::Assembly const& _assembly) { return m_asm.appendSubSize(_assembly); }
+ /// on the stack. @returns the pushsub assembly item.
+ eth::AssemblyItem addSubroutine(eth::AssemblyPointer const& _assembly) { auto sub = m_asm->newSub(_assembly); m_asm->append(m_asm->newPushSubSize(size_t(sub.data()))); return sub; }
+ void pushSubroutineSize(size_t _subRoutine) { m_asm->append(m_asm->newPushSubSize(_subRoutine)); }
+ /// Pushes the offset of the subroutine.
+ void pushSubroutineOffset(size_t _subRoutine) { m_asm->append(eth::AssemblyItem(eth::PushSub, _subRoutine)); }
/// Pushes the size of the final program
- void appendProgramSize() { return m_asm.appendProgramSize(); }
+ void appendProgramSize() { m_asm->appendProgramSize(); }
/// Adds data to the data section, pushes a reference to the stack
- eth::AssemblyItem appendData(bytes const& _data) { return m_asm.append(_data); }
+ eth::AssemblyItem appendData(bytes const& _data) { return m_asm->append(_data); }
/// Appends the address (virtual, will be filled in by linker) of a library.
- void appendLibraryAddress(std::string const& _identifier) { m_asm.appendLibraryAddress(_identifier); }
+ void appendLibraryAddress(std::string const& _identifier) { m_asm->appendLibraryAddress(_identifier); }
/// Resets the stack of visited nodes with a new stack having only @c _node
void resetVisitedNodes(ASTNode const* _node);
/// Pops the stack of visited nodes
@@ -127,10 +138,10 @@ public:
void pushVisitedNodes(ASTNode const* _node) { m_visitedNodes.push(_node); updateSourceLocation(); }
/// Append elements to the current instruction list and adjust @a m_stackOffset.
- CompilerContext& operator<<(eth::AssemblyItem const& _item) { m_asm.append(_item); return *this; }
- CompilerContext& operator<<(Instruction _instruction) { m_asm.append(_instruction); return *this; }
- CompilerContext& operator<<(u256 const& _value) { m_asm.append(_value); return *this; }
- CompilerContext& operator<<(bytes const& _data) { m_asm.append(_data); return *this; }
+ CompilerContext& operator<<(eth::AssemblyItem const& _item) { m_asm->append(_item); return *this; }
+ CompilerContext& operator<<(Instruction _instruction) { m_asm->append(_instruction); return *this; }
+ CompilerContext& operator<<(u256 const& _value) { m_asm->append(_value); return *this; }
+ CompilerContext& operator<<(bytes const& _data) { m_asm->append(_data); return *this; }
/// Appends inline assembly. @a _replacements are string-matching replacements that are performed
/// prior to parsing the inline assembly.
@@ -141,25 +152,30 @@ public:
std::map<std::string, std::string> const& _replacements = std::map<std::string, std::string>{}
);
- /// Prepends "PUSH <compiler version number> POP"
- void injectVersionStampIntoSub(size_t _subIndex);
+ /// Appends arbitrary data to the end of the bytecode.
+ void appendAuxiliaryData(bytes const& _data) { m_asm->appendAuxiliaryDataToEnd(_data); }
+
+ void optimise(bool _fullOptimsation, unsigned _runs = 200) { m_asm->optimise(_fullOptimsation, true, _runs); }
- void optimise(unsigned _runs = 200) { m_asm.optimise(true, true, _runs); }
+ /// @returns the runtime context if in creation mode and runtime context is set, nullptr otherwise.
+ CompilerContext* runtimeContext() { return m_runtimeContext; }
+ /// @returns the identifier of the runtime subroutine.
+ size_t runtimeSub() const { return m_runtimeSub; }
- eth::Assembly const& assembly() const { return m_asm; }
+ eth::Assembly const& assembly() const { return *m_asm; }
/// @returns non-const reference to the underlying assembly. Should be avoided in favour of
/// wrappers in this class.
- eth::Assembly& nonConstAssembly() { return m_asm; }
+ eth::Assembly& nonConstAssembly() { return *m_asm; }
/// @arg _sourceCodes is the map of input files to source code strings
/// @arg _inJsonFormat shows whether the out should be in Json format
Json::Value streamAssembly(std::ostream& _stream, StringMap const& _sourceCodes = StringMap(), bool _inJsonFormat = false) const
{
- return m_asm.stream(_stream, "", _sourceCodes, _inJsonFormat);
+ return m_asm->stream(_stream, "", _sourceCodes, _inJsonFormat);
}
- eth::LinkerObject const& assembledObject() { return m_asm.assemble(); }
- eth::LinkerObject const& assembledRuntimeObject(size_t _subIndex) { return m_asm.sub(_subIndex).assemble(); }
+ eth::LinkerObject const& assembledObject() { return m_asm->assemble(); }
+ eth::LinkerObject const& assembledRuntimeObject(size_t _subIndex) { return m_asm->sub(_subIndex).assemble(); }
/**
* Helper class to pop the visited nodes stack when a scope closes
@@ -172,9 +188,9 @@ public:
};
private:
- /// @returns the entry label of the given function - searches the inheritance hierarchy
- /// startig from the given point towards the base.
- eth::AssemblyItem virtualFunctionEntryLabel(
+ /// Searches the inheritance hierarchy towards the base starting from @a _searchStart and returns
+ /// the first function definition that is overwritten by _function.
+ FunctionDefinition const& resolveVirtualFunction(
FunctionDefinition const& _function,
std::vector<ContractDefinition const*>::const_iterator _searchStart
);
@@ -215,7 +231,7 @@ private:
mutable std::queue<Declaration const*> m_functionsToCompile;
} m_functionCompilationQueue;
- eth::Assembly m_asm;
+ eth::AssemblyPointer m_asm;
/// Magic global variables like msg, tx or this, distinguished by type.
std::set<Declaration const*> m_magicGlobals;
/// Other already compiled contracts to be used in contract creation calls.
@@ -228,6 +244,10 @@ private:
std::vector<ContractDefinition const*> m_inheritanceHierarchy;
/// Stack of current visited AST nodes, used for location attachment
std::stack<ASTNode const*> m_visitedNodes;
+ /// The runtime context if in Creation mode, this is used for generating tags that would be stored into the storage and then used at runtime.
+ CompilerContext *m_runtimeContext;
+ /// The index of the runtime subroutine.
+ size_t m_runtimeSub = -1;
};
}
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index e064c1a6..7c159ff7 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -133,12 +133,22 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound
m_context << u256(str->value().size());
m_context << Instruction::ADD;
}
+ else if (
+ _type.category() == Type::Category::Function &&
+ dynamic_cast<FunctionType const&>(_type).location() == FunctionType::Location::External
+ )
+ {
+ solUnimplementedAssert(_padToWordBoundaries, "Non-padded store for function not implemented.");
+ combineExternalFunctionType(true);
+ m_context << Instruction::DUP2 << Instruction::MSTORE;
+ m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD;
+ }
else
{
unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries);
if (numBytes > 0)
{
- solAssert(
+ solUnimplementedAssert(
_type.sizeOnStack() == 1,
"Memory store of types with stack size != 1 not implemented."
);
@@ -161,7 +171,7 @@ void CompilerUtils::encodeToMemory(
solAssert(targetTypes.size() == _givenTypes.size(), "");
for (TypePointer& t: targetTypes)
{
- solAssert(
+ solUnimplementedAssert(
t->mobileType() &&
t->mobileType()->interfaceType(_encodeAsLibraryTypes) &&
t->mobileType()->interfaceType(_encodeAsLibraryTypes)->encodingType(),
@@ -206,7 +216,8 @@ void CompilerUtils::encodeToMemory(
else if (
_givenTypes[i]->dataStoredIn(DataLocation::Storage) ||
_givenTypes[i]->dataStoredIn(DataLocation::CallData) ||
- _givenTypes[i]->category() == Type::Category::StringLiteral
+ _givenTypes[i]->category() == Type::Category::StringLiteral ||
+ _givenTypes[i]->category() == Type::Category::Function
)
type = _givenTypes[i]; // delay conversion
else
@@ -301,10 +312,54 @@ void CompilerUtils::memoryCopy()
m_context << Instruction::DIV << u256(c_identityWordGas) << Instruction::MUL;
m_context << u256(c_identityGas) << Instruction::ADD;
m_context << Instruction::CALL;
- m_context << Instruction::POP; // ignore return value
+ m_context << Instruction::ISZERO;
+ m_context.appendConditionalJumpTo(m_context.errorTag());
}
-void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded)
+void CompilerUtils::splitExternalFunctionType(bool _leftAligned)
+{
+ // We have to split the left-aligned <address><function identifier> into two stack slots:
+ // address (right aligned), function identifier (right aligned)
+ if (_leftAligned)
+ {
+ m_context << Instruction::DUP1 << (u256(1) << (64 + 32)) << Instruction::SWAP1 << Instruction::DIV;
+ // <input> <address>
+ m_context << Instruction::SWAP1 << (u256(1) << 64) << Instruction::SWAP1 << Instruction::DIV;
+ }
+ else
+ {
+ m_context << Instruction::DUP1 << (u256(1) << 32) << Instruction::SWAP1 << Instruction::DIV;
+ m_context << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::SWAP1;
+ }
+ m_context << u256(0xffffffffUL) << Instruction::AND;
+}
+
+void CompilerUtils::combineExternalFunctionType(bool _leftAligned)
+{
+ // <address> <function_id>
+ m_context << u256(0xffffffffUL) << Instruction::AND << Instruction::SWAP1;
+ if (!_leftAligned)
+ m_context << ((u256(1) << 160) - 1) << Instruction::AND;
+ m_context << (u256(1) << 32) << Instruction::MUL;
+ m_context << Instruction::OR;
+ if (_leftAligned)
+ m_context << (u256(1) << 64) << Instruction::MUL;
+}
+
+void CompilerUtils::pushCombinedFunctionEntryLabel(Declaration const& _function)
+{
+ m_context << m_context.functionEntryLabel(_function).pushTag();
+ // If there is a runtime context, we have to merge both labels into the same
+ // stack slot in case we store it in storage.
+ if (CompilerContext* rtc = m_context.runtimeContext())
+ m_context <<
+ (u256(1) << 32) <<
+ Instruction::MUL <<
+ rtc->functionEntryLabel(_function).toSubAssemblyTag(m_context.runtimeSub()) <<
+ Instruction::OR;
+}
+
+void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded, bool _chopSignBits)
{
// For a type extension, we need to remove all higher-order bits that we might have ignored in
// previous operations.
@@ -315,6 +370,14 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
Type::Category stackTypeCategory = _typeOnStack.category();
Type::Category targetTypeCategory = _targetType.category();
+ bool enumOverflowCheckPending = (targetTypeCategory == Type::Category::Enum || stackTypeCategory == Type::Category::Enum);
+ bool chopSignBitsPending = _chopSignBits && targetTypeCategory == Type::Category::Integer;
+ if (chopSignBitsPending)
+ {
+ const IntegerType& targetIntegerType = dynamic_cast<const IntegerType &>(_targetType);
+ chopSignBitsPending = targetIntegerType.isSigned();
+ }
+
switch (stackTypeCategory)
{
case Type::Category::FixedBytes:
@@ -348,10 +411,18 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
}
break;
case Type::Category::Enum:
- solAssert(targetTypeCategory == Type::Category::Integer || targetTypeCategory == Type::Category::Enum, "");
+ solAssert(_targetType == _typeOnStack || targetTypeCategory == Type::Category::Integer, "");
+ if (enumOverflowCheckPending)
+ {
+ EnumType const& enumType = dynamic_cast<decltype(enumType)>(_typeOnStack);
+ solAssert(enumType.numberOfMembers() > 0, "empty enum should have caused a parser error.");
+ m_context << u256(enumType.numberOfMembers() - 1) << Instruction::DUP2 << Instruction::GT;
+ m_context.appendConditionalJumpTo(m_context.errorTag());
+ enumOverflowCheckPending = false;
+ }
break;
case Type::Category::FixedPoint:
- solAssert(false, "Not yet implemented - FixedPointType.");
+ solUnimplemented("Not yet implemented - FixedPointType.");
case Type::Category::Integer:
case Type::Category::Contract:
case Type::Category::RationalNumber:
@@ -372,6 +443,11 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
solAssert(_typeOnStack.mobileType(), "");
// just clean
convertType(_typeOnStack, *_typeOnStack.mobileType(), true);
+ EnumType const& enumType = dynamic_cast<decltype(enumType)>(_targetType);
+ solAssert(enumType.numberOfMembers() > 0, "empty enum should have caused a parser error.");
+ m_context << u256(enumType.numberOfMembers() - 1) << Instruction::DUP2 << Instruction::GT;
+ m_context.appendConditionalJumpTo(m_context.errorTag());
+ enumOverflowCheckPending = false;
}
else if (targetTypeCategory == Type::Category::FixedPoint)
{
@@ -386,7 +462,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
if (auto typeOnStack = dynamic_cast<IntegerType const*>(&_typeOnStack))
if (targetFixedPointType.integerBits() > typeOnStack->numBits())
cleanHigherOrderBits(*typeOnStack);
- solAssert(false, "Not yet implemented - FixedPointType.");
+ solUnimplemented("Not yet implemented - FixedPointType.");
}
else
{
@@ -399,7 +475,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
RationalNumberType const& constType = dynamic_cast<RationalNumberType const&>(_typeOnStack);
// We know that the stack is clean, we only have to clean for a narrowing conversion
// where cleanup is forced.
- solAssert(!constType.isFractional(), "Not yet implemented - FixedPointType.");
+ solUnimplementedAssert(!constType.isFractional(), "Not yet implemented - FixedPointType.");
if (targetType.numBits() < constType.integerType()->numBits() && _cleanupNeeded)
cleanHigherOrderBits(targetType);
}
@@ -413,6 +489,14 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
cleanHigherOrderBits(typeOnStack);
else if (_cleanupNeeded)
cleanHigherOrderBits(targetType);
+ if (chopSignBitsPending)
+ {
+ if (typeOnStack.numBits() < 256)
+ m_context
+ << ((u256(1) << typeOnStack.numBits()) - 1)
+ << Instruction::AND;
+ chopSignBitsPending = false;
+ }
}
}
break;
@@ -651,15 +735,31 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
solAssert(_targetType == _typeOnStack, "Invalid conversion for bool.");
if (_cleanupNeeded)
m_context << Instruction::ISZERO << Instruction::ISZERO;
+ break;
default:
// All other types should not be convertible to non-equal types.
solAssert(_typeOnStack == _targetType, "Invalid type conversion requested.");
+ if (_cleanupNeeded && _targetType.canBeStored() && _targetType.storageBytes() < 32)
+ m_context
+ << ((u256(1) << (8 * _targetType.storageBytes())) - 1)
+ << Instruction::AND;
break;
}
+
+ solAssert(!enumOverflowCheckPending, "enum overflow checking missing.");
+ solAssert(!chopSignBitsPending, "forgot to chop the sign bits.");
}
void CompilerUtils::pushZeroValue(Type const& _type)
{
+ if (auto const* funType = dynamic_cast<FunctionType const*>(&_type))
+ {
+ if (funType->location() == FunctionType::Location::Internal)
+ {
+ m_context << m_context.errorTag();
+ return;
+ }
+ }
auto const* referenceType = dynamic_cast<ReferenceType const*>(&_type);
if (!referenceType || referenceType->location() == DataLocation::Storage)
{
@@ -804,22 +904,30 @@ void CompilerUtils::storeStringData(bytesConstRef _data)
unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries)
{
unsigned numBytes = _type.calldataEncodedSize(_padToWordBoundaries);
- bool leftAligned = _type.category() == Type::Category::FixedBytes;
+ bool isExternalFunctionType = false;
+ if (auto const* funType = dynamic_cast<FunctionType const*>(&_type))
+ if (funType->location() == FunctionType::Location::External)
+ isExternalFunctionType = true;
if (numBytes == 0)
+ {
m_context << Instruction::POP << u256(0);
- else
+ return numBytes;
+ }
+ solAssert(numBytes <= 32, "Static memory load of more than 32 bytes requested.");
+ m_context << (_fromCalldata ? Instruction::CALLDATALOAD : Instruction::MLOAD);
+ if (isExternalFunctionType)
+ splitExternalFunctionType(true);
+ else if (numBytes != 32)
{
- solAssert(numBytes <= 32, "Static memory load of more than 32 bytes requested.");
- m_context << (_fromCalldata ? Instruction::CALLDATALOAD : Instruction::MLOAD);
- if (numBytes != 32)
- {
- // add leading or trailing zeros by dividing/multiplying depending on alignment
- u256 shiftFactor = u256(1) << ((32 - numBytes) * 8);
- m_context << shiftFactor << Instruction::SWAP1 << Instruction::DIV;
- if (leftAligned)
- m_context << shiftFactor << Instruction::MUL;
- }
+ bool leftAligned = _type.category() == Type::Category::FixedBytes;
+ // add leading or trailing zeros by dividing/multiplying depending on alignment
+ u256 shiftFactor = u256(1) << ((32 - numBytes) * 8);
+ m_context << shiftFactor << Instruction::SWAP1 << Instruction::DIV;
+ if (leftAligned)
+ m_context << shiftFactor << Instruction::MUL;
}
+ if (_fromCalldata)
+ convertType(_type, _type, true);
return numBytes;
}
@@ -834,7 +942,7 @@ void CompilerUtils::cleanHigherOrderBits(IntegerType const& _typeOnStack)
m_context << ((u256(1) << _typeOnStack.numBits()) - 1) << Instruction::AND;
}
-unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) const
+unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWordBoundaries)
{
unsigned numBytes = _type.calldataEncodedSize(_padToWordBoundaries);
bool leftAligned = _type.category() == Type::Category::FixedBytes;
@@ -843,6 +951,7 @@ unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWordBou
else
{
solAssert(numBytes <= 32, "Memory store of more than 32 bytes requested.");
+ convertType(_type, _type, true);
if (numBytes != 32 && !leftAligned && !_padToWordBoundaries)
// shift the value accordingly before storing
m_context << (u256(1) << ((32 - numBytes) * 8)) << Instruction::MUL;
diff --git a/libsolidity/codegen/CompilerUtils.h b/libsolidity/codegen/CompilerUtils.h
index da74dc90..0a5d8e1c 100644
--- a/libsolidity/codegen/CompilerUtils.h
+++ b/libsolidity/codegen/CompilerUtils.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -114,12 +114,24 @@ public:
/// Stack post:
void memoryCopy();
+ /// Converts the combined and left-aligned (right-aligned if @a _rightAligned is true)
+ /// external function type <address><function identifier> into two stack slots:
+ /// address (right aligned), function identifier (right aligned)
+ void splitExternalFunctionType(bool _rightAligned);
+ /// Performs the opposite operation of splitExternalFunctionType(_rightAligned)
+ void combineExternalFunctionType(bool _rightAligned);
+ /// Appends code that combines the construction-time (if available) and runtime function
+ /// entry label of the given function into a single stack slot.
+ /// Note: This might cause the compilation queue of the runtime context to be extended.
+ void pushCombinedFunctionEntryLabel(Declaration const& _function);
+
/// Appends code for an implicit or explicit type conversion. This includes erasing higher
/// order bits (@see appendHighBitCleanup) when widening integer but also copy to memory
/// if a reference type is converted from calldata or storage to memory.
/// If @a _cleanupNeeded, high order bits cleanup is also done if no type conversion would be
/// necessary.
- void convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded = false);
+ /// If @a _chopSignBits, the function resets the signed bits out of the width of the signed integer.
+ void convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded = false, bool _chopSignBits = false);
/// Creates a zero-value for the given type and puts it onto the stack. This might allocate
/// memory for memory references.
@@ -173,7 +185,7 @@ private:
void cleanHigherOrderBits(IntegerType const& _typeOnStack);
/// Prepares the given type for storing in memory by shifting it if necessary.
- unsigned prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) const;
+ unsigned prepareMemoryStore(Type const& _type, bool _padToWordBoundaries);
/// Loads type from memory assuming memory offset is on stack top.
unsigned loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries);
diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp
index ebb84784..a0f196bc 100644
--- a/libsolidity/codegen/ContractCompiler.cpp
+++ b/libsolidity/codegen/ContractCompiler.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -60,14 +60,13 @@ void ContractCompiler::compileContract(
}
size_t ContractCompiler::compileConstructor(
- CompilerContext const& _runtimeContext,
ContractDefinition const& _contract,
std::map<const ContractDefinition*, eth::Assembly const*> const& _contracts
)
{
CompilerContext::LocationSetter locationSetter(m_context, _contract);
initializeContext(_contract, _contracts);
- return packIntoContractCreator(_contract, _runtimeContext);
+ return packIntoContractCreator(_contract);
}
size_t ContractCompiler::compileClone(
@@ -80,7 +79,7 @@ size_t ContractCompiler::compileClone(
appendInitAndConstructorCode(_contract);
//@todo determine largest return size of all runtime functions
- eth::AssemblyItem runtimeSub = m_context.addSubroutine(cloneRuntime());
+ auto runtimeSub = m_context.addSubroutine(cloneRuntime());
// stack contains sub size
m_context << Instruction::DUP1 << runtimeSub << u256(0) << Instruction::CODECOPY;
@@ -88,7 +87,6 @@ size_t ContractCompiler::compileClone(
appendMissingFunctions();
- solAssert(runtimeSub.data() < numeric_limits<size_t>::max(), "");
return size_t(runtimeSub.data());
}
@@ -104,6 +102,13 @@ void ContractCompiler::initializeContext(
m_context.resetVisitedNodes(&_contract);
}
+void ContractCompiler::appendCallValueCheck()
+{
+ // Throw if function is not payable but call contained ether.
+ m_context << Instruction::CALLVALUE;
+ m_context.appendConditionalJumpTo(m_context.errorTag());
+}
+
void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _contract)
{
// Determine the arguments that are used for the base constructors.
@@ -139,23 +144,35 @@ void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _c
appendConstructor(*constructor);
else if (auto c = m_context.nextConstructor(_contract))
appendBaseConstructor(*c);
+ else
+ appendCallValueCheck();
}
-size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _contract, CompilerContext const& _runtimeContext)
+size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _contract)
{
- appendInitAndConstructorCode(_contract);
+ solAssert(!!m_runtimeCompiler, "");
- eth::AssemblyItem runtimeSub = m_context.addSubroutine(_runtimeContext.assembly());
+ appendInitAndConstructorCode(_contract);
- // stack contains sub size
- m_context << Instruction::DUP1 << runtimeSub << u256(0) << Instruction::CODECOPY;
- m_context << u256(0) << Instruction::RETURN;
+ // We jump to the deploy routine because we first have to append all missing functions,
+ // which can cause further functions to be added to the runtime context.
+ eth::AssemblyItem deployRoutine = m_context.appendJumpToNew();
- // note that we have to include the functions again because of absolute jump labels
+ // We have to include copies of functions in the construction time and runtime context
+ // because of absolute jumps.
appendMissingFunctions();
+ m_runtimeCompiler->appendMissingFunctions();
- solAssert(runtimeSub.data() < numeric_limits<size_t>::max(), "");
- return size_t(runtimeSub.data());
+ m_context << deployRoutine;
+
+ solAssert(m_context.runtimeSub() != size_t(-1), "Runtime sub not registered");
+ m_context.pushSubroutineSize(m_context.runtimeSub());
+ m_context << Instruction::DUP1;
+ m_context.pushSubroutineOffset(m_context.runtimeSub());
+ m_context << u256(0) << Instruction::CODECOPY;
+ m_context << u256(0) << Instruction::RETURN;
+
+ return m_context.runtimeSub();
}
void ContractCompiler::appendBaseConstructor(FunctionDefinition const& _constructor)
@@ -176,6 +193,9 @@ void ContractCompiler::appendBaseConstructor(FunctionDefinition const& _construc
void ContractCompiler::appendConstructor(FunctionDefinition const& _constructor)
{
CompilerContext::LocationSetter locationSetter(m_context, _constructor);
+ if (!_constructor.isPayable())
+ appendCallValueCheck();
+
// copy constructor arguments from code to memory and then to stack, they are supplied after the actual program
if (!_constructor.parameters().empty())
{
@@ -243,11 +263,8 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac
if (fallback)
{
if (!fallback->isPayable())
- {
- // Throw if function is not payable but call contained ether.
- m_context << Instruction::CALLVALUE;
- m_context.appendConditionalJumpTo(m_context.errorTag());
- }
+ appendCallValueCheck();
+
eth::AssemblyItem returnTag = m_context.pushNewTag();
fallback->accept(*this);
m_context << returnTag;
@@ -266,11 +283,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac
// We have to allow this for libraries, because value of the previous
// call is still visible in the delegatecall.
if (!functionType->isPayable() && !_contract.isLibrary())
- {
- // Throw if function is not payable but call contained ether.
- m_context << Instruction::CALLVALUE;
- m_context.appendConditionalJumpTo(m_context.errorTag());
- }
+ appendCallValueCheck();
eth::AssemblyItem returnTag = m_context.pushNewTag();
m_context << CompilerUtils::dataStartOffset;
@@ -293,13 +306,14 @@ void ContractCompiler::appendCalldataUnpacker(TypePointers const& _typeParameter
{
// stack: v1 v2 ... v(k-1) base_offset current_offset
TypePointer type = parameterType->decodingType();
+ solAssert(type, "No decoding type found.");
if (type->category() == Type::Category::Array)
{
auto const& arrayType = dynamic_cast<ArrayType const&>(*type);
- solAssert(!arrayType.baseType()->isDynamicallySized(), "Nested arrays not yet implemented.");
+ solUnimplementedAssert(!arrayType.baseType()->isDynamicallySized(), "Nested arrays not yet implemented.");
if (_fromMemory)
{
- solAssert(
+ solUnimplementedAssert(
arrayType.baseType()->isValueType(),
"Nested memory arrays not yet implemented here."
);
@@ -515,7 +529,19 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
{
solAssert(!!decl->type(), "Type of declaration required but not yet determined.");
if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(decl))
- _assembly.append(m_context.virtualFunctionEntryLabel(*functionDef).pushTag());
+ {
+ functionDef = &m_context.resolveVirtualFunction(*functionDef);
+ _assembly.append(m_context.functionEntryLabel(*functionDef).pushTag());
+ // If there is a runtime context, we have to merge both labels into the same
+ // stack slot in case we store it in storage.
+ if (CompilerContext* rtc = m_context.runtimeContext())
+ {
+ _assembly.append(u256(1) << 32);
+ _assembly.append(Instruction::MUL);
+ _assembly.append(rtc->functionEntryLabel(*functionDef).toSubAssemblyTag(m_context.runtimeSub()));
+ _assembly.append(Instruction::OR);
+ }
+ }
else if (auto variable = dynamic_cast<VariableDeclaration const*>(decl))
{
solAssert(!variable->isConstant(), "");
@@ -557,7 +583,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
// lvalue context
auto variable = dynamic_cast<VariableDeclaration const*>(decl);
solAssert(
- !!variable || !m_context.isLocalVariable(variable),
+ !!variable && m_context.isLocalVariable(variable),
"Can only assign to stack variables in inline assembly."
);
unsigned size = variable->type()->sizeOnStack();
@@ -611,12 +637,25 @@ bool ContractCompiler::visit(WhileStatement const& _whileStatement)
m_breakTags.push_back(loopEnd);
m_context << loopStart;
- compileExpression(_whileStatement.condition());
- m_context << Instruction::ISZERO;
- m_context.appendConditionalJumpTo(loopEnd);
+
+ // While loops have the condition prepended
+ if (!_whileStatement.isDoWhile())
+ {
+ compileExpression(_whileStatement.condition());
+ m_context << Instruction::ISZERO;
+ m_context.appendConditionalJumpTo(loopEnd);
+ }
_whileStatement.body().accept(*this);
+ // Do-while loops have the condition appended
+ if (_whileStatement.isDoWhile())
+ {
+ compileExpression(_whileStatement.condition());
+ m_context << Instruction::ISZERO;
+ m_context.appendConditionalJumpTo(loopEnd);
+ }
+
m_context.appendJumpTo(loopStart);
m_context << loopEnd;
@@ -823,8 +862,6 @@ void ContractCompiler::appendModifierOrFunctionCode()
CompilerUtils::sizeOnStack(modifier.parameters()) +
CompilerUtils::sizeOnStack(modifier.localVariables());
codeBlock = &modifier.body();
-
- codeBlock = &modifier.body();
}
}
@@ -858,7 +895,7 @@ void ContractCompiler::compileExpression(Expression const& _expression, TypePoin
CompilerUtils(m_context).convertType(*_expression.annotation().type, *_targetType);
}
-eth::Assembly ContractCompiler::cloneRuntime()
+eth::AssemblyPointer ContractCompiler::cloneRuntime()
{
eth::Assembly a;
a << Instruction::CALLDATASIZE;
@@ -876,5 +913,5 @@ eth::Assembly ContractCompiler::cloneRuntime()
a.appendJumpI(a.errorTag());
//@todo adjust for larger return values, make this dynamic.
a << u256(0x20) << u256(0) << Instruction::RETURN;
- return a;
+ return make_shared<eth::Assembly>(a);
}
diff --git a/libsolidity/codegen/ContractCompiler.h b/libsolidity/codegen/ContractCompiler.h
index 0799a543..38c1e045 100644
--- a/libsolidity/codegen/ContractCompiler.h
+++ b/libsolidity/codegen/ContractCompiler.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -38,11 +38,12 @@ namespace solidity {
class ContractCompiler: private ASTConstVisitor
{
public:
- explicit ContractCompiler(CompilerContext& _context, bool _optimise):
+ explicit ContractCompiler(ContractCompiler* _runtimeCompiler, CompilerContext& _context, bool _optimise):
m_optimise(_optimise),
+ m_runtimeCompiler(_runtimeCompiler),
m_context(_context)
{
- m_context = CompilerContext();
+ m_context = CompilerContext(_runtimeCompiler ? &_runtimeCompiler->m_context : nullptr);
}
void compileContract(
@@ -52,7 +53,6 @@ public:
/// Compiles the constructor part of the contract.
/// @returns the identifier of the runtime sub-assembly.
size_t compileConstructor(
- CompilerContext const& _runtimeContext,
ContractDefinition const& _contract,
std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts
);
@@ -74,12 +74,13 @@ private:
/// Adds the code that is run at creation time. Should be run after exchanging the run-time context
/// with a new and initialized context. Adds the constructor code.
/// @returns the identifier of the runtime sub assembly
- size_t packIntoContractCreator(ContractDefinition const& _contract, CompilerContext const& _runtimeContext);
+ size_t packIntoContractCreator(ContractDefinition const& _contract);
/// Appends state variable initialisation and constructor code.
void appendInitAndConstructorCode(ContractDefinition const& _contract);
void appendBaseConstructor(FunctionDefinition const& _constructor);
void appendConstructor(FunctionDefinition const& _constructor);
void appendFunctionSelector(ContractDefinition const& _contract);
+ void appendCallValueCheck();
/// Creates code that unpacks the arguments for the given function represented by a vector of TypePointers.
/// From memory if @a _fromMemory is true, otherwise from call data.
/// Expects source offset on the stack, which is removed.
@@ -114,9 +115,11 @@ private:
void compileExpression(Expression const& _expression, TypePointer const& _targetType = TypePointer());
/// @returns the runtime assembly for clone contracts.
- static eth::Assembly cloneRuntime();
+ static eth::AssemblyPointer cloneRuntime();
bool const m_optimise;
+ /// Pointer to the runtime compiler in case this is a creation compiler.
+ ContractCompiler* m_runtimeCompiler = nullptr;
CompilerContext& m_context;
std::vector<eth::AssemblyItem> m_breakTags; ///< tag to jump to for a "break" statement
std::vector<eth::AssemblyItem> m_continueTags; ///< tag to jump to for a "continue" statement
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 9a096e2d..5748d818 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -99,7 +99,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
if (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
{
solAssert(CompilerUtils::freeMemoryPointer >= 0x40, "");
- solAssert(
+ solUnimplementedAssert(
!paramTypes[i]->isDynamicallySized(),
"Accessors for mapping with dynamically-sized keys not yet implemented."
);
@@ -211,7 +211,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
Token::Value op = _assignment.assignmentOperator();
if (op != Token::Assign) // compound assignment
{
- solAssert(_assignment.annotation().type->isValueType(), "Compound operators not implemented for non-value types.");
+ solUnimplementedAssert(_assignment.annotation().type->isValueType(), "Compound operators not implemented for non-value types.");
unsigned lvalueSize = m_currentLValue->sizeOnStack();
unsigned itemSize = _assignment.annotation().type->sizeOnStack();
if (lvalueSize > 0)
@@ -312,7 +312,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation)
if (!_unaryOperation.isPrefixOperation())
{
// store value for later
- solAssert(_unaryOperation.annotation().type->sizeOnStack() == 1, "Stack size != 1 not implemented.");
+ solUnimplementedAssert(_unaryOperation.annotation().type->sizeOnStack() == 1, "Stack size != 1 not implemented.");
m_context << Instruction::DUP1;
if (m_currentLValue->sizeOnStack() > 0)
for (unsigned i = 1 + m_currentLValue->sizeOnStack(); i > 0; --i)
@@ -488,6 +488,13 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
parameterSize += function.selfType()->sizeOnStack();
}
+ if (m_context.runtimeContext())
+ // We have a runtime context, so we need the creation part.
+ m_context << (u256(1) << 32) << Instruction::SWAP1 << Instruction::DIV;
+ else
+ // Extract the runtime part.
+ m_context << ((u256(1) << 32) - 1) << Instruction::AND;
+
m_context.appendJump(eth::AssemblyItem::JumpType::IntoFunction);
m_context << returnLabel;
@@ -521,8 +528,11 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
// copy the contract's code into memory
eth::Assembly const& assembly = m_context.compiledContract(contract);
utils().fetchFreeMemoryPointer();
+ // TODO we create a copy here, which is actually what we want.
+ // This should be revisited at the point where we fix
+ // https://github.com/ethereum/solidity/issues/1092
// pushes size
- eth::AssemblyItem subroutine = m_context.addSubroutine(assembly);
+ auto subroutine = m_context.addSubroutine(make_shared<eth::Assembly>(assembly));
m_context << Instruction::DUP1 << subroutine;
m_context << Instruction::DUP4 << Instruction::CODECOPY;
@@ -845,9 +855,8 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
);
if (funType->location() == FunctionType::Location::Internal)
{
- m_context << m_context.functionEntryLabel(
- dynamic_cast<FunctionDefinition const&>(funType->declaration())
- ).pushTag();
+ FunctionDefinition const& funDef = dynamic_cast<decltype(funDef)>(funType->declaration());
+ utils().pushCombinedFunctionEntryLabel(funDef);
utils().moveIntoStack(funType->selfType()->sizeOnStack(), 1);
}
else
@@ -883,7 +892,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
// us to link against it although we actually do not need it.
auto const* function = dynamic_cast<FunctionDefinition const*>(_memberAccess.annotation().referencedDeclaration);
solAssert(!!function, "Function not found in member access");
- m_context << m_context.functionEntryLabel(*function).pushTag();
+ utils().pushCombinedFunctionEntryLabel(*function);
}
}
else if (dynamic_cast<TypeType const*>(_memberAccess.annotation().type.get()))
@@ -915,10 +924,10 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
if (type.isSuper())
{
solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved.");
- m_context << m_context.superFunctionEntryLabel(
+ utils().pushCombinedFunctionEntryLabel(m_context.superFunction(
dynamic_cast<FunctionDefinition const&>(*_memberAccess.annotation().referencedDeclaration),
type.contractDefinition()
- ).pushTag();
+ ));
}
else
{
@@ -1141,7 +1150,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
break;
case DataLocation::CallData:
//@todo if we implement this, the value in calldata has to be added to the base offset
- solAssert(!arrayType.baseType()->isDynamicallySized(), "Nested arrays not yet implemented.");
+ solUnimplementedAssert(!arrayType.baseType()->isDynamicallySized(), "Nested arrays not yet implemented.");
if (arrayType.baseType()->isValueType())
CompilerUtils(m_context).loadFromMemoryDynamic(
*arrayType.baseType(),
@@ -1203,7 +1212,7 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
}
}
else if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration))
- m_context << m_context.virtualFunctionEntryLabel(*functionDef).pushTag();
+ utils().pushCombinedFunctionEntryLabel(m_context.resolveVirtualFunction(*functionDef));
else if (auto variable = dynamic_cast<VariableDeclaration const*>(declaration))
appendVariable(*variable, static_cast<Expression const&>(_identifier));
else if (auto contract = dynamic_cast<ContractDefinition const*>(declaration))
@@ -1243,7 +1252,7 @@ void ExpressionCompiler::endVisit(Literal const& _literal)
case Type::Category::StringLiteral:
break; // will be done during conversion
default:
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Only integer, boolean and string literals implemented for now."));
+ solUnimplemented("Only integer, boolean and string literals implemented for now.");
}
}
@@ -1266,6 +1275,17 @@ void ExpressionCompiler::appendCompareOperatorCode(Token::Value _operator, Type
{
if (_operator == Token::Equal || _operator == Token::NotEqual)
{
+ if (FunctionType const* funType = dynamic_cast<decltype(funType)>(&_type))
+ {
+ if (funType->location() == FunctionType::Location::Internal)
+ {
+ // We have to remove the upper bits (construction time value) because they might
+ // be "unknown" in one of the operands and not in the other.
+ m_context << ((u256(1) << 32) - 1) << Instruction::AND;
+ m_context << Instruction::SWAP1;
+ m_context << ((u256(1) << 32) - 1) << Instruction::AND;
+ }
+ }
m_context << Instruction::EQ;
if (_operator == Token::NotEqual)
m_context << Instruction::ISZERO;
@@ -1318,7 +1338,7 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token::Value _operator, Ty
bool const c_isSigned = type.isSigned();
if (_type.category() == Type::Category::FixedPoint)
- solAssert(false, "Not yet implemented - FixedPointType.");
+ solUnimplemented("Not yet implemented - FixedPointType.");
switch (_operator)
{
@@ -1372,7 +1392,7 @@ void ExpressionCompiler::appendBitOperatorCode(Token::Value _operator)
void ExpressionCompiler::appendShiftOperatorCode(Token::Value _operator)
{
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Shift operators not yet implemented."));
+ solUnimplemented("Shift operators not yet implemented.");
switch (_operator)
{
case Token::SHL:
@@ -1634,7 +1654,7 @@ void ExpressionCompiler::appendExternalFunctionCall(
void ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression)
{
- solAssert(_expectedType.isValueType(), "Not implemented for non-value types.");
+ solUnimplementedAssert(_expectedType.isValueType(), "Not implemented for non-value types.");
_expression.accept(*this);
utils().convertType(*_expression.annotation().type, _expectedType, true);
utils().storeInMemoryDynamic(_expectedType);
diff --git a/libsolidity/codegen/ExpressionCompiler.h b/libsolidity/codegen/ExpressionCompiler.h
index f4ce1fec..f08bded9 100644
--- a/libsolidity/codegen/ExpressionCompiler.h
+++ b/libsolidity/codegen/ExpressionCompiler.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp
index c1e05792..b9e141d8 100644
--- a/libsolidity/codegen/LValue.cpp
+++ b/libsolidity/codegen/LValue.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -120,7 +120,7 @@ void MemoryItem::storeValue(Type const& _sourceType, SourceLocation const&, bool
}
else
{
- solAssert(_sourceType == *m_dataType, "Conversion not implemented for assignment to memory.");
+ solUnimplementedAssert(_sourceType == *m_dataType, "Conversion not implemented for assignment to memory.");
solAssert(m_dataType->sizeOnStack() == 1, "");
if (!_move)
@@ -153,7 +153,8 @@ StorageItem::StorageItem(CompilerContext& _compilerContext, Type const& _type):
{
if (m_dataType->isValueType())
{
- solAssert(m_dataType->storageSize() == m_dataType->sizeOnStack(), "");
+ if (m_dataType->category() != Type::Category::Function)
+ solAssert(m_dataType->storageSize() == m_dataType->sizeOnStack(), "");
solAssert(m_dataType->storageSize() == 1, "Invalid storage size.");
}
}
@@ -176,27 +177,47 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const
m_context << Instruction::POP << Instruction::SLOAD;
else
{
+ bool cleaned = false;
m_context
<< Instruction::SWAP1 << Instruction::SLOAD << Instruction::SWAP1
<< u256(0x100) << Instruction::EXP << Instruction::SWAP1 << Instruction::DIV;
if (m_dataType->category() == Type::Category::FixedPoint)
// implementation should be very similar to the integer case.
- solAssert(false, "Not yet implemented - FixedPointType.");
+ solUnimplemented("Not yet implemented - FixedPointType.");
if (m_dataType->category() == Type::Category::FixedBytes)
+ {
m_context << (u256(0x1) << (256 - 8 * m_dataType->storageBytes())) << Instruction::MUL;
+ cleaned = true;
+ }
else if (
m_dataType->category() == Type::Category::Integer &&
dynamic_cast<IntegerType const&>(*m_dataType).isSigned()
)
+ {
m_context << u256(m_dataType->storageBytes() - 1) << Instruction::SIGNEXTEND;
- else
+ cleaned = true;
+ }
+ else if (FunctionType const* fun = dynamic_cast<decltype(fun)>(m_dataType))
+ {
+ if (fun->location() == FunctionType::Location::External)
+ {
+ CompilerUtils(m_context).splitExternalFunctionType(false);
+ cleaned = true;
+ }
+ }
+ if (!cleaned)
+ {
+ solAssert(m_dataType->sizeOnStack() == 1, "");
m_context << ((u256(0x1) << (8 * m_dataType->storageBytes())) - 1) << Instruction::AND;
+ }
}
}
void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _location, bool _move) const
{
CompilerUtils utils(m_context);
+ solAssert(m_dataType, "");
+
// stack: value storage_key storage_offset
if (m_dataType->isValueType())
{
@@ -204,10 +225,16 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
solAssert(m_dataType->storageBytes() > 0, "Invalid storage bytes size.");
if (m_dataType->storageBytes() == 32)
{
+ solAssert(m_dataType->sizeOnStack() == 1, "Invalid stack size.");
// offset should be zero
m_context << Instruction::POP;
if (!_move)
m_context << Instruction::DUP2 << Instruction::SWAP1;
+
+ m_context << Instruction::SWAP1;
+ utils.convertType(_sourceType, *m_dataType, true);
+ m_context << Instruction::SWAP1;
+
m_context << Instruction::SSTORE;
}
else
@@ -222,28 +249,39 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
m_context
<< Instruction::DUP2 << ((u256(1) << (8 * m_dataType->storageBytes())) - 1)
<< Instruction::MUL;
- m_context << Instruction::NOT << Instruction::AND;
- // stack: value storage_ref multiplier cleared_value
- m_context
- << Instruction::SWAP1 << Instruction::DUP4;
+ m_context << Instruction::NOT << Instruction::AND << Instruction::SWAP1;
+ // stack: value storage_ref cleared_value multiplier
+ utils.copyToStackTop(3 + m_dataType->sizeOnStack(), m_dataType->sizeOnStack());
// stack: value storage_ref cleared_value multiplier value
- if (m_dataType->category() == Type::Category::FixedBytes)
+ if (FunctionType const* fun = dynamic_cast<decltype(fun)>(m_dataType))
+ {
+ solAssert(_sourceType == *m_dataType, "function item stored but target is not equal to source");
+ if (fun->location() == FunctionType::Location::External)
+ // Combine the two-item function type into a single stack slot.
+ utils.combineExternalFunctionType(false);
+ else
+ m_context <<
+ ((u256(1) << (8 * m_dataType->storageBytes())) - 1) <<
+ Instruction::AND;
+ }
+ else if (m_dataType->category() == Type::Category::FixedBytes)
+ {
+ solAssert(_sourceType.category() == Type::Category::FixedBytes, "source not fixed bytes");
m_context
<< (u256(0x1) << (256 - 8 * dynamic_cast<FixedBytesType const&>(*m_dataType).numBytes()))
<< Instruction::SWAP1 << Instruction::DIV;
+ }
else
+ {
+ solAssert(m_dataType->sizeOnStack() == 1, "Invalid stack size for opaque type.");
// remove the higher order bits
- m_context
- << (u256(1) << (8 * (32 - m_dataType->storageBytes())))
- << Instruction::SWAP1
- << Instruction::DUP2
- << Instruction::MUL
- << Instruction::DIV;
+ utils.convertType(_sourceType, *m_dataType, true, true);
+ }
m_context << Instruction::MUL << Instruction::OR;
// stack: value storage_ref updated_value
m_context << Instruction::SWAP1 << Instruction::SSTORE;
if (_move)
- m_context << Instruction::POP;
+ utils.popStackElement(*m_dataType);
}
}
else
diff --git a/libsolidity/codegen/LValue.h b/libsolidity/codegen/LValue.h
index a2f979db..f8b68362 100644
--- a/libsolidity/codegen/LValue.h
+++ b/libsolidity/codegen/LValue.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/formal/Why3Translator.cpp b/libsolidity/formal/Why3Translator.cpp
index 813fa3ab..2903a4e3 100644
--- a/libsolidity/formal/Why3Translator.cpp
+++ b/libsolidity/formal/Why3Translator.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -410,6 +410,16 @@ bool Why3Translator::visit(WhileStatement const& _node)
{
addSourceFromDocStrings(_node.annotation());
+ // Why3 does not appear to support do-while loops,
+ // so we will simulate them by performing a while
+ // loop with the body prepended once.
+
+ if (_node.isDoWhile())
+ {
+ visitIndentedUnlessBlock(_node.body());
+ newLine();
+ }
+
add("while ");
_node.condition().accept(*this);
newLine();
diff --git a/libsolidity/formal/Why3Translator.h b/libsolidity/formal/Why3Translator.h
index 4fdac385..03f3bf9c 100644
--- a/libsolidity/formal/Why3Translator.h
+++ b/libsolidity/formal/Why3Translator.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/grammar.txt b/libsolidity/grammar.txt
deleted file mode 100644
index d84ee10c..00000000
--- a/libsolidity/grammar.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-SourceUnit = (PragmaDirective | ImportDirective | ContractDefinition)*
-
-// Pragma actually parses anything up to the trailing ';' to be fully forward-compatible.
-PragmaDirective = 'pragma' Identifier Expression ';'
-
-ImportDirective = 'import' StringLiteral ('as' Identifier)? ';'
- | 'import' ('*' | Identifier) ('as' Identifier)? 'from' StringLiteral ';'
- | 'import' '{' Identifier ('as' Identifier)? ( ',' Identifier ('as' Identifier)? )* '}' 'from' StringLiteral ';'
-
-ContractDefinition = ( 'contract' | 'library' ) Identifier
- ( 'is' InheritanceSpecifier (',' InheritanceSpecifier )* )?
- '{' ContractPart* '}'
-
-ContractPart = StateVariableDeclaration | UsingForDeclaration
- | StructDefinition | ModifierDefinition | FunctionDefinition | EventDefinition | EnumDefinition
-
-InheritanceSpecifier = Identifier ( '(' Expression ( ',' Expression )* ')' )?
-
-StateVariableDeclaration = TypeName ( 'public' | 'internal' | 'private' )? Identifier ('=' Expression)? ';'
-UsingForDeclaration = 'using' Identifier 'for' ('*' | TypeName) ';'
-StructDefinition = 'struct' Identifier '{'
- ( VariableDeclaration ';' (VariableDeclaration ';')* )? '}'
-ModifierDefinition = 'modifier' Identifier ParameterList? Block
-FunctionDefinition = 'function' Identifier? ParameterList
- ( FunctionCall | Identifier | 'constant' | 'external' | 'public' | 'internal' | 'private' )*
- ( 'returns' ParameterList )? Block
-EventDefinition = 'event' Identifier IndexedParameterList 'anonymous'? ';'
-
-EnumValue = Identifier
-EnumDefinition = 'enum' Identifier '{' EnumValue? (',' EnumValue)* '}'
-
-IndexedParameterList = '(' ( TypeName 'indexed'? Identifier? (',' TypeName 'indexed'? Identifier?)* )? ')'
-ParameterList = '(' ( TypeName Identifier? (',' TypeName Identifier?)* )? ')'
-
-// semantic restriction: mappings and structs (recursively) containing mappings
-// are not allowed in argument lists
-VariableDeclaration = TypeName Identifier
-TypeName = ElementaryTypeName | Identifier StorageLocation? | Mapping | ArrayTypeName
-Mapping = 'mapping' '(' ElementaryTypeName '=>' TypeName ')'
-ArrayTypeName = TypeName StorageLocation? '[' Expression? ']'
-StorageLocation = 'memory' | 'storage'
-
-Block = '{' Statement* '}'
-Statement = IfStatement | WhileStatement | ForStatement | Block |
- ( PlaceholderStatement | Continue | Break | Return |
- Throw | SimpleStatement ) ';'
-
-ExpressionStatement = Expression
-IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )?
-WhileStatement = 'while' '(' Expression ')' Statement
-PlaceholderStatement = '_'
-SimpleStatement = VariableDefinition | ExpressionStatement
-ForStatement = 'for' '(' (SimpleStatement)? ';' (Expression)? ';' (ExpressionStatement)? ')' Statement
-Continue = 'continue'
-Break = 'break'
-Return = 'return' Expression?
-Throw = 'throw'
-VariableDefinition = VariableDeclaration ( '=' Expression )?
-
-// Precedence by order (see github.com/ethereum/solidity/pull/732)
-Expression =
- ( Expression ('++' | '--') | FunctionCall | IndexAccess | MemberAccess | '(' Expression ')' )
- | ('!' | '~' | 'delete' | '++' | '--' | '+' | '-') Expression
- | Expression '**' Expression
- | Expression ('*' | '/' | '%') Expression
- | Expression ('+' | '-') Expression
- | Expression ('<<' | '>>' | '>>>')
- | Expression '&' Expression
- | Expression '^' Expression
- | Expression '|' Expression
- | Expression ('<' | '>' | '<=' | '>=') Expression
- | Expression ('==' | '!=') Expression
- | Expression '&&' Expression
- | Expression '||' Expression
- | Expression '?' Expression ':' Expression
- | Expression ('=' | '|=' | '^=' | '&=' | '<<=' | '>>=' | '+=' | '-=' | '*=' | '/=' | '%=') Expression
- | Expression? (',' Expression)
- | PrimaryExpression
-
-PrimaryExpression = Identifier | BooleanLiteral | NumberLiteral | HexLiteral | StringLiteral
-
-FunctionCall = ( PrimaryExpression | NewExpression | TypeName ) ( ( '.' Identifier ) | ( '[' Expression ']' ) )* '(' Expression? ( ',' Expression )* ')'
-NewExpression = 'new' Identifier
-MemberAccess = Expression '.' Identifier
-IndexAccess = Expression '[' Expression? ']'
-
-BooleanLiteral = 'true' | 'false'
-NumberLiteral = '0x'? [0-9]+ (' ' NumberUnit)?
-NumberUnit = 'wei' | 'szabo' | 'finney' | 'ether'
- | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years'
-HexLiteral = 'hex' ('"' ([0-9a-fA-F]{2})* '"' | '\'' ([0-9a-fA-F]{2})* '\'')
-StringLiteral = '"' ([^"\r\n\\] | '\\' .)* '"'
-Identifier = [a-zA-Z_] [a-zA-Z_0-9]*
-
-ElementaryTypeName = 'address' | 'bool' | 'string' | 'var'
- | Int | Uint | Byte | Fixed | Ufixed
-
-Int = 'int' | 'int8' | 'int16' | 'int24' | 'int32' | 'int40' | 'int48' | 'int56' | 'int64' | 'int72' | 'int80' | 'int88' | 'int96' | 'int104' | 'int112' | 'int120' | 'int128' | 'int136' | 'int144' | 'int152' | 'int160' | 'int168' | 'int176' | 'int184' | 'int192' | 'int200' | 'int208' | 'int216' | 'int224' | 'int232' | 'int240' | 'int248' | 'int256'
-
-Uint = 'uint' | 'uint8' | 'uint16' | 'uint24' | 'uint32' | 'uint40' | 'uint48' | 'uint56' | 'uint64' | 'uint72' | 'uint80' | 'uint88' | 'uint96' | 'uint104' | 'uint112' | 'uint120' | 'uint128' | 'uint136' | 'uint144' | 'uint152' | 'uint160' | 'uint168' | 'uint176' | 'uint184' | 'uint192' | 'uint200' | 'uint208' | 'uint216' | 'uint224' | 'uint232' | 'uint240' | 'uint248' | 'uint256'
-
-Byte = 'byte' | 'bytes' | 'bytes1' | 'bytes2' | 'bytes3' | 'bytes4' | 'bytes5' | 'bytes6' | 'bytes7' | 'bytes8' | 'bytes9' | 'bytes10' | 'bytes11' | 'bytes12' | 'bytes13' | 'bytes14' | 'bytes15' | 'bytes16' | 'bytes17' | 'bytes18' | 'bytes19' | 'bytes20' | 'bytes21' | 'bytes22' | 'bytes23' | 'bytes24' | 'bytes25' | 'bytes26' | 'bytes27' | 'bytes28' | 'bytes29' | 'bytes30' | 'bytes31' | 'bytes32'
-
-Fixed = 'fixed' | 'fixed0x8' | 'fixed0x16' | 'fixed0x24' | 'fixed0x32' | 'fixed0x40' | 'fixed0x48' | 'fixed0x56' | 'fixed0x64' | 'fixed0x72' | 'fixed0x80' | 'fixed0x88' | 'fixed0x96' | 'fixed0x104' | 'fixed0x112' | 'fixed0x120' | 'fixed0x128' | 'fixed0x136' | 'fixed0x144' | 'fixed0x152' | 'fixed0x160' | 'fixed0x168' | 'fixed0x176' | 'fixed0x184' | 'fixed0x192' | 'fixed0x200' | 'fixed0x208' | 'fixed0x216' | 'fixed0x224' | 'fixed0x232' | 'fixed0x240' | 'fixed0x248' | 'fixed0x256' | 'fixed8x8' | 'fixed8x16' | 'fixed8x24' | 'fixed8x32' | 'fixed8x40' | 'fixed8x48' | 'fixed8x56' | 'fixed8x64' | 'fixed8x72' | 'fixed8x80' | 'fixed8x88' | 'fixed8x96' | 'fixed8x104' | 'fixed8x112' | 'fixed8x120' | 'fixed8x128' | 'fixed8x136' | 'fixed8x144' | 'fixed8x152' | 'fixed8x160' | 'fixed8x168' | 'fixed8x176' | 'fixed8x184' | 'fixed8x192' | 'fixed8x200' | 'fixed8x208' | 'fixed8x216' | 'fixed8x224' | 'fixed8x232' | 'fixed8x240' | 'fixed8x248' | 'fixed16x8' | 'fixed16x16' | 'fixed16x24' | 'fixed16x32' | 'fixed16x40' | 'fixed16x48' | 'fixed16x56' | 'fixed16x64' | 'fixed16x72' | 'fixed16x80' | 'fixed16x88' | 'fixed16x96' | 'fixed16x104' | 'fixed16x112' | 'fixed16x120' | 'fixed16x128' | 'fixed16x136' | 'fixed16x144' | 'fixed16x152' | 'fixed16x160' | 'fixed16x168' | 'fixed16x176' | 'fixed16x184' | 'fixed16x192' | 'fixed16x200' | 'fixed16x208' | 'fixed16x216' | 'fixed16x224' | 'fixed16x232' | 'fixed16x240' | 'fixed24x8' | 'fixed24x16' | 'fixed24x24' | 'fixed24x32' | 'fixed24x40' | 'fixed24x48' | 'fixed24x56' | 'fixed24x64' | 'fixed24x72' | 'fixed24x80' | 'fixed24x88' | 'fixed24x96' | 'fixed24x104' | 'fixed24x112' | 'fixed24x120' | 'fixed24x128' | 'fixed24x136' | 'fixed24x144' | 'fixed24x152' | 'fixed24x160' | 'fixed24x168' | 'fixed24x176' | 'fixed24x184' | 'fixed24x192' | 'fixed24x200' | 'fixed24x208' | 'fixed24x216' | 'fixed24x224' | 'fixed24x232' | 'fixed32x8' | 'fixed32x16' | 'fixed32x24' | 'fixed32x32' | 'fixed32x40' | 'fixed32x48' | 'fixed32x56' | 'fixed32x64' | 'fixed32x72' | 'fixed32x80' | 'fixed32x88' | 'fixed32x96' | 'fixed32x104' | 'fixed32x112' | 'fixed32x120' | 'fixed32x128' | 'fixed32x136' | 'fixed32x144' | 'fixed32x152' | 'fixed32x160' | 'fixed32x168' | 'fixed32x176' | 'fixed32x184' | 'fixed32x192' | 'fixed32x200' | 'fixed32x208' | 'fixed32x216' | 'fixed32x224' | 'fixed40x8' | 'fixed40x16' | 'fixed40x24' | 'fixed40x32' | 'fixed40x40' | 'fixed40x48' | 'fixed40x56' | 'fixed40x64' | 'fixed40x72' | 'fixed40x80' | 'fixed40x88' | 'fixed40x96' | 'fixed40x104' | 'fixed40x112' | 'fixed40x120' | 'fixed40x128' | 'fixed40x136' | 'fixed40x144' | 'fixed40x152' | 'fixed40x160' | 'fixed40x168' | 'fixed40x176' | 'fixed40x184' | 'fixed40x192' | 'fixed40x200' | 'fixed40x208' | 'fixed40x216' | 'fixed48x8' | 'fixed48x16' | 'fixed48x24' | 'fixed48x32' | 'fixed48x40' | 'fixed48x48' | 'fixed48x56' | 'fixed48x64' | 'fixed48x72' | 'fixed48x80' | 'fixed48x88' | 'fixed48x96' | 'fixed48x104' | 'fixed48x112' | 'fixed48x120' | 'fixed48x128' | 'fixed48x136' | 'fixed48x144' | 'fixed48x152' | 'fixed48x160' | 'fixed48x168' | 'fixed48x176' | 'fixed48x184' | 'fixed48x192' | 'fixed48x200' | 'fixed48x208' | 'fixed56x8' | 'fixed56x16' | 'fixed56x24' | 'fixed56x32' | 'fixed56x40' | 'fixed56x48' | 'fixed56x56' | 'fixed56x64' | 'fixed56x72' | 'fixed56x80' | 'fixed56x88' | 'fixed56x96' | 'fixed56x104' | 'fixed56x112' | 'fixed56x120' | 'fixed56x128' | 'fixed56x136' | 'fixed56x144' | 'fixed56x152' | 'fixed56x160' | 'fixed56x168' | 'fixed56x176' | 'fixed56x184' | 'fixed56x192' | 'fixed56x200' | 'fixed64x8' | 'fixed64x16' | 'fixed64x24' | 'fixed64x32' | 'fixed64x40' | 'fixed64x48' | 'fixed64x56' | 'fixed64x64' | 'fixed64x72' | 'fixed64x80' | 'fixed64x88' | 'fixed64x96' | 'fixed64x104' | 'fixed64x112' | 'fixed64x120' | 'fixed64x128' | 'fixed64x136' | 'fixed64x144' | 'fixed64x152' | 'fixed64x160' | 'fixed64x168' | 'fixed64x176' | 'fixed64x184' | 'fixed64x192' | 'fixed72x8' | 'fixed72x16' | 'fixed72x24' | 'fixed72x32' | 'fixed72x40' | 'fixed72x48' | 'fixed72x56' | 'fixed72x64' | 'fixed72x72' | 'fixed72x80' | 'fixed72x88' | 'fixed72x96' | 'fixed72x104' | 'fixed72x112' | 'fixed72x120' | 'fixed72x128' | 'fixed72x136' | 'fixed72x144' | 'fixed72x152' | 'fixed72x160' | 'fixed72x168' | 'fixed72x176' | 'fixed72x184' | 'fixed80x8' | 'fixed80x16' | 'fixed80x24' | 'fixed80x32' | 'fixed80x40' | 'fixed80x48' | 'fixed80x56' | 'fixed80x64' | 'fixed80x72' | 'fixed80x80' | 'fixed80x88' | 'fixed80x96' | 'fixed80x104' | 'fixed80x112' | 'fixed80x120' | 'fixed80x128' | 'fixed80x136' | 'fixed80x144' | 'fixed80x152' | 'fixed80x160' | 'fixed80x168' | 'fixed80x176' | 'fixed88x8' | 'fixed88x16' | 'fixed88x24' | 'fixed88x32' | 'fixed88x40' | 'fixed88x48' | 'fixed88x56' | 'fixed88x64' | 'fixed88x72' | 'fixed88x80' | 'fixed88x88' | 'fixed88x96' | 'fixed88x104' | 'fixed88x112' | 'fixed88x120' | 'fixed88x128' | 'fixed88x136' | 'fixed88x144' | 'fixed88x152' | 'fixed88x160' | 'fixed88x168' | 'fixed96x8' | 'fixed96x16' | 'fixed96x24' | 'fixed96x32' | 'fixed96x40' | 'fixed96x48' | 'fixed96x56' | 'fixed96x64' | 'fixed96x72' | 'fixed96x80' | 'fixed96x88' | 'fixed96x96' | 'fixed96x104' | 'fixed96x112' | 'fixed96x120' | 'fixed96x128' | 'fixed96x136' | 'fixed96x144' | 'fixed96x152' | 'fixed96x160' | 'fixed104x8' | 'fixed104x16' | 'fixed104x24' | 'fixed104x32' | 'fixed104x40' | 'fixed104x48' | 'fixed104x56' | 'fixed104x64' | 'fixed104x72' | 'fixed104x80' | 'fixed104x88' | 'fixed104x96' | 'fixed104x104' | 'fixed104x112' | 'fixed104x120' | 'fixed104x128' | 'fixed104x136' | 'fixed104x144' | 'fixed104x152' | 'fixed112x8' | 'fixed112x16' | 'fixed112x24' | 'fixed112x32' | 'fixed112x40' | 'fixed112x48' | 'fixed112x56' | 'fixed112x64' | 'fixed112x72' | 'fixed112x80' | 'fixed112x88' | 'fixed112x96' | 'fixed112x104' | 'fixed112x112' | 'fixed112x120' | 'fixed112x128' | 'fixed112x136' | 'fixed112x144' | 'fixed120x8' | 'fixed120x16' | 'fixed120x24' | 'fixed120x32' | 'fixed120x40' | 'fixed120x48' | 'fixed120x56' | 'fixed120x64' | 'fixed120x72' | 'fixed120x80' | 'fixed120x88' | 'fixed120x96' | 'fixed120x104' | 'fixed120x112' | 'fixed120x120' | 'fixed120x128' | 'fixed120x136' | 'fixed128x8' | 'fixed128x16' | 'fixed128x24' | 'fixed128x32' | 'fixed128x40' | 'fixed128x48' | 'fixed128x56' | 'fixed128x64' | 'fixed128x72' | 'fixed128x80' | 'fixed128x88' | 'fixed128x96' | 'fixed128x104' | 'fixed128x112' | 'fixed128x120' | 'fixed128x128' | 'fixed136x8' | 'fixed136x16' | 'fixed136x24' | 'fixed136x32' | 'fixed136x40' | 'fixed136x48' | 'fixed136x56' | 'fixed136x64' | 'fixed136x72' | 'fixed136x80' | 'fixed136x88' | 'fixed136x96' | 'fixed136x104' | 'fixed136x112' | 'fixed136x120' | 'fixed144x8' | 'fixed144x16' | 'fixed144x24' | 'fixed144x32' | 'fixed144x40' | 'fixed144x48' | 'fixed144x56' | 'fixed144x64' | 'fixed144x72' | 'fixed144x80' | 'fixed144x88' | 'fixed144x96' | 'fixed144x104' | 'fixed144x112' | 'fixed152x8' | 'fixed152x16' | 'fixed152x24' | 'fixed152x32' | 'fixed152x40' | 'fixed152x48' | 'fixed152x56' | 'fixed152x64' | 'fixed152x72' | 'fixed152x80' | 'fixed152x88' | 'fixed152x96' | 'fixed152x104' | 'fixed160x8' | 'fixed160x16' | 'fixed160x24' | 'fixed160x32' | 'fixed160x40' | 'fixed160x48' | 'fixed160x56' | 'fixed160x64' | 'fixed160x72' | 'fixed160x80' | 'fixed160x88' | 'fixed160x96' | 'fixed168x8' | 'fixed168x16' | 'fixed168x24' | 'fixed168x32' | 'fixed168x40' | 'fixed168x48' | 'fixed168x56' | 'fixed168x64' | 'fixed168x72' | 'fixed168x80' | 'fixed168x88' | 'fixed176x8' | 'fixed176x16' | 'fixed176x24' | 'fixed176x32' | 'fixed176x40' | 'fixed176x48' | 'fixed176x56' | 'fixed176x64' | 'fixed176x72' | 'fixed176x80' | 'fixed184x8' | 'fixed184x16' | 'fixed184x24' | 'fixed184x32' | 'fixed184x40' | 'fixed184x48' | 'fixed184x56' | 'fixed184x64' | 'fixed184x72' | 'fixed192x8' | 'fixed192x16' | 'fixed192x24' | 'fixed192x32' | 'fixed192x40' | 'fixed192x48' | 'fixed192x56' | 'fixed192x64' | 'fixed200x8' | 'fixed200x16' | 'fixed200x24' | 'fixed200x32' | 'fixed200x40' | 'fixed200x48' | 'fixed200x56' | 'fixed208x8' | 'fixed208x16' | 'fixed208x24' | 'fixed208x32' | 'fixed208x40' | 'fixed208x48' | 'fixed216x8' | 'fixed216x16' | 'fixed216x24' | 'fixed216x32' | 'fixed216x40' | 'fixed224x8' | 'fixed224x16' | 'fixed224x24' | 'fixed224x32' | 'fixed232x8' | 'fixed232x16' | 'fixed232x24' | 'fixed240x8' | 'fixed240x16' | 'fixed248x8'
-
-Ufixed = 'ufixed' | 'ufixed0x8' | 'ufixed0x16' | 'ufixed0x24' | 'ufixed0x32' | 'ufixed0x40' | 'ufixed0x48' | 'ufixed0x56' | 'ufixed0x64' | 'ufixed0x72' | 'ufixed0x80' | 'ufixed0x88' | 'ufixed0x96' | 'ufixed0x104' | 'ufixed0x112' | 'ufixed0x120' | 'ufixed0x128' | 'ufixed0x136' | 'ufixed0x144' | 'ufixed0x152' | 'ufixed0x160' | 'ufixed0x168' | 'ufixed0x176' | 'ufixed0x184' | 'ufixed0x192' | 'ufixed0x200' | 'ufixed0x208' | 'ufixed0x216' | 'ufixed0x224' | 'ufixed0x232' | 'ufixed0x240' | 'ufixed0x248' | 'ufixed0x256' | 'ufixed8x8' | 'ufixed8x16' | 'ufixed8x24' | 'ufixed8x32' | 'ufixed8x40' | 'ufixed8x48' | 'ufixed8x56' | 'ufixed8x64' | 'ufixed8x72' | 'ufixed8x80' | 'ufixed8x88' | 'ufixed8x96' | 'ufixed8x104' | 'ufixed8x112' | 'ufixed8x120' | 'ufixed8x128' | 'ufixed8x136' | 'ufixed8x144' | 'ufixed8x152' | 'ufixed8x160' | 'ufixed8x168' | 'ufixed8x176' | 'ufixed8x184' | 'ufixed8x192' | 'ufixed8x200' | 'ufixed8x208' | 'ufixed8x216' | 'ufixed8x224' | 'ufixed8x232' | 'ufixed8x240' | 'ufixed8x248' | 'ufixed16x8' | 'ufixed16x16' | 'ufixed16x24' | 'ufixed16x32' | 'ufixed16x40' | 'ufixed16x48' | 'ufixed16x56' | 'ufixed16x64' | 'ufixed16x72' | 'ufixed16x80' | 'ufixed16x88' | 'ufixed16x96' | 'ufixed16x104' | 'ufixed16x112' | 'ufixed16x120' | 'ufixed16x128' | 'ufixed16x136' | 'ufixed16x144' | 'ufixed16x152' | 'ufixed16x160' | 'ufixed16x168' | 'ufixed16x176' | 'ufixed16x184' | 'ufixed16x192' | 'ufixed16x200' | 'ufixed16x208' | 'ufixed16x216' | 'ufixed16x224' | 'ufixed16x232' | 'ufixed16x240' | 'ufixed24x8' | 'ufixed24x16' | 'ufixed24x24' | 'ufixed24x32' | 'ufixed24x40' | 'ufixed24x48' | 'ufixed24x56' | 'ufixed24x64' | 'ufixed24x72' | 'ufixed24x80' | 'ufixed24x88' | 'ufixed24x96' | 'ufixed24x104' | 'ufixed24x112' | 'ufixed24x120' | 'ufixed24x128' | 'ufixed24x136' | 'ufixed24x144' | 'ufixed24x152' | 'ufixed24x160' | 'ufixed24x168' | 'ufixed24x176' | 'ufixed24x184' | 'ufixed24x192' | 'ufixed24x200' | 'ufixed24x208' | 'ufixed24x216' | 'ufixed24x224' | 'ufixed24x232' | 'ufixed32x8' | 'ufixed32x16' | 'ufixed32x24' | 'ufixed32x32' | 'ufixed32x40' | 'ufixed32x48' | 'ufixed32x56' | 'ufixed32x64' | 'ufixed32x72' | 'ufixed32x80' | 'ufixed32x88' | 'ufixed32x96' | 'ufixed32x104' | 'ufixed32x112' | 'ufixed32x120' | 'ufixed32x128' | 'ufixed32x136' | 'ufixed32x144' | 'ufixed32x152' | 'ufixed32x160' | 'ufixed32x168' | 'ufixed32x176' | 'ufixed32x184' | 'ufixed32x192' | 'ufixed32x200' | 'ufixed32x208' | 'ufixed32x216' | 'ufixed32x224' | 'ufixed40x8' | 'ufixed40x16' | 'ufixed40x24' | 'ufixed40x32' | 'ufixed40x40' | 'ufixed40x48' | 'ufixed40x56' | 'ufixed40x64' | 'ufixed40x72' | 'ufixed40x80' | 'ufixed40x88' | 'ufixed40x96' | 'ufixed40x104' | 'ufixed40x112' | 'ufixed40x120' | 'ufixed40x128' | 'ufixed40x136' | 'ufixed40x144' | 'ufixed40x152' | 'ufixed40x160' | 'ufixed40x168' | 'ufixed40x176' | 'ufixed40x184' | 'ufixed40x192' | 'ufixed40x200' | 'ufixed40x208' | 'ufixed40x216' | 'ufixed48x8' | 'ufixed48x16' | 'ufixed48x24' | 'ufixed48x32' | 'ufixed48x40' | 'ufixed48x48' | 'ufixed48x56' | 'ufixed48x64' | 'ufixed48x72' | 'ufixed48x80' | 'ufixed48x88' | 'ufixed48x96' | 'ufixed48x104' | 'ufixed48x112' | 'ufixed48x120' | 'ufixed48x128' | 'ufixed48x136' | 'ufixed48x144' | 'ufixed48x152' | 'ufixed48x160' | 'ufixed48x168' | 'ufixed48x176' | 'ufixed48x184' | 'ufixed48x192' | 'ufixed48x200' | 'ufixed48x208' | 'ufixed56x8' | 'ufixed56x16' | 'ufixed56x24' | 'ufixed56x32' | 'ufixed56x40' | 'ufixed56x48' | 'ufixed56x56' | 'ufixed56x64' | 'ufixed56x72' | 'ufixed56x80' | 'ufixed56x88' | 'ufixed56x96' | 'ufixed56x104' | 'ufixed56x112' | 'ufixed56x120' | 'ufixed56x128' | 'ufixed56x136' | 'ufixed56x144' | 'ufixed56x152' | 'ufixed56x160' | 'ufixed56x168' | 'ufixed56x176' | 'ufixed56x184' | 'ufixed56x192' | 'ufixed56x200' | 'ufixed64x8' | 'ufixed64x16' | 'ufixed64x24' | 'ufixed64x32' | 'ufixed64x40' | 'ufixed64x48' | 'ufixed64x56' | 'ufixed64x64' | 'ufixed64x72' | 'ufixed64x80' | 'ufixed64x88' | 'ufixed64x96' | 'ufixed64x104' | 'ufixed64x112' | 'ufixed64x120' | 'ufixed64x128' | 'ufixed64x136' | 'ufixed64x144' | 'ufixed64x152' | 'ufixed64x160' | 'ufixed64x168' | 'ufixed64x176' | 'ufixed64x184' | 'ufixed64x192' | 'ufixed72x8' | 'ufixed72x16' | 'ufixed72x24' | 'ufixed72x32' | 'ufixed72x40' | 'ufixed72x48' | 'ufixed72x56' | 'ufixed72x64' | 'ufixed72x72' | 'ufixed72x80' | 'ufixed72x88' | 'ufixed72x96' | 'ufixed72x104' | 'ufixed72x112' | 'ufixed72x120' | 'ufixed72x128' | 'ufixed72x136' | 'ufixed72x144' | 'ufixed72x152' | 'ufixed72x160' | 'ufixed72x168' | 'ufixed72x176' | 'ufixed72x184' | 'ufixed80x8' | 'ufixed80x16' | 'ufixed80x24' | 'ufixed80x32' | 'ufixed80x40' | 'ufixed80x48' | 'ufixed80x56' | 'ufixed80x64' | 'ufixed80x72' | 'ufixed80x80' | 'ufixed80x88' | 'ufixed80x96' | 'ufixed80x104' | 'ufixed80x112' | 'ufixed80x120' | 'ufixed80x128' | 'ufixed80x136' | 'ufixed80x144' | 'ufixed80x152' | 'ufixed80x160' | 'ufixed80x168' | 'ufixed80x176' | 'ufixed88x8' | 'ufixed88x16' | 'ufixed88x24' | 'ufixed88x32' | 'ufixed88x40' | 'ufixed88x48' | 'ufixed88x56' | 'ufixed88x64' | 'ufixed88x72' | 'ufixed88x80' | 'ufixed88x88' | 'ufixed88x96' | 'ufixed88x104' | 'ufixed88x112' | 'ufixed88x120' | 'ufixed88x128' | 'ufixed88x136' | 'ufixed88x144' | 'ufixed88x152' | 'ufixed88x160' | 'ufixed88x168' | 'ufixed96x8' | 'ufixed96x16' | 'ufixed96x24' | 'ufixed96x32' | 'ufixed96x40' | 'ufixed96x48' | 'ufixed96x56' | 'ufixed96x64' | 'ufixed96x72' | 'ufixed96x80' | 'ufixed96x88' | 'ufixed96x96' | 'ufixed96x104' | 'ufixed96x112' | 'ufixed96x120' | 'ufixed96x128' | 'ufixed96x136' | 'ufixed96x144' | 'ufixed96x152' | 'ufixed96x160' | 'ufixed104x8' | 'ufixed104x16' | 'ufixed104x24' | 'ufixed104x32' | 'ufixed104x40' | 'ufixed104x48' | 'ufixed104x56' | 'ufixed104x64' | 'ufixed104x72' | 'ufixed104x80' | 'ufixed104x88' | 'ufixed104x96' | 'ufixed104x104' | 'ufixed104x112' | 'ufixed104x120' | 'ufixed104x128' | 'ufixed104x136' | 'ufixed104x144' | 'ufixed104x152' | 'ufixed112x8' | 'ufixed112x16' | 'ufixed112x24' | 'ufixed112x32' | 'ufixed112x40' | 'ufixed112x48' | 'ufixed112x56' | 'ufixed112x64' | 'ufixed112x72' | 'ufixed112x80' | 'ufixed112x88' | 'ufixed112x96' | 'ufixed112x104' | 'ufixed112x112' | 'ufixed112x120' | 'ufixed112x128' | 'ufixed112x136' | 'ufixed112x144' | 'ufixed120x8' | 'ufixed120x16' | 'ufixed120x24' | 'ufixed120x32' | 'ufixed120x40' | 'ufixed120x48' | 'ufixed120x56' | 'ufixed120x64' | 'ufixed120x72' | 'ufixed120x80' | 'ufixed120x88' | 'ufixed120x96' | 'ufixed120x104' | 'ufixed120x112' | 'ufixed120x120' | 'ufixed120x128' | 'ufixed120x136' | 'ufixed128x8' | 'ufixed128x16' | 'ufixed128x24' | 'ufixed128x32' | 'ufixed128x40' | 'ufixed128x48' | 'ufixed128x56' | 'ufixed128x64' | 'ufixed128x72' | 'ufixed128x80' | 'ufixed128x88' | 'ufixed128x96' | 'ufixed128x104' | 'ufixed128x112' | 'ufixed128x120' | 'ufixed128x128' | 'ufixed136x8' | 'ufixed136x16' | 'ufixed136x24' | 'ufixed136x32' | 'ufixed136x40' | 'ufixed136x48' | 'ufixed136x56' | 'ufixed136x64' | 'ufixed136x72' | 'ufixed136x80' | 'ufixed136x88' | 'ufixed136x96' | 'ufixed136x104' | 'ufixed136x112' | 'ufixed136x120' | 'ufixed144x8' | 'ufixed144x16' | 'ufixed144x24' | 'ufixed144x32' | 'ufixed144x40' | 'ufixed144x48' | 'ufixed144x56' | 'ufixed144x64' | 'ufixed144x72' | 'ufixed144x80' | 'ufixed144x88' | 'ufixed144x96' | 'ufixed144x104' | 'ufixed144x112' | 'ufixed152x8' | 'ufixed152x16' | 'ufixed152x24' | 'ufixed152x32' | 'ufixed152x40' | 'ufixed152x48' | 'ufixed152x56' | 'ufixed152x64' | 'ufixed152x72' | 'ufixed152x80' | 'ufixed152x88' | 'ufixed152x96' | 'ufixed152x104' | 'ufixed160x8' | 'ufixed160x16' | 'ufixed160x24' | 'ufixed160x32' | 'ufixed160x40' | 'ufixed160x48' | 'ufixed160x56' | 'ufixed160x64' | 'ufixed160x72' | 'ufixed160x80' | 'ufixed160x88' | 'ufixed160x96' | 'ufixed168x8' | 'ufixed168x16' | 'ufixed168x24' | 'ufixed168x32' | 'ufixed168x40' | 'ufixed168x48' | 'ufixed168x56' | 'ufixed168x64' | 'ufixed168x72' | 'ufixed168x80' | 'ufixed168x88' | 'ufixed176x8' | 'ufixed176x16' | 'ufixed176x24' | 'ufixed176x32' | 'ufixed176x40' | 'ufixed176x48' | 'ufixed176x56' | 'ufixed176x64' | 'ufixed176x72' | 'ufixed176x80' | 'ufixed184x8' | 'ufixed184x16' | 'ufixed184x24' | 'ufixed184x32' | 'ufixed184x40' | 'ufixed184x48' | 'ufixed184x56' | 'ufixed184x64' | 'ufixed184x72' | 'ufixed192x8' | 'ufixed192x16' | 'ufixed192x24' | 'ufixed192x32' | 'ufixed192x40' | 'ufixed192x48' | 'ufixed192x56' | 'ufixed192x64' | 'ufixed200x8' | 'ufixed200x16' | 'ufixed200x24' | 'ufixed200x32' | 'ufixed200x40' | 'ufixed200x48' | 'ufixed200x56' | 'ufixed208x8' | 'ufixed208x16' | 'ufixed208x24' | 'ufixed208x32' | 'ufixed208x40' | 'ufixed208x48' | 'ufixed216x8' | 'ufixed216x16' | 'ufixed216x24' | 'ufixed216x32' | 'ufixed216x40' | 'ufixed224x8' | 'ufixed224x16' | 'ufixed224x24' | 'ufixed224x32' | 'ufixed232x8' | 'ufixed232x16' | 'ufixed232x24' | 'ufixed240x8' | 'ufixed240x16' | 'ufixed248x8'
diff --git a/libsolidity/inlineasm/AsmCodeGen.cpp b/libsolidity/inlineasm/AsmCodeGen.cpp
index 5d920cb7..43c3b27a 100644
--- a/libsolidity/inlineasm/AsmCodeGen.cpp
+++ b/libsolidity/inlineasm/AsmCodeGen.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -81,7 +81,11 @@ struct GeneratorState
class LabelOrganizer: public boost::static_visitor<>
{
public:
- LabelOrganizer(GeneratorState& _state): m_state(_state) {}
+ LabelOrganizer(GeneratorState& _state): m_state(_state)
+ {
+ // Make the Solidity ErrorTag available to inline assembly
+ m_state.labels.insert(make_pair("invalidJumpLabel", m_state.assembly.errorTag()));
+ }
template <class T>
void operator()(T const& /*_item*/) { }
@@ -216,10 +220,18 @@ public:
size_t numVariables = m_state.variables.size();
int deposit = m_state.assembly.deposit();
std::for_each(_block.statements.begin(), _block.statements.end(), boost::apply_visitor(*this));
- deposit = m_state.assembly.deposit() - deposit;
+
+ // pop variables
+ while (m_state.variables.size() > numVariables)
+ {
+ m_state.assembly.append(solidity::Instruction::POP);
+ m_state.variables.pop_back();
+ }
m_state.assembly.setSourceLocation(_block.location);
+ deposit = m_state.assembly.deposit() - deposit;
+
// issue warnings for stack height discrepancies
if (deposit < 0)
{
@@ -238,12 +250,6 @@ public:
);
}
- // pop variables
- while (m_state.variables.size() > numVariables)
- {
- m_state.assembly.append(solidity::Instruction::POP);
- m_state.variables.pop_back();
- }
}
private:
diff --git a/libsolidity/inlineasm/AsmCodeGen.h b/libsolidity/inlineasm/AsmCodeGen.h
index b1fafe15..bd71812e 100644
--- a/libsolidity/inlineasm/AsmCodeGen.h
+++ b/libsolidity/inlineasm/AsmCodeGen.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/inlineasm/AsmData.h b/libsolidity/inlineasm/AsmData.h
index d6abf67f..d622ff54 100644
--- a/libsolidity/inlineasm/AsmData.h
+++ b/libsolidity/inlineasm/AsmData.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp
index 8d2c2ed4..ef3da255 100644
--- a/libsolidity/inlineasm/AsmParser.cpp
+++ b/libsolidity/inlineasm/AsmParser.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/inlineasm/AsmParser.h b/libsolidity/inlineasm/AsmParser.h
index 0a9d51d5..8b56ab90 100644
--- a/libsolidity/inlineasm/AsmParser.h
+++ b/libsolidity/inlineasm/AsmParser.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/inlineasm/AsmStack.cpp b/libsolidity/inlineasm/AsmStack.cpp
index 11c6e28f..b8e0e857 100644
--- a/libsolidity/inlineasm/AsmStack.cpp
+++ b/libsolidity/inlineasm/AsmStack.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/inlineasm/AsmStack.h b/libsolidity/inlineasm/AsmStack.h
index 521f5fe7..1543cb2a 100644
--- a/libsolidity/inlineasm/AsmStack.h
+++ b/libsolidity/inlineasm/AsmStack.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp
index efbbd237..eb588fc2 100644
--- a/libsolidity/interface/CompilerStack.cpp
+++ b/libsolidity/interface/CompilerStack.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -32,12 +32,18 @@
#include <libsolidity/analysis/NameAndTypeResolver.h>
#include <libsolidity/analysis/TypeChecker.h>
#include <libsolidity/analysis/DocStringAnalyser.h>
+#include <libsolidity/analysis/StaticAnalyzer.h>
#include <libsolidity/analysis/SyntaxChecker.h>
#include <libsolidity/codegen/Compiler.h>
#include <libsolidity/interface/InterfaceHandler.h>
#include <libsolidity/formal/Why3Translator.h>
-#include <libdevcore/SHA3.h>
+#include <libevmasm/Exceptions.h>
+
+#include <libdevcore/SwarmHash.h>
+#include <libdevcore/JSON.h>
+
+#include <json/json.h>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
@@ -78,6 +84,8 @@ void CompilerStack::reset(bool _keepSources)
{
m_sources.clear();
}
+ m_optimize = false;
+ m_optimizeRuns = 200;
m_globalContext.reset();
m_sourceOrder.clear();
m_contracts.clear();
@@ -195,6 +203,15 @@ bool CompilerStack::parse()
m_contracts[contract->name()].contract = contract;
}
+
+ if (noErrors)
+ {
+ StaticAnalyzer staticAnalyzer(m_errors);
+ for (Source const* source: m_sourceOrder)
+ if (!staticAnalyzer.analyze(*source->ast))
+ noErrors = false;
+ }
+
m_parseSuccessful = noErrors;
return m_parseSuccessful;
}
@@ -216,32 +233,37 @@ vector<string> CompilerStack::contractNames() const
}
-bool CompilerStack::compile(bool _optimize, unsigned _runs)
+bool CompilerStack::compile(bool _optimize, unsigned _runs, map<string, h160> const& _libraries)
{
if (!m_parseSuccessful)
if (!parse())
return false;
+ m_optimize = _optimize;
+ m_optimizeRuns = _runs;
+ m_libraries = _libraries;
+
map<ContractDefinition const*, eth::Assembly const*> compiledContracts;
for (Source const* source: m_sourceOrder)
for (ASTPointer<ASTNode> const& node: source->ast->nodes())
if (auto contract = dynamic_cast<ContractDefinition const*>(node.get()))
- compileContract(_optimize, _runs, *contract, compiledContracts);
+ compileContract(*contract, compiledContracts);
+ this->link();
return true;
}
-bool CompilerStack::compile(string const& _sourceCode, bool _optimize)
+bool CompilerStack::compile(string const& _sourceCode, bool _optimize, unsigned _runs)
{
- return parse(_sourceCode) && compile(_optimize);
+ return parse(_sourceCode) && compile(_optimize, _runs);
}
-void CompilerStack::link(const std::map<string, h160>& _libraries)
+void CompilerStack::link()
{
for (auto& contract: m_contracts)
{
- contract.second.object.link(_libraries);
- contract.second.runtimeObject.link(_libraries);
- contract.second.cloneObject.link(_libraries);
+ contract.second.object.link(m_libraries);
+ contract.second.runtimeObject.link(m_libraries);
+ contract.second.cloneObject.link(m_libraries);
}
}
@@ -345,30 +367,38 @@ map<string, unsigned> CompilerStack::sourceIndices() const
return indices;
}
-string const& CompilerStack::interface(string const& _contractName) const
+Json::Value const& CompilerStack::interface(string const& _contractName) const
{
return metadata(_contractName, DocumentationType::ABIInterface);
}
-string const& CompilerStack::metadata(string const& _contractName, DocumentationType _type) const
+Json::Value const& CompilerStack::metadata(string const& _contractName, DocumentationType _type) const
{
if (!m_parseSuccessful)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
- std::unique_ptr<string const>* doc;
- Contract const& currentContract = contract(_contractName);
+ return metadata(contract(_contractName), _type);
+}
+
+Json::Value const& CompilerStack::metadata(Contract const& _contract, DocumentationType _type) const
+{
+ if (!m_parseSuccessful)
+ BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
+
+ solAssert(_contract.contract, "");
+ std::unique_ptr<Json::Value const>* doc;
// checks wheather we already have the documentation
switch (_type)
{
case DocumentationType::NatspecUser:
- doc = &currentContract.userDocumentation;
+ doc = &_contract.userDocumentation;
break;
case DocumentationType::NatspecDev:
- doc = &currentContract.devDocumentation;
+ doc = &_contract.devDocumentation;
break;
case DocumentationType::ABIInterface:
- doc = &currentContract.interface;
+ doc = &_contract.interface;
break;
default:
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Illegal documentation type."));
@@ -376,11 +406,19 @@ string const& CompilerStack::metadata(string const& _contractName, Documentation
// caches the result
if (!*doc)
- doc->reset(new string(InterfaceHandler::documentation(*currentContract.contract, _type)));
+ doc->reset(new Json::Value(InterfaceHandler::documentation(*_contract.contract, _type)));
return *(*doc);
}
+string const& CompilerStack::onChainMetadata(string const& _contractName) const
+{
+ if (!m_parseSuccessful)
+ BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
+
+ return contract(_contractName).onChainMetadata;
+}
+
Scanner const& CompilerStack::scanner(string const& _sourceName) const
{
return *source(_sourceName).scanner;
@@ -571,8 +609,6 @@ string CompilerStack::absolutePath(string const& _path, string const& _reference
}
void CompilerStack::compileContract(
- bool _optimize,
- unsigned _runs,
ContractDefinition const& _contract,
map<ContractDefinition const*, eth::Assembly const*>& _compiledContracts
)
@@ -580,19 +616,38 @@ void CompilerStack::compileContract(
if (_compiledContracts.count(&_contract) || !_contract.annotation().isFullyImplemented)
return;
for (auto const* dependency: _contract.annotation().contractDependencies)
- compileContract(_optimize, _runs, *dependency, _compiledContracts);
+ compileContract(*dependency, _compiledContracts);
- shared_ptr<Compiler> compiler = make_shared<Compiler>(_optimize, _runs);
- compiler->compileContract(_contract, _compiledContracts);
+ shared_ptr<Compiler> compiler = make_shared<Compiler>(m_optimize, m_optimizeRuns);
Contract& compiledContract = m_contracts.at(_contract.name());
+ string onChainMetadata = createOnChainMetadata(compiledContract);
+ bytes cborEncodedMetadata =
+ // CBOR-encoding of {"bzzr0": dev::swarmHash(onChainMetadata)}
+ bytes{0xa1, 0x65, 'b', 'z', 'z', 'r', '0', 0x58, 0x20} +
+ dev::swarmHash(onChainMetadata).asBytes();
+ solAssert(cborEncodedMetadata.size() <= 0xffff, "Metadata too large");
+ // 16-bit big endian length
+ cborEncodedMetadata += toCompactBigEndian(cborEncodedMetadata.size(), 2);
+ compiler->compileContract(_contract, _compiledContracts, cborEncodedMetadata);
compiledContract.compiler = compiler;
compiledContract.object = compiler->assembledObject();
compiledContract.runtimeObject = compiler->runtimeObject();
+ compiledContract.onChainMetadata = onChainMetadata;
_compiledContracts[compiledContract.contract] = &compiler->assembly();
- Compiler cloneCompiler(_optimize, _runs);
- cloneCompiler.compileClone(_contract, _compiledContracts);
- compiledContract.cloneObject = cloneCompiler.assembledObject();
+ try
+ {
+ Compiler cloneCompiler(m_optimize, m_optimizeRuns);
+ cloneCompiler.compileClone(_contract, _compiledContracts);
+ compiledContract.cloneObject = cloneCompiler.assembledObject();
+ }
+ catch (eth::AssemblyException const&)
+ {
+ // In some cases (if the constructor requests a runtime function), it is not
+ // possible to compile the clone.
+
+ // TODO: Report error / warning
+ }
}
std::string CompilerStack::defaultContractName() const
@@ -626,6 +681,45 @@ CompilerStack::Source const& CompilerStack::source(string const& _sourceName) co
return it->second;
}
+string CompilerStack::createOnChainMetadata(Contract const& _contract) const
+{
+ Json::Value meta;
+ meta["version"] = 1;
+ meta["language"] = "Solidity";
+ meta["compiler"]["version"] = VersionString;
+
+ meta["sources"] = Json::objectValue;
+ for (auto const& s: m_sources)
+ {
+ solAssert(s.second.scanner, "Scanner not available");
+ meta["sources"][s.first]["keccak256"] =
+ "0x" + toHex(dev::keccak256(s.second.scanner->source()).asBytes());
+ meta["sources"][s.first]["url"] =
+ "bzzr://" + toHex(dev::swarmHash(s.second.scanner->source()).asBytes());
+ }
+ meta["settings"]["optimizer"]["enabled"] = m_optimize;
+ meta["settings"]["optimizer"]["runs"] = m_optimizeRuns;
+ meta["settings"]["compilationTarget"][_contract.contract->sourceUnitName()] =
+ _contract.contract->annotation().canonicalName;
+
+ meta["settings"]["remappings"] = Json::arrayValue;
+ set<string> remappings;
+ for (auto const& r: m_remappings)
+ remappings.insert(r.context + ":" + r.prefix + "=" + r.target);
+ for (auto const& r: remappings)
+ meta["settings"]["remappings"].append(r);
+
+ meta["settings"]["libraries"] = Json::objectValue;
+ for (auto const& library: m_libraries)
+ meta["settings"]["libraries"][library.first] = "0x" + toHex(library.second.asBytes());
+
+ meta["output"]["abi"] = metadata(_contract, DocumentationType::ABIInterface);
+ meta["output"]["userdoc"] = metadata(_contract, DocumentationType::NatspecUser);
+ meta["output"]["devdoc"] = metadata(_contract, DocumentationType::NatspecDev);
+
+ return jsonCompactPrint(meta);
+}
+
string CompilerStack::computeSourceMapping(eth::AssemblyItems const& _items) const
{
string ret;
diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h
index da479638..f98a457a 100644
--- a/libsolidity/interface/CompilerStack.h
+++ b/libsolidity/interface/CompilerStack.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -113,13 +113,14 @@ public:
/// Compiles the source units that were previously added and parsed.
/// @returns false on error.
- bool compile(bool _optimize = false, unsigned _runs = 200);
+ bool compile(
+ bool _optimize = false,
+ unsigned _runs = 200,
+ std::map<std::string, h160> const& _libraries = std::map<std::string, h160>{}
+ );
/// Parses and compiles the given source code.
/// @returns false on error.
- bool compile(std::string const& _sourceCode, bool _optimize = false);
-
- /// Inserts the given addresses into the linker objects of all compiled contracts.
- void link(std::map<std::string, h160> const& _libraries);
+ bool compile(std::string const& _sourceCode, bool _optimize = false, unsigned _runs = 200);
/// Tries to translate all source files into a language suitable for formal analysis.
/// @param _errors list to store errors - defaults to the internal error list.
@@ -162,14 +163,15 @@ public:
/// @returns a mapping assigning each source name its index inside the vector returned
/// by sourceNames().
std::map<std::string, unsigned> sourceIndices() const;
- /// @returns a string representing the contract interface in JSON.
+ /// @returns a JSON representing the contract interface.
/// Prerequisite: Successful call to parse or compile.
- std::string const& interface(std::string const& _contractName = "") const;
- /// @returns a string representing the contract's documentation in JSON.
+ Json::Value const& interface(std::string const& _contractName = "") const;
+ /// @returns a JSON representing the contract's documentation.
/// Prerequisite: Successful call to parse or compile.
/// @param type The type of the documentation to get.
/// Can be one of 4 types defined at @c DocumentationType
- std::string const& metadata(std::string const& _contractName, DocumentationType _type) const;
+ Json::Value const& metadata(std::string const& _contractName, DocumentationType _type) const;
+ std::string const& onChainMetadata(std::string const& _contractName) const;
/// @returns the previously used scanner, useful for counting lines during error reporting.
Scanner const& scanner(std::string const& _sourceName = "") const;
@@ -213,9 +215,10 @@ private:
eth::LinkerObject object;
eth::LinkerObject runtimeObject;
eth::LinkerObject cloneObject;
- mutable std::unique_ptr<std::string const> interface;
- mutable std::unique_ptr<std::string const> userDocumentation;
- mutable std::unique_ptr<std::string const> devDocumentation;
+ std::string onChainMetadata; ///< The metadata json that will be hashed into the chain.
+ mutable std::unique_ptr<Json::Value const> interface;
+ mutable std::unique_ptr<Json::Value const> userDocumentation;
+ mutable std::unique_ptr<Json::Value const> devDocumentation;
mutable std::unique_ptr<std::string const> sourceMapping;
mutable std::unique_ptr<std::string const> runtimeSourceMapping;
};
@@ -233,16 +236,18 @@ private:
std::string absolutePath(std::string const& _path, std::string const& _reference) const;
/// Compile a single contract and put the result in @a _compiledContracts.
void compileContract(
- bool _optimize,
- unsigned _runs,
ContractDefinition const& _contract,
std::map<ContractDefinition const*, eth::Assembly const*>& _compiledContracts
);
+ void link();
+
Contract const& contract(std::string const& _contractName = "") const;
Source const& source(std::string const& _sourceName = "") const;
+ std::string createOnChainMetadata(Contract const& _contract) const;
std::string computeSourceMapping(eth::AssemblyItems const& _items) const;
+ Json::Value const& metadata(Contract const&, DocumentationType _type) const;
struct Remapping
{
@@ -252,6 +257,9 @@ private:
};
ReadFileCallback m_readFile;
+ bool m_optimize = false;
+ unsigned m_optimizeRuns = 200;
+ std::map<std::string, h160> m_libraries;
/// list of path prefix remappings, e.g. mylibrary: github.com/ethereum = /usr/local/ethereum
/// "context:prefix=target"
std::vector<Remapping> m_remappings;
diff --git a/libsolidity/interface/Exceptions.cpp b/libsolidity/interface/Exceptions.cpp
index 6d72520b..90a680b4 100644
--- a/libsolidity/interface/Exceptions.cpp
+++ b/libsolidity/interface/Exceptions.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Liana <liana@ethdev.com>
diff --git a/libsolidity/interface/Exceptions.h b/libsolidity/interface/Exceptions.h
index 07835320..81716c41 100644
--- a/libsolidity/interface/Exceptions.h
+++ b/libsolidity/interface/Exceptions.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -37,6 +37,7 @@ using ErrorList = std::vector<std::shared_ptr<Error const>>;
struct CompilerError: virtual Exception {};
struct InternalCompilerError: virtual Exception {};
struct FatalError: virtual Exception {};
+struct UnimplementedFeatureError: virtual Exception{};
class Error: virtual public Exception
{
diff --git a/libsolidity/interface/GasEstimator.cpp b/libsolidity/interface/GasEstimator.cpp
index 1c804b78..852b392c 100644
--- a/libsolidity/interface/GasEstimator.cpp
+++ b/libsolidity/interface/GasEstimator.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/interface/GasEstimator.h b/libsolidity/interface/GasEstimator.h
index 518e58e4..bf63df96 100644
--- a/libsolidity/interface/GasEstimator.h
+++ b/libsolidity/interface/GasEstimator.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/interface/InterfaceHandler.cpp b/libsolidity/interface/InterfaceHandler.cpp
index de16a372..9944bb22 100644
--- a/libsolidity/interface/InterfaceHandler.cpp
+++ b/libsolidity/interface/InterfaceHandler.cpp
@@ -8,7 +8,7 @@ using namespace std;
using namespace dev;
using namespace dev::solidity;
-string InterfaceHandler::documentation(
+Json::Value InterfaceHandler::documentation(
ContractDefinition const& _contractDef,
DocumentationType _type
)
@@ -24,10 +24,9 @@ string InterfaceHandler::documentation(
}
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown documentation type"));
- return "";
}
-string InterfaceHandler::abiInterface(ContractDefinition const& _contractDef)
+Json::Value InterfaceHandler::abiInterface(ContractDefinition const& _contractDef)
{
Json::Value abi(Json::arrayValue);
@@ -67,8 +66,9 @@ string InterfaceHandler::abiInterface(ContractDefinition const& _contractDef)
{
Json::Value method;
method["type"] = "constructor";
- auto externalFunction = FunctionType(*_contractDef.constructor()).interfaceFunctionType();
+ auto externalFunction = FunctionType(*_contractDef.constructor(), false).interfaceFunctionType();
solAssert(!!externalFunction, "");
+ method["payable"] = externalFunction->isPayable();
method["inputs"] = populateParameters(
externalFunction->parameterNames(),
externalFunction->parameterTypeNames(_contractDef.isLibrary())
@@ -77,7 +77,7 @@ string InterfaceHandler::abiInterface(ContractDefinition const& _contractDef)
}
if (_contractDef.fallbackFunction())
{
- auto externalFunctionType = FunctionType(*_contractDef.fallbackFunction()).interfaceFunctionType();
+ auto externalFunctionType = FunctionType(*_contractDef.fallbackFunction(), false).interfaceFunctionType();
solAssert(!!externalFunctionType, "");
Json::Value method;
method["type"] = "fallback";
@@ -103,10 +103,11 @@ string InterfaceHandler::abiInterface(ContractDefinition const& _contractDef)
event["inputs"] = params;
abi.append(event);
}
- return Json::FastWriter().write(abi);
+
+ return abi;
}
-string InterfaceHandler::userDocumentation(ContractDefinition const& _contractDef)
+Json::Value InterfaceHandler::userDocumentation(ContractDefinition const& _contractDef)
{
Json::Value doc;
Json::Value methods(Json::objectValue);
@@ -126,10 +127,10 @@ string InterfaceHandler::userDocumentation(ContractDefinition const& _contractDe
}
doc["methods"] = methods;
- return Json::StyledWriter().write(doc);
+ return doc;
}
-string InterfaceHandler::devDocumentation(ContractDefinition const& _contractDef)
+Json::Value InterfaceHandler::devDocumentation(ContractDefinition const& _contractDef)
{
Json::Value doc;
Json::Value methods(Json::objectValue);
@@ -175,7 +176,7 @@ string InterfaceHandler::devDocumentation(ContractDefinition const& _contractDef
}
doc["methods"] = methods;
- return Json::StyledWriter().write(doc);
+ return doc;
}
string InterfaceHandler::extractDoc(multimap<string, DocTag> const& _tags, string const& _name)
diff --git a/libsolidity/interface/InterfaceHandler.h b/libsolidity/interface/InterfaceHandler.h
index 54199e4e..b7e1bb00 100644
--- a/libsolidity/interface/InterfaceHandler.h
+++ b/libsolidity/interface/InterfaceHandler.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Lefteris <lefteris@ethdev.com>
@@ -64,24 +64,24 @@ public:
/// @param _contractDef The contract definition
/// @param _type The type of the documentation. Can be one of the
/// types provided by @c DocumentationType
- /// @return A string with the json representation of provided type
- static std::string documentation(
+ /// @return A JSON representation of provided type
+ static Json::Value documentation(
ContractDefinition const& _contractDef,
DocumentationType _type
);
/// Get the ABI Interface of the contract
/// @param _contractDef The contract definition
- /// @return A string with the json representation of the contract's ABI Interface
- static std::string abiInterface(ContractDefinition const& _contractDef);
+ /// @return A JSONrepresentation of the contract's ABI Interface
+ static Json::Value abiInterface(ContractDefinition const& _contractDef);
/// Get the User documentation of the contract
/// @param _contractDef The contract definition
- /// @return A string with the json representation of the contract's user documentation
- static std::string userDocumentation(ContractDefinition const& _contractDef);
+ /// @return A JSON representation of the contract's user documentation
+ static Json::Value userDocumentation(ContractDefinition const& _contractDef);
/// Genereates the Developer's documentation of the contract
/// @param _contractDef The contract definition
- /// @return A string with the json representation
+ /// @return A JSON representation
/// of the contract's developer documentation
- static std::string devDocumentation(ContractDefinition const& _contractDef);
+ static Json::Value devDocumentation(ContractDefinition const& _contractDef);
private:
/// @returns concatenation of all content under the given tag name.
diff --git a/libsolidity/interface/SourceReferenceFormatter.cpp b/libsolidity/interface/SourceReferenceFormatter.cpp
index f09d2d45..7730a99a 100644
--- a/libsolidity/interface/SourceReferenceFormatter.cpp
+++ b/libsolidity/interface/SourceReferenceFormatter.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/interface/SourceReferenceFormatter.h b/libsolidity/interface/SourceReferenceFormatter.h
index 2b908c46..7034f4ab 100644
--- a/libsolidity/interface/SourceReferenceFormatter.h
+++ b/libsolidity/interface/SourceReferenceFormatter.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/interface/Utils.h b/libsolidity/interface/Utils.h
index 738669ac..0027759c 100644
--- a/libsolidity/interface/Utils.h
+++ b/libsolidity/interface/Utils.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -30,6 +30,7 @@ namespace dev
namespace solidity
{
struct InternalCompilerError;
+struct UnimplementedFeatureError;
}
}
@@ -37,3 +38,8 @@ struct InternalCompilerError;
#define solAssert(CONDITION, DESCRIPTION) \
assertThrow(CONDITION, ::dev::solidity::InternalCompilerError, DESCRIPTION)
+#define solUnimplementedAssert(CONDITION, DESCRIPTION) \
+ assertThrow(CONDITION, ::dev::solidity::UnimplementedFeatureError, DESCRIPTION)
+
+#define solUnimplemented(DESCRIPTION) \
+ solUnimplementedAssert(false, DESCRIPTION)
diff --git a/libsolidity/interface/Version.cpp b/libsolidity/interface/Version.cpp
index 0dca1ced..ff66f039 100644
--- a/libsolidity/interface/Version.cpp
+++ b/libsolidity/interface/Version.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/interface/Version.h b/libsolidity/interface/Version.h
index fea73997..5b07b3f4 100644
--- a/libsolidity/interface/Version.h
+++ b/libsolidity/interface/Version.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/parsing/DocStringParser.h b/libsolidity/parsing/DocStringParser.h
index f67b8bbd..c7f81c55 100644
--- a/libsolidity/parsing/DocStringParser.h
+++ b/libsolidity/parsing/DocStringParser.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Lefteris <lefteris@ethdev.com>
diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp
index 0e99d1e7..f02a4a45 100644
--- a/libsolidity/parsing/Parser.cpp
+++ b/libsolidity/parsing/Parser.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -217,7 +217,9 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary)
if (currentTokenValue == Token::RBrace)
break;
else if (currentTokenValue == Token::Function)
- subNodes.push_back(parseFunctionDefinition(name.get()));
+ // This can be a function or a state variable of function type (especially
+ // complicated to distinguish fallback function from function type state variable)
+ subNodes.push_back(parseFunctionDefinitionOrFunctionTypeStateVariable(name.get()));
else if (currentTokenValue == Token::Struct)
subNodes.push_back(parseStructDefinition());
else if (currentTokenValue == Token::Enum)
@@ -288,81 +290,121 @@ Declaration::Visibility Parser::parseVisibilitySpecifier(Token::Value _token)
return visibility;
}
-ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(ASTString const* _contractName)
+Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers)
{
- ASTNodeFactory nodeFactory(*this);
- ASTPointer<ASTString> docstring;
- if (m_scanner->currentCommentLiteral() != "")
- docstring = make_shared<ASTString>(m_scanner->currentCommentLiteral());
-
+ FunctionHeaderParserResult result;
expectToken(Token::Function);
- ASTPointer<ASTString> name;
- if (m_scanner->currentToken() == Token::LParen)
- name = make_shared<ASTString>(); // anonymous function
+ if (_forceEmptyName || m_scanner->currentToken() == Token::LParen)
+ result.name = make_shared<ASTString>(); // anonymous function
else
- name = expectIdentifierToken();
+ result.name = expectIdentifierToken();
VarDeclParserOptions options;
options.allowLocationSpecifier = true;
- ASTPointer<ParameterList> parameters(parseParameterList(options));
- bool isDeclaredConst = false;
- bool isPayable = false;
- Declaration::Visibility visibility(Declaration::Visibility::Default);
- vector<ASTPointer<ModifierInvocation>> modifiers;
+ result.parameters = parseParameterList(options);
while (true)
{
Token::Value token = m_scanner->currentToken();
if (token == Token::Const)
{
- isDeclaredConst = true;
+ result.isDeclaredConst = true;
m_scanner->next();
}
else if (m_scanner->currentToken() == Token::Payable)
{
- isPayable = true;
+ result.isPayable = true;
m_scanner->next();
}
- else if (token == Token::Identifier)
- modifiers.push_back(parseModifierInvocation());
+ else if (_allowModifiers && token == Token::Identifier)
+ {
+ // This can either be a modifier (function declaration) or the name of the
+ // variable (function type name plus variable).
+ if (
+ m_scanner->peekNextToken() == Token::Semicolon ||
+ m_scanner->peekNextToken() == Token::Assign
+ )
+ // Variable declaration, break here.
+ break;
+ else
+ result.modifiers.push_back(parseModifierInvocation());
+ }
else if (Token::isVisibilitySpecifier(token))
{
- if (visibility != Declaration::Visibility::Default)
+ if (result.visibility != Declaration::Visibility::Default)
fatalParserError(string("Multiple visibility specifiers."));
- visibility = parseVisibilitySpecifier(token);
+ result.visibility = parseVisibilitySpecifier(token);
}
else
break;
}
- ASTPointer<ParameterList> returnParameters;
if (m_scanner->currentToken() == Token::Returns)
{
bool const permitEmptyParameterList = false;
m_scanner->next();
- returnParameters = parseParameterList(options, permitEmptyParameterList);
+ result.returnParameters = parseParameterList(options, permitEmptyParameterList);
}
else
- returnParameters = createEmptyParameterList();
- ASTPointer<Block> block = ASTPointer<Block>();
- nodeFactory.markEndPosition();
- if (m_scanner->currentToken() != Token::Semicolon)
+ result.returnParameters = createEmptyParameterList();
+ return result;
+}
+
+ASTPointer<ASTNode> Parser::parseFunctionDefinitionOrFunctionTypeStateVariable(ASTString const* _contractName)
+{
+ ASTNodeFactory nodeFactory(*this);
+ ASTPointer<ASTString> docstring;
+ if (m_scanner->currentCommentLiteral() != "")
+ docstring = make_shared<ASTString>(m_scanner->currentCommentLiteral());
+
+ FunctionHeaderParserResult header = parseFunctionHeader(false, true);
+
+ if (
+ !header.modifiers.empty() ||
+ !header.name->empty() ||
+ m_scanner->currentToken() == Token::Semicolon ||
+ m_scanner->currentToken() == Token::LBrace
+ )
{
- block = parseBlock();
- nodeFactory.setEndPositionFromNode(block);
+ // this has to be a function
+ ASTPointer<Block> block = ASTPointer<Block>();
+ nodeFactory.markEndPosition();
+ if (m_scanner->currentToken() != Token::Semicolon)
+ {
+ block = parseBlock();
+ nodeFactory.setEndPositionFromNode(block);
+ }
+ else
+ m_scanner->next(); // just consume the ';'
+ bool const c_isConstructor = (_contractName && *header.name == *_contractName);
+ return nodeFactory.createNode<FunctionDefinition>(
+ header.name,
+ header.visibility,
+ c_isConstructor,
+ docstring,
+ header.parameters,
+ header.isDeclaredConst,
+ header.modifiers,
+ header.returnParameters,
+ header.isPayable,
+ block
+ );
}
else
- m_scanner->next(); // just consume the ';'
- bool const c_isConstructor = (_contractName && *name == *_contractName);
- return nodeFactory.createNode<FunctionDefinition>(
- name,
- visibility,
- c_isConstructor,
- docstring,
- parameters,
- isDeclaredConst,
- modifiers,
- returnParameters,
- isPayable,
- block
- );
+ {
+ // this has to be a state variable
+ ASTPointer<TypeName> type = nodeFactory.createNode<FunctionTypeName>(
+ header.parameters,
+ header.returnParameters,
+ header.visibility,
+ header.isDeclaredConst,
+ header.isPayable
+ );
+ type = parseTypeNameSuffix(type, nodeFactory);
+ VarDeclParserOptions options;
+ options.isStateVariable = true;
+ options.allowInitialValue = true;
+ auto node = parseVariableDeclaration(options, type);
+ expectToken(Token::Semicolon);
+ return node;
+ }
}
ASTPointer<StructDefinition> Parser::parseStructDefinition()
@@ -406,6 +448,8 @@ ASTPointer<EnumDefinition> Parser::parseEnumDefinition()
if (m_scanner->currentToken() != Token::Identifier)
fatalParserError(string("Expected Identifier after ','"));
}
+ if (members.size() == 0)
+ parserError({"enum with no members is not allowed."});
nodeFactory.markEndPosition();
expectToken(Token::RBrace);
@@ -609,6 +653,21 @@ ASTPointer<UserDefinedTypeName> Parser::parseUserDefinedTypeName()
return nodeFactory.createNode<UserDefinedTypeName>(identifierPath);
}
+ASTPointer<TypeName> Parser::parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory)
+{
+ while (m_scanner->currentToken() == Token::LBrack)
+ {
+ m_scanner->next();
+ ASTPointer<Expression> length;
+ if (m_scanner->currentToken() != Token::RBrack)
+ length = parseExpression();
+ nodeFactory.markEndPosition();
+ expectToken(Token::RBrack);
+ type = nodeFactory.createNode<ArrayTypeName>(type, length);
+ }
+ return type;
+}
+
ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
{
ASTNodeFactory nodeFactory(*this);
@@ -629,6 +688,8 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
fatalParserError(string("Expected explicit type name."));
m_scanner->next();
}
+ else if (token == Token::Function)
+ type = parseFunctionType();
else if (token == Token::Mapping)
type = parseMapping();
else if (token == Token::Identifier)
@@ -638,19 +699,23 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
if (type)
// Parse "[...]" postfixes for arrays.
- while (m_scanner->currentToken() == Token::LBrack)
- {
- m_scanner->next();
- ASTPointer<Expression> length;
- if (m_scanner->currentToken() != Token::RBrack)
- length = parseExpression();
- nodeFactory.markEndPosition();
- expectToken(Token::RBrack);
- type = nodeFactory.createNode<ArrayTypeName>(type, length);
- }
+ type = parseTypeNameSuffix(type, nodeFactory);
return type;
}
+ASTPointer<FunctionTypeName> Parser::parseFunctionType()
+{
+ ASTNodeFactory nodeFactory(*this);
+ FunctionHeaderParserResult header = parseFunctionHeader(true, false);
+ return nodeFactory.createNode<FunctionTypeName>(
+ header.parameters,
+ header.returnParameters,
+ header.visibility,
+ header.isDeclaredConst,
+ header.isPayable
+ );
+}
+
ASTPointer<Mapping> Parser::parseMapping()
{
ASTNodeFactory nodeFactory(*this);
@@ -722,6 +787,8 @@ ASTPointer<Statement> Parser::parseStatement()
return parseIfStatement(docString);
case Token::While:
return parseWhileStatement(docString);
+ case Token::Do:
+ return parseDoWhileStatement(docString);
case Token::For:
return parseForStatement(docString);
case Token::LBrace:
@@ -816,9 +883,24 @@ ASTPointer<WhileStatement> Parser::parseWhileStatement(ASTPointer<ASTString> con
expectToken(Token::RParen);
ASTPointer<Statement> body = parseStatement();
nodeFactory.setEndPositionFromNode(body);
- return nodeFactory.createNode<WhileStatement>(_docString, condition, body);
+ return nodeFactory.createNode<WhileStatement>(_docString, condition, body, false);
+}
+
+ASTPointer<WhileStatement> Parser::parseDoWhileStatement(ASTPointer<ASTString> const& _docString)
+{
+ ASTNodeFactory nodeFactory(*this);
+ expectToken(Token::Do);
+ ASTPointer<Statement> body = parseStatement();
+ expectToken(Token::While);
+ expectToken(Token::LParen);
+ ASTPointer<Expression> condition = parseExpression();
+ expectToken(Token::RParen);
+ nodeFactory.markEndPosition();
+ expectToken(Token::Semicolon);
+ return nodeFactory.createNode<WhileStatement>(_docString, condition, body, true);
}
+
ASTPointer<ForStatement> Parser::parseForStatement(ASTPointer<ASTString> const& _docString)
{
ASTNodeFactory nodeFactory(*this);
@@ -1259,7 +1341,7 @@ Parser::LookAheadInfo Parser::peekStatementType() const
Token::Value token(m_scanner->currentToken());
bool mightBeTypeName = (Token::isElementaryTypeName(token) || token == Token::Identifier);
- if (token == Token::Mapping || token == Token::Var)
+ if (token == Token::Mapping || token == Token::Function || token == Token::Var)
return LookAheadInfo::VariableDeclarationStatement;
if (mightBeTypeName)
{
diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h
index 9c30cf60..79d1d1d4 100644
--- a/libsolidity/parsing/Parser.h
+++ b/libsolidity/parsing/Parser.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -53,6 +53,18 @@ private:
bool allowLocationSpecifier = false;
};
+ /// This struct is shared for parsing a function header and a function type.
+ struct FunctionHeaderParserResult
+ {
+ ASTPointer<ASTString> name;
+ ASTPointer<ParameterList> parameters;
+ ASTPointer<ParameterList> returnParameters;
+ Declaration::Visibility visibility = Declaration::Visibility::Default;
+ bool isDeclaredConst = false;
+ bool isPayable = false;
+ std::vector<ASTPointer<ModifierInvocation>> modifiers;
+ };
+
///@{
///@name Parsing functions for the AST nodes
ASTPointer<PragmaDirective> parsePragmaDirective();
@@ -60,6 +72,8 @@ private:
ASTPointer<ContractDefinition> parseContractDefinition(bool _isLibrary);
ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier();
Declaration::Visibility parseVisibilitySpecifier(Token::Value _token);
+ FunctionHeaderParserResult parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers);
+ ASTPointer<ASTNode> parseFunctionDefinitionOrFunctionTypeStateVariable(ASTString const* _contractName);
ASTPointer<FunctionDefinition> parseFunctionDefinition(ASTString const* _contractName);
ASTPointer<StructDefinition> parseStructDefinition();
ASTPointer<EnumDefinition> parseEnumDefinition();
@@ -74,7 +88,9 @@ private:
ASTPointer<ModifierInvocation> parseModifierInvocation();
ASTPointer<Identifier> parseIdentifier();
ASTPointer<UserDefinedTypeName> parseUserDefinedTypeName();
+ ASTPointer<TypeName> parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory);
ASTPointer<TypeName> parseTypeName(bool _allowVar);
+ ASTPointer<FunctionTypeName> parseFunctionType();
ASTPointer<Mapping> parseMapping();
ASTPointer<ParameterList> parseParameterList(
VarDeclParserOptions const& _options,
@@ -85,6 +101,7 @@ private:
ASTPointer<InlineAssembly> parseInlineAssembly(ASTPointer<ASTString> const& _docString = {});
ASTPointer<IfStatement> parseIfStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<WhileStatement> parseWhileStatement(ASTPointer<ASTString> const& _docString);
+ ASTPointer<WhileStatement> parseDoWhileStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<ForStatement> parseForStatement(ASTPointer<ASTString> const& _docString);
/// A "simple statement" can be a variable declaration statement or an expression statement.
ASTPointer<Statement> parseSimpleStatement(ASTPointer<ASTString> const& _docString);
diff --git a/libsolidity/parsing/ParserBase.cpp b/libsolidity/parsing/ParserBase.cpp
index 2abf58cc..87d47f4b 100644
--- a/libsolidity/parsing/ParserBase.cpp
+++ b/libsolidity/parsing/ParserBase.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/parsing/ParserBase.h b/libsolidity/parsing/ParserBase.h
index 9705228f..dfb7cab7 100644
--- a/libsolidity/parsing/ParserBase.h
+++ b/libsolidity/parsing/ParserBase.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/libsolidity/parsing/Scanner.cpp b/libsolidity/parsing/Scanner.cpp
index 603f3e42..3623f23f 100644
--- a/libsolidity/parsing/Scanner.cpp
+++ b/libsolidity/parsing/Scanner.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
This file is derived from the file "scanner.cc", which was part of the
V8 project. The original copyright header follows:
@@ -327,7 +327,12 @@ Token::Value Scanner::scanMultiLineDocComment()
if (isLineTerminator(m_char))
{
skipWhitespace();
- if (!m_source.isPastEndOfInput(1) && m_source.get(0) == '*' && m_source.get(1) != '/')
+ if (!m_source.isPastEndOfInput(1) && m_source.get(0) == '*' && m_source.get(1) == '*')
+ { // it is unknown if this leads to the end of the comment
+ addCommentLiteralChar('*');
+ advance();
+ }
+ else if (!m_source.isPastEndOfInput(1) && m_source.get(0) == '*' && m_source.get(1) != '/')
{ // skip first '*' in subsequent lines
if (charsAdded)
addCommentLiteralChar('\n');
diff --git a/libsolidity/parsing/Scanner.h b/libsolidity/parsing/Scanner.h
index 36cba112..d6b48c6f 100644
--- a/libsolidity/parsing/Scanner.h
+++ b/libsolidity/parsing/Scanner.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
This file is derived from the file "scanner.h", which was part of the
V8 project. The original copyright header follows:
@@ -80,6 +80,8 @@ public:
void reset() { m_position = 0; }
+ std::string const& source() const { return m_source; }
+
///@{
///@name Error printing helper functions
/// Functions that help pretty-printing parse errors
@@ -102,6 +104,8 @@ public:
explicit Scanner(CharStream const& _source = CharStream(), std::string const& _sourceName = "") { reset(_source, _sourceName); }
+ std::string source() const { return m_source.source(); }
+
/// Resets the scanner as if newly constructed with _source and _sourceName as input.
void reset(CharStream const& _source, std::string const& _sourceName);
/// Resets scanner to the start of input.
diff --git a/libsolidity/parsing/Token.cpp b/libsolidity/parsing/Token.cpp
index 0ab97988..66312f69 100644
--- a/libsolidity/parsing/Token.cpp
+++ b/libsolidity/parsing/Token.cpp
@@ -25,20 +25,20 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Modifications as part of cpp-ethereum under the following license:
+// Modifications as part of solidity under the following license:
//
-// cpp-ethereum is free software: you can redistribute it and/or modify
+// 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.
//
-// cpp-ethereum is distributed in the hope that it will be useful,
+// 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+// along with solidity. If not, see <http://www.gnu.org/licenses/>.
#include <map>
#include <libsolidity/parsing/Token.h>
diff --git a/libsolidity/parsing/Token.h b/libsolidity/parsing/Token.h
index 5dd42992..c6d050bb 100644
--- a/libsolidity/parsing/Token.h
+++ b/libsolidity/parsing/Token.h
@@ -25,20 +25,20 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Modifications as part of cpp-ethereum under the following license:
+// Modifications as part of solidity under the following license:
//
-// cpp-ethereum is free software: you can redistribute it and/or modify
+// 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.
//
-// cpp-ethereum is distributed in the hope that it will be useful,
+// 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+// along with solidity. If not, see <http://www.gnu.org/licenses/>.
#pragma once
@@ -147,7 +147,6 @@ namespace solidity
K(Const, "constant", 0) \
K(Continue, "continue", 0) \
K(Contract, "contract", 0) \
- K(Default, "default", 0) \
K(Do, "do", 0) \
K(Else, "else", 0) \
K(Enum, "enum", 0) \
@@ -208,7 +207,6 @@ namespace solidity
T(TypesEnd, NULL, 0) /* used as type enum end marker */ \
\
/* Literals */ \
- K(NullLiteral, "null", 0) \
K(TrueLiteral, "true", 0) \
K(FalseLiteral, "false", 0) \
T(Number, NULL, 0) \
@@ -223,12 +221,14 @@ namespace solidity
K(After, "after", 0) \
K(Case, "case", 0) \
K(Catch, "catch", 0) \
+ K(Default, "default", 0) \
K(Final, "final", 0) \
K(In, "in", 0) \
K(Inline, "inline", 0) \
K(Interface, "interface", 0) \
K(Let, "let", 0) \
K(Match, "match", 0) \
+ K(NullLiteral, "null", 0) \
K(Of, "of", 0) \
K(Pure, "pure", 0) \
K(Relocatable, "relocatable", 0) \