2014-10-07 16:25:04 +00:00
/*
2019-02-13 15:56:46 +00:00
This file is part of solidity .
2014-10-07 16:25:04 +00:00
2019-02-13 15:56:46 +00:00
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 .
2014-10-07 16:25:04 +00:00
2019-02-13 15:56:46 +00:00
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 .
2014-10-07 16:25:04 +00:00
2019-02-13 15:56:46 +00:00
You should have received a copy of the GNU General Public License
along with solidity . If not , see < http : //www.gnu.org/licenses/>.
2014-10-07 16:25:04 +00:00
*/
2020-07-17 14:54:12 +00:00
// SPDX-License-Identifier: GPL-3.0
2014-10-07 16:25:04 +00:00
/**
* @ author Christian < c @ ethdev . com >
* @ date 2014
* Solidity abstract syntax tree .
*/
2015-10-20 22:21:52 +00:00
# include <libsolidity/ast/AST.h>
2018-12-17 14:33:15 +00:00
2021-03-18 12:28:04 +00:00
# include <libsolidity/ast/CallGraph.h>
2015-10-20 22:21:52 +00:00
# include <libsolidity/ast/ASTVisitor.h>
# include <libsolidity/ast/AST_accept.h>
2019-04-15 13:33:39 +00:00
# include <libsolidity/ast/TypeProvider.h>
2022-09-27 12:13:44 +00:00
# include <libsolutil/FunctionSelector.h>
2020-01-06 10:52:23 +00:00
# include <libsolutil/Keccak256.h>
2015-01-07 15:39:21 +00:00
2022-07-06 07:17:59 +00:00
# include <range/v3/range/conversion.hpp>
2022-08-17 17:43:51 +00:00
# include <range/v3/view/tail.hpp>
2022-07-06 07:17:59 +00:00
# include <range/v3/view/zip.hpp>
2022-08-17 17:43:51 +00:00
2017-01-24 16:38:06 +00:00
# include <boost/algorithm/string.hpp>
2020-04-01 03:04:29 +00:00
2017-01-24 16:38:06 +00:00
# include <functional>
2020-04-01 03:04:29 +00:00
# include <utility>
2023-05-04 16:04:38 +00:00
# include <numeric>
# include <set>
2017-01-24 16:38:06 +00:00
2014-10-24 17:06:30 +00:00
using namespace std ;
2019-12-11 16:31:36 +00:00
using namespace solidity ;
using namespace solidity : : frontend ;
2014-10-24 17:06:30 +00:00
2022-08-17 17:43:51 +00:00
namespace
{
TryCatchClause const * findClause ( vector < ASTPointer < TryCatchClause > > const & _clauses , optional < string > _errorName = { } )
{
for ( auto const & clause : ranges : : views : : tail ( _clauses ) )
if ( _errorName . has_value ( ) ? clause - > errorName ( ) = = _errorName : clause - > errorName ( ) . empty ( ) )
return clause . get ( ) ;
return nullptr ;
}
}
2020-04-01 03:04:29 +00:00
ASTNode : : ASTNode ( int64_t _id , SourceLocation _location ) :
2020-06-02 13:42:46 +00:00
m_id ( static_cast < size_t > ( _id ) ) ,
2020-04-01 03:04:29 +00:00
m_location ( std : : move ( _location ) )
2014-10-16 12:08:54 +00:00
{
2014-10-23 17:22:30 +00:00
}
2021-03-24 15:14:58 +00:00
Declaration const * ASTNode : : referencedDeclaration ( Expression const & _expression )
{
if ( auto const * memberAccess = dynamic_cast < MemberAccess const * > ( & _expression ) )
return memberAccess - > annotation ( ) . referencedDeclaration ;
else if ( auto const * identifierPath = dynamic_cast < IdentifierPath const * > ( & _expression ) )
return identifierPath - > annotation ( ) . referencedDeclaration ;
else if ( auto const * identifier = dynamic_cast < Identifier const * > ( & _expression ) )
return identifier - > annotation ( ) . referencedDeclaration ;
else
return nullptr ;
}
2021-06-03 11:09:13 +00:00
FunctionDefinition const * ASTNode : : resolveFunctionCall ( FunctionCall const & _functionCall , ContractDefinition const * _mostDerivedContract )
{
auto const * functionDef = dynamic_cast < FunctionDefinition const * > (
ASTNode : : referencedDeclaration ( _functionCall . expression ( ) )
) ;
if ( ! functionDef )
return nullptr ;
if ( auto const * memberAccess = dynamic_cast < MemberAccess const * > ( & _functionCall . expression ( ) ) )
{
if ( * memberAccess - > annotation ( ) . requiredLookup = = VirtualLookup : : Super )
{
if ( auto const typeType = dynamic_cast < TypeType const * > ( memberAccess - > expression ( ) . annotation ( ) . type ) )
if ( auto const contractType = dynamic_cast < ContractType const * > ( typeType - > actualType ( ) ) )
{
solAssert ( _mostDerivedContract , " " ) ;
solAssert ( contractType - > isSuper ( ) , " " ) ;
ContractDefinition const * superContract = contractType - > contractDefinition ( ) . superContract ( * _mostDerivedContract ) ;
return & functionDef - > resolveVirtual (
* _mostDerivedContract ,
superContract
) ;
}
}
else
solAssert ( * memberAccess - > annotation ( ) . requiredLookup = = VirtualLookup : : Static , " " ) ;
}
else if ( auto const * identifier = dynamic_cast < Identifier const * > ( & _functionCall . expression ( ) ) )
{
solAssert ( * identifier - > annotation ( ) . requiredLookup = = VirtualLookup : : Virtual , " " ) ;
if ( functionDef - > virtualSemantics ( ) )
{
solAssert ( _mostDerivedContract , " " ) ;
return & functionDef - > resolveVirtual ( * _mostDerivedContract ) ;
}
}
else
solAssert ( false , " " ) ;
return functionDef ;
}
2015-09-21 16:55:58 +00:00
ASTAnnotation & ASTNode : : annotation ( ) const
{
if ( ! m_annotation )
2019-11-27 17:03:09 +00:00
m_annotation = make_unique < ASTAnnotation > ( ) ;
2015-09-21 16:55:58 +00:00
return * m_annotation ;
2015-01-22 00:02:38 +00:00
}
2015-12-15 14:46:03 +00:00
SourceUnitAnnotation & SourceUnit : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < SourceUnitAnnotation > ( ) ;
2015-12-15 14:46:03 +00:00
}
2017-07-13 00:07:23 +00:00
set < SourceUnit const * > SourceUnit : : referencedSourceUnits ( bool _recurse , set < SourceUnit const * > _skipList ) const
2017-07-12 23:08:28 +00:00
{
2017-07-12 23:17:25 +00:00
set < SourceUnit const * > sourceUnits ;
2017-07-12 23:08:28 +00:00
for ( ImportDirective const * importDirective : filteredNodes < ImportDirective > ( nodes ( ) ) )
{
2017-07-13 00:07:23 +00:00
auto const & sourceUnit = importDirective - > annotation ( ) . sourceUnit ;
if ( ! _skipList . count ( sourceUnit ) )
2017-07-12 23:17:25 +00:00
{
2017-07-13 00:07:23 +00:00
_skipList . insert ( sourceUnit ) ;
sourceUnits . insert ( sourceUnit ) ;
if ( _recurse )
2017-07-13 23:17:52 +00:00
sourceUnits + = sourceUnit - > referencedSourceUnits ( true , _skipList ) ;
2017-07-12 23:17:25 +00:00
}
2017-07-12 23:08:28 +00:00
}
return sourceUnits ;
}
2015-12-09 16:35:20 +00:00
ImportAnnotation & ImportDirective : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < ImportAnnotation > ( ) ;
2015-12-09 16:35:20 +00:00
}
2021-03-22 16:12:05 +00:00
Type const * ImportDirective : : type ( ) const
2015-12-15 14:46:03 +00:00
{
solAssert ( ! ! annotation ( ) . sourceUnit , " " ) ;
2019-04-17 11:40:50 +00:00
return TypeProvider : : module ( * annotation ( ) . sourceUnit ) ;
2015-12-15 14:46:03 +00:00
}
2020-01-14 13:00:51 +00:00
bool ContractDefinition : : derivesFrom ( ContractDefinition const & _base ) const
{
return util : : contains ( annotation ( ) . linearizedBaseContracts , & _base ) ;
}
2020-04-08 22:08:49 +00:00
map < util : : FixedHash < 4 > , FunctionTypePointer > ContractDefinition : : interfaceFunctions ( bool _includeInheritedFunctions ) const
2014-11-11 16:41:48 +00:00
{
2020-04-08 22:08:49 +00:00
auto exportedFunctionList = interfaceFunctionList ( _includeInheritedFunctions ) ;
2015-01-23 15:37:06 +00:00
2019-12-11 16:31:36 +00:00
map < util : : FixedHash < 4 > , FunctionTypePointer > exportedFunctions ;
2015-01-23 15:37:06 +00:00
for ( auto const & it : exportedFunctionList )
2015-01-29 15:39:30 +00:00
exportedFunctions . insert ( it ) ;
2015-01-22 16:40:22 +00:00
2015-09-10 08:17:17 +00:00
solAssert (
exportedFunctionList . size ( ) = = exportedFunctions . size ( ) ,
2015-09-08 12:30:21 +00:00
" Hash collision at Function Definition Hash calculation "
) ;
2014-11-11 16:41:48 +00:00
return exportedFunctions ;
}
2015-08-31 16:44:29 +00:00
FunctionDefinition const * ContractDefinition : : constructor ( ) const
2014-12-12 15:49:26 +00:00
{
2015-11-23 22:57:17 +00:00
for ( FunctionDefinition const * f : definedFunctions ( ) )
2015-01-20 14:58:04 +00:00
if ( f - > isConstructor ( ) )
2015-11-23 22:57:17 +00:00
return f ;
2014-12-12 15:49:26 +00:00
return nullptr ;
}
2019-01-17 19:08:17 +00:00
bool ContractDefinition : : canBeDeployed ( ) const
{
2020-06-10 16:19:42 +00:00
return ! abstract ( ) & & ! isInterface ( ) ;
2019-01-17 19:08:17 +00:00
}
2015-08-31 16:44:29 +00:00
FunctionDefinition const * ContractDefinition : : fallbackFunction ( ) const
2015-01-29 21:50:20 +00:00
{
2015-09-16 14:56:30 +00:00
for ( ContractDefinition const * contract : annotation ( ) . linearizedBaseContracts )
2015-11-23 22:57:17 +00:00
for ( FunctionDefinition const * f : contract - > definedFunctions ( ) )
2017-07-27 19:55:55 +00:00
if ( f - > isFallback ( ) )
2015-11-23 22:57:17 +00:00
return f ;
2015-01-29 21:50:20 +00:00
return nullptr ;
}
2019-09-09 16:22:02 +00:00
FunctionDefinition const * ContractDefinition : : receiveFunction ( ) const
{
for ( ContractDefinition const * contract : annotation ( ) . linearizedBaseContracts )
for ( FunctionDefinition const * f : contract - > definedFunctions ( ) )
if ( f - > isReceive ( ) )
return f ;
return nullptr ;
}
2022-02-01 14:42:08 +00:00
vector < EventDefinition const * > const & ContractDefinition : : definedInterfaceEvents ( ) const
2015-01-31 13:41:11 +00:00
{
2020-05-13 17:57:20 +00:00
return m_interfaceEvents . init ( [ & ] {
2015-01-31 13:41:11 +00:00
set < string > eventsSeen ;
2020-05-13 17:57:20 +00:00
vector < EventDefinition const * > interfaceEvents ;
2015-09-16 14:56:30 +00:00
for ( ContractDefinition const * contract : annotation ( ) . linearizedBaseContracts )
2015-11-23 22:57:17 +00:00
for ( EventDefinition const * e : contract - > events ( ) )
2017-08-25 09:41:48 +00:00
{
/// NOTE: this requires the "internal" version of an Event,
/// though here internal strictly refers to visibility,
/// and not to function encoding (jump vs. call)
2021-02-23 13:13:52 +00:00
FunctionType const * functionType = e - > functionType ( true ) ;
solAssert ( functionType , " " ) ;
string eventSignature = functionType - > externalSignature ( ) ;
2017-08-25 09:41:48 +00:00
if ( eventsSeen . count ( eventSignature ) = = 0 )
2015-01-31 13:41:11 +00:00
{
2017-08-25 09:41:48 +00:00
eventsSeen . insert ( eventSignature ) ;
2020-05-13 17:57:20 +00:00
interfaceEvents . push_back ( e ) ;
2015-01-31 13:41:11 +00:00
}
2017-08-25 09:41:48 +00:00
}
2020-05-13 17:57:20 +00:00
return interfaceEvents ;
} ) ;
2015-01-31 13:41:11 +00:00
}
2022-02-01 14:42:08 +00:00
vector < EventDefinition const * > const ContractDefinition : : usedInterfaceEvents ( ) const
{
solAssert ( annotation ( ) . creationCallGraph . set ( ) , " " ) ;
2022-03-07 04:25:35 +00:00
return util : : convertContainer < std : : vector < EventDefinition const * > > (
2022-02-01 14:42:08 +00:00
( * annotation ( ) . creationCallGraph ) - > emittedEvents +
( * annotation ( ) . deployedCallGraph ) - > emittedEvents
) ;
}
2021-02-23 13:13:52 +00:00
vector < EventDefinition const * > ContractDefinition : : interfaceEvents ( bool _requireCallGraph ) const
{
set < EventDefinition const * , CompareByID > result ;
for ( ContractDefinition const * contract : annotation ( ) . linearizedBaseContracts )
result + = contract - > events ( ) ;
solAssert ( annotation ( ) . creationCallGraph . set ( ) = = annotation ( ) . deployedCallGraph . set ( ) ) ;
if ( _requireCallGraph )
solAssert ( annotation ( ) . creationCallGraph . set ( ) ) ;
if ( annotation ( ) . creationCallGraph . set ( ) )
result + = usedInterfaceEvents ( ) ;
// We could filter out all events that do not have an external interface
// if _requireCallGraph is false.
return util : : convertContainer < vector < EventDefinition const * > > ( std : : move ( result ) ) ;
}
2021-03-18 12:28:04 +00:00
vector < ErrorDefinition const * > ContractDefinition : : interfaceErrors ( bool _requireCallGraph ) const
2021-01-28 11:56:22 +00:00
{
set < ErrorDefinition const * , CompareByID > result ;
for ( ContractDefinition const * contract : annotation ( ) . linearizedBaseContracts )
result + = filteredNodes < ErrorDefinition > ( contract - > m_subNodes ) ;
2021-03-18 12:28:04 +00:00
solAssert ( annotation ( ) . creationCallGraph . set ( ) = = annotation ( ) . deployedCallGraph . set ( ) , " " ) ;
if ( _requireCallGraph )
solAssert ( annotation ( ) . creationCallGraph . set ( ) , " " ) ;
if ( annotation ( ) . creationCallGraph . set ( ) )
2022-02-01 14:42:08 +00:00
result + =
( * annotation ( ) . creationCallGraph ) - > usedErrors +
( * annotation ( ) . deployedCallGraph ) - > usedErrors ;
2022-08-23 17:28:45 +00:00
return util : : convertContainer < vector < ErrorDefinition const * > > ( std : : move ( result ) ) ;
2021-01-28 11:56:22 +00:00
}
2020-04-08 22:08:49 +00:00
vector < pair < util : : FixedHash < 4 > , FunctionTypePointer > > const & ContractDefinition : : interfaceFunctionList ( bool _includeInheritedFunctions ) const
2015-01-16 16:50:10 +00:00
{
2020-05-13 17:59:15 +00:00
return m_interfaceFunctionList [ _includeInheritedFunctions ] . init ( [ & ] {
2015-03-01 03:34:39 +00:00
set < string > signaturesSeen ;
2020-05-13 17:59:15 +00:00
vector < pair < util : : FixedHash < 4 > , FunctionTypePointer > > interfaceFunctionList ;
2015-09-16 14:56:30 +00:00
for ( ContractDefinition const * contract : annotation ( ) . linearizedBaseContracts )
2015-01-22 16:40:22 +00:00
{
2020-04-08 22:08:49 +00:00
if ( _includeInheritedFunctions = = false & & contract ! = this )
continue ;
2015-10-16 11:11:16 +00:00
vector < FunctionTypePointer > functions ;
2015-11-23 22:57:17 +00:00
for ( FunctionDefinition const * f : contract - > definedFunctions ( ) )
2015-10-16 11:11:16 +00:00
if ( f - > isPartOfExternalInterface ( ) )
2020-01-07 10:42:37 +00:00
functions . push_back ( TypeProvider : : function ( * f , FunctionType : : Kind : : External ) ) ;
2015-11-23 22:57:17 +00:00
for ( VariableDeclaration const * v : contract - > stateVariables ( ) )
2015-10-16 11:11:16 +00:00
if ( v - > isPartOfExternalInterface ( ) )
2019-04-17 11:40:50 +00:00
functions . push_back ( TypeProvider : : function ( * v ) ) ;
2015-10-16 11:11:16 +00:00
for ( FunctionTypePointer const & fun : functions )
2015-03-01 03:34:39 +00:00
{
2015-10-16 11:11:16 +00:00
if ( ! fun - > interfaceFunctionType ( ) )
// Fails hopefully because we already registered the error
2015-06-26 14:52:30 +00:00
continue ;
2015-10-16 11:11:16 +00:00
string functionSignature = fun - > externalSignature ( ) ;
2015-06-26 14:52:30 +00:00
if ( signaturesSeen . count ( functionSignature ) = = 0 )
2015-01-16 16:50:10 +00:00
{
2015-03-01 03:34:39 +00:00
signaturesSeen . insert ( functionSignature ) ;
2022-09-27 12:13:44 +00:00
interfaceFunctionList . emplace_back ( util : : selectorFromSignatureH32 ( functionSignature ) , fun ) ;
2015-01-16 16:50:10 +00:00
}
2015-03-01 03:34:39 +00:00
}
2015-01-22 16:40:22 +00:00
}
2020-05-13 17:59:15 +00:00
return interfaceFunctionList ;
} ) ;
2015-01-14 09:16:58 +00:00
}
2020-11-11 18:36:50 +00:00
uint32_t ContractDefinition : : interfaceId ( ) const
2020-09-14 10:39:38 +00:00
{
2020-11-11 18:36:50 +00:00
uint32_t result { 0 } ;
2020-09-14 10:39:38 +00:00
for ( auto const & function : interfaceFunctionList ( false ) )
2021-09-16 14:33:28 +00:00
result ^ = fromBigEndian < uint32_t > ( function . first . ref ( ) ) ;
2020-09-14 10:39:38 +00:00
return result ;
}
2021-03-22 16:12:05 +00:00
Type const * ContractDefinition : : type ( ) const
2015-02-10 12:40:21 +00:00
{
2019-04-17 11:40:50 +00:00
return TypeProvider : : typeType ( TypeProvider : : contract ( * this ) ) ;
2015-01-19 20:05:47 +00:00
}
2015-09-21 16:55:58 +00:00
ContractDefinitionAnnotation & ContractDefinition : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < ContractDefinitionAnnotation > ( ) ;
2015-09-21 16:55:58 +00:00
}
2020-04-06 15:30:01 +00:00
ContractDefinition const * ContractDefinition : : superContract ( ContractDefinition const & _mostDerivedContract ) const
{
auto const & hierarchy = _mostDerivedContract . annotation ( ) . linearizedBaseContracts ;
auto it = find ( hierarchy . begin ( ) , hierarchy . end ( ) , this ) ;
solAssert ( it ! = hierarchy . end ( ) , " Base not found in inheritance hierarchy. " ) ;
+ + it ;
if ( it = = hierarchy . end ( ) )
return nullptr ;
else
{
solAssert ( * it ! = this , " " ) ;
return * it ;
}
}
FunctionDefinition const * ContractDefinition : : nextConstructor ( ContractDefinition const & _mostDerivedContract ) const
{
ContractDefinition const * next = superContract ( _mostDerivedContract ) ;
if ( next = = nullptr )
return nullptr ;
for ( ContractDefinition const * c : _mostDerivedContract . annotation ( ) . linearizedBaseContracts )
if ( c = = next | | next = = nullptr )
{
if ( c - > constructor ( ) )
return c - > constructor ( ) ;
next = nullptr ;
}
return nullptr ;
}
2021-06-01 12:55:35 +00:00
multimap < std : : string , FunctionDefinition const * > const & ContractDefinition : : definedFunctionsByName ( ) const
{
return m_definedFunctionsByName . init ( [ & ] {
std : : multimap < std : : string , FunctionDefinition const * > result ;
for ( FunctionDefinition const * fun : filteredNodes < FunctionDefinition > ( m_subNodes ) )
result . insert ( { fun - > name ( ) , fun } ) ;
return result ;
} ) ;
}
2015-09-21 16:55:58 +00:00
TypeNameAnnotation & TypeName : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < TypeNameAnnotation > ( ) ;
2015-09-21 16:55:58 +00:00
}
2021-07-28 08:32:59 +00:00
Type const * UserDefinedValueTypeDefinition : : type ( ) const
{
solAssert ( m_underlyingType - > annotation ( ) . type , " " ) ;
return TypeProvider : : typeType ( TypeProvider : : userDefinedValueType ( * this ) ) ;
}
2021-09-14 15:31:00 +00:00
TypeDeclarationAnnotation & UserDefinedValueTypeDefinition : : annotation ( ) const
{
return initAnnotation < TypeDeclarationAnnotation > ( ) ;
}
2022-07-06 07:17:59 +00:00
std : : vector < std : : pair < ASTPointer < IdentifierPath > , std : : optional < Token > > > UsingForDirective : : functionsAndOperators ( ) const
{
return ranges : : zip_view ( m_functionsOrLibrary , m_operators ) | ranges : : to < vector > ;
}
2023-05-09 10:16:06 +00:00
void StructDefinition : : insertEip712EncodedSubtypes ( std : : set < std : : string > & subtypes ) const
2023-05-04 15:35:59 +00:00
{
for ( size_t i = 0 ; i < m_members . size ( ) ; i + + )
{
if ( m_members [ i ] - > type ( ) - > category ( ) = = Type : : Category : : Struct )
{
Declaration const * declaration = m_members [ i ] - > type ( ) - > typeDefinition ( ) ;
StructDefinition const * structDef = dynamic_cast < StructDefinition const * > ( declaration ) ;
solAssert ( structDef ! = nullptr ) ;
2023-05-09 10:16:06 +00:00
subtypes . insert ( structDef - > eip712EncodeTypeWithoutSubtypes ( ) ) ;
structDef - > insertEip712EncodedSubtypes ( subtypes ) ;
2023-05-04 15:35:59 +00:00
}
}
}
2023-05-09 10:16:06 +00:00
std : : string StructDefinition : : eip712EncodeTypeWithoutSubtypes ( ) const
2023-04-28 08:54:52 +00:00
{
std : : string str = name ( ) + " ( " ;
for ( size_t i = 0 ; i < m_members . size ( ) ; i + + )
{
str + = i = = 0 ? " " : " , " ;
str + = m_members [ i ] - > type ( ) - > canonicalName ( ) + " " + m_members [ i ] - > name ( ) ;
}
2023-05-04 15:35:59 +00:00
return str + " ) " ;
}
2023-05-09 10:16:06 +00:00
std : : string StructDefinition : : eip712EncodeType ( ) const
2023-05-04 15:35:59 +00:00
{
2023-05-09 10:38:12 +00:00
// EIP-712 supports recurvie structs, but not containing nested mappings
solAssert ( ! annotation ( ) . containsNestedMapping . has_value ( ) | | ! annotation ( ) . containsNestedMapping . value ( ) , " Struct containing mapping cannot be used in EIP-712. " ) ;
2023-05-04 15:35:59 +00:00
// std::set enables duplicates elimination and ordered enumeration
std : : set < std : : string > subtypes ;
2023-05-09 10:16:06 +00:00
insertEip712EncodedSubtypes ( subtypes ) ;
return std : : accumulate ( subtypes . begin ( ) , subtypes . end ( ) , eip712EncodeTypeWithoutSubtypes ( ) ) ;
2023-05-04 11:36:06 +00:00
}
util : : h256 StructDefinition : : typehash ( ) const
{
2023-05-09 10:16:06 +00:00
return util : : keccak256 ( eip712EncodeType ( ) ) ;
2023-04-28 08:54:52 +00:00
}
2021-03-22 16:12:05 +00:00
Type const * StructDefinition : : type ( ) const
2015-01-22 00:02:38 +00:00
{
2020-04-14 14:36:37 +00:00
solAssert ( annotation ( ) . recursive . has_value ( ) , " Requested struct type before DeclarationTypeChecker. " ) ;
2019-04-15 15:28:32 +00:00
return TypeProvider : : typeType ( TypeProvider : : structType ( * this , DataLocation : : Storage ) ) ;
2015-01-22 00:02:38 +00:00
}
2020-04-14 14:36:37 +00:00
StructDeclarationAnnotation & StructDefinition : : annotation ( ) const
2015-10-05 15:19:23 +00:00
{
2020-04-14 14:36:37 +00:00
return initAnnotation < StructDeclarationAnnotation > ( ) ;
2015-10-05 15:19:23 +00:00
}
2021-03-22 16:12:05 +00:00
Type const * EnumValue : : type ( ) const
2014-12-03 06:46:55 +00:00
{
2015-09-16 14:56:30 +00:00
auto parentDef = dynamic_cast < EnumDefinition const * > ( scope ( ) ) ;
solAssert ( parentDef , " Enclosing Scope of EnumValue was not set " ) ;
2019-04-15 13:33:39 +00:00
return TypeProvider : : enumType ( * parentDef ) ;
2014-12-03 06:46:55 +00:00
}
2021-03-22 16:12:05 +00:00
Type const * EnumDefinition : : type ( ) const
2015-02-09 17:08:56 +00:00
{
2019-04-15 13:33:39 +00:00
return TypeProvider : : typeType ( TypeProvider : : enumType ( * this ) ) ;
2015-02-09 17:08:56 +00:00
}
2015-10-05 15:19:23 +00:00
TypeDeclarationAnnotation & EnumDefinition : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < TypeDeclarationAnnotation > ( ) ;
2015-10-05 15:19:23 +00:00
}
2020-06-09 15:56:58 +00:00
bool FunctionDefinition : : libraryFunction ( ) const
2018-03-14 15:56:06 +00:00
{
2020-06-09 15:56:58 +00:00
if ( auto const * contractDef = dynamic_cast < ContractDefinition const * > ( scope ( ) ) )
return contractDef - > isLibrary ( ) ;
return false ;
2018-03-14 15:56:06 +00:00
}
2020-06-18 15:34:05 +00:00
Visibility FunctionDefinition : : defaultVisibility ( ) const
{
solAssert ( ! isConstructor ( ) , " " ) ;
2020-06-16 01:35:09 +00:00
return isFree ( ) ? Visibility : : Internal : Declaration : : defaultVisibility ( ) ;
2020-06-18 15:34:05 +00:00
}
2017-12-30 12:44:09 +00:00
FunctionTypePointer FunctionDefinition : : functionType ( bool _internal ) const
2017-01-10 15:26:13 +00:00
{
if ( _internal )
{
switch ( visibility ( ) )
{
2019-12-10 14:54:09 +00:00
case Visibility : : Default :
2017-01-10 15:26:13 +00:00
solAssert ( false , " visibility() should not return Default " ) ;
2019-12-10 14:54:09 +00:00
case Visibility : : Private :
case Visibility : : Internal :
case Visibility : : Public :
2020-01-07 10:42:37 +00:00
return TypeProvider : : function ( * this , FunctionType : : Kind : : Internal ) ;
2019-12-10 14:54:09 +00:00
case Visibility : : External :
2017-01-10 15:26:13 +00:00
return { } ;
}
}
else
{
switch ( visibility ( ) )
{
2019-12-10 14:54:09 +00:00
case Visibility : : Default :
2017-01-10 15:26:13 +00:00
solAssert ( false , " visibility() should not return Default " ) ;
2019-12-10 14:54:09 +00:00
case Visibility : : Private :
case Visibility : : Internal :
2017-01-10 15:26:13 +00:00
return { } ;
2019-12-10 14:54:09 +00:00
case Visibility : : Public :
case Visibility : : External :
2020-01-07 10:42:37 +00:00
return TypeProvider : : function ( * this , FunctionType : : Kind : : External ) ;
2017-01-10 15:26:13 +00:00
}
}
// To make the compiler happy
return { } ;
}
2021-03-22 16:12:05 +00:00
Type const * FunctionDefinition : : type ( ) const
2015-01-22 00:02:38 +00:00
{
2019-12-10 14:54:09 +00:00
solAssert ( visibility ( ) ! = Visibility : : External , " " ) ;
2020-01-07 10:42:37 +00:00
return TypeProvider : : function ( * this , FunctionType : : Kind : : Internal ) ;
2015-01-22 00:02:38 +00:00
}
2021-03-22 16:12:05 +00:00
Type const * FunctionDefinition : : typeViaContractName ( ) const
2020-01-14 13:00:51 +00:00
{
2020-05-04 16:38:00 +00:00
if ( libraryFunction ( ) )
2020-05-25 17:30:17 +00:00
{
if ( isPublic ( ) )
2020-05-26 08:48:17 +00:00
return FunctionType ( * this ) . asExternallyCallableFunction ( true ) ;
2020-05-25 17:30:17 +00:00
else
return TypeProvider : : function ( * this , FunctionType : : Kind : : Internal ) ;
}
else
return TypeProvider : : function ( * this , FunctionType : : Kind : : Declaration ) ;
2020-01-14 13:00:51 +00:00
}
2015-03-27 12:28:32 +00:00
string FunctionDefinition : : externalSignature ( ) const
2015-01-06 16:42:38 +00:00
{
2019-04-17 11:40:50 +00:00
return TypeProvider : : function ( * this ) - > externalSignature ( ) ;
2015-01-06 16:42:38 +00:00
}
2019-12-09 00:26:23 +00:00
string FunctionDefinition : : externalIdentifierHex ( ) const
{
return TypeProvider : : function ( * this ) - > externalIdentifierHex ( ) ;
}
2015-10-26 14:13:36 +00:00
FunctionDefinitionAnnotation & FunctionDefinition : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < FunctionDefinitionAnnotation > ( ) ;
2015-10-26 14:13:36 +00:00
}
2020-03-24 17:25:59 +00:00
FunctionDefinition const & FunctionDefinition : : resolveVirtual (
ContractDefinition const & _mostDerivedContract ,
ContractDefinition const * _searchStart
) const
{
solAssert ( ! isConstructor ( ) , " " ) ;
2021-06-01 12:55:35 +00:00
solAssert ( ! name ( ) . empty ( ) , " " ) ;
2021-06-01 15:16:09 +00:00
2020-03-24 17:25:59 +00:00
// If we are not doing super-lookup and the function is not virtual, we can stop here.
if ( _searchStart = = nullptr & & ! virtualSemantics ( ) )
return * this ;
2020-05-04 16:38:00 +00:00
solAssert ( ! isFree ( ) , " " ) ;
solAssert ( isOrdinary ( ) , " " ) ;
solAssert ( ! libraryFunction ( ) , " " ) ;
2020-03-24 17:25:59 +00:00
2022-03-24 14:03:02 +00:00
// We actually do not want the externally callable function here.
// This is just to add an assertion since the comparison used to be less strict.
FunctionType const * externalFunctionType = TypeProvider : : function ( * this ) - > asExternallyCallableFunction ( false ) ;
2020-03-24 17:25:59 +00:00
2021-06-01 15:16:09 +00:00
bool foundSearchStart = ( _searchStart = = nullptr ) ;
2020-03-24 17:25:59 +00:00
for ( ContractDefinition const * c : _mostDerivedContract . annotation ( ) . linearizedBaseContracts )
{
2021-06-01 15:16:09 +00:00
if ( ! foundSearchStart & & c ! = _searchStart )
2020-03-24 17:25:59 +00:00
continue ;
2021-06-01 15:16:09 +00:00
else
foundSearchStart = true ;
2021-06-01 12:55:35 +00:00
for ( FunctionDefinition const * function : c - > definedFunctions ( name ( ) ) )
2020-03-24 17:25:59 +00:00
if (
2021-06-01 15:16:09 +00:00
// With super lookup analysis guarantees that there is an implemented function in the chain.
// With virtual lookup there are valid cases where returning an unimplemented one is fine.
( function - > isImplemented ( ) | | _searchStart = = nullptr ) & &
2022-03-24 14:03:02 +00:00
FunctionType ( * function ) . asExternallyCallableFunction ( false ) - > hasEqualParameterTypes ( * externalFunctionType )
2020-03-24 17:25:59 +00:00
)
2022-03-24 14:03:02 +00:00
{
solAssert ( FunctionType ( * function ) . hasEqualParameterTypes ( * TypeProvider : : function ( * this ) ) ) ;
2020-03-24 17:25:59 +00:00
return * function ;
2022-03-24 14:03:02 +00:00
}
2020-03-24 17:25:59 +00:00
}
2021-06-01 15:16:09 +00:00
2020-03-24 17:25:59 +00:00
solAssert ( false , " Virtual function " + name ( ) + " not found. " ) ;
return * this ; // not reached
}
2021-03-22 16:12:05 +00:00
Type const * ModifierDefinition : : type ( ) const
2015-01-22 00:02:38 +00:00
{
2019-04-17 11:40:50 +00:00
return TypeProvider : : modifier ( * this ) ;
2015-02-14 00:22:44 +00:00
}
2015-10-26 14:13:36 +00:00
ModifierDefinitionAnnotation & ModifierDefinition : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < ModifierDefinitionAnnotation > ( ) ;
2015-10-26 14:13:36 +00:00
}
2020-03-24 17:25:59 +00:00
ModifierDefinition const & ModifierDefinition : : resolveVirtual (
ContractDefinition const & _mostDerivedContract ,
ContractDefinition const * _searchStart
) const
{
2021-12-28 17:29:20 +00:00
// Super is not possible with modifiers
2020-03-24 17:25:59 +00:00
solAssert ( _searchStart = = nullptr , " Used super in connection with modifiers. " ) ;
2021-12-28 17:29:20 +00:00
// The modifier is not virtual, we can stop here.
if ( ! virtualSemantics ( ) )
2020-03-24 17:25:59 +00:00
return * this ;
solAssert ( ! dynamic_cast < ContractDefinition const & > ( * scope ( ) ) . isLibrary ( ) , " " ) ;
for ( ContractDefinition const * c : _mostDerivedContract . annotation ( ) . linearizedBaseContracts )
for ( ModifierDefinition const * modifier : c - > functionModifiers ( ) )
if ( modifier - > name ( ) = = name ( ) )
return * modifier ;
2021-12-28 17:29:20 +00:00
2020-03-24 17:25:59 +00:00
solAssert ( false , " Virtual modifier " + name ( ) + " not found. " ) ;
return * this ; // not reached
}
2021-03-22 16:12:05 +00:00
Type const * EventDefinition : : type ( ) const
2015-02-17 15:21:38 +00:00
{
2019-04-17 11:40:50 +00:00
return TypeProvider : : function ( * this ) ;
2015-09-16 14:56:30 +00:00
}
2015-03-08 22:26:36 +00:00
2017-12-30 12:44:09 +00:00
FunctionTypePointer EventDefinition : : functionType ( bool _internal ) const
2017-01-10 17:55:36 +00:00
{
if ( _internal )
2019-04-17 11:40:50 +00:00
return TypeProvider : : function ( * this ) ;
2017-01-10 17:55:36 +00:00
else
2019-04-15 13:33:39 +00:00
return nullptr ;
2017-01-10 17:55:36 +00:00
}
2015-10-26 14:13:36 +00:00
EventDefinitionAnnotation & EventDefinition : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < EventDefinitionAnnotation > ( ) ;
2015-10-26 14:13:36 +00:00
}
2021-01-28 11:56:22 +00:00
Type const * ErrorDefinition : : type ( ) const
{
return TypeProvider : : function ( * this ) ;
}
FunctionTypePointer ErrorDefinition : : functionType ( bool _internal ) const
{
if ( _internal )
return TypeProvider : : function ( * this ) ;
else
return nullptr ;
}
ErrorDefinitionAnnotation & ErrorDefinition : : annotation ( ) const
{
return initAnnotation < ErrorDefinitionAnnotation > ( ) ;
}
2018-02-14 00:48:40 +00:00
SourceUnit const & Scopable : : sourceUnit ( ) const
{
ASTNode const * s = scope ( ) ;
solAssert ( s , " " ) ;
2018-08-16 05:42:46 +00:00
// will not always be a declaration
2018-02-14 00:48:40 +00:00
while ( dynamic_cast < Scopable const * > ( s ) & & dynamic_cast < Scopable const * > ( s ) - > scope ( ) )
s = dynamic_cast < Scopable const * > ( s ) - > scope ( ) ;
return dynamic_cast < SourceUnit const & > ( * s ) ;
}
2019-05-07 09:51:32 +00:00
CallableDeclaration const * Scopable : : functionOrModifierDefinition ( ) const
{
ASTNode const * s = scope ( ) ;
solAssert ( s , " " ) ;
while ( dynamic_cast < Scopable const * > ( s ) )
{
if ( auto funDef = dynamic_cast < FunctionDefinition const * > ( s ) )
return funDef ;
if ( auto modDef = dynamic_cast < ModifierDefinition const * > ( s ) )
return modDef ;
s = dynamic_cast < Scopable const * > ( s ) - > scope ( ) ;
}
return nullptr ;
}
2018-02-14 00:48:40 +00:00
string Scopable : : sourceUnitName ( ) const
{
2020-09-10 10:01:23 +00:00
return * sourceUnit ( ) . annotation ( ) . path ;
2018-02-14 00:48:40 +00:00
}
2020-09-26 22:00:56 +00:00
bool Declaration : : isEnumValue ( ) const
{
solAssert ( scope ( ) , " " ) ;
return dynamic_cast < EnumDefinition const * > ( scope ( ) ) ;
}
bool Declaration : : isStructMember ( ) const
{
solAssert ( scope ( ) , " " ) ;
return dynamic_cast < StructDefinition const * > ( scope ( ) ) ;
}
2021-01-28 11:56:22 +00:00
bool Declaration : : isEventOrErrorParameter ( ) const
2020-09-26 22:00:56 +00:00
{
solAssert ( scope ( ) , " " ) ;
2021-01-28 11:56:22 +00:00
return dynamic_cast < EventDefinition const * > ( scope ( ) ) | | dynamic_cast < ErrorDefinition const * > ( scope ( ) ) ;
2020-09-26 22:00:56 +00:00
}
2021-02-08 04:50:58 +00:00
bool Declaration : : isVisibleAsUnqualifiedName ( ) const
{
if ( ! scope ( ) )
return true ;
if ( isStructMember ( ) | | isEnumValue ( ) | | isEventOrErrorParameter ( ) )
return false ;
if ( auto const * functionDefinition = dynamic_cast < FunctionDefinition const * > ( scope ( ) ) )
if ( ! functionDefinition - > isImplemented ( ) )
return false ; // parameter of a function without body
return true ;
}
2019-12-19 23:04:46 +00:00
DeclarationAnnotation & Declaration : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < DeclarationAnnotation > ( ) ;
2019-12-19 23:04:46 +00:00
}
2015-09-16 14:56:30 +00:00
bool VariableDeclaration : : isLValue ( ) const
{
2019-08-12 15:06:10 +00:00
// Constant declared variables are Read-Only
2020-06-22 16:10:18 +00:00
return ! isConstant ( ) ;
2015-02-17 15:21:38 +00:00
}
2018-02-09 15:53:52 +00:00
bool VariableDeclaration : : isLocalVariable ( ) const
{
auto s = scope ( ) ;
return
2018-08-07 13:58:34 +00:00
dynamic_cast < FunctionTypeName const * > ( s ) | |
2018-02-09 15:53:52 +00:00
dynamic_cast < CallableDeclaration const * > ( s ) | |
dynamic_cast < Block const * > ( s ) | |
2019-09-02 14:17:02 +00:00
dynamic_cast < TryCatchClause const * > ( s ) | |
2018-02-09 15:53:52 +00:00
dynamic_cast < ForStatement const * > ( s ) ;
}
2019-09-05 18:02:34 +00:00
bool VariableDeclaration : : isCallableOrCatchParameter ( ) const
2015-06-05 09:07:50 +00:00
{
2019-09-05 18:02:34 +00:00
if ( isReturnParameter ( ) | | isTryCatchParameter ( ) )
2018-08-07 13:58:34 +00:00
return true ;
vector < ASTPointer < VariableDeclaration > > const * parameters = nullptr ;
if ( auto const * funTypeName = dynamic_cast < FunctionTypeName const * > ( scope ( ) ) )
parameters = & funTypeName - > parameterTypes ( ) ;
else if ( auto const * callable = dynamic_cast < CallableDeclaration const * > ( scope ( ) ) )
parameters = & callable - > parameters ( ) ;
if ( parameters )
for ( auto const & variable : * parameters )
2015-06-09 12:26:08 +00:00
if ( variable . get ( ) = = this )
return true ;
2015-06-05 09:07:50 +00:00
return false ;
}
2017-07-06 09:05:05 +00:00
bool VariableDeclaration : : isLocalOrReturn ( ) const
{
2019-09-05 18:02:34 +00:00
return isReturnParameter ( ) | | ( isLocalVariable ( ) & & ! isCallableOrCatchParameter ( ) ) ;
2017-07-06 09:05:05 +00:00
}
bool VariableDeclaration : : isReturnParameter ( ) const
{
2018-08-07 13:58:34 +00:00
vector < ASTPointer < VariableDeclaration > > const * returnParameters = nullptr ;
if ( auto const * funTypeName = dynamic_cast < FunctionTypeName const * > ( scope ( ) ) )
returnParameters = & funTypeName - > returnParameterTypes ( ) ;
else if ( auto const * callable = dynamic_cast < CallableDeclaration const * > ( scope ( ) ) )
if ( callable - > returnParameterList ( ) )
returnParameters = & callable - > returnParameterList ( ) - > parameters ( ) ;
if ( returnParameters )
for ( auto const & variable : * returnParameters )
2017-07-06 09:05:05 +00:00
if ( variable . get ( ) = = this )
return true ;
return false ;
}
2019-09-05 18:02:34 +00:00
bool VariableDeclaration : : isTryCatchParameter ( ) const
{
return dynamic_cast < TryCatchClause const * > ( scope ( ) ) ;
}
2015-06-09 12:26:08 +00:00
bool VariableDeclaration : : isExternalCallableParameter ( ) const
2015-02-14 00:22:44 +00:00
{
2019-09-05 18:02:34 +00:00
if ( ! isCallableOrCatchParameter ( ) )
2015-02-14 00:22:44 +00:00
return false ;
2018-08-07 13:58:34 +00:00
if ( auto const * callable = dynamic_cast < CallableDeclaration const * > ( scope ( ) ) )
2019-12-10 14:54:09 +00:00
if ( callable - > visibility ( ) = = Visibility : : External )
2018-08-07 13:58:34 +00:00
return ! isReturnParameter ( ) ;
2015-02-14 00:22:44 +00:00
return false ;
2015-01-22 00:02:38 +00:00
}
2020-04-16 14:29:23 +00:00
bool VariableDeclaration : : isPublicCallableParameter ( ) const
{
if ( ! isCallableOrCatchParameter ( ) )
return false ;
if ( auto const * callable = dynamic_cast < CallableDeclaration const * > ( scope ( ) ) )
if ( callable - > visibility ( ) = = Visibility : : Public )
return ! isReturnParameter ( ) ;
return false ;
}
2018-08-07 13:58:34 +00:00
bool VariableDeclaration : : isInternalCallableParameter ( ) const
{
2019-09-05 18:02:34 +00:00
if ( ! isCallableOrCatchParameter ( ) )
2018-08-07 13:58:34 +00:00
return false ;
if ( auto const * funTypeName = dynamic_cast < FunctionTypeName const * > ( scope ( ) ) )
2019-12-10 14:54:09 +00:00
return funTypeName - > visibility ( ) = = Visibility : : Internal ;
2018-08-07 13:58:34 +00:00
else if ( auto const * callable = dynamic_cast < CallableDeclaration const * > ( scope ( ) ) )
2019-12-10 14:54:09 +00:00
return callable - > visibility ( ) < = Visibility : : Internal ;
2018-08-07 13:58:34 +00:00
return false ;
}
2020-07-06 14:52:51 +00:00
bool VariableDeclaration : : isConstructorParameter ( ) const
{
if ( ! isCallableOrCatchParameter ( ) )
return false ;
if ( auto const * function = dynamic_cast < FunctionDefinition const * > ( scope ( ) ) )
return function - > isConstructor ( ) ;
return false ;
}
2018-08-07 13:58:34 +00:00
bool VariableDeclaration : : isLibraryFunctionParameter ( ) const
{
2019-09-05 18:02:34 +00:00
if ( ! isCallableOrCatchParameter ( ) )
2018-08-07 13:58:34 +00:00
return false ;
if ( auto const * funDef = dynamic_cast < FunctionDefinition const * > ( scope ( ) ) )
2020-05-04 16:38:00 +00:00
return funDef - > libraryFunction ( ) ;
return false ;
2018-08-07 13:58:34 +00:00
}
bool VariableDeclaration : : hasReferenceOrMappingType ( ) const
{
2020-07-15 17:50:59 +00:00
solAssert ( typeName ( ) . annotation ( ) . type , " Can only be called after reference resolution " ) ;
Type const * type = typeName ( ) . annotation ( ) . type ;
2019-04-15 13:33:39 +00:00
return type - > category ( ) = = Type : : Category : : Mapping | | dynamic_cast < ReferenceType const * > ( type ) ;
2018-08-07 13:58:34 +00:00
}
2020-09-28 17:31:54 +00:00
bool VariableDeclaration : : isStateVariable ( ) const
{
return dynamic_cast < ContractDefinition const * > ( scope ( ) ) ;
}
2020-09-25 10:15:31 +00:00
bool VariableDeclaration : : isFileLevelVariable ( ) const
{
return dynamic_cast < SourceUnit const * > ( scope ( ) ) ;
}
2018-08-07 13:58:34 +00:00
set < VariableDeclaration : : Location > VariableDeclaration : : allowedDataLocations ( ) const
{
using Location = VariableDeclaration : : Location ;
2021-01-28 11:56:22 +00:00
if ( ! hasReferenceOrMappingType ( ) | | isStateVariable ( ) | | isEventOrErrorParameter ( ) )
2018-08-17 23:09:31 +00:00
return set < Location > { Location : : Unspecified } ;
2019-09-05 18:02:34 +00:00
else if ( isCallableOrCatchParameter ( ) )
2018-08-07 13:58:34 +00:00
{
set < Location > locations { Location : : Memory } ;
2020-06-18 15:34:05 +00:00
if (
isConstructorParameter ( ) | |
isInternalCallableParameter ( ) | |
2021-05-31 09:21:04 +00:00
isLibraryFunctionParameter ( )
2020-06-18 15:34:05 +00:00
)
2018-08-07 13:58:34 +00:00
locations . insert ( Location : : Storage ) ;
2020-07-06 14:52:51 +00:00
if ( ! isTryCatchParameter ( ) & & ! isConstructorParameter ( ) )
2020-05-25 17:30:17 +00:00
locations . insert ( Location : : CallData ) ;
2018-08-07 13:58:34 +00:00
return locations ;
}
else if ( isLocalVariable ( ) )
2020-07-15 17:50:59 +00:00
// Further restrictions will be imposed later on.
return set < Location > { Location : : Memory , Location : : Storage , Location : : CallData } ;
2018-08-07 13:58:34 +00:00
else
// Struct members etc.
2018-08-17 23:09:31 +00:00
return set < Location > { Location : : Unspecified } ;
2018-08-07 13:58:34 +00:00
}
2019-12-09 00:26:23 +00:00
string VariableDeclaration : : externalIdentifierHex ( ) const
{
solAssert ( isStateVariable ( ) & & isPublic ( ) , " Can only be called for public state variables " ) ;
return TypeProvider : : function ( * this ) - > externalIdentifierHex ( ) ;
}
2021-03-22 16:12:05 +00:00
Type const * VariableDeclaration : : type ( ) const
2014-10-13 16:22:15 +00:00
{
2015-09-16 14:56:30 +00:00
return annotation ( ) . type ;
2014-10-16 12:08:54 +00:00
}
2015-09-21 16:55:58 +00:00
2017-12-30 12:44:09 +00:00
FunctionTypePointer VariableDeclaration : : functionType ( bool _internal ) const
2017-01-10 15:26:13 +00:00
{
if ( _internal )
2019-04-15 13:33:39 +00:00
return nullptr ;
2017-01-10 15:26:13 +00:00
switch ( visibility ( ) )
{
2019-12-10 14:54:09 +00:00
case Visibility : : Default :
2017-01-10 15:26:13 +00:00
solAssert ( false , " visibility() should not return Default " ) ;
2019-12-10 14:54:09 +00:00
case Visibility : : Private :
case Visibility : : Internal :
2019-04-15 13:33:39 +00:00
return nullptr ;
2019-12-10 14:54:09 +00:00
case Visibility : : Public :
case Visibility : : External :
2019-04-17 11:40:50 +00:00
return TypeProvider : : function ( * this ) ;
2017-01-10 15:26:13 +00:00
}
// To make the compiler happy
2019-04-15 13:33:39 +00:00
return nullptr ;
2017-01-10 15:26:13 +00:00
}
2015-09-21 16:55:58 +00:00
VariableDeclarationAnnotation & VariableDeclaration : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < VariableDeclarationAnnotation > ( ) ;
2015-09-21 16:55:58 +00:00
}
2015-10-26 16:20:29 +00:00
StatementAnnotation & Statement : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < StatementAnnotation > ( ) ;
2015-10-26 16:20:29 +00:00
}
2016-03-01 21:56:39 +00:00
InlineAssemblyAnnotation & InlineAssembly : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < InlineAssemblyAnnotation > ( ) ;
2016-03-01 21:56:39 +00:00
}
2019-12-20 01:20:27 +00:00
BlockAnnotation & Block : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < BlockAnnotation > ( ) ;
2019-12-20 01:20:27 +00:00
}
TryCatchClauseAnnotation & TryCatchClause : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < TryCatchClauseAnnotation > ( ) ;
2019-12-20 01:20:27 +00:00
}
ForStatementAnnotation & ForStatement : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < ForStatementAnnotation > ( ) ;
2019-12-20 01:20:27 +00:00
}
2015-09-21 16:55:58 +00:00
ReturnAnnotation & Return : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < ReturnAnnotation > ( ) ;
2015-09-21 16:55:58 +00:00
}
ExpressionAnnotation & Expression : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < ExpressionAnnotation > ( ) ;
2015-09-21 16:55:58 +00:00
}
MemberAccessAnnotation & MemberAccess : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < MemberAccessAnnotation > ( ) ;
2015-09-21 16:55:58 +00:00
}
2022-07-06 07:17:59 +00:00
OperationAnnotation & UnaryOperation : : annotation ( ) const
{
return initAnnotation < OperationAnnotation > ( ) ;
}
FunctionType const * UnaryOperation : : userDefinedFunctionType ( ) const
{
if ( * annotation ( ) . userDefinedFunction = = nullptr )
return nullptr ;
FunctionDefinition const * userDefinedFunction = * annotation ( ) . userDefinedFunction ;
return dynamic_cast < FunctionType const * > (
userDefinedFunction - > libraryFunction ( ) ?
userDefinedFunction - > typeViaContractName ( ) :
userDefinedFunction - > type ( )
) ;
}
FunctionType const * BinaryOperation : : userDefinedFunctionType ( ) const
{
if ( * annotation ( ) . userDefinedFunction = = nullptr )
return nullptr ;
FunctionDefinition const * userDefinedFunction = * annotation ( ) . userDefinedFunction ;
return dynamic_cast < FunctionType const * > (
userDefinedFunction - > libraryFunction ( ) ?
userDefinedFunction - > typeViaContractName ( ) :
userDefinedFunction - > type ( )
) ;
}
2015-09-21 16:55:58 +00:00
BinaryOperationAnnotation & BinaryOperation : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < BinaryOperationAnnotation > ( ) ;
2015-09-21 16:55:58 +00:00
}
FunctionCallAnnotation & FunctionCall : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < FunctionCallAnnotation > ( ) ;
2015-09-21 16:55:58 +00:00
}
2020-11-09 13:09:34 +00:00
vector < ASTPointer < Expression const > > FunctionCall : : sortedArguments ( ) const
{
// normal arguments
if ( m_names . empty ( ) )
return arguments ( ) ;
// named arguments
FunctionTypePointer functionType ;
if ( * annotation ( ) . kind = = FunctionCallKind : : StructConstructorCall )
{
auto const & type = dynamic_cast < TypeType const & > ( * m_expression - > annotation ( ) . type ) ;
auto const & structType = dynamic_cast < StructType const & > ( * type . actualType ( ) ) ;
functionType = structType . constructorType ( ) ;
}
else
functionType = dynamic_cast < FunctionType const * > ( m_expression - > annotation ( ) . type ) ;
vector < ASTPointer < Expression const > > sorted ;
for ( auto const & parameterName : functionType - > parameterNames ( ) )
{
bool found = false ;
for ( size_t j = 0 ; j < m_names . size ( ) & & ! found ; j + + )
if ( ( found = ( parameterName = = * m_names . at ( j ) ) ) )
// we found the actual parameter position
sorted . push_back ( m_arguments . at ( j ) ) ;
solAssert ( found , " " ) ;
}
if ( ! functionType - > takesArbitraryParameters ( ) )
{
solAssert ( m_arguments . size ( ) = = functionType - > parameterTypes ( ) . size ( ) , " " ) ;
solAssert ( m_arguments . size ( ) = = m_names . size ( ) , " " ) ;
solAssert ( m_arguments . size ( ) = = sorted . size ( ) , " " ) ;
}
return sorted ;
}
2015-09-21 16:55:58 +00:00
IdentifierAnnotation & Identifier : : annotation ( ) const
{
2019-12-21 04:10:01 +00:00
return initAnnotation < IdentifierAnnotation > ( ) ;
2015-09-21 16:55:58 +00:00
}
2017-01-24 16:38:06 +00:00
2018-10-01 12:36:57 +00:00
ASTString Literal : : valueWithoutUnderscores ( ) const
{
return boost : : erase_all_copy ( value ( ) , " _ " ) ;
}
2017-06-28 15:59:34 +00:00
bool Literal : : isHexNumber ( ) const
2017-06-26 11:49:05 +00:00
{
if ( token ( ) ! = Token : : Number )
return false ;
2017-06-28 16:00:14 +00:00
return boost : : starts_with ( value ( ) , " 0x " ) ;
2017-06-26 11:49:05 +00:00
}
2017-01-24 16:38:06 +00:00
bool Literal : : looksLikeAddress ( ) const
{
if ( subDenomination ( ) ! = SubDenomination : : None )
return false ;
2017-06-26 11:49:05 +00:00
2017-06-28 15:59:34 +00:00
if ( ! isHexNumber ( ) )
2017-06-22 14:39:42 +00:00
return false ;
2017-01-24 16:38:06 +00:00
2018-10-01 12:36:57 +00:00
return abs ( int ( valueWithoutUnderscores ( ) . length ( ) ) - 42 ) < = 1 ;
2017-01-24 16:38:06 +00:00
}
bool Literal : : passesAddressChecksum ( ) const
{
2017-06-28 15:59:34 +00:00
solAssert ( isHexNumber ( ) , " Expected hex number " ) ;
2019-12-11 16:31:36 +00:00
return util : : passesAddressChecksum ( valueWithoutUnderscores ( ) , true ) ;
2017-01-24 16:38:06 +00:00
}
2017-10-05 13:28:25 +00:00
2018-08-07 13:58:34 +00:00
string Literal : : getChecksummedAddress ( ) const
2017-10-05 13:28:25 +00:00
{
solAssert ( isHexNumber ( ) , " Expected hex number " ) ;
2017-10-24 10:01:56 +00:00
/// Pad literal to be a proper hex address.
2018-10-01 12:36:57 +00:00
string address = valueWithoutUnderscores ( ) . substr ( 2 ) ;
2017-10-24 10:01:56 +00:00
if ( address . length ( ) > 40 )
2017-10-24 09:54:51 +00:00
return string ( ) ;
2017-10-24 10:01:56 +00:00
address . insert ( address . begin ( ) , 40 - address . size ( ) , ' 0 ' ) ;
2019-12-11 16:31:36 +00:00
return util : : getChecksummedAddress ( address ) ;
2017-10-05 13:28:25 +00:00
}
2020-03-16 10:47:39 +00:00
TryCatchClause const * TryStatement : : successClause ( ) const
{
solAssert ( m_clauses . size ( ) > 0 , " " ) ;
return m_clauses [ 0 ] . get ( ) ;
}
2022-08-17 17:43:51 +00:00
TryCatchClause const * TryStatement : : panicClause ( ) const {
return findClause ( m_clauses , " Panic " ) ;
2020-10-20 13:30:46 +00:00
}
2022-08-17 17:43:51 +00:00
TryCatchClause const * TryStatement : : errorClause ( ) const {
return findClause ( m_clauses , " Error " ) ;
2020-03-16 10:47:39 +00:00
}
2022-08-17 17:43:51 +00:00
TryCatchClause const * TryStatement : : fallbackClause ( ) const {
return findClause ( m_clauses ) ;
2020-03-16 10:47:39 +00:00
}