Return Optional<uint64_t> from readInteger instead of returning just success/failure.

llvm-svn: 299600
This commit is contained in:
Rui Ueyama
2017-04-05 23:22:11 +00:00
parent 963bcd2ec3
commit 5c65088fd4

View File

@@ -762,38 +762,38 @@ uint64_t static getConstant(StringRef S) {
return 0;
}
// Parses Tok as an integer. Returns true if successful.
// It recognizes hexadecimal (prefixed with "0x" or suffixed with "H")
// and decimal numbers. Decimal numbers may have "K" (kilo) or
// "M" (mega) prefixes.
static bool readInteger(StringRef Tok, uint64_t &Result) {
// Parses Tok as an integer. It recognizes hexadecimal (prefixed with
// "0x" or suffixed with "H") and decimal numbers. Decimal numbers may
// have "K" (Ki) or "M" (Mi) suffixes.
static Optional<uint64_t> parseInt(StringRef Tok) {
// Negative number
if (Tok.startswith("-")) {
if (!readInteger(Tok.substr(1), Result))
return false;
Result = -Result;
return true;
if (Optional<uint64_t> Val = parseInt(Tok.substr(1)))
return -*Val;
return None;
}
// Hexadecimal
if (Tok.startswith_lower("0x"))
return !Tok.substr(2).getAsInteger(16, Result);
if (Tok.endswith_lower("H"))
return !Tok.drop_back().getAsInteger(16, Result);
uint64_t Val;
if (Tok.startswith_lower("0x") && !Tok.substr(2).getAsInteger(16, Val))
return Val;
if (Tok.endswith_lower("H") && !Tok.drop_back().getAsInteger(16, Val))
return Val;
// Decimal
int Suffix = 1;
if (Tok.endswith_lower("K")) {
Suffix = 1024;
Tok = Tok.drop_back();
} else if (Tok.endswith_lower("M")) {
Suffix = 1024 * 1024;
Tok = Tok.drop_back();
if (Tok.drop_back().getAsInteger(10, Val))
return None;
return Val * 1024;
}
if (Tok.getAsInteger(10, Result))
return false;
Result *= Suffix;
return true;
if (Tok.endswith_lower("M")) {
if (Tok.drop_back().getAsInteger(10, Val))
return None;
return Val * 1024 * 1024;
}
if (Tok.getAsInteger(10, Val))
return None;
return Val;
}
BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) {
@@ -820,18 +820,18 @@ Expr ScriptParser::readPrimary() {
if (peek() == "(")
return readParenExpr();
StringRef Tok = next();
std::string Location = getCurrentLocation();
if (Tok == "~") {
if (consume("~")) {
Expr E = readPrimary();
return [=] { return ~E().getValue(); };
}
if (Tok == "-") {
if (consume("-")) {
Expr E = readPrimary();
return [=] { return -E().getValue(); };
}
StringRef Tok = next();
std::string Location = getCurrentLocation();
// Built-in functions are parsed here.
// https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
if (Tok == "ABSOLUTE") {
@@ -921,9 +921,8 @@ Expr ScriptParser::readPrimary() {
return [=] { return Script->getSymbolValue(Location, Tok); };
// Tok is a literal number.
uint64_t V;
if (readInteger(Tok, V))
return [=] { return V; };
if (Optional<uint64_t> Val = parseInt(Tok))
return [=] { return *Val; };
// Tok is a symbol name.
if (!isValidCIdentifier(Tok))
@@ -959,9 +958,8 @@ std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
// name of a program header type or a constant (e.g. "0x3").
unsigned ScriptParser::readPhdrType() {
StringRef Tok = next();
uint64_t Val;
if (readInteger(Tok, Val))
return Val;
if (Optional<uint64_t> Val = parseInt(Tok))
return *Val;
unsigned Ret = StringSwitch<unsigned>(Tok)
.Case("PT_NULL", PT_NULL)
@@ -1102,10 +1100,10 @@ uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,
expect("=");
// TODO: Fully support constant expressions.
uint64_t Val;
if (!readInteger(next(), Val))
setError("nonconstant expression for " + S1);
return Val;
if (Optional<uint64_t> Val = parseInt(next()))
return *Val;
setError("nonconstant expression for " + S1);
return 0;
}
// Parse the MEMORY command as specified in: