aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-11-24 06:57:17 +0800
committerchriseth <c@ethdev.com>2015-11-26 22:37:55 +0800
commitb47d5932528357939ee29758a8b8027c90bdb1e5 (patch)
treea32526db014b5a654e193660e883e97ab437aa95
parent86495dfc57dde9b825ffd8c219ea809446e978f9 (diff)
downloaddexon-solidity-b47d5932528357939ee29758a8b8027c90bdb1e5.tar.gz
dexon-solidity-b47d5932528357939ee29758a8b8027c90bdb1e5.tar.zst
dexon-solidity-b47d5932528357939ee29758a8b8027c90bdb1e5.zip
Do not store elements of a contract by AST node type.
-rw-r--r--libsolidity/analysis/NameAndTypeResolver.cpp38
-rw-r--r--libsolidity/analysis/ReferencesResolver.cpp2
-rw-r--r--libsolidity/analysis/ReferencesResolver.h2
-rw-r--r--libsolidity/analysis/TypeChecker.cpp32
-rw-r--r--libsolidity/ast/AST.cpp84
-rw-r--r--libsolidity/ast/AST.h46
-rw-r--r--libsolidity/ast/AST_accept.h14
-rw-r--r--libsolidity/ast/Types.cpp8
-rw-r--r--libsolidity/codegen/Compiler.cpp2
-rw-r--r--libsolidity/codegen/CompilerContext.cpp6
-rw-r--r--libsolidity/formal/Why3Translator.cpp15
-rw-r--r--libsolidity/formal/Why3Translator.h2
-rw-r--r--libsolidity/parsing/Parser.cpp26
-rw-r--r--test/libsolidity/SolidityParser.cpp16
14 files changed, 141 insertions, 152 deletions
diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp
index a2397d9e..612989e1 100644
--- a/libsolidity/analysis/NameAndTypeResolver.cpp
+++ b/libsolidity/analysis/NameAndTypeResolver.cpp
@@ -84,35 +84,11 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
importInheritedScope(*base);
}
- for (ASTPointer<StructDefinition> const& structDef: _contract.definedStructs())
- if (!resolver.resolve(*structDef))
- success = false;
- for (ASTPointer<EnumDefinition> const& enumDef: _contract.definedEnums())
- if (!resolver.resolve(*enumDef))
- success = false;
- for (ASTPointer<VariableDeclaration> const& variable: _contract.stateVariables())
- if (!resolver.resolve(*variable))
- success = false;
- for (ASTPointer<EventDefinition> const& event: _contract.events())
- if (!resolver.resolve(*event))
- success = false;
// these can contain code, only resolve parameters for now
- for (ASTPointer<ModifierDefinition> const& modifier: _contract.functionModifiers())
+ for (ASTPointer<ASTNode> const& node: _contract.subNodes())
{
- m_currentScope = &m_scopes[modifier.get()];
- ReferencesResolver resolver(m_errors, *this, nullptr);
- if (!resolver.resolve(*modifier))
- success = false;
- }
-
- for (ASTPointer<FunctionDefinition> const& function: _contract.definedFunctions())
- {
- m_currentScope = &m_scopes[function.get()];
- if (!ReferencesResolver(
- m_errors,
- *this,
- function->returnParameterList().get()
- ).resolve(*function))
+ m_currentScope = &m_scopes[m_scopes.count(node.get()) ? node.get() : &_contract];
+ if (!resolver.resolve(*node))
success = false;
}
@@ -122,17 +98,17 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
m_currentScope = &m_scopes[&_contract];
// now resolve references inside the code
- for (ASTPointer<ModifierDefinition> const& modifier: _contract.functionModifiers())
+ for (ModifierDefinition const* modifier: _contract.functionModifiers())
{
- m_currentScope = &m_scopes[modifier.get()];
+ m_currentScope = &m_scopes[modifier];
ReferencesResolver resolver(m_errors, *this, nullptr, true);
if (!resolver.resolve(*modifier))
success = false;
}
- for (ASTPointer<FunctionDefinition> const& function: _contract.definedFunctions())
+ for (FunctionDefinition const* function: _contract.definedFunctions())
{
- m_currentScope = &m_scopes[function.get()];
+ m_currentScope = &m_scopes[function];
if (!ReferencesResolver(
m_errors,
*this,
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp
index 2207fd80..e5b1c52b 100644
--- a/libsolidity/analysis/ReferencesResolver.cpp
+++ b/libsolidity/analysis/ReferencesResolver.cpp
@@ -53,7 +53,7 @@ bool ReferencesResolver::visit(UserDefinedTypeName const& _typeName)
return true;
}
-bool ReferencesResolver::resolve(ASTNode& _root)
+bool ReferencesResolver::resolve(ASTNode const& _root)
{
try
{
diff --git a/libsolidity/analysis/ReferencesResolver.h b/libsolidity/analysis/ReferencesResolver.h
index 870312f1..6f5ced8c 100644
--- a/libsolidity/analysis/ReferencesResolver.h
+++ b/libsolidity/analysis/ReferencesResolver.h
@@ -55,7 +55,7 @@ public:
{}
/// @returns true if no errors during resolving
- bool resolve(ASTNode& _root);
+ bool resolve(ASTNode const& _root);
private:
virtual bool visit(Block const&) override { return m_resolveInsideCode; }
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 2dc357bb..1d2d0258 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -63,6 +63,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
m_scope = &_contract;
// We force our own visiting order here.
+ //@TODO structs will be visited again below, but it is probably fine.
ASTNode::listAccept(_contract.definedStructs(), *this);
ASTNode::listAccept(_contract.baseContracts(), *this);
@@ -76,7 +77,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
typeError(function->returnParameterList()->location(), "Non-empty \"returns\" directive for constructor.");
FunctionDefinition const* fallbackFunction = nullptr;
- for (ASTPointer<FunctionDefinition> const& function: _contract.definedFunctions())
+ for (FunctionDefinition const* function: _contract.definedFunctions())
{
if (function->name().empty())
{
@@ -88,7 +89,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
}
else
{
- fallbackFunction = function.get();
+ fallbackFunction = function;
if (!fallbackFunction->parameters().empty())
typeError(fallbackFunction->parameterList().location(), "Fallback function cannot take parameters.");
}
@@ -97,10 +98,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
_contract.annotation().isFullyImplemented = false;
}
- ASTNode::listAccept(_contract.stateVariables(), *this);
- ASTNode::listAccept(_contract.events(), *this);
- ASTNode::listAccept(_contract.functionModifiers(), *this);
- ASTNode::listAccept(_contract.definedFunctions(), *this);
+ ASTNode::listAccept(_contract.subNodes(), *this);
checkContractExternalTypeClashes(_contract);
// check for hash collisions in function signatures
@@ -127,8 +125,8 @@ void TypeChecker::checkContractDuplicateFunctions(ContractDefinition const& _con
/// Checks that two functions with the same name defined in this contract have different
/// argument types and that there is at most one constructor.
map<string, vector<FunctionDefinition const*>> functions;
- for (ASTPointer<FunctionDefinition> const& function: _contract.definedFunctions())
- functions[function->name()].push_back(function.get());
+ for (FunctionDefinition const* function: _contract.definedFunctions())
+ functions[function->name()].push_back(function);
// Constructor
if (functions[_contract.name()].size() > 1)
@@ -172,7 +170,7 @@ void TypeChecker::checkContractAbstractFunctions(ContractDefinition const& _cont
// Search from base to derived
for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.annotation().linearizedBaseContracts))
- for (ASTPointer<FunctionDefinition> const& function: contract->definedFunctions())
+ for (FunctionDefinition const* function: contract->definedFunctions())
{
auto& overloads = functions[function->name()];
FunctionTypePointer funType = make_shared<FunctionType>(*function);
@@ -248,7 +246,7 @@ void TypeChecker::checkContractIllegalOverrides(ContractDefinition const& _contr
// We search from derived to base, so the stored item causes the error.
for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts)
{
- for (ASTPointer<FunctionDefinition> const& function: contract->definedFunctions())
+ for (FunctionDefinition const* function: contract->definedFunctions())
{
if (function->isConstructor())
continue; // constructors can neither be overridden nor override anything
@@ -269,14 +267,14 @@ void TypeChecker::checkContractIllegalOverrides(ContractDefinition const& _contr
)
typeError(overriding->location(), "Override changes extended function signature.");
}
- functions[name].push_back(function.get());
+ functions[name].push_back(function);
}
- for (ASTPointer<ModifierDefinition> const& modifier: contract->functionModifiers())
+ for (ModifierDefinition const* modifier: contract->functionModifiers())
{
string const& name = modifier->name();
ModifierDefinition const*& override = modifiers[name];
if (!override)
- override = modifier.get();
+ override = modifier;
else if (ModifierType(*override) != ModifierType(*modifier))
typeError(override->location(), "Override changes modifier signature.");
if (!functions[name].empty())
@@ -290,20 +288,20 @@ void TypeChecker::checkContractExternalTypeClashes(ContractDefinition const& _co
map<string, vector<pair<Declaration const*, FunctionTypePointer>>> externalDeclarations;
for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts)
{
- for (ASTPointer<FunctionDefinition> const& f: contract->definedFunctions())
+ for (FunctionDefinition const* f: contract->definedFunctions())
if (f->isPartOfExternalInterface())
{
auto functionType = make_shared<FunctionType>(*f);
externalDeclarations[functionType->externalSignature()].push_back(
- make_pair(f.get(), functionType)
+ make_pair(f, functionType)
);
}
- for (ASTPointer<VariableDeclaration> const& v: contract->stateVariables())
+ for (VariableDeclaration const* v: contract->stateVariables())
if (v->isPartOfExternalInterface())
{
auto functionType = make_shared<FunctionType>(*v);
externalDeclarations[functionType->externalSignature()].push_back(
- make_pair(v.get(), functionType)
+ make_pair(v, functionType)
);
}
}
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index 7ceab752..65535388 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -74,29 +74,83 @@ 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<StructDefinition const*> ContractDefinition::definedStructs() const
+{
+ vector<StructDefinition const*> ret;
+ for (auto const& node: m_subNodes)
+ if (auto v = dynamic_cast<StructDefinition const*>(node.get()))
+ ret.push_back(v);
+ return ret;
+}
+
+vector<EnumDefinition const*> ContractDefinition::definedEnums() const
+{
+ vector<EnumDefinition const*> ret;
+ for (auto const& node: m_subNodes)
+ if (auto v = dynamic_cast<EnumDefinition const*>(node.get()))
+ ret.push_back(v);
+ return ret;
+}
+
+vector<VariableDeclaration const*> ContractDefinition::stateVariables() const
+{
+ vector<VariableDeclaration const*> ret;
+ for (auto const& node: m_subNodes)
+ if (auto v = dynamic_cast<VariableDeclaration const*>(node.get()))
+ ret.push_back(v);
+ return ret;
+}
+
+vector<ModifierDefinition const*> ContractDefinition::functionModifiers() const
+{
+ vector<ModifierDefinition const*> ret;
+ for (auto const& node: m_subNodes)
+ if (auto v = dynamic_cast<ModifierDefinition const*>(node.get()))
+ ret.push_back(v);
+ return ret;
+}
+
+vector<FunctionDefinition const*> ContractDefinition::definedFunctions() const
+{
+ vector<FunctionDefinition const*> ret;
+ for (auto const& node: m_subNodes)
+ if (auto v = dynamic_cast<FunctionDefinition const*>(node.get()))
+ ret.push_back(v);
+ return ret;
+}
+
+vector<EventDefinition const*> ContractDefinition::events() const
+{
+ vector<EventDefinition const*> ret;
+ for (auto const& node: m_subNodes)
+ if (auto v = dynamic_cast<EventDefinition const*>(node.get()))
+ ret.push_back(v);
+ return ret;
+}
+
+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 +170,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,14 +230,14 @@ 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;
}
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index 11c4fef6..ab872750 100644
--- a/libsolidity/ast/AST.h
+++ b/libsolidity/ast/AST.h
@@ -58,15 +58,15 @@ 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);
}
@@ -238,23 +238,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 +252,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;
+ std::vector<EnumDefinition const*> definedEnums() const;
+ std::vector<VariableDeclaration const*> stateVariables() const;
+ std::vector<ModifierDefinition const*> functionModifiers() const;
+ std::vector<FunctionDefinition const*> definedFunctions() const;
+ std::vector<EventDefinition const*> events() const;
+ std::vector<EventDefinition const*> const& interfaceEvents() const;
bool isLibrary() const { return m_isLibrary; }
/// @returns a map of canonical function signatures to FunctionDefinitions
@@ -296,12 +287,7 @@ public:
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 +296,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;
};
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 85e1fd49..a4da5b13 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -970,7 +970,7 @@ MemberList const& ContractType::members(ContractDefinition const*) 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(ContractDefinition const*) 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);
diff --git a/libsolidity/codegen/Compiler.cpp b/libsolidity/codegen/Compiler.cpp
index 055e607f..f1d95980 100644
--- a/libsolidity/codegen/Compiler.cpp
+++ b/libsolidity/codegen/Compiler.cpp
@@ -385,7 +385,7 @@ void Compiler::registerStateVariables(ContractDefinition const& _contract)
void Compiler::initializeStateVariables(ContractDefinition const& _contract)
{
- for (ASTPointer<VariableDeclaration> const& variable: _contract.stateVariables())
+ for (VariableDeclaration const* variable: _contract.stateVariables())
if (variable->value() && !variable->isConstant())
ExpressionCompiler(m_context, m_optimize).appendStateVariableInitialization(*variable);
}
diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp
index 00b9d87c..9e2405cc 100644
--- a/libsolidity/codegen/CompilerContext.cpp
+++ b/libsolidity/codegen/CompilerContext.cpp
@@ -133,9 +133,9 @@ ModifierDefinition const& CompilerContext::functionModifier(string const& _name)
{
solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set.");
for (ContractDefinition const* contract: m_inheritanceHierarchy)
- for (ASTPointer<ModifierDefinition> const& modifier: contract->functionModifiers())
+ for (ModifierDefinition const* modifier: contract->functionModifiers())
if (modifier->name() == _name)
- return *modifier.get();
+ return *modifier;
BOOST_THROW_EXCEPTION(InternalCompilerError()
<< errinfo_comment("Function modifier " + _name + " not found."));
}
@@ -195,7 +195,7 @@ eth::AssemblyItem CompilerContext::virtualFunctionEntryLabel(
FunctionType functionType(_function);
auto it = _searchStart;
for (; it != m_inheritanceHierarchy.end(); ++it)
- for (ASTPointer<FunctionDefinition> const& function: (*it)->definedFunctions())
+ for (FunctionDefinition const* function: (*it)->definedFunctions())
if (
function->name() == name &&
!function->isConstructor() &&
diff --git a/libsolidity/formal/Why3Translator.cpp b/libsolidity/formal/Why3Translator.cpp
index fe3729d4..5028e2c3 100644
--- a/libsolidity/formal/Why3Translator.cpp
+++ b/libsolidity/formal/Why3Translator.cpp
@@ -145,8 +145,8 @@ bool Why3Translator::visit(ContractDefinition const& _contract)
addLine("type state = {");
indent();
- m_stateVariables = &_contract.stateVariables();
- for (auto const& variable: _contract.stateVariables())
+ m_stateVariables = _contract.stateVariables();
+ for (VariableDeclaration const* variable: m_stateVariables)
{
string varType = toFormalType(*variable->annotation().type);
if (varType.empty())
@@ -174,7 +174,7 @@ bool Why3Translator::visit(ContractDefinition const& _contract)
void Why3Translator::endVisit(ContractDefinition const& _contract)
{
- m_stateVariables = nullptr;
+ m_stateVariables.clear();
addSourceFromDocStrings(_contract.annotation());
unindent();
addLine("end");
@@ -600,17 +600,12 @@ bool Why3Translator::visit(Literal const& _literal)
bool Why3Translator::isStateVariable(VariableDeclaration const* _var) const
{
- solAssert(!!m_stateVariables, "");
- for (auto const& var: *m_stateVariables)
- if (var.get() == _var)
- return true;
- return false;
+ return contains(m_stateVariables, _var);
}
bool Why3Translator::isStateVariable(string const& _name) const
{
- solAssert(!!m_stateVariables, "");
- for (auto const& var: *m_stateVariables)
+ for (auto const& var: m_stateVariables)
if (var->name() == _name)
return true;
return false;
diff --git a/libsolidity/formal/Why3Translator.h b/libsolidity/formal/Why3Translator.h
index e5c298b4..f4315a7a 100644
--- a/libsolidity/formal/Why3Translator.h
+++ b/libsolidity/formal/Why3Translator.h
@@ -117,7 +117,7 @@ private:
bool m_seenContract = false;
bool m_errorOccured = false;
- std::vector<ASTPointer<VariableDeclaration>> const* m_stateVariables = nullptr;
+ std::vector<VariableDeclaration const*> m_stateVariables;
std::map<std::string, VariableDeclaration const*> m_localVariables;
struct Line
diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp
index 2d4ca43e..9272eb4b 100644
--- a/libsolidity/parsing/Parser.cpp
+++ b/libsolidity/parsing/Parser.cpp
@@ -132,12 +132,6 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary)
expectToken(_isLibrary ? Token::Library : Token::Contract);
ASTPointer<ASTString> name = expectIdentifierToken();
vector<ASTPointer<InheritanceSpecifier>> baseContracts;
- vector<ASTPointer<StructDefinition>> structs;
- vector<ASTPointer<EnumDefinition>> enums;
- vector<ASTPointer<VariableDeclaration>> stateVariables;
- vector<ASTPointer<FunctionDefinition>> functions;
- vector<ASTPointer<ModifierDefinition>> modifiers;
- vector<ASTPointer<EventDefinition>> events;
if (m_scanner->currentToken() == Token::Is)
do
{
@@ -145,6 +139,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary)
baseContracts.push_back(parseInheritanceSpecifier());
}
while (m_scanner->currentToken() == Token::Comma);
+ vector<ASTPointer<ASTNode>> subNodes;
expectToken(Token::LBrace);
while (true)
{
@@ -152,11 +147,11 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary)
if (currentTokenValue == Token::RBrace)
break;
else if (currentTokenValue == Token::Function)
- functions.push_back(parseFunctionDefinition(name.get()));
+ subNodes.push_back(parseFunctionDefinition(name.get()));
else if (currentTokenValue == Token::Struct)
- structs.push_back(parseStructDefinition());
+ subNodes.push_back(parseStructDefinition());
else if (currentTokenValue == Token::Enum)
- enums.push_back(parseEnumDefinition());
+ subNodes.push_back(parseEnumDefinition());
else if (
currentTokenValue == Token::Identifier ||
currentTokenValue == Token::Mapping ||
@@ -166,13 +161,13 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary)
VarDeclParserOptions options;
options.isStateVariable = true;
options.allowInitialValue = true;
- stateVariables.push_back(parseVariableDeclaration(options));
+ subNodes.push_back(parseVariableDeclaration(options));
expectToken(Token::Semicolon);
}
else if (currentTokenValue == Token::Modifier)
- modifiers.push_back(parseModifierDefinition());
+ subNodes.push_back(parseModifierDefinition());
else if (currentTokenValue == Token::Event)
- events.push_back(parseEventDefinition());
+ subNodes.push_back(parseEventDefinition());
else
fatalParserError(std::string("Function, variable, struct or modifier declaration expected."));
}
@@ -182,12 +177,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary)
name,
docString,
baseContracts,
- structs,
- enums,
- stateVariables,
- functions,
- modifiers,
- events,
+ subNodes,
_isLibrary
);
}
diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp
index beb71942..b494a1aa 100644
--- a/test/libsolidity/SolidityParser.cpp
+++ b/test/libsolidity/SolidityParser.cpp
@@ -73,7 +73,7 @@ bool successParse(std::string const& _source)
}
void checkFunctionNatspec(
- ASTPointer<FunctionDefinition> _function,
+ FunctionDefinition const* _function,
std::string const& _expectedDoc
)
{
@@ -193,7 +193,7 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation)
BOOST_CHECK(successParse(text));
ErrorList e;
ASTPointer<ContractDefinition> contract = parseText(text, e);
- ASTPointer<FunctionDefinition> function;
+ FunctionDefinition const* function = nullptr;
ErrorList errors;
auto functions = parseText(text, errors)->definedFunctions();
@@ -204,7 +204,7 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation)
BOOST_AUTO_TEST_CASE(function_normal_comments)
{
ASTPointer<ContractDefinition> contract;
- ASTPointer<FunctionDefinition> function;
+ FunctionDefinition const* function = nullptr;
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" // We won't see this comment\n"
@@ -221,7 +221,7 @@ BOOST_AUTO_TEST_CASE(function_normal_comments)
BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation)
{
ASTPointer<ContractDefinition> contract;
- ASTPointer<FunctionDefinition> function;
+ FunctionDefinition const* function = nullptr;
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" /// This is test function 1\n"
@@ -254,7 +254,7 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation)
BOOST_AUTO_TEST_CASE(multiline_function_documentation)
{
ASTPointer<ContractDefinition> contract;
- ASTPointer<FunctionDefinition> function;
+ FunctionDefinition const* function = nullptr;
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" /// This is a test function\n"
@@ -272,7 +272,7 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation)
BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body)
{
ASTPointer<ContractDefinition> contract;
- ASTPointer<FunctionDefinition> function;
+ FunctionDefinition const* function = nullptr;
char const* text = "contract test {\n"
" /// fun1 description\n"
" function fun1(uint256 a) {\n"
@@ -301,7 +301,7 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body)
BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature)
{
ASTPointer<ContractDefinition> contract;
- ASTPointer<FunctionDefinition> function;
+ FunctionDefinition const* function = nullptr;
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" function ///I am in the wrong place \n"
@@ -325,7 +325,7 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature)
BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature)
{
ASTPointer<ContractDefinition> contract;
- ASTPointer<FunctionDefinition> function;
+ FunctionDefinition const* function = nullptr;
char const* text = "contract test {\n"
" uint256 stateVar;\n"
" function fun1(uint256 a) {\n"