diff options
Diffstat (limited to 'lld/ELF/ScriptParser.cpp')
| -rw-r--r-- | lld/ELF/ScriptParser.cpp | 74 |
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: |

