mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Most trivial members.
This commit is contained in:
parent
b99ad2aaa3
commit
acca390ef5
@ -393,6 +393,154 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
}
|
||||
}
|
||||
|
||||
void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
{
|
||||
ASTString const& member = _memberAccess.memberName();
|
||||
if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type))
|
||||
if (funType->bound())
|
||||
{
|
||||
solUnimplementedAssert(false, "");
|
||||
}
|
||||
|
||||
switch (_memberAccess.expression().annotation().type->category())
|
||||
{
|
||||
case Type::Category::Contract:
|
||||
{
|
||||
ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type);
|
||||
if (type.isSuper())
|
||||
{
|
||||
solUnimplementedAssert(false, "");
|
||||
}
|
||||
// ordinary contract type
|
||||
else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)
|
||||
{
|
||||
u256 identifier;
|
||||
if (auto const* variable = dynamic_cast<VariableDeclaration const*>(declaration))
|
||||
identifier = FunctionType(*variable).externalIdentifier();
|
||||
else if (auto const* function = dynamic_cast<FunctionDefinition const*>(declaration))
|
||||
identifier = FunctionType(*function).externalIdentifier();
|
||||
else
|
||||
solAssert(false, "Contract member is neither variable nor function.");
|
||||
// TODO here, we need to assign address and function identifier to two variables.
|
||||
// We migt also just combine them into a single variable already....
|
||||
solUnimplementedAssert(false, "");
|
||||
}
|
||||
else
|
||||
solAssert(false, "Invalid member access in contract");
|
||||
break;
|
||||
}
|
||||
case Type::Category::Integer:
|
||||
{
|
||||
solAssert(false, "Invalid member access to integer");
|
||||
break;
|
||||
}
|
||||
case Type::Category::Address:
|
||||
{
|
||||
if (member == "balance")
|
||||
defineExpression(_memberAccess) <<
|
||||
"balance(" <<
|
||||
expressionAsType(_memberAccess.expression(), *TypeProvider::address()) <<
|
||||
")\n";
|
||||
else if (set<string>{"send", "transfer"}.count(member))
|
||||
{
|
||||
solAssert(dynamic_cast<AddressType const&>(*_memberAccess.expression().annotation().type).stateMutability() == StateMutability::Payable, "");
|
||||
defineExpression(_memberAccess) <<
|
||||
expressionAsType(_memberAccess.expression(), *TypeProvider::payableAddress()) <<
|
||||
"\n";
|
||||
}
|
||||
else if (set<string>{"call", "callcode", "delegatecall", "staticcall"}.count(member))
|
||||
defineExpression(_memberAccess) <<
|
||||
expressionAsType(_memberAccess.expression(), *TypeProvider::address()) <<
|
||||
"\n";
|
||||
else
|
||||
solAssert(false, "Invalid member access to address");
|
||||
break;
|
||||
}
|
||||
case Type::Category::Function:
|
||||
if (member == "selector")
|
||||
{
|
||||
solUnimplementedAssert(false, "");
|
||||
}
|
||||
else
|
||||
solAssert(
|
||||
!!_memberAccess.expression().annotation().type->memberType(member),
|
||||
"Invalid member access to function."
|
||||
);
|
||||
break;
|
||||
case Type::Category::Magic:
|
||||
// we can ignore the kind of magic and only look at the name of the member
|
||||
if (member == "coinbase")
|
||||
defineExpression(_memberAccess) << "coinbase()\n";
|
||||
else if (member == "timestamp")
|
||||
defineExpression(_memberAccess) << "timestamp()\n";
|
||||
else if (member == "difficulty")
|
||||
defineExpression(_memberAccess) << "difficulty()\n";
|
||||
else if (member == "number")
|
||||
defineExpression(_memberAccess) << "number()\n";
|
||||
else if (member == "gaslimit")
|
||||
defineExpression(_memberAccess) << "gaslimit()\n";
|
||||
else if (member == "sender")
|
||||
defineExpression(_memberAccess) << "caller()\n";
|
||||
else if (member == "value")
|
||||
defineExpression(_memberAccess) << "callvalue()\n";
|
||||
else if (member == "origin")
|
||||
defineExpression(_memberAccess) << "origin()\n";
|
||||
else if (member == "gasprice")
|
||||
defineExpression(_memberAccess) << "gasprice()\n";
|
||||
else if (member == "data")
|
||||
solUnimplementedAssert(false, "");
|
||||
else if (member == "sig")
|
||||
defineExpression(_memberAccess) <<
|
||||
"and(calldataload(0), " <<
|
||||
formatNumber(u256(0xffffffff) << (256 - 32)) <<
|
||||
")\n";
|
||||
else if (member == "gas")
|
||||
solAssert(false, "Gas has been removed.");
|
||||
else if (member == "blockhash")
|
||||
solAssert(false, "Blockhash has been removed.");
|
||||
else if (member == "creationCode" || member == "runtimeCode")
|
||||
{
|
||||
solUnimplementedAssert(false, "");
|
||||
}
|
||||
else if (member == "name")
|
||||
{
|
||||
solUnimplementedAssert(false, "");
|
||||
}
|
||||
else if (set<string>{"encode", "encodePacked", "encodeWithSelector", "encodeWithSignature", "decode"}.count(member))
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
else
|
||||
solAssert(false, "Unknown magic member.");
|
||||
break;
|
||||
case Type::Category::Struct:
|
||||
{
|
||||
solUnimplementedAssert(false, "");
|
||||
}
|
||||
case Type::Category::Enum:
|
||||
{
|
||||
EnumType const& type = dynamic_cast<EnumType const&>(*_memberAccess.expression().annotation().type);
|
||||
defineExpression(_memberAccess) << to_string(type.memberValue(_memberAccess.memberName())) << "\n";
|
||||
break;
|
||||
}
|
||||
case Type::Category::Array:
|
||||
{
|
||||
solUnimplementedAssert(false, "");
|
||||
}
|
||||
case Type::Category::FixedBytes:
|
||||
{
|
||||
auto const& type = dynamic_cast<FixedBytesType const&>(*_memberAccess.expression().annotation().type);
|
||||
if (member == "length")
|
||||
defineExpression(_memberAccess) << to_string(type.numBytes());
|
||||
else
|
||||
solAssert(false, "Illegal fixed bytes member.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
solAssert(false, "Member access to unknown type.");
|
||||
}
|
||||
}
|
||||
|
||||
bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)
|
||||
{
|
||||
CopyTranslate bodyCopier{m_context, _inlineAsm.annotation().externalReferences};
|
||||
@ -405,10 +553,32 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IRGeneratorForStatements::visit(Identifier const& _identifier)
|
||||
void IRGeneratorForStatements::endVisit(Identifier const& _identifier)
|
||||
{
|
||||
Declaration const* declaration = _identifier.annotation().referencedDeclaration;
|
||||
if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration))
|
||||
if (MagicVariableDeclaration const* magicVar = dynamic_cast<MagicVariableDeclaration const*>(declaration))
|
||||
{
|
||||
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", "");
|
||||
defineExpression(_identifier) << "address()\n";
|
||||
}
|
||||
break;
|
||||
case Type::Category::Integer:
|
||||
solAssert(_identifier.name() == "now", "");
|
||||
defineExpression(_identifier) << "timestamp()\n";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration))
|
||||
defineExpression(_identifier) << to_string(m_context.virtualFunction(*functionDef).id()) << "\n";
|
||||
else if (VariableDeclaration const* varDecl = dynamic_cast<VariableDeclaration const*>(declaration))
|
||||
{
|
||||
@ -426,9 +596,8 @@ bool IRGeneratorForStatements::visit(Identifier const& _identifier)
|
||||
|
||||
setLValue(_identifier, move(lvalue));
|
||||
}
|
||||
else if (!dynamic_cast<MagicVariableDeclaration const*>(declaration))
|
||||
solUnimplemented("");
|
||||
return false;
|
||||
else
|
||||
solUnimplemented("Identifier of type " + declaration->type()->toString() + " not implemented.");
|
||||
}
|
||||
|
||||
bool IRGeneratorForStatements::visit(Literal const& _literal)
|
||||
|
@ -55,8 +55,9 @@ public:
|
||||
void endVisit(UnaryOperation const& _unaryOperation) override;
|
||||
bool visit(BinaryOperation const& _binOp) override;
|
||||
void endVisit(FunctionCall const& _funCall) override;
|
||||
void endVisit(MemberAccess const& _memberAccess) override;
|
||||
bool visit(InlineAssembly const& _inlineAsm) override;
|
||||
bool visit(Identifier const& _identifier) override;
|
||||
void endVisit(Identifier const& _identifier) override;
|
||||
bool visit(Literal const& _literal) override;
|
||||
|
||||
private:
|
||||
|
11
test/libsolidity/semanticTests/viaYul/msg_sender.sol
Normal file
11
test/libsolidity/semanticTests/viaYul/msg_sender.sol
Normal file
@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function test() public view returns (bool) {
|
||||
address x;
|
||||
assembly { x := caller() }
|
||||
return x == msg.sender;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: true
|
||||
// ----
|
||||
// test() -> true
|
Loading…
Reference in New Issue
Block a user