From 6b9dda06f3d85344a70efb2f868760a0dde9dc45 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 14 Feb 2018 01:48:40 +0100 Subject: Enable C99-scoping with the 0.5.0-experimental pragma. --- libsolidity/analysis/NameAndTypeResolver.cpp | 30 ++++++++++++++++------------ libsolidity/analysis/ReferencesResolver.cpp | 17 ++++++++++++---- libsolidity/analysis/ReferencesResolver.h | 1 + libsolidity/ast/AST.cpp | 30 ++++++++++++++-------------- libsolidity/ast/AST.h | 13 ++++++------ 5 files changed, 53 insertions(+), 38 deletions(-) (limited to 'libsolidity') diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 1566df94..40021771 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -612,26 +612,34 @@ void DeclarationRegistrationHelper::endVisit(ModifierDefinition&) bool DeclarationRegistrationHelper::visit(Block& _block) { - enterNewSubScope(_block); + _block.setScope(m_currentScope); + // Enable C99-scoped variables. + if (_block.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050)) + enterNewSubScope(_block); return true; } -void DeclarationRegistrationHelper::endVisit(Block&) +void DeclarationRegistrationHelper::endVisit(Block& _block) { - closeCurrentScope(); + // Enable C99-scoped variables. + if (_block.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050)) + closeCurrentScope(); } bool DeclarationRegistrationHelper::visit(ForStatement& _for) { - // TODO special scoping rules for the init statement - if it is a block, then it should - // not open its own scope. - enterNewSubScope(_for); + _for.setScope(m_currentScope); + if (_for.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050)) + // TODO special scoping rules for the init statement - if it is a block, then it should + // not open its own scope. + enterNewSubScope(_for); return true; } -void DeclarationRegistrationHelper::endVisit(ForStatement&) +void DeclarationRegistrationHelper::endVisit(ForStatement& _for) { - closeCurrentScope(); + if (_for.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050)) + closeCurrentScope(); } void DeclarationRegistrationHelper::endVisit(VariableDeclarationStatement& _variableDeclarationStatement) @@ -663,9 +671,6 @@ void DeclarationRegistrationHelper::endVisit(EventDefinition&) void DeclarationRegistrationHelper::enterNewSubScope(ASTNode& _subScope) { - if (auto s = dynamic_cast(&_subScope)) - s->setScope(m_currentScope); - map>::iterator iter; bool newlyAdded; shared_ptr container(new DeclarationContainer(m_currentScope, m_scopes[m_currentScope].get())); @@ -701,10 +706,9 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, warnAboutShadowing, m_errorReporter); + _declaration.setScope(m_currentScope); if (_opensScope) enterNewSubScope(_declaration); - else - _declaration.setScope(m_currentScope); } string DeclarationRegistrationHelper::currentCanonicalName() const diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index bee42e77..4d919f2b 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -47,7 +47,10 @@ bool ReferencesResolver::visit(Block const& _block) { if (!m_resolveInsideCode) return false; - m_resolver.setScope(&_block); + m_experimental050Mode = _block.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); + // C99-scoped variables + if (m_experimental050Mode) + m_resolver.setScope(&_block); return true; } @@ -56,14 +59,19 @@ void ReferencesResolver::endVisit(Block const& _block) if (!m_resolveInsideCode) return; - m_resolver.setScope(_block.scope()); + // C99-scoped variables + if (m_experimental050Mode) + m_resolver.setScope(_block.scope()); } bool ReferencesResolver::visit(ForStatement const& _for) { if (!m_resolveInsideCode) return false; - m_resolver.setScope(&_for); + m_experimental050Mode = _for.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); + // C99-scoped variables + if (m_experimental050Mode) + m_resolver.setScope(&_for); return true; } @@ -71,7 +79,8 @@ void ReferencesResolver::endVisit(ForStatement const& _for) { if (!m_resolveInsideCode) return; - m_resolver.setScope(_for.scope()); + if (m_experimental050Mode) + m_resolver.setScope(_for.scope()); } bool ReferencesResolver::visit(Identifier const& _identifier) diff --git a/libsolidity/analysis/ReferencesResolver.h b/libsolidity/analysis/ReferencesResolver.h index 5bfd6c5a..ab7c987e 100644 --- a/libsolidity/analysis/ReferencesResolver.h +++ b/libsolidity/analysis/ReferencesResolver.h @@ -93,6 +93,7 @@ private: std::vector m_returnParameters; bool const m_resolveInsideCode; bool m_errorOccurred = false; + bool m_experimental050Mode = false; }; } diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 60a15aeb..27220b1f 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -96,21 +96,6 @@ set SourceUnit::referencedSourceUnits(bool _recurse, set(s) && dynamic_cast(s)->scope()) - s = dynamic_cast(s)->scope(); - return dynamic_cast(*s); -} - -string Declaration::sourceUnitName() const -{ - return sourceUnit().annotation().path; -} - ImportAnnotation& ImportDirective::annotation() const { if (!m_annotation) @@ -409,6 +394,21 @@ UserDefinedTypeNameAnnotation& UserDefinedTypeName::annotation() const return dynamic_cast(*m_annotation); } +SourceUnit const& Scopable::sourceUnit() const +{ + ASTNode const* s = scope(); + solAssert(s, ""); + // will not always be a declaratoion + while (dynamic_cast(s) && dynamic_cast(s)->scope()) + s = dynamic_cast(s)->scope(); + return dynamic_cast(*s); +} + +string Scopable::sourceUnitName() const +{ + return sourceUnit().annotation().path; +} + bool VariableDeclaration::isLValue() const { // External function parameters and constant declared variables are Read-Only diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 1e4c6591..863ad2fe 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -151,6 +151,13 @@ public: ASTNode const* scope() const { return m_scope; } void setScope(ASTNode const* _scope) { m_scope = _scope; } + /// @returns the source unit this scopable is present in. + SourceUnit const& sourceUnit() const; + + /// @returns the source name this scopable is present in. + /// Can be combined with annotation().canonicalName (if present) to form a globally unique name. + std::string sourceUnitName() const; + protected: ASTNode const* m_scope = nullptr; }; @@ -197,12 +204,6 @@ public: virtual bool isVisibleInContract() const { return visibility() != Visibility::External; } bool isVisibleInDerivedContracts() const { return isVisibleInContract() && visibility() >= Visibility::Internal; } - /// @returns the source unit this declaration is present in. - SourceUnit const& sourceUnit() const; - - /// @returns the source name this declaration is present in. - /// Can be combined with annotation().canonicalName to form a globally unique name. - std::string sourceUnitName() const; std::string fullyQualifiedName() const { return sourceUnitName() + ":" + name(); } virtual bool isLValue() const { return false; } -- cgit