From bc71f6146772b5b239f7791801177237a9c3b48a Mon Sep 17 00:00:00 2001 From: Jason Cobb Date: Thu, 19 Dec 2019 18:01:43 -0500 Subject: [PATCH 1/5] Add ScopableAnnotation --- libsolidity/ast/ASTAnnotations.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 6d3c89092..268532976 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -75,6 +75,13 @@ struct SourceUnitAnnotation: ASTAnnotation std::set experimentalFeatures; }; +struct ScopableAnnotation +{ + /// The scope this declaration resides in. Can be nullptr if it is the global scope. + /// Available only after name and type resolution step. + ASTNode const* scope = nullptr; +}; + struct ImportAnnotation: ASTAnnotation { /// The absolute path of the source unit to import. From be14d5f28d0cc71f5e6a12c4c3bd81678f49a252 Mon Sep 17 00:00:00 2001 From: Jason Cobb Date: Thu, 19 Dec 2019 18:04:46 -0500 Subject: [PATCH 2/5] Add DeclarationAnnotation --- libsolidity/ast/AST.cpp | 7 +++++++ libsolidity/ast/AST.h | 2 ++ libsolidity/ast/ASTAnnotations.h | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 140fe7a99..cd8a66ad7 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -449,6 +449,13 @@ string Scopable::sourceUnitName() const return sourceUnit().annotation().path; } +DeclarationAnnotation& Declaration::annotation() const +{ + if (!m_annotation) + m_annotation = make_unique(); + return dynamic_cast(*m_annotation); +} + bool VariableDeclaration::isLValue() const { // Constant declared variables are Read-Only diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index f761fe7af..871760a41 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -231,6 +231,8 @@ public: /// @returns null when it is not accessible as a function. virtual FunctionTypePointer functionType(bool /*_internal*/) const { return {}; } + DeclarationAnnotation& annotation() const override; + protected: virtual Visibility defaultVisibility() const { return Visibility::Public; } diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 268532976..8fa02a3fe 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -82,6 +82,10 @@ struct ScopableAnnotation ASTNode const* scope = nullptr; }; +struct DeclarationAnnotation: ASTAnnotation, ScopableAnnotation +{ +}; + struct ImportAnnotation: ASTAnnotation { /// The absolute path of the source unit to import. From 30b1b39901befd2f7e911ee9083c27f6b52eb07e Mon Sep 17 00:00:00 2001 From: Jason Cobb Date: Thu, 19 Dec 2019 18:14:53 -0500 Subject: [PATCH 3/5] Have other annotations subclass DeclarationAnnotation --- libsolidity/ast/ASTAnnotations.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 8fa02a3fe..107da87f5 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -86,7 +86,7 @@ struct DeclarationAnnotation: ASTAnnotation, ScopableAnnotation { }; -struct ImportAnnotation: ASTAnnotation +struct ImportAnnotation: DeclarationAnnotation { /// The absolute path of the source unit to import. std::string absolutePath; @@ -94,7 +94,7 @@ struct ImportAnnotation: ASTAnnotation SourceUnit const* sourceUnit = nullptr; }; -struct TypeDeclarationAnnotation: ASTAnnotation +struct TypeDeclarationAnnotation: DeclarationAnnotation { /// The name of this type, prefixed by proper namespaces if globally accessible. std::string canonicalName; @@ -115,7 +115,7 @@ struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, DocumentedAnnota std::map baseConstructorArguments; }; -struct CallableDeclarationAnnotation: ASTAnnotation +struct CallableDeclarationAnnotation: DeclarationAnnotation { /// The set of functions/modifiers/events this callable overrides. std::set baseFunctions; @@ -135,7 +135,7 @@ struct ModifierDefinitionAnnotation: CallableDeclarationAnnotation, DocumentedAn { }; -struct VariableDeclarationAnnotation: ASTAnnotation +struct VariableDeclarationAnnotation: DeclarationAnnotation { /// Type of variable (type of identifier referencing this variable). TypePointer type = nullptr; From 69fd185903e86e55fef1740395417d763887afdc Mon Sep 17 00:00:00 2001 From: Jason Cobb Date: Thu, 19 Dec 2019 20:20:27 -0500 Subject: [PATCH 4/5] Add new annotations for Scopables --- libsolidity/ast/AST.cpp | 21 +++++++++++++++++++++ libsolidity/ast/AST.h | 6 ++++++ libsolidity/ast/ASTAnnotations.h | 12 ++++++++++++ 3 files changed, 39 insertions(+) diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index cd8a66ad7..a7d5e73ca 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -660,6 +660,27 @@ InlineAssemblyAnnotation& InlineAssembly::annotation() const return dynamic_cast(*m_annotation); } +BlockAnnotation& Block::annotation() const +{ + if (!m_annotation) + m_annotation = make_unique(); + return dynamic_cast(*m_annotation); +} + +TryCatchClauseAnnotation& TryCatchClause::annotation() const +{ + if (!m_annotation) + m_annotation = make_unique(); + return dynamic_cast(*m_annotation); +} + +ForStatementAnnotation& ForStatement::annotation() const +{ + if (!m_annotation) + m_annotation = make_unique(); + return dynamic_cast(*m_annotation); +} + ReturnAnnotation& Return::annotation() const { if (!m_annotation) diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 871760a41..4abaf93e3 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -1171,6 +1171,8 @@ public: std::vector> const& statements() const { return m_statements; } + BlockAnnotation& annotation() const override; + private: std::vector> m_statements; }; @@ -1250,6 +1252,8 @@ public: ParameterList const* parameters() const { return m_parameters.get(); } Block const& block() const { return *m_block; } + TryCatchClauseAnnotation& annotation() const override; + private: ASTPointer m_errorName; ASTPointer m_parameters; @@ -1359,6 +1363,8 @@ public: ExpressionStatement const* loopExpression() const { return m_loopExpression.get(); } Statement const& body() const { return *m_body; } + ForStatementAnnotation& annotation() const override; + private: /// For statement's initialization expression. for (XXX; ; ). Can be empty ASTPointer m_initExpression; diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 107da87f5..0f11b1c5a 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -163,6 +163,18 @@ struct InlineAssemblyAnnotation: StatementAnnotation std::shared_ptr analysisInfo; }; +struct BlockAnnotation: StatementAnnotation, ScopableAnnotation +{ +}; + +struct TryCatchClauseAnnotation: ASTAnnotation, ScopableAnnotation +{ +}; + +struct ForStatementAnnotation: StatementAnnotation, ScopableAnnotation +{ +}; + struct ReturnAnnotation: StatementAnnotation { /// Reference to the return parameters of the function. From 6679f92c8afbf1f0361702320b0123dc59addff1 Mon Sep 17 00:00:00 2001 From: Jason Cobb Date: Thu, 19 Dec 2019 20:49:43 -0500 Subject: [PATCH 5/5] Move all references to scope into annotation --- libsolidity/analysis/NameAndTypeResolver.cpp | 8 ++++---- libsolidity/ast/AST.h | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 21f8a5d19..6881e14d6 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -639,7 +639,7 @@ void DeclarationRegistrationHelper::endVisit(FunctionDefinition&) bool DeclarationRegistrationHelper::visit(TryCatchClause& _tryCatchClause) { - _tryCatchClause.setScope(m_currentScope); + _tryCatchClause.annotation().scope = m_currentScope; enterNewSubScope(_tryCatchClause); return true; } @@ -675,7 +675,7 @@ void DeclarationRegistrationHelper::endVisit(FunctionTypeName&) bool DeclarationRegistrationHelper::visit(Block& _block) { - _block.setScope(m_currentScope); + _block.annotation().scope = m_currentScope; enterNewSubScope(_block); return true; } @@ -687,7 +687,7 @@ void DeclarationRegistrationHelper::endVisit(Block&) bool DeclarationRegistrationHelper::visit(ForStatement& _for) { - _for.setScope(m_currentScope); + _for.annotation().scope = m_currentScope; enterNewSubScope(_for); return true; } @@ -761,7 +761,7 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, warnAboutShadowing, inactive, m_errorReporter); - _declaration.setScope(m_currentScope); + _declaration.annotation().scope = m_currentScope; if (_opensScope) enterNewSubScope(_declaration); } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 4abaf93e3..f687f20c9 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -159,8 +159,7 @@ public: virtual ~Scopable() = default; /// @returns the scope this declaration resides in. Can be nullptr if it is the global scope. /// Available only after name and type resolution step. - ASTNode const* scope() const { return m_scope; } - void setScope(ASTNode const* _scope) { m_scope = _scope; } + ASTNode const* scope() const { return annotation().scope; } /// @returns the source unit this scopable is present in. SourceUnit const& sourceUnit() const; @@ -172,8 +171,7 @@ public: /// Can be combined with annotation().canonicalName (if present) to form a globally unique name. std::string sourceUnitName() const; -protected: - ASTNode const* m_scope = nullptr; + virtual ScopableAnnotation& annotation() const = 0; }; /**