mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #14490 from ethereum/purge-using-namespace-std-from-libsolidity-codegen
Purge using namespace std from libsolidity/codegen
This commit is contained in:
		
						commit
						f085572e24
					
				| @ -30,12 +30,11 @@ | ||||
| 
 | ||||
| #include <boost/algorithm/string/join.hpp> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::util; | ||||
| using namespace solidity::frontend; | ||||
| 
 | ||||
| string ABIFunctions::tupleEncoder( | ||||
| std::string ABIFunctions::tupleEncoder( | ||||
| 	TypePointers const& _givenTypes, | ||||
| 	TypePointers _targetTypes, | ||||
| 	bool _encodeAsLibraryTypes, | ||||
| @ -56,7 +55,7 @@ string ABIFunctions::tupleEncoder( | ||||
| 		solAssert(t, ""); | ||||
| 	} | ||||
| 
 | ||||
| 	string functionName = string("abi_encode_tuple_"); | ||||
| 	std::string functionName = std::string("abi_encode_tuple_"); | ||||
| 	for (auto const& t: _givenTypes) | ||||
| 		functionName += t->identifier() + "_"; | ||||
| 	functionName += "_to_"; | ||||
| @ -76,8 +75,8 @@ string ABIFunctions::tupleEncoder( | ||||
| 		)"); | ||||
| 		templ("functionName", functionName); | ||||
| 		size_t const headSize_ = headSize(_targetTypes); | ||||
| 		templ("headSize", to_string(headSize_)); | ||||
| 		string encodeElements; | ||||
| 		templ("headSize", std::to_string(headSize_)); | ||||
| 		std::string encodeElements; | ||||
| 		size_t headPos = 0; | ||||
| 		size_t stackPos = 0; | ||||
| 		for (size_t i = 0; i < _givenTypes.size(); ++i) | ||||
| @ -88,24 +87,24 @@ string ABIFunctions::tupleEncoder( | ||||
| 			bool dynamic = _targetTypes[i]->isDynamicallyEncoded(); | ||||
| 			Whiskers elementTempl( | ||||
| 				dynamic ? | ||||
| 				string(R"( | ||||
| 				std::string(R"( | ||||
| 					mstore(add(headStart, <pos>), sub(tail, headStart)) | ||||
| 					tail := <abiEncode>(<values> tail) | ||||
| 				)") : | ||||
| 				string(R"( | ||||
| 				std::string(R"( | ||||
| 					<abiEncode>(<values> add(headStart, <pos>)) | ||||
| 				)") | ||||
| 			); | ||||
| 			string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack); | ||||
| 			std::string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack); | ||||
| 			elementTempl("values", values.empty() ? "" : values + ", "); | ||||
| 			elementTempl("pos", to_string(headPos)); | ||||
| 			elementTempl("pos", std::to_string(headPos)); | ||||
| 			elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], options)); | ||||
| 			encodeElements += elementTempl.render(); | ||||
| 			headPos += _targetTypes[i]->calldataHeadSize(); | ||||
| 			stackPos += sizeOnStack; | ||||
| 		} | ||||
| 		solAssert(headPos == headSize_, ""); | ||||
| 		string valueParams = | ||||
| 		std::string valueParams = | ||||
| 			_reversed ? | ||||
| 			suffixedVariableNameList("value", stackPos, 0) : | ||||
| 			suffixedVariableNameList("value", 0, stackPos); | ||||
| @ -116,7 +115,7 @@ string ABIFunctions::tupleEncoder( | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::tupleEncoderPacked( | ||||
| std::string ABIFunctions::tupleEncoderPacked( | ||||
| 	TypePointers const& _givenTypes, | ||||
| 	TypePointers _targetTypes, | ||||
| 	bool _reversed | ||||
| @ -135,7 +134,7 @@ string ABIFunctions::tupleEncoderPacked( | ||||
| 		solAssert(t, ""); | ||||
| 	} | ||||
| 
 | ||||
| 	string functionName = string("abi_encode_tuple_packed_"); | ||||
| 	std::string functionName = std::string("abi_encode_tuple_packed_"); | ||||
| 	for (auto const& t: _givenTypes) | ||||
| 		functionName += t->identifier() + "_"; | ||||
| 	functionName += "_to_"; | ||||
| @ -154,7 +153,7 @@ string ABIFunctions::tupleEncoderPacked( | ||||
| 			} | ||||
| 		)"); | ||||
| 		templ("functionName", functionName); | ||||
| 		string encodeElements; | ||||
| 		std::string encodeElements; | ||||
| 		size_t stackPos = 0; | ||||
| 		for (size_t i = 0; i < _givenTypes.size(); ++i) | ||||
| 		{ | ||||
| @ -164,23 +163,23 @@ string ABIFunctions::tupleEncoderPacked( | ||||
| 			bool dynamic = _targetTypes[i]->isDynamicallyEncoded(); | ||||
| 			Whiskers elementTempl( | ||||
| 				dynamic ? | ||||
| 				string(R"( | ||||
| 				std::string(R"( | ||||
| 					pos := <abiEncode>(<values> pos) | ||||
| 				)") : | ||||
| 				string(R"( | ||||
| 				std::string(R"( | ||||
| 					<abiEncode>(<values> pos) | ||||
| 					pos := add(pos, <calldataEncodedSize>) | ||||
| 				)") | ||||
| 			); | ||||
| 			string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack); | ||||
| 			std::string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack); | ||||
| 			elementTempl("values", values.empty() ? "" : values + ", "); | ||||
| 			if (!dynamic) | ||||
| 				elementTempl("calldataEncodedSize", to_string(_targetTypes[i]->calldataEncodedSize(false))); | ||||
| 				elementTempl("calldataEncodedSize", std::to_string(_targetTypes[i]->calldataEncodedSize(false))); | ||||
| 			elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], options)); | ||||
| 			encodeElements += elementTempl.render(); | ||||
| 			stackPos += sizeOnStack; | ||||
| 		} | ||||
| 		string valueParams = | ||||
| 		std::string valueParams = | ||||
| 			_reversed ? | ||||
| 			suffixedVariableNameList("value", stackPos, 0) : | ||||
| 			suffixedVariableNameList("value", 0, stackPos); | ||||
| @ -190,9 +189,9 @@ string ABIFunctions::tupleEncoderPacked( | ||||
| 		return templ.render(); | ||||
| 	}); | ||||
| } | ||||
| string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory) | ||||
| std::string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory) | ||||
| { | ||||
| 	string functionName = string("abi_decode_tuple_"); | ||||
| 	std::string functionName = std::string("abi_decode_tuple_"); | ||||
| 	for (auto const& t: _types) | ||||
| 		functionName += t->identifier(); | ||||
| 	if (_fromMemory) | ||||
| @ -211,10 +210,10 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory) | ||||
| 		)"); | ||||
| 		templ("functionName", functionName); | ||||
| 		templ("revertString", revertReasonIfDebugFunction("ABI decoding: tuple data too short")); | ||||
| 		templ("minimumSize", to_string(headSize(decodingTypes))); | ||||
| 		templ("minimumSize", std::to_string(headSize(decodingTypes))); | ||||
| 
 | ||||
| 		string decodeElements; | ||||
| 		vector<string> valueReturnParams; | ||||
| 		std::string decodeElements; | ||||
| 		std::vector<std::string> valueReturnParams; | ||||
| 		size_t headPos = 0; | ||||
| 		size_t stackPos = 0; | ||||
| 		for (size_t i = 0; i < _types.size(); ++i) | ||||
| @ -224,11 +223,11 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory) | ||||
| 			size_t sizeOnStack = _types[i]->sizeOnStack(); | ||||
| 			solAssert(sizeOnStack == decodingTypes[i]->sizeOnStack(), ""); | ||||
| 			solAssert(sizeOnStack > 0, ""); | ||||
| 			vector<string> valueNamesLocal; | ||||
| 			std::vector<std::string> valueNamesLocal; | ||||
| 			for (size_t j = 0; j < sizeOnStack; j++) | ||||
| 			{ | ||||
| 				valueNamesLocal.emplace_back("value" + to_string(stackPos)); | ||||
| 				valueReturnParams.emplace_back("value" + to_string(stackPos)); | ||||
| 				valueNamesLocal.emplace_back("value" + std::to_string(stackPos)); | ||||
| 				valueReturnParams.emplace_back("value" + std::to_string(stackPos)); | ||||
| 				stackPos++; | ||||
| 			} | ||||
| 			Whiskers elementTempl(R"( | ||||
| @ -247,7 +246,7 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory) | ||||
| 			elementTempl("revertString", revertReasonIfDebugFunction("ABI decoding: invalid tuple offset")); | ||||
| 			elementTempl("load", _fromMemory ? "mload" : "calldataload"); | ||||
| 			elementTempl("values", boost::algorithm::join(valueNamesLocal, ", ")); | ||||
| 			elementTempl("pos", to_string(headPos)); | ||||
| 			elementTempl("pos", std::to_string(headPos)); | ||||
| 			elementTempl("abiDecode", abiDecodingFunction(*_types[i], _fromMemory, true)); | ||||
| 			decodeElements += elementTempl.render(); | ||||
| 			headPos += decodingTypes[i]->calldataHeadSize(); | ||||
| @ -260,9 +259,9 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory) | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::EncodingOptions::toFunctionNameSuffix() const | ||||
| std::string ABIFunctions::EncodingOptions::toFunctionNameSuffix() const | ||||
| { | ||||
| 	string suffix; | ||||
| 	std::string suffix; | ||||
| 	if (!padded) | ||||
| 		suffix += "_nonPadded"; | ||||
| 	if (dynamicInplace) | ||||
| @ -274,7 +273,7 @@ string ABIFunctions::EncodingOptions::toFunctionNameSuffix() const | ||||
| 	return suffix; | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiEncodingFunction( | ||||
| std::string ABIFunctions::abiEncodingFunction( | ||||
| 	Type const& _from, | ||||
| 	Type const& _to, | ||||
| 	EncodingOptions const& _options | ||||
| @ -349,7 +348,7 @@ string ABIFunctions::abiEncodingFunction( | ||||
| 	solAssert(_from.sizeOnStack() == 1, ""); | ||||
| 	solAssert(to.isValueType(), ""); | ||||
| 	solAssert(to.calldataEncodedSize() == 32, ""); | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_encode_" + | ||||
| 		_from.identifier() + | ||||
| 		"_to_" + | ||||
| @ -376,7 +375,7 @@ string ABIFunctions::abiEncodingFunction( | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			string cleanupConvert; | ||||
| 			std::string cleanupConvert; | ||||
| 			if (_from == to) | ||||
| 				cleanupConvert = m_utils.cleanupFunction(_from) + "(value)"; | ||||
| 			else | ||||
| @ -389,21 +388,21 @@ string ABIFunctions::abiEncodingFunction( | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiEncodeAndReturnUpdatedPosFunction( | ||||
| std::string ABIFunctions::abiEncodeAndReturnUpdatedPosFunction( | ||||
| 	Type const& _givenType, | ||||
| 	Type const& _targetType, | ||||
| 	ABIFunctions::EncodingOptions const& _options | ||||
| ) | ||||
| { | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_encodeUpdatedPos_" + | ||||
| 		_givenType.identifier() + | ||||
| 		"_to_" + | ||||
| 		_targetType.identifier() + | ||||
| 		_options.toFunctionNameSuffix(); | ||||
| 	return createFunction(functionName, [&]() { | ||||
| 		string values = suffixedVariableNameList("value", 0, numVariablesForType(_givenType, _options)); | ||||
| 		string encoder = abiEncodingFunction(_givenType, _targetType, _options); | ||||
| 		std::string values = suffixedVariableNameList("value", 0, numVariablesForType(_givenType, _options)); | ||||
| 		std::string encoder = abiEncodingFunction(_givenType, _targetType, _options); | ||||
| 		Type const* targetEncoding = _targetType.fullEncodingType(_options.encodeAsLibraryTypes, true, false); | ||||
| 		solAssert(targetEncoding, ""); | ||||
| 		if (targetEncoding->isDynamicallyEncoded()) | ||||
| @ -435,7 +434,7 @@ string ABIFunctions::abiEncodeAndReturnUpdatedPosFunction( | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup( | ||||
| std::string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup( | ||||
| 	Type const& _from, | ||||
| 	Type const& _to, | ||||
| 	EncodingOptions const& _options | ||||
| @ -461,7 +460,7 @@ string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup( | ||||
| 		"" | ||||
| 	); | ||||
| 
 | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_encode_" + | ||||
| 		_from.identifier() + | ||||
| 		"_to_" + | ||||
| @ -522,13 +521,13 @@ string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup( | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiEncodingFunctionSimpleArray( | ||||
| std::string ABIFunctions::abiEncodingFunctionSimpleArray( | ||||
| 	ArrayType const& _from, | ||||
| 	ArrayType const& _to, | ||||
| 	EncodingOptions const& _options | ||||
| ) | ||||
| { | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_encode_" + | ||||
| 		_from.identifier() + | ||||
| 		"_to_" + | ||||
| @ -548,7 +547,7 @@ string ABIFunctions::abiEncodingFunctionSimpleArray( | ||||
| 		EncodingOptions subOptions(_options); | ||||
| 		subOptions.encodeFunctionFromStack = false; | ||||
| 		subOptions.padded = true; | ||||
| 		string elementValues = suffixedVariableNameList("elementValue", 0, numVariablesForType(*_from.baseType(), subOptions)); | ||||
| 		std::string elementValues = suffixedVariableNameList("elementValue", 0, numVariablesForType(*_from.baseType(), subOptions)); | ||||
| 		Whiskers templ( | ||||
| 			usesTail ? | ||||
| 			R"( | ||||
| @ -632,13 +631,13 @@ string ABIFunctions::abiEncodingFunctionSimpleArray( | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiEncodingFunctionMemoryByteArray( | ||||
| std::string ABIFunctions::abiEncodingFunctionMemoryByteArray( | ||||
| 	ArrayType const& _from, | ||||
| 	ArrayType const& _to, | ||||
| 	EncodingOptions const& _options | ||||
| ) | ||||
| { | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_encode_" + | ||||
| 		_from.identifier() + | ||||
| 		"_to_" + | ||||
| @ -669,13 +668,13 @@ string ABIFunctions::abiEncodingFunctionMemoryByteArray( | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiEncodingFunctionCompactStorageArray( | ||||
| std::string ABIFunctions::abiEncodingFunctionCompactStorageArray( | ||||
| 	ArrayType const& _from, | ||||
| 	ArrayType const& _to, | ||||
| 	EncodingOptions const& _options | ||||
| ) | ||||
| { | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_encode_" + | ||||
| 		_from.identifier() + | ||||
| 		"_to_" + | ||||
| @ -791,13 +790,13 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray( | ||||
| 				templ("useSpill", "1"); | ||||
| 			else | ||||
| 				templ("useSpill", "0"); | ||||
| 			templ("itemsPerSlot", to_string(itemsPerSlot)); | ||||
| 			templ("itemsPerSlot", std::to_string(itemsPerSlot)); | ||||
| 			templ("stride", toCompactHexWithPrefix(_to.calldataStride())); | ||||
| 
 | ||||
| 			EncodingOptions subOptions(_options); | ||||
| 			subOptions.encodeFunctionFromStack = false; | ||||
| 			subOptions.padded = true; | ||||
| 			string encodeToMemoryFun = abiEncodingFunction( | ||||
| 			std::string encodeToMemoryFun = abiEncodingFunction( | ||||
| 				*_from.baseType(), | ||||
| 				*_to.baseType(), | ||||
| 				subOptions | ||||
| @ -820,13 +819,13 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray( | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiEncodingFunctionStruct( | ||||
| std::string ABIFunctions::abiEncodingFunctionStruct( | ||||
| 	StructType const& _from, | ||||
| 	StructType const& _to, | ||||
| 	EncodingOptions const& _options | ||||
| ) | ||||
| { | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_encode_" + | ||||
| 		_from.identifier() + | ||||
| 		"_to_" + | ||||
| @ -867,7 +866,7 @@ string ABIFunctions::abiEncodingFunctionStruct( | ||||
| 		templ("init", _from.dataStoredIn(DataLocation::Storage) ? "let slotValue := 0" : ""); | ||||
| 		u256 previousSlotOffset(-1); | ||||
| 		u256 encodingOffset = 0; | ||||
| 		vector<map<string, string>> members; | ||||
| 		std::vector<std::map<std::string, std::string>> members; | ||||
| 		for (auto const& member: _to.members(nullptr)) | ||||
| 		{ | ||||
| 			solAssert(member.type, ""); | ||||
| @ -890,7 +889,7 @@ string ABIFunctions::abiEncodingFunctionStruct( | ||||
| 					solAssert(memberTypeFrom->isValueType() == memberTypeTo->isValueType(), ""); | ||||
| 					u256 storageSlotOffset; | ||||
| 					size_t intraSlotOffset; | ||||
| 					tie(storageSlotOffset, intraSlotOffset) = _from.storageOffsetsOfMember(member.name); | ||||
| 					std::tie(storageSlotOffset, intraSlotOffset) = _from.storageOffsetsOfMember(member.name); | ||||
| 					if (memberTypeFrom->isValueType()) | ||||
| 					{ | ||||
| 						if (storageSlotOffset != previousSlotOffset) | ||||
| @ -910,13 +909,13 @@ string ABIFunctions::abiEncodingFunctionStruct( | ||||
| 				} | ||||
| 				case DataLocation::Memory: | ||||
| 				{ | ||||
| 					string sourceOffset = toCompactHexWithPrefix(_from.memoryOffsetOfMember(member.name)); | ||||
| 					std::string sourceOffset = toCompactHexWithPrefix(_from.memoryOffsetOfMember(member.name)); | ||||
| 					members.back()["retrieveValue"] = "mload(add(value, " + sourceOffset + "))"; | ||||
| 					break; | ||||
| 				} | ||||
| 				case DataLocation::CallData: | ||||
| 				{ | ||||
| 					string sourceOffset = toCompactHexWithPrefix(_from.calldataOffsetOfMember(member.name)); | ||||
| 					std::string sourceOffset = toCompactHexWithPrefix(_from.calldataOffsetOfMember(member.name)); | ||||
| 					members.back()["retrieveValue"] = calldataAccessFunction(*memberTypeFrom) + "(value, add(value, " + sourceOffset + "))"; | ||||
| 					break; | ||||
| 				} | ||||
| @ -929,10 +928,10 @@ string ABIFunctions::abiEncodingFunctionStruct( | ||||
| 			// Like with arrays, struct members are always padded.
 | ||||
| 			subOptions.padded = true; | ||||
| 
 | ||||
| 			string memberValues = suffixedVariableNameList("memberValue", 0, numVariablesForType(*memberTypeFrom, subOptions)); | ||||
| 			std::string memberValues = suffixedVariableNameList("memberValue", 0, numVariablesForType(*memberTypeFrom, subOptions)); | ||||
| 			members.back()["memberValues"] = memberValues; | ||||
| 
 | ||||
| 			string encode; | ||||
| 			std::string encode; | ||||
| 			if (_options.dynamicInplace) | ||||
| 				encode = Whiskers{"pos := <encode>(<memberValues>, pos)"} | ||||
| 					("encode", abiEncodeAndReturnUpdatedPosFunction(*memberTypeFrom, *memberTypeTo, subOptions)) | ||||
| @ -942,7 +941,7 @@ string ABIFunctions::abiEncodingFunctionStruct( | ||||
| 			{ | ||||
| 				Whiskers encodeTempl( | ||||
| 					dynamicMember ? | ||||
| 					string(R"( | ||||
| 					std::string(R"( | ||||
| 						mstore(add(pos, <encodingOffset>), sub(tail, pos)) | ||||
| 						tail := <abiEncode>(<memberValues>, tail) | ||||
| 					)") : | ||||
| @ -966,7 +965,7 @@ string ABIFunctions::abiEncodingFunctionStruct( | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiEncodingFunctionStringLiteral( | ||||
| std::string ABIFunctions::abiEncodingFunctionStringLiteral( | ||||
| 	Type const& _from, | ||||
| 	Type const& _to, | ||||
| 	EncodingOptions const& _options | ||||
| @ -974,7 +973,7 @@ string ABIFunctions::abiEncodingFunctionStringLiteral( | ||||
| { | ||||
| 	solAssert(_from.category() == Type::Category::StringLiteral, ""); | ||||
| 
 | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_encode_" + | ||||
| 		_from.identifier() + | ||||
| 		"_to_" + | ||||
| @ -982,7 +981,7 @@ string ABIFunctions::abiEncodingFunctionStringLiteral( | ||||
| 		_options.toFunctionNameSuffix(); | ||||
| 	return createFunction(functionName, [&]() { | ||||
| 		auto const& strType = dynamic_cast<StringLiteralType const&>(_from); | ||||
| 		string const& value = strType.value(); | ||||
| 		std::string const& value = strType.value(); | ||||
| 		solAssert(_from.sizeOnStack() == 0, ""); | ||||
| 
 | ||||
| 		if (_to.isDynamicallySized()) | ||||
| @ -998,12 +997,12 @@ string ABIFunctions::abiEncodingFunctionStringLiteral( | ||||
| 			templ("functionName", functionName); | ||||
| 
 | ||||
| 			// TODO this can make use of CODECOPY for large strings once we have that in Yul
 | ||||
| 			templ("length", to_string(value.size())); | ||||
| 			templ("length", std::to_string(value.size())); | ||||
| 			templ("storeLength", arrayStoreLengthForEncodingFunction(dynamic_cast<ArrayType const&>(_to), _options)); | ||||
| 			if (_options.padded) | ||||
| 				templ("overallSize", to_string(((value.size() + 31) / 32) * 32)); | ||||
| 				templ("overallSize", std::to_string(((value.size() + 31) / 32) * 32)); | ||||
| 			else | ||||
| 				templ("overallSize", to_string(value.size())); | ||||
| 				templ("overallSize", std::to_string(value.size())); | ||||
| 			templ("storeLiteralInMemory", m_utils.storeLiteralInMemoryFunction(value)); | ||||
| 			return templ.render(); | ||||
| 		} | ||||
| @ -1023,7 +1022,7 @@ string ABIFunctions::abiEncodingFunctionStringLiteral( | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiEncodingFunctionFunctionType( | ||||
| std::string ABIFunctions::abiEncodingFunctionFunctionType( | ||||
| 	FunctionType const& _from, | ||||
| 	Type const& _to, | ||||
| 	EncodingOptions const& _options | ||||
| @ -1036,7 +1035,7 @@ string ABIFunctions::abiEncodingFunctionFunctionType( | ||||
| 		"Invalid function type conversion requested" | ||||
| 	); | ||||
| 
 | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_encode_" + | ||||
| 		_from.identifier() + | ||||
| 		"_to_" + | ||||
| @ -1069,7 +1068,7 @@ string ABIFunctions::abiEncodingFunctionFunctionType( | ||||
| 		}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiDecodingFunction(Type const& _type, bool _fromMemory, bool _forUseOnStack) | ||||
| std::string ABIFunctions::abiDecodingFunction(Type const& _type, bool _fromMemory, bool _forUseOnStack) | ||||
| { | ||||
| 	// The decoding function has to perform bounds checks unless it decodes a value type.
 | ||||
| 	// Conversely, bounds checks have to be performed before the decoding function
 | ||||
| @ -1104,7 +1103,7 @@ string ABIFunctions::abiDecodingFunction(Type const& _type, bool _fromMemory, bo | ||||
| 		return abiDecodingFunctionValueType(_type, _fromMemory); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiDecodingFunctionValueType(Type const& _type, bool _fromMemory) | ||||
| std::string ABIFunctions::abiDecodingFunctionValueType(Type const& _type, bool _fromMemory) | ||||
| { | ||||
| 	Type const* decodingType = _type.decodingType(); | ||||
| 	solAssert(decodingType, ""); | ||||
| @ -1113,7 +1112,7 @@ string ABIFunctions::abiDecodingFunctionValueType(Type const& _type, bool _fromM | ||||
| 	solAssert(!decodingType->isDynamicallyEncoded(), ""); | ||||
| 	solAssert(decodingType->calldataEncodedSize() == 32, ""); | ||||
| 
 | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_decode_" + | ||||
| 		_type.identifier() + | ||||
| 		(_fromMemory ? "_fromMemory" : ""); | ||||
| @ -1134,17 +1133,17 @@ string ABIFunctions::abiDecodingFunctionValueType(Type const& _type, bool _fromM | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiDecodingFunctionArray(ArrayType const& _type, bool _fromMemory) | ||||
| std::string ABIFunctions::abiDecodingFunctionArray(ArrayType const& _type, bool _fromMemory) | ||||
| { | ||||
| 	solAssert(_type.dataStoredIn(DataLocation::Memory), ""); | ||||
| 
 | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_decode_" + | ||||
| 		_type.identifier() + | ||||
| 		(_fromMemory ? "_fromMemory" : ""); | ||||
| 
 | ||||
| 	return createFunction(functionName, [&]() { | ||||
| 		string load = _fromMemory ? "mload" : "calldataload"; | ||||
| 		std::string load = _fromMemory ? "mload" : "calldataload"; | ||||
| 		Whiskers templ( | ||||
| 			R"( | ||||
| 				// <readableTypeName>
 | ||||
| @ -1166,14 +1165,14 @@ string ABIFunctions::abiDecodingFunctionArray(ArrayType const& _type, bool _from | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiDecodingFunctionArrayAvailableLength(ArrayType const& _type, bool _fromMemory) | ||||
| std::string ABIFunctions::abiDecodingFunctionArrayAvailableLength(ArrayType const& _type, bool _fromMemory) | ||||
| { | ||||
| 	solAssert(_type.dataStoredIn(DataLocation::Memory), ""); | ||||
| 	if (_type.isByteArrayOrString()) | ||||
| 		return abiDecodingFunctionByteArrayAvailableLength(_type, _fromMemory); | ||||
| 	solAssert(_type.calldataStride() > 0, ""); | ||||
| 
 | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_decode_available_length_" + | ||||
| 		_type.identifier() + | ||||
| 		(_fromMemory ? "_fromMemory" : ""); | ||||
| @ -1224,7 +1223,7 @@ string ABIFunctions::abiDecodingFunctionArrayAvailableLength(ArrayType const& _t | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type) | ||||
| std::string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type) | ||||
| { | ||||
| 	solAssert(_type.dataStoredIn(DataLocation::CallData), ""); | ||||
| 	if (!_type.isDynamicallySized()) | ||||
| @ -1232,7 +1231,7 @@ string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type) | ||||
| 	solAssert(_type.calldataStride() > 0, ""); | ||||
| 	solAssert(_type.calldataStride() < u256("0xffffffffffffffff"), ""); | ||||
| 
 | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_decode_" + | ||||
| 		_type.identifier(); | ||||
| 	return createFunction(functionName, [&]() { | ||||
| @ -1273,12 +1272,12 @@ string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type) | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiDecodingFunctionByteArrayAvailableLength(ArrayType const& _type, bool _fromMemory) | ||||
| std::string ABIFunctions::abiDecodingFunctionByteArrayAvailableLength(ArrayType const& _type, bool _fromMemory) | ||||
| { | ||||
| 	solAssert(_type.dataStoredIn(DataLocation::Memory), ""); | ||||
| 	solAssert(_type.isByteArrayOrString(), ""); | ||||
| 
 | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_decode_available_length_" + | ||||
| 		_type.identifier() + | ||||
| 		(_fromMemory ? "_fromMemory" : ""); | ||||
| @ -1302,10 +1301,10 @@ string ABIFunctions::abiDecodingFunctionByteArrayAvailableLength(ArrayType const | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiDecodingFunctionCalldataStruct(StructType const& _type) | ||||
| std::string ABIFunctions::abiDecodingFunctionCalldataStruct(StructType const& _type) | ||||
| { | ||||
| 	solAssert(_type.dataStoredIn(DataLocation::CallData), ""); | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_decode_" + | ||||
| 		_type.identifier(); | ||||
| 
 | ||||
| @ -1321,15 +1320,15 @@ string ABIFunctions::abiDecodingFunctionCalldataStruct(StructType const& _type) | ||||
| 		w("revertString", revertReasonIfDebugFunction("ABI decoding: struct calldata too short")); | ||||
| 		w("functionName", functionName); | ||||
| 		w("readableTypeName", _type.toString(true)); | ||||
| 		w("minimumSize", to_string(_type.isDynamicallyEncoded() ? _type.calldataEncodedTailSize() : _type.calldataEncodedSize(true))); | ||||
| 		w("minimumSize", std::to_string(_type.isDynamicallyEncoded() ? _type.calldataEncodedTailSize() : _type.calldataEncodedSize(true))); | ||||
| 		return w.render(); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fromMemory) | ||||
| std::string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fromMemory) | ||||
| { | ||||
| 	solAssert(!_type.dataStoredIn(DataLocation::CallData), ""); | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_decode_" + | ||||
| 		_type.identifier() + | ||||
| 		(_fromMemory ? "_fromMemory" : ""); | ||||
| @ -1356,7 +1355,7 @@ string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fr | ||||
| 		solAssert(_type.memoryDataSize() < u256("0xffffffffffffffff"), ""); | ||||
| 		templ("memorySize", toCompactHexWithPrefix(_type.memoryDataSize())); | ||||
| 		size_t headPos = 0; | ||||
| 		vector<map<string, string>> members; | ||||
| 		std::vector<std::map<std::string, std::string>> members; | ||||
| 		for (auto const& member: _type.members(nullptr)) | ||||
| 		{ | ||||
| 			solAssert(member.type, ""); | ||||
| @ -1376,7 +1375,7 @@ string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fr | ||||
| 			// TODO add test
 | ||||
| 			memberTempl("revertString", revertReasonIfDebugFunction("ABI decoding: invalid struct offset")); | ||||
| 			memberTempl("load", _fromMemory ? "mload" : "calldataload"); | ||||
| 			memberTempl("pos", to_string(headPos)); | ||||
| 			memberTempl("pos", std::to_string(headPos)); | ||||
| 			memberTempl("memoryOffset", toCompactHexWithPrefix(_type.memoryOffsetOfMember(member.name))); | ||||
| 			memberTempl("abiDecode", abiDecodingFunction(*member.type, _fromMemory, false)); | ||||
| 
 | ||||
| @ -1391,11 +1390,11 @@ string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fr | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::abiDecodingFunctionFunctionType(FunctionType const& _type, bool _fromMemory, bool _forUseOnStack) | ||||
| std::string ABIFunctions::abiDecodingFunctionFunctionType(FunctionType const& _type, bool _fromMemory, bool _forUseOnStack) | ||||
| { | ||||
| 	solAssert(_type.kind() == FunctionType::Kind::External, ""); | ||||
| 
 | ||||
| 	string functionName = | ||||
| 	std::string functionName = | ||||
| 		"abi_decode_" + | ||||
| 		_type.identifier() + | ||||
| 		(_fromMemory ? "_fromMemory" : "") + | ||||
| @ -1430,10 +1429,10 @@ string ABIFunctions::abiDecodingFunctionFunctionType(FunctionType const& _type, | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::calldataAccessFunction(Type const& _type) | ||||
| std::string ABIFunctions::calldataAccessFunction(Type const& _type) | ||||
| { | ||||
| 	solAssert(_type.isValueType() || _type.dataStoredIn(DataLocation::CallData), ""); | ||||
| 	string functionName = "calldata_access_" + _type.identifier(); | ||||
| 	std::string functionName = "calldata_access_" + _type.identifier(); | ||||
| 	return createFunction(functionName, [&]() { | ||||
| 		if (_type.isDynamicallyEncoded()) | ||||
| 		{ | ||||
| @ -1477,7 +1476,7 @@ string ABIFunctions::calldataAccessFunction(Type const& _type) | ||||
| 		} | ||||
| 		else if (_type.isValueType()) | ||||
| 		{ | ||||
| 			string decodingFunction; | ||||
| 			std::string decodingFunction; | ||||
| 			if (auto const* functionType = dynamic_cast<FunctionType const*>(&_type)) | ||||
| 				decodingFunction = abiDecodingFunctionFunctionType(*functionType, false, false); | ||||
| 			else | ||||
| @ -1510,9 +1509,9 @@ string ABIFunctions::calldataAccessFunction(Type const& _type) | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::arrayStoreLengthForEncodingFunction(ArrayType const& _type, EncodingOptions const& _options) | ||||
| std::string ABIFunctions::arrayStoreLengthForEncodingFunction(ArrayType const& _type, EncodingOptions const& _options) | ||||
| { | ||||
| 	string functionName = "array_storeLengthForEncoding_" + _type.identifier() + _options.toFunctionNameSuffix(); | ||||
| 	std::string functionName = "array_storeLengthForEncoding_" + _type.identifier() + _options.toFunctionNameSuffix(); | ||||
| 	return createFunction(functionName, [&]() { | ||||
| 		if (_type.isDynamicallySized() && !_options.dynamicInplace) | ||||
| 			return Whiskers(R"( | ||||
| @ -1534,7 +1533,7 @@ string ABIFunctions::arrayStoreLengthForEncodingFunction(ArrayType const& _type, | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string ABIFunctions::createFunction(string const& _name, function<string ()> const& _creator) | ||||
| std::string ABIFunctions::createFunction(std::string const& _name, std::function<std::string ()> const& _creator) | ||||
| { | ||||
| 	return m_functionCollector.createFunction(_name, _creator); | ||||
| } | ||||
|  | ||||
| @ -36,7 +36,6 @@ | ||||
| #include <libevmasm/Instruction.h> | ||||
| #include <liblangutil/Exceptions.h> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::evmasm; | ||||
| using namespace solidity::frontend; | ||||
| @ -314,7 +313,7 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord | ||||
| 		if (!_sourceType.isByteArrayOrString()) | ||||
| 			convertLengthToSize(_sourceType); | ||||
| 
 | ||||
| 		string routine = "calldatacopy(target, source, len)\n"; | ||||
| 		std::string routine = "calldatacopy(target, source, len)\n"; | ||||
| 		if (_padToWordBoundaries) | ||||
| 			routine += R"( | ||||
| 				// Set padding suffix to zero
 | ||||
| @ -890,7 +889,7 @@ void ArrayUtils::popStorageArrayElement(ArrayType const& _type) const | ||||
| 			sstore(ref, slot_value) | ||||
| 		})"); | ||||
| 		code("panicSelector", util::selectorFromSignatureU256("Panic(uint256)").str()); | ||||
| 		code("emptyArrayPop", to_string(unsigned(util::PanicCode::EmptyArrayPop))); | ||||
| 		code("emptyArrayPop", std::to_string(unsigned(util::PanicCode::EmptyArrayPop))); | ||||
| 		m_context.appendInlineAssembly(code.render(), {"ref", "slot_value", "length"}); | ||||
| 		m_context << Instruction::POP << Instruction::POP << Instruction::POP; | ||||
| 	} | ||||
|  | ||||
| @ -26,13 +26,12 @@ | ||||
| #include <libsolidity/codegen/ContractCompiler.h> | ||||
| #include <libevmasm/Assembly.h> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::frontend; | ||||
| 
 | ||||
| void Compiler::compileContract( | ||||
| 	ContractDefinition const& _contract, | ||||
| 	std::map<ContractDefinition const*, shared_ptr<Compiler const>> const& _otherCompilers, | ||||
| 	std::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers, | ||||
| 	bytes const& _metadata | ||||
| ) | ||||
| { | ||||
|  | ||||
| @ -55,7 +55,6 @@ | ||||
| #undef SOL_OUTPUT_ASM | ||||
| 
 | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::util; | ||||
| using namespace solidity::evmasm; | ||||
| @ -68,7 +67,7 @@ void CompilerContext::addStateVariable( | ||||
| 	unsigned _byteOffset | ||||
| ) | ||||
| { | ||||
| 	m_stateVariables[&_declaration] = make_pair(_storageOffset, _byteOffset); | ||||
| 	m_stateVariables[&_declaration] = std::make_pair(_storageOffset, _byteOffset); | ||||
| } | ||||
| 
 | ||||
| void CompilerContext::addImmutable(VariableDeclaration const& _variable) | ||||
| @ -88,14 +87,14 @@ size_t CompilerContext::immutableMemoryOffset(VariableDeclaration const& _variab | ||||
| 	return m_immutableVariables.at(&_variable); | ||||
| } | ||||
| 
 | ||||
| vector<string> CompilerContext::immutableVariableSlotNames(VariableDeclaration const& _variable) | ||||
| std::vector<std::string> CompilerContext::immutableVariableSlotNames(VariableDeclaration const& _variable) | ||||
| { | ||||
| 	string baseName = to_string(_variable.id()); | ||||
| 	std::string baseName = std::to_string(_variable.id()); | ||||
| 	solAssert(_variable.annotation().type->sizeOnStack() > 0, ""); | ||||
| 	if (_variable.annotation().type->sizeOnStack() == 1) | ||||
| 		return {baseName}; | ||||
| 	vector<string> names; | ||||
| 	auto collectSlotNames = [&](string const& _baseName, Type const* type, auto const& _recurse) -> void { | ||||
| 	std::vector<std::string> names; | ||||
| 	auto collectSlotNames = [&](std::string const& _baseName, Type const* type, auto const& _recurse) -> void { | ||||
| 		for (auto const& [slot, type]: type->stackItems()) | ||||
| 			if (type) | ||||
| 				_recurse(_baseName + " " + slot, type, _recurse); | ||||
| @ -121,10 +120,10 @@ void CompilerContext::startFunction(Declaration const& _function) | ||||
| } | ||||
| 
 | ||||
| void CompilerContext::callLowLevelFunction( | ||||
| 	string const& _name, | ||||
| 	std::string const& _name, | ||||
| 	unsigned _inArgs, | ||||
| 	unsigned _outArgs, | ||||
| 	function<void(CompilerContext&)> const& _generator | ||||
| 	std::function<void(CompilerContext&)> const& _generator | ||||
| ) | ||||
| { | ||||
| 	evmasm::AssemblyItem retTag = pushNewTag(); | ||||
| @ -138,7 +137,7 @@ void CompilerContext::callLowLevelFunction( | ||||
| } | ||||
| 
 | ||||
| void CompilerContext::callYulFunction( | ||||
| 	string const& _name, | ||||
| 	std::string const& _name, | ||||
| 	unsigned _inArgs, | ||||
| 	unsigned _outArgs | ||||
| ) | ||||
| @ -152,10 +151,10 @@ void CompilerContext::callYulFunction( | ||||
| } | ||||
| 
 | ||||
| evmasm::AssemblyItem CompilerContext::lowLevelFunctionTag( | ||||
| 	string const& _name, | ||||
| 	std::string const& _name, | ||||
| 	unsigned _inArgs, | ||||
| 	unsigned _outArgs, | ||||
| 	function<void(CompilerContext&)> const& _generator | ||||
| 	std::function<void(CompilerContext&)> const& _generator | ||||
| ) | ||||
| { | ||||
| 	auto it = m_lowLevelFunctions.find(_name); | ||||
| @ -174,10 +173,10 @@ void CompilerContext::appendMissingLowLevelFunctions() | ||||
| { | ||||
| 	while (!m_lowLevelFunctionGenerationQueue.empty()) | ||||
| 	{ | ||||
| 		string name; | ||||
| 		std::string name; | ||||
| 		unsigned inArgs; | ||||
| 		unsigned outArgs; | ||||
| 		function<void(CompilerContext&)> generator; | ||||
| 		std::function<void(CompilerContext&)> generator; | ||||
| 		tie(name, inArgs, outArgs, generator) = m_lowLevelFunctionGenerationQueue.front(); | ||||
| 		m_lowLevelFunctionGenerationQueue.pop(); | ||||
| 
 | ||||
| @ -195,7 +194,7 @@ void CompilerContext::appendYulUtilityFunctions(OptimiserSettings const& _optimi | ||||
| 	solAssert(!m_appendYulUtilityFunctionsRan, "requestedYulFunctions called more than once."); | ||||
| 	m_appendYulUtilityFunctionsRan = true; | ||||
| 
 | ||||
| 	string code = m_yulFunctionCollector.requestedFunctions(); | ||||
| 	std::string code = m_yulFunctionCollector.requestedFunctions(); | ||||
| 	if (!code.empty()) | ||||
| 	{ | ||||
| 		appendInlineAssembly( | ||||
| @ -233,7 +232,7 @@ void CompilerContext::removeVariable(Declaration const& _declaration) | ||||
| 
 | ||||
| void CompilerContext::removeVariablesAboveStackHeight(unsigned _stackHeight) | ||||
| { | ||||
| 	vector<Declaration const*> toRemove; | ||||
| 	std::vector<Declaration const*> toRemove; | ||||
| 	for (auto _var: m_localVariables) | ||||
| 	{ | ||||
| 		solAssert(!_var.second.empty(), ""); | ||||
| @ -250,14 +249,14 @@ unsigned CompilerContext::numberOfLocalVariables() const | ||||
| 	return static_cast<unsigned>(m_localVariables.size()); | ||||
| } | ||||
| 
 | ||||
| shared_ptr<evmasm::Assembly> CompilerContext::compiledContract(ContractDefinition const& _contract) const | ||||
| std::shared_ptr<evmasm::Assembly> CompilerContext::compiledContract(ContractDefinition const& _contract) const | ||||
| { | ||||
| 	auto ret = m_otherCompilers.find(&_contract); | ||||
| 	solAssert(ret != m_otherCompilers.end(), "Compiled contract not found."); | ||||
| 	return ret->second->assemblyPtr(); | ||||
| } | ||||
| 
 | ||||
| shared_ptr<evmasm::Assembly> CompilerContext::compiledContractRuntime(ContractDefinition const& _contract) const | ||||
| std::shared_ptr<evmasm::Assembly> CompilerContext::compiledContractRuntime(ContractDefinition const& _contract) const | ||||
| { | ||||
| 	auto ret = m_otherCompilers.find(&_contract); | ||||
| 	solAssert(ret != m_otherCompilers.end(), "Compiled contract not found."); | ||||
| @ -320,7 +319,7 @@ unsigned CompilerContext::currentToBaseStackOffset(unsigned _offset) const | ||||
| 	return static_cast<unsigned>(m_asm->deposit()) - _offset - 1; | ||||
| } | ||||
| 
 | ||||
| pair<u256, unsigned> CompilerContext::storageLocationOfVariable(Declaration const& _declaration) const | ||||
| std::pair<u256, unsigned> CompilerContext::storageLocationOfVariable(Declaration const& _declaration) const | ||||
| { | ||||
| 	auto it = m_stateVariables.find(&_declaration); | ||||
| 	solAssert(it != m_stateVariables.end(), "Variable not found in storage."); | ||||
| @ -349,13 +348,13 @@ CompilerContext& CompilerContext::appendConditionalPanic(util::PanicCode _code) | ||||
| 	return *this; | ||||
| } | ||||
| 
 | ||||
| CompilerContext& CompilerContext::appendRevert(string const& _message) | ||||
| CompilerContext& CompilerContext::appendRevert(std::string const& _message) | ||||
| { | ||||
| 	appendInlineAssembly("{ " + revertReasonIfDebug(_message) + " }"); | ||||
| 	return *this; | ||||
| } | ||||
| 
 | ||||
| CompilerContext& CompilerContext::appendConditionalRevert(bool _forwardReturnData, string const& _message) | ||||
| CompilerContext& CompilerContext::appendConditionalRevert(bool _forwardReturnData, std::string const& _message) | ||||
| { | ||||
| 	if (_forwardReturnData && m_evmVersion.supportsReturndata()) | ||||
| 		appendInlineAssembly(R"({ | ||||
| @ -372,24 +371,24 @@ CompilerContext& CompilerContext::appendConditionalRevert(bool _forwardReturnDat | ||||
| 
 | ||||
| void CompilerContext::resetVisitedNodes(ASTNode const* _node) | ||||
| { | ||||
| 	stack<ASTNode const*> newStack; | ||||
| 	std::stack<ASTNode const*> newStack; | ||||
| 	newStack.push(_node); | ||||
| 	std::swap(m_visitedNodes, newStack); | ||||
| 	updateSourceLocation(); | ||||
| } | ||||
| 
 | ||||
| void CompilerContext::appendInlineAssembly( | ||||
| 	string const& _assembly, | ||||
| 	vector<string> const& _localVariables, | ||||
| 	set<string> const& _externallyUsedFunctions, | ||||
| 	std::string const& _assembly, | ||||
| 	std::vector<std::string> const& _localVariables, | ||||
| 	std::set<std::string> const& _externallyUsedFunctions, | ||||
| 	bool _system, | ||||
| 	OptimiserSettings const& _optimiserSettings, | ||||
| 	string _sourceName | ||||
| 	std::string _sourceName | ||||
| ) | ||||
| { | ||||
| 	unsigned startStackHeight = stackHeight(); | ||||
| 
 | ||||
| 	set<yul::YulString> externallyUsedIdentifiers; | ||||
| 	std::set<yul::YulString> externallyUsedIdentifiers; | ||||
| 	for (auto const& fun: _externallyUsedFunctions) | ||||
| 		externallyUsedIdentifiers.insert(yul::YulString(fun)); | ||||
| 	for (auto const& var: _localVariables) | ||||
| @ -438,19 +437,19 @@ void CompilerContext::appendInlineAssembly( | ||||
| 	ErrorReporter errorReporter(errors); | ||||
| 	langutil::CharStream charStream(_assembly, _sourceName); | ||||
| 	yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); | ||||
| 	optional<langutil::SourceLocation> locationOverride; | ||||
| 	std::optional<langutil::SourceLocation> locationOverride; | ||||
| 	if (!_system) | ||||
| 		locationOverride = m_asm->currentSourceLocation(); | ||||
| 	shared_ptr<yul::Block> parserResult = | ||||
| 	std::shared_ptr<yul::Block> parserResult = | ||||
| 		yul::Parser(errorReporter, dialect, std::move(locationOverride)) | ||||
| 		.parse(charStream); | ||||
| #ifdef SOL_OUTPUT_ASM | ||||
| 	cout << yul::AsmPrinter(&dialect)(*parserResult) << endl; | ||||
| #endif | ||||
| 
 | ||||
| 	auto reportError = [&](string const& _context) | ||||
| 	auto reportError = [&](std::string const& _context) | ||||
| 	{ | ||||
| 		string message = | ||||
| 		std::string message = | ||||
| 			"Error parsing/analyzing inline assembly block:\n" + | ||||
| 			_context + "\n" | ||||
| 			"------------------ Input: -----------------\n" + | ||||
| @ -483,7 +482,7 @@ void CompilerContext::appendInlineAssembly( | ||||
| 	{ | ||||
| 		yul::Object obj; | ||||
| 		obj.code = parserResult; | ||||
| 		obj.analysisInfo = make_shared<yul::AsmAnalysisInfo>(analysisInfo); | ||||
| 		obj.analysisInfo = std::make_shared<yul::AsmAnalysisInfo>(analysisInfo); | ||||
| 
 | ||||
| 		solAssert(!dialect.providesObjectAccess()); | ||||
| 		optimizeYul(obj, dialect, _optimiserSettings, externallyUsedIdentifiers); | ||||
| @ -493,7 +492,7 @@ void CompilerContext::appendInlineAssembly( | ||||
| 			// Store as generated sources, but first re-parse to update the source references.
 | ||||
| 			solAssert(m_generatedYulUtilityCode.empty(), ""); | ||||
| 			m_generatedYulUtilityCode = yul::AsmPrinter(dialect)(*obj.code); | ||||
| 			string code = yul::AsmPrinter{dialect}(*obj.code); | ||||
| 			std::string code = yul::AsmPrinter{dialect}(*obj.code); | ||||
| 			langutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName); | ||||
| 			obj.code = yul::Parser(errorReporter, dialect).parse(charStream); | ||||
| 			*obj.analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj); | ||||
| @ -548,7 +547,7 @@ void CompilerContext::optimizeYul(yul::Object& _object, yul::EVMDialect const& _ | ||||
| 		_optimiserSettings.optimizeStackAllocation, | ||||
| 		_optimiserSettings.yulOptimiserSteps, | ||||
| 		_optimiserSettings.yulOptimiserCleanupSteps, | ||||
| 		isCreation? nullopt : make_optional(_optimiserSettings.expectedExecutionsPerDeployment), | ||||
| 		isCreation? std::nullopt : std::make_optional(_optimiserSettings.expectedExecutionsPerDeployment), | ||||
| 		_externalIdentifiers | ||||
| 	); | ||||
| 
 | ||||
| @ -558,11 +557,11 @@ void CompilerContext::optimizeYul(yul::Object& _object, yul::EVMDialect const& _ | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| string CompilerContext::revertReasonIfDebug(string const& _message) | ||||
| std::string CompilerContext::revertReasonIfDebug(std::string const& _message) | ||||
| { | ||||
| 	return YulUtilFunctions::revertReasonIfDebugBody( | ||||
| 		m_revertStrings, | ||||
| 		"mload(" + to_string(CompilerUtils::freeMemoryPointer) + ")", | ||||
| 		"mload(" + std::to_string(CompilerUtils::freeMemoryPointer) + ")", | ||||
| 		_message | ||||
| 	); | ||||
| } | ||||
| @ -590,14 +589,14 @@ evmasm::AssemblyItem CompilerContext::FunctionCompilationQueue::entryLabel( | ||||
| 		} | ||||
| 
 | ||||
| 		// some name that cannot clash with yul function names.
 | ||||
| 		string labelName = "@" + _declaration.name() + "_" + to_string(_declaration.id()); | ||||
| 		std::string labelName = "@" + _declaration.name() + "_" + std::to_string(_declaration.id()); | ||||
| 		evmasm::AssemblyItem tag = _context.namedTag( | ||||
| 			labelName, | ||||
| 			params, | ||||
| 			returns, | ||||
| 			_declaration.id() | ||||
| 		); | ||||
| 		m_entryLabels.insert(make_pair(&_declaration, tag)); | ||||
| 		m_entryLabels.insert(std::make_pair(&_declaration, tag)); | ||||
| 		m_functionsToCompile.push(&_declaration); | ||||
| 		return tag.tag(); | ||||
| 	} | ||||
|  | ||||
| @ -33,7 +33,6 @@ | ||||
| #include <libsolutil/Whiskers.h> | ||||
| #include <libsolutil/StackTooDeepString.h> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::evmasm; | ||||
| using namespace solidity::frontend; | ||||
| @ -105,9 +104,9 @@ void CompilerUtils::revertWithStringData(Type const& _argumentType) | ||||
| } | ||||
| 
 | ||||
| void CompilerUtils::revertWithError( | ||||
| 	string const& _signature, | ||||
| 	vector<Type const*> const& _parameterTypes, | ||||
| 	vector<Type const*> const& _argumentTypes | ||||
| 	std::string const& _signature, | ||||
| 	std::vector<Type const*> const& _parameterTypes, | ||||
| 	std::vector<Type const*> const& _argumentTypes | ||||
| ) | ||||
| { | ||||
| 	fetchFreeMemoryPointer(); | ||||
| @ -215,7 +214,7 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound | ||||
| 		m_context << Instruction::DUP1; | ||||
| 		storeStringData(bytesConstRef(str->value())); | ||||
| 		if (_padToWordBoundaries) | ||||
| 			m_context << u256(max<size_t>(32, ((str->value().size() + 31) / 32) * 32)); | ||||
| 			m_context << u256(std::max<size_t>(32, ((str->value().size() + 31) / 32) * 32)); | ||||
| 		else | ||||
| 			m_context << u256(str->value().size()); | ||||
| 		m_context << Instruction::ADD; | ||||
| @ -264,7 +263,7 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem | ||||
| 	Whiskers templ(R"({ | ||||
| 		if lt(len, <encodedSize>) { <revertString> } | ||||
| 	})"); | ||||
| 	templ("encodedSize", to_string(encodedSize)); | ||||
| 	templ("encodedSize", std::to_string(encodedSize)); | ||||
| 	templ("revertString", m_context.revertReasonIfDebug("Calldata too short")); | ||||
| 	m_context.appendInlineAssembly(templ.render(), {"len"}); | ||||
| 
 | ||||
| @ -320,7 +319,7 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem | ||||
| 						mstore(dst, array_length) | ||||
| 						dst := add(dst, 0x20) | ||||
| 					})"); | ||||
| 					templ("item_size", to_string(arrayType.calldataStride())); | ||||
| 					templ("item_size", std::to_string(arrayType.calldataStride())); | ||||
| 					// TODO add test
 | ||||
| 					templ("revertStringPointer", m_context.revertReasonIfDebug("ABI memory decoding: invalid data pointer")); | ||||
| 					templ("revertStringStart", m_context.revertReasonIfDebug("ABI memory decoding: invalid data start")); | ||||
| @ -374,7 +373,7 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem | ||||
| 					m_context.appendInlineAssembly(Whiskers(R"({ | ||||
| 						if or( | ||||
| 							gt(array_length, 0x100000000), | ||||
| 							gt(add(data_ptr, mul(array_length, )" + to_string(arrayType.calldataStride()) + R"()), input_end) | ||||
| 							gt(add(data_ptr, mul(array_length, )" + std::to_string(arrayType.calldataStride()) + R"()), input_end) | ||||
| 						) { <revertString> } | ||||
| 					})") | ||||
| 					("revertString", m_context.revertReasonIfDebug("ABI calldata decoding: invalid data pointer")) | ||||
| @ -618,7 +617,7 @@ void CompilerUtils::abiEncodeV2( | ||||
| 
 | ||||
| 	// stack: <$value0> <$value1> ... <$value(n-1)> <$headStart>
 | ||||
| 
 | ||||
| 	string encoderName = | ||||
| 	std::string encoderName = | ||||
| 		_padToWordBoundaries ? | ||||
| 		m_context.abiFunctions().tupleEncoderReversed(_givenTypes, _targetTypes, _encodeAsLibraryTypes) : | ||||
| 		m_context.abiFunctions().tupleEncoderPackedReversed(_givenTypes, _targetTypes); | ||||
| @ -631,7 +630,7 @@ void CompilerUtils::abiDecodeV2(TypePointers const& _parameterTypes, bool _fromM | ||||
| 	m_context << Instruction::DUP2 << Instruction::ADD; | ||||
| 	m_context << Instruction::SWAP1; | ||||
| 	// stack: <end> <start>
 | ||||
| 	string decoderName = m_context.abiFunctions().tupleDecoder(_parameterTypes, _fromMemory); | ||||
| 	std::string decoderName = m_context.abiFunctions().tupleDecoder(_parameterTypes, _fromMemory); | ||||
| 	m_context.callYulFunction(decoderName, 2, sizeOnStack(_parameterTypes)); | ||||
| } | ||||
| 
 | ||||
| @ -646,7 +645,7 @@ void CompilerUtils::zeroInitialiseMemoryArray(ArrayType const& _type) | ||||
| 			calldatacopy(memptr, calldatasize(), size) | ||||
| 			memptr := add(memptr, size) | ||||
| 		})"); | ||||
| 		templ("element_size", to_string(_type.memoryStride())); | ||||
| 		templ("element_size", std::to_string(_type.memoryStride())); | ||||
| 		m_context.appendInlineAssembly(templ.render(), {"length", "memptr"}); | ||||
| 	} | ||||
| 	else | ||||
| @ -842,7 +841,7 @@ void CompilerUtils::convertType( | ||||
| 				m_context << Instruction::POP << u256(0); | ||||
| 			else if (targetType.numBytes() > typeOnStack.numBytes() || _cleanupNeeded) | ||||
| 			{ | ||||
| 				unsigned bytes = min(typeOnStack.numBytes(), targetType.numBytes()); | ||||
| 				unsigned bytes = std::min(typeOnStack.numBytes(), targetType.numBytes()); | ||||
| 				m_context << ((u256(1) << (256 - bytes * 8)) - 1); | ||||
| 				m_context << Instruction::NOT << Instruction::AND; | ||||
| 			} | ||||
| @ -960,7 +959,7 @@ void CompilerUtils::convertType( | ||||
| 	case Type::Category::StringLiteral: | ||||
| 	{ | ||||
| 		auto const& literalType = dynamic_cast<StringLiteralType const&>(_typeOnStack); | ||||
| 		string const& value = literalType.value(); | ||||
| 		std::string const& value = literalType.value(); | ||||
| 		bytesConstRef data(value); | ||||
| 		if (targetTypeCategory == Type::Category::FixedBytes) | ||||
| 		{ | ||||
| @ -1186,7 +1185,7 @@ void CompilerUtils::convertType( | ||||
| 					for (auto const& member: typeOnStack->members(nullptr)) | ||||
| 					{ | ||||
| 						solAssert(!member.type->containsNestedMapping()); | ||||
| 						pair<u256, unsigned> const& offsets = typeOnStack->storageOffsetsOfMember(member.name); | ||||
| 						std::pair<u256, unsigned> const& offsets = typeOnStack->storageOffsetsOfMember(member.name); | ||||
| 						_context << offsets.first << Instruction::DUP3 << Instruction::ADD; | ||||
| 						_context << u256(offsets.second); | ||||
| 						StorageItem(_context, *member.type).retrieveValue(SourceLocation(), true); | ||||
| @ -1268,7 +1267,7 @@ void CompilerUtils::convertType( | ||||
| 				if (sourceSize > 0 || targetSize > 0) | ||||
| 				{ | ||||
| 					// Move it back into its place.
 | ||||
| 					for (unsigned j = 0; j < min(sourceSize, targetSize); ++j) | ||||
| 					for (unsigned j = 0; j < std::min(sourceSize, targetSize); ++j) | ||||
| 						m_context << | ||||
| 							swapInstruction(depth + targetSize - sourceSize) << | ||||
| 							Instruction::POP; | ||||
| @ -1375,7 +1374,7 @@ void CompilerUtils::pushZeroValue(Type const& _type) | ||||
| 		[type](CompilerContext& _context) { | ||||
| 			CompilerUtils utils(_context); | ||||
| 
 | ||||
| 			utils.allocateMemory(max<u256>(32u, type->memoryDataSize())); | ||||
| 			utils.allocateMemory(std::max<u256>(32u, type->memoryDataSize())); | ||||
| 			_context << Instruction::DUP1; | ||||
| 
 | ||||
| 			if (auto structType = dynamic_cast<StructType const*>(type)) | ||||
| @ -1493,7 +1492,7 @@ void CompilerUtils::popAndJump(unsigned _toHeight, evmasm::AssemblyItem const& _ | ||||
| 	m_context.adjustStackOffset(static_cast<int>(amount)); | ||||
| } | ||||
| 
 | ||||
| unsigned CompilerUtils::sizeOnStack(vector<Type const*> const& _variableTypes) | ||||
| unsigned CompilerUtils::sizeOnStack(std::vector<Type const*> const& _variableTypes) | ||||
| { | ||||
| 	unsigned size = 0; | ||||
| 	for (Type const* type: _variableTypes) | ||||
| @ -1509,7 +1508,7 @@ void CompilerUtils::computeHashStatic() | ||||
| 
 | ||||
| void CompilerUtils::copyContractCodeToMemory(ContractDefinition const& contract, bool _creation) | ||||
| { | ||||
| 	string which = _creation ? "Creation" : "Runtime"; | ||||
| 	std::string which = _creation ? "Creation" : "Runtime"; | ||||
| 	m_context.callLowLevelFunction( | ||||
| 		"$copyContract" + which + "CodeToMemory_" + contract.type()->identifier(), | ||||
| 		1, | ||||
| @ -1517,7 +1516,7 @@ void CompilerUtils::copyContractCodeToMemory(ContractDefinition const& contract, | ||||
| 		[&contract, _creation](CompilerContext& _context) | ||||
| 		{ | ||||
| 			// copy the contract's code into memory
 | ||||
| 			shared_ptr<evmasm::Assembly> assembly = | ||||
| 			std::shared_ptr<evmasm::Assembly> assembly = | ||||
| 				_creation ? | ||||
| 				_context.compiledContract(contract) : | ||||
| 				_context.compiledContractRuntime(contract); | ||||
|  | ||||
| @ -55,7 +55,6 @@ | ||||
| #include <algorithm> | ||||
| #include <limits> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::evmasm; | ||||
| using namespace solidity::frontend; | ||||
| @ -80,7 +79,7 @@ public: | ||||
| 	{ | ||||
| 		solAssert( | ||||
| 			m_context.stackHeight() == stackHeight, | ||||
| 			std::string("I sense a disturbance in the stack: ") + to_string(m_context.stackHeight()) + " vs " + to_string(stackHeight) | ||||
| 			std::string("I sense a disturbance in the stack: ") + std::to_string(m_context.stackHeight()) + " vs " + std::to_string(stackHeight) | ||||
| 		); | ||||
| 	} | ||||
| private: | ||||
| @ -92,7 +91,7 @@ private: | ||||
| 
 | ||||
| void ContractCompiler::compileContract( | ||||
| 	ContractDefinition const& _contract, | ||||
| 	map<ContractDefinition const*, shared_ptr<Compiler const>> const& _otherCompilers | ||||
| 	std::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers | ||||
| ) | ||||
| { | ||||
| 	CompilerContext::LocationSetter locationSetter(m_context, _contract); | ||||
| @ -111,7 +110,7 @@ void ContractCompiler::compileContract( | ||||
| 
 | ||||
| size_t ContractCompiler::compileConstructor( | ||||
| 	ContractDefinition const& _contract, | ||||
| 	std::map<ContractDefinition const*, shared_ptr<Compiler const>> const& _otherCompilers | ||||
| 	std::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers | ||||
| ) | ||||
| { | ||||
| 	CompilerContext::LocationSetter locationSetter(m_context, _contract); | ||||
| @ -126,7 +125,7 @@ size_t ContractCompiler::compileConstructor( | ||||
| 
 | ||||
| void ContractCompiler::initializeContext( | ||||
| 	ContractDefinition const& _contract, | ||||
| 	map<ContractDefinition const*, shared_ptr<Compiler const>> const& _otherCompilers | ||||
| 	std::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers | ||||
| ) | ||||
| { | ||||
| 	m_context.setUseABICoderV2(*_contract.sourceUnit().annotation().useABICoderV2); | ||||
| @ -187,7 +186,7 @@ size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _cont | ||||
| 	CompilerContext::LocationSetter locationSetter(m_context, _contract); | ||||
| 	m_context << deployRoutine; | ||||
| 
 | ||||
| 	solAssert(m_context.runtimeSub() != numeric_limits<size_t>::max(), "Runtime sub not registered"); | ||||
| 	solAssert(m_context.runtimeSub() != std::numeric_limits<size_t>::max(), "Runtime sub not registered"); | ||||
| 
 | ||||
| 	ContractType contractType(_contract); | ||||
| 	auto const& immutables = contractType.immutableVariables(); | ||||
| @ -231,7 +230,7 @@ size_t ContractCompiler::deployLibrary(ContractDefinition const& _contract) | ||||
| 
 | ||||
| 	CompilerContext::LocationSetter locationSetter(m_context, _contract); | ||||
| 
 | ||||
| 	solAssert(m_context.runtimeSub() != numeric_limits<size_t>::max(), "Runtime sub not registered"); | ||||
| 	solAssert(m_context.runtimeSub() != std::numeric_limits<size_t>::max(), "Runtime sub not registered"); | ||||
| 	m_context.pushSubroutineSize(m_context.runtimeSub()); | ||||
| 	m_context.pushSubroutineOffset(m_context.runtimeSub()); | ||||
| 	// This code replaces the address added by appendDeployTimeAddress().
 | ||||
| @ -324,8 +323,8 @@ void ContractCompiler::appendDelegatecallCheck() | ||||
| } | ||||
| 
 | ||||
| void ContractCompiler::appendInternalSelector( | ||||
| 	map<FixedHash<4>, evmasm::AssemblyItem const> const& _entryPoints, | ||||
| 	vector<FixedHash<4>> const& _ids, | ||||
| 	std::map<FixedHash<4>, evmasm::AssemblyItem const> const& _entryPoints, | ||||
| 	std::vector<FixedHash<4>> const& _ids, | ||||
| 	evmasm::AssemblyItem const& _notFoundTag, | ||||
| 	size_t _runs | ||||
| ) | ||||
| @ -369,11 +368,11 @@ void ContractCompiler::appendInternalSelector( | ||||
| 		m_context << dupInstruction(1) << u256(FixedHash<4>::Arith(pivot)) << Instruction::GT; | ||||
| 		evmasm::AssemblyItem lessTag{m_context.appendConditionalJump()}; | ||||
| 		// Here, we have funid >= pivot
 | ||||
| 		vector<FixedHash<4>> larger{_ids.begin() + static_cast<ptrdiff_t>(pivotIndex), _ids.end()}; | ||||
| 		std::vector<FixedHash<4>> larger{_ids.begin() + static_cast<ptrdiff_t>(pivotIndex), _ids.end()}; | ||||
| 		appendInternalSelector(_entryPoints, larger, _notFoundTag, _runs); | ||||
| 		m_context << lessTag; | ||||
| 		// Here, we have funid < pivot
 | ||||
| 		vector<FixedHash<4>> smaller{_ids.begin(), _ids.begin() + static_cast<ptrdiff_t>(pivotIndex)}; | ||||
| 		std::vector<FixedHash<4>> smaller{_ids.begin(), _ids.begin() + static_cast<ptrdiff_t>(pivotIndex)}; | ||||
| 		appendInternalSelector(_entryPoints, smaller, _notFoundTag, _runs); | ||||
| 	} | ||||
| 	else | ||||
| @ -411,8 +410,8 @@ bool hasPayableFunctions(ContractDefinition const& _contract) | ||||
| 
 | ||||
| void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contract) | ||||
| { | ||||
| 	map<FixedHash<4>, FunctionTypePointer> interfaceFunctions = _contract.interfaceFunctions(); | ||||
| 	map<FixedHash<4>, evmasm::AssemblyItem const> callDataUnpackerEntryPoints; | ||||
| 	std::map<FixedHash<4>, FunctionTypePointer> interfaceFunctions = _contract.interfaceFunctions(); | ||||
| 	std::map<FixedHash<4>, evmasm::AssemblyItem const> callDataUnpackerEntryPoints; | ||||
| 
 | ||||
| 	if (_contract.isLibrary()) | ||||
| 	{ | ||||
| @ -448,7 +447,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac | ||||
| 		CompilerUtils(m_context).loadFromMemory(0, IntegerType(CompilerUtils::dataStartOffset * 8), true, false); | ||||
| 
 | ||||
| 		// stack now is: <can-call-non-view-functions>? <funhash>
 | ||||
| 		vector<FixedHash<4>> sortedIDs; | ||||
| 		std::vector<FixedHash<4>> sortedIDs; | ||||
| 		for (auto const& it: interfaceFunctions) | ||||
| 		{ | ||||
| 			callDataUnpackerEntryPoints.emplace(it.first, m_context.newTag()); | ||||
| @ -572,7 +571,7 @@ void ContractCompiler::appendReturnValuePacker(TypePointers const& _typeParamete | ||||
| void ContractCompiler::registerStateVariables(ContractDefinition const& _contract) | ||||
| { | ||||
| 	for (auto const& var: ContractType(_contract).stateVariables()) | ||||
| 		m_context.addStateVariable(*get<0>(var), get<1>(var), get<2>(var)); | ||||
| 		m_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var)); | ||||
| } | ||||
| 
 | ||||
| void ContractCompiler::registerImmutableVariables(ContractDefinition const& _contract) | ||||
| @ -645,7 +644,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) | ||||
| 	m_breakTags.clear(); | ||||
| 	m_continueTags.clear(); | ||||
| 	m_currentFunction = &_function; | ||||
| 	m_modifierDepth = numeric_limits<unsigned>::max(); | ||||
| 	m_modifierDepth = std::numeric_limits<unsigned>::max(); | ||||
| 	m_scopeStackHeight.clear(); | ||||
| 	m_context.setModifierDepth(0); | ||||
| 
 | ||||
| @ -662,10 +661,10 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) | ||||
| 	unsigned const c_argumentsSize = CompilerUtils::sizeOnStack(_function.parameters()); | ||||
| 	unsigned const c_returnValuesSize = CompilerUtils::sizeOnStack(_function.returnParameters()); | ||||
| 
 | ||||
| 	vector<int> stackLayout; | ||||
| 	std::vector<int> stackLayout; | ||||
| 	if (!_function.isConstructor() && !_function.isFallback()) | ||||
| 		stackLayout.push_back(static_cast<int>(c_returnValuesSize)); // target of return address
 | ||||
| 	stackLayout += vector<int>(c_argumentsSize, -1); // discard all arguments
 | ||||
| 	stackLayout += std::vector<int>(c_argumentsSize, -1); // discard all arguments
 | ||||
| 	for (size_t i = 0; i < c_returnValuesSize; ++i) | ||||
| 		stackLayout.push_back(static_cast<int>(i)); | ||||
| 
 | ||||
| @ -684,7 +683,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) | ||||
| 		else | ||||
| 		{ | ||||
| 			m_context << swapInstruction(static_cast<unsigned>(stackLayout.size()) - static_cast<unsigned>(stackLayout.back()) - 1u); | ||||
| 			swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back()); | ||||
| 			std::swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back()); | ||||
| 		} | ||||
| 	for (size_t i = 0; i < stackLayout.size(); ++i) | ||||
| 		if (stackLayout[i] != static_cast<int>(i)) | ||||
| @ -790,7 +789,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) | ||||
| 					unsigned stackDiff = static_cast<unsigned>(_assembly.stackHeight()) - m_context.baseStackOffsetOfVariable(*variable); | ||||
| 					if (!ref->second.suffix.empty()) | ||||
| 					{ | ||||
| 						string const& suffix = ref->second.suffix; | ||||
| 						std::string const& suffix = ref->second.suffix; | ||||
| 						if (variable->type()->dataStoredIn(DataLocation::Storage)) | ||||
| 						{ | ||||
| 							solAssert(suffix == "offset" || suffix == "slot", ""); | ||||
| @ -865,7 +864,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) | ||||
| 			// lvalue context
 | ||||
| 			auto variable = dynamic_cast<VariableDeclaration const*>(decl); | ||||
| 			unsigned stackDiff = static_cast<unsigned>(_assembly.stackHeight()) - m_context.baseStackOffsetOfVariable(*variable) - 1; | ||||
| 			string const& suffix = ref->second.suffix; | ||||
| 			std::string const& suffix = ref->second.suffix; | ||||
| 			if (variable->type()->dataStoredIn(DataLocation::Storage)) | ||||
| 			{ | ||||
| 				solAssert( | ||||
| @ -928,7 +927,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) | ||||
| 	yul::AsmAnalysisInfo* analysisInfo = _inlineAssembly.annotation().analysisInfo.get(); | ||||
| 
 | ||||
| 	// Only used in the scope below, but required to live outside to keep the
 | ||||
| 	// shared_ptr's alive
 | ||||
| 	// std::shared_ptr's alive
 | ||||
| 	yul::Object object = {}; | ||||
| 
 | ||||
| 	// The optimiser cannot handle external references
 | ||||
| @ -941,8 +940,8 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) | ||||
| 		solAssert(dialect, ""); | ||||
| 
 | ||||
| 		// Create a modifiable copy of the code and analysis
 | ||||
| 		object.code = make_shared<yul::Block>(yul::ASTCopier().translate(*code)); | ||||
| 		object.analysisInfo = make_shared<yul::AsmAnalysisInfo>(yul::AsmAnalyzer::analyzeStrictAssertCorrect(*dialect, object)); | ||||
| 		object.code = std::make_shared<yul::Block>(yul::ASTCopier().translate(*code)); | ||||
| 		object.analysisInfo = std::make_shared<yul::AsmAnalysisInfo>(yul::AsmAnalyzer::analyzeStrictAssertCorrect(*dialect, object)); | ||||
| 
 | ||||
| 		m_context.optimizeYul(object, *dialect, m_optimiserSettings); | ||||
| 
 | ||||
| @ -989,10 +988,10 @@ bool ContractCompiler::visit(TryStatement const& _tryStatement) | ||||
| 		TryCatchClause const& successClause = *_tryStatement.clauses().front(); | ||||
| 		if (successClause.parameters()) | ||||
| 		{ | ||||
| 			vector<Type const*> exprTypes{_tryStatement.externalCall().annotation().type}; | ||||
| 			std::vector<Type const*> exprTypes{_tryStatement.externalCall().annotation().type}; | ||||
| 			if (auto tupleType = dynamic_cast<TupleType const*>(exprTypes.front())) | ||||
| 				exprTypes = tupleType->components(); | ||||
| 			vector<ASTPointer<VariableDeclaration>> const& params = successClause.parameters()->parameters(); | ||||
| 			std::vector<ASTPointer<VariableDeclaration>> const& params = successClause.parameters()->parameters(); | ||||
| 			solAssert(exprTypes.size() == params.size(), ""); | ||||
| 			for (size_t i = 0; i < exprTypes.size(); ++i) | ||||
| 				solAssert(params[i] && exprTypes[i] && *params[i]->annotation().type == *exprTypes[i], ""); | ||||
| @ -1008,7 +1007,7 @@ bool ContractCompiler::visit(TryStatement const& _tryStatement) | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| void ContractCompiler::handleCatch(vector<ASTPointer<TryCatchClause>> const& _catchClauses) | ||||
| void ContractCompiler::handleCatch(std::vector<ASTPointer<TryCatchClause>> const& _catchClauses) | ||||
| { | ||||
| 	// Stack is empty.
 | ||||
| 	ASTPointer<TryCatchClause> error{}; | ||||
| @ -1285,7 +1284,7 @@ bool ContractCompiler::visit(Return const& _return) | ||||
| 	if (Expression const* expression = _return.expression()) | ||||
| 	{ | ||||
| 		solAssert(_return.annotation().functionReturnParameters, "Invalid return parameters pointer."); | ||||
| 		vector<ASTPointer<VariableDeclaration>> const& returnParameters = | ||||
| 		std::vector<ASTPointer<VariableDeclaration>> const& returnParameters = | ||||
| 			_return.annotation().functionReturnParameters->parameters(); | ||||
| 		TypePointers types; | ||||
| 		for (auto const& retVariable: returnParameters) | ||||
| @ -1432,7 +1431,7 @@ void ContractCompiler::appendModifierOrFunctionCode() | ||||
| 	solAssert(m_currentFunction, ""); | ||||
| 	unsigned stackSurplus = 0; | ||||
| 	Block const* codeBlock = nullptr; | ||||
| 	vector<VariableDeclaration const*> addedVariables; | ||||
| 	std::vector<VariableDeclaration const*> addedVariables; | ||||
| 
 | ||||
| 	m_modifierDepth++; | ||||
| 	m_context.setModifierDepth(m_modifierDepth); | ||||
|  | ||||
| @ -43,7 +43,6 @@ | ||||
| #include <numeric> | ||||
| #include <utility> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::evmasm; | ||||
| using namespace solidity::frontend; | ||||
| @ -242,7 +241,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& | ||||
| 			if (auto arrayType = dynamic_cast<ArrayType const*>(returnTypes[i])) | ||||
| 				if (!arrayType->isByteArrayOrString()) | ||||
| 					continue; | ||||
| 			pair<u256, unsigned> const& offsets = structType->storageOffsetsOfMember(names[i]); | ||||
| 			std::pair<u256, unsigned> const& offsets = structType->storageOffsetsOfMember(names[i]); | ||||
| 			m_context << Instruction::DUP1 << u256(offsets.first) << Instruction::ADD << u256(offsets.second); | ||||
| 			Type const* memberType = structType->memberType(names[i]); | ||||
| 			StorageItem(m_context, *memberType).retrieveValue(SourceLocation(), true); | ||||
| @ -370,7 +369,7 @@ bool ExpressionCompiler::visit(TupleExpression const& _tuple) | ||||
| 		ArrayType const& arrayType = dynamic_cast<ArrayType const&>(*_tuple.annotation().type); | ||||
| 
 | ||||
| 		solAssert(!arrayType.isDynamicallySized(), "Cannot create dynamically sized inline array."); | ||||
| 		utils().allocateMemory(max(u256(32u), arrayType.memoryDataSize())); | ||||
| 		utils().allocateMemory(std::max(u256(32u), arrayType.memoryDataSize())); | ||||
| 		m_context << Instruction::DUP1; | ||||
| 
 | ||||
| 		for (auto const& component: _tuple.components()) | ||||
| @ -383,7 +382,7 @@ bool ExpressionCompiler::visit(TupleExpression const& _tuple) | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		vector<unique_ptr<LValue>> lvalues; | ||||
| 		std::vector<std::unique_ptr<LValue>> lvalues; | ||||
| 		for (auto const& component: _tuple.components()) | ||||
| 			if (component) | ||||
| 			{ | ||||
| @ -395,13 +394,13 @@ bool ExpressionCompiler::visit(TupleExpression const& _tuple) | ||||
| 				} | ||||
| 			} | ||||
| 			else if (_tuple.annotation().willBeWrittenTo) | ||||
| 				lvalues.push_back(unique_ptr<LValue>()); | ||||
| 				lvalues.push_back(std::unique_ptr<LValue>()); | ||||
| 		if (_tuple.annotation().willBeWrittenTo) | ||||
| 		{ | ||||
| 			if (_tuple.components().size() == 1) | ||||
| 				m_currentLValue = std::move(lvalues[0]); | ||||
| 			else | ||||
| 				m_currentLValue = make_unique<TupleObject>(m_context, std::move(lvalues)); | ||||
| 				m_currentLValue = std::make_unique<TupleObject>(m_context, std::move(lvalues)); | ||||
| 		} | ||||
| 	} | ||||
| 	return false; | ||||
| @ -524,7 +523,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation) | ||||
| 			m_context << u256(0) << Instruction::SUB; | ||||
| 		break; | ||||
| 	default: | ||||
| 		solAssert(false, "Invalid unary operator: " + string(TokenTraits::toString(_unaryOperation.getOperator()))); | ||||
| 		solAssert(false, "Invalid unary operator: " + std::string(TokenTraits::toString(_unaryOperation.getOperator()))); | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
| @ -659,14 +658,14 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) | ||||
| 
 | ||||
| 	TypePointers parameterTypes = functionType->parameterTypes(); | ||||
| 
 | ||||
| 	vector<ASTPointer<Expression const>> const& arguments = _functionCall.sortedArguments(); | ||||
| 	std::vector<ASTPointer<Expression const>> const& arguments = _functionCall.sortedArguments(); | ||||
| 
 | ||||
| 	if (functionCallKind == FunctionCallKind::StructConstructorCall) | ||||
| 	{ | ||||
| 		TypeType const& type = dynamic_cast<TypeType const&>(*_functionCall.expression().annotation().type); | ||||
| 		auto const& structType = dynamic_cast<StructType const&>(*type.actualType()); | ||||
| 
 | ||||
| 		utils().allocateMemory(max(u256(32u), structType.memoryDataSize())); | ||||
| 		utils().allocateMemory(std::max(u256(32u), structType.memoryDataSize())); | ||||
| 		m_context << Instruction::DUP1; | ||||
| 
 | ||||
| 		for (unsigned i = 0; i < arguments.size(); ++i) | ||||
| @ -992,7 +991,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) | ||||
| 		case FunctionType::Kind::Error: | ||||
| 		{ | ||||
| 			_functionCall.expression().accept(*this); | ||||
| 			vector<Type const*> argumentTypes; | ||||
| 			std::vector<Type const*> argumentTypes; | ||||
| 			for (ASTPointer<Expression const> const& arg: _functionCall.sortedArguments()) | ||||
| 			{ | ||||
| 				arg->accept(*this); | ||||
| @ -1060,7 +1059,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) | ||||
| 		case FunctionType::Kind::RIPEMD160: | ||||
| 		{ | ||||
| 			_functionCall.expression().accept(*this); | ||||
| 			static map<FunctionType::Kind, u256> const contractAddresses{ | ||||
| 			static std::map<FunctionType::Kind, u256> const contractAddresses{ | ||||
| 				{FunctionType::Kind::ECRecover, 1}, | ||||
| 				{FunctionType::Kind::SHA256, 2}, | ||||
| 				{FunctionType::Kind::RIPEMD160, 3} | ||||
| @ -1151,8 +1150,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) | ||||
| 		case FunctionType::Kind::BytesConcat: | ||||
| 		{ | ||||
| 			_functionCall.expression().accept(*this); | ||||
| 			vector<Type const*> argumentTypes; | ||||
| 			vector<Type const*> targetTypes; | ||||
| 			std::vector<Type const*> argumentTypes; | ||||
| 			std::vector<Type const*> targetTypes; | ||||
| 			for (auto const& argument: arguments) | ||||
| 			{ | ||||
| 				argument->accept(*this); | ||||
| @ -1416,7 +1415,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) | ||||
| 				// stack: <memory pointer> <selector>
 | ||||
| 
 | ||||
| 				// load current memory, mask and combine the selector
 | ||||
| 				string mask = formatNumber((u256(-1) >> 32)); | ||||
| 				std::string mask = formatNumber((u256(-1) >> 32)); | ||||
| 				m_context.appendInlineAssembly(R"({ | ||||
| 					let data_start := add(mem_ptr, 0x20) | ||||
| 					let data := mload(data_start) | ||||
| @ -1476,7 +1475,7 @@ bool ExpressionCompiler::visit(FunctionCallOptions const& _functionCallOptions) | ||||
| 	// Desired Stack: [salt], [gas], [value]
 | ||||
| 	enum Option { Salt, Gas, Value }; | ||||
| 
 | ||||
| 	vector<Option> presentOptions; | ||||
| 	std::vector<Option> presentOptions; | ||||
| 	FunctionType const& funType = dynamic_cast<FunctionType const&>( | ||||
| 		*_functionCallOptions.expression().annotation().type | ||||
| 	); | ||||
| @ -1486,7 +1485,7 @@ bool ExpressionCompiler::visit(FunctionCallOptions const& _functionCallOptions) | ||||
| 
 | ||||
| 	for (size_t i = 0; i < _functionCallOptions.options().size(); ++i) | ||||
| 	{ | ||||
| 		string const& name = *_functionCallOptions.names()[i]; | ||||
| 		std::string const& name = *_functionCallOptions.names()[i]; | ||||
| 		Type const* requiredType = TypeProvider::uint256(); | ||||
| 		Option newOption; | ||||
| 		if (name == "salt") | ||||
| @ -1818,7 +1817,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) | ||||
| 			); | ||||
| 			m_context << Instruction::EXTCODEHASH; | ||||
| 		} | ||||
| 		else if ((set<string>{"send", "transfer"}).count(member)) | ||||
| 		else if ((std::set<std::string>{"send", "transfer"}).count(member)) | ||||
| 		{ | ||||
| 			solAssert(dynamic_cast<AddressType const&>(*_memberAccess.expression().annotation().type).stateMutability() == StateMutability::Payable, ""); | ||||
| 			utils().convertType( | ||||
| @ -1827,7 +1826,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) | ||||
| 				true | ||||
| 			); | ||||
| 		} | ||||
| 		else if ((set<string>{"call", "callcode", "delegatecall", "staticcall"}).count(member)) | ||||
| 		else if ((std::set<std::string>{"call", "callcode", "delegatecall", "staticcall"}).count(member)) | ||||
| 			utils().convertType( | ||||
| 				*_memberAccess.expression().annotation().type, | ||||
| 				*TypeProvider::address(), | ||||
| @ -1910,7 +1909,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) | ||||
| 				Whiskers(R"({ | ||||
| 					mstore(start, sub(end, add(start, 0x20))) | ||||
| 					mstore(<free>, and(add(end, 31), not(31))) | ||||
| 				})")("free", to_string(CompilerUtils::freeMemoryPointer)).render(), | ||||
| 				})")("free", std::to_string(CompilerUtils::freeMemoryPointer)).render(), | ||||
| 				{"start", "end"} | ||||
| 			); | ||||
| 			m_context << Instruction::POP; | ||||
| @ -1946,7 +1945,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) | ||||
| 				solAssert(false, "min/max not available for the given type."); | ||||
| 
 | ||||
| 		} | ||||
| 		else if ((set<string>{"encode", "encodePacked", "encodeWithSelector", "encodeWithSignature", "decode"}).count(member)) | ||||
| 		else if ((std::set<std::string>{"encode", "encodePacked", "encodeWithSelector", "encodeWithSignature", "decode"}).count(member)) | ||||
| 		{ | ||||
| 			// no-op
 | ||||
| 		} | ||||
| @ -1961,7 +1960,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) | ||||
| 		{ | ||||
| 		case DataLocation::Storage: | ||||
| 		{ | ||||
| 			pair<u256, unsigned> const& offsets = type.storageOffsetsOfMember(member); | ||||
| 			std::pair<u256, unsigned> const& offsets = type.storageOffsetsOfMember(member); | ||||
| 			m_context << offsets.first << Instruction::ADD << u256(offsets.second); | ||||
| 			setLValueToStorageItem(_memberAccess); | ||||
| 			break; | ||||
| @ -2454,7 +2453,7 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token _operator, Type cons | ||||
| 	IntegerType const& type = dynamic_cast<IntegerType const&>(_type); | ||||
| 	if (m_context.arithmetic() == Arithmetic::Checked) | ||||
| 	{ | ||||
| 		string functionName; | ||||
| 		std::string functionName; | ||||
| 		switch (_operator) | ||||
| 		{ | ||||
| 		case Token::Add: | ||||
| @ -2620,7 +2619,7 @@ void ExpressionCompiler::appendExpOperatorCode(Type const& _valueType, Type cons | ||||
| 
 | ||||
| void ExpressionCompiler::appendExternalFunctionCall( | ||||
| 	FunctionType const& _functionType, | ||||
| 	vector<ASTPointer<Expression const>> const& _arguments, | ||||
| 	std::vector<ASTPointer<Expression const>> const& _arguments, | ||||
| 	bool _tryCall | ||||
| ) | ||||
| { | ||||
|  | ||||
| @ -30,7 +30,6 @@ | ||||
| 
 | ||||
| #include <libsolutil/StackTooDeepString.h> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::evmasm; | ||||
| using namespace solidity::frontend; | ||||
| @ -410,7 +409,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc | ||||
| 					if (sourceType.location() == DataLocation::Storage) | ||||
| 					{ | ||||
| 						// stack layout: source_ref target_ref
 | ||||
| 						pair<u256, unsigned> const& offsets = sourceType.storageOffsetsOfMember(member.name); | ||||
| 						std::pair<u256, unsigned> const& offsets = sourceType.storageOffsetsOfMember(member.name); | ||||
| 						m_context << offsets.first << Instruction::DUP3 << Instruction::ADD; | ||||
| 						m_context << u256(offsets.second); | ||||
| 						// stack: source_ref target_ref source_member_ref source_member_off
 | ||||
| @ -427,7 +426,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc | ||||
| 						// stack layout: source_ref target_ref source_value...
 | ||||
| 					} | ||||
| 					unsigned stackSize = sourceMemberType->sizeOnStack(); | ||||
| 					pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member.name); | ||||
| 					std::pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member.name); | ||||
| 					m_context << dupInstruction(1 + stackSize) << offsets.first << Instruction::ADD; | ||||
| 					m_context << u256(offsets.second); | ||||
| 					// stack: source_ref target_ref target_off source_value... target_member_ref target_member_byte_off
 | ||||
| @ -469,7 +468,7 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const | ||||
| 			Type const* memberType = member.type; | ||||
| 			if (memberType->category() == Type::Category::Mapping) | ||||
| 				continue; | ||||
| 			pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member.name); | ||||
| 			std::pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member.name); | ||||
| 			m_context | ||||
| 				<< offsets.first << Instruction::DUP3 << Instruction::ADD | ||||
| 				<< u256(offsets.second); | ||||
| @ -592,7 +591,7 @@ void TupleObject::storeValue(Type const& _sourceType, SourceLocation const& _loc | ||||
| 	// We will assign from right to left to optimize stack layout.
 | ||||
| 	for (size_t i = 0; i < m_lvalues.size(); ++i) | ||||
| 	{ | ||||
| 		unique_ptr<LValue> const& lvalue = m_lvalues[m_lvalues.size() - i - 1]; | ||||
| 		std::unique_ptr<LValue> const& lvalue = m_lvalues[m_lvalues.size() - i - 1]; | ||||
| 		Type const* valType = valueTypes[valueTypes.size() - i - 1]; | ||||
| 		unsigned stackHeight = m_context.stackHeight(); | ||||
| 		solAssert(!valType == !lvalue, ""); | ||||
|  | ||||
| @ -26,44 +26,43 @@ | ||||
| #include <libsolutil/Whiskers.h> | ||||
| #include <libsolutil/StringUtils.h> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::frontend; | ||||
| using namespace solidity::util; | ||||
| 
 | ||||
| string MultiUseYulFunctionCollector::requestedFunctions() | ||||
| std::string MultiUseYulFunctionCollector::requestedFunctions() | ||||
| { | ||||
| 	string result = std::move(m_code); | ||||
| 	std::string result = std::move(m_code); | ||||
| 	m_code.clear(); | ||||
| 	m_requestedFunctions.clear(); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| string MultiUseYulFunctionCollector::createFunction(string const& _name, function<string ()> const& _creator) | ||||
| std::string MultiUseYulFunctionCollector::createFunction(std::string const& _name, std::function<std::string()> const& _creator) | ||||
| { | ||||
| 	if (!m_requestedFunctions.count(_name)) | ||||
| 	{ | ||||
| 		m_requestedFunctions.insert(_name); | ||||
| 		string fun = _creator(); | ||||
| 		std::string fun = _creator(); | ||||
| 		solAssert(!fun.empty(), ""); | ||||
| 		solAssert(fun.find("function " + _name + "(") != string::npos, "Function not properly named."); | ||||
| 		solAssert(fun.find("function " + _name + "(") != std::string::npos, "Function not properly named."); | ||||
| 		m_code += std::move(fun); | ||||
| 	} | ||||
| 	return _name; | ||||
| } | ||||
| 
 | ||||
| string MultiUseYulFunctionCollector::createFunction( | ||||
| 	string const& _name, | ||||
| 	function<string(vector<string>&, vector<string>&)> const& _creator | ||||
| std::string MultiUseYulFunctionCollector::createFunction( | ||||
| 	std::string const& _name, | ||||
| 	std::function<std::string(std::vector<std::string>&, std::vector<std::string>&)> const& _creator | ||||
| ) | ||||
| { | ||||
| 	solAssert(!_name.empty(), ""); | ||||
| 	if (!m_requestedFunctions.count(_name)) | ||||
| 	{ | ||||
| 		m_requestedFunctions.insert(_name); | ||||
| 		vector<string> arguments; | ||||
| 		vector<string> returnParameters; | ||||
| 		string body = _creator(arguments, returnParameters); | ||||
| 		std::vector<std::string> arguments; | ||||
| 		std::vector<std::string> returnParameters; | ||||
| 		std::string body = _creator(arguments, returnParameters); | ||||
| 		solAssert(!body.empty(), ""); | ||||
| 
 | ||||
| 		m_code += Whiskers(R"( | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -24,7 +24,6 @@ | ||||
| 
 | ||||
| #include <libyul/AsmPrinter.h> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity::langutil; | ||||
| using namespace solidity::frontend; | ||||
| using namespace solidity::util; | ||||
| @ -41,110 +40,110 @@ YulArity YulArity::fromType(FunctionType const& _functionType) | ||||
| 	}; | ||||
| } | ||||
| 
 | ||||
| string IRNames::externalFunctionABIWrapper(Declaration const& _functionOrVarDecl) | ||||
| std::string IRNames::externalFunctionABIWrapper(Declaration const& _functionOrVarDecl) | ||||
| { | ||||
| 	if (auto const* function = dynamic_cast<FunctionDefinition const*>(&_functionOrVarDecl)) | ||||
| 		solAssert(!function->isConstructor()); | ||||
| 
 | ||||
| 	return "external_fun_" + _functionOrVarDecl.name() + "_" + to_string(_functionOrVarDecl.id()); | ||||
| 	return "external_fun_" + _functionOrVarDecl.name() + "_" + std::to_string(_functionOrVarDecl.id()); | ||||
| } | ||||
| 
 | ||||
| string IRNames::function(FunctionDefinition const& _function) | ||||
| std::string IRNames::function(FunctionDefinition const& _function) | ||||
| { | ||||
| 	if (_function.isConstructor()) | ||||
| 		return constructor(*_function.annotation().contract); | ||||
| 
 | ||||
| 	return "fun_" + _function.name() + "_" + to_string(_function.id()); | ||||
| 	return "fun_" + _function.name() + "_" + std::to_string(_function.id()); | ||||
| } | ||||
| 
 | ||||
| string IRNames::function(VariableDeclaration const& _varDecl) | ||||
| std::string IRNames::function(VariableDeclaration const& _varDecl) | ||||
| { | ||||
| 	return "getter_fun_" + _varDecl.name() + "_" + to_string(_varDecl.id()); | ||||
| 	return "getter_fun_" + _varDecl.name() + "_" + std::to_string(_varDecl.id()); | ||||
| } | ||||
| 
 | ||||
| string IRNames::modifierInvocation(ModifierInvocation const& _modifierInvocation) | ||||
| std::string IRNames::modifierInvocation(ModifierInvocation const& _modifierInvocation) | ||||
| { | ||||
| 	// This uses the ID of the modifier invocation because it has to be unique
 | ||||
| 	// for each invocation.
 | ||||
| 	solAssert(!_modifierInvocation.name().path().empty(), ""); | ||||
| 	string const& modifierName = _modifierInvocation.name().path().back(); | ||||
| 	std::string const& modifierName = _modifierInvocation.name().path().back(); | ||||
| 	solAssert(!modifierName.empty(), ""); | ||||
| 	return "modifier_" + modifierName + "_" + to_string(_modifierInvocation.id()); | ||||
| 	return "modifier_" + modifierName + "_" + std::to_string(_modifierInvocation.id()); | ||||
| } | ||||
| 
 | ||||
| string IRNames::functionWithModifierInner(FunctionDefinition const& _function) | ||||
| std::string IRNames::functionWithModifierInner(FunctionDefinition const& _function) | ||||
| { | ||||
| 	return "fun_" + _function.name() + "_" + to_string(_function.id()) + "_inner"; | ||||
| 	return "fun_" + _function.name() + "_" + std::to_string(_function.id()) + "_inner"; | ||||
| } | ||||
| 
 | ||||
| string IRNames::creationObject(ContractDefinition const& _contract) | ||||
| std::string IRNames::creationObject(ContractDefinition const& _contract) | ||||
| { | ||||
| 	return _contract.name() + "_" + toString(_contract.id()); | ||||
| } | ||||
| 
 | ||||
| string IRNames::deployedObject(ContractDefinition const& _contract) | ||||
| std::string IRNames::deployedObject(ContractDefinition const& _contract) | ||||
| { | ||||
| 	return _contract.name() + "_" + toString(_contract.id()) + "_deployed"; | ||||
| } | ||||
| 
 | ||||
| string IRNames::internalDispatch(YulArity const& _arity) | ||||
| std::string IRNames::internalDispatch(YulArity const& _arity) | ||||
| { | ||||
| 	return "dispatch_internal" | ||||
| 		"_in_" + to_string(_arity.in) + | ||||
| 		"_out_" + to_string(_arity.out); | ||||
| 		"_in_" + std::to_string(_arity.in) + | ||||
| 		"_out_" + std::to_string(_arity.out); | ||||
| } | ||||
| 
 | ||||
| string IRNames::constructor(ContractDefinition const& _contract) | ||||
| std::string IRNames::constructor(ContractDefinition const& _contract) | ||||
| { | ||||
| 	return "constructor_" + _contract.name() + "_" + to_string(_contract.id()); | ||||
| 	return "constructor_" + _contract.name() + "_" + std::to_string(_contract.id()); | ||||
| } | ||||
| 
 | ||||
| string IRNames::libraryAddressImmutable() | ||||
| std::string IRNames::libraryAddressImmutable() | ||||
| { | ||||
| 	return "library_deploy_address"; | ||||
| } | ||||
| 
 | ||||
| string IRNames::constantValueFunction(VariableDeclaration const& _constant) | ||||
| std::string IRNames::constantValueFunction(VariableDeclaration const& _constant) | ||||
| { | ||||
| 	solAssert(_constant.isConstant(), ""); | ||||
| 	return "constant_" + _constant.name() + "_" + to_string(_constant.id()); | ||||
| 	return "constant_" + _constant.name() + "_" + std::to_string(_constant.id()); | ||||
| } | ||||
| 
 | ||||
| string IRNames::localVariable(VariableDeclaration const& _declaration) | ||||
| std::string IRNames::localVariable(VariableDeclaration const& _declaration) | ||||
| { | ||||
| 	return "var_" + _declaration.name() + '_' + std::to_string(_declaration.id()); | ||||
| } | ||||
| 
 | ||||
| string IRNames::localVariable(Expression const& _expression) | ||||
| std::string IRNames::localVariable(Expression const& _expression) | ||||
| { | ||||
| 	return "expr_" + to_string(_expression.id()); | ||||
| 	return "expr_" + std::to_string(_expression.id()); | ||||
| } | ||||
| 
 | ||||
| string IRNames::trySuccessConditionVariable(Expression const& _expression) | ||||
| std::string IRNames::trySuccessConditionVariable(Expression const& _expression) | ||||
| { | ||||
| 	auto annotation = dynamic_cast<FunctionCallAnnotation const*>(&_expression.annotation()); | ||||
| 	solAssert(annotation, ""); | ||||
| 	solAssert(annotation->tryCall, "Parameter must be a FunctionCall with tryCall-annotation set."); | ||||
| 
 | ||||
| 	return "trySuccessCondition_" + to_string(_expression.id()); | ||||
| 	return "trySuccessCondition_" + std::to_string(_expression.id()); | ||||
| } | ||||
| 
 | ||||
| string IRNames::tupleComponent(size_t _i) | ||||
| std::string IRNames::tupleComponent(size_t _i) | ||||
| { | ||||
| 	return "component_" + to_string(_i + 1); | ||||
| 	return "component_" + std::to_string(_i + 1); | ||||
| } | ||||
| 
 | ||||
| string IRNames::zeroValue(Type const& _type, string const& _variableName) | ||||
| std::string IRNames::zeroValue(Type const& _type, std::string const& _variableName) | ||||
| { | ||||
| 	return "zero_" + _type.identifier() + _variableName; | ||||
| } | ||||
| 
 | ||||
| string dispenseLocationComment(langutil::SourceLocation const& _location, IRGenerationContext& _context) | ||||
| std::string dispenseLocationComment(langutil::SourceLocation const& _location, IRGenerationContext& _context) | ||||
| { | ||||
| 	solAssert(_location.sourceName, ""); | ||||
| 	_context.markSourceUsed(*_location.sourceName); | ||||
| 
 | ||||
| 	string debugInfo = AsmPrinter::formatSourceLocation( | ||||
| 	std::string debugInfo = AsmPrinter::formatSourceLocation( | ||||
| 		_location, | ||||
| 		_context.sourceIndices(), | ||||
| 		_context.debugInfoSelection(), | ||||
| @ -154,7 +153,7 @@ string dispenseLocationComment(langutil::SourceLocation const& _location, IRGene | ||||
| 	return debugInfo.empty() ? "" : "/// " + debugInfo; | ||||
| } | ||||
| 
 | ||||
| string dispenseLocationComment(ASTNode const& _node, IRGenerationContext& _context) | ||||
| std::string dispenseLocationComment(ASTNode const& _node, IRGenerationContext& _context) | ||||
| { | ||||
| 	return dispenseLocationComment(_node.location(), _context); | ||||
| } | ||||
|  | ||||
| @ -32,14 +32,13 @@ | ||||
| 
 | ||||
| #include <range/v3/view/map.hpp> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::util; | ||||
| using namespace solidity::frontend; | ||||
| 
 | ||||
| string IRGenerationContext::enqueueFunctionForCodeGeneration(FunctionDefinition const& _function) | ||||
| std::string IRGenerationContext::enqueueFunctionForCodeGeneration(FunctionDefinition const& _function) | ||||
| { | ||||
| 	string name = IRNames::function(_function); | ||||
| 	std::string name = IRNames::function(_function); | ||||
| 
 | ||||
| 	if (!m_functions.contains(name)) | ||||
| 		m_functionGenerationQueue.insert(&_function); | ||||
| @ -121,12 +120,12 @@ void IRGenerationContext::addStateVariable( | ||||
| 	unsigned _byteOffset | ||||
| ) | ||||
| { | ||||
| 	m_stateVariables[&_declaration] = make_pair(std::move(_storageOffset), _byteOffset); | ||||
| 	m_stateVariables[&_declaration] = std::make_pair(std::move(_storageOffset), _byteOffset); | ||||
| } | ||||
| 
 | ||||
| string IRGenerationContext::newYulVariable() | ||||
| std::string IRGenerationContext::newYulVariable() | ||||
| { | ||||
| 	return "_" + to_string(++m_varCounter); | ||||
| 	return "_" + std::to_string(++m_varCounter); | ||||
| } | ||||
| 
 | ||||
| void IRGenerationContext::initializeInternalDispatch(InternalDispatchMap _internalDispatch) | ||||
|  | ||||
| @ -43,18 +43,18 @@ | ||||
| #include <sstream> | ||||
| #include <variant> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::frontend; | ||||
| using namespace solidity::langutil; | ||||
| using namespace solidity::util; | ||||
| using namespace std::string_literals; | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
| 
 | ||||
| void verifyCallGraph( | ||||
| 	set<CallableDeclaration const*, ASTNode::CompareByID> const& _expectedCallables, | ||||
| 	set<FunctionDefinition const*> _generatedFunctions | ||||
| 	std::set<CallableDeclaration const*, ASTNode::CompareByID> const& _expectedCallables, | ||||
| 	std::set<FunctionDefinition const*> _generatedFunctions | ||||
| ) | ||||
| { | ||||
| 	for (auto const& expectedCallable: _expectedCallables) | ||||
| @ -73,47 +73,47 @@ void verifyCallGraph( | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| set<CallableDeclaration const*, ASTNode::CompareByID> collectReachableCallables( | ||||
| std::set<CallableDeclaration const*, ASTNode::CompareByID> collectReachableCallables( | ||||
| 	CallGraph const& _graph | ||||
| ) | ||||
| { | ||||
| 	set<CallableDeclaration const*, ASTNode::CompareByID> reachableCallables; | ||||
| 	std::set<CallableDeclaration const*, ASTNode::CompareByID> reachableCallables; | ||||
| 	for (CallGraph::Node const& reachableNode: _graph.edges | ranges::views::keys) | ||||
| 		if (holds_alternative<CallableDeclaration const*>(reachableNode)) | ||||
| 			reachableCallables.emplace(get<CallableDeclaration const*>(reachableNode)); | ||||
| 		if (std::holds_alternative<CallableDeclaration const*>(reachableNode)) | ||||
| 			reachableCallables.emplace(std::get<CallableDeclaration const*>(reachableNode)); | ||||
| 
 | ||||
| 	return reachableCallables; | ||||
| } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::run( | ||||
| std::string IRGenerator::run( | ||||
| 	ContractDefinition const& _contract, | ||||
| 	bytes const& _cborMetadata, | ||||
| 	map<ContractDefinition const*, string_view const> const& _otherYulSources | ||||
| 	std::map<ContractDefinition const*, std::string_view const> const& _otherYulSources | ||||
| ) | ||||
| { | ||||
| 	return yul::reindent(generate(_contract, _cborMetadata, _otherYulSources)); | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::generate( | ||||
| std::string IRGenerator::generate( | ||||
| 	ContractDefinition const& _contract, | ||||
| 	bytes const& _cborMetadata, | ||||
| 	map<ContractDefinition const*, string_view const> const& _otherYulSources | ||||
| 	std::map<ContractDefinition const*, std::string_view const> const& _otherYulSources | ||||
| ) | ||||
| { | ||||
| 	auto subObjectSources = [&_otherYulSources](std::set<ContractDefinition const*, ASTNode::CompareByID> const& subObjects) -> string | ||||
| 	auto subObjectSources = [&_otherYulSources](std::set<ContractDefinition const*, ASTNode::CompareByID> const& subObjects) -> std::string | ||||
| 	{ | ||||
| 		std::string subObjectsSources; | ||||
| 		for (ContractDefinition const* subObject: subObjects) | ||||
| 			subObjectsSources += _otherYulSources.at(subObject); | ||||
| 		return subObjectsSources; | ||||
| 	}; | ||||
| 	auto formatUseSrcMap = [](IRGenerationContext const& _context) -> string | ||||
| 	auto formatUseSrcMap = [](IRGenerationContext const& _context) -> std::string | ||||
| 	{ | ||||
| 		return joinHumanReadable( | ||||
| 			ranges::views::transform(_context.usedSourceNames(), [_context](string const& _sourceName) { | ||||
| 				return to_string(_context.sourceIndices().at(_sourceName)) + ":" + escapeAndQuoteString(_sourceName); | ||||
| 			ranges::views::transform(_context.usedSourceNames(), [_context](std::string const& _sourceName) { | ||||
| 				return std::to_string(_context.sourceIndices().at(_sourceName)) + ":" + escapeAndQuoteString(_sourceName); | ||||
| 			}), | ||||
| 			", " | ||||
| 		); | ||||
| @ -162,7 +162,7 @@ string IRGenerator::generate( | ||||
| 
 | ||||
| 	FunctionDefinition const* constructor = _contract.constructor(); | ||||
| 	t("callValueCheck", !constructor || !constructor->isPayable() ? callValueCheck() : ""); | ||||
| 	vector<string> constructorParams; | ||||
| 	std::vector<std::string> constructorParams; | ||||
| 	if (constructor && !constructor->parameters().empty()) | ||||
| 	{ | ||||
| 		for (size_t i = 0; i < CompilerUtils::sizeOnStack(constructor->parameters()); ++i) | ||||
| @ -178,7 +178,7 @@ string IRGenerator::generate( | ||||
| 
 | ||||
| 	t("deploy", deployCode(_contract)); | ||||
| 	generateConstructors(_contract); | ||||
| 	set<FunctionDefinition const*> creationFunctionList = generateQueuedFunctions(); | ||||
| 	std::set<FunctionDefinition const*> creationFunctionList = generateQueuedFunctions(); | ||||
| 	InternalDispatchMap internalDispatchMap = generateInternalDispatchFunctions(_contract); | ||||
| 
 | ||||
| 	t("functions", m_context.functionCollector().requestedFunctions()); | ||||
| @ -201,7 +201,7 @@ string IRGenerator::generate( | ||||
| 	t("sourceLocationCommentDeployed", dispenseLocationComment(_contract)); | ||||
| 	t("library_address", IRNames::libraryAddressImmutable()); | ||||
| 	t("dispatch", dispatchRoutine(_contract)); | ||||
| 	set<FunctionDefinition const*> deployedFunctionList = generateQueuedFunctions(); | ||||
| 	std::set<FunctionDefinition const*> deployedFunctionList = generateQueuedFunctions(); | ||||
| 	generateInternalDispatchFunctions(_contract); | ||||
| 	t("deployedFunctions", m_context.functionCollector().requestedFunctions()); | ||||
| 	t("deployedSubObjects", subObjectSources(m_context.subObjectsCreated())); | ||||
| @ -222,16 +222,16 @@ string IRGenerator::generate( | ||||
| 	return t.render(); | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::generate(Block const& _block) | ||||
| std::string IRGenerator::generate(Block const& _block) | ||||
| { | ||||
| 	IRGeneratorForStatements generator(m_context, m_utils); | ||||
| 	generator.generate(_block); | ||||
| 	return generator.code(); | ||||
| } | ||||
| 
 | ||||
| set<FunctionDefinition const*> IRGenerator::generateQueuedFunctions() | ||||
| std::set<FunctionDefinition const*> IRGenerator::generateQueuedFunctions() | ||||
| { | ||||
| 	set<FunctionDefinition const*> functions; | ||||
| 	std::set<FunctionDefinition const*> functions; | ||||
| 
 | ||||
| 	while (!m_context.functionGenerationQueueEmpty()) | ||||
| 	{ | ||||
| @ -256,7 +256,7 @@ InternalDispatchMap IRGenerator::generateInternalDispatchFunctions(ContractDefin | ||||
| 	InternalDispatchMap internalDispatchMap = m_context.consumeInternalDispatchMap(); | ||||
| 	for (YulArity const& arity: internalDispatchMap | ranges::views::keys) | ||||
| 	{ | ||||
| 		string funName = IRNames::internalDispatch(arity); | ||||
| 		std::string funName = IRNames::internalDispatch(arity); | ||||
| 		m_context.functionCollector().createFunction(funName, [&]() { | ||||
| 			Whiskers templ(R"( | ||||
| 				<sourceLocationComment> | ||||
| @ -278,7 +278,7 @@ InternalDispatchMap IRGenerator::generateInternalDispatchFunctions(ContractDefin | ||||
| 			templ("in", suffixedVariableNameList("in_", 0, arity.in)); | ||||
| 			templ("out", suffixedVariableNameList("out_", 0, arity.out)); | ||||
| 
 | ||||
| 			vector<map<string, string>> cases; | ||||
| 			std::vector<std::map<std::string, std::string>> cases; | ||||
| 			for (FunctionDefinition const* function: internalDispatchMap.at(arity)) | ||||
| 			{ | ||||
| 				solAssert(function, ""); | ||||
| @ -291,8 +291,8 @@ InternalDispatchMap IRGenerator::generateInternalDispatchFunctions(ContractDefin | ||||
| 				solAssert(function->id() != 0, "Unexpected function ID: 0"); | ||||
| 				solAssert(m_context.functionCollector().contains(IRNames::function(*function)), ""); | ||||
| 
 | ||||
| 				cases.emplace_back(map<string, string>{ | ||||
| 					{"funID", to_string(m_context.mostDerivedContract().annotation().internalFunctionIDs.at(function))}, | ||||
| 				cases.emplace_back(std::map<std::string, std::string>{ | ||||
| 					{"funID", std::to_string(m_context.mostDerivedContract().annotation().internalFunctionIDs.at(function))}, | ||||
| 					{"name", IRNames::function(*function)} | ||||
| 				}); | ||||
| 			} | ||||
| @ -311,9 +311,9 @@ InternalDispatchMap IRGenerator::generateInternalDispatchFunctions(ContractDefin | ||||
| 	return internalDispatchMap; | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::generateFunction(FunctionDefinition const& _function) | ||||
| std::string IRGenerator::generateFunction(FunctionDefinition const& _function) | ||||
| { | ||||
| 	string functionName = IRNames::function(_function); | ||||
| 	std::string functionName = IRNames::function(_function); | ||||
| 	return m_context.functionCollector().createFunction(functionName, [&]() { | ||||
| 		m_context.resetLocalVariables(); | ||||
| 		Whiskers t(R"( | ||||
| @ -326,7 +326,7 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function) | ||||
| 		)"); | ||||
| 
 | ||||
| 		if (m_context.debugInfoSelection().astID) | ||||
| 			t("astIDComment", "/// @ast-id " + to_string(_function.id()) + "\n"); | ||||
| 			t("astIDComment", "/// @ast-id " + std::to_string(_function.id()) + "\n"); | ||||
| 		else | ||||
| 			t("astIDComment", ""); | ||||
| 		t("sourceLocationComment", dispenseLocationComment(_function)); | ||||
| @ -336,12 +336,12 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function) | ||||
| 		); | ||||
| 
 | ||||
| 		t("functionName", functionName); | ||||
| 		vector<string> params; | ||||
| 		std::vector<std::string> params; | ||||
| 		for (auto const& varDecl: _function.parameters()) | ||||
| 			params += m_context.addLocalVariable(*varDecl).stackSlots(); | ||||
| 		t("params", joinHumanReadable(params)); | ||||
| 		vector<string> retParams; | ||||
| 		string retInit; | ||||
| 		std::vector<std::string> retParams; | ||||
| 		std::string retInit; | ||||
| 		for (auto const& varDecl: _function.returnParameters()) | ||||
| 		{ | ||||
| 			retParams += m_context.addLocalVariable(*varDecl).stackSlots(); | ||||
| @ -358,14 +358,14 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function) | ||||
| 			for (size_t i = 0; i < _function.modifiers().size(); ++i) | ||||
| 			{ | ||||
| 				ModifierInvocation const& modifier = *_function.modifiers().at(i); | ||||
| 				string next = | ||||
| 				std::string next = | ||||
| 					i + 1 < _function.modifiers().size() ? | ||||
| 					IRNames::modifierInvocation(*_function.modifiers().at(i + 1)) : | ||||
| 					IRNames::functionWithModifierInner(_function); | ||||
| 				generateModifier(modifier, _function, next); | ||||
| 			} | ||||
| 			t("body", | ||||
| 				(retParams.empty() ? string{} : joinHumanReadable(retParams) + " := ") + | ||||
| 				(retParams.empty() ? std::string{} : joinHumanReadable(retParams) + " := ") + | ||||
| 				IRNames::modifierInvocation(*_function.modifiers().at(0)) + | ||||
| 				"(" + | ||||
| 				joinHumanReadable(retParams + params) + | ||||
| @ -378,13 +378,13 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function) | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::generateModifier( | ||||
| std::string IRGenerator::generateModifier( | ||||
| 	ModifierInvocation const& _modifierInvocation, | ||||
| 	FunctionDefinition const& _function, | ||||
| 	string const& _nextFunction | ||||
| 	std::string const& _nextFunction | ||||
| ) | ||||
| { | ||||
| 	string functionName = IRNames::modifierInvocation(_modifierInvocation); | ||||
| 	std::string functionName = IRNames::modifierInvocation(_modifierInvocation); | ||||
| 	return m_context.functionCollector().createFunction(functionName, [&]() { | ||||
| 		m_context.resetLocalVariables(); | ||||
| 		Whiskers t(R"( | ||||
| @ -398,15 +398,15 @@ string IRGenerator::generateModifier( | ||||
| 		)"); | ||||
| 
 | ||||
| 		t("functionName", functionName); | ||||
| 		vector<string> retParamsIn; | ||||
| 		std::vector<std::string> retParamsIn; | ||||
| 		for (auto const& varDecl: _function.returnParameters()) | ||||
| 			retParamsIn += m_context.addLocalVariable(*varDecl).stackSlots(); | ||||
| 		vector<string> params = retParamsIn; | ||||
| 		std::vector<std::string> params = retParamsIn; | ||||
| 		for (auto const& varDecl: _function.parameters()) | ||||
| 			params += m_context.addLocalVariable(*varDecl).stackSlots(); | ||||
| 		t("params", joinHumanReadable(params)); | ||||
| 		vector<string> retParams; | ||||
| 		string assignRetParams; | ||||
| 		std::vector<std::string> retParams; | ||||
| 		std::string assignRetParams; | ||||
| 		for (size_t i = 0; i < retParamsIn.size(); ++i) | ||||
| 		{ | ||||
| 			retParams.emplace_back(m_context.newYulVariable()); | ||||
| @ -421,7 +421,7 @@ string IRGenerator::generateModifier( | ||||
| 		solAssert(modifier, ""); | ||||
| 
 | ||||
| 		if (m_context.debugInfoSelection().astID) | ||||
| 			t("astIDComment", "/// @ast-id " + to_string(modifier->id()) + "\n"); | ||||
| 			t("astIDComment", "/// @ast-id " + std::to_string(modifier->id()) + "\n"); | ||||
| 		else | ||||
| 			t("astIDComment", ""); | ||||
| 		t("sourceLocationComment", dispenseLocationComment(*modifier)); | ||||
| @ -463,7 +463,7 @@ string IRGenerator::generateModifier( | ||||
| 
 | ||||
| 		t("evalArgs", expressionEvaluator.code()); | ||||
| 		IRGeneratorForStatements generator(m_context, m_utils, [&]() { | ||||
| 			string ret = joinHumanReadable(retParams); | ||||
| 			std::string ret = joinHumanReadable(retParams); | ||||
| 			return | ||||
| 				(ret.empty() ? "" : ret + " := ") + | ||||
| 				_nextFunction + "(" + joinHumanReadable(params) + ")\n"; | ||||
| @ -474,9 +474,9 @@ string IRGenerator::generateModifier( | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::generateFunctionWithModifierInner(FunctionDefinition const& _function) | ||||
| std::string IRGenerator::generateFunctionWithModifierInner(FunctionDefinition const& _function) | ||||
| { | ||||
| 	string functionName = IRNames::functionWithModifierInner(_function); | ||||
| 	std::string functionName = IRNames::functionWithModifierInner(_function); | ||||
| 	return m_context.functionCollector().createFunction(functionName, [&]() { | ||||
| 		m_context.resetLocalVariables(); | ||||
| 		Whiskers t(R"( | ||||
| @ -493,17 +493,17 @@ string IRGenerator::generateFunctionWithModifierInner(FunctionDefinition const& | ||||
| 			dispenseLocationComment(m_context.mostDerivedContract()) | ||||
| 		); | ||||
| 		t("functionName", functionName); | ||||
| 		vector<string> retParams; | ||||
| 		vector<string> retParamsIn; | ||||
| 		std::vector<std::string> retParams; | ||||
| 		std::vector<std::string> retParamsIn; | ||||
| 		for (auto const& varDecl: _function.returnParameters()) | ||||
| 			retParams += m_context.addLocalVariable(*varDecl).stackSlots(); | ||||
| 		string assignRetParams; | ||||
| 		std::string assignRetParams; | ||||
| 		for (size_t i = 0; i < retParams.size(); ++i) | ||||
| 		{ | ||||
| 			retParamsIn.emplace_back(m_context.newYulVariable()); | ||||
| 			assignRetParams += retParams.at(i) + " := " + retParamsIn.at(i) + "\n"; | ||||
| 		} | ||||
| 		vector<string> params = retParamsIn; | ||||
| 		std::vector<std::string> params = retParamsIn; | ||||
| 		for (auto const& varDecl: _function.parameters()) | ||||
| 			params += m_context.addLocalVariable(*varDecl).stackSlots(); | ||||
| 		t("params", joinHumanReadable(params)); | ||||
| @ -514,9 +514,9 @@ string IRGenerator::generateFunctionWithModifierInner(FunctionDefinition const& | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| std::string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| { | ||||
| 	string functionName = IRNames::function(_varDecl); | ||||
| 	std::string functionName = IRNames::function(_varDecl); | ||||
| 	return m_context.functionCollector().createFunction(functionName, [&]() { | ||||
| 		Type const* type = _varDecl.annotation().type; | ||||
| 
 | ||||
| @ -538,7 +538,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| 			( | ||||
| 				"astIDComment", | ||||
| 				m_context.debugInfoSelection().astID ? | ||||
| 					"/// @ast-id " + to_string(_varDecl.id()) + "\n" : | ||||
| 					"/// @ast-id " + std::to_string(_varDecl.id()) + "\n" : | ||||
| 					"" | ||||
| 			) | ||||
| 			("sourceLocationComment", dispenseLocationComment(_varDecl)) | ||||
| @ -547,7 +547,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| 				dispenseLocationComment(m_context.mostDerivedContract()) | ||||
| 			) | ||||
| 			("functionName", functionName) | ||||
| 			("id", to_string(_varDecl.id())) | ||||
| 			("id", std::to_string(_varDecl.id())) | ||||
| 			.render(); | ||||
| 		} | ||||
| 		else if (_varDecl.isConstant()) | ||||
| @ -563,7 +563,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| 			( | ||||
| 				"astIDComment", | ||||
| 				m_context.debugInfoSelection().astID ? | ||||
| 					"/// @ast-id " + to_string(_varDecl.id()) + "\n" : | ||||
| 					"/// @ast-id " + std::to_string(_varDecl.id()) + "\n" : | ||||
| 					"" | ||||
| 			) | ||||
| 			("sourceLocationComment", dispenseLocationComment(_varDecl)) | ||||
| @ -577,7 +577,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| 			.render(); | ||||
| 		} | ||||
| 
 | ||||
| 		string code; | ||||
| 		std::string code; | ||||
| 
 | ||||
| 		auto const& location = m_context.storageLocationOfStateVariable(_varDecl); | ||||
| 		code += Whiskers(R"( | ||||
| @ -585,7 +585,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| 			let offset := <offset> | ||||
| 		)") | ||||
| 		("slot", location.first.str()) | ||||
| 		("offset", to_string(location.second)) | ||||
| 		("offset", std::to_string(location.second)) | ||||
| 		.render(); | ||||
| 
 | ||||
| 		if (!paramTypes.empty()) | ||||
| @ -601,8 +601,8 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| 		// The initial value of @a currentType is only used if we skip the loop completely.
 | ||||
| 		Type const* currentType = _varDecl.annotation().type; | ||||
| 
 | ||||
| 		vector<string> parameters; | ||||
| 		vector<string> returnVariables; | ||||
| 		std::vector<std::string> parameters; | ||||
| 		std::vector<std::string> returnVariables; | ||||
| 
 | ||||
| 		for (size_t i = 0; i < paramTypes.size(); ++i) | ||||
| 		{ | ||||
| @ -610,7 +610,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| 			ArrayType const* arrayType = dynamic_cast<ArrayType const*>(currentType); | ||||
| 			solAssert(mappingType || arrayType, ""); | ||||
| 
 | ||||
| 			vector<string> keys = IRVariable("key_" + to_string(i), | ||||
| 			std::vector<std::string> keys = IRVariable("key_" + std::to_string(i), | ||||
| 				mappingType ? *mappingType->keyType() : *TypeProvider::uint256() | ||||
| 			).stackSlots(); | ||||
| 			parameters += keys; | ||||
| @ -653,8 +653,8 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| 				) | ||||
| 					continue; | ||||
| 
 | ||||
| 				pair<u256, unsigned> const& offsets = structType->storageOffsetsOfMember(names[i]); | ||||
| 				vector<string> retVars = IRVariable("ret_" + to_string(returnVariables.size()), *returnTypes[i]).stackSlots(); | ||||
| 				std::pair<u256, unsigned> const& offsets = structType->storageOffsetsOfMember(names[i]); | ||||
| 				std::vector<std::string> retVars = IRVariable("ret_" + std::to_string(returnVariables.size()), *returnTypes[i]).stackSlots(); | ||||
| 				returnVariables += retVars; | ||||
| 				code += Whiskers(R"( | ||||
| 					<ret> := <readStorage>(add(slot, <slotOffset>)) | ||||
| @ -671,7 +671,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| 			auto const* arrayType = dynamic_cast<ArrayType const*>(returnTypes.front()); | ||||
| 			if (arrayType) | ||||
| 				solAssert(arrayType->isByteArrayOrString(), ""); | ||||
| 			vector<string> retVars = IRVariable("ret", *returnTypes.front()).stackSlots(); | ||||
| 			std::vector<std::string> retVars = IRVariable("ret", *returnTypes.front()).stackSlots(); | ||||
| 			returnVariables += retVars; | ||||
| 			code += Whiskers(R"( | ||||
| 				<ret> := <readStorage>(slot, offset) | ||||
| @ -695,7 +695,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| 		( | ||||
| 			"astIDComment", | ||||
| 			m_context.debugInfoSelection().astID ? | ||||
| 				"/// @ast-id " + to_string(_varDecl.id()) + "\n" : | ||||
| 				"/// @ast-id " + std::to_string(_varDecl.id()) + "\n" : | ||||
| 				"" | ||||
| 		) | ||||
| 		("sourceLocationComment", dispenseLocationComment(_varDecl)) | ||||
| @ -707,10 +707,10 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::generateExternalFunction(ContractDefinition const& _contract, FunctionType const& _functionType) | ||||
| std::string IRGenerator::generateExternalFunction(ContractDefinition const& _contract, FunctionType const& _functionType) | ||||
| { | ||||
| 	string functionName = IRNames::externalFunctionABIWrapper(_functionType.declaration()); | ||||
| 	return m_context.functionCollector().createFunction(functionName, [&](vector<string>&, vector<string>&) -> string { | ||||
| 	std::string functionName = IRNames::externalFunctionABIWrapper(_functionType.declaration()); | ||||
| 	return m_context.functionCollector().createFunction(functionName, [&](std::vector<std::string>&, std::vector<std::string>&) -> std::string { | ||||
| 		Whiskers t(R"X( | ||||
| 			<callValueCheck> | ||||
| 			<?+params>let <params> := </+params> <abiDecode>(4, calldatasize()) | ||||
| @ -721,8 +721,8 @@ string IRGenerator::generateExternalFunction(ContractDefinition const& _contract | ||||
| 		)X"); | ||||
| 		t("callValueCheck", (_functionType.isPayable() || _contract.isLibrary()) ? "" : callValueCheck()); | ||||
| 
 | ||||
| 		unsigned paramVars = make_shared<TupleType>(_functionType.parameterTypes())->sizeOnStack(); | ||||
| 		unsigned retVars = make_shared<TupleType>(_functionType.returnParameterTypes())->sizeOnStack(); | ||||
| 		unsigned paramVars = std::make_shared<TupleType>(_functionType.parameterTypes())->sizeOnStack(); | ||||
| 		unsigned retVars = std::make_shared<TupleType>(_functionType.returnParameterTypes())->sizeOnStack(); | ||||
| 
 | ||||
| 		ABIFunctions abiFunctions(m_evmVersion, m_context.revertStrings(), m_context.functionCollector()); | ||||
| 		t("abiDecode", abiFunctions.tupleDecoder(_functionType.parameterTypes())); | ||||
| @ -745,14 +745,14 @@ string IRGenerator::generateExternalFunction(ContractDefinition const& _contract | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::generateInitialAssignment(VariableDeclaration const& _varDecl) | ||||
| std::string IRGenerator::generateInitialAssignment(VariableDeclaration const& _varDecl) | ||||
| { | ||||
| 	IRGeneratorForStatements generator(m_context, m_utils); | ||||
| 	generator.initializeLocalVar(_varDecl); | ||||
| 	return generator.code(); | ||||
| } | ||||
| 
 | ||||
| pair<string, map<ContractDefinition const*, vector<string>>> IRGenerator::evaluateConstructorArguments( | ||||
| std::pair<std::string, std::map<ContractDefinition const*, std::vector<std::string>>> IRGenerator::evaluateConstructorArguments( | ||||
| 	ContractDefinition const& _contract | ||||
| ) | ||||
| { | ||||
| @ -765,12 +765,12 @@ pair<string, map<ContractDefinition const*, vector<string>>> IRGenerator::evalua | ||||
| 			auto it2 = find(linearizedBaseContracts.begin(), linearizedBaseContracts.end(), _c2); | ||||
| 			return it1 < it2; | ||||
| 		} | ||||
| 		vector<ContractDefinition const*> const& linearizedBaseContracts; | ||||
| 		std::vector<ContractDefinition const*> const& linearizedBaseContracts; | ||||
| 	} inheritanceOrder{_contract.annotation().linearizedBaseContracts}; | ||||
| 
 | ||||
| 	map<ContractDefinition const*, vector<string>> constructorParams; | ||||
| 	std::map<ContractDefinition const*, std::vector<std::string>> constructorParams; | ||||
| 
 | ||||
| 	map<ContractDefinition const*, std::vector<ASTPointer<Expression>>const *, InheritanceOrder> | ||||
| 	std::map<ContractDefinition const*, std::vector<ASTPointer<Expression>>const *, InheritanceOrder> | ||||
| 		baseConstructorArguments(inheritanceOrder); | ||||
| 
 | ||||
| 	for (ASTPointer<InheritanceSpecifier> const& base: _contract.baseContracts()) | ||||
| @ -802,7 +802,7 @@ pair<string, map<ContractDefinition const*, vector<string>>> IRGenerator::evalua | ||||
| 		solAssert(baseContract && arguments, ""); | ||||
| 		if (baseContract->constructor() && !arguments->empty()) | ||||
| 		{ | ||||
| 			vector<string> params; | ||||
| 			std::vector<std::string> params; | ||||
| 			for (size_t i = 0; i < arguments->size(); ++i) | ||||
| 				params += generator.evaluateExpression( | ||||
| 					*(arguments->at(i)), | ||||
| @ -815,7 +815,7 @@ pair<string, map<ContractDefinition const*, vector<string>>> IRGenerator::evalua | ||||
| 	return {generator.code(), constructorParams}; | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::initStateVariables(ContractDefinition const& _contract) | ||||
| std::string IRGenerator::initStateVariables(ContractDefinition const& _contract) | ||||
| { | ||||
| 	IRGeneratorForStatements generator{m_context, m_utils}; | ||||
| 	for (VariableDeclaration const* variable: _contract.stateVariables()) | ||||
| @ -829,16 +829,16 @@ string IRGenerator::initStateVariables(ContractDefinition const& _contract) | ||||
| void IRGenerator::generateConstructors(ContractDefinition const& _contract) | ||||
| { | ||||
| 	auto listAllParams = | ||||
| 		[&](map<ContractDefinition const*, vector<string>> const& baseParams) -> vector<string> | ||||
| 		[&](std::map<ContractDefinition const*, std::vector<std::string>> const& baseParams) -> std::vector<std::string> | ||||
| 		{ | ||||
| 			vector<string> params; | ||||
| 			std::vector<std::string> params; | ||||
| 			for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts) | ||||
| 				if (baseParams.count(contract)) | ||||
| 					params += baseParams.at(contract); | ||||
| 			return params; | ||||
| 		}; | ||||
| 
 | ||||
| 	map<ContractDefinition const*, vector<string>> baseConstructorParams; | ||||
| 	std::map<ContractDefinition const*, std::vector<std::string>> baseConstructorParams; | ||||
| 	for (size_t i = 0; i < _contract.annotation().linearizedBaseContracts.size(); ++i) | ||||
| 	{ | ||||
| 		ContractDefinition const* contract = _contract.annotation().linearizedBaseContracts[i]; | ||||
| @ -857,13 +857,13 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract) | ||||
| 				} | ||||
| 				<contractSourceLocationComment> | ||||
| 			)"); | ||||
| 			vector<string> params; | ||||
| 			std::vector<std::string> params; | ||||
| 			if (contract->constructor()) | ||||
| 				for (ASTPointer<VariableDeclaration> const& varDecl: contract->constructor()->parameters()) | ||||
| 					params += m_context.addLocalVariable(*varDecl).stackSlots(); | ||||
| 
 | ||||
| 			if (m_context.debugInfoSelection().astID && contract->constructor()) | ||||
| 				t("astIDComment", "/// @ast-id " + to_string(contract->constructor()->id()) + "\n"); | ||||
| 				t("astIDComment", "/// @ast-id " + std::to_string(contract->constructor()->id()) + "\n"); | ||||
| 			else | ||||
| 				t("astIDComment", ""); | ||||
| 			t("sourceLocationComment", dispenseLocationComment( | ||||
| @ -877,11 +877,11 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract) | ||||
| 			); | ||||
| 
 | ||||
| 			t("params", joinHumanReadable(params)); | ||||
| 			vector<string> baseParams = listAllParams(baseConstructorParams); | ||||
| 			std::vector<std::string> baseParams = listAllParams(baseConstructorParams); | ||||
| 			t("baseParams", joinHumanReadable(baseParams)); | ||||
| 			t("comma", !params.empty() && !baseParams.empty() ? ", " : ""); | ||||
| 			t("functionName", IRNames::constructor(*contract)); | ||||
| 			pair<string, map<ContractDefinition const*, vector<string>>> evaluatedArgs = evaluateConstructorArguments(*contract); | ||||
| 			std::pair<std::string, std::map<ContractDefinition const*, std::vector<std::string>>> evaluatedArgs = evaluateConstructorArguments(*contract); | ||||
| 			baseConstructorParams.insert(evaluatedArgs.second.begin(), evaluatedArgs.second.end()); | ||||
| 			t("evalBaseArguments", evaluatedArgs.first); | ||||
| 			if (i < _contract.annotation().linearizedBaseContracts.size() - 1) | ||||
| @ -894,10 +894,10 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract) | ||||
| 			else | ||||
| 				t("hasNextConstructor", false); | ||||
| 			t("initStateVariables", initStateVariables(*contract)); | ||||
| 			string body; | ||||
| 			std::string body; | ||||
| 			if (FunctionDefinition const* constructor = contract->constructor()) | ||||
| 			{ | ||||
| 				vector<ModifierInvocation*> realModifiers; | ||||
| 				std::vector<ModifierInvocation*> realModifiers; | ||||
| 				for (auto const& modifierInvocation: constructor->modifiers()) | ||||
| 					// Filter out the base constructor calls
 | ||||
| 					if (dynamic_cast<ModifierDefinition const*>(modifierInvocation->name().annotation().referencedDeclaration)) | ||||
| @ -909,7 +909,7 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract) | ||||
| 					for (size_t i = 0; i < realModifiers.size(); ++i) | ||||
| 					{ | ||||
| 						ModifierInvocation const& modifier = *realModifiers.at(i); | ||||
| 						string next = | ||||
| 						std::string next = | ||||
| 							i + 1 < realModifiers.size() ? | ||||
| 							IRNames::modifierInvocation(*realModifiers.at(i + 1)) : | ||||
| 							IRNames::functionWithModifierInner(*constructor); | ||||
| @ -931,7 +931,7 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::deployCode(ContractDefinition const& _contract) | ||||
| std::string IRGenerator::deployCode(ContractDefinition const& _contract) | ||||
| { | ||||
| 	Whiskers t(R"X( | ||||
| 		let <codeOffset> := <allocateUnbounded>() | ||||
| @ -945,11 +945,11 @@ string IRGenerator::deployCode(ContractDefinition const& _contract) | ||||
| 	t("codeOffset", m_context.newYulVariable()); | ||||
| 	t("object", IRNames::deployedObject(_contract)); | ||||
| 
 | ||||
| 	vector<map<string, string>> immutables; | ||||
| 	std::vector<std::map<std::string, std::string>> immutables; | ||||
| 	if (_contract.isLibrary()) | ||||
| 	{ | ||||
| 		solAssert(ContractType(_contract).immutableVariables().empty(), ""); | ||||
| 		immutables.emplace_back(map<string, string>{ | ||||
| 		immutables.emplace_back(std::map<std::string, std::string>{ | ||||
| 			{"immutableName"s, IRNames::libraryAddressImmutable()}, | ||||
| 			{"value"s, "address()"} | ||||
| 		}); | ||||
| @ -960,21 +960,21 @@ string IRGenerator::deployCode(ContractDefinition const& _contract) | ||||
| 		{ | ||||
| 			solUnimplementedAssert(immutable->type()->isValueType()); | ||||
| 			solUnimplementedAssert(immutable->type()->sizeOnStack() == 1); | ||||
| 			immutables.emplace_back(map<string, string>{ | ||||
| 				{"immutableName"s, to_string(immutable->id())}, | ||||
| 				{"value"s, "mload(" + to_string(m_context.immutableMemoryOffset(*immutable)) + ")"} | ||||
| 			immutables.emplace_back(std::map<std::string, std::string>{ | ||||
| 				{"immutableName"s, std::to_string(immutable->id())}, | ||||
| 				{"value"s, "mload(" + std::to_string(m_context.immutableMemoryOffset(*immutable)) + ")"} | ||||
| 			}); | ||||
| 		} | ||||
| 	t("immutables", std::move(immutables)); | ||||
| 	return t.render(); | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::callValueCheck() | ||||
| std::string IRGenerator::callValueCheck() | ||||
| { | ||||
| 	return "if callvalue() { " + m_utils.revertReasonIfDebugFunction("Ether sent to non-payable function") + "() }"; | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::dispatchRoutine(ContractDefinition const& _contract) | ||||
| std::string IRGenerator::dispatchRoutine(ContractDefinition const& _contract) | ||||
| { | ||||
| 	Whiskers t(R"X( | ||||
| 		<?+cases>if iszero(lt(calldatasize(), 4)) | ||||
| @ -995,15 +995,15 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract) | ||||
| 		<fallback> | ||||
| 	)X"); | ||||
| 	t("shr224", m_utils.shiftRightFunction(224)); | ||||
| 	vector<map<string, string>> functions; | ||||
| 	std::vector<std::map<std::string, std::string>> functions; | ||||
| 	for (auto const& function: _contract.interfaceFunctions()) | ||||
| 	{ | ||||
| 		functions.emplace_back(); | ||||
| 		map<string, string>& templ = functions.back(); | ||||
| 		std::map<std::string, std::string>& templ = functions.back(); | ||||
| 		templ["functionSelector"] = "0x" + function.first.hex(); | ||||
| 		FunctionTypePointer const& type = function.second; | ||||
| 		templ["functionName"] = type->externalSignature(); | ||||
| 		string delegatecallCheck; | ||||
| 		std::string delegatecallCheck; | ||||
| 		if (_contract.isLibrary()) | ||||
| 		{ | ||||
| 			solAssert(!type->isPayable(), ""); | ||||
| @ -1031,7 +1031,7 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract) | ||||
| 	if (FunctionDefinition const* fallback = _contract.fallbackFunction()) | ||||
| 	{ | ||||
| 		solAssert(!_contract.isLibrary(), ""); | ||||
| 		string fallbackCode; | ||||
| 		std::string fallbackCode; | ||||
| 		if (!fallback->isPayable()) | ||||
| 			fallbackCode += callValueCheck() + "\n"; | ||||
| 		if (fallback->parameters().empty()) | ||||
| @ -1055,7 +1055,7 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract) | ||||
| 	return t.render(); | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::memoryInit(bool _useMemoryGuard) | ||||
| std::string IRGenerator::memoryInit(bool _useMemoryGuard) | ||||
| { | ||||
| 	// This function should be called at the beginning of the EVM call frame
 | ||||
| 	// and thus can assume all memory to be zero, including the contents of
 | ||||
| @ -1066,10 +1066,10 @@ string IRGenerator::memoryInit(bool _useMemoryGuard) | ||||
| 			"mstore(<memPtr>, memoryguard(<freeMemoryStart>))" : | ||||
| 			"mstore(<memPtr>, <freeMemoryStart>)" | ||||
| 		} | ||||
| 		("memPtr", to_string(CompilerUtils::freeMemoryPointer)) | ||||
| 		("memPtr", std::to_string(CompilerUtils::freeMemoryPointer)) | ||||
| 		( | ||||
| 			"freeMemoryStart", | ||||
| 			to_string(CompilerUtils::generalPurposeMemoryStart + m_context.reservedMemory()) | ||||
| 			std::to_string(CompilerUtils::generalPurposeMemoryStart + m_context.reservedMemory()) | ||||
| 		).render(); | ||||
| } | ||||
| 
 | ||||
| @ -1099,10 +1099,10 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon | ||||
| 
 | ||||
| 	m_context.setMostDerivedContract(_contract); | ||||
| 	for (auto const& var: ContractType(_contract).stateVariables()) | ||||
| 		m_context.addStateVariable(*get<0>(var), get<1>(var), get<2>(var)); | ||||
| 		m_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var)); | ||||
| } | ||||
| 
 | ||||
| string IRGenerator::dispenseLocationComment(ASTNode const& _node) | ||||
| std::string IRGenerator::dispenseLocationComment(ASTNode const& _node) | ||||
| { | ||||
| 	return ::dispenseLocationComment(_node, m_context); | ||||
| } | ||||
|  | ||||
| @ -49,7 +49,6 @@ | ||||
| 
 | ||||
| #include <range/v3/view/transform.hpp> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::util; | ||||
| using namespace solidity::frontend; | ||||
| @ -95,8 +94,8 @@ struct CopyTranslate: public yul::ASTCopier | ||||
| 			return ASTCopier::translate(_identifier); | ||||
| 
 | ||||
| 		yul::Expression translated = translateReference(_identifier); | ||||
| 		solAssert(holds_alternative<yul::Identifier>(translated)); | ||||
| 		return get<yul::Identifier>(std::move(translated)); | ||||
| 		solAssert(std::holds_alternative<yul::Identifier>(translated)); | ||||
| 		return std::get<yul::Identifier>(std::move(translated)); | ||||
| 	} | ||||
| 
 | ||||
| private: | ||||
| @ -109,9 +108,9 @@ private: | ||||
| 		auto const& reference = m_references.at(&_identifier); | ||||
| 		auto const varDecl = dynamic_cast<VariableDeclaration const*>(reference.declaration); | ||||
| 		solUnimplementedAssert(varDecl); | ||||
| 		string const& suffix = reference.suffix; | ||||
| 		std::string const& suffix = reference.suffix; | ||||
| 
 | ||||
| 		string value; | ||||
| 		std::string value; | ||||
| 		if (suffix.empty() && varDecl->isLocalVariable()) | ||||
| 		{ | ||||
| 			auto const& var = m_context.localVariable(*varDecl); | ||||
| @ -165,7 +164,7 @@ private: | ||||
| 			if (suffix == "slot") | ||||
| 				value = m_context.storageLocationOfStateVariable(*varDecl).first.str(); | ||||
| 			else if (suffix == "offset") | ||||
| 				value = to_string(m_context.storageLocationOfStateVariable(*varDecl).second); | ||||
| 				value = std::to_string(m_context.storageLocationOfStateVariable(*varDecl).second); | ||||
| 			else | ||||
| 				solAssert(false); | ||||
| 		} | ||||
| @ -216,7 +215,7 @@ private: | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| string IRGeneratorForStatementsBase::code() const | ||||
| std::string IRGeneratorForStatementsBase::code() const | ||||
| { | ||||
| 	return m_code.str(); | ||||
| } | ||||
| @ -240,7 +239,7 @@ void IRGeneratorForStatementsBase::setLocation(ASTNode const& _node) | ||||
| 	m_currentLocation = _node.location(); | ||||
| } | ||||
| 
 | ||||
| string IRGeneratorForStatements::code() const | ||||
| std::string IRGeneratorForStatements::code() const | ||||
| { | ||||
| 	solAssert(!m_currentLValue, "LValue not reset!"); | ||||
| 	return IRGeneratorForStatementsBase::code(); | ||||
| @ -338,11 +337,11 @@ IRVariable IRGeneratorForStatements::evaluateExpression(Expression const& _expre | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| string IRGeneratorForStatements::constantValueFunction(VariableDeclaration const& _constant) | ||||
| std::string IRGeneratorForStatements::constantValueFunction(VariableDeclaration const& _constant) | ||||
| { | ||||
| 	try | ||||
| 	{ | ||||
| 		string functionName = IRNames::constantValueFunction(_constant); | ||||
| 		std::string functionName = IRNames::constantValueFunction(_constant); | ||||
| 		return m_context.functionCollector().createFunction(functionName, [&] { | ||||
| 			Whiskers templ(R"( | ||||
| 				<sourceLocationComment> | ||||
| @ -410,7 +409,7 @@ bool IRGeneratorForStatements::visit(Conditional const& _conditional) | ||||
| 
 | ||||
| 	setLocation(_conditional); | ||||
| 
 | ||||
| 	string condition = expressionAsType(_conditional.condition(), *TypeProvider::boolean()); | ||||
| 	std::string condition = expressionAsType(_conditional.condition(), *TypeProvider::boolean()); | ||||
| 	declare(_conditional); | ||||
| 
 | ||||
| 	appendCode() << "switch " << condition << "\n" "case 0 {\n"; | ||||
| @ -501,7 +500,7 @@ bool IRGeneratorForStatements::visit(TupleExpression const& _tuple) | ||||
| 			_tuple.components().size() << | ||||
| 			")\n"; | ||||
| 
 | ||||
| 		string mpos = IRVariable(_tuple).part("mpos").name(); | ||||
| 		std::string mpos = IRVariable(_tuple).part("mpos").name(); | ||||
| 		Type const& baseType = *arrayType.baseType(); | ||||
| 		for (size_t i = 0; i < _tuple.components().size(); i++) | ||||
| 		{ | ||||
| @ -512,7 +511,7 @@ bool IRGeneratorForStatements::visit(TupleExpression const& _tuple) | ||||
| 			appendCode() << | ||||
| 				m_utils.writeToMemoryFunction(baseType) << | ||||
| 				"(" << | ||||
| 				("add(" + mpos + ", " + to_string(i * arrayType.memoryStride()) + ")") << | ||||
| 				("add(" + mpos + ", " + std::to_string(i * arrayType.memoryStride()) + ")") << | ||||
| 				", " << | ||||
| 				converted.commaSeparatedList() << | ||||
| 				")\n"; | ||||
| @ -535,7 +534,7 @@ bool IRGeneratorForStatements::visit(TupleExpression const& _tuple) | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			vector<optional<IRLValue>> lvalues; | ||||
| 			std::vector<std::optional<IRLValue>> lvalues; | ||||
| 			for (size_t i = 0; i < _tuple.components().size(); ++i) | ||||
| 				if (auto const& component = _tuple.components()[i]) | ||||
| 				{ | ||||
| @ -586,7 +585,7 @@ bool IRGeneratorForStatements::visit(IfStatement const& _ifStatement) | ||||
| { | ||||
| 	_ifStatement.condition().accept(*this); | ||||
| 	setLocation(_ifStatement); | ||||
| 	string condition = expressionAsType(_ifStatement.condition(), *TypeProvider::boolean()); | ||||
| 	std::string condition = expressionAsType(_ifStatement.condition(), *TypeProvider::boolean()); | ||||
| 
 | ||||
| 	if (_ifStatement.falseStatement()) | ||||
| 	{ | ||||
| @ -658,7 +657,7 @@ void IRGeneratorForStatements::endVisit(Return const& _return) | ||||
| 	if (Expression const* value = _return.expression()) | ||||
| 	{ | ||||
| 		solAssert(_return.annotation().functionReturnParameters, "Invalid return parameters pointer."); | ||||
| 		vector<ASTPointer<VariableDeclaration>> const& returnParameters = | ||||
| 		std::vector<ASTPointer<VariableDeclaration>> const& returnParameters = | ||||
| 			_return.annotation().functionReturnParameters->parameters(); | ||||
| 		if (returnParameters.size() > 1) | ||||
| 			for (size_t i = 0; i < returnParameters.size(); ++i) | ||||
| @ -685,7 +684,7 @@ bool IRGeneratorForStatements::visit(UnaryOperation const& _unaryOperation) | ||||
| 		solAssert(function->returnParameters().size() == 1); | ||||
| 		solAssert(*function->returnParameters()[0]->type() == *_unaryOperation.annotation().type); | ||||
| 
 | ||||
| 		string argument = expressionAsType(_unaryOperation.subExpression(), *function->parameters()[0]->type()); | ||||
| 		std::string argument = expressionAsType(_unaryOperation.subExpression(), *function->parameters()[0]->type()); | ||||
| 		solAssert(!argument.empty()); | ||||
| 
 | ||||
| 		solAssert(_unaryOperation.userDefinedFunctionType()->kind() == FunctionType::Kind::Internal); | ||||
| @ -812,8 +811,8 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp) | ||||
| 		solAssert(function->returnParameters().size() == 1); | ||||
| 		solAssert(*function->returnParameters()[0]->type() == *_binOp.annotation().type); | ||||
| 
 | ||||
| 		string left = expressionAsType(_binOp.leftExpression(), *function->parameters()[0]->type()); | ||||
| 		string right = expressionAsType(_binOp.rightExpression(), *function->parameters()[1]->type()); | ||||
| 		std::string left = expressionAsType(_binOp.leftExpression(), *function->parameters()[0]->type()); | ||||
| 		std::string right = expressionAsType(_binOp.rightExpression(), *function->parameters()[1]->type()); | ||||
| 		solAssert(!left.empty() && !right.empty()); | ||||
| 
 | ||||
| 		solAssert(_binOp.userDefinedFunctionType()->kind() == FunctionType::Kind::Internal); | ||||
| @ -853,13 +852,13 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp) | ||||
| 		if (auto type = dynamic_cast<IntegerType const*>(commonType)) | ||||
| 			isSigned = type->isSigned(); | ||||
| 
 | ||||
| 		string args = expressionAsCleanedType(_binOp.leftExpression(), *commonType); | ||||
| 		std::string args = expressionAsCleanedType(_binOp.leftExpression(), *commonType); | ||||
| 		args += ", " + expressionAsCleanedType(_binOp.rightExpression(), *commonType); | ||||
| 
 | ||||
| 		auto functionType = dynamic_cast<FunctionType const*>(commonType); | ||||
| 		solAssert(functionType ? (op == Token::Equal || op == Token::NotEqual) : true, "Invalid function pointer comparison!"); | ||||
| 
 | ||||
| 		string expr; | ||||
| 		std::string expr; | ||||
| 
 | ||||
| 		if (functionType && functionType->kind() ==  FunctionType::Kind::External) | ||||
| 		{ | ||||
| @ -879,9 +878,9 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp) | ||||
| 		else if (op == Token::NotEqual) | ||||
| 			expr = "iszero(eq(" + std::move(args) + "))"; | ||||
| 		else if (op == Token::GreaterThanOrEqual) | ||||
| 			expr = "iszero(" + string(isSigned ? "slt(" : "lt(") + std::move(args) + "))"; | ||||
| 			expr = "iszero(" + std::string(isSigned ? "slt(" : "lt(") + std::move(args) + "))"; | ||||
| 		else if (op == Token::LessThanOrEqual) | ||||
| 			expr = "iszero(" + string(isSigned ? "sgt(" : "gt(") + std::move(args) + "))"; | ||||
| 			expr = "iszero(" + std::string(isSigned ? "sgt(" : "gt(") + std::move(args) + "))"; | ||||
| 		else if (op == Token::GreaterThan) | ||||
| 			expr = (isSigned ? "sgt(" : "gt(") + std::move(args) + ")"; | ||||
| 		else if (op == Token::LessThan) | ||||
| @ -925,8 +924,8 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp) | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		string left = expressionAsType(_binOp.leftExpression(), *commonType); | ||||
| 		string right = expressionAsType(_binOp.rightExpression(), *commonType); | ||||
| 		std::string left = expressionAsType(_binOp.leftExpression(), *commonType); | ||||
| 		std::string right = expressionAsType(_binOp.rightExpression(), *commonType); | ||||
| 		define(_binOp) << binaryOperation(_binOp.getOperator(), *commonType, left, right) << "\n"; | ||||
| 	} | ||||
| 	return false; | ||||
| @ -960,7 +959,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 
 | ||||
| 	TypePointers parameterTypes = functionType->parameterTypes(); | ||||
| 
 | ||||
| 	vector<ASTPointer<Expression const>> const& arguments = _functionCall.sortedArguments(); | ||||
| 	std::vector<ASTPointer<Expression const>> const& arguments = _functionCall.sortedArguments(); | ||||
| 
 | ||||
| 	if (functionCallKind == FunctionCallKind::StructConstructorCall) | ||||
| 	{ | ||||
| @ -1001,7 +1000,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 
 | ||||
| 		solAssert(!functionType->takesArbitraryParameters()); | ||||
| 
 | ||||
| 		vector<string> args; | ||||
| 		std::vector<std::string> args; | ||||
| 		if (functionType->hasBoundFirstArgument()) | ||||
| 			args += IRVariable(_functionCall.expression()).part("self").stackSlots(); | ||||
| 
 | ||||
| @ -1049,8 +1048,8 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 		TypePointers paramTypes = functionType->parameterTypes(); | ||||
| 		ABIFunctions abi(m_context.evmVersion(), m_context.revertStrings(), m_context.functionCollector()); | ||||
| 
 | ||||
| 		vector<IRVariable> indexedArgs; | ||||
| 		vector<string> nonIndexedArgs; | ||||
| 		std::vector<IRVariable> indexedArgs; | ||||
| 		std::vector<std::string> nonIndexedArgs; | ||||
| 		TypePointers nonIndexedArgTypes; | ||||
| 		TypePointers nonIndexedParamTypes; | ||||
| 		if (!event.isAnonymous()) | ||||
| @ -1061,7 +1060,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 			Expression const& arg = *arguments[i]; | ||||
| 			if (event.parameters()[i]->isIndexed()) | ||||
| 			{ | ||||
| 				string value; | ||||
| 				std::string value; | ||||
| 				if (auto const& referenceType = dynamic_cast<ReferenceType const*>(paramTypes[i])) | ||||
| 					define(indexedArgs.emplace_back(m_context.newYulVariable(), *TypeProvider::uint256())) << | ||||
| 						m_utils.packedHashFunction({arg.annotation().type}, {referenceType}) << | ||||
| @ -1106,7 +1105,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 		templ("allocateUnbounded", m_utils.allocateUnboundedFunction()); | ||||
| 		templ("encode", abi.tupleEncoder(nonIndexedArgTypes, nonIndexedParamTypes)); | ||||
| 		templ("nonIndexedArgs", joinHumanReadablePrefixed(nonIndexedArgs)); | ||||
| 		templ("log", "log" + to_string(indexedArgs.size())); | ||||
| 		templ("log", "log" + std::to_string(indexedArgs.size())); | ||||
| 		templ("indexedArgs", joinHumanReadablePrefixed(indexedArgs | ranges::views::transform([&](auto const& _arg) { | ||||
| 			return _arg.commaSeparatedList(); | ||||
| 		}))); | ||||
| @ -1152,7 +1151,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 			arguments.size() > 1 && m_context.revertStrings() != RevertStrings::Strip ? | ||||
| 			arguments[1]->annotation().type : | ||||
| 			nullptr; | ||||
| 		string requireOrAssertFunction = m_utils.requireOrAssertFunction( | ||||
| 		std::string requireOrAssertFunction = m_utils.requireOrAssertFunction( | ||||
| 			functionType->kind() == FunctionType::Kind::Assert, | ||||
| 			messageArgumentType | ||||
| 		); | ||||
| @ -1179,9 +1178,9 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 
 | ||||
| 		TypePointers argumentTypes; | ||||
| 		TypePointers targetTypes; | ||||
| 		vector<string> argumentVars; | ||||
| 		string selector; | ||||
| 		vector<ASTPointer<Expression const>> argumentsOfEncodeFunction; | ||||
| 		std::vector<std::string> argumentVars; | ||||
| 		std::string selector; | ||||
| 		std::vector<ASTPointer<Expression const>> argumentsOfEncodeFunction; | ||||
| 
 | ||||
| 		if (functionType->kind() == FunctionType::Kind::ABIEncodeCall) | ||||
| 		{ | ||||
| @ -1252,13 +1251,13 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 				// TODO This is an abuse of the `allocateUnbounded` function.
 | ||||
| 				// We might want to introduce a new set of memory handling functions here
 | ||||
| 				// a la "setMemoryCheckPoint" and "freeUntilCheckPoint".
 | ||||
| 				string freeMemoryPre = m_context.newYulVariable(); | ||||
| 				std::string freeMemoryPre = m_context.newYulVariable(); | ||||
| 				appendCode() << "let " << freeMemoryPre << " := " << m_utils.allocateUnboundedFunction() << "()\n"; | ||||
| 				IRVariable array = convert(*arguments[0], *TypeProvider::bytesMemory()); | ||||
| 				IRVariable hashVariable(m_context.newYulVariable(), *TypeProvider::fixedBytes(32)); | ||||
| 
 | ||||
| 				string dataAreaFunction = m_utils.arrayDataAreaFunction(*TypeProvider::bytesMemory()); | ||||
| 				string arrayLengthFunction = m_utils.arrayLengthFunction(*TypeProvider::bytesMemory()); | ||||
| 				std::string dataAreaFunction = m_utils.arrayDataAreaFunction(*TypeProvider::bytesMemory()); | ||||
| 				std::string arrayLengthFunction = m_utils.arrayLengthFunction(*TypeProvider::bytesMemory()); | ||||
| 				define(hashVariable) << | ||||
| 					"keccak256(" << | ||||
| 					(dataAreaFunction + "(" + array.commaSeparatedList() + ")") << | ||||
| @ -1389,8 +1388,8 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 		{ | ||||
| 			auto array = convert(*arguments[0], *arrayType); | ||||
| 
 | ||||
| 			string dataAreaFunction = m_utils.arrayDataAreaFunction(*arrayType); | ||||
| 			string arrayLengthFunction = m_utils.arrayLengthFunction(*arrayType); | ||||
| 			std::string dataAreaFunction = m_utils.arrayDataAreaFunction(*arrayType); | ||||
| 			std::string arrayLengthFunction = m_utils.arrayLengthFunction(*arrayType); | ||||
| 			define(_functionCall) << | ||||
| 				"keccak256(" << | ||||
| 				(dataAreaFunction + "(" + array.commaSeparatedList() + ")") << | ||||
| @ -1453,7 +1452,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 	case FunctionType::Kind::BytesConcat: | ||||
| 	{ | ||||
| 		TypePointers argumentTypes; | ||||
| 		vector<string> argumentVars; | ||||
| 		std::vector<std::string> argumentVars; | ||||
| 		for (ASTPointer<Expression const> const& argument: arguments) | ||||
| 		{ | ||||
| 			argumentTypes.emplace_back(&type(*argument)); | ||||
| @ -1473,7 +1472,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 	case FunctionType::Kind::AddMod: | ||||
| 	case FunctionType::Kind::MulMod: | ||||
| 	{ | ||||
| 		static map<FunctionType::Kind, string> functions = { | ||||
| 		static std::map<FunctionType::Kind, std::string> functions = { | ||||
| 			{FunctionType::Kind::AddMod, "addmod"}, | ||||
| 			{FunctionType::Kind::MulMod, "mulmod"}, | ||||
| 		}; | ||||
| @ -1487,7 +1486,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 		templ("panic", m_utils.panicFunction(PanicCode::DivisionByZero)); | ||||
| 		appendCode() << templ.render(); | ||||
| 
 | ||||
| 		string args; | ||||
| 		std::string args; | ||||
| 		for (size_t i = 0; i < 2; ++i) | ||||
| 			args += expressionAsType(*arguments[i], *(parameterTypes[i])) + ", "; | ||||
| 		args += modulus.name(); | ||||
| @ -1498,14 +1497,14 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 	case FunctionType::Kind::Selfdestruct: | ||||
| 	case FunctionType::Kind::BlockHash: | ||||
| 	{ | ||||
| 		static map<FunctionType::Kind, string> functions = { | ||||
| 		static std::map<FunctionType::Kind, std::string> functions = { | ||||
| 			{FunctionType::Kind::GasLeft, "gas"}, | ||||
| 			{FunctionType::Kind::Selfdestruct, "selfdestruct"}, | ||||
| 			{FunctionType::Kind::BlockHash, "blockhash"}, | ||||
| 		}; | ||||
| 		solAssert(functions.find(functionType->kind()) != functions.end()); | ||||
| 
 | ||||
| 		string args; | ||||
| 		std::string args; | ||||
| 		for (size_t i = 0; i < arguments.size(); ++i) | ||||
| 			args += (args.empty() ? "" : ", ") + expressionAsType(*arguments[i], *(parameterTypes[i])); | ||||
| 		define(_functionCall) << functions[functionType->kind()] << "(" << args << ")\n"; | ||||
| @ -1520,7 +1519,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 		); | ||||
| 
 | ||||
| 		TypePointers argumentTypes; | ||||
| 		vector<string> constructorParams; | ||||
| 		std::vector<std::string> constructorParams; | ||||
| 		for (ASTPointer<Expression const> const& arg: arguments) | ||||
| 		{ | ||||
| 			argumentTypes.push_back(arg->annotation().type); | ||||
| @ -1575,8 +1574,8 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 	case FunctionType::Kind::Transfer: | ||||
| 	{ | ||||
| 		solAssert(arguments.size() == 1 && parameterTypes.size() == 1); | ||||
| 		string address{IRVariable(_functionCall.expression()).part("address").name()}; | ||||
| 		string value{expressionAsType(*arguments[0], *(parameterTypes[0]))}; | ||||
| 		std::string address{IRVariable(_functionCall.expression()).part("address").name()}; | ||||
| 		std::string value{expressionAsType(*arguments[0], *(parameterTypes[0]))}; | ||||
| 		Whiskers templ(R"( | ||||
| 			let <gas> := 0 | ||||
| 			if iszero(<value>) { <gas> := <callStipend> } | ||||
| @ -1608,14 +1607,14 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 		solAssert(!functionType->gasSet()); | ||||
| 		solAssert(!functionType->hasBoundFirstArgument()); | ||||
| 
 | ||||
| 		static map<FunctionType::Kind, std::tuple<unsigned, size_t>> precompiles = { | ||||
| 		static std::map<FunctionType::Kind, std::tuple<unsigned, size_t>> precompiles = { | ||||
| 			{FunctionType::Kind::ECRecover, std::make_tuple(1, 0)}, | ||||
| 			{FunctionType::Kind::SHA256, std::make_tuple(2, 0)}, | ||||
| 			{FunctionType::Kind::RIPEMD160, std::make_tuple(3, 12)}, | ||||
| 		}; | ||||
| 		auto [ address, offset ] = precompiles[functionType->kind()]; | ||||
| 		TypePointers argumentTypes; | ||||
| 		vector<string> argumentStrings; | ||||
| 		std::vector<std::string> argumentStrings; | ||||
| 		for (auto const& arg: arguments) | ||||
| 		{ | ||||
| 			argumentTypes.emplace_back(&type(*arg)); | ||||
| @ -1676,11 +1675,11 @@ void IRGeneratorForStatements::endVisit(FunctionCallOptions const& _options) | ||||
| 
 | ||||
| 	// Copy over existing values.
 | ||||
| 	for (auto const& item: previousType.stackItems()) | ||||
| 		define(IRVariable(_options).part(get<0>(item)), IRVariable(_options.expression()).part(get<0>(item))); | ||||
| 		define(IRVariable(_options).part(std::get<0>(item)), IRVariable(_options.expression()).part(std::get<0>(item))); | ||||
| 
 | ||||
| 	for (size_t i = 0; i < _options.names().size(); ++i) | ||||
| 	{ | ||||
| 		string const& name = *_options.names()[i]; | ||||
| 		std::string const& name = *_options.names()[i]; | ||||
| 		solAssert(name == "salt" || name == "gas" || name == "value"); | ||||
| 
 | ||||
| 		define(IRVariable(_options).part(name), *_options.options()[i]); | ||||
| @ -1785,7 +1784,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) | ||||
| 				")\n"; | ||||
| 		else if (member == "code") | ||||
| 		{ | ||||
| 			string externalCodeFunction = m_utils.externalCodeFunction(); | ||||
| 			std::string externalCodeFunction = m_utils.externalCodeFunction(); | ||||
| 			define(_memberAccess) << | ||||
| 				externalCodeFunction << | ||||
| 				"(" << | ||||
| @ -1797,12 +1796,12 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) | ||||
| 				"extcodehash(" << | ||||
| 				expressionAsType(_memberAccess.expression(), *TypeProvider::address()) << | ||||
| 				")\n"; | ||||
| 		else if (set<string>{"send", "transfer"}.count(member)) | ||||
| 		else if (std::set<std::string>{"send", "transfer"}.count(member)) | ||||
| 		{ | ||||
| 			solAssert(dynamic_cast<AddressType const&>(*_memberAccess.expression().annotation().type).stateMutability() == StateMutability::Payable); | ||||
| 			define(IRVariable{_memberAccess}.part("address"), _memberAccess.expression()); | ||||
| 		} | ||||
| 		else if (set<string>{"call", "callcode", "delegatecall", "staticcall"}.count(member)) | ||||
| 		else if (std::set<std::string>{"call", "callcode", "delegatecall", "staticcall"}.count(member)) | ||||
| 			define(IRVariable{_memberAccess}.part("address"), _memberAccess.expression()); | ||||
| 		else | ||||
| 			solAssert(false, "Invalid member access to address"); | ||||
| @ -1945,7 +1944,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) | ||||
| 		{ | ||||
| 			MagicType const* arg = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type); | ||||
| 
 | ||||
| 			string requestedValue; | ||||
| 			std::string requestedValue; | ||||
| 			if (IntegerType const* integerType = dynamic_cast<IntegerType const*>(arg->typeArgument())) | ||||
| 			{ | ||||
| 				if (member == "min") | ||||
| @ -1956,16 +1955,16 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) | ||||
| 			else if (EnumType const* enumType = dynamic_cast<EnumType const*>(arg->typeArgument())) | ||||
| 			{ | ||||
| 				if (member == "min") | ||||
| 					requestedValue = to_string(enumType->minValue()); | ||||
| 					requestedValue = std::to_string(enumType->minValue()); | ||||
| 				else | ||||
| 					requestedValue = to_string(enumType->maxValue()); | ||||
| 					requestedValue = std::to_string(enumType->maxValue()); | ||||
| 			} | ||||
| 			else | ||||
| 				solAssert(false, "min/max requested on unexpected type."); | ||||
| 
 | ||||
| 			define(_memberAccess) << requestedValue << "\n"; | ||||
| 		} | ||||
| 		else if (set<string>{"encode", "encodePacked", "encodeWithSelector", "encodeCall", "encodeWithSignature", "decode"}.count(member)) | ||||
| 		else if (std::set<std::string>{"encode", "encodePacked", "encodeWithSelector", "encodeCall", "encodeWithSignature", "decode"}.count(member)) | ||||
| 		{ | ||||
| 			// no-op
 | ||||
| 		} | ||||
| @ -1981,8 +1980,8 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) | ||||
| 		{ | ||||
| 		case DataLocation::Storage: | ||||
| 		{ | ||||
| 			pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member); | ||||
| 			string slot = m_context.newYulVariable(); | ||||
| 			std::pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member); | ||||
| 			std::string slot = m_context.newYulVariable(); | ||||
| 			appendCode() << "let " << slot << " := " << | ||||
| 				("add(" + expression.part("slot").name() + ", " + offsets.first.str() + ")\n"); | ||||
| 			setLValue(_memberAccess, IRLValue{ | ||||
| @ -1993,7 +1992,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) | ||||
| 		} | ||||
| 		case DataLocation::Memory: | ||||
| 		{ | ||||
| 			string pos = m_context.newYulVariable(); | ||||
| 			std::string pos = m_context.newYulVariable(); | ||||
| 			appendCode() << "let " << pos << " := " << | ||||
| 				("add(" + expression.part("mpos").name() + ", " + structType.memoryOffsetOfMember(member).str() + ")\n"); | ||||
| 			setLValue(_memberAccess, IRLValue{ | ||||
| @ -2004,9 +2003,9 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) | ||||
| 		} | ||||
| 		case DataLocation::CallData: | ||||
| 		{ | ||||
| 			string baseRef = expression.part("offset").name(); | ||||
| 			string offset = m_context.newYulVariable(); | ||||
| 			appendCode() << "let " << offset << " := " << "add(" << baseRef << ", " << to_string(structType.calldataOffsetOfMember(member)) << ")\n"; | ||||
| 			std::string baseRef = expression.part("offset").name(); | ||||
| 			std::string offset = m_context.newYulVariable(); | ||||
| 			appendCode() << "let " << offset << " := " << "add(" << baseRef << ", " << std::to_string(structType.calldataOffsetOfMember(member)) << ")\n"; | ||||
| 			if (_memberAccess.annotation().type->isDynamicallyEncoded()) | ||||
| 				define(_memberAccess) << | ||||
| 					m_utils.accessCalldataTailFunction(*_memberAccess.annotation().type) << | ||||
| @ -2036,7 +2035,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) | ||||
| 	case Type::Category::Enum: | ||||
| 	{ | ||||
| 		EnumType const& type = dynamic_cast<EnumType const&>(*_memberAccess.expression().annotation().type); | ||||
| 		define(_memberAccess) << to_string(type.memberValue(_memberAccess.memberName())) << "\n"; | ||||
| 		define(_memberAccess) << std::to_string(type.memberValue(_memberAccess.memberName())) << "\n"; | ||||
| 		break; | ||||
| 	} | ||||
| 	case Type::Category::Array: | ||||
| @ -2076,7 +2075,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) | ||||
| 	{ | ||||
| 		auto const& type = dynamic_cast<FixedBytesType const&>(*_memberAccess.expression().annotation().type); | ||||
| 		if (member == "length") | ||||
| 			define(_memberAccess) << to_string(type.numBytes()) << "\n"; | ||||
| 			define(_memberAccess) << std::to_string(type.numBytes()) << "\n"; | ||||
| 		else | ||||
| 			solAssert(false, "Illegal fixed bytes member."); | ||||
| 		break; | ||||
| @ -2162,7 +2161,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) | ||||
| 				solAssert(false); | ||||
| 		} | ||||
| 		else if (EnumType const* enumType = dynamic_cast<EnumType const*>(&actualType)) | ||||
| 			define(_memberAccess) << to_string(enumType->memberValue(_memberAccess.memberName())) << "\n"; | ||||
| 			define(_memberAccess) << std::to_string(enumType->memberValue(_memberAccess.memberName())) << "\n"; | ||||
| 		else if (dynamic_cast<UserDefinedValueType const*>(&actualType)) | ||||
| 			solAssert(member == "wrap" || member == "unwrap"); | ||||
| 		else if (auto const* arrayType = dynamic_cast<ArrayType const*>(&actualType)) | ||||
| @ -2222,7 +2221,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm) | ||||
| 
 | ||||
| 	yul::Statement modified = bodyCopier(_inlineAsm.operations()); | ||||
| 
 | ||||
| 	solAssert(holds_alternative<yul::Block>(modified)); | ||||
| 	solAssert(std::holds_alternative<yul::Block>(modified)); | ||||
| 
 | ||||
| 	// Do not provide dialect so that we get the full type information.
 | ||||
| 	appendCode() << yul::AsmPrinter()(std::get<yul::Block>(modified)) << "\n"; | ||||
| @ -2242,7 +2241,7 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess) | ||||
| 		MappingType const& mappingType = dynamic_cast<MappingType const&>(baseType); | ||||
| 		Type const& keyType = *_indexAccess.indexExpression()->annotation().type; | ||||
| 
 | ||||
| 		string slot = m_context.newYulVariable(); | ||||
| 		std::string slot = m_context.newYulVariable(); | ||||
| 		Whiskers templ("let <slot> := <indexAccess>(<base><?+key>,<key></+key>)\n"); | ||||
| 		templ("slot", slot); | ||||
| 		templ("indexAccess", m_utils.mappingIndexAccessFunction(mappingType, keyType)); | ||||
| @ -2273,8 +2272,8 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess) | ||||
| 		{ | ||||
| 			case DataLocation::Storage: | ||||
| 			{ | ||||
| 				string slot = m_context.newYulVariable(); | ||||
| 				string offset = m_context.newYulVariable(); | ||||
| 				std::string slot = m_context.newYulVariable(); | ||||
| 				std::string offset = m_context.newYulVariable(); | ||||
| 
 | ||||
| 				appendCode() << Whiskers(R"( | ||||
| 					let <slot>, <offset> := <indexFunc>(<array>, <index>) | ||||
| @ -2295,13 +2294,13 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess) | ||||
| 			} | ||||
| 			case DataLocation::Memory: | ||||
| 			{ | ||||
| 				string const indexAccessFunction = m_utils.memoryArrayIndexAccessFunction(arrayType); | ||||
| 				string const baseRef = IRVariable(_indexAccess.baseExpression()).part("mpos").name(); | ||||
| 				string const indexExpression = expressionAsType( | ||||
| 				std::string const indexAccessFunction = m_utils.memoryArrayIndexAccessFunction(arrayType); | ||||
| 				std::string const baseRef = IRVariable(_indexAccess.baseExpression()).part("mpos").name(); | ||||
| 				std::string const indexExpression = expressionAsType( | ||||
| 					*_indexAccess.indexExpression(), | ||||
| 					*TypeProvider::uint256() | ||||
| 				); | ||||
| 				string const memAddress = indexAccessFunction + "(" + baseRef + ", " + indexExpression + ")"; | ||||
| 				std::string const memAddress = indexAccessFunction + "(" + baseRef + ", " + indexExpression + ")"; | ||||
| 
 | ||||
| 				setLValue(_indexAccess, IRLValue{ | ||||
| 					*arrayType.baseType(), | ||||
| @ -2311,13 +2310,13 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess) | ||||
| 			} | ||||
| 			case DataLocation::CallData: | ||||
| 			{ | ||||
| 				string const indexAccessFunction = m_utils.calldataArrayIndexAccessFunction(arrayType); | ||||
| 				string const baseRef = IRVariable(_indexAccess.baseExpression()).commaSeparatedList(); | ||||
| 				string const indexExpression = expressionAsType( | ||||
| 				std::string const indexAccessFunction = m_utils.calldataArrayIndexAccessFunction(arrayType); | ||||
| 				std::string const baseRef = IRVariable(_indexAccess.baseExpression()).commaSeparatedList(); | ||||
| 				std::string const indexExpression = expressionAsType( | ||||
| 					*_indexAccess.indexExpression(), | ||||
| 					*TypeProvider::uint256() | ||||
| 				); | ||||
| 				string const calldataAddress = indexAccessFunction + "(" + baseRef + ", " + indexExpression + ")"; | ||||
| 				std::string const calldataAddress = indexAccessFunction + "(" + baseRef + ", " + indexExpression + ")"; | ||||
| 
 | ||||
| 				if (arrayType.isByteArrayOrString()) | ||||
| 					define(_indexAccess) << | ||||
| @ -2349,7 +2348,7 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess) | ||||
| 			let <result> := <shl248>(byte(<index>, <array>)) | ||||
| 		)") | ||||
| 		("index", index.name()) | ||||
| 		("length", to_string(fixedBytesType.numBytes())) | ||||
| 		("length", std::to_string(fixedBytesType.numBytes())) | ||||
| 		("panic", m_utils.panicFunction(PanicCode::ArrayOutOfBounds)) | ||||
| 		("array", IRVariable(_indexAccess.baseExpression()).name()) | ||||
| 		("shl248", m_utils.shiftLeftFunction(256 - 8)) | ||||
| @ -2538,7 +2537,7 @@ void IRGeneratorForStatements::handleVariableReference( | ||||
| 
 | ||||
| void IRGeneratorForStatements::appendExternalFunctionCall( | ||||
| 	FunctionCall const& _functionCall, | ||||
| 	vector<ASTPointer<Expression const>> const& _arguments | ||||
| 	std::vector<ASTPointer<Expression const>> const& _arguments | ||||
| ) | ||||
| { | ||||
| 	FunctionType const& funType = dynamic_cast<FunctionType const&>(type(_functionCall.expression())); | ||||
| @ -2559,7 +2558,7 @@ void IRGeneratorForStatements::appendExternalFunctionCall( | ||||
| 
 | ||||
| 	TypePointers parameterTypes = funType.parameterTypes(); | ||||
| 	TypePointers argumentTypes; | ||||
| 	vector<string> argumentStrings; | ||||
| 	std::vector<std::string> argumentStrings; | ||||
| 	if (funType.hasBoundFirstArgument()) | ||||
| 	{ | ||||
| 		parameterTypes.insert(parameterTypes.begin(), funType.selfType()); | ||||
| @ -2581,7 +2580,7 @@ void IRGeneratorForStatements::appendExternalFunctionCall( | ||||
| 		// We could also just use MLOAD; POP right before the gas calculation, but the optimizer
 | ||||
| 		// would remove that, so we use MSTORE here.
 | ||||
| 		if (!funType.gasSet() && returnInfo.estimatedReturnSize > 0) | ||||
| 			appendCode() << "mstore(add(" << m_utils.allocateUnboundedFunction() << "() , " << to_string(returnInfo.estimatedReturnSize) << "), 0)\n"; | ||||
| 			appendCode() << "mstore(add(" << m_utils.allocateUnboundedFunction() << "() , " << std::to_string(returnInfo.estimatedReturnSize) << "), 0)\n"; | ||||
| 	} | ||||
| 
 | ||||
| 	// NOTE: When the expected size of returndata is static, we pass that in to the call opcode and it gets copied automatically.
 | ||||
| @ -2649,10 +2648,10 @@ void IRGeneratorForStatements::appendExternalFunctionCall( | ||||
| 	if (returnInfo.dynamicReturnSize) | ||||
| 		solAssert(m_context.evmVersion().supportsReturndata()); | ||||
| 	templ("returnDataSizeVar", m_context.newYulVariable()); | ||||
| 	templ("staticReturndataSize", to_string(returnInfo.estimatedReturnSize)); | ||||
| 	templ("staticReturndataSize", std::to_string(returnInfo.estimatedReturnSize)); | ||||
| 	templ("supportsReturnData", m_context.evmVersion().supportsReturndata()); | ||||
| 
 | ||||
| 	string const retVars = IRVariable(_functionCall).commaSeparatedList(); | ||||
| 	std::string const retVars = IRVariable(_functionCall).commaSeparatedList(); | ||||
| 	templ("retVars", retVars); | ||||
| 	solAssert(retVars.empty() == returnInfo.returnTypes.empty()); | ||||
| 
 | ||||
| @ -2704,7 +2703,7 @@ void IRGeneratorForStatements::appendExternalFunctionCall( | ||||
| 
 | ||||
| void IRGeneratorForStatements::appendBareCall( | ||||
| 	FunctionCall const& _functionCall, | ||||
| 	vector<ASTPointer<Expression const>> const& _arguments | ||||
| 	std::vector<ASTPointer<Expression const>> const& _arguments | ||||
| ) | ||||
| { | ||||
| 	FunctionType const& funType = dynamic_cast<FunctionType const&>(type(_functionCall.expression())); | ||||
| @ -2807,7 +2806,7 @@ void IRGeneratorForStatements::assignInternalFunctionIDIfNotCalledDirectly( | ||||
| 		return; | ||||
| 
 | ||||
| 	define(IRVariable(_expression).part("functionIdentifier")) << | ||||
| 		to_string(m_context.mostDerivedContract().annotation().internalFunctionIDs.at(&_referencedFunction)) << | ||||
| 		std::to_string(m_context.mostDerivedContract().annotation().internalFunctionIDs.at(&_referencedFunction)) << | ||||
| 		"\n"; | ||||
| 	m_context.addToInternalDispatch(_referencedFunction); | ||||
| } | ||||
| @ -2864,7 +2863,7 @@ void IRGeneratorForStatements::declare(IRVariable const& _var) | ||||
| 
 | ||||
| void IRGeneratorForStatements::declareAssign(IRVariable const& _lhs, IRVariable const& _rhs, bool _declare, bool _forceCleanup) | ||||
| { | ||||
| 	string output; | ||||
| 	std::string output; | ||||
| 	if (_lhs.type() == _rhs.type() && !_forceCleanup) | ||||
| 		for (auto const& [stackItemName, stackItemType]: _lhs.type().stackItems()) | ||||
| 			if (stackItemType) | ||||
| @ -2894,7 +2893,7 @@ IRVariable IRGeneratorForStatements::zeroValue(Type const& _type, bool _splitFun | ||||
| 
 | ||||
| void IRGeneratorForStatements::appendSimpleUnaryOperation(UnaryOperation const& _operation, Expression const& _expr) | ||||
| { | ||||
| 	string func; | ||||
| 	std::string func; | ||||
| 
 | ||||
| 	if (_operation.getOperator() == Token::Not) | ||||
| 		func = "iszero"; | ||||
| @ -2913,18 +2912,18 @@ void IRGeneratorForStatements::appendSimpleUnaryOperation(UnaryOperation const& | ||||
| 		")\n"; | ||||
| } | ||||
| 
 | ||||
| string IRGeneratorForStatements::binaryOperation( | ||||
| std::string IRGeneratorForStatements::binaryOperation( | ||||
| 	langutil::Token _operator, | ||||
| 	Type const& _type, | ||||
| 	string const& _left, | ||||
| 	string const& _right | ||||
| 	std::string const& _left, | ||||
| 	std::string const& _right | ||||
| ) | ||||
| { | ||||
| 	solAssert( | ||||
| 		!TokenTraits::isShiftOp(_operator), | ||||
| 		"Have to use specific shift operation function for shifts." | ||||
| 	); | ||||
| 	string fun; | ||||
| 	std::string fun; | ||||
| 	if (TokenTraits::isBitOp(_operator)) | ||||
| 	{ | ||||
| 		solAssert( | ||||
| @ -3030,12 +3029,12 @@ void IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable | ||||
| 	std::visit( | ||||
| 		util::GenericVisitor{ | ||||
| 			[&](IRLValue::Storage const& _storage) { | ||||
| 				string offsetArgument; | ||||
| 				optional<unsigned> offsetStatic; | ||||
| 				std::string offsetArgument; | ||||
| 				std::optional<unsigned> offsetStatic; | ||||
| 
 | ||||
| 				std::visit(GenericVisitor{ | ||||
| 					[&](unsigned _offset) { offsetStatic = _offset; }, | ||||
| 					[&](string const& _offset) { offsetArgument = ", " + _offset; } | ||||
| 					[&](std::string const& _offset) { offsetArgument = ", " + _offset; } | ||||
| 				}, _storage.offset); | ||||
| 
 | ||||
| 				appendCode() << | ||||
| @ -3068,7 +3067,7 @@ void IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable | ||||
| 				} | ||||
| 				else if (auto const* literalType = dynamic_cast<StringLiteralType const*>(&_value.type())) | ||||
| 				{ | ||||
| 					string writeUInt = m_utils.writeToMemoryFunction(*TypeProvider::uint256()); | ||||
| 					std::string writeUInt = m_utils.writeToMemoryFunction(*TypeProvider::uint256()); | ||||
| 					appendCode() << | ||||
| 						writeUInt << | ||||
| 						"(" << | ||||
| @ -3099,7 +3098,7 @@ void IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable | ||||
| 				IRVariable prepared(m_context.newYulVariable(), _lvalue.type); | ||||
| 				define(prepared, _value); | ||||
| 
 | ||||
| 				appendCode() << "mstore(" << to_string(memOffset) << ", " << prepared.commaSeparatedList() << ")\n"; | ||||
| 				appendCode() << "mstore(" << std::to_string(memOffset) << ", " << prepared.commaSeparatedList() << ")\n"; | ||||
| 			}, | ||||
| 			[&](IRLValue::Tuple const& _tuple) { | ||||
| 				auto components = std::move(_tuple.components); | ||||
| @ -3122,13 +3121,13 @@ IRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue) | ||||
| 		[&](IRLValue::Storage const& _storage) { | ||||
| 			if (!_lvalue.type.isValueType()) | ||||
| 				define(result) << _storage.slot << "\n"; | ||||
| 			else if (std::holds_alternative<string>(_storage.offset)) | ||||
| 			else if (std::holds_alternative<std::string>(_storage.offset)) | ||||
| 				define(result) << | ||||
| 					m_utils.readFromStorageDynamic(_lvalue.type, true) << | ||||
| 					"(" << | ||||
| 					_storage.slot << | ||||
| 					", " << | ||||
| 					std::get<string>(_storage.offset) << | ||||
| 					std::get<std::string>(_storage.offset) << | ||||
| 					")\n"; | ||||
| 			else | ||||
| 				define(result) << | ||||
| @ -3156,15 +3155,15 @@ IRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue) | ||||
| 			solAssert(_lvalue.type == *_immutable.variable->type()); | ||||
| 			if (m_context.executionContext() == IRGenerationContext::ExecutionContext::Creation) | ||||
| 			{ | ||||
| 				string readFunction = m_utils.readFromMemory(*_immutable.variable->type()); | ||||
| 				std::string readFunction = m_utils.readFromMemory(*_immutable.variable->type()); | ||||
| 				define(result) << | ||||
| 					readFunction << | ||||
| 					"(" << | ||||
| 					to_string(m_context.immutableMemoryOffset(*_immutable.variable)) << | ||||
| 					std::to_string(m_context.immutableMemoryOffset(*_immutable.variable)) << | ||||
| 					")\n"; | ||||
| 			} | ||||
| 			else | ||||
| 				define(result) << "loadimmutable(\"" << to_string(_immutable.variable->id()) << "\")\n"; | ||||
| 				define(result) << "loadimmutable(\"" << std::to_string(_immutable.variable->id()) << "\")\n"; | ||||
| 		}, | ||||
| 		[&](IRLValue::Tuple const&) { | ||||
| 			solAssert(false, "Attempted to read from tuple lvalue."); | ||||
| @ -3181,7 +3180,7 @@ void IRGeneratorForStatements::setLValue(Expression const& _expression, IRLValue | ||||
| 	{ | ||||
| 		m_currentLValue.emplace(std::move(_lvalue)); | ||||
| 		if (_lvalue.type.dataStoredIn(DataLocation::CallData)) | ||||
| 			solAssert(holds_alternative<IRLValue::Stack>(_lvalue.kind)); | ||||
| 			solAssert(std::holds_alternative<IRLValue::Stack>(_lvalue.kind)); | ||||
| 	} | ||||
| 	else | ||||
| 		// Only define the expression, if it will not be written to.
 | ||||
| @ -3196,7 +3195,7 @@ void IRGeneratorForStatements::generateLoop( | ||||
| 	bool _isDoWhile | ||||
| ) | ||||
| { | ||||
| 	string firstRun; | ||||
| 	std::string firstRun; | ||||
| 
 | ||||
| 	if (_isDoWhile) | ||||
| 	{ | ||||
| @ -3278,7 +3277,7 @@ bool IRGeneratorForStatements::visit(TryStatement const& _tryStatement) | ||||
| void IRGeneratorForStatements::handleCatch(TryStatement const& _tryStatement) | ||||
| { | ||||
| 	setLocation(_tryStatement); | ||||
| 	string const runFallback = m_context.newYulVariable(); | ||||
| 	std::string const runFallback = m_context.newYulVariable(); | ||||
| 	appendCode() << "let " << runFallback << " := 1\n"; | ||||
| 
 | ||||
| 	// This function returns zero on "short returndata". We have to add a success flag
 | ||||
| @ -3290,7 +3289,7 @@ void IRGeneratorForStatements::handleCatch(TryStatement const& _tryStatement) | ||||
| 	{ | ||||
| 		appendCode() << "case " << selectorFromSignatureU32("Error(string)") << " {\n"; | ||||
| 		setLocation(*errorClause); | ||||
| 		string const dataVariable = m_context.newYulVariable(); | ||||
| 		std::string const dataVariable = m_context.newYulVariable(); | ||||
| 		appendCode() << "let " << dataVariable << " := " << m_utils.tryDecodeErrorMessageFunction() << "()\n"; | ||||
| 		appendCode() << "if " << dataVariable << " {\n"; | ||||
| 		appendCode() << runFallback << " := 0\n"; | ||||
| @ -3310,8 +3309,8 @@ void IRGeneratorForStatements::handleCatch(TryStatement const& _tryStatement) | ||||
| 	{ | ||||
| 		appendCode() << "case " << selectorFromSignatureU32("Panic(uint256)") << " {\n"; | ||||
| 		setLocation(*panicClause); | ||||
| 		string const success = m_context.newYulVariable(); | ||||
| 		string const code = m_context.newYulVariable(); | ||||
| 		std::string const success = m_context.newYulVariable(); | ||||
| 		std::string const code = m_context.newYulVariable(); | ||||
| 		appendCode() << "let " << success << ", " << code << " := " << m_utils.tryDecodePanicDataFunction() << "()\n"; | ||||
| 		appendCode() << "if " << success << " {\n"; | ||||
| 		appendCode() << runFallback << " := 0\n"; | ||||
| @ -3358,9 +3357,9 @@ void IRGeneratorForStatements::handleCatchFallback(TryCatchClause const& _fallba | ||||
| } | ||||
| 
 | ||||
| void IRGeneratorForStatements::revertWithError( | ||||
| 	string const& _signature, | ||||
| 	vector<Type const*> const& _parameterTypes, | ||||
| 	vector<ASTPointer<Expression const>> const& _errorArguments | ||||
| 	std::string const& _signature, | ||||
| 	std::vector<Type const*> const& _parameterTypes, | ||||
| 	std::vector<ASTPointer<Expression const>> const& _errorArguments | ||||
| ) | ||||
| { | ||||
| 	Whiskers templ(R"({ | ||||
| @ -3374,8 +3373,8 @@ void IRGeneratorForStatements::revertWithError( | ||||
| 	templ("hash", util::selectorFromSignatureU256(_signature).str()); | ||||
| 	templ("allocateUnbounded", m_utils.allocateUnboundedFunction()); | ||||
| 
 | ||||
| 	vector<string> errorArgumentVars; | ||||
| 	vector<Type const*> errorArgumentTypes; | ||||
| 	std::vector<std::string> errorArgumentVars; | ||||
| 	std::vector<Type const*> errorArgumentTypes; | ||||
| 	for (ASTPointer<Expression const> const& arg: _errorArguments) | ||||
| 	{ | ||||
| 		errorArgumentVars += IRVariable(*arg).stackSlots(); | ||||
| @ -3395,7 +3394,7 @@ bool IRGeneratorForStatements::visit(TryCatchClause const& _clause) | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| string IRGeneratorForStatements::linkerSymbol(ContractDefinition const& _library) const | ||||
| std::string IRGeneratorForStatements::linkerSymbol(ContractDefinition const& _library) const | ||||
| { | ||||
| 	solAssert(_library.isLibrary()); | ||||
| 	return "linkersymbol(" + util::escapeAndQuoteString(_library.fullyQualifiedName()) + ")"; | ||||
|  | ||||
| @ -20,7 +20,6 @@ | ||||
| #include <libsolidity/ast/AST.h> | ||||
| #include <libsolutil/StringUtils.h> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::frontend; | ||||
| using namespace solidity::util; | ||||
| @ -41,7 +40,7 @@ IRVariable::IRVariable(Expression const& _expression): | ||||
| { | ||||
| } | ||||
| 
 | ||||
| IRVariable IRVariable::part(string const& _name) const | ||||
| IRVariable IRVariable::part(std::string const& _name) const | ||||
| { | ||||
| 	for (auto const& [itemName, itemType]: m_type.stackItems()) | ||||
| 		if (itemName == _name) | ||||
| @ -63,9 +62,9 @@ bool IRVariable::hasPart(std::string const& _name) const | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| vector<string> IRVariable::stackSlots() const | ||||
| std::vector<std::string> IRVariable::stackSlots() const | ||||
| { | ||||
| 	vector<string> result; | ||||
| 	std::vector<std::string> result; | ||||
| 	for (auto const& [itemName, itemType]: m_type.stackItems()) | ||||
| 		if (itemType) | ||||
| 		{ | ||||
| @ -81,17 +80,17 @@ vector<string> IRVariable::stackSlots() const | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| string IRVariable::commaSeparatedList() const | ||||
| std::string IRVariable::commaSeparatedList() const | ||||
| { | ||||
| 	return joinHumanReadable(stackSlots()); | ||||
| } | ||||
| 
 | ||||
| string IRVariable::commaSeparatedListPrefixed() const | ||||
| std::string IRVariable::commaSeparatedListPrefixed() const | ||||
| { | ||||
| 	return joinHumanReadablePrefixed(stackSlots()); | ||||
| } | ||||
| 
 | ||||
| string IRVariable::name() const | ||||
| std::string IRVariable::name() const | ||||
| { | ||||
| 	solAssert(m_type.sizeOnStack() == 1, ""); | ||||
| 	auto const& [itemName, type] = m_type.stackItems().front(); | ||||
| @ -108,7 +107,7 @@ IRVariable IRVariable::tupleComponent(size_t _i) const | ||||
| 	return part(IRNames::tupleComponent(_i)); | ||||
| } | ||||
| 
 | ||||
| string IRVariable::suffixedName(string const& _suffix) const | ||||
| std::string IRVariable::suffixedName(std::string const& _suffix) const | ||||
| { | ||||
| 	if (_suffix.empty()) | ||||
| 		return m_baseName; | ||||
|  | ||||
| @ -27,6 +27,8 @@ NAMESPACE_STD_FREE_FILES=( | ||||
|     libsolc/* | ||||
|     libsolidity/analysis/* | ||||
|     libsolidity/ast/* | ||||
|     libsolidity/codegen/ir/* | ||||
|     libsolidity/codegen/* | ||||
| ) | ||||
| 
 | ||||
| ( | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user