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:
@@ -1355,59 +1355,72 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
||||
// for internal functions, or enum/struct definitions.
|
||||
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");
|
||||
if (auto variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
|
||||
appendVariable(*variable, static_cast<Expression const&>(_memberAccess));
|
||||
else if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type))
|
||||
if (contractType->isSuper())
|
||||
{
|
||||
switch (funType->kind())
|
||||
{
|
||||
case FunctionType::Kind::Declaration:
|
||||
break;
|
||||
case FunctionType::Kind::Internal:
|
||||
// We do not visit the expression here on purpose, because in the case of an
|
||||
// internal library function call, this would push the library address forcing
|
||||
// us to link against it although we actually do not need it.
|
||||
if (auto const* function = dynamic_cast<FunctionDefinition const*>(_memberAccess.annotation().referencedDeclaration))
|
||||
{
|
||||
solAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Static, "");
|
||||
utils().pushCombinedFunctionEntryLabel(*function);
|
||||
}
|
||||
else
|
||||
solAssert(false, "Function not found in member access");
|
||||
break;
|
||||
case FunctionType::Kind::Event:
|
||||
if (!dynamic_cast<EventDefinition const*>(_memberAccess.annotation().referencedDeclaration))
|
||||
solAssert(false, "event not found");
|
||||
// no-op, because the parent node will do the job
|
||||
break;
|
||||
case FunctionType::Kind::DelegateCall:
|
||||
_memberAccess.expression().accept(*this);
|
||||
m_context << funType->externalIdentifier();
|
||||
break;
|
||||
case FunctionType::Kind::External:
|
||||
case FunctionType::Kind::Creation:
|
||||
case FunctionType::Kind::Send:
|
||||
case FunctionType::Kind::BareCall:
|
||||
case FunctionType::Kind::BareCallCode:
|
||||
case FunctionType::Kind::BareDelegateCall:
|
||||
case FunctionType::Kind::BareStaticCall:
|
||||
case FunctionType::Kind::Transfer:
|
||||
case FunctionType::Kind::ECRecover:
|
||||
case FunctionType::Kind::SHA256:
|
||||
case FunctionType::Kind::RIPEMD160:
|
||||
default:
|
||||
solAssert(false, "unsupported member function");
|
||||
}
|
||||
}
|
||||
else if (dynamic_cast<TypeType const*>(_memberAccess.annotation().type))
|
||||
{
|
||||
// no-op
|
||||
_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
|
||||
_memberAccess.expression().accept(*this);
|
||||
{
|
||||
if (auto variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
|
||||
appendVariable(*variable, static_cast<Expression const&>(_memberAccess));
|
||||
else if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type))
|
||||
{
|
||||
switch (funType->kind())
|
||||
{
|
||||
case FunctionType::Kind::Declaration:
|
||||
break;
|
||||
case FunctionType::Kind::Internal:
|
||||
// We do not visit the expression here on purpose, because in the case of an
|
||||
// internal library function call, this would push the library address forcing
|
||||
// us to link against it although we actually do not need it.
|
||||
if (auto const* function = dynamic_cast<FunctionDefinition const*>(_memberAccess.annotation().referencedDeclaration))
|
||||
{
|
||||
solAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Static, "");
|
||||
utils().pushCombinedFunctionEntryLabel(*function);
|
||||
}
|
||||
else
|
||||
solAssert(false, "Function not found in member access");
|
||||
break;
|
||||
case FunctionType::Kind::Event:
|
||||
if (!dynamic_cast<EventDefinition const*>(_memberAccess.annotation().referencedDeclaration))
|
||||
solAssert(false, "event not found");
|
||||
// no-op, because the parent node will do the job
|
||||
break;
|
||||
case FunctionType::Kind::DelegateCall:
|
||||
_memberAccess.expression().accept(*this);
|
||||
m_context << funType->externalIdentifier();
|
||||
break;
|
||||
case FunctionType::Kind::External:
|
||||
case FunctionType::Kind::Creation:
|
||||
case FunctionType::Kind::Send:
|
||||
case FunctionType::Kind::BareCall:
|
||||
case FunctionType::Kind::BareCallCode:
|
||||
case FunctionType::Kind::BareDelegateCall:
|
||||
case FunctionType::Kind::BareStaticCall:
|
||||
case FunctionType::Kind::Transfer:
|
||||
case FunctionType::Kind::ECRecover:
|
||||
case FunctionType::Kind::SHA256:
|
||||
case FunctionType::Kind::RIPEMD160:
|
||||
default:
|
||||
solAssert(false, "unsupported member function");
|
||||
}
|
||||
}
|
||||
else if (dynamic_cast<TypeType const*>(_memberAccess.annotation().type))
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
else
|
||||
_memberAccess.expression().accept(*this);
|
||||
}
|
||||
}
|
||||
else if (auto enumType = dynamic_cast<EnumType const*>(type->actualType()))
|
||||
{
|
||||
@@ -1480,17 +1493,8 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
||||
case Type::Category::Contract:
|
||||
{
|
||||
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
|
||||
else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)
|
||||
if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)
|
||||
{
|
||||
u256 identifier;
|
||||
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.");
|
||||
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();
|
||||
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();
|
||||
m_context << Instruction::DUP1 << u256(32) << Instruction::ADD;
|
||||
utils().copyContractCodeToMemory(contract, member == "creationCode");
|
||||
@@ -1610,7 +1617,10 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
||||
else if (member == "name")
|
||||
{
|
||||
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);
|
||||
// store string length
|
||||
m_context << u256(contract.name().length()) << Instruction::DUP2 << Instruction::MSTORE;
|
||||
@@ -1960,9 +1970,11 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
|
||||
switch (magicVar->type()->category())
|
||||
{
|
||||
case Type::Category::Contract:
|
||||
// "this" or "super"
|
||||
if (!dynamic_cast<ContractType const&>(*magicVar->type()).isSuper())
|
||||
if (dynamic_cast<ContractType const*>(magicVar->type()))
|
||||
{
|
||||
solAssert(_identifier.name() == "this", "");
|
||||
m_context << Instruction::ADDRESS;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -884,17 +884,17 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
solAssert(*identifier->annotation().requiredLookup == VirtualLookup::Virtual, "");
|
||||
functionDef = &functionDef->resolveVirtual(m_context.mostDerivedContract());
|
||||
}
|
||||
else
|
||||
{
|
||||
ContractType const* type = dynamic_cast<ContractType const*>(memberAccess->expression().annotation().type);
|
||||
if (type && type->isSuper())
|
||||
else if (auto typeType = dynamic_cast<TypeType const*>(memberAccess->expression().annotation().type))
|
||||
if (
|
||||
auto contractType = dynamic_cast<ContractType const*>(typeType->actualType());
|
||||
contractType->isSuper()
|
||||
)
|
||||
{
|
||||
ContractDefinition const* super = type->contractDefinition().superContract(m_context.mostDerivedContract());
|
||||
ContractDefinition const* super = contractType->contractDefinition().superContract(m_context.mostDerivedContract());
|
||||
solAssert(super, "Super contract not available.");
|
||||
solAssert(*memberAccess->annotation().requiredLookup == VirtualLookup::Super, "");
|
||||
functionDef = &functionDef->resolveVirtual(m_context.mostDerivedContract(), super);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (type.isSuper())
|
||||
{
|
||||
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);
|
||||
solAssert(false, "");
|
||||
|
||||
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
|
||||
else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)
|
||||
{
|
||||
@@ -1649,7 +1638,9 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
else if (member == "creationCode" || member == "runtimeCode")
|
||||
{
|
||||
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_code << Whiskers(R"(
|
||||
let <size> := datasize("<objectName>")
|
||||
@@ -1669,7 +1660,9 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
else if (member == "interfaceId")
|
||||
{
|
||||
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";
|
||||
}
|
||||
else if (member == "min" || member == "max")
|
||||
@@ -1790,8 +1783,24 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
|
||||
if (actualType.category() == Type::Category::Contract)
|
||||
{
|
||||
if (auto const* variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
|
||||
handleVariableReference(*variable, _memberAccess);
|
||||
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);
|
||||
else if (memberFunctionType)
|
||||
{
|
||||
switch (memberFunctionType->kind())
|
||||
@@ -1812,7 +1821,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
dynamic_cast<EventDefinition const*>(_memberAccess.annotation().referencedDeclaration),
|
||||
"Event not found"
|
||||
);
|
||||
// the call will do the resolving
|
||||
// the call will do the resolving
|
||||
break;
|
||||
case FunctionType::Kind::DelegateCall:
|
||||
define(IRVariable(_memberAccess).part("address"), _memberAccess.expression());
|
||||
@@ -1835,7 +1844,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
}
|
||||
else if (dynamic_cast<TypeType const*>(_memberAccess.annotation().type))
|
||||
{
|
||||
// no-op
|
||||
// no-op
|
||||
}
|
||||
else
|
||||
// The old code generator had a generic "else" case here
|
||||
@@ -2095,18 +2104,20 @@ void IRGeneratorForStatements::endVisit(Identifier const& _identifier)
|
||||
switch (magicVar->type()->category())
|
||||
{
|
||||
case Type::Category::Contract:
|
||||
if (dynamic_cast<ContractType const&>(*magicVar->type()).isSuper())
|
||||
solAssert(_identifier.name() == "super", "");
|
||||
else
|
||||
{
|
||||
solAssert(_identifier.name() == "this", "");
|
||||
define(_identifier) << "address()\n";
|
||||
}
|
||||
solAssert(_identifier.name() == "this", "");
|
||||
define(_identifier) << "address()\n";
|
||||
break;
|
||||
case Type::Category::Integer:
|
||||
solAssert(_identifier.name() == "now", "");
|
||||
define(_identifier) << "timestamp()\n";
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user