aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/interface
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-12-03 22:48:03 +0800
committerGitHub <noreply@github.com>2018-12-03 22:48:03 +0800
commitc8a2cb62832afb2dc09ccee6fd42c1516dfdb981 (patch)
tree7977e9dcbbc215088c05b847f849871ef5d4ae66 /libsolidity/interface
parent1d4f565a64988a3400847d2655ca24f73f234bc6 (diff)
parent590be1d84cea9850ce69b68be3dc5294b39041e5 (diff)
downloaddexon-solidity-c8a2cb62832afb2dc09ccee6fd42c1516dfdb981.tar.gz
dexon-solidity-c8a2cb62832afb2dc09ccee6fd42c1516dfdb981.tar.zst
dexon-solidity-c8a2cb62832afb2dc09ccee6fd42c1516dfdb981.zip
Merge pull request #5571 from ethereum/develop
Version 0.5.1
Diffstat (limited to 'libsolidity/interface')
-rw-r--r--libsolidity/interface/AssemblyStack.cpp64
-rw-r--r--libsolidity/interface/AssemblyStack.h36
-rw-r--r--libsolidity/interface/CompilerStack.cpp84
-rw-r--r--libsolidity/interface/CompilerStack.h36
-rw-r--r--libsolidity/interface/EVMVersion.h94
-rw-r--r--libsolidity/interface/ErrorReporter.cpp226
-rw-r--r--libsolidity/interface/ErrorReporter.h126
-rw-r--r--libsolidity/interface/Exceptions.cpp66
-rw-r--r--libsolidity/interface/Exceptions.h132
-rw-r--r--libsolidity/interface/GasEstimator.cpp1
-rw-r--r--libsolidity/interface/GasEstimator.h2
-rw-r--r--libsolidity/interface/SourceReferenceFormatter.cpp135
-rw-r--r--libsolidity/interface/SourceReferenceFormatter.h79
-rw-r--r--libsolidity/interface/StandardCompiler.cpp34
-rw-r--r--libsolidity/interface/Version.cpp2
15 files changed, 165 insertions, 952 deletions
diff --git a/libsolidity/interface/AssemblyStack.cpp b/libsolidity/interface/AssemblyStack.cpp
index 26496de7..f5eb7e41 100644
--- a/libsolidity/interface/AssemblyStack.cpp
+++ b/libsolidity/interface/AssemblyStack.cpp
@@ -22,37 +22,40 @@
#include <libsolidity/interface/AssemblyStack.h>
-#include <libsolidity/parsing/Scanner.h>
-#include <libsolidity/inlineasm/AsmPrinter.h>
-#include <libsolidity/inlineasm/AsmParser.h>
-#include <libsolidity/inlineasm/AsmAnalysis.h>
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
-#include <libsolidity/inlineasm/AsmCodeGen.h>
+#include <liblangutil/Scanner.h>
+#include <libyul/AsmPrinter.h>
+#include <libyul/AsmParser.h>
+#include <libyul/AsmAnalysis.h>
+#include <libyul/AsmAnalysisInfo.h>
+#include <libyul/AsmCodeGen.h>
+#include <libyul/backends/evm/EVMCodeTransform.h>
+#include <libyul/backends/evm/EVMAssembly.h>
+#include <libyul/ObjectParser.h>
#include <libevmasm/Assembly.h>
-#include <libyul/backends/evm/EVMCodeTransform.h>
-#include <libyul/backends/evm/EVMAssembly.h>
+#include <libyul/optimiser/Suite.h>
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
namespace
{
-assembly::AsmFlavour languageToAsmFlavour(AssemblyStack::Language _language)
+yul::AsmFlavour languageToAsmFlavour(AssemblyStack::Language _language)
{
switch (_language)
{
case AssemblyStack::Language::Assembly:
- return assembly::AsmFlavour::Loose;
+ return yul::AsmFlavour::Loose;
case AssemblyStack::Language::StrictAssembly:
- return assembly::AsmFlavour::Strict;
+ return yul::AsmFlavour::Strict;
case AssemblyStack::Language::Yul:
- return assembly::AsmFlavour::Yul;
+ return yul::AsmFlavour::Yul;
}
solAssert(false, "");
- return assembly::AsmFlavour::Yul;
+ return yul::AsmFlavour::Yul;
}
}
@@ -68,31 +71,30 @@ bool AssemblyStack::parseAndAnalyze(std::string const& _sourceName, std::string
{
m_errors.clear();
m_analysisSuccessful = false;
- m_scanner = make_shared<Scanner>(CharStream(_source), _sourceName);
- m_parserResult = assembly::Parser(m_errorReporter, languageToAsmFlavour(m_language)).parse(m_scanner, false);
+ m_scanner = make_shared<Scanner>(CharStream(_source, _sourceName));
+ m_parserResult = yul::ObjectParser(m_errorReporter, languageToAsmFlavour(m_language)).parse(m_scanner, false);
if (!m_errorReporter.errors().empty())
return false;
solAssert(m_parserResult, "");
+ solAssert(m_parserResult->code, "");
return analyzeParsed();
}
-bool AssemblyStack::analyze(assembly::Block const& _block, Scanner const* _scanner)
+void AssemblyStack::optimize()
{
- m_errors.clear();
- m_analysisSuccessful = false;
- if (_scanner)
- m_scanner = make_shared<Scanner>(*_scanner);
- m_parserResult = make_shared<assembly::Block>(_block);
-
- return analyzeParsed();
+ solAssert(m_language != Language::Assembly, "Optimization requested for loose assembly.");
+ yul::OptimiserSuite::run(*m_parserResult->code, *m_parserResult->analysisInfo);
+ solAssert(analyzeParsed(), "Invalid source code after optimization.");
}
bool AssemblyStack::analyzeParsed()
{
- m_analysisInfo = make_shared<assembly::AsmAnalysisInfo>();
- assembly::AsmAnalyzer analyzer(*m_analysisInfo, m_errorReporter, m_evmVersion, boost::none, languageToAsmFlavour(m_language));
- m_analysisSuccessful = analyzer.analyze(*m_parserResult);
+ solAssert(m_parserResult, "");
+ solAssert(m_parserResult->code, "");
+ m_parserResult->analysisInfo = make_shared<yul::AsmAnalysisInfo>();
+ yul::AsmAnalyzer analyzer(*m_parserResult->analysisInfo, m_errorReporter, m_evmVersion, boost::none, languageToAsmFlavour(m_language));
+ m_analysisSuccessful = analyzer.analyze(*m_parserResult->code);
return m_analysisSuccessful;
}
@@ -100,7 +102,8 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
{
solAssert(m_analysisSuccessful, "");
solAssert(m_parserResult, "");
- solAssert(m_analysisInfo, "");
+ solAssert(m_parserResult->code, "");
+ solAssert(m_parserResult->analysisInfo, "");
switch (_machine)
{
@@ -108,7 +111,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
{
MachineAssemblyObject object;
eth::Assembly assembly;
- assembly::CodeGenerator::assemble(*m_parserResult, *m_analysisInfo, assembly);
+ yul::CodeGenerator::assemble(*m_parserResult->code, *m_parserResult->analysisInfo, assembly);
object.bytecode = make_shared<eth::LinkerObject>(assembly.assemble());
object.assembly = assembly.assemblyString();
return object;
@@ -117,7 +120,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
{
MachineAssemblyObject object;
yul::EVMAssembly assembly(true);
- yul::CodeTransform(assembly, *m_analysisInfo, m_language == Language::Yul, true)(*m_parserResult);
+ yul::CodeTransform(assembly, *m_parserResult->analysisInfo, m_language == Language::Yul, true)(*m_parserResult->code);
object.bytecode = make_shared<eth::LinkerObject>(assembly.finalize());
/// TODO: fill out text representation
return object;
@@ -132,5 +135,6 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
string AssemblyStack::print() const
{
solAssert(m_parserResult, "");
- return assembly::AsmPrinter(m_language == Language::Yul)(*m_parserResult);
+ solAssert(m_parserResult->code, "");
+ return m_parserResult->toString(m_language == Language::Yul) + "\n";
}
diff --git a/libsolidity/interface/AssemblyStack.h b/libsolidity/interface/AssemblyStack.h
index 8132ce63..0d04ffec 100644
--- a/libsolidity/interface/AssemblyStack.h
+++ b/libsolidity/interface/AssemblyStack.h
@@ -21,24 +21,26 @@
#pragma once
-#include <libsolidity/interface/ErrorReporter.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/ErrorReporter.h>
+#include <liblangutil/EVMVersion.h>
+
+#include <libyul/Object.h>
+#include <libyul/ObjectParser.h>
#include <libevmasm/LinkerObject.h>
#include <string>
#include <memory>
+namespace langutil
+{
+class Scanner;
+}
+
namespace dev
{
namespace solidity
{
-class Scanner;
-namespace assembly
-{
-struct AsmAnalysisInfo;
-struct Block;
-}
struct MachineAssemblyObject
{
@@ -61,21 +63,20 @@ public:
{}
/// @returns the scanner used during parsing
- Scanner const& scanner() const;
+ langutil::Scanner const& scanner() const;
/// Runs parsing and analysis steps, returns false if input cannot be assembled.
/// Multiple calls overwrite the previous state.
bool parseAndAnalyze(std::string const& _sourceName, std::string const& _source);
- /// Runs analysis step on the supplied block, returns false if input cannot be assembled.
- /// Multiple calls overwrite the previous state.
- bool analyze(assembly::Block const& _block, Scanner const* _scanner = nullptr);
+ /// Run the optimizer suite. Can only be used with Yul or strict assembly.
+ void optimize();
/// Run the assembly step (should only be called after parseAndAnalyze).
MachineAssemblyObject assemble(Machine _machine) const;
/// @returns the errors generated during parsing, analysis (and potentially assembly).
- ErrorList const& errors() const { return m_errors; }
+ langutil::ErrorList const& errors() const { return m_errors; }
/// Pretty-print the input after having parsed it.
std::string print() const;
@@ -86,13 +87,12 @@ private:
Language m_language = Language::Assembly;
EVMVersion m_evmVersion;
- std::shared_ptr<Scanner> m_scanner;
+ std::shared_ptr<langutil::Scanner> m_scanner;
bool m_analysisSuccessful = false;
- std::shared_ptr<assembly::Block> m_parserResult;
- std::shared_ptr<assembly::AsmAnalysisInfo> m_analysisInfo;
- ErrorList m_errors;
- ErrorReporter m_errorReporter;
+ std::shared_ptr<yul::Object> m_parserResult;
+ langutil::ErrorList m_errors;
+ langutil::ErrorReporter m_errorReporter;
};
}
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp
index 441c7897..610caea1 100644
--- a/libsolidity/interface/CompilerStack.cpp
+++ b/libsolidity/interface/CompilerStack.cpp
@@ -27,8 +27,8 @@
#include <libsolidity/interface/Version.h>
#include <libsolidity/analysis/SemVerHandler.h>
#include <libsolidity/ast/AST.h>
-#include <libsolidity/parsing/Scanner.h>
#include <libsolidity/parsing/Parser.h>
+#include <libsolidity/analysis/ContractLevelChecker.h>
#include <libsolidity/analysis/ControlFlowAnalyzer.h>
#include <libsolidity/analysis/ControlFlowGraph.h>
#include <libsolidity/analysis/GlobalContext.h>
@@ -45,10 +45,12 @@
#include <libsolidity/interface/Natspec.h>
#include <libsolidity/interface/GasEstimator.h>
-#include <libevmasm/Exceptions.h>
-
#include <libyul/YulString.h>
+#include <liblangutil/Scanner.h>
+
+#include <libevmasm/Exceptions.h>
+
#include <libdevcore/SwarmHash.h>
#include <libdevcore/JSON.h>
@@ -58,6 +60,7 @@
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
boost::optional<CompilerStack::Remapping> CompilerStack::parseRemapping(string const& _remapping)
@@ -106,6 +109,8 @@ void CompilerStack::reset(bool _keepSources)
m_stackState = Empty;
m_sources.clear();
}
+ m_smtlib2Responses.clear();
+ m_unhandledSMTLib2Queries.clear();
m_libraries.clear();
m_evmVersion = EVMVersion();
m_optimize = false;
@@ -121,7 +126,7 @@ bool CompilerStack::addSource(string const& _name, string const& _content, bool
{
bool existed = m_sources.count(_name) != 0;
reset(true);
- m_sources[_name].scanner = make_shared<Scanner>(CharStream(_content), _name);
+ m_sources[_name].scanner = make_shared<Scanner>(CharStream(_content, _name));
m_sources[_name].isLibrary = _isLibrary;
m_stackState = SourcesSet;
return existed;
@@ -156,7 +161,7 @@ bool CompilerStack::parse()
{
string const& newPath = newSource.first;
string const& newContents = newSource.second;
- m_sources[newPath].scanner = make_shared<Scanner>(CharStream(newContents), newPath);
+ m_sources[newPath].scanner = make_shared<Scanner>(CharStream(newContents, newPath));
sourcesToParse.push_back(newPath);
}
}
@@ -221,8 +226,21 @@ bool CompilerStack::analyze()
m_contracts[contract->fullyQualifiedName()].contract = contract;
}
- // This cannot be done in the above loop, because cross-contract types couldn't be resolved.
- // A good example is `LibraryName.TypeName x;`.
+ // Next, we check inheritance, overrides, function collisions and other things at
+ // contract or function level.
+ // This also calculates whether a contract is abstract, which is needed by the
+ // type checker.
+ ContractLevelChecker contractLevelChecker(m_errorReporter);
+ for (Source const* source: m_sourceOrder)
+ for (ASTPointer<ASTNode> const& node: source->ast->nodes())
+ if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
+ if (!contractLevelChecker.check(*contract))
+ noErrors = false;
+
+ // New we run full type checks that go down to the expression level. This
+ // cannot be done earlier, because we need cross-contract types and information
+ // about whether a contract is abstract for the `new` expression.
+ // This populates the `type` annotation for all expressions.
//
// Note: this does not resolve overloaded functions. In order to do that, types of arguments are needed,
// which is only done one step later.
@@ -282,9 +300,10 @@ bool CompilerStack::analyze()
if (noErrors)
{
- SMTChecker smtChecker(m_errorReporter, m_smtQuery);
+ SMTChecker smtChecker(m_errorReporter, m_smtlib2Responses);
for (Source const* source: m_sourceOrder)
smtChecker.analyze(*source->ast, source->scanner);
+ m_unhandledSMTLib2Queries += smtChecker.unhandledQueries();
}
}
catch(FatalError const&)
@@ -329,13 +348,14 @@ bool CompilerStack::compile()
if (auto contract = dynamic_cast<ContractDefinition const*>(node.get()))
if (isRequestedContract(*contract))
compileContract(*contract, compiledContracts);
- this->link();
m_stackState = CompilationSuccessful;
+ this->link();
return true;
}
void CompilerStack::link()
{
+ solAssert(m_stackState >= CompilationSuccessful, "");
for (auto& contract: m_contracts)
{
contract.second.object.link(m_libraries);
@@ -353,6 +373,19 @@ vector<string> CompilerStack::contractNames() const
return contractNames;
}
+string const CompilerStack::lastContractName() const
+{
+ if (m_stackState < AnalysisSuccessful)
+ BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
+ // try to find some user-supplied contract
+ string contractName;
+ for (auto const& it: m_sources)
+ for (ASTPointer<ASTNode> const& node: it.second.ast->nodes())
+ if (auto contract = dynamic_cast<ContractDefinition const*>(node.get()))
+ contractName = contract->fullyQualifiedName();
+ return contractName;
+}
+
eth::AssemblyItems const* CompilerStack::assemblyItems(string const& _contractName) const
{
Contract const& currentContract = contract(_contractName);
@@ -389,6 +422,9 @@ string const* CompilerStack::runtimeSourceMapping(string const& _contractName) c
std::string const CompilerStack::filesystemFriendlyName(string const& _contractName) const
{
+ if (m_stackState < AnalysisSuccessful)
+ BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("No compiled contracts found."));
+
// Look up the contract (by its fully-qualified name)
Contract const& matchContract = m_contracts.at(_contractName);
// Check to see if it could collide on name
@@ -576,14 +612,15 @@ tuple<int, int, int, int> CompilerStack::positionFromSourceLocation(SourceLocati
int startColumn;
int endLine;
int endColumn;
- tie(startLine, startColumn) = scanner(*_sourceLocation.sourceName).translatePositionToLineColumn(_sourceLocation.start);
- tie(endLine, endColumn) = scanner(*_sourceLocation.sourceName).translatePositionToLineColumn(_sourceLocation.end);
+ tie(startLine, startColumn) = scanner(_sourceLocation.source->name()).translatePositionToLineColumn(_sourceLocation.start);
+ tie(endLine, endColumn) = scanner(_sourceLocation.source->name()).translatePositionToLineColumn(_sourceLocation.end);
return make_tuple(++startLine, ++startColumn, ++endLine, ++endColumn);
}
StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string const& _sourcePath)
{
+ solAssert(m_stackState < ParsingSuccessful, "");
StringMap newSources;
for (auto const& node: _ast.nodes())
if (ImportDirective const* import = dynamic_cast<ImportDirective*>(node.get()))
@@ -617,6 +654,7 @@ StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string
string CompilerStack::applyRemapping(string const& _path, string const& _context)
{
+ solAssert(m_stackState < ParsingSuccessful, "");
// Try to find the longest prefix match in all remappings that are active in the current context.
auto isPrefixOf = [](string const& _a, string const& _b)
{
@@ -658,6 +696,8 @@ string CompilerStack::applyRemapping(string const& _path, string const& _context
void CompilerStack::resolveImports()
{
+ solAssert(m_stackState == ParsingSuccessful, "");
+
// topological sorting (depth first search) of the import graph, cutting potential cycles
vector<Source const*> sourceOrder;
set<Source const*> sourcesSeen;
@@ -702,6 +742,8 @@ void CompilerStack::compileContract(
map<ContractDefinition const*, eth::Assembly const*>& _compiledContracts
)
{
+ solAssert(m_stackState >= AnalysisSuccessful, "");
+
if (
_compiledContracts.count(&_contract) ||
!_contract.annotation().unimplementedFunctions.empty() ||
@@ -757,23 +799,9 @@ void CompilerStack::compileContract(
_compiledContracts[compiledContract.contract] = &compiler->assembly();
}
-string const CompilerStack::lastContractName() const
-{
- if (m_contracts.empty())
- BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("No compiled contracts found."));
- // try to find some user-supplied contract
- string contractName;
- for (auto const& it: m_sources)
- for (ASTPointer<ASTNode> const& node: it.second.ast->nodes())
- if (auto contract = dynamic_cast<ContractDefinition const*>(node.get()))
- contractName = contract->fullyQualifiedName();
- return contractName;
-}
-
CompilerStack::Contract const& CompilerStack::contract(string const& _contractName) const
{
- if (m_contracts.empty())
- BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("No compiled contracts found."));
+ solAssert(m_stackState >= AnalysisSuccessful, "");
auto it = m_contracts.find(_contractName);
if (it != m_contracts.end())
@@ -908,8 +936,8 @@ string CompilerStack::computeSourceMapping(eth::AssemblyItems const& _items) con
SourceLocation const& location = item.location();
int length = location.start != -1 && location.end != -1 ? location.end - location.start : -1;
int sourceIndex =
- location.sourceName && sourceIndicesMap.count(*location.sourceName) ?
- sourceIndicesMap.at(*location.sourceName) :
+ location.source && sourceIndicesMap.count(location.source->name()) ?
+ sourceIndicesMap.at(location.source->name()) :
-1;
char jump = '-';
if (item.getJumpType() == eth::AssemblyItem::JumpType::IntoFunction)
diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h
index 9a15fbf0..2c7add3b 100644
--- a/libsolidity/interface/CompilerStack.h
+++ b/libsolidity/interface/CompilerStack.h
@@ -23,11 +23,12 @@
#pragma once
-#include <libsolidity/interface/ErrorReporter.h>
#include <libsolidity/interface/ReadFile.h>
-#include <libsolidity/interface/EVMVersion.h>
-#include <libevmasm/SourceLocation.h>
+#include <liblangutil/ErrorReporter.h>
+#include <liblangutil/EVMVersion.h>
+#include <liblangutil/SourceLocation.h>
+
#include <libevmasm/LinkerObject.h>
#include <libdevcore/Common.h>
@@ -43,6 +44,11 @@
#include <vector>
#include <functional>
+namespace langutil
+{
+class Scanner;
+}
+
namespace dev
{
@@ -57,7 +63,6 @@ namespace solidity
{
// forward declarations
-class Scanner;
class ASTNode;
class ContractDefinition;
class FunctionDefinition;
@@ -65,7 +70,6 @@ class SourceUnit;
class Compiler;
class GlobalContext;
class Natspec;
-class Error;
class DeclarationContainer;
/**
@@ -100,7 +104,7 @@ public:
m_errorReporter(m_errorList) {}
/// @returns the list of errors that occurred during parsing and type checking.
- ErrorList const& errors() const { return m_errorReporter.errors(); }
+ langutil::ErrorList const& errors() const { return m_errorReporter.errors(); }
/// @returns the current state.
State state() const { return m_stackState; }
@@ -149,6 +153,9 @@ public:
/// @returns true if a source object by the name already existed and was replaced.
bool addSource(std::string const& _name, std::string const& _content, bool _isLibrary = false);
+ /// Adds a response to an SMTLib2 query (identified by the hash of the query input).
+ void addSMTLib2Response(h256 const& _hash, std::string const& _response) { m_smtlib2Responses[_hash] = _response; }
+
/// Parses all source units that were added
/// @returns false on error.
bool parse();
@@ -174,7 +181,7 @@ public:
std::map<std::string, unsigned> sourceIndices() const;
/// @returns the previously used scanner, useful for counting lines during error reporting.
- Scanner const& scanner(std::string const& _sourceName) const;
+ langutil::Scanner const& scanner(std::string const& _sourceName) const;
/// @returns the parsed source unit with the supplied name.
SourceUnit const& ast(std::string const& _sourceName) const;
@@ -182,7 +189,11 @@ public:
/// Helper function for logs printing. Do only use in error cases, it's quite expensive.
/// line and columns are numbered starting from 1 with following order:
/// start line, start column, end line, end column
- std::tuple<int, int, int, int> positionFromSourceLocation(SourceLocation const& _sourceLocation) const;
+ std::tuple<int, int, int, int> positionFromSourceLocation(langutil::SourceLocation const& _sourceLocation) const;
+
+ /// @returns a list of unhandled queries to the SMT solver (has to be supplied in a second run
+ /// by calling @a addSMTLib2Response).
+ std::vector<std::string> const& unhandledSMTLib2Queries() const { return m_unhandledSMTLib2Queries; }
/// @returns a list of the contract names in the sources.
std::vector<std::string> contractNames() const;
@@ -248,7 +259,7 @@ private:
/// The state per source unit. Filled gradually during parsing.
struct Source
{
- std::shared_ptr<Scanner> scanner;
+ std::shared_ptr<langutil::Scanner> scanner;
std::shared_ptr<SourceUnit> ast;
bool isLibrary = false;
void reset() { scanner.reset(); ast.reset(); }
@@ -330,7 +341,6 @@ private:
) const;
ReadCallback::Callback m_readFile;
- ReadCallback::Callback m_smtQuery;
bool m_optimize = false;
unsigned m_optimizeRuns = 200;
EVMVersion m_evmVersion;
@@ -340,13 +350,15 @@ private:
/// "context:prefix=target"
std::vector<Remapping> m_remappings;
std::map<std::string const, Source> m_sources;
+ std::vector<std::string> m_unhandledSMTLib2Queries;
+ std::map<h256, std::string> m_smtlib2Responses;
std::shared_ptr<GlobalContext> m_globalContext;
std::vector<Source const*> m_sourceOrder;
/// This is updated during compilation.
std::map<ASTNode const*, std::shared_ptr<DeclarationContainer>> m_scopes;
std::map<std::string const, Contract> m_contracts;
- ErrorList m_errorList;
- ErrorReporter m_errorReporter;
+ langutil::ErrorList m_errorList;
+ langutil::ErrorReporter m_errorReporter;
bool m_metadataLiteralSources = false;
State m_stackState = Empty;
};
diff --git a/libsolidity/interface/EVMVersion.h b/libsolidity/interface/EVMVersion.h
deleted file mode 100644
index 657727ac..00000000
--- a/libsolidity/interface/EVMVersion.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- 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/>.
-*/
-/**
- * EVM versioning.
- */
-
-#pragma once
-
-#include <string>
-
-#include <boost/optional.hpp>
-#include <boost/operators.hpp>
-
-namespace dev
-{
-namespace solidity
-{
-
-/**
- * A version specifier of the EVM we want to compile to.
- * Defaults to the latest version.
- */
-class EVMVersion:
- boost::less_than_comparable<EVMVersion>,
- boost::equality_comparable<EVMVersion>
-{
-public:
- EVMVersion() {}
-
- static EVMVersion homestead() { return {Version::Homestead}; }
- static EVMVersion tangerineWhistle() { return {Version::TangerineWhistle}; }
- static EVMVersion spuriousDragon() { return {Version::SpuriousDragon}; }
- static EVMVersion byzantium() { return {Version::Byzantium}; }
- static EVMVersion constantinople() { return {Version::Constantinople}; }
-
- static boost::optional<EVMVersion> fromString(std::string const& _version)
- {
- for (auto const& v: {homestead(), tangerineWhistle(), spuriousDragon(), byzantium(), constantinople()})
- if (_version == v.name())
- return v;
- return {};
- }
-
- bool operator==(EVMVersion const& _other) const { return m_version == _other.m_version; }
- bool operator<(EVMVersion const& _other) const { return m_version < _other.m_version; }
-
- std::string name() const
- {
- switch (m_version)
- {
- case Version::Homestead: return "homestead";
- case Version::TangerineWhistle: return "tangerineWhistle";
- case Version::SpuriousDragon: return "spuriousDragon";
- case Version::Byzantium: return "byzantium";
- case Version::Constantinople: return "constantinople";
- }
- return "INVALID";
- }
-
- /// Has the RETURNDATACOPY and RETURNDATASIZE opcodes.
- bool supportsReturndata() const { return *this >= byzantium(); }
- bool hasStaticCall() const { return *this >= byzantium(); }
- bool hasBitwiseShifting() const { return *this >= constantinople(); }
- bool hasCreate2() const { return *this >= constantinople(); }
-
- /// Whether we have to retain the costs for the call opcode itself (false),
- /// or whether we can just forward easily all remaining gas (true).
- bool canOverchargeGasForCall() const { return *this >= tangerineWhistle(); }
-
-private:
- enum class Version { Homestead, TangerineWhistle, SpuriousDragon, Byzantium, Constantinople };
-
- EVMVersion(Version _version): m_version(_version) {}
-
- Version m_version = Version::Byzantium;
-};
-
-
-}
-}
diff --git a/libsolidity/interface/ErrorReporter.cpp b/libsolidity/interface/ErrorReporter.cpp
deleted file mode 100644
index 368e25e0..00000000
--- a/libsolidity/interface/ErrorReporter.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- 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 Rhett <roadriverrail@gmail.com>
- * @date 2017
- * Error helper class.
- */
-
-#include <libsolidity/interface/ErrorReporter.h>
-#include <libsolidity/ast/AST.h>
-#include <memory>
-
-using namespace std;
-using namespace dev;
-using namespace dev::solidity;
-
-ErrorReporter& ErrorReporter::operator=(ErrorReporter const& _errorReporter)
-{
- if (&_errorReporter == this)
- return *this;
- m_errorList = _errorReporter.m_errorList;
- return *this;
-}
-
-
-void ErrorReporter::warning(string const& _description)
-{
- error(Error::Type::Warning, SourceLocation(), _description);
-}
-
-void ErrorReporter::warning(
- SourceLocation const& _location,
- string const& _description
-)
-{
- error(Error::Type::Warning, _location, _description);
-}
-
-void ErrorReporter::warning(
- SourceLocation const& _location,
- string const& _description,
- SecondarySourceLocation const& _secondaryLocation
-)
-{
- error(Error::Type::Warning, _location, _secondaryLocation, _description);
-}
-
-void ErrorReporter::error(Error::Type _type, SourceLocation const& _location, string const& _description)
-{
- if (checkForExcessiveErrors(_type))
- return;
-
- auto err = make_shared<Error>(_type);
- *err <<
- errinfo_sourceLocation(_location) <<
- errinfo_comment(_description);
-
- m_errorList.push_back(err);
-}
-
-void ErrorReporter::error(Error::Type _type, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, string const& _description)
-{
- if (checkForExcessiveErrors(_type))
- return;
-
- auto err = make_shared<Error>(_type);
- *err <<
- errinfo_sourceLocation(_location) <<
- errinfo_secondarySourceLocation(_secondaryLocation) <<
- errinfo_comment(_description);
-
- m_errorList.push_back(err);
-}
-
-bool ErrorReporter::checkForExcessiveErrors(Error::Type _type)
-{
- if (_type == Error::Type::Warning)
- {
- m_warningCount++;
-
- if (m_warningCount == c_maxWarningsAllowed)
- {
- auto err = make_shared<Error>(Error::Type::Warning);
- *err << errinfo_comment("There are more than 256 warnings. Ignoring the rest.");
- m_errorList.push_back(err);
- }
-
- if (m_warningCount >= c_maxWarningsAllowed)
- return true;
- }
- else
- {
- m_errorCount++;
-
- if (m_errorCount > c_maxErrorsAllowed)
- {
- auto err = make_shared<Error>(Error::Type::Warning);
- *err << errinfo_comment("There are more than 256 errors. Aborting.");
- m_errorList.push_back(err);
- BOOST_THROW_EXCEPTION(FatalError());
- }
- }
-
- return false;
-}
-
-void ErrorReporter::fatalError(Error::Type _type, SourceLocation const& _location, string const& _description)
-{
- error(_type, _location, _description);
- BOOST_THROW_EXCEPTION(FatalError());
-}
-
-ErrorList const& ErrorReporter::errors() const
-{
- return m_errorList;
-}
-
-void ErrorReporter::clear()
-{
- m_errorList.clear();
-}
-
-void ErrorReporter::declarationError(SourceLocation const& _location, SecondarySourceLocation const&_secondaryLocation, string const& _description)
-{
- error(
- Error::Type::DeclarationError,
- _location,
- _secondaryLocation,
- _description
- );
-}
-
-void ErrorReporter::declarationError(SourceLocation const& _location, string const& _description)
-{
- error(
- Error::Type::DeclarationError,
- _location,
- _description
- );
-}
-
-void ErrorReporter::fatalDeclarationError(SourceLocation const& _location, std::string const& _description)
-{
- fatalError(
- Error::Type::DeclarationError,
- _location,
- _description);
-}
-
-void ErrorReporter::parserError(SourceLocation const& _location, string const& _description)
-{
- error(
- Error::Type::ParserError,
- _location,
- _description
- );
-}
-
-void ErrorReporter::fatalParserError(SourceLocation const& _location, string const& _description)
-{
- fatalError(
- Error::Type::ParserError,
- _location,
- _description
- );
-}
-
-void ErrorReporter::syntaxError(SourceLocation const& _location, string const& _description)
-{
- error(
- Error::Type::SyntaxError,
- _location,
- _description
- );
-}
-
-void ErrorReporter::typeError(SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, string const& _description)
-{
- error(
- Error::Type::TypeError,
- _location,
- _secondaryLocation,
- _description
- );
-}
-
-void ErrorReporter::typeError(SourceLocation const& _location, string const& _description)
-{
- error(
- Error::Type::TypeError,
- _location,
- _description
- );
-}
-
-
-void ErrorReporter::fatalTypeError(SourceLocation const& _location, string const& _description)
-{
- fatalError(Error::Type::TypeError,
- _location,
- _description
- );
-}
-
-void ErrorReporter::docstringParsingError(string const& _description)
-{
- error(
- Error::Type::DocstringParsingError,
- SourceLocation(),
- _description
- );
-}
diff --git a/libsolidity/interface/ErrorReporter.h b/libsolidity/interface/ErrorReporter.h
deleted file mode 100644
index fd53587a..00000000
--- a/libsolidity/interface/ErrorReporter.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- 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 Rhett <roadriverrail@gmail.com>
- * @date 2017
- * Error reporting helper class.
- */
-
-#pragma once
-
-#include <libsolidity/interface/Exceptions.h>
-#include <libevmasm/SourceLocation.h>
-
-namespace dev
-{
-namespace solidity
-{
-
-class ASTNode;
-
-class ErrorReporter
-{
-public:
-
- explicit ErrorReporter(ErrorList& _errors):
- m_errorList(_errors) { }
-
- ErrorReporter(ErrorReporter const& _errorReporter) noexcept:
- m_errorList(_errorReporter.m_errorList) { }
-
- ErrorReporter& operator=(ErrorReporter const& _errorReporter);
-
- void warning(std::string const& _description);
-
- void warning(SourceLocation const& _location, std::string const& _description);
-
- void warning(
- SourceLocation const& _location,
- std::string const& _description,
- SecondarySourceLocation const& _secondaryLocation
- );
-
- void error(
- Error::Type _type,
- SourceLocation const& _location,
- std::string const& _description
- );
-
- void declarationError(
- SourceLocation const& _location,
- SecondarySourceLocation const& _secondaryLocation,
- std::string const& _description
- );
-
- void declarationError(SourceLocation const& _location, std::string const& _description);
-
- void fatalDeclarationError(SourceLocation const& _location, std::string const& _description);
-
- void parserError(SourceLocation const& _location, std::string const& _description);
-
- void fatalParserError(SourceLocation const& _location, std::string const& _description);
-
- void syntaxError(SourceLocation const& _location, std::string const& _description);
-
- void typeError(
- SourceLocation const& _location,
- SecondarySourceLocation const& _secondaryLocation = SecondarySourceLocation(),
- std::string const& _description = std::string()
- );
-
- void typeError(SourceLocation const& _location, std::string const& _description);
-
- void fatalTypeError(SourceLocation const& _location, std::string const& _description);
-
- void docstringParsingError(std::string const& _description);
-
- ErrorList const& errors() const;
-
- void clear();
-
- /// @returns true iff there is any error (ignores warnings).
- bool hasErrors() const
- {
- return m_errorCount > 0;
- }
-
-private:
- void error(Error::Type _type,
- SourceLocation const& _location,
- SecondarySourceLocation const& _secondaryLocation,
- std::string const& _description = std::string());
-
- void fatalError(Error::Type _type,
- SourceLocation const& _location = SourceLocation(),
- std::string const& _description = std::string());
-
- // @returns true if error shouldn't be stored
- bool checkForExcessiveErrors(Error::Type _type);
-
- ErrorList& m_errorList;
-
- unsigned m_errorCount = 0;
- unsigned m_warningCount = 0;
-
- const unsigned c_maxWarningsAllowed = 256;
- const unsigned c_maxErrorsAllowed = 256;
-};
-
-
-}
-}
-
diff --git a/libsolidity/interface/Exceptions.cpp b/libsolidity/interface/Exceptions.cpp
deleted file mode 100644
index ecadd0b7..00000000
--- a/libsolidity/interface/Exceptions.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- 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 Liana <liana@ethdev.com>
- * @date 2015
- * Solidity exception hierarchy.
- */
-
-#include <libsolidity/interface/Exceptions.h>
-
-using namespace std;
-using namespace dev;
-using namespace dev::solidity;
-
-Error::Error(Type _type, SourceLocation const& _location, string const& _description):
- m_type(_type)
-{
- switch(m_type)
- {
- case Type::DeclarationError:
- m_typeName = "DeclarationError";
- break;
- case Type::DocstringParsingError:
- m_typeName = "DocstringParsingError";
- break;
- case Type::ParserError:
- m_typeName = "ParserError";
- break;
- case Type::SyntaxError:
- m_typeName = "SyntaxError";
- break;
- case Type::TypeError:
- m_typeName = "TypeError";
- break;
- case Type::Warning:
- m_typeName = "Warning";
- break;
- }
-
- if (!_location.isEmpty())
- *this << errinfo_sourceLocation(_location);
- if (!_description.empty())
- *this << errinfo_comment(_description);
-}
-
-Error::Error(Error::Type _type, const std::string& _description, const SourceLocation& _location):
- Error(_type)
-{
- if (!_location.isEmpty())
- *this << errinfo_sourceLocation(_location);
- *this << errinfo_comment(_description);
-}
diff --git a/libsolidity/interface/Exceptions.h b/libsolidity/interface/Exceptions.h
deleted file mode 100644
index 629b8f3f..00000000
--- a/libsolidity/interface/Exceptions.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- 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 Christian <c@ethdev.com>
- * @date 2014
- * Solidity exception hierarchy.
- */
-
-#pragma once
-
-#include <string>
-#include <utility>
-#include <libdevcore/Exceptions.h>
-#include <libdevcore/Assertions.h>
-#include <libevmasm/SourceLocation.h>
-
-namespace dev
-{
-namespace solidity
-{
-class Error;
-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{};
-
-/// Assertion that throws an InternalCompilerError containing the given description if it is not met.
-#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)
-
-class Error: virtual public Exception
-{
-public:
- enum class Type
- {
- DeclarationError,
- DocstringParsingError,
- ParserError,
- TypeError,
- SyntaxError,
- Warning
- };
-
- explicit Error(
- Type _type,
- SourceLocation const& _location = SourceLocation(),
- std::string const& _description = std::string()
- );
-
- Error(Type _type, std::string const& _description, SourceLocation const& _location = SourceLocation());
-
- Type type() const { return m_type; }
- std::string const& typeName() const { return m_typeName; }
-
- /// helper functions
- static Error const* containsErrorOfType(ErrorList const& _list, Error::Type _type)
- {
- for (auto e: _list)
- {
- if (e->type() == _type)
- return e.get();
- }
- return nullptr;
- }
- static bool containsOnlyWarnings(ErrorList const& _list)
- {
- for (auto e: _list)
- {
- if (e->type() != Type::Warning)
- return false;
- }
- return true;
- }
-private:
- Type m_type;
- std::string m_typeName;
-};
-
-
-using errorSourceLocationInfo = std::pair<std::string, SourceLocation>;
-
-class SecondarySourceLocation
-{
-public:
- SecondarySourceLocation& append(std::string const& _errMsg, SourceLocation const& _sourceLocation)
- {
- infos.push_back(std::make_pair(_errMsg, _sourceLocation));
- return *this;
- }
- /// Limits the number of secondary source locations to 32 and appends a notice to the
- /// error message.
- void limitSize(std::string& _message)
- {
- size_t occurrences = infos.size();
- if (occurrences > 32)
- {
- infos.resize(32);
- _message += " Truncated from " + std::to_string(occurrences) + " to the first 32 occurrences.";
- }
- }
-
- std::vector<errorSourceLocationInfo> infos;
-};
-
-
-using errinfo_sourceLocation = boost::error_info<struct tag_sourceLocation, SourceLocation>;
-using errinfo_secondarySourceLocation = boost::error_info<struct tag_secondarySourceLocation, SecondarySourceLocation>;
-
-}
-}
diff --git a/libsolidity/interface/GasEstimator.cpp b/libsolidity/interface/GasEstimator.cpp
index 1f20366e..de6b2ce5 100644
--- a/libsolidity/interface/GasEstimator.cpp
+++ b/libsolidity/interface/GasEstimator.cpp
@@ -35,6 +35,7 @@
using namespace std;
using namespace dev;
using namespace dev::eth;
+using namespace langutil;
using namespace dev::solidity;
GasEstimator::ASTGasConsumptionSelfAccumulated GasEstimator::structuralEstimation(
diff --git a/libsolidity/interface/GasEstimator.h b/libsolidity/interface/GasEstimator.h
index ea94d988..214a3e58 100644
--- a/libsolidity/interface/GasEstimator.h
+++ b/libsolidity/interface/GasEstimator.h
@@ -22,7 +22,7 @@
#pragma once
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <libevmasm/GasMeter.h>
#include <libevmasm/Assembly.h>
diff --git a/libsolidity/interface/SourceReferenceFormatter.cpp b/libsolidity/interface/SourceReferenceFormatter.cpp
deleted file mode 100644
index 865907e2..00000000
--- a/libsolidity/interface/SourceReferenceFormatter.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- 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 Christian <c@ethdev.com>
- * @date 2014
- * Formatting functions for errors referencing positions and locations in the source.
- */
-
-#include <libsolidity/interface/SourceReferenceFormatter.h>
-#include <libsolidity/parsing/Scanner.h>
-#include <libsolidity/interface/Exceptions.h>
-
-using namespace std;
-
-namespace dev
-{
-namespace solidity
-{
-
-void SourceReferenceFormatter::printSourceLocation(SourceLocation const* _location)
-{
- if (!_location || !_location->sourceName)
- return; // Nothing we can print here
- auto const& scanner = m_scannerFromSourceName(*_location->sourceName);
- int startLine;
- int startColumn;
- tie(startLine, startColumn) = scanner.translatePositionToLineColumn(_location->start);
- int endLine;
- int endColumn;
- tie(endLine, endColumn) = scanner.translatePositionToLineColumn(_location->end);
- if (startLine == endLine)
- {
- string line = scanner.lineAtPosition(_location->start);
-
- int locationLength = endColumn - startColumn;
- if (locationLength > 150)
- {
- line = line.substr(0, startColumn + 35) + " ... " + line.substr(endColumn - 35);
- endColumn = startColumn + 75;
- locationLength = 75;
- }
- if (line.length() > 150)
- {
- int len = line.length();
- line = line.substr(max(0, startColumn - 35), min(startColumn, 35) + min(locationLength + 35, len - startColumn));
- if (startColumn + locationLength + 35 < len)
- line += " ...";
- if (startColumn > 35)
- {
- line = " ... " + line;
- startColumn = 40;
- }
- endColumn = startColumn + locationLength;
- }
-
- m_stream << line << endl;
-
- for_each(
- line.cbegin(),
- line.cbegin() + startColumn,
- [this](char const& ch) { m_stream << (ch == '\t' ? '\t' : ' '); }
- );
- m_stream << "^";
- if (endColumn > startColumn + 2)
- m_stream << string(endColumn - startColumn - 2, '-');
- if (endColumn > startColumn + 1)
- m_stream << "^";
- m_stream << endl;
- }
- else
- m_stream <<
- scanner.lineAtPosition(_location->start) <<
- endl <<
- string(startColumn, ' ') <<
- "^ (Relevant source part starts here and spans across multiple lines)." <<
- endl;
-}
-
-void SourceReferenceFormatter::printSourceName(SourceLocation const* _location)
-{
- if (!_location || !_location->sourceName)
- return; // Nothing we can print here
- auto const& scanner = m_scannerFromSourceName(*_location->sourceName);
- int startLine;
- int startColumn;
- tie(startLine, startColumn) = scanner.translatePositionToLineColumn(_location->start);
- m_stream << *_location->sourceName << ":" << (startLine + 1) << ":" << (startColumn + 1) << ": ";
-}
-
-void SourceReferenceFormatter::printExceptionInformation(
- Exception const& _exception,
- string const& _name
-)
-{
- SourceLocation const* location = boost::get_error_info<errinfo_sourceLocation>(_exception);
- auto secondarylocation = boost::get_error_info<errinfo_secondarySourceLocation>(_exception);
-
- printSourceName(location);
-
- m_stream << _name;
- if (string const* description = boost::get_error_info<errinfo_comment>(_exception))
- m_stream << ": " << *description << endl;
- else
- m_stream << endl;
-
- printSourceLocation(location);
-
- if (secondarylocation && !secondarylocation->infos.empty())
- {
- for (auto info: secondarylocation->infos)
- {
- printSourceName(&info.second);
- m_stream << info.first << endl;
- printSourceLocation(&info.second);
- }
- m_stream << endl;
- }
-}
-
-}
-}
diff --git a/libsolidity/interface/SourceReferenceFormatter.h b/libsolidity/interface/SourceReferenceFormatter.h
deleted file mode 100644
index a32babdc..00000000
--- a/libsolidity/interface/SourceReferenceFormatter.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- 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 Christian <c@ethdev.com>
- * @date 2014
- * Formatting functions for errors referencing positions and locations in the source.
- */
-
-#pragma once
-
-#include <ostream>
-#include <sstream>
-#include <functional>
-#include <libevmasm/SourceLocation.h>
-
-namespace dev
-{
-
-struct Exception; // forward
-
-namespace solidity
-{
-
-class Scanner; // forward
-class CompilerStack; // forward
-
-class SourceReferenceFormatter
-{
-public:
- using ScannerFromSourceNameFun = std::function<Scanner const&(std::string const&)>;
-
- explicit SourceReferenceFormatter(
- std::ostream& _stream,
- ScannerFromSourceNameFun _scannerFromSourceName
- ):
- m_stream(_stream),
- m_scannerFromSourceName(std::move(_scannerFromSourceName))
- {}
-
- /// Prints source location if it is given.
- void printSourceLocation(SourceLocation const* _location);
- void printExceptionInformation(Exception const& _exception, std::string const& _name);
-
- static std::string formatExceptionInformation(
- Exception const& _exception,
- std::string const& _name,
- ScannerFromSourceNameFun const& _scannerFromSourceName
- )
- {
- std::ostringstream errorOutput;
-
- SourceReferenceFormatter formatter(errorOutput, _scannerFromSourceName);
- formatter.printExceptionInformation(_exception, _name);
- return errorOutput.str();
- }
-private:
- /// Prints source name if location is given.
- void printSourceName(SourceLocation const* _location);
-
- std::ostream& m_stream;
- ScannerFromSourceNameFun m_scannerFromSourceName;
-};
-
-}
-}
diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp
index c8b03a94..0eef50d2 100644
--- a/libsolidity/interface/StandardCompiler.cpp
+++ b/libsolidity/interface/StandardCompiler.cpp
@@ -21,7 +21,7 @@
*/
#include <libsolidity/interface/StandardCompiler.h>
-#include <libsolidity/interface/SourceReferenceFormatter.h>
+#include <liblangutil/SourceReferenceFormatter.h>
#include <libsolidity/ast/ASTJsonConverter.h>
#include <libevmasm/Instruction.h>
#include <libdevcore/JSON.h>
@@ -31,6 +31,7 @@
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
namespace {
@@ -84,9 +85,9 @@ Json::Value formatErrorWithException(
message = _message;
Json::Value sourceLocation;
- if (location && location->sourceName)
+ if (location && location->source && location->source->name() != "")
{
- sourceLocation["file"] = *location->sourceName;
+ sourceLocation["file"] = location->source->name();
sourceLocation["start"] = location->start;
sourceLocation["end"] = location->end;
}
@@ -318,6 +319,27 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
return formatFatalError("JSONError", "Invalid input source specified.");
}
+ Json::Value const& auxInputs = _input["auxiliaryInput"];
+ if (!!auxInputs)
+ {
+ Json::Value const& smtlib2Responses = auxInputs["smtlib2responses"];
+ if (!!smtlib2Responses)
+ for (auto const& hashString: smtlib2Responses.getMemberNames())
+ {
+ h256 hash;
+ try
+ {
+ hash = h256(hashString);
+ }
+ catch (dev::BadHexCharacter const&)
+ {
+ return formatFatalError("JSONError", "Invalid hex encoding of SMTLib2 auxiliary input.");
+ }
+
+ m_compilerStack.addSMTLib2Response(hash, smtlib2Responses[hashString].asString());
+ }
+ }
+
Json::Value const& settings = _input.get("settings", Json::Value());
if (settings.isMember("evmVersion"))
@@ -411,7 +433,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
Json::Value outputSelection = settings.get("outputSelection", Json::Value());
m_compilerStack.setRequestedContractNames(requestedContractNames(outputSelection));
- auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compilerStack.scanner(_sourceName); };
+ auto scannerFromSourceName = [&](string const& _sourceName) -> Scanner const& { return m_compilerStack.scanner(_sourceName); };
try
{
@@ -517,6 +539,10 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
if (errors.size() > 0)
output["errors"] = errors;
+ if (!m_compilerStack.unhandledSMTLib2Queries().empty())
+ for (string const& query: m_compilerStack.unhandledSMTLib2Queries())
+ output["auxiliaryInputRequested"]["smtlib2queries"]["0x" + keccak256(query).hex()] = query;
+
output["sources"] = Json::objectValue;
unsigned sourceIndex = 0;
for (string const& sourceName: analysisSuccess ? m_compilerStack.sourceNames() : vector<string>())
diff --git a/libsolidity/interface/Version.cpp b/libsolidity/interface/Version.cpp
index b5f68ce8..b785d557 100644
--- a/libsolidity/interface/Version.cpp
+++ b/libsolidity/interface/Version.cpp
@@ -24,7 +24,7 @@
#include <string>
#include <libdevcore/CommonData.h>
#include <libdevcore/Common.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <solidity/BuildInfo.h>
using namespace dev;