diff options
author | chriseth <c@ethdev.com> | 2015-06-05 17:07:50 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-05 20:44:05 +0800 |
commit | f4d1acc563a972ee4f5a44c690cd3fdd1783ae97 (patch) | |
tree | b2814613dff69ffe8f1e14ef6160dcc0902eb3c4 /NameAndTypeResolver.cpp | |
parent | 4987eec3d1e87868e091850d31af58e054ab5ee5 (diff) | |
download | dexon-solidity-f4d1acc563a972ee4f5a44c690cd3fdd1783ae97.tar.gz dexon-solidity-f4d1acc563a972ee4f5a44c690cd3fdd1783ae97.tar.zst dexon-solidity-f4d1acc563a972ee4f5a44c690cd3fdd1783ae97.zip |
Ability to specify the storage location of a reference type.
Diffstat (limited to 'NameAndTypeResolver.cpp')
-rw-r--r-- | NameAndTypeResolver.cpp | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/NameAndTypeResolver.cpp b/NameAndTypeResolver.cpp index 5ef14f60..22232014 100644 --- a/NameAndTypeResolver.cpp +++ b/NameAndTypeResolver.cpp @@ -424,10 +424,49 @@ void ReferencesResolver::endVisit(VariableDeclaration& _variable) if (_variable.getTypeName()) { TypePointer type = _variable.getTypeName()->toType(); - // All array parameter types should point to call data - if (_variable.isExternalFunctionParameter()) - if (auto const* arrayType = dynamic_cast<ArrayType const*>(type.get())) - type = arrayType->copyForLocation(ArrayType::Location::CallData); + using Location = VariableDeclaration::Location; + Location loc = _variable.referenceLocation(); + // References are forced to calldata for external function parameters (not return) + // and memory for parameters (also return) of publicly visible functions. + // They default to memory for function parameters and storage for local variables. + if (auto ref = dynamic_cast<ReferenceType const*>(type.get())) + { + if (_variable.isExternalFunctionParameter()) + { + // force location of external function parameters (not return) to calldata + if (loc != Location::Default) + BOOST_THROW_EXCEPTION(_variable.createTypeError( + "Location has to be calldata for external functions " + "(remove the \"memory\" or \"storage\" keyword)." + )); + type = ref->copyForLocation(ReferenceType::Location::CallData); + } + else if (_variable.isFunctionParameter() && _variable.getScope()->isPublic()) + { + // force locations of public or external function (return) parameters to memory + if (loc == VariableDeclaration::Location::Storage) + BOOST_THROW_EXCEPTION(_variable.createTypeError( + "Location has to be memory for publicly visible functions " + "(remove the \"storage\" keyword)." + )); + type = ref->copyForLocation(ReferenceType::Location::Memory); + } + else + { + if (loc == Location::Default) + loc = _variable.isFunctionParameter() ? Location::Memory : Location::Storage; + type = ref->copyForLocation( + loc == Location::Memory ? + ReferenceType::Location::Memory : + ReferenceType::Location::Storage + ); + } + } + else if (loc != Location::Default && !ref) + BOOST_THROW_EXCEPTION(_variable.createTypeError( + "Storage location can only be given for array or struct types." + )); + _variable.setType(type); if (!_variable.getType()) |