From 7159944f0fa5d9eb3205cd8a3e1d6ec4f133a4ad Mon Sep 17 00:00:00 2001
From: chriseth <c@ethdev.com>
Date: Fri, 20 Jan 2017 11:47:20 +0100
Subject: [PATCH] Reset AST node IDs between compilation runs.

---
 libsolidity/ast/AST.cpp                 | 22 ++++++++++++++++++++--
 libsolidity/ast/AST.h                   |  2 ++
 libsolidity/ast/Types.cpp               |  7 ++++---
 libsolidity/interface/CompilerStack.cpp |  1 +
 test/libsolidity/SolidityTypes.cpp      |  1 +
 5 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index fcd6e38c0..8a43c3f75 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -34,11 +34,24 @@ using namespace std;
 using namespace dev;
 using namespace dev::solidity;
 
+class IDDispenser
+{
+public:
+	static size_t next() { return ++instance(); }
+	static void reset() { instance() = 0; }
+private:
+	static size_t& instance()
+	{
+		static IDDispenser dispenser;
+		return dispenser.id;
+	}
+	size_t id = 0;
+};
+
 ASTNode::ASTNode(SourceLocation const& _location):
+	m_id(IDDispenser::next()),
 	m_location(_location)
 {
-	static size_t id = 0;
-	m_id = ++id;
 }
 
 ASTNode::~ASTNode()
@@ -46,6 +59,11 @@ ASTNode::~ASTNode()
 	delete m_annotation;
 }
 
+void ASTNode::resetID()
+{
+	IDDispenser::reset();
+}
+
 ASTAnnotation& ASTNode::annotation() const
 {
 	if (!m_annotation)
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index 4af649634..116275c34 100644
--- a/libsolidity/ast/AST.h
+++ b/libsolidity/ast/AST.h
@@ -59,6 +59,8 @@ public:
 
 	/// @returns an identifier of this AST node that is unique for a single compilation run.
 	size_t id() const { return m_id; }
+	/// Resets the global ID counter. This invalidates all previous IDs.
+	static void resetID();
 
 	virtual void accept(ASTVisitor& _visitor) = 0;
 	virtual void accept(ASTConstVisitor& _visitor) const = 0;
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 6e9e9d7e2..cefd0603d 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -31,6 +31,7 @@
 #include <libdevcore/UTF8.h>
 
 #include <boost/algorithm/string/join.hpp>
+#include <boost/algorithm/string/replace.hpp>
 #include <boost/range/adaptor/reversed.hpp>
 #include <boost/range/adaptor/sliced.hpp>
 #include <boost/range/adaptor/transformed.hpp>
@@ -163,7 +164,7 @@ string identifierList(TypePointer const& _type1, TypePointer const& _type2)
 
 string parenthesizeUserIdentifier(string const& _internal)
 {
-	return parenthesizeIdentifier(boost::replace_all_copy(_internal, "$", "$$$"));
+	return parenthesizeIdentifier(boost::algorithm::replace_all_copy(_internal, "$", "$$$"));
 }
 
 }
@@ -2109,9 +2110,9 @@ string FunctionType::identifier() const
 		id += "_constant";
 	id += identifierList(m_parameterTypes) + "returns" + identifierList(m_returnParameterTypes);
 	if (m_gasSet)
-		id += "gas_set_";
+		id += "gas";
 	if (m_valueSet)
-		id += "value_set_";
+		id += "value";
 	if (bound())
 		id += "bound_to" + identifierList(selfType());
 	return id;
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp
index 61fc77287..85ec0fb1a 100644
--- a/libsolidity/interface/CompilerStack.cpp
+++ b/libsolidity/interface/CompilerStack.cpp
@@ -112,6 +112,7 @@ bool CompilerStack::parse()
 {
 	//reset
 	m_errors.clear();
+	ASTNode::resetID();
 	m_parseSuccessful = false;
 
 	if (SemVerVersion{string(VersionString)}.isPrerelease())
diff --git a/test/libsolidity/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp
index b4c068731..2dcb92265 100644
--- a/test/libsolidity/SolidityTypes.cpp
+++ b/test/libsolidity/SolidityTypes.cpp
@@ -90,6 +90,7 @@ BOOST_AUTO_TEST_CASE(storage_layout_arrays)
 
 BOOST_AUTO_TEST_CASE(type_identifiers)
 {
+	ASTNode::resetID();
 	BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("uint128")->identifier(), "t_uint128");
 	BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("int128")->identifier(), "t_int128");
 	BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("address")->identifier(), "t_address");