mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Change type of super to TypeType
This commit is contained in:
parent
da92fe548e
commit
9eafa1fa1a
@ -140,7 +140,7 @@ MagicVariableDeclaration const* GlobalContext::currentSuper() const
|
|||||||
{
|
{
|
||||||
Type const* type = TypeProvider::emptyTuple();
|
Type const* type = TypeProvider::emptyTuple();
|
||||||
if (m_currentContract)
|
if (m_currentContract)
|
||||||
type = TypeProvider::contract(*m_currentContract, true);
|
type = TypeProvider::typeType(TypeProvider::contract(*m_currentContract, true));
|
||||||
m_superPointer[m_currentContract] =
|
m_superPointer[m_currentContract] =
|
||||||
make_shared<MagicVariableDeclaration>(magicVariableToID("super"), "super", type);
|
make_shared<MagicVariableDeclaration>(magicVariableToID("super"), "super", type);
|
||||||
}
|
}
|
||||||
|
@ -2760,10 +2760,13 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!funType->bound())
|
if (!funType->bound())
|
||||||
if (auto contractType = dynamic_cast<ContractType const*>(exprType))
|
if (auto typeType = dynamic_cast<TypeType const*>(exprType))
|
||||||
if (contractType->isSuper())
|
{
|
||||||
|
auto contractType = dynamic_cast<ContractType const*>(typeType->actualType());
|
||||||
|
if (contractType && contractType->isSuper())
|
||||||
requiredLookup = VirtualLookup::Super;
|
requiredLookup = VirtualLookup::Super;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
annotation.requiredLookup = requiredLookup;
|
annotation.requiredLookup = requiredLookup;
|
||||||
|
|
||||||
@ -2837,8 +2840,13 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
|
|||||||
_memberAccess.location(),
|
_memberAccess.location(),
|
||||||
"\"runtimeCode\" is not available for contracts containing immutable variables."
|
"\"runtimeCode\" is not available for contracts containing immutable variables."
|
||||||
);
|
);
|
||||||
|
if (accessedContractType.isSuper())
|
||||||
if (m_currentContract)
|
m_errorReporter.typeError(
|
||||||
|
3625_error,
|
||||||
|
_memberAccess.location(),
|
||||||
|
"\"creationCode\" and \"runtimeCode\" are not available for the \"super\" contract."
|
||||||
|
);
|
||||||
|
else if (m_currentContract)
|
||||||
{
|
{
|
||||||
// TODO in the same way as with ``new``,
|
// TODO in the same way as with ``new``,
|
||||||
// this is not properly detecting creation-cycles if they go through
|
// this is not properly detecting creation-cycles if they go through
|
||||||
|
@ -194,8 +194,8 @@ void ViewPureChecker::endVisit(Identifier const& _identifier)
|
|||||||
switch (magicVar->type()->category())
|
switch (magicVar->type()->category())
|
||||||
{
|
{
|
||||||
case Type::Category::Contract:
|
case Type::Category::Contract:
|
||||||
solAssert(_identifier.name() == "this" || _identifier.name() == "super", "");
|
solAssert(_identifier.name() == "this", "");
|
||||||
if (!dynamic_cast<ContractType const&>(*magicVar->type()).isSuper())
|
if (dynamic_cast<ContractType const*>(magicVar->type()))
|
||||||
// reads the address
|
// reads the address
|
||||||
mutability = StateMutability::View;
|
mutability = StateMutability::View;
|
||||||
break;
|
break;
|
||||||
@ -440,4 +440,3 @@ void ViewPureChecker::endVisit(ModifierInvocation const& _modifier)
|
|||||||
else
|
else
|
||||||
solAssert(dynamic_cast<ContractDefinition const*>(_modifier.name().annotation().referencedDeclaration), "");
|
solAssert(dynamic_cast<ContractDefinition const*>(_modifier.name().annotation().referencedDeclaration), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2158,36 +2158,8 @@ string ContractType::canonicalName() const
|
|||||||
MemberList::MemberMap ContractType::nativeMembers(ASTNode const*) const
|
MemberList::MemberMap ContractType::nativeMembers(ASTNode const*) const
|
||||||
{
|
{
|
||||||
MemberList::MemberMap members;
|
MemberList::MemberMap members;
|
||||||
if (m_super)
|
solAssert(!m_super, "");
|
||||||
{
|
if (!m_contract.isLibrary())
|
||||||
// add the most derived of all functions which are visible in derived contracts
|
|
||||||
auto bases = m_contract.annotation().linearizedBaseContracts;
|
|
||||||
solAssert(bases.size() >= 1, "linearizedBaseContracts should at least contain the most derived contract.");
|
|
||||||
// `sliced(1, ...)` ignores the most derived contract, which should not be searchable from `super`.
|
|
||||||
for (ContractDefinition const* base: bases | boost::adaptors::sliced(1, bases.size()))
|
|
||||||
for (FunctionDefinition const* function: base->definedFunctions())
|
|
||||||
{
|
|
||||||
if (!function->isVisibleInDerivedContracts() || !function->isImplemented())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto functionType = TypeProvider::function(*function, FunctionType::Kind::Internal);
|
|
||||||
bool functionWithEqualArgumentsFound = false;
|
|
||||||
for (auto const& member: members)
|
|
||||||
{
|
|
||||||
if (member.name != function->name())
|
|
||||||
continue;
|
|
||||||
auto memberType = dynamic_cast<FunctionType const*>(member.type);
|
|
||||||
solAssert(!!memberType, "Override changes type.");
|
|
||||||
if (!memberType->hasEqualParameterTypes(*functionType))
|
|
||||||
continue;
|
|
||||||
functionWithEqualArgumentsFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!functionWithEqualArgumentsFound)
|
|
||||||
members.emplace_back(function->name(), functionType, function);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!m_contract.isLibrary())
|
|
||||||
for (auto const& it: m_contract.interfaceFunctions())
|
for (auto const& it: m_contract.interfaceFunctions())
|
||||||
members.emplace_back(
|
members.emplace_back(
|
||||||
it.second->declaration().name(),
|
it.second->declaration().name(),
|
||||||
@ -3838,7 +3810,11 @@ vector<tuple<string, TypePointer>> TypeType::makeStackItems() const
|
|||||||
{
|
{
|
||||||
if (auto contractType = dynamic_cast<ContractType const*>(m_actualType))
|
if (auto contractType = dynamic_cast<ContractType const*>(m_actualType))
|
||||||
if (contractType->contractDefinition().isLibrary())
|
if (contractType->contractDefinition().isLibrary())
|
||||||
|
{
|
||||||
|
solAssert(!contractType->isSuper(), "");
|
||||||
return {make_tuple("address", TypeProvider::address())};
|
return {make_tuple("address", TypeProvider::address())};
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3846,9 +3822,41 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons
|
|||||||
{
|
{
|
||||||
MemberList::MemberMap members;
|
MemberList::MemberMap members;
|
||||||
if (m_actualType->category() == Category::Contract)
|
if (m_actualType->category() == Category::Contract)
|
||||||
|
{
|
||||||
|
auto contractType = dynamic_cast<ContractType const*>(m_actualType);
|
||||||
|
ContractDefinition const& contract = contractType->contractDefinition();
|
||||||
|
if (contractType->isSuper())
|
||||||
|
{
|
||||||
|
// add the most derived of all functions which are visible in derived contracts
|
||||||
|
auto bases = contract.annotation().linearizedBaseContracts;
|
||||||
|
solAssert(bases.size() >= 1, "linearizedBaseContracts should at least contain the most derived contract.");
|
||||||
|
// `sliced(1, ...)` ignores the most derived contract, which should not be searchable from `super`.
|
||||||
|
for (ContractDefinition const* base: bases | boost::adaptors::sliced(1, bases.size()))
|
||||||
|
for (FunctionDefinition const* function: base->definedFunctions())
|
||||||
|
{
|
||||||
|
if (!function->isVisibleInDerivedContracts() || !function->isImplemented())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto functionType = TypeProvider::function(*function, FunctionType::Kind::Internal);
|
||||||
|
bool functionWithEqualArgumentsFound = false;
|
||||||
|
for (auto const& member: members)
|
||||||
|
{
|
||||||
|
if (member.name != function->name())
|
||||||
|
continue;
|
||||||
|
auto memberType = dynamic_cast<FunctionType const*>(member.type);
|
||||||
|
solAssert(!!memberType, "Override changes type.");
|
||||||
|
if (!memberType->hasEqualParameterTypes(*functionType))
|
||||||
|
continue;
|
||||||
|
functionWithEqualArgumentsFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!functionWithEqualArgumentsFound)
|
||||||
|
members.emplace_back(function->name(), functionType, function);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
auto const* contractScope = dynamic_cast<ContractDefinition const*>(_currentScope);
|
auto const* contractScope = dynamic_cast<ContractDefinition const*>(_currentScope);
|
||||||
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*m_actualType).contractDefinition();
|
|
||||||
bool inDerivingScope = contractScope && contractScope->derivesFrom(contract);
|
bool inDerivingScope = contractScope && contractScope->derivesFrom(contract);
|
||||||
|
|
||||||
for (auto const* declaration: contract.declarations())
|
for (auto const* declaration: contract.declarations())
|
||||||
@ -3875,6 +3883,7 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons
|
|||||||
members.emplace_back(declaration->name(), declaration->typeViaContractName(), declaration);
|
members.emplace_back(declaration->name(), declaration->typeViaContractName(), declaration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (m_actualType->category() == Category::Enum)
|
else if (m_actualType->category() == Category::Enum)
|
||||||
{
|
{
|
||||||
EnumDefinition const& enumDef = dynamic_cast<EnumType const&>(*m_actualType).enumDefinition();
|
EnumDefinition const& enumDef = dynamic_cast<EnumType const&>(*m_actualType).enumDefinition();
|
||||||
|
@ -1355,9 +1355,21 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
|||||||
// for internal functions, or enum/struct definitions.
|
// for internal functions, or enum/struct definitions.
|
||||||
if (TypeType const* type = dynamic_cast<TypeType const*>(_memberAccess.expression().annotation().type))
|
if (TypeType const* type = dynamic_cast<TypeType const*>(_memberAccess.expression().annotation().type))
|
||||||
{
|
{
|
||||||
if (dynamic_cast<ContractType const*>(type->actualType()))
|
if (auto contractType = dynamic_cast<ContractType const*>(type->actualType()))
|
||||||
{
|
{
|
||||||
solAssert(_memberAccess.annotation().type, "_memberAccess has no type");
|
solAssert(_memberAccess.annotation().type, "_memberAccess has no type");
|
||||||
|
if (contractType->isSuper())
|
||||||
|
{
|
||||||
|
_memberAccess.expression().accept(*this);
|
||||||
|
solAssert(_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved.");
|
||||||
|
solAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Super, "");
|
||||||
|
utils().pushCombinedFunctionEntryLabel(m_context.superFunction(
|
||||||
|
dynamic_cast<FunctionDefinition const&>(*_memberAccess.annotation().referencedDeclaration),
|
||||||
|
contractType->contractDefinition()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (auto variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
|
if (auto variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
|
||||||
appendVariable(*variable, static_cast<Expression const&>(_memberAccess));
|
appendVariable(*variable, static_cast<Expression const&>(_memberAccess));
|
||||||
else if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type))
|
else if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type))
|
||||||
@ -1409,6 +1421,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
|||||||
else
|
else
|
||||||
_memberAccess.expression().accept(*this);
|
_memberAccess.expression().accept(*this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (auto enumType = dynamic_cast<EnumType const*>(type->actualType()))
|
else if (auto enumType = dynamic_cast<EnumType const*>(type->actualType()))
|
||||||
{
|
{
|
||||||
_memberAccess.expression().accept(*this);
|
_memberAccess.expression().accept(*this);
|
||||||
@ -1480,17 +1493,8 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
|||||||
case Type::Category::Contract:
|
case Type::Category::Contract:
|
||||||
{
|
{
|
||||||
ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type);
|
ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type);
|
||||||
if (type.isSuper())
|
|
||||||
{
|
|
||||||
solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved.");
|
|
||||||
solAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Super, "");
|
|
||||||
utils().pushCombinedFunctionEntryLabel(m_context.superFunction(
|
|
||||||
dynamic_cast<FunctionDefinition const&>(*_memberAccess.annotation().referencedDeclaration),
|
|
||||||
type.contractDefinition()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
// ordinary contract type
|
// ordinary contract type
|
||||||
else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)
|
if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)
|
||||||
{
|
{
|
||||||
u256 identifier;
|
u256 identifier;
|
||||||
if (auto const* variable = dynamic_cast<VariableDeclaration const*>(declaration))
|
if (auto const* variable = dynamic_cast<VariableDeclaration const*>(declaration))
|
||||||
@ -1592,8 +1596,11 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
|||||||
solAssert(false, "Blockhash has been removed.");
|
solAssert(false, "Blockhash has been removed.");
|
||||||
else if (member == "creationCode" || member == "runtimeCode")
|
else if (member == "creationCode" || member == "runtimeCode")
|
||||||
{
|
{
|
||||||
|
// FIXME For super this needs to be fixed
|
||||||
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
|
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
|
||||||
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();
|
auto const& contractType = dynamic_cast<ContractType const&>(*arg);
|
||||||
|
solAssert(!contractType.isSuper(), "");
|
||||||
|
ContractDefinition const& contract = contractType.contractDefinition();
|
||||||
utils().fetchFreeMemoryPointer();
|
utils().fetchFreeMemoryPointer();
|
||||||
m_context << Instruction::DUP1 << u256(32) << Instruction::ADD;
|
m_context << Instruction::DUP1 << u256(32) << Instruction::ADD;
|
||||||
utils().copyContractCodeToMemory(contract, member == "creationCode");
|
utils().copyContractCodeToMemory(contract, member == "creationCode");
|
||||||
@ -1610,7 +1617,10 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
|||||||
else if (member == "name")
|
else if (member == "name")
|
||||||
{
|
{
|
||||||
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
|
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
|
||||||
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();
|
auto const& contractType = dynamic_cast<ContractType const&>(*arg);
|
||||||
|
ContractDefinition const& contract = contractType.isSuper() ?
|
||||||
|
*contractType.contractDefinition().superContract(m_context.mostDerivedContract()) :
|
||||||
|
dynamic_cast<ContractType const&>(*arg).contractDefinition();
|
||||||
utils().allocateMemory(((contract.name().length() + 31) / 32) * 32 + 32);
|
utils().allocateMemory(((contract.name().length() + 31) / 32) * 32 + 32);
|
||||||
// store string length
|
// store string length
|
||||||
m_context << u256(contract.name().length()) << Instruction::DUP2 << Instruction::MSTORE;
|
m_context << u256(contract.name().length()) << Instruction::DUP2 << Instruction::MSTORE;
|
||||||
@ -1960,9 +1970,11 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
|
|||||||
switch (magicVar->type()->category())
|
switch (magicVar->type()->category())
|
||||||
{
|
{
|
||||||
case Type::Category::Contract:
|
case Type::Category::Contract:
|
||||||
// "this" or "super"
|
if (dynamic_cast<ContractType const*>(magicVar->type()))
|
||||||
if (!dynamic_cast<ContractType const&>(*magicVar->type()).isSuper())
|
{
|
||||||
|
solAssert(_identifier.name() == "this", "");
|
||||||
m_context << Instruction::ADDRESS;
|
m_context << Instruction::ADDRESS;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -884,17 +884,17 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|||||||
solAssert(*identifier->annotation().requiredLookup == VirtualLookup::Virtual, "");
|
solAssert(*identifier->annotation().requiredLookup == VirtualLookup::Virtual, "");
|
||||||
functionDef = &functionDef->resolveVirtual(m_context.mostDerivedContract());
|
functionDef = &functionDef->resolveVirtual(m_context.mostDerivedContract());
|
||||||
}
|
}
|
||||||
else
|
else if (auto typeType = dynamic_cast<TypeType const*>(memberAccess->expression().annotation().type))
|
||||||
|
if (
|
||||||
|
auto contractType = dynamic_cast<ContractType const*>(typeType->actualType());
|
||||||
|
contractType->isSuper()
|
||||||
|
)
|
||||||
{
|
{
|
||||||
ContractType const* type = dynamic_cast<ContractType const*>(memberAccess->expression().annotation().type);
|
ContractDefinition const* super = contractType->contractDefinition().superContract(m_context.mostDerivedContract());
|
||||||
if (type && type->isSuper())
|
|
||||||
{
|
|
||||||
ContractDefinition const* super = type->contractDefinition().superContract(m_context.mostDerivedContract());
|
|
||||||
solAssert(super, "Super contract not available.");
|
solAssert(super, "Super contract not available.");
|
||||||
solAssert(*memberAccess->annotation().requiredLookup == VirtualLookup::Super, "");
|
solAssert(*memberAccess->annotation().requiredLookup == VirtualLookup::Super, "");
|
||||||
functionDef = &functionDef->resolveVirtual(m_context.mostDerivedContract(), super);
|
functionDef = &functionDef->resolveVirtual(m_context.mostDerivedContract(), super);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
solAssert(functionDef && functionDef->isImplemented(), "");
|
solAssert(functionDef && functionDef->isImplemented(), "");
|
||||||
}
|
}
|
||||||
@ -1527,19 +1527,8 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
|||||||
{
|
{
|
||||||
ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type);
|
ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type);
|
||||||
if (type.isSuper())
|
if (type.isSuper())
|
||||||
{
|
solAssert(false, "");
|
||||||
solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved.");
|
|
||||||
ContractDefinition const* super = type.contractDefinition().superContract(m_context.mostDerivedContract());
|
|
||||||
solAssert(super, "Super contract not available.");
|
|
||||||
FunctionDefinition const& resolvedFunctionDef = dynamic_cast<FunctionDefinition const&>(
|
|
||||||
*_memberAccess.annotation().referencedDeclaration
|
|
||||||
).resolveVirtual(m_context.mostDerivedContract(), super);
|
|
||||||
|
|
||||||
define(_memberAccess) << to_string(resolvedFunctionDef.id()) << "\n";
|
|
||||||
solAssert(resolvedFunctionDef.functionType(true), "");
|
|
||||||
solAssert(resolvedFunctionDef.functionType(true)->kind() == FunctionType::Kind::Internal, "");
|
|
||||||
m_context.internalFunctionAccessed(_memberAccess, resolvedFunctionDef);
|
|
||||||
}
|
|
||||||
// ordinary contract type
|
// ordinary contract type
|
||||||
else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)
|
else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)
|
||||||
{
|
{
|
||||||
@ -1649,7 +1638,9 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
|||||||
else if (member == "creationCode" || member == "runtimeCode")
|
else if (member == "creationCode" || member == "runtimeCode")
|
||||||
{
|
{
|
||||||
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
|
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
|
||||||
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();
|
auto const& contractType = dynamic_cast<ContractType const&>(*arg);
|
||||||
|
solAssert(!contractType.isSuper(), "");
|
||||||
|
ContractDefinition const& contract = contractType.contractDefinition();
|
||||||
m_context.subObjectsCreated().insert(&contract);
|
m_context.subObjectsCreated().insert(&contract);
|
||||||
m_code << Whiskers(R"(
|
m_code << Whiskers(R"(
|
||||||
let <size> := datasize("<objectName>")
|
let <size> := datasize("<objectName>")
|
||||||
@ -1669,7 +1660,9 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
|||||||
else if (member == "interfaceId")
|
else if (member == "interfaceId")
|
||||||
{
|
{
|
||||||
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
|
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
|
||||||
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();
|
auto const& contractType = dynamic_cast<ContractType const&>(*arg);
|
||||||
|
solAssert(!contractType.isSuper(), "");
|
||||||
|
ContractDefinition const& contract = contractType.contractDefinition();
|
||||||
define(_memberAccess) << formatNumber(u256{contract.interfaceId()} << (256 - 32)) << "\n";
|
define(_memberAccess) << formatNumber(u256{contract.interfaceId()} << (256 - 32)) << "\n";
|
||||||
}
|
}
|
||||||
else if (member == "min" || member == "max")
|
else if (member == "min" || member == "max")
|
||||||
@ -1790,7 +1783,23 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
|||||||
|
|
||||||
if (actualType.category() == Type::Category::Contract)
|
if (actualType.category() == Type::Category::Contract)
|
||||||
{
|
{
|
||||||
if (auto const* variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
|
ContractType const& contractType = dynamic_cast<ContractType const&>(actualType);
|
||||||
|
if (contractType.isSuper())
|
||||||
|
{
|
||||||
|
solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved.");
|
||||||
|
ContractDefinition const* super = contractType.contractDefinition().superContract(m_context.mostDerivedContract());
|
||||||
|
solAssert(super, "Super contract not available.");
|
||||||
|
FunctionDefinition const& resolvedFunctionDef =
|
||||||
|
dynamic_cast<FunctionDefinition const&>(
|
||||||
|
*_memberAccess.annotation().referencedDeclaration
|
||||||
|
).resolveVirtual(m_context.mostDerivedContract(), super);
|
||||||
|
|
||||||
|
define(_memberAccess) << to_string(resolvedFunctionDef.id()) << "\n";
|
||||||
|
solAssert(resolvedFunctionDef.functionType(true), "");
|
||||||
|
solAssert(resolvedFunctionDef.functionType(true)->kind() == FunctionType::Kind::Internal, "");
|
||||||
|
m_context.internalFunctionAccessed(_memberAccess, resolvedFunctionDef);
|
||||||
|
}
|
||||||
|
else if (auto const* variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
|
||||||
handleVariableReference(*variable, _memberAccess);
|
handleVariableReference(*variable, _memberAccess);
|
||||||
else if (memberFunctionType)
|
else if (memberFunctionType)
|
||||||
{
|
{
|
||||||
@ -2095,18 +2104,20 @@ void IRGeneratorForStatements::endVisit(Identifier const& _identifier)
|
|||||||
switch (magicVar->type()->category())
|
switch (magicVar->type()->category())
|
||||||
{
|
{
|
||||||
case Type::Category::Contract:
|
case Type::Category::Contract:
|
||||||
if (dynamic_cast<ContractType const&>(*magicVar->type()).isSuper())
|
|
||||||
solAssert(_identifier.name() == "super", "");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
solAssert(_identifier.name() == "this", "");
|
solAssert(_identifier.name() == "this", "");
|
||||||
define(_identifier) << "address()\n";
|
define(_identifier) << "address()\n";
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Type::Category::Integer:
|
case Type::Category::Integer:
|
||||||
solAssert(_identifier.name() == "now", "");
|
solAssert(_identifier.name() == "now", "");
|
||||||
define(_identifier) << "timestamp()\n";
|
define(_identifier) << "timestamp()\n";
|
||||||
break;
|
break;
|
||||||
|
case Type::Category::TypeType:
|
||||||
|
{
|
||||||
|
auto typeType = dynamic_cast<TypeType const*>(magicVar->type());
|
||||||
|
if (auto contractType = dynamic_cast<ContractType const*>(typeType->actualType()))
|
||||||
|
solAssert(!contractType->isSuper() || _identifier.name() == "super", "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user