diff options
Diffstat (limited to 'libsolidity/ast')
-rw-r--r-- | libsolidity/ast/AST.cpp | 48 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 80 | ||||
-rw-r--r-- | libsolidity/ast/ASTAnnotations.h | 3 | ||||
-rw-r--r-- | libsolidity/ast/AST_accept.h | 14 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 39 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 31 |
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; |