aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/ast
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/ast')
-rw-r--r--libsolidity/ast/AST.cpp48
-rw-r--r--libsolidity/ast/AST.h80
-rw-r--r--libsolidity/ast/ASTAnnotations.h3
-rw-r--r--libsolidity/ast/AST_accept.h14
-rw-r--r--libsolidity/ast/Types.cpp39
-rw-r--r--libsolidity/ast/Types.h31
6 files changed, 104 insertions, 111 deletions
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index 41a4d182..6006d441 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -74,29 +74,29 @@ map<FixedHash<4>, FunctionTypePointer> ContractDefinition::interfaceFunctions()
FunctionDefinition const* ContractDefinition::constructor() const
{
- for (ASTPointer<FunctionDefinition> const& f: m_definedFunctions)
+ for (FunctionDefinition const* f: definedFunctions())
if (f->isConstructor())
- return f.get();
+ return f;
return nullptr;
}
FunctionDefinition const* ContractDefinition::fallbackFunction() const
{
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
- for (ASTPointer<FunctionDefinition> const& f: contract->definedFunctions())
+ for (FunctionDefinition const* f: contract->definedFunctions())
if (f->name().empty())
- return f.get();
+ return f;
return nullptr;
}
-vector<ASTPointer<EventDefinition>> const& ContractDefinition::interfaceEvents() const
+vector<EventDefinition const*> const& ContractDefinition::interfaceEvents() const
{
if (!m_interfaceEvents)
{
set<string> eventsSeen;
- m_interfaceEvents.reset(new vector<ASTPointer<EventDefinition>>());
+ m_interfaceEvents.reset(new vector<EventDefinition const*>());
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
- for (ASTPointer<EventDefinition> const& e: contract->events())
+ for (EventDefinition const* e: contract->events())
if (eventsSeen.count(e->name()) == 0)
{
eventsSeen.insert(e->name());
@@ -116,10 +116,10 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::inter
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
{
vector<FunctionTypePointer> functions;
- for (ASTPointer<FunctionDefinition> const& f: contract->definedFunctions())
+ for (FunctionDefinition const* f: contract->definedFunctions())
if (f->isPartOfExternalInterface())
functions.push_back(make_shared<FunctionType>(*f, false));
- for (ASTPointer<VariableDeclaration> const& v: contract->stateVariables())
+ for (VariableDeclaration const* v: contract->stateVariables())
if (v->isPartOfExternalInterface())
functions.push_back(make_shared<FunctionType>(*v));
for (FunctionTypePointer const& fun: functions)
@@ -176,21 +176,21 @@ vector<Declaration const*> const& ContractDefinition::inheritableMembers() const
}
};
- for (ASTPointer<FunctionDefinition> const& f: definedFunctions())
- addInheritableMember(f.get());
+ for (FunctionDefinition const* f: definedFunctions())
+ addInheritableMember(f);
- for (ASTPointer<VariableDeclaration> const& v: stateVariables())
- addInheritableMember(v.get());
+ for (VariableDeclaration const* v: stateVariables())
+ addInheritableMember(v);
- for (ASTPointer<StructDefinition> const& s: definedStructs())
- addInheritableMember(s.get());
+ for (StructDefinition const* s: definedStructs())
+ addInheritableMember(s);
}
return *m_inheritableMembers;
}
-TypePointer ContractDefinition::type(ContractDefinition const* m_currentContract) const
+TypePointer ContractDefinition::type() const
{
- return make_shared<TypeType>(make_shared<ContractType>(*this), m_currentContract);
+ return make_shared<TypeType>(make_shared<ContractType>(*this));
}
ContractDefinitionAnnotation& ContractDefinition::annotation() const
@@ -207,7 +207,7 @@ TypeNameAnnotation& TypeName::annotation() const
return static_cast<TypeNameAnnotation&>(*m_annotation);
}
-TypePointer StructDefinition::type(ContractDefinition const*) const
+TypePointer StructDefinition::type() const
{
return make_shared<TypeType>(make_shared<StructType>(*this));
}
@@ -219,14 +219,14 @@ TypeDeclarationAnnotation& StructDefinition::annotation() const
return static_cast<TypeDeclarationAnnotation&>(*m_annotation);
}
-TypePointer EnumValue::type(ContractDefinition const*) const
+TypePointer EnumValue::type() const
{
auto parentDef = dynamic_cast<EnumDefinition const*>(scope());
solAssert(parentDef, "Enclosing Scope of EnumValue was not set");
return make_shared<EnumType>(*parentDef);
}
-TypePointer EnumDefinition::type(ContractDefinition const*) const
+TypePointer EnumDefinition::type() const
{
return make_shared<TypeType>(make_shared<EnumType>(*this));
}
@@ -238,7 +238,7 @@ TypeDeclarationAnnotation& EnumDefinition::annotation() const
return static_cast<TypeDeclarationAnnotation&>(*m_annotation);
}
-TypePointer FunctionDefinition::type(ContractDefinition const*) const
+TypePointer FunctionDefinition::type() const
{
return make_shared<FunctionType>(*this);
}
@@ -255,7 +255,7 @@ FunctionDefinitionAnnotation& FunctionDefinition::annotation() const
return static_cast<FunctionDefinitionAnnotation&>(*m_annotation);
}
-TypePointer ModifierDefinition::type(ContractDefinition const*) const
+TypePointer ModifierDefinition::type() const
{
return make_shared<ModifierType>(*this);
}
@@ -267,7 +267,7 @@ ModifierDefinitionAnnotation& ModifierDefinition::annotation() const
return static_cast<ModifierDefinitionAnnotation&>(*m_annotation);
}
-TypePointer EventDefinition::type(ContractDefinition const*) const
+TypePointer EventDefinition::type() const
{
return make_shared<FunctionType>(*this);
}
@@ -324,7 +324,7 @@ bool VariableDeclaration::canHaveAutoType() const
return (!!callable && !isCallableParameter());
}
-TypePointer VariableDeclaration::type(ContractDefinition const*) const
+TypePointer VariableDeclaration::type() const
{
return annotation().type;
}
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index e2ed1853..a28d9f4f 100644
--- a/libsolidity/ast/AST.h
+++ b/libsolidity/ast/AST.h
@@ -58,18 +58,22 @@ public:
virtual void accept(ASTVisitor& _visitor) = 0;
virtual void accept(ASTConstVisitor& _visitor) const = 0;
template <class T>
- static void listAccept(std::vector<ASTPointer<T>>& _list, ASTVisitor& _visitor)
+ static void listAccept(std::vector<T> const& _list, ASTVisitor& _visitor)
{
- for (ASTPointer<T>& element: _list)
+ for (T const& element: _list)
element->accept(_visitor);
}
template <class T>
- static void listAccept(std::vector<ASTPointer<T>> const& _list, ASTConstVisitor& _visitor)
+ static void listAccept(std::vector<T> const& _list, ASTConstVisitor& _visitor)
{
- for (ASTPointer<T> const& element: _list)
+ for (T const& element: _list)
element->accept(_visitor);
}
+ /// @returns a copy of the vector containing only the nodes which derive from T.
+ template <class _T>
+ static std::vector<_T const*> filteredNodes(std::vector<ASTPointer<ASTNode>> const& _nodes);
+
/// Returns the source code location of this node.
SourceLocation const& location() const { return m_location; }
@@ -95,6 +99,16 @@ private:
SourceLocation m_location;
};
+template <class _T>
+std::vector<_T const*> ASTNode::filteredNodes(std::vector<ASTPointer<ASTNode>> const& _nodes)
+{
+ std::vector<_T const*> ret;
+ for (auto const& n: _nodes)
+ if (auto const* nt = dynamic_cast<_T const*>(n.get()))
+ ret.push_back(nt);
+ return ret;
+}
+
/**
* Source unit containing import directives and contract definitions.
*/
@@ -168,7 +182,7 @@ public:
/// The current contract has to be given since this context can change the type, especially of
/// contract types.
/// This can only be called once types of variable declarations have already been resolved.
- virtual TypePointer type(ContractDefinition const* m_currentContract = nullptr) const = 0;
+ virtual TypePointer type() const = 0;
protected:
virtual Visibility defaultVisibility() const { return Visibility::Public; }
@@ -238,23 +252,13 @@ public:
ASTPointer<ASTString> const& _name,
ASTPointer<ASTString> const& _documentation,
std::vector<ASTPointer<InheritanceSpecifier>> const& _baseContracts,
- std::vector<ASTPointer<StructDefinition>> const& _definedStructs,
- std::vector<ASTPointer<EnumDefinition>> const& _definedEnums,
- std::vector<ASTPointer<VariableDeclaration>> const& _stateVariables,
- std::vector<ASTPointer<FunctionDefinition>> const& _definedFunctions,
- std::vector<ASTPointer<ModifierDefinition>> const& _functionModifiers,
- std::vector<ASTPointer<EventDefinition>> const& _events,
+ std::vector<ASTPointer<ASTNode>> const& _subNodes,
bool _isLibrary
):
Declaration(_location, _name),
Documented(_documentation),
m_baseContracts(_baseContracts),
- m_definedStructs(_definedStructs),
- m_definedEnums(_definedEnums),
- m_stateVariables(_stateVariables),
- m_definedFunctions(_definedFunctions),
- m_functionModifiers(_functionModifiers),
- m_events(_events),
+ m_subNodes(_subNodes),
m_isLibrary(_isLibrary)
{}
@@ -262,13 +266,14 @@ public:
virtual void accept(ASTConstVisitor& _visitor) const override;
std::vector<ASTPointer<InheritanceSpecifier>> const& baseContracts() const { return m_baseContracts; }
- std::vector<ASTPointer<StructDefinition>> const& definedStructs() const { return m_definedStructs; }
- std::vector<ASTPointer<EnumDefinition>> const& definedEnums() const { return m_definedEnums; }
- std::vector<ASTPointer<VariableDeclaration>> const& stateVariables() const { return m_stateVariables; }
- std::vector<ASTPointer<ModifierDefinition>> const& functionModifiers() const { return m_functionModifiers; }
- std::vector<ASTPointer<FunctionDefinition>> const& definedFunctions() const { return m_definedFunctions; }
- std::vector<ASTPointer<EventDefinition>> const& events() const { return m_events; }
- std::vector<ASTPointer<EventDefinition>> const& interfaceEvents() const;
+ std::vector<ASTPointer<ASTNode>> const& subNodes() const { return m_subNodes; }
+ std::vector<StructDefinition const*> definedStructs() const { return filteredNodes<StructDefinition>(m_subNodes); }
+ std::vector<EnumDefinition const*> definedEnums() const { return filteredNodes<EnumDefinition>(m_subNodes); }
+ std::vector<VariableDeclaration const*> stateVariables() const { return filteredNodes<VariableDeclaration>(m_subNodes); }
+ std::vector<ModifierDefinition const*> functionModifiers() const { return filteredNodes<ModifierDefinition>(m_subNodes); }
+ std::vector<FunctionDefinition const*> definedFunctions() const { return filteredNodes<FunctionDefinition>(m_subNodes); }
+ std::vector<EventDefinition const*> events() const { return filteredNodes<EventDefinition>(m_subNodes); }
+ std::vector<EventDefinition const*> const& interfaceEvents() const;
bool isLibrary() const { return m_isLibrary; }
/// @returns a map of canonical function signatures to FunctionDefinitions
@@ -290,18 +295,13 @@ public:
std::string const& devDocumentation() const;
void setDevDocumentation(std::string const& _devDocumentation);
- virtual TypePointer type(ContractDefinition const* m_currentContract) const override;
+ virtual TypePointer type() const override;
virtual ContractDefinitionAnnotation& annotation() const override;
private:
std::vector<ASTPointer<InheritanceSpecifier>> m_baseContracts;
- std::vector<ASTPointer<StructDefinition>> m_definedStructs;
- std::vector<ASTPointer<EnumDefinition>> m_definedEnums;
- std::vector<ASTPointer<VariableDeclaration>> m_stateVariables;
- std::vector<ASTPointer<FunctionDefinition>> m_definedFunctions;
- std::vector<ASTPointer<ModifierDefinition>> m_functionModifiers;
- std::vector<ASTPointer<EventDefinition>> m_events;
+ std::vector<ASTPointer<ASTNode>> m_subNodes;
bool m_isLibrary;
// parsed Natspec documentation of the contract.
@@ -310,7 +310,7 @@ private:
std::vector<ContractDefinition const*> m_linearizedBaseContracts;
mutable std::unique_ptr<std::vector<std::pair<FixedHash<4>, FunctionTypePointer>>> m_interfaceFunctionList;
- mutable std::unique_ptr<std::vector<ASTPointer<EventDefinition>>> m_interfaceEvents;
+ mutable std::unique_ptr<std::vector<EventDefinition const*>> m_interfaceEvents;
mutable std::unique_ptr<std::vector<Declaration const*>> m_inheritableMembers;
};
@@ -350,7 +350,7 @@ public:
std::vector<ASTPointer<VariableDeclaration>> const& members() const { return m_members; }
- virtual TypePointer type(ContractDefinition const* m_currentContract) const override;
+ virtual TypePointer type() const override;
virtual TypeDeclarationAnnotation& annotation() const override;
@@ -372,7 +372,7 @@ public:
std::vector<ASTPointer<EnumValue>> const& members() const { return m_members; }
- virtual TypePointer type(ContractDefinition const* m_currentContract) const override;
+ virtual TypePointer type() const override;
virtual TypeDeclarationAnnotation& annotation() const override;
@@ -392,7 +392,7 @@ public:
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
- virtual TypePointer type(ContractDefinition const* m_currentContract) const override;
+ virtual TypePointer type() const override;
};
/**
@@ -490,7 +490,7 @@ public:
/// arguments separated by commas all enclosed in parentheses without any spaces.
std::string externalSignature() const;
- virtual TypePointer type(ContractDefinition const* m_currentContract) const override;
+ virtual TypePointer type() const override;
virtual FunctionDefinitionAnnotation& annotation() const override;
@@ -551,7 +551,7 @@ public:
bool isConstant() const { return m_isConstant; }
Location referenceLocation() const { return m_location; }
- virtual TypePointer type(ContractDefinition const* m_currentContract) const override;
+ virtual TypePointer type() const override;
virtual VariableDeclarationAnnotation& annotation() const override;
@@ -593,7 +593,7 @@ public:
Block const& body() const { return *m_body; }
- virtual TypePointer type(ContractDefinition const* m_currentContract) const override;
+ virtual TypePointer type() const override;
virtual ModifierDefinitionAnnotation& annotation() const override;
@@ -649,7 +649,7 @@ public:
bool isAnonymous() const { return m_anonymous; }
- virtual TypePointer type(ContractDefinition const* m_currentContract) const override;
+ virtual TypePointer type() const override;
virtual EventDefinitionAnnotation& annotation() const override;
@@ -675,7 +675,7 @@ public:
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("MagicVariableDeclaration used inside real AST."));
}
- virtual TypePointer type(ContractDefinition const*) const override { return m_type; }
+ virtual TypePointer type() const override { return m_type; }
private:
std::shared_ptr<Type const> m_type;
diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h
index b9667302..4e0187cf 100644
--- a/libsolidity/ast/ASTAnnotations.h
+++ b/libsolidity/ast/ASTAnnotations.h
@@ -138,9 +138,6 @@ struct ExpressionAnnotation: ASTAnnotation
struct IdentifierAnnotation: ExpressionAnnotation
{
- /// Stores a reference to the current contract.
- /// This is needed because types of base contracts change depending on the context.
- ContractDefinition const* contractScope = nullptr;
/// Referenced declaration, set at latest during overload resolution stage.
Declaration const* referencedDeclaration = nullptr;
/// List of possible declarations it could refer to.
diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h
index 99d1bf6a..f65595b8 100644
--- a/libsolidity/ast/AST_accept.h
+++ b/libsolidity/ast/AST_accept.h
@@ -62,12 +62,7 @@ void ContractDefinition::accept(ASTVisitor& _visitor)
if (_visitor.visit(*this))
{
listAccept(m_baseContracts, _visitor);
- listAccept(m_definedStructs, _visitor);
- listAccept(m_definedEnums, _visitor);
- listAccept(m_stateVariables, _visitor);
- listAccept(m_events, _visitor);
- listAccept(m_functionModifiers, _visitor);
- listAccept(m_definedFunctions, _visitor);
+ listAccept(m_subNodes, _visitor);
}
_visitor.endVisit(*this);
}
@@ -77,12 +72,7 @@ void ContractDefinition::accept(ASTConstVisitor& _visitor) const
if (_visitor.visit(*this))
{
listAccept(m_baseContracts, _visitor);
- listAccept(m_definedStructs, _visitor);
- listAccept(m_definedEnums, _visitor);
- listAccept(m_stateVariables, _visitor);
- listAccept(m_events, _visitor);
- listAccept(m_functionModifiers, _visitor);
- listAccept(m_definedFunctions, _visitor);
+ listAccept(m_subNodes, _visitor);
}
_visitor.endVisit(*this);
}
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index cb97eae8..96f44571 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -858,7 +858,7 @@ string ArrayType::canonicalName(bool _addDataLocation) const
return ret;
}
-MemberList const& ArrayType::members() const
+MemberList const& ArrayType::members(ContractDefinition const*) const
{
if (!m_members)
{
@@ -956,7 +956,7 @@ string ContractType::canonicalName(bool) const
return m_contract.annotation().canonicalName;
}
-MemberList const& ContractType::members() const
+MemberList const& ContractType::members(ContractDefinition const*) const
{
// We need to lazy-initialize it because of recursive references.
if (!m_members)
@@ -970,7 +970,7 @@ MemberList const& ContractType::members() const
{
// add the most derived of all functions which are visible in derived contracts
for (ContractDefinition const* base: m_contract.annotation().linearizedBaseContracts)
- for (ASTPointer<FunctionDefinition> const& function: base->definedFunctions())
+ for (FunctionDefinition const* function: base->definedFunctions())
{
if (!function->isVisibleInDerivedContracts())
continue;
@@ -991,7 +991,7 @@ MemberList const& ContractType::members() const
members.push_back(MemberList::Member(
function->name(),
functionType,
- function.get()
+ function
));
}
}
@@ -1024,9 +1024,9 @@ vector<tuple<VariableDeclaration const*, u256, unsigned>> ContractType::stateVar
{
vector<VariableDeclaration const*> variables;
for (ContractDefinition const* contract: boost::adaptors::reverse(m_contract.annotation().linearizedBaseContracts))
- for (ASTPointer<VariableDeclaration> const& variable: contract->stateVariables())
+ for (VariableDeclaration const* variable: contract->stateVariables())
if (!variable->isConstant())
- variables.push_back(variable.get());
+ variables.push_back(variable);
TypePointers types;
for (auto variable: variables)
types.push_back(variable->annotation().type);
@@ -1064,7 +1064,7 @@ bool StructType::operator==(Type const& _other) const
unsigned StructType::calldataEncodedSize(bool _padded) const
{
unsigned size = 0;
- for (auto const& member: members())
+ for (auto const& member: members(nullptr))
if (!member.type->canLiveOutsideStorage())
return 0;
else
@@ -1080,7 +1080,7 @@ unsigned StructType::calldataEncodedSize(bool _padded) const
u256 StructType::memorySize() const
{
u256 size;
- for (auto const& member: members())
+ for (auto const& member: members(nullptr))
if (member.type->canLiveOutsideStorage())
size += member.type->memoryHeadSize();
return size;
@@ -1088,7 +1088,7 @@ u256 StructType::memorySize() const
u256 StructType::storageSize() const
{
- return max<u256>(1, members().storageSize());
+ return max<u256>(1, members(nullptr).storageSize());
}
string StructType::toString(bool _short) const
@@ -1099,7 +1099,7 @@ string StructType::toString(bool _short) const
return ret;
}
-MemberList const& StructType::members() const
+MemberList const& StructType::members(ContractDefinition const*) const
{
// We need to lazy-initialize it because of recursive references.
if (!m_members)
@@ -1149,7 +1149,7 @@ FunctionTypePointer StructType::constructorType() const
{
TypePointers paramTypes;
strings paramNames;
- for (auto const& member: members())
+ for (auto const& member: members(nullptr))
{
if (!member.type->canLiveOutsideStorage())
continue;
@@ -1167,7 +1167,7 @@ FunctionTypePointer StructType::constructorType() const
pair<u256, unsigned> const& StructType::storageOffsetsOfMember(string const& _name) const
{
- auto const* offsets = members().memberStorageOffset(_name);
+ auto const* offsets = members(nullptr).memberStorageOffset(_name);
solAssert(offsets, "Storage offset of non-existing member requested.");
return *offsets;
}
@@ -1175,7 +1175,7 @@ pair<u256, unsigned> const& StructType::storageOffsetsOfMember(string const& _na
u256 StructType::memoryOffsetOfMember(string const& _name) const
{
u256 offset;
- for (auto const& member: members())
+ for (auto const& member: members(nullptr))
if (member.name == _name)
return offset;
else
@@ -1395,7 +1395,7 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl):
vector<string> retParamNames;
if (auto structType = dynamic_cast<StructType const*>(returnType.get()))
{
- for (auto const& member: structType->members())
+ for (auto const& member: structType->members(nullptr))
if (member.type->category() != Category::Mapping)
{
if (auto arrayType = dynamic_cast<ArrayType const*>(member.type.get()))
@@ -1533,7 +1533,7 @@ FunctionTypePointer FunctionType::interfaceFunctionType() const
return make_shared<FunctionType>(paramTypes, retParamTypes, m_parameterNames, m_returnParameterNames, m_location, m_arbitraryParameters);
}
-MemberList const& FunctionType::members() const
+MemberList const& FunctionType::members(ContractDefinition const*) const
{
switch (m_location)
{
@@ -1784,10 +1784,10 @@ unsigned TypeType::sizeOnStack() const
return 0;
}
-MemberList const& TypeType::members() const
+MemberList const& TypeType::members(ContractDefinition const* _currentScope) const
{
// We need to lazy-initialize it because of recursive references.
- if (!m_members)
+ if (!m_members || m_cachedScope != _currentScope)
{
MemberList::MemberMap members;
if (m_actualType->category() == Category::Contract)
@@ -1800,9 +1800,9 @@ MemberList const& TypeType::members() const
it.second->asMemberFunction(true), // use callcode
&it.second->declaration()
));
- else if (m_currentContract != nullptr)
+ else if (_currentScope != nullptr)
{
- auto const& currentBases = m_currentContract->annotation().linearizedBaseContracts;
+ auto const& currentBases = _currentScope->annotation().linearizedBaseContracts;
if (find(currentBases.begin(), currentBases.end(), &contract) != currentBases.end())
// We are accessing the type of a base contract, so add all public and protected
// members. Note that this does not add inherited functions on purpose.
@@ -1818,6 +1818,7 @@ MemberList const& TypeType::members() const
members.push_back(MemberList::Member(enumValue->name(), enumType));
}
m_members.reset(new MemberList(members));
+ m_cachedScope = _currentScope;
}
return *m_members;
}
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index 63207a51..f841a1be 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -217,9 +217,13 @@ public:
}
/// Returns the list of all members of this type. Default implementation: no members.
- virtual MemberList const& members() const { return EmptyMemberList; }
+ /// @param _currentScope scope in which the members are accessed.
+ virtual MemberList const& members(ContractDefinition const* /*_currentScope*/) const { return EmptyMemberList; }
/// Convenience method, returns the type of the given named member or an empty pointer if no such member exists.
- TypePointer memberType(std::string const& _name) const { return members().memberType(_name); }
+ TypePointer memberType(std::string const& _name, ContractDefinition const* _currentScope = nullptr) const
+ {
+ return members(_currentScope).memberType(_name);
+ }
virtual std::string toString(bool _short) const = 0;
std::string toString() const { return toString(false); }
@@ -277,7 +281,10 @@ public:
virtual unsigned storageBytes() const override { return m_bits / 8; }
virtual bool isValueType() const override { return true; }
- virtual MemberList const& members() const override { return isAddress() ? AddressMemberList : EmptyMemberList; }
+ virtual MemberList const& members(ContractDefinition const* /*_currentScope*/) const override
+ {
+ return isAddress() ? AddressMemberList : EmptyMemberList;
+ }
virtual std::string toString(bool _short) const override;
@@ -510,7 +517,7 @@ public:
virtual unsigned sizeOnStack() const override;
virtual std::string toString(bool _short) const override;
virtual std::string canonicalName(bool _addDataLocation) const override;
- virtual MemberList const& members() const override;
+ virtual MemberList const& members(ContractDefinition const* _currentScope) const override;
virtual TypePointer encodingType() const override;
virtual TypePointer decodingType() const override;
virtual TypePointer interfaceType(bool _inLibrary) const override;
@@ -563,7 +570,7 @@ public:
virtual std::string toString(bool _short) const override;
virtual std::string canonicalName(bool _addDataLocation) const override;
- virtual MemberList const& members() const override;
+ virtual MemberList const& members(ContractDefinition const* _currentScope) const override;
virtual TypePointer encodingType() const override
{
return std::make_shared<IntegerType>(160, IntegerType::Modifier::Address);
@@ -616,7 +623,7 @@ public:
virtual bool canLiveOutsideStorage() const override { return true; }
virtual std::string toString(bool _short) const override;
- virtual MemberList const& members() const override;
+ virtual MemberList const& members(ContractDefinition const* _currentScope) const override;
virtual TypePointer encodingType() const override
{
return location() == DataLocation::Storage ? std::make_shared<IntegerType>(256) : TypePointer();
@@ -810,7 +817,7 @@ public:
virtual u256 storageSize() const override;
virtual bool canLiveOutsideStorage() const override { return false; }
virtual unsigned sizeOnStack() const override;
- virtual MemberList const& members() const override;
+ virtual MemberList const& members(ContractDefinition const* _currentScope) const override;
/// @returns TypePointer of a new FunctionType object. All input/return parameters are an
/// appropriate external types (i.e. the interfaceType()s) of input/return parameters of
@@ -918,8 +925,7 @@ class TypeType: public Type
{
public:
virtual Category category() const override { return Category::TypeType; }
- explicit TypeType(TypePointer const& _actualType, ContractDefinition const* _currentContract = nullptr):
- m_actualType(_actualType), m_currentContract(_currentContract) {}
+ explicit TypeType(TypePointer const& _actualType): m_actualType(_actualType) {}
TypePointer const& actualType() const { return m_actualType; }
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
@@ -929,14 +935,13 @@ public:
virtual bool canLiveOutsideStorage() const override { return false; }
virtual unsigned sizeOnStack() const override;
virtual std::string toString(bool _short) const override { return "type(" + m_actualType->toString(_short) + ")"; }
- virtual MemberList const& members() const override;
+ virtual MemberList const& members(ContractDefinition const* _currentScope) const override;
private:
TypePointer m_actualType;
- /// Context in which this type is used (influences visibility etc.), can be nullptr.
- ContractDefinition const* m_currentContract;
/// List of member types, will be lazy-initialized because of recursive references.
mutable std::unique_ptr<MemberList> m_members;
+ mutable ContractDefinition const* m_cachedScope = nullptr;
};
@@ -983,7 +988,7 @@ public:
virtual bool canBeStored() const override { return false; }
virtual bool canLiveOutsideStorage() const override { return true; }
virtual unsigned sizeOnStack() const override { return 0; }
- virtual MemberList const& members() const override { return m_members; }
+ virtual MemberList const& members(ContractDefinition const*) const override { return m_members; }
virtual std::string toString(bool _short) const override;