aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/analysis
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r--libsolidity/analysis/ReferencesResolver.cpp140
-rw-r--r--libsolidity/analysis/ReferencesResolver.h8
2 files changed, 66 insertions, 82 deletions
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp
index e5b1c52b..17f93029 100644
--- a/libsolidity/analysis/ReferencesResolver.cpp
+++ b/libsolidity/analysis/ReferencesResolver.cpp
@@ -31,28 +31,6 @@ using namespace dev;
using namespace dev::solidity;
-bool ReferencesResolver::visit(Return const& _return)
-{
- _return.annotation().functionReturnParameters = m_returnParameters;
- return true;
-}
-
-void ReferencesResolver::endVisit(NewExpression const& _new)
-{
- typeFor(_new.typeName());
-}
-
-bool ReferencesResolver::visit(UserDefinedTypeName const& _typeName)
-{
- Declaration const* declaration = m_resolver.pathFromCurrentScope(_typeName.namePath());
- if (!declaration)
- fatalDeclarationError(_typeName.location(), "Identifier not found or not unique.");
-
- _typeName.annotation().referencedDeclaration = declaration;
-
- return true;
-}
-
bool ReferencesResolver::resolve(ASTNode const& _root)
{
try
@@ -79,6 +57,67 @@ bool ReferencesResolver::visit(Identifier const& _identifier)
return false;
}
+bool ReferencesResolver::visit(ElementaryTypeName const& _typeName)
+{
+ _typeName.annotation().type = Type::fromElementaryTypeName(_typeName.typeName());
+ return true;
+}
+
+void ReferencesResolver::endVisit(UserDefinedTypeName const& _typeName)
+{
+ Declaration const* declaration = m_resolver.pathFromCurrentScope(_typeName.namePath());
+ if (!declaration)
+ fatalDeclarationError(_typeName.location(), "Identifier not found or not unique.");
+
+ _typeName.annotation().referencedDeclaration = declaration;
+
+ if (StructDefinition const* structDef = dynamic_cast<StructDefinition const*>(declaration))
+ _typeName.annotation().type = make_shared<StructType>(*structDef);
+ else if (EnumDefinition const* enumDef = dynamic_cast<EnumDefinition const*>(declaration))
+ _typeName.annotation().type = make_shared<EnumType>(*enumDef);
+ else if (ContractDefinition const* contract = dynamic_cast<ContractDefinition const*>(declaration))
+ _typeName.annotation().type = make_shared<ContractType>(*contract);
+ else
+ fatalTypeError(_typeName.location(), "Name has to refer to a struct, enum or contract.");
+}
+
+void ReferencesResolver::endVisit(Mapping const& _typeName)
+{
+ TypePointer keyType = _typeName.keyType().annotation().type;
+ TypePointer valueType = _typeName.valueType().annotation().type;
+ // Convert key type to memory.
+ keyType = ReferenceType::copyForLocationIfReference(DataLocation::Memory, keyType);
+ // Convert value type to storage reference.
+ valueType = ReferenceType::copyForLocationIfReference(DataLocation::Storage, valueType);
+ _typeName.annotation().type = make_shared<MappingType>(keyType, valueType);
+}
+
+void ReferencesResolver::endVisit(ArrayTypeName const& _typeName)
+{
+ TypePointer baseType = _typeName.baseType().annotation().type;
+ if (baseType->storageBytes() == 0)
+ fatalTypeError(_typeName.baseType().location(), "Illegal base type of storage size zero for array.");
+ if (Expression const* length = _typeName.length())
+ {
+ if (!length->annotation().type)
+ ConstantEvaluator e(*length);
+
+ auto const* lengthType = dynamic_cast<IntegerConstantType const*>(length->annotation().type.get());
+ if (!lengthType)
+ fatalTypeError(length->location(), "Invalid array length.");
+ else
+ _typeName.annotation().type = make_shared<ArrayType>(DataLocation::Storage, baseType, lengthType->literalValue(nullptr));
+ }
+ else
+ _typeName.annotation().type = make_shared<ArrayType>(DataLocation::Storage, baseType);
+}
+
+bool ReferencesResolver::visit(Return const& _return)
+{
+ _return.annotation().functionReturnParameters = m_returnParameters;
+ return true;
+}
+
void ReferencesResolver::endVisit(VariableDeclaration const& _variable)
{
if (_variable.annotation().type)
@@ -87,7 +126,7 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable)
TypePointer type;
if (_variable.typeName())
{
- type = typeFor(*_variable.typeName());
+ type = _variable.typeName()->annotation().type;
using Location = VariableDeclaration::Location;
Location loc = _variable.referenceLocation();
// References are forced to calldata for external function parameters (not return)
@@ -167,61 +206,6 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable)
_variable.annotation().type = type;
}
-TypePointer ReferencesResolver::typeFor(TypeName const& _typeName)
-{
- if (_typeName.annotation().type)
- return _typeName.annotation().type;
-
- TypePointer type;
- if (auto elemTypeName = dynamic_cast<ElementaryTypeName const*>(&_typeName))
- type = Type::fromElementaryTypeName(elemTypeName->typeName());
- else if (auto typeName = dynamic_cast<UserDefinedTypeName const*>(&_typeName))
- {
- Declaration const* declaration = typeName->annotation().referencedDeclaration;
- solAssert(!!declaration, "");
-
- if (StructDefinition const* structDef = dynamic_cast<StructDefinition const*>(declaration))
- type = make_shared<StructType>(*structDef);
- else if (EnumDefinition const* enumDef = dynamic_cast<EnumDefinition const*>(declaration))
- type = make_shared<EnumType>(*enumDef);
- else if (ContractDefinition const* contract = dynamic_cast<ContractDefinition const*>(declaration))
- type = make_shared<ContractType>(*contract);
- else
- fatalTypeError(typeName->location(), "Name has to refer to a struct, enum or contract.");
- }
- else if (auto mapping = dynamic_cast<Mapping const*>(&_typeName))
- {
- TypePointer keyType = typeFor(mapping->keyType());
- TypePointer valueType = typeFor(mapping->valueType());
- // Convert key type to memory.
- keyType = ReferenceType::copyForLocationIfReference(DataLocation::Memory, keyType);
- // Convert value type to storage reference.
- valueType = ReferenceType::copyForLocationIfReference(DataLocation::Storage, valueType);
- type = make_shared<MappingType>(keyType, valueType);
- }
- else if (auto arrayType = dynamic_cast<ArrayTypeName const*>(&_typeName))
- {
- TypePointer baseType = typeFor(arrayType->baseType());
- if (baseType->storageBytes() == 0)
- fatalTypeError(arrayType->baseType().location(), "Illegal base type of storage size zero for array.");
- if (Expression const* length = arrayType->length())
- {
- if (!length->annotation().type)
- ConstantEvaluator e(*length);
-
- auto const* lengthType = dynamic_cast<IntegerConstantType const*>(length->annotation().type.get());
- if (!lengthType)
- fatalTypeError(length->location(), "Invalid array length.");
- else
- type = make_shared<ArrayType>(DataLocation::Storage, baseType, lengthType->literalValue(nullptr));
- }
- else
- type = make_shared<ArrayType>(DataLocation::Storage, baseType);
- }
-
- return _typeName.annotation().type = move(type);
-}
-
void ReferencesResolver::typeError(SourceLocation const& _location, string const& _description)
{
auto err = make_shared<Error>(Error::Type::TypeError);
diff --git a/libsolidity/analysis/ReferencesResolver.h b/libsolidity/analysis/ReferencesResolver.h
index 6f5ced8c..a2d71dc3 100644
--- a/libsolidity/analysis/ReferencesResolver.h
+++ b/libsolidity/analysis/ReferencesResolver.h
@@ -60,13 +60,13 @@ public:
private:
virtual bool visit(Block const&) override { return m_resolveInsideCode; }
virtual bool visit(Identifier const& _identifier) override;
- virtual bool visit(UserDefinedTypeName const& _typeName) override;
+ virtual bool visit(ElementaryTypeName const& _typeName) override;
+ virtual void endVisit(UserDefinedTypeName const& _typeName) override;
+ virtual void endVisit(Mapping const& _typeName) override;
+ virtual void endVisit(ArrayTypeName const& _typeName) override;
virtual bool visit(Return const& _return) override;
- virtual void endVisit(NewExpression const& _new) override;
virtual void endVisit(VariableDeclaration const& _variable) override;
- TypePointer typeFor(TypeName const& _typeName);
-
/// Adds a new error to the list of errors.
void typeError(SourceLocation const& _location, std::string const& _description);