From 07bc04ff384b367d6e4bb318fbad8e9c6b0a304e Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Fri, 6 Oct 2017 21:26:06 +0000 Subject: [llvm-rc] Serialize VERSIONINFO resources to .res files. This is now able to dump VERSIONINFO resources. Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381058.aspx Differential Revision: https://reviews.llvm.org/D38410 Patch by: Marek Sokolowski llvm-svn: 315110 --- llvm/tools/llvm-rc/ResourceScriptParser.cpp | 40 +++++++++++++++++------------ 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'llvm/tools/llvm-rc/ResourceScriptParser.cpp') diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.cpp b/llvm/tools/llvm-rc/ResourceScriptParser.cpp index d8c081771cb..47f8745837e 100644 --- a/llvm/tools/llvm-rc/ResourceScriptParser.cpp +++ b/llvm/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 RCParser::readInt() { return parseIntExpr1(); } +Expected RCParser::readInt() { return parseIntExpr1(); } -Expected RCParser::parseIntExpr1() { +Expected 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 RCParser::parseIntExpr1() { return Result; } -Expected RCParser::parseIntExpr2() { +Expected RCParser::parseIntExpr2() { // Exp2 ::= -Exp2 || ~Exp2 || Int || (Exp1). static const char ErrorMsg[] = "'-', '~', integer or '('"; @@ -191,7 +191,7 @@ Expected 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> -RCParser::readIntsWithCommas(size_t MinCount, size_t MaxCount) { +Expected> RCParser::readIntsWithCommas(size_t MinCount, + size_t MaxCount) { assert(MinCount <= MaxCount); - SmallVector Result; + SmallVector Result; auto FailureHandler = - [&](llvm::Error Err) -> Expected> { + [&](llvm::Error Err) -> Expected> { if (Result.size() < MinCount) return std::move(Err); consumeError(std::move(Err)); @@ -477,7 +477,7 @@ Expected RCParser::parseControl() { ASSIGN_OR_RETURN(Args, readIntsWithCommas(5, 8)); auto TakeOptArg = [&Args](size_t Id) -> Optional { - return Args->size() > Id ? (*Args)[Id] : Optional(); + return Args->size() > Id ? (uint32_t)(*Args)[Id] : Optional(); }; return Control(*ClassResult, Caption, (*Args)[0], (*Args)[1], (*Args)[2], @@ -608,15 +608,22 @@ Expected> 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 Values; - - while (consumeOptionalType(Kind::Comma)) { + std::vector 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(*KeyResult, std::move(Values)); + return llvm::make_unique(*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 ArgInts(ArgsResult->begin(), ArgsResult->end()); + Result.setValue(FixedType, ArgInts); } return Result; -- cgit v1.2.3