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)
|
bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)
|
||||||
{
|
{
|
||||||
CopyTranslate bodyCopier{m_context, _inlineAsm.annotation().externalReferences};
|
CopyTranslate bodyCopier{m_context, _inlineAsm.annotation().externalReferences};
|
||||||
@ -405,10 +553,32 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IRGeneratorForStatements::visit(Identifier const& _identifier)
|
void IRGeneratorForStatements::endVisit(Identifier const& _identifier)
|
||||||
{
|
{
|
||||||
Declaration const* declaration = _identifier.annotation().referencedDeclaration;
|
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";
|
defineExpression(_identifier) << to_string(m_context.virtualFunction(*functionDef).id()) << "\n";
|
||||||
else if (VariableDeclaration const* varDecl = dynamic_cast<VariableDeclaration const*>(declaration))
|
else if (VariableDeclaration const* varDecl = dynamic_cast<VariableDeclaration const*>(declaration))
|
||||||
{
|
{
|
||||||
@ -426,9 +596,8 @@ bool IRGeneratorForStatements::visit(Identifier const& _identifier)
|
|||||||
|
|
||||||
setLValue(_identifier, move(lvalue));
|
setLValue(_identifier, move(lvalue));
|
||||||
}
|
}
|
||||||
else if (!dynamic_cast<MagicVariableDeclaration const*>(declaration))
|
else
|
||||||
solUnimplemented("");
|
solUnimplemented("Identifier of type " + declaration->type()->toString() + " not implemented.");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IRGeneratorForStatements::visit(Literal const& _literal)
|
bool IRGeneratorForStatements::visit(Literal const& _literal)
|
||||||
|
@ -55,8 +55,9 @@ public:
|
|||||||
void endVisit(UnaryOperation const& _unaryOperation) override;
|
void endVisit(UnaryOperation const& _unaryOperation) override;
|
||||||
bool visit(BinaryOperation const& _binOp) override;
|
bool visit(BinaryOperation const& _binOp) override;
|
||||||
void endVisit(FunctionCall const& _funCall) override;
|
void endVisit(FunctionCall const& _funCall) override;
|
||||||
|
void endVisit(MemberAccess const& _memberAccess) override;
|
||||||
bool visit(InlineAssembly const& _inlineAsm) 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;
|
bool visit(Literal const& _literal) override;
|
||||||
|
|
||||||
private:
|
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