aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AST.cpp8
-rw-r--r--AST.h16
-rw-r--r--CompilerContext.cpp20
-rw-r--r--CompilerUtils.cpp6
-rw-r--r--ExpressionCompiler.cpp33
-rw-r--r--InterfaceHandler.cpp3
-rw-r--r--NameAndTypeResolver.cpp15
-rw-r--r--Scanner.cpp13
-rw-r--r--Token.h13
-rw-r--r--Types.cpp13
-rw-r--r--Utils.h49
11 files changed, 105 insertions, 84 deletions
diff --git a/AST.cpp b/AST.cpp
index 4c042f2c..1fa6d8f6 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -21,7 +21,7 @@
*/
#include <algorithm>
-
+#include <libsolidity/Utils.h>
#include <libsolidity/AST.h>
#include <libsolidity/ASTVisitor.h>
#include <libsolidity/Exceptions.h>
@@ -145,8 +145,7 @@ void Return::checkTypeRequirements()
{
if (!m_expression)
return;
- if (asserts(m_returnParameters))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Return parameters not assigned."));
+ solAssert(m_returnParameters, "Return parameters not assigned.");
if (m_returnParameters->getParameters().size() != 1)
BOOST_THROW_EXCEPTION(createTypeError("Different number of arguments in return statement "
"than in returns declaration."));
@@ -336,8 +335,7 @@ void IndexAccess::checkTypeRequirements()
void Identifier::checkTypeRequirements()
{
- if (asserts(m_referencedDeclaration))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier not resolved."));
+ solAssert(m_referencedDeclaration, "Identifier not resolved.");
VariableDeclaration const* variable = dynamic_cast<VariableDeclaration const*>(m_referencedDeclaration);
if (variable)
diff --git a/AST.h b/AST.h
index c8369044..b7c3dc6c 100644
--- a/AST.h
+++ b/AST.h
@@ -27,6 +27,7 @@
#include <vector>
#include <memory>
#include <boost/noncopyable.hpp>
+#include <libsolidity/Utils.h>
#include <libsolidity/ASTForward.h>
#include <libsolidity/BaseTypes.h>
#include <libsolidity/Token.h>
@@ -364,7 +365,7 @@ public:
explicit ElementaryTypeName(Location const& _location, Token::Value _type):
TypeName(_location), m_type(_type)
{
- if (asserts(Token::isElementaryTypeName(_type))) BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(Token::isElementaryTypeName(_type), "");
}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
@@ -575,8 +576,7 @@ public:
void setFunctionReturnParameters(ParameterList& _parameters) { m_returnParameters = &_parameters; }
ParameterList const& getFunctionReturnParameters() const
{
- if (asserts(m_returnParameters))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(m_returnParameters, "");
return *m_returnParameters;
}
Expression const* getExpression() const { return m_expression.get(); }
@@ -682,7 +682,7 @@ public:
Expression(_location), m_leftHandSide(_leftHandSide),
m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide)
{
- if (asserts(Token::isAssignmentOp(_assignmentOperator))) BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(Token::isAssignmentOp(_assignmentOperator), "");
}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
@@ -710,7 +710,7 @@ public:
Expression(_location), m_operator(_operator),
m_subExpression(_subExpression), m_isPrefix(_isPrefix)
{
- if (asserts(Token::isUnaryOp(_operator))) BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(Token::isUnaryOp(_operator), "");
}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
@@ -737,7 +737,7 @@ public:
Token::Value _operator, ASTPointer<Expression> const& _right):
Expression(_location), m_left(_left), m_operator(_operator), m_right(_right)
{
- if (asserts(Token::isBinaryOp(_operator) || Token::isCompareOp(_operator))) BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(Token::isBinaryOp(_operator) || Token::isCompareOp(_operator), "");
}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
@@ -799,7 +799,7 @@ public:
std::vector<ASTPointer<Expression const>> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; }
/// Returns the referenced contract. Can only be called after type checking.
- ContractDefinition const* getContract() const { if (asserts(m_contract)) BOOST_THROW_EXCEPTION(InternalCompilerError()); else return m_contract; }
+ ContractDefinition const* getContract() const { solAssert(m_contract, ""); return m_contract; }
private:
ASTPointer<Identifier> m_contractName;
@@ -894,7 +894,7 @@ public:
ElementaryTypeNameExpression(Location const& _location, Token::Value _typeToken):
PrimaryExpression(_location), m_typeToken(_typeToken)
{
- if (asserts(Token::isElementaryTypeName(_typeToken))) BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(Token::isElementaryTypeName(_typeToken), "");
}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
diff --git a/CompilerContext.cpp b/CompilerContext.cpp
index 47401436..18357bf0 100644
--- a/CompilerContext.cpp
+++ b/CompilerContext.cpp
@@ -27,8 +27,10 @@
using namespace std;
-namespace dev {
-namespace solidity {
+namespace dev
+{
+namespace solidity
+{
void CompilerContext::addMagicGlobal(MagicVariableDeclaration const& _declaration)
{
@@ -65,8 +67,7 @@ void CompilerContext::addFunction(FunctionDefinition const& _function)
bytes const& CompilerContext::getCompiledContract(const ContractDefinition& _contract) const
{
auto ret = m_compiledContracts.find(&_contract);
- if (asserts(ret != m_compiledContracts.end()))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Compiled contract not found."));
+ solAssert(ret != m_compiledContracts.end(), "Compiled contract not found.");
return *ret->second;
}
@@ -78,16 +79,14 @@ bool CompilerContext::isLocalVariable(Declaration const* _declaration) const
eth::AssemblyItem CompilerContext::getFunctionEntryLabel(FunctionDefinition const& _function) const
{
auto res = m_functionEntryLabels.find(&_function);
- if (asserts(res != m_functionEntryLabels.end()))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Function entry label not found."));
+ solAssert(res != m_functionEntryLabels.end(), "Function entry label not found.");
return res->second.tag();
}
unsigned CompilerContext::getBaseStackOffsetOfVariable(Declaration const& _declaration) const
{
auto res = m_localVariables.find(&_declaration);
- if (asserts(res != m_localVariables.end()))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable not found on stack."));
+ solAssert(res != m_localVariables.end(), "Variable not found on stack.");
return m_localVariablesSize - res->second - 1;
}
@@ -99,12 +98,9 @@ unsigned CompilerContext::baseToCurrentStackOffset(unsigned _baseOffset) const
u256 CompilerContext::getStorageLocationOfVariable(const Declaration& _declaration) const
{
auto it = m_stateVariables.find(&_declaration);
- if (it == m_stateVariables.end())
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable not found in storage."));
+ solAssert(it != m_stateVariables.end(), "Variable not found in storage.");
return it->second;
}
-
-
}
}
diff --git a/CompilerUtils.cpp b/CompilerUtils.cpp
index 9f474896..680e9190 100644
--- a/CompilerUtils.cpp
+++ b/CompilerUtils.cpp
@@ -39,8 +39,7 @@ void CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _left
return;
}
eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD;
- if (asserts(_bytes <= 32))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory load of more than 32 bytes requested."));
+ solAssert(_bytes <= 32, "Memory load of more than 32 bytes requested.");
if (_bytes == 32)
m_context << u256(_offset) << load;
else
@@ -63,8 +62,7 @@ void CompilerUtils::storeInMemory(unsigned _offset, unsigned _bytes, bool _leftA
m_context << eth::Instruction::POP;
return;
}
- if (asserts(_bytes <= 32))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory store of more than 32 bytes requested."));
+ solAssert(_bytes <= 32, "Memory store of more than 32 bytes requested.");
if (_bytes != 32 && !_leftAligned)
// shift the value accordingly before storing
m_context << (u256(1) << ((32 - _bytes) * 8)) << eth::Instruction::MUL;
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 743503bb..f58c157d 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -30,8 +30,10 @@
using namespace std;
-namespace dev {
-namespace solidity {
+namespace dev
+{
+namespace solidity
+{
void ExpressionCompiler::compileExpression(CompilerContext& _context, Expression const& _expression, bool _optimize)
{
@@ -51,8 +53,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
_assignment.getRightHandSide().accept(*this);
appendTypeConversion(*_assignment.getRightHandSide().getType(), *_assignment.getType());
_assignment.getLeftHandSide().accept(*this);
- if (asserts(m_currentLValue.isValid()))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("LValue not retrieved."));
+ solAssert(m_currentLValue.isValid(), "LValue not retrieved.");
Token::Value op = _assignment.getAssignmentOperator();
if (op != Token::ASSIGN) // compound assignment
@@ -84,8 +85,7 @@ void ExpressionCompiler::endVisit(UnaryOperation const& _unaryOperation)
break;
case Token::DELETE: // delete
// @todo semantics change for complex types
- if (asserts(m_currentLValue.isValid()))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("LValue not retrieved."));
+ solAssert(m_currentLValue.isValid(), "LValue not retrieved.");
m_context << u256(0);
if (m_currentLValue.storesReferenceOnStack())
@@ -95,8 +95,7 @@ void ExpressionCompiler::endVisit(UnaryOperation const& _unaryOperation)
break;
case Token::INC: // ++ (pre- or postfix)
case Token::DEC: // -- (pre- or postfix)
- if (asserts(m_currentLValue.isValid()))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("LValue not retrieved."));
+ solAssert(m_currentLValue.isValid(), "LValue not retrieved.");
m_currentLValue.retrieveValue(_unaryOperation);
if (!_unaryOperation.isPrefixOperation())
{
@@ -179,8 +178,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
if (_functionCall.isTypeConversion())
{
//@todo struct construction
- if (asserts(_functionCall.getArguments().size() == 1))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(_functionCall.getArguments().size() == 1, "");
Expression const& firstArgument = *_functionCall.getArguments().front();
firstArgument.accept(*this);
if (firstArgument.getType()->getCategory() == Type::Category::CONTRACT &&
@@ -195,8 +193,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
{
FunctionType const& function = dynamic_cast<FunctionType const&>(*_functionCall.getExpression().getType());
vector<ASTPointer<Expression const>> arguments = _functionCall.getArguments();
- if (asserts(arguments.size() == function.getParameterTypes().size()))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(arguments.size() == function.getParameterTypes().size(), "");
switch (function.getLocation())
{
@@ -282,12 +279,10 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
bool ExpressionCompiler::visit(NewExpression const& _newExpression)
{
ContractType const* type = dynamic_cast<ContractType const*>(_newExpression.getType().get());
- if (asserts(type))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(type, "");
TypePointers const& types = type->getConstructorType()->getParameterTypes();
vector<ASTPointer<Expression const>> arguments = _newExpression.getArguments();
- if (asserts(arguments.size() == types.size()))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(arguments.size() == types.size(), "");
// copy the contracts code into memory
bytes const& bytecode = m_context.getCompiledContract(*_newExpression.getContract());
@@ -439,8 +434,7 @@ void ExpressionCompiler::endVisit(Literal const& _literal)
void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation const& _binaryOperation)
{
Token::Value const op = _binaryOperation.getOperator();
- if (asserts(op == Token::OR || op == Token::AND))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(op == Token::OR || op == Token::AND, "");
_binaryOperation.getLeftExpression().accept(*this);
m_context << eth::Instruction::DUP1;
@@ -592,8 +586,7 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
vector<ASTPointer<Expression const>> const& _arguments,
FunctionCallOptions const& _options)
{
- if (asserts(_arguments.size() == _functionType.getParameterTypes().size()))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(_arguments.size() == _functionType.getParameterTypes().size(), "");
unsigned dataOffset = _options.bare ? 0 : 1; // reserve one byte for the function index
for (unsigned i = 0; i < _arguments.size(); ++i)
diff --git a/InterfaceHandler.cpp b/InterfaceHandler.cpp
index 1310f504..c734fa38 100644
--- a/InterfaceHandler.cpp
+++ b/InterfaceHandler.cpp
@@ -198,8 +198,7 @@ std::string::const_iterator InterfaceHandler::appendDocTagParam(std::string::con
std::string::const_iterator _end)
{
// Should never be called with an empty vector
- if (asserts(!m_params.empty()))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Internal: Tried to append to empty parameter"));
+ solAssert(!m_params.empty(), "Internal: Tried to append to empty parameter");
auto pair = m_params.back();
pair.second += " ";
diff --git a/NameAndTypeResolver.cpp b/NameAndTypeResolver.cpp
index 80732615..3774537d 100644
--- a/NameAndTypeResolver.cpp
+++ b/NameAndTypeResolver.cpp
@@ -70,8 +70,7 @@ void NameAndTypeResolver::checkTypeRequirements(ContractDefinition& _contract)
void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration)
{
m_scopes[nullptr].registerDeclaration(_declaration, true);
- if (asserts(_declaration.getScope() == nullptr))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Updated declaration outside global scope."));
+ solAssert(_declaration.getScope() == nullptr, "Updated declaration outside global scope.");
}
Declaration const* NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const
@@ -133,8 +132,7 @@ void DeclarationRegistrationHelper::endVisit(VariableDefinition& _variableDefini
{
// Register the local variables with the function
// This does not fit here perfectly, but it saves us another AST visit.
- if (asserts(m_currentFunction))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable definition without function."));
+ solAssert(m_currentFunction, "Variable definition without function.");
m_currentFunction->addLocalVariable(_variableDefinition.getDeclaration());
}
@@ -149,15 +147,13 @@ void DeclarationRegistrationHelper::enterNewSubScope(Declaration const& _declara
map<ASTNode const*, DeclarationContainer>::iterator iter;
bool newlyAdded;
tie(iter, newlyAdded) = m_scopes.emplace(&_declaration, DeclarationContainer(m_currentScope, &m_scopes[m_currentScope]));
- if (asserts(newlyAdded))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to add new scope."));
+ solAssert(newlyAdded, "Unable to add new scope.");
m_currentScope = &_declaration;
}
void DeclarationRegistrationHelper::closeCurrentScope()
{
- if (asserts(m_currentScope))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Closed non-existing scope."));
+ solAssert(m_currentScope, "Closed non-existing scope.");
m_currentScope = m_scopes[m_currentScope].getEnclosingDeclaration();
}
@@ -196,8 +192,7 @@ void ReferencesResolver::endVisit(VariableDeclaration& _variable)
bool ReferencesResolver::visit(Return& _return)
{
- if (asserts(m_returnParameters))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Return parameters not set."));
+ solAssert(m_returnParameters, "Return parameters not set.");
_return.setFunctionReturnParameters(*m_returnParameters);
return true;
}
diff --git a/Scanner.cpp b/Scanner.cpp
index 08bf744d..1a21149a 100644
--- a/Scanner.cpp
+++ b/Scanner.cpp
@@ -52,6 +52,7 @@
#include <algorithm>
#include <tuple>
+#include <libsolidity/Utils.h>
#include <libsolidity/Scanner.h>
using namespace std;
@@ -249,8 +250,7 @@ Token::Value Scanner::scanDocumentationComment()
Token::Value Scanner::skipMultiLineComment()
{
- if (asserts(m_char == '*'))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(m_char == '*', "");
advance();
while (!isSourcePastEndOfInput())
{
@@ -597,8 +597,7 @@ Token::Value Scanner::scanNumber(char _charSeen)
// scan exponent, if any
if (m_char == 'e' || m_char == 'E')
{
- if (asserts(kind != HEX)) // 'e'/'E' must be scanned as part of the hex number
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(kind != HEX, "'e'/'E' must be scanned as part of the hex number");
if (kind != DECIMAL)
return Token::ILLEGAL;
// scan exponent
@@ -639,8 +638,7 @@ static Token::Value keywordOrIdentifierToken(string const& _input)
Token::Value Scanner::scanIdentifierOrKeyword()
{
- if (asserts(isIdentifierStart(m_char)))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(isIdentifierStart(m_char), "");
LiteralScope literal(this, LITERAL_TYPE_STRING);
addLiteralCharAndAdvance();
// Scan the rest of the identifier characters.
@@ -662,8 +660,7 @@ char CharStream::advanceAndGet(size_t _chars)
char CharStream::rollback(size_t _amount)
{
- if (asserts(m_pos >= _amount))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(m_pos >= _amount, "");
m_pos -= _amount;
return get();
}
diff --git a/Token.h b/Token.h
index 22378ae0..32656096 100644
--- a/Token.h
+++ b/Token.h
@@ -44,6 +44,7 @@
#include <libdevcore/Common.h>
#include <libdevcore/Log.h>
+#include <libsolidity/Utils.h>
#include <libsolidity/Exceptions.h>
namespace dev
@@ -344,8 +345,7 @@ public:
// (e.g. "LT" for the token LT).
static char const* getName(Value tok)
{
- if (asserts(tok < NUM_TOKENS))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(tok < NUM_TOKENS, "");
return m_name[tok];
}
@@ -360,8 +360,7 @@ public:
static Value AssignmentToBinaryOp(Value op)
{
- if (asserts(isAssignmentOp(op) && op != ASSIGN))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(isAssignmentOp(op) && op != ASSIGN, "");
return Token::Value(op + (BIT_OR - ASSIGN_BIT_OR));
}
@@ -375,8 +374,7 @@ public:
// have a (unique) string (e.g. an IDENTIFIER).
static char const* toString(Value tok)
{
- if (asserts(tok < NUM_TOKENS))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(tok < NUM_TOKENS, "");
return m_string[tok];
}
@@ -384,8 +382,7 @@ public:
// operators; returns 0 otherwise.
static int precedence(Value tok)
{
- if (asserts(tok < NUM_TOKENS))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(tok < NUM_TOKENS, "");
return m_precedence[tok];
}
diff --git a/Types.cpp b/Types.cpp
index eba11cb0..71319c3a 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -22,6 +22,7 @@
#include <libdevcore/CommonIO.h>
#include <libdevcore/CommonData.h>
+#include <libsolidity/Utils.h>
#include <libsolidity/Types.h>
#include <libsolidity/AST.h>
@@ -34,8 +35,7 @@ namespace solidity
shared_ptr<Type const> Type::fromElementaryTypeName(Token::Value _typeToken)
{
- if (asserts(Token::isElementaryTypeName(_typeToken)))
- BOOST_THROW_EXCEPTION(InternalCompilerError());
+ solAssert(Token::isElementaryTypeName(_typeToken), "");
if (Token::INT <= _typeToken && _typeToken <= Token::HASH256)
{
@@ -120,8 +120,8 @@ IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier):
{
if (isAddress())
m_bits = 160;
- if (asserts(m_bits > 0 && m_bits <= 256 && m_bits % 8 == 0))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid bit number for integer type: " + dev::toString(_bits)));
+ solAssert(m_bits > 0 && m_bits <= 256 && m_bits % 8 == 0,
+ "Invalid bit number for integer type: " + dev::toString(_bits));
}
bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
@@ -215,9 +215,8 @@ shared_ptr<StaticStringType> StaticStringType::smallestTypeForLiteral(string con
StaticStringType::StaticStringType(int _bytes): m_bytes(_bytes)
{
- if (asserts(m_bytes >= 0 && m_bytes <= 32))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid byte number for static string type: " +
- dev::toString(m_bytes)));
+ solAssert(m_bytes >= 0 && m_bytes <= 32,
+ "Invalid byte number for static string type: " + dev::toString(m_bytes));
}
bool StaticStringType::isImplicitlyConvertibleTo(Type const& _convertTo) const
diff --git a/Utils.h b/Utils.h
new file mode 100644
index 00000000..8d6a3ab0
--- /dev/null
+++ b/Utils.h
@@ -0,0 +1,49 @@
+/*
+ This file is part of cpp-ethereum.
+
+ cpp-ethereum 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,
+ 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/>.
+*/
+/**
+ * @author Christian <c@ethdev.com>
+ * @date 2014
+ * Solidity Utilities.
+ */
+
+#pragma once
+
+#include <string>
+#include <libsolidity/Exceptions.h>
+
+namespace dev
+{
+namespace solidity
+{
+
+/// Assertion that throws an InternalCompilerError containing the given description if it is not met.
+#define solAssert(CONDITION, DESCRIPTION) \
+ ::dev::solidity::solAssertAux(CONDITION, DESCRIPTION, __LINE__, __FILE__, ETH_FUNC)
+
+inline void solAssertAux(bool _condition, std::string const& _errorDescription, unsigned _line,
+ char const* _file, char const* _function)
+{
+ if (!_condition)
+ ::boost::throw_exception( InternalCompilerError()
+ << errinfo_comment(_errorDescription)
+ << ::boost::throw_function(_function)
+ << ::boost::throw_file(_file)
+ << ::boost::throw_line(_line));
+}
+
+}
+}