diff options
Diffstat (limited to 'libsolidity/ast')
-rw-r--r-- | libsolidity/ast/AST.cpp | 28 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 33 | ||||
-rw-r--r-- | libsolidity/ast/ASTAnnotations.h | 7 | ||||
-rw-r--r-- | libsolidity/ast/ASTJsonConverter.cpp | 37 | ||||
-rw-r--r-- | libsolidity/ast/ASTJsonConverter.h | 1 | ||||
-rw-r--r-- | libsolidity/ast/ExperimentalFeatures.h | 35 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 139 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 14 |
8 files changed, 190 insertions, 104 deletions
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 724a908f..1d68231e 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -84,13 +84,35 @@ SourceUnitAnnotation& SourceUnit::annotation() const return dynamic_cast<SourceUnitAnnotation&>(*m_annotation); } -string Declaration::sourceUnitName() const +set<SourceUnit const*> SourceUnit::referencedSourceUnits(bool _recurse, set<SourceUnit const*> _skipList) const +{ + set<SourceUnit const*> sourceUnits; + for (ImportDirective const* importDirective: filteredNodes<ImportDirective>(nodes())) + { + auto const& sourceUnit = importDirective->annotation().sourceUnit; + if (!_skipList.count(sourceUnit)) + { + _skipList.insert(sourceUnit); + sourceUnits.insert(sourceUnit); + if (_recurse) + sourceUnits += sourceUnit->referencedSourceUnits(true, _skipList); + } + } + return sourceUnits; +} + +SourceUnit const& Declaration::sourceUnit() 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; + return dynamic_cast<SourceUnit const&>(*scope); +} + +string Declaration::sourceUnitName() const +{ + return sourceUnit().annotation().path; } ImportAnnotation& ImportDirective::annotation() const @@ -140,7 +162,7 @@ FunctionDefinition const* ContractDefinition::fallbackFunction() const { for (ContractDefinition const* contract: annotation().linearizedBaseContracts) for (FunctionDefinition const* f: contract->definedFunctions()) - if (f->name().empty()) + if (f->isFallback()) return f; return nullptr; } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 81ddc754..bdf20e81 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -136,6 +136,9 @@ public: std::vector<ASTPointer<ASTNode>> nodes() const { return m_nodes; } + /// @returns a set of referenced SourceUnits. Recursively if @a _recurse is true. + std::set<SourceUnit const*> referencedSourceUnits(bool _recurse = false, std::set<SourceUnit const*> _skipList = std::set<SourceUnit const*>()) const; + private: std::vector<ASTPointer<ASTNode>> m_nodes; }; @@ -149,6 +152,24 @@ public: /// Visibility ordered from restricted to unrestricted. enum class Visibility { Default, Private, Internal, Public, External }; + static std::string visibilityToString(Declaration::Visibility _visibility) + { + switch(_visibility) + { + case Declaration::Visibility::Public: + return "public"; + case Declaration::Visibility::Internal: + return "internal"; + case Declaration::Visibility::Private: + return "private"; + case Declaration::Visibility::External: + return "external"; + default: + solAssert(false, "Invalid visibility specifier."); + } + return std::string(); + } + Declaration( SourceLocation const& _location, ASTPointer<ASTString> const& _name, @@ -168,6 +189,9 @@ public: ASTNode const* scope() const { return m_scope; } void setScope(ASTNode const* _scope) { m_scope = _scope; } + /// @returns the source unit this declaration is present in. + SourceUnit const& sourceUnit() const; + /// @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; @@ -583,6 +607,7 @@ public: virtual void accept(ASTConstVisitor& _visitor) const override; bool isConstructor() const { return m_isConstructor; } + bool isFallback() const { return name().empty(); } bool isDeclaredConst() const { return m_isDeclaredConst; } bool isPayable() const { return m_isPayable; } std::vector<ASTPointer<ModifierInvocation>> const& modifiers() const { return m_functionModifiers; } @@ -590,9 +615,9 @@ public: Block const& body() const { solAssert(m_body, ""); return *m_body; } virtual bool isVisibleInContract() const override { - return Declaration::isVisibleInContract() && !isConstructor() && !name().empty(); + return Declaration::isVisibleInContract() && !isConstructor() && !isFallback(); } - virtual bool isPartOfExternalInterface() const override { return isPublic() && !m_isConstructor && !name().empty(); } + virtual bool isPartOfExternalInterface() const override { return isPublic() && !isConstructor() && !isFallback(); } /// @returns the external signature of the function /// That consists of the name of the function followed by the types of the @@ -791,11 +816,11 @@ public: Declaration(SourceLocation(), std::make_shared<ASTString>(_name)), m_type(_type) {} virtual void accept(ASTVisitor&) override { - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("MagicVariableDeclaration used inside real AST.")); + solAssert(false, "MagicVariableDeclaration used inside real AST."); } virtual void accept(ASTConstVisitor&) const override { - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("MagicVariableDeclaration used inside real AST.")); + solAssert(false, "MagicVariableDeclaration used inside real AST."); } virtual TypePointer type() const override { return m_type; } diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 45a6dd1a..fd9efb4d 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -23,6 +23,7 @@ #pragma once #include <libsolidity/ast/ASTForward.h> +#include <libsolidity/ast/ExperimentalFeatures.h> #include <map> #include <memory> @@ -61,6 +62,8 @@ struct SourceUnitAnnotation: ASTAnnotation std::string path; /// The exported symbols (all global symbols). std::map<ASTString, std::vector<Declaration const*>> exportedSymbols; + /// Experimental features. + std::set<ExperimentalFeature> experimentalFeatures; }; struct ImportAnnotation: ASTAnnotation @@ -79,8 +82,8 @@ struct TypeDeclarationAnnotation: ASTAnnotation struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, DocumentedAnnotation { - /// Whether all functions are implemented. - bool isFullyImplemented = true; + /// List of functions without a body. Can also contain functions from base classes. + std::vector<FunctionDefinition const*> unimplementedFunctions; /// List of all (direct and indirect) base contracts in order from derived to /// base, including the contract itself. std::vector<ContractDefinition const*> linearizedBaseContracts; diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index a90debb2..abee55ee 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -253,7 +253,7 @@ bool ASTJsonConverter::visit(ContractDefinition const& _node) make_pair("name", _node.name()), make_pair("documentation", _node.documentation() ? Json::Value(*_node.documentation()) : Json::nullValue), make_pair("contractKind", contractKind(_node.contractKind())), - make_pair("fullyImplemented", _node.annotation().isFullyImplemented), + make_pair("fullyImplemented", _node.annotation().unimplementedFunctions.empty()), make_pair("linearizedBaseContracts", getContainerIds(_node.annotation().linearizedBaseContracts)), make_pair("baseContracts", toJson(_node.baseContracts())), make_pair("contractDependencies", getContainerIds(_node.annotation().contractDependencies)), @@ -285,7 +285,7 @@ bool ASTJsonConverter::visit(StructDefinition const& _node) { setJsonNode(_node, "StructDefinition", { make_pair("name", _node.name()), - make_pair("visibility", visibility(_node.visibility())), + make_pair("visibility", Declaration::visibilityToString(_node.visibility())), make_pair("canonicalName", _node.annotation().canonicalName), make_pair("members", toJson(_node.members())), make_pair("scope", idOrNull(_node.scope())) @@ -325,7 +325,7 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node) make_pair("name", _node.name()), make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.isDeclaredConst()), make_pair("payable", _node.isPayable()), - make_pair("visibility", visibility(_node.visibility())), + make_pair("visibility", Declaration::visibilityToString(_node.visibility())), make_pair("parameters", toJson(_node.parameterList())), make_pair("isConstructor", _node.isConstructor()), make_pair("returnParameters", toJson(*_node.returnParameterList())), @@ -346,7 +346,7 @@ bool ASTJsonConverter::visit(VariableDeclaration const& _node) make_pair("constant", _node.isConstant()), make_pair("stateVariable", _node.isStateVariable()), make_pair("storageLocation", location(_node.referenceLocation())), - make_pair("visibility", visibility(_node.visibility())), + make_pair("visibility", Declaration::visibilityToString(_node.visibility())), make_pair("value", _node.value() ? toJson(*_node.value()) : Json::nullValue), make_pair("scope", idOrNull(_node.scope())), make_pair("typeDescriptions", typePointerToJson(_node.annotation().type)) @@ -361,7 +361,7 @@ bool ASTJsonConverter::visit(ModifierDefinition const& _node) { setJsonNode(_node, "ModifierDefinition", { make_pair("name", _node.name()), - make_pair("visibility", visibility(_node.visibility())), + make_pair("visibility", Declaration::visibilityToString(_node.visibility())), make_pair("parameters", toJson(_node.parameterList())), make_pair("body", toJson(_node.body())) }); @@ -418,7 +418,7 @@ bool ASTJsonConverter::visit(FunctionTypeName const& _node) { setJsonNode(_node, "FunctionTypeName", { make_pair("payable", _node.isPayable()), - make_pair("visibility", visibility(_node.visibility())), + make_pair("visibility", Declaration::visibilityToString(_node.visibility())), make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.isDeclaredConst()), make_pair("parameterTypes", toJson(*_node.parameterTypeList())), make_pair("returnParameterTypes", toJson(*_node.returnParameterTypeList())), @@ -730,23 +730,6 @@ void ASTJsonConverter::endVisit(EventDefinition const&) m_inEvent = false; } -string ASTJsonConverter::visibility(Declaration::Visibility const& _visibility) -{ - switch (_visibility) - { - case Declaration::Visibility::Private: - return "private"; - case Declaration::Visibility::Internal: - return "internal"; - case Declaration::Visibility::Public: - return "public"; - case Declaration::Visibility::External: - return "external"; - default: - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown declaration visibility.")); - } -} - string ASTJsonConverter::location(VariableDeclaration::Location _location) { switch (_location) @@ -758,7 +741,7 @@ string ASTJsonConverter::location(VariableDeclaration::Location _location) case VariableDeclaration::Location::Memory: return "memory"; default: - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown declaration location.")); + solAssert(false, "Unknown declaration location."); } } @@ -773,7 +756,7 @@ string ASTJsonConverter::contractKind(ContractDefinition::ContractKind _kind) case ContractDefinition::ContractKind::Library: return "library"; default: - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of contract.")); + solAssert(false, "Unknown kind of contract."); } } @@ -788,7 +771,7 @@ string ASTJsonConverter::functionCallKind(FunctionCallKind _kind) case FunctionCallKind::StructConstructorCall: return "structConstructorCall"; default: - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of function call .")); + solAssert(false, "Unknown kind of function call."); } } @@ -804,7 +787,7 @@ string ASTJsonConverter::literalTokenKind(Token::Value _token) case dev::solidity::Token::FalseLiteral: return "bool"; default: - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of literal token.")); + solAssert(false, "Unknown kind of literal token."); } } diff --git a/libsolidity/ast/ASTJsonConverter.h b/libsolidity/ast/ASTJsonConverter.h index 27114c2a..70e260db 100644 --- a/libsolidity/ast/ASTJsonConverter.h +++ b/libsolidity/ast/ASTJsonConverter.h @@ -128,7 +128,6 @@ private: return _node ? toJson(*_node) : Json::nullValue; } Json::Value inlineAssemblyIdentifierToJson(std::pair<assembly::Identifier const* , InlineAssemblyAnnotation::ExternalIdentifierInfo> _info); - std::string visibility(Declaration::Visibility const& _visibility); std::string location(VariableDeclaration::Location _location); std::string contractKind(ContractDefinition::ContractKind _kind); std::string functionCallKind(FunctionCallKind _kind); diff --git a/libsolidity/ast/ExperimentalFeatures.h b/libsolidity/ast/ExperimentalFeatures.h new file mode 100644 index 00000000..b0a07142 --- /dev/null +++ b/libsolidity/ast/ExperimentalFeatures.h @@ -0,0 +1,35 @@ +/* + 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/>. +*/ +/** + * List of experimental features. + */ + +#pragma once + +#include <map> + +namespace dev +{ +namespace solidity +{ + +enum class ExperimentalFeature {}; + +static const std::map<std::string, ExperimentalFeature> ExperimentalFeatureNames = {}; + +} +} diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index bcfccc3e..a66ccda5 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -211,9 +211,10 @@ TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type) return make_shared<ArrayType>(DataLocation::Storage, true); //no types found default: - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment( + solAssert( + false, "Unable to convert elementary typename " + _type.toString() + " to type." - )); + ); } } @@ -476,7 +477,7 @@ MemberList::MemberMap IntegerType::nativeMembers(ContractDefinition const*) cons if (isAddress()) return { {"balance", make_shared<IntegerType >(256)}, - {"call", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::Bare, true, false, true)}, + {"call", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareCall, true, false, true)}, {"callcode", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareCallCode, true, false, true)}, {"delegatecall", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareDelegateCall, true)}, {"send", make_shared<FunctionType>(strings{"uint"}, strings{"bool"}, FunctionType::Kind::Send)}, @@ -524,19 +525,20 @@ bool FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) const TypePointer FixedPointType::unaryOperatorResult(Token::Value _operator) const { - // "delete" is ok for all fixed types - if (_operator == Token::Delete) + switch(_operator) + { + case Token::Delete: + // "delete" is ok for all fixed types return make_shared<TupleType>(); - // for fixed, we allow +, -, ++ and -- - else if ( - _operator == Token::Add || - _operator == Token::Sub || - _operator == Token::Inc || - _operator == Token::Dec - ) + case Token::Add: + case Token::Sub: + case Token::Inc: + case Token::Dec: + // for fixed, we allow +, -, ++ and -- return shared_from_this(); - else + default: return TypePointer(); + } } bool FixedPointType::operator==(Type const& _other) const @@ -1176,7 +1178,7 @@ u256 BoolType::literalValue(Literal const* _literal) const else if (_literal->token() == Token::FalseLiteral) return u256(0); else - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Bool type constructed from non-boolean literal.")); + solAssert(false, "Bool type constructed from non-boolean literal."); } TypePointer BoolType::unaryOperatorResult(Token::Value _operator) const @@ -1407,6 +1409,11 @@ unsigned ArrayType::calldataEncodedSize(bool _padded) const return unsigned(size); } +bool ArrayType::isDynamicallyEncoded() const +{ + return isDynamicallySized() || baseType()->isDynamicallyEncoded(); +} + u256 ArrayType::storageSize() const { if (isDynamicallySized()) @@ -1709,6 +1716,11 @@ unsigned StructType::calldataEncodedSize(bool _padded) const return size; } +bool StructType::isDynamicallyEncoded() const +{ + solAssert(false, "Structs are not yet supported in the ABI."); +} + u256 StructType::memorySize() const { u256 size; @@ -1938,10 +1950,7 @@ string TupleType::toString(bool _short) const u256 TupleType::storageSize() const { - BOOST_THROW_EXCEPTION( - InternalCompilerError() << - errinfo_comment("Storage size of non-storable tuple type requested.") - ); + solAssert(false, "Storage size of non-storable tuple type requested."); } unsigned TupleType::sizeOnStack() const @@ -2180,7 +2189,7 @@ string FunctionType::identifier() const case Kind::External: id += "external"; break; case Kind::CallCode: id += "callcode"; break; case Kind::DelegateCall: id += "delegatecall"; break; - case Kind::Bare: id += "bare"; break; + case Kind::BareCall: id += "barecall"; break; case Kind::BareCallCode: id += "barecallcode"; break; case Kind::BareDelegateCall: id += "baredelegatecall"; break; case Kind::Creation: id += "creation"; break; @@ -2212,6 +2221,8 @@ string FunctionType::identifier() const } if (isConstant()) id += "_constant"; + if (isPayable()) + id += "_payable"; id += identifierList(m_parameterTypes) + "returns" + identifierList(m_returnParameterTypes); if (m_gasSet) id += "gas"; @@ -2226,23 +2237,22 @@ bool FunctionType::operator==(Type const& _other) const { if (_other.category() != category()) return false; - FunctionType const& other = dynamic_cast<FunctionType const&>(_other); - if (m_kind != other.m_kind) - return false; - if (m_isConstant != other.isConstant()) + FunctionType const& other = dynamic_cast<FunctionType const&>(_other); + if ( + m_kind != other.m_kind || + m_isConstant != other.isConstant() || + m_isPayable != other.isPayable() || + m_parameterTypes.size() != other.m_parameterTypes.size() || + m_returnParameterTypes.size() != other.m_returnParameterTypes.size() + ) return false; - if (m_parameterTypes.size() != other.m_parameterTypes.size() || - m_returnParameterTypes.size() != other.m_returnParameterTypes.size()) - return false; auto typeCompare = [](TypePointer const& _a, TypePointer const& _b) -> bool { return *_a == *_b; }; - - if (!equal(m_parameterTypes.cbegin(), m_parameterTypes.cend(), - other.m_parameterTypes.cbegin(), typeCompare)) - return false; - if (!equal(m_returnParameterTypes.cbegin(), m_returnParameterTypes.cend(), - other.m_returnParameterTypes.cbegin(), typeCompare)) + if ( + !equal(m_parameterTypes.cbegin(), m_parameterTypes.cend(), other.m_parameterTypes.cbegin(), typeCompare) || + !equal(m_returnParameterTypes.cbegin(), m_returnParameterTypes.cend(), other.m_returnParameterTypes.cbegin(), typeCompare) + ) return false; //@todo this is ugly, but cannot be prevented right now if (m_gasSet != other.m_gasSet || m_valueSet != other.m_valueSet) @@ -2323,9 +2333,7 @@ u256 FunctionType::storageSize() const if (m_kind == Kind::External || m_kind == Kind::Internal) return 1; else - BOOST_THROW_EXCEPTION( - InternalCompilerError() - << errinfo_comment("Storage size of non-storable function type requested.")); + solAssert(false, "Storage size of non-storable function type requested."); } unsigned FunctionType::storageBytes() const @@ -2335,9 +2343,7 @@ unsigned FunctionType::storageBytes() const else if (m_kind == Kind::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.")); + solAssert(false, "Storage size of non-storable function type requested."); } unsigned FunctionType::sizeOnStack() const @@ -2350,14 +2356,26 @@ unsigned FunctionType::sizeOnStack() const } unsigned size = 0; - if (kind == Kind::External || kind == Kind::CallCode || kind == Kind::DelegateCall) + + switch(kind) + { + case Kind::External: + case Kind::CallCode: + case Kind::DelegateCall: size = 2; - else if (kind == Kind::Bare || kind == Kind::BareCallCode || kind == Kind::BareDelegateCall) - size = 1; - else if (kind == Kind::Internal) - size = 1; - else if (kind == Kind::ArrayPush || kind == Kind::ByteArrayPush) + break; + case Kind::BareCall: + case Kind::BareCallCode: + case Kind::BareDelegateCall: + case Kind::Internal: + case Kind::ArrayPush: + case Kind::ByteArrayPush: size = 1; + break; + default: + break; + } + if (m_gasSet) size++; if (m_valueSet) @@ -2395,10 +2413,15 @@ FunctionTypePointer FunctionType::interfaceFunctionType() const return FunctionTypePointer(); return make_shared<FunctionType>( - paramTypes, retParamTypes, - m_parameterNames, m_returnParameterNames, - m_kind, m_arbitraryParameters, - m_declaration, m_isConstant, m_isPayable + paramTypes, + retParamTypes, + m_parameterNames, + m_returnParameterNames, + m_kind, + m_arbitraryParameters, + m_declaration, + m_isConstant, + m_isPayable ); } @@ -2408,10 +2431,7 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con { case Kind::External: case Kind::Creation: - case Kind::ECRecover: - case Kind::SHA256: - case Kind::RIPEMD160: - case Kind::Bare: + case Kind::BareCall: case Kind::BareCallCode: case Kind::BareDelegateCall: { @@ -2515,7 +2535,7 @@ bool FunctionType::isBareCall() const { switch (m_kind) { - case Kind::Bare: + case Kind::BareCall: case Kind::BareCallCode: case Kind::BareDelegateCall: case Kind::ECRecover: @@ -2530,6 +2550,7 @@ bool FunctionType::isBareCall() const string FunctionType::externalSignature() const { solAssert(m_declaration != nullptr, "External signature of function needs declaration"); + solAssert(!m_declaration->name().empty(), "Fallback function has no signature."); bool _inLibrary = dynamic_cast<ContractDefinition const&>(*m_declaration->scope()).isLibrary(); @@ -2695,9 +2716,7 @@ bool TypeType::operator==(Type const& _other) const u256 TypeType::storageSize() const { - BOOST_THROW_EXCEPTION( - InternalCompilerError() - << errinfo_comment("Storage size of non-storable type type requested.")); + solAssert(false, "Storage size of non-storable type type requested."); } unsigned TypeType::sizeOnStack() const @@ -2764,9 +2783,7 @@ ModifierType::ModifierType(const ModifierDefinition& _modifier) u256 ModifierType::storageSize() const { - BOOST_THROW_EXCEPTION( - InternalCompilerError() - << errinfo_comment("Storage size of non-storable type type requested.")); + solAssert(false, "Storage size of non-storable type type requested."); } string ModifierType::identifier() const @@ -2875,7 +2892,7 @@ MemberList::MemberMap MagicType::nativeMembers(ContractDefinition const*) const {"gasprice", make_shared<IntegerType>(256)} }); default: - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of magic.")); + solAssert(false, "Unknown kind of magic."); } } @@ -2890,6 +2907,6 @@ string MagicType::toString(bool) const case Kind::Transaction: return "tx"; default: - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of magic.")); + solAssert(false, "Unknown kind of magic."); } } diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 3d7dad16..8c9232c6 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -187,6 +187,7 @@ public: /// @returns number of bytes used by this type when encoded for CALL. If it is a dynamic type, /// returns the size of the pointer (usually 32). Returns 0 if the type cannot be encoded /// in calldata. + /// @note: This should actually not be called on types, where isDynamicallyEncoded returns true. /// If @a _padded then it is assumed that each element is padded to a multiple of 32 bytes. virtual unsigned calldataEncodedSize(bool _padded) const { (void)_padded; return 0; } /// @returns the size of this data type in bytes when stored in memory. For memory-reference @@ -194,8 +195,10 @@ public: virtual unsigned memoryHeadSize() const { return calldataEncodedSize(); } /// Convenience version of @see calldataEncodedSize(bool) unsigned calldataEncodedSize() const { return calldataEncodedSize(true); } - /// @returns true if the type is dynamically encoded in calldata + /// @returns true if the type is a dynamic array virtual bool isDynamicallySized() const { return false; } + /// @returns true if the type is dynamically encoded in the ABI + virtual bool isDynamicallyEncoded() const { return false; } /// @returns the number of storage slots required to hold this value in storage. /// For dynamically "allocated" types, it returns the size of the statically allocated head, virtual u256 storageSize() const { return 1; } @@ -245,10 +248,7 @@ public: virtual std::string canonicalName(bool /*_addDataLocation*/) const { return toString(true); } virtual u256 literalValue(Literal const*) const { - BOOST_THROW_EXCEPTION( - InternalCompilerError() << - errinfo_comment("Literal value requested for type without literals.") - ); + solAssert(false, "Literal value requested for type without literals."); } /// @returns a (simpler) type that is encoded in the same way for external function calls. @@ -612,6 +612,7 @@ public: virtual bool operator==(const Type& _other) const override; virtual unsigned calldataEncodedSize(bool _padded) const override; virtual bool isDynamicallySized() const override { return m_hasDynamicLength; } + virtual bool isDynamicallyEncoded() const override; virtual u256 storageSize() const override; virtual bool canLiveOutsideStorage() const override { return m_baseType->canLiveOutsideStorage(); } virtual unsigned sizeOnStack() const override; @@ -726,6 +727,7 @@ public: virtual std::string identifier() const override; virtual bool operator==(Type const& _other) const override; virtual unsigned calldataEncodedSize(bool _padded) const override; + virtual bool isDynamicallyEncoded() const override; u256 memorySize() const; virtual u256 storageSize() const override; virtual bool canLiveOutsideStorage() const override { return true; } @@ -841,7 +843,7 @@ public: External, ///< external call using CALL CallCode, ///< external call using CALLCODE, i.e. not exchanging the storage DelegateCall, ///< external call using DELEGATECALL, i.e. not exchanging the storage - Bare, ///< CALL without function hash + BareCall, ///< CALL without function hash BareCallCode, ///< CALLCODE without function hash BareDelegateCall, ///< DELEGATECALL without function hash Creation, ///< external call using CREATE |