summaryrefslogtreecommitdiffstats
path: root/lld/ELF/ScriptParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/ScriptParser.cpp')
-rw-r--r--lld/ELF/ScriptParser.cpp74
1 files changed, 36 insertions, 38 deletions
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 5894ee973a3..6c115fb9e51 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -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:
OpenPOWER on IntegriCloud