Allow data location suffix for internal elementary type parsing

This commit is contained in:
mingchuan 2018-05-22 23:20:40 +08:00
parent e97f9b6ba8
commit 9865012f7b
No known key found for this signature in database
GPG Key ID: 607CD25FA2D03651
2 changed files with 30 additions and 15 deletions

View File

@ -33,6 +33,8 @@
#include <boost/algorithm/string/join.hpp> #include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/range/adaptor/reversed.hpp> #include <boost/range/adaptor/reversed.hpp>
#include <boost/range/algorithm/copy.hpp> #include <boost/range/algorithm/copy.hpp>
#include <boost/range/adaptor/sliced.hpp> #include <boost/range/adaptor/sliced.hpp>
@ -312,22 +314,34 @@ TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type)
TypePointer Type::fromElementaryTypeName(string const& _name) TypePointer Type::fromElementaryTypeName(string const& _name)
{ {
string name = _name; vector<string> nameParts;
DataLocation location = DataLocation::Storage; boost::split(nameParts, _name, boost::is_any_of(" "));
if (boost::algorithm::ends_with(name, " memory")) solAssert(nameParts.size() == 1 || nameParts.size() == 2, "Cannot parse elementary type: " + _name);
{
name = name.substr(0, name.length() - 7);
location = DataLocation::Memory;
}
unsigned short firstNum;
unsigned short secondNum;
Token::Value token; Token::Value token;
tie(token, firstNum, secondNum) = Token::fromIdentifierOrKeyword(name); unsigned short firstNum, secondNum;
tie(token, firstNum, secondNum) = Token::fromIdentifierOrKeyword(nameParts[0]);
auto t = fromElementaryTypeName(ElementaryTypeNameToken(token, firstNum, secondNum)); auto t = fromElementaryTypeName(ElementaryTypeNameToken(token, firstNum, secondNum));
if (auto* ref = dynamic_cast<ReferenceType const*>(t.get())) if (auto* ref = dynamic_cast<ReferenceType const*>(t.get()))
{
DataLocation location = DataLocation::Storage;
if (nameParts.size() == 2)
{
if (nameParts[1] == "storage")
location = DataLocation::Storage;
else if (nameParts[1] == "calldata")
location = DataLocation::CallData;
else if (nameParts[1] == "memory")
location = DataLocation::Memory;
else
solAssert(false, "Unknown data location: " + nameParts[1]);
}
return ref->copyForLocation(location, true); return ref->copyForLocation(location, true);
}
else else
{
solAssert(nameParts.size() == 1, "Storage location suffix only allowed for reference types");
return t; return t;
}
} }
TypePointer Type::forLiteral(Literal const& _literal) TypePointer Type::forLiteral(Literal const& _literal)
@ -982,7 +996,7 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ
} }
else else
value = m_value.numerator() % other.m_value.numerator(); value = m_value.numerator() % other.m_value.numerator();
break; break;
case Token::Exp: case Token::Exp:
{ {
using boost::multiprecision::pow; using boost::multiprecision::pow;
@ -1128,7 +1142,7 @@ u256 RationalNumberType::literalValue(Literal const*) const
// its value. // its value.
u256 value; u256 value;
bigint shiftedValue; bigint shiftedValue;
if (!isFractional()) if (!isFractional())
shiftedValue = m_value.numerator(); shiftedValue = m_value.numerator();
@ -1180,7 +1194,7 @@ shared_ptr<FixedPointType const> RationalNumberType::fixedPointType() const
bool negative = (m_value < 0); bool negative = (m_value < 0);
unsigned fractionalDigits = 0; unsigned fractionalDigits = 0;
rational value = abs(m_value); // We care about the sign later. rational value = abs(m_value); // We care about the sign later.
rational maxValue = negative ? rational maxValue = negative ?
rational(bigint(1) << 255, 1): rational(bigint(1) << 255, 1):
rational((bigint(1) << 256) - 1, 1); rational((bigint(1) << 256) - 1, 1);
@ -1189,7 +1203,7 @@ shared_ptr<FixedPointType const> RationalNumberType::fixedPointType() const
value *= 10; value *= 10;
fractionalDigits++; fractionalDigits++;
} }
if (value > maxValue) if (value > maxValue)
return shared_ptr<FixedPointType const>(); return shared_ptr<FixedPointType const>();
// This means we round towards zero for positive and negative values. // This means we round towards zero for positive and negative values.

View File

@ -151,7 +151,8 @@ public:
/// @name Factory functions /// @name Factory functions
/// Factory functions that convert an AST @ref TypeName to a Type. /// Factory functions that convert an AST @ref TypeName to a Type.
static TypePointer fromElementaryTypeName(ElementaryTypeNameToken const& _type); static TypePointer fromElementaryTypeName(ElementaryTypeNameToken const& _type);
/// Converts a given elementary type name with optional suffix " memory" to a type pointer. /// Converts a given elementary type name with optional data location
/// suffix " storage", " calldata" or " memory" to a type pointer. If suffix not given, defaults to " storage".
static TypePointer fromElementaryTypeName(std::string const& _name); static TypePointer fromElementaryTypeName(std::string const& _name);
/// @} /// @}