diff options
Diffstat (limited to 'tools/llvm-rc/ResourceScriptParser.cpp')
-rw-r--r-- | tools/llvm-rc/ResourceScriptParser.cpp | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/tools/llvm-rc/ResourceScriptParser.cpp b/tools/llvm-rc/ResourceScriptParser.cpp index d8c081771cb..47f8745837e 100644 --- a/tools/llvm-rc/ResourceScriptParser.cpp +++ b/tools/llvm-rc/ResourceScriptParser.cpp @@ -134,12 +134,12 @@ void RCParser::consume() { // 1 => 01 00, -1 => ff ff, --1 => 01 00, ---1 => ff ff; // 1 => 01 00, ~1 => fe ff, ~~1 => 01 00, ~~~1 => fe ff. -Expected<uint32_t> RCParser::readInt() { return parseIntExpr1(); } +Expected<RCInt> RCParser::readInt() { return parseIntExpr1(); } -Expected<uint32_t> RCParser::parseIntExpr1() { +Expected<RCInt> RCParser::parseIntExpr1() { // Exp1 ::= Exp2 || Exp1 + Exp2 || Exp1 - Exp2 || Exp1 | Exp2 || Exp1 & Exp2. ASSIGN_OR_RETURN(FirstResult, parseIntExpr2()); - uint32_t Result = *FirstResult; + RCInt Result = *FirstResult; while (!isEof() && look().isBinaryOp()) { auto OpToken = read(); @@ -170,7 +170,7 @@ Expected<uint32_t> RCParser::parseIntExpr1() { return Result; } -Expected<uint32_t> RCParser::parseIntExpr2() { +Expected<RCInt> RCParser::parseIntExpr2() { // Exp2 ::= -Exp2 || ~Exp2 || Int || (Exp1). static const char ErrorMsg[] = "'-', '~', integer or '('"; @@ -191,7 +191,7 @@ Expected<uint32_t> RCParser::parseIntExpr2() { } case Kind::Int: - return read().intValue(); + return RCInt(read()); case Kind::LeftParen: { consume(); @@ -261,14 +261,14 @@ bool RCParser::consumeOptionalType(Kind TokenKind) { return false; } -Expected<SmallVector<uint32_t, 8>> -RCParser::readIntsWithCommas(size_t MinCount, size_t MaxCount) { +Expected<SmallVector<RCInt, 8>> RCParser::readIntsWithCommas(size_t MinCount, + size_t MaxCount) { assert(MinCount <= MaxCount); - SmallVector<uint32_t, 8> Result; + SmallVector<RCInt, 8> Result; auto FailureHandler = - [&](llvm::Error Err) -> Expected<SmallVector<uint32_t, 8>> { + [&](llvm::Error Err) -> Expected<SmallVector<RCInt, 8>> { if (Result.size() < MinCount) return std::move(Err); consumeError(std::move(Err)); @@ -477,7 +477,7 @@ Expected<Control> RCParser::parseControl() { ASSIGN_OR_RETURN(Args, readIntsWithCommas(5, 8)); auto TakeOptArg = [&Args](size_t Id) -> Optional<uint32_t> { - return Args->size() > Id ? (*Args)[Id] : Optional<uint32_t>(); + return Args->size() > Id ? (uint32_t)(*Args)[Id] : Optional<uint32_t>(); }; return Control(*ClassResult, Caption, (*Args)[0], (*Args)[1], (*Args)[2], @@ -608,15 +608,22 @@ Expected<std::unique_ptr<VersionInfoStmt>> RCParser::parseVersionInfoStmt() { if (TypeResult->equals_lower("VALUE")) { ASSIGN_OR_RETURN(KeyResult, readString()); - // Read a (possibly empty) list of strings and/or ints, each preceded by - // a comma. + // Read a non-empty list of strings and/or ints, each + // possibly preceded by a comma. Unfortunately, the tool behavior depends + // on them existing or not, so we need to memorize where we found them. std::vector<IntOrString> Values; - - while (consumeOptionalType(Kind::Comma)) { + std::vector<bool> PrecedingCommas; + RETURN_IF_ERROR(consumeType(Kind::Comma)); + while (!isNextTokenKind(Kind::Identifier) && + !isNextTokenKind(Kind::BlockEnd)) { + // Try to eat a comma if it's not the first statement. + bool HadComma = Values.size() > 0 && consumeOptionalType(Kind::Comma); ASSIGN_OR_RETURN(ValueResult, readIntOrString()); Values.push_back(*ValueResult); + PrecedingCommas.push_back(HadComma); } - return llvm::make_unique<VersionInfoValue>(*KeyResult, std::move(Values)); + return llvm::make_unique<VersionInfoValue>(*KeyResult, std::move(Values), + std::move(PrecedingCommas)); } return getExpectedError("BLOCK or VALUE", true); @@ -641,7 +648,8 @@ RCParser::parseVersionInfoFixed() { // VERSION variations take multiple integers. size_t NumInts = RetType::isVersionType(FixedType) ? 4 : 1; ASSIGN_OR_RETURN(ArgsResult, readIntsWithCommas(NumInts, NumInts)); - Result.setValue(FixedType, *ArgsResult); + SmallVector<uint32_t, 4> ArgInts(ArgsResult->begin(), ArgsResult->end()); + Result.setValue(FixedType, ArgInts); } return Result; |