[llvm] [llvm-rc] add support for MENUEX (PR #67464)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 5 06:03:04 PDT 2023
https://github.com/oltolm updated https://github.com/llvm/llvm-project/pull/67464
>From a484436434cb209b9ef697ff23c3eb0947456e22 Mon Sep 17 00:00:00 2001
From: oltolm <oleg.tolmatcev at gmail.com>
Date: Tue, 26 Sep 2023 18:41:22 +0200
Subject: [PATCH 1/2] [llvm-rc] add support for MENUEX
---
llvm/test/tools/llvm-rc/Inputs/menuex.rc | 14 +++
llvm/test/tools/llvm-rc/menuex.test | 25 +++++
llvm/tools/llvm-rc/ResourceFileWriter.cpp | 58 ++++++++++++
llvm/tools/llvm-rc/ResourceFileWriter.h | 5 +
llvm/tools/llvm-rc/ResourceScriptParser.cpp | 100 ++++++++++++++++++++
llvm/tools/llvm-rc/ResourceScriptParser.h | 4 +
llvm/tools/llvm-rc/ResourceScriptStmt.cpp | 17 ++++
llvm/tools/llvm-rc/ResourceScriptStmt.h | 61 +++++++++++-
llvm/tools/llvm-rc/ResourceVisitor.h | 1 +
9 files changed, 283 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/tools/llvm-rc/Inputs/menuex.rc
create mode 100644 llvm/test/tools/llvm-rc/menuex.test
diff --git a/llvm/test/tools/llvm-rc/Inputs/menuex.rc b/llvm/test/tools/llvm-rc/Inputs/menuex.rc
new file mode 100644
index 000000000000000..766fffe03b87d9b
--- /dev/null
+++ b/llvm/test/tools/llvm-rc/Inputs/menuex.rc
@@ -0,0 +1,14 @@
+101 MENUEX
+BEGIN
+ POPUP "File", 40182
+ BEGIN
+ MENUITEM "Load", 40011
+ MENUITEM "", 0, 0x00000800L
+
+ POPUP "Savestate Slot", 40187
+ BEGIN
+ MENUITEM "&1", 40099
+ MENUITEM "&2", 40100
+ END
+ END
+END
diff --git a/llvm/test/tools/llvm-rc/menuex.test b/llvm/test/tools/llvm-rc/menuex.test
new file mode 100644
index 000000000000000..2a51ffd110419c7
--- /dev/null
+++ b/llvm/test/tools/llvm-rc/menuex.test
@@ -0,0 +1,25 @@
+; RUN: llvm-rc -no-preprocess /FO %t -- %p/Inputs/menuex.rc
+; RUN: llvm-readobj %t | FileCheck %s
+
+CHECK: Resource type (int): MENU (ID 4)
+CHECK-NEXT: Resource name (int): 101
+CHECK-NEXT: Data version: 0
+CHECK-NEXT: Memory flags: 0x1030
+CHECK-NEXT: Language ID: 1033
+CHECK-NEXT: Version (major): 0
+CHECK-NEXT: Version (minor): 0
+CHECK-NEXT: Characteristics: 0
+CHECK-NEXT: Data size: 164
+CHECK-NEXT: Data: (
+CHECK-NEXT: 0000: 01000400 00000000 00000000 00000000 |................|
+CHECK-NEXT: 0010: F69C0000 81004600 69006C00 65000000 |......F.i.l.e...|
+CHECK-NEXT: 0020: 00000000 00000000 00000000 4B9C0000 |............K...|
+CHECK-NEXT: 0030: 00004C00 6F006100 64000000 00080000 |..L.o.a.d.......|
+CHECK-NEXT: 0040: 00000000 00000000 00000000 00000000 |................|
+CHECK-NEXT: 0050: 00000000 FB9C0000 81005300 61007600 |..........S.a.v.|
+CHECK-NEXT: 0060: 65007300 74006100 74006500 20005300 |e.s.t.a.t.e. .S.|
+CHECK-NEXT: 0070: 6C006F00 74000000 00000000 00000000 |l.o.t...........|
+CHECK-NEXT: 0080: 00000000 A39C0000 00002600 31000000 |..........&.1...|
+CHECK-NEXT: 0090: 00000000 00000000 A49C0000 80002600 |..............&.|
+CHECK-NEXT: 00A0: 32000000 |2...|
+CHECK-NEXT: )
diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.cpp b/llvm/tools/llvm-rc/ResourceFileWriter.cpp
index 62eed50976d90a0..dd9db338ece255b 100644
--- a/llvm/tools/llvm-rc/ResourceFileWriter.cpp
+++ b/llvm/tools/llvm-rc/ResourceFileWriter.cpp
@@ -471,6 +471,10 @@ Error ResourceFileWriter::visitMenuResource(const RCResource *Res) {
return writeResource(Res, &ResourceFileWriter::writeMenuBody);
}
+Error ResourceFileWriter::visitMenuExResource(const RCResource *Res) {
+ return writeResource(Res, &ResourceFileWriter::writeMenuExBody);
+}
+
Error ResourceFileWriter::visitStringTableResource(const RCResource *Base) {
const auto *Res = cast<StringTableResource>(Base);
@@ -1176,6 +1180,7 @@ Error ResourceFileWriter::writeHTMLBody(const RCResource *Base) {
Error ResourceFileWriter::writeMenuDefinition(
const std::unique_ptr<MenuDefinition> &Def, uint16_t Flags) {
+ // https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-menuitemtemplate
assert(Def);
const MenuDefinition *DefPtr = Def.get();
@@ -1202,6 +1207,34 @@ Error ResourceFileWriter::writeMenuDefinition(
return writeMenuDefinitionList(PopupPtr->SubItems);
}
+Error ResourceFileWriter::writeMenuExDefinition(
+ const std::unique_ptr<MenuDefinition> &Def, uint16_t Flags) {
+ // https://learn.microsoft.com/en-us/windows/win32/menurc/menuex-template-item
+ assert(Def);
+ const MenuDefinition *DefPtr = Def.get();
+
+ padStream(sizeof(uint32_t));
+ if (auto *MenuItemPtr = dyn_cast<MenuExItem>(DefPtr)) {
+ writeInt<uint32_t>(MenuItemPtr->Type);
+ writeInt<uint32_t>(MenuItemPtr->State);
+ writeInt<uint32_t>(MenuItemPtr->Id);
+ writeInt<uint16_t>(Flags);
+ padStream(sizeof(uint16_t));
+ RETURN_IF_ERROR(writeCString(MenuItemPtr->Name));
+ return Error::success();
+ }
+
+ auto *PopupPtr = cast<PopupExItem>(DefPtr);
+ writeInt<uint32_t>(PopupPtr->Type);
+ writeInt<uint32_t>(PopupPtr->State);
+ writeInt<uint32_t>(PopupPtr->Id);
+ writeInt<uint16_t>(Flags);
+ padStream(sizeof(uint16_t));
+ RETURN_IF_ERROR(writeCString(PopupPtr->Name));
+ writeInt<uint32_t>(PopupPtr->HelpId);
+ return writeMenuExDefinitionList(PopupPtr->SubItems);
+}
+
Error ResourceFileWriter::writeMenuDefinitionList(
const MenuDefinitionList &List) {
for (auto &Def : List.Definitions) {
@@ -1216,6 +1249,20 @@ Error ResourceFileWriter::writeMenuDefinitionList(
return Error::success();
}
+Error ResourceFileWriter::writeMenuExDefinitionList(
+ const MenuDefinitionList &List) {
+ for (auto &Def : List.Definitions) {
+ uint16_t Flags = Def->getResFlags();
+ // Last element receives an additional 0x80 flag.
+ const uint16_t LastElementFlag = 0x0080;
+ if (&Def == &List.Definitions.back())
+ Flags |= LastElementFlag;
+
+ RETURN_IF_ERROR(writeMenuExDefinition(Def, Flags));
+ }
+ return Error::success();
+}
+
Error ResourceFileWriter::writeMenuBody(const RCResource *Base) {
// At first, MENUHEADER structure. In fact, these are two WORDs equal to 0.
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648018.aspx
@@ -1224,6 +1271,17 @@ Error ResourceFileWriter::writeMenuBody(const RCResource *Base) {
return writeMenuDefinitionList(cast<MenuResource>(Base)->Elements);
}
+Error ResourceFileWriter::writeMenuExBody(const RCResource *Base) {
+ // At first, MENUEX_TEMPLATE_HEADER structure.
+ // Ref:
+ // https://learn.microsoft.com/en-us/windows/win32/menurc/menuex-template-header
+ writeInt<uint16_t>(1);
+ writeInt<uint16_t>(4);
+ writeInt<uint32_t>(0);
+
+ return writeMenuExDefinitionList(cast<MenuExResource>(Base)->Elements);
+}
+
// --- StringTableResource helpers. --- //
class BundleResource : public RCResource {
diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.h b/llvm/tools/llvm-rc/ResourceFileWriter.h
index 7a92f84d5d84f29..d809890ee8e8201 100644
--- a/llvm/tools/llvm-rc/ResourceFileWriter.h
+++ b/llvm/tools/llvm-rc/ResourceFileWriter.h
@@ -55,6 +55,7 @@ class ResourceFileWriter : public Visitor {
Error visitHTMLResource(const RCResource *) override;
Error visitIconResource(const RCResource *) override;
Error visitMenuResource(const RCResource *) override;
+ Error visitMenuExResource(const RCResource *) override;
Error visitVersionInfoResource(const RCResource *) override;
Error visitStringTableResource(const RCResource *) override;
Error visitUserDefinedResource(const RCResource *) override;
@@ -150,8 +151,12 @@ class ResourceFileWriter : public Visitor {
// MenuResource
Error writeMenuDefinition(const std::unique_ptr<MenuDefinition> &,
uint16_t Flags);
+ Error writeMenuExDefinition(const std::unique_ptr<MenuDefinition> &,
+ uint16_t Flags);
Error writeMenuDefinitionList(const MenuDefinitionList &List);
+ Error writeMenuExDefinitionList(const MenuDefinitionList &List);
Error writeMenuBody(const RCResource *);
+ Error writeMenuExBody(const RCResource *);
// StringTableResource
Error visitStringTableBundle(const RCResource *);
diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.cpp b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
index 0037fec4c0247d7..cc2e3c01045126f 100644
--- a/llvm/tools/llvm-rc/ResourceScriptParser.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
@@ -80,6 +80,8 @@ RCParser::ParseType RCParser::parseSingleResource() {
Result = parseIconResource();
else if (TypeToken->equalsLower("MENU"))
Result = parseMenuResource();
+ else if (TypeToken->equalsLower("MENUEX"))
+ Result = parseMenuExResource();
else if (TypeToken->equalsLower("RCDATA"))
Result = parseUserDefinedResource(RkRcData);
else if (TypeToken->equalsLower("VERSIONINFO"))
@@ -623,6 +625,13 @@ RCParser::ParseType RCParser::parseMenuResource() {
std::move(*Items), MemoryFlags);
}
+RCParser::ParseType RCParser::parseMenuExResource() {
+ uint16_t MemoryFlags =
+ parseMemoryFlags(MenuExResource::getDefaultMemoryFlags());
+ ASSIGN_OR_RETURN(Items, parseMenuExItemsList());
+ return std::make_unique<MenuExResource>(std::move(*Items), MemoryFlags);
+}
+
Expected<MenuDefinitionList> RCParser::parseMenuItemsList() {
RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
@@ -682,6 +691,97 @@ Expected<MenuDefinitionList> RCParser::parseMenuItemsList() {
return std::move(List);
}
+Expected<MenuDefinitionList> RCParser::parseMenuExItemsList() {
+ RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
+
+ MenuDefinitionList List;
+
+ // Read a set of items. Each item is of one of three kinds:
+ // MENUITEM caption:String [,[id][, [type][, state]]]]
+ // POPUP caption:String [,[id][, [type][, [state][, helpID]]]] { popupBody }
+ // }
+ while (!consumeOptionalType(Kind::BlockEnd)) {
+ ASSIGN_OR_RETURN(ItemTypeResult, readIdentifier());
+
+ bool IsMenuItem = ItemTypeResult->equals_insensitive("MENUITEM");
+ bool IsPopup = ItemTypeResult->equals_insensitive("POPUP");
+ if (!IsMenuItem && !IsPopup)
+ return getExpectedError("MENUITEM, POPUP, END or '}'", true);
+
+ // Not a separator. Read the caption.
+ ASSIGN_OR_RETURN(CaptionResult, readString());
+
+ // If MENUITEM, expect [,[id][, [type][, state]]]]
+ uint32_t MenuId = 0;
+ uint32_t MenuType = 0;
+ uint32_t MenuState = 0;
+
+ if (IsMenuItem) {
+ if (consumeOptionalType(Kind::Comma)) {
+ auto IntId = readInt();
+ if (IntId) {
+ MenuId = *IntId;
+ }
+ if (consumeOptionalType(Kind::Comma)) {
+ auto IntType = readInt();
+ if (IntType) {
+ MenuType = *IntType;
+ }
+ if (consumeOptionalType(Kind::Comma)) {
+ auto IntState = readInt();
+ if (IntState) {
+ MenuState = *IntState;
+ }
+ }
+ }
+ }
+ }
+
+ uint32_t PopupId = 0;
+ uint32_t PopupType = 0;
+ uint32_t PopupState = 0;
+ uint32_t PopupHelpID = 0;
+ if (IsPopup) {
+ if (consumeOptionalType(Kind::Comma)) {
+ auto IntId = readInt();
+ if (IntId) {
+ PopupId = *IntId;
+ }
+ if (consumeOptionalType(Kind::Comma)) {
+ auto IntType = readInt();
+ if (IntType) {
+ PopupType = *IntType;
+ }
+ if (consumeOptionalType(Kind::Comma)) {
+ auto IntState = readInt();
+ if (IntState) {
+ PopupState = *IntState;
+ }
+ if (consumeOptionalType(Kind::Comma)) {
+ auto IntHelpID = readInt();
+ if (IntHelpID) {
+ PopupHelpID = *IntHelpID;
+ }
+ }
+ }
+ }
+ }
+ // If POPUP, read submenu items recursively.
+ ASSIGN_OR_RETURN(SubMenuResult, parseMenuExItemsList());
+ List.addDefinition(std::make_unique<PopupExItem>(
+ *CaptionResult, PopupId, PopupType, PopupState, PopupHelpID,
+ std::move(*SubMenuResult)));
+ continue;
+ }
+
+ assert(IsMenuItem);
+ List.addDefinition(std::make_unique<MenuExItem>(*CaptionResult, MenuId,
+ MenuType, MenuState));
+ }
+
+ return std::move(List);
+}
+
RCParser::ParseType RCParser::parseStringTableResource() {
uint16_t MemoryFlags =
parseMemoryFlags(StringTableResource::getDefaultMemoryFlags());
diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.h b/llvm/tools/llvm-rc/ResourceScriptParser.h
index a7d3b595f794377..5c01cec0f151e8b 100644
--- a/llvm/tools/llvm-rc/ResourceScriptParser.h
+++ b/llvm/tools/llvm-rc/ResourceScriptParser.h
@@ -143,6 +143,7 @@ class RCParser {
ParseType parseIconResource();
ParseType parseHTMLResource();
ParseType parseMenuResource();
+ ParseType parseMenuExResource();
ParseType parseStringTableResource();
ParseType parseUserDefinedResource(IntOrString Type);
ParseType parseVersionInfoResource();
@@ -153,6 +154,9 @@ class RCParser {
// Helper MENU parser.
Expected<MenuDefinitionList> parseMenuItemsList();
+ // Helper MENUEX parser.
+ Expected<MenuDefinitionList> parseMenuExItemsList();
+
// Helper VERSIONINFO parser - read the contents of a single BLOCK statement,
// from BEGIN to END.
Expected<std::unique_ptr<VersionInfoBlock>>
diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.cpp b/llvm/tools/llvm-rc/ResourceScriptStmt.cpp
index ef8c34541881ac8..768733f71319dac 100644
--- a/llvm/tools/llvm-rc/ResourceScriptStmt.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptStmt.cpp
@@ -102,6 +102,11 @@ raw_ostream &MenuSeparator::log(raw_ostream &OS) const {
return OS << " Menu separator\n";
}
+raw_ostream &MenuExItem::log(raw_ostream &OS) const {
+ OS << " MenuExItem (" << Name << "), ID = " << Id;
+ return OS << "\n";
+}
+
raw_ostream &PopupItem::log(raw_ostream &OS) const {
OS << " Popup (" << Name << ")";
logFlags(OS, Flags);
@@ -109,12 +114,24 @@ raw_ostream &PopupItem::log(raw_ostream &OS) const {
return SubItems.log(OS);
}
+raw_ostream &PopupExItem::log(raw_ostream &OS) const {
+ OS << " Popup (" << Name << ")";
+ OS << ":\n";
+ return SubItems.log(OS);
+}
+
raw_ostream &MenuResource::log(raw_ostream &OS) const {
OS << "Menu (" << ResName << "):\n";
OptStatements->log(OS);
return Elements.log(OS);
}
+raw_ostream &MenuExResource::log(raw_ostream &OS) const {
+ OS << "MenuEx (" << ResName << "):\n";
+ OptStatements->log(OS);
+ return Elements.log(OS);
+}
+
raw_ostream &StringTableResource::log(raw_ostream &OS) const {
OS << "StringTable:\n";
OptStatements->log(OS);
diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.h b/llvm/tools/llvm-rc/ResourceScriptStmt.h
index 71f6a9d212e46cf..09853da6c500aaf 100644
--- a/llvm/tools/llvm-rc/ResourceScriptStmt.h
+++ b/llvm/tools/llvm-rc/ResourceScriptStmt.h
@@ -536,6 +536,23 @@ class MenuItem : public MenuDefinition {
}
};
+class MenuExItem : public MenuDefinition {
+public:
+ StringRef Name;
+ uint32_t Id;
+ uint32_t Type;
+ uint32_t State;
+
+ MenuExItem(StringRef Caption, uint32_t ItemId, uint32_t Type, uint32_t State)
+ : Name(Caption), Id(ItemId), Type(Type), State(State) {}
+ raw_ostream &log(raw_ostream &) const override;
+
+ MenuDefKind getKind() const override { return MkMenuItem; }
+ static bool classof(const MenuDefinition *D) {
+ return D->getKind() == MkMenuItem;
+ }
+};
+
// POPUP statement definition.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381030(v=vs.85).aspx
@@ -550,8 +567,7 @@ class PopupItem : public MenuDefinition {
: Name(Caption), Flags(ItemFlags), SubItems(std::move(SubItemsList)) {}
raw_ostream &log(raw_ostream &) const override;
- // This has an additional (0x10) flag. It doesn't match with documented
- // 0x01 flag, though.
+ // This has an additional MF_POPUP (0x10) flag.
uint16_t getResFlags() const override { return Flags | 0x10; }
MenuDefKind getKind() const override { return MkPopup; }
static bool classof(const MenuDefinition *D) {
@@ -559,6 +575,28 @@ class PopupItem : public MenuDefinition {
}
};
+class PopupExItem : public MenuDefinition {
+public:
+ StringRef Name;
+ uint32_t Id;
+ uint32_t Type;
+ uint32_t State;
+ uint32_t HelpId;
+ MenuDefinitionList SubItems;
+
+ PopupExItem(StringRef Caption, uint32_t Id, uint32_t Type, uint32_t State,
+ uint32_t HelpId, MenuDefinitionList &&SubItemsList)
+ : Name(Caption), Id(Id), Type(Type), State(State), HelpId(HelpId),
+ SubItems(std::move(SubItemsList)) {}
+ raw_ostream &log(raw_ostream &) const override;
+
+ uint16_t getResFlags() const override { return 0x01; }
+ MenuDefKind getKind() const override { return MkPopup; }
+ static bool classof(const MenuDefinition *D) {
+ return D->getKind() == MkPopup;
+ }
+};
+
// Menu resource definition.
class MenuResource : public OptStatementsRCResource {
public:
@@ -579,6 +617,25 @@ class MenuResource : public OptStatementsRCResource {
}
};
+class MenuExResource : public OptStatementsRCResource {
+public:
+ MenuDefinitionList Elements;
+
+ MenuExResource(MenuDefinitionList &&Items, uint16_t Flags)
+ : OptStatementsRCResource({}, Flags), Elements(std::move(Items)) {}
+ raw_ostream &log(raw_ostream &) const override;
+
+ IntOrString getResourceType() const override { return RkMenu; }
+ Twine getResourceTypeName() const override { return "MENUEX"; }
+ Error visit(Visitor *V) const override {
+ return V->visitMenuExResource(this);
+ }
+ ResourceKind getKind() const override { return RkMenu; }
+ static bool classof(const RCResource *Res) {
+ return Res->getKind() == RkMenu;
+ }
+};
+
// STRINGTABLE resource. Contains a list of strings, each having its unique ID.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381050(v=vs.85).aspx
diff --git a/llvm/tools/llvm-rc/ResourceVisitor.h b/llvm/tools/llvm-rc/ResourceVisitor.h
index 843c8d898a21122..a950cd7555ecdf1 100644
--- a/llvm/tools/llvm-rc/ResourceVisitor.h
+++ b/llvm/tools/llvm-rc/ResourceVisitor.h
@@ -39,6 +39,7 @@ class Visitor {
virtual Error visitHTMLResource(const RCResource *) = 0;
virtual Error visitIconResource(const RCResource *) = 0;
virtual Error visitMenuResource(const RCResource *) = 0;
+ virtual Error visitMenuExResource(const RCResource *) = 0;
virtual Error visitStringTableResource(const RCResource *) = 0;
virtual Error visitUserDefinedResource(const RCResource *) = 0;
virtual Error visitVersionInfoResource(const RCResource *) = 0;
>From 221603c56034808d8c8e3aa5ca7f9272880d5e6c Mon Sep 17 00:00:00 2001
From: oltolm <oleg.tolmatcev at gmail.com>
Date: Thu, 5 Oct 2023 15:00:23 +0200
Subject: [PATCH 2/2] [llvm-rc] code review fixes
---
llvm/tools/llvm-rc/ResourceScriptParser.cpp | 81 ++++++++++-----------
llvm/tools/llvm-rc/ResourceScriptStmt.cpp | 2 +
2 files changed, 42 insertions(+), 41 deletions(-)
diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.cpp b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
index cc2e3c01045126f..9e1047448831b37 100644
--- a/llvm/tools/llvm-rc/ResourceScriptParser.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
@@ -501,7 +501,7 @@ RCParser::ParseType RCParser::parseUserDefinedResource(IntOrString Type) {
case Kind::String:
case Kind::Identifier:
return std::make_unique<UserDefinedResource>(Type, read().value(),
- MemoryFlags);
+ MemoryFlags);
default:
break;
}
@@ -520,7 +520,7 @@ RCParser::ParseType RCParser::parseUserDefinedResource(IntOrString Type) {
}
return std::make_unique<UserDefinedResource>(Type, std::move(Data),
- MemoryFlags);
+ MemoryFlags);
}
RCParser::ParseType RCParser::parseVersionInfoResource() {
@@ -559,7 +559,8 @@ Expected<Control> RCParser::parseControl() {
IntOrString Class;
std::optional<IntWithNotMask> Style;
if (ClassUpper == "CONTROL") {
- // CONTROL text, id, class, style, x, y, width, height [, exstyle] [, helpID]
+ // CONTROL text, id, class, style, x, y, width, height [, exstyle] [,
+ // helpID]
ASSIGN_OR_RETURN(ClassStr, readString());
RETURN_IF_ERROR(consumeType(Kind::Comma));
Class = *ClassStr;
@@ -591,8 +592,8 @@ Expected<Control> RCParser::parseControl() {
HelpID = *Val;
}
- return Control(*ClassResult, Caption, *ID, (*Args)[0], (*Args)[1],
- (*Args)[2], (*Args)[3], Style, ExStyle, HelpID, Class);
+ return Control(*ClassResult, Caption, *ID, (*Args)[0], (*Args)[1], (*Args)[2],
+ (*Args)[3], Style, ExStyle, HelpID, Class);
}
RCParser::ParseType RCParser::parseBitmapResource() {
@@ -622,7 +623,7 @@ RCParser::ParseType RCParser::parseMenuResource() {
ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements());
ASSIGN_OR_RETURN(Items, parseMenuItemsList());
return std::make_unique<MenuResource>(std::move(*OptStatements),
- std::move(*Items), MemoryFlags);
+ std::move(*Items), MemoryFlags);
}
RCParser::ParseType RCParser::parseMenuExResource() {
@@ -696,10 +697,9 @@ Expected<MenuDefinitionList> RCParser::parseMenuExItemsList() {
MenuDefinitionList List;
- // Read a set of items. Each item is of one of three kinds:
+ // Read a set of items. Each item is of one of two kinds:
// MENUITEM caption:String [,[id][, [type][, state]]]]
// POPUP caption:String [,[id][, [type][, [state][, helpID]]]] { popupBody }
- // }
while (!consumeOptionalType(Kind::BlockEnd)) {
ASSIGN_OR_RETURN(ItemTypeResult, readIdentifier());
@@ -712,11 +712,11 @@ Expected<MenuDefinitionList> RCParser::parseMenuExItemsList() {
ASSIGN_OR_RETURN(CaptionResult, readString());
// If MENUITEM, expect [,[id][, [type][, state]]]]
- uint32_t MenuId = 0;
- uint32_t MenuType = 0;
- uint32_t MenuState = 0;
-
if (IsMenuItem) {
+ uint32_t MenuId = 0;
+ uint32_t MenuType = 0;
+ uint32_t MenuState = 0;
+
if (consumeOptionalType(Kind::Comma)) {
auto IntId = readInt();
if (IntId) {
@@ -735,48 +735,47 @@ Expected<MenuDefinitionList> RCParser::parseMenuExItemsList() {
}
}
}
+ List.addDefinition(std::make_unique<MenuExItem>(*CaptionResult, MenuId,
+ MenuType, MenuState));
+ continue;
}
+ assert(IsPopup);
+
uint32_t PopupId = 0;
uint32_t PopupType = 0;
uint32_t PopupState = 0;
uint32_t PopupHelpID = 0;
- if (IsPopup) {
+
+ if (consumeOptionalType(Kind::Comma)) {
+ auto IntId = readInt();
+ if (IntId) {
+ PopupId = *IntId;
+ }
if (consumeOptionalType(Kind::Comma)) {
- auto IntId = readInt();
- if (IntId) {
- PopupId = *IntId;
+ auto IntType = readInt();
+ if (IntType) {
+ PopupType = *IntType;
}
if (consumeOptionalType(Kind::Comma)) {
- auto IntType = readInt();
- if (IntType) {
- PopupType = *IntType;
+ auto IntState = readInt();
+ if (IntState) {
+ PopupState = *IntState;
}
if (consumeOptionalType(Kind::Comma)) {
- auto IntState = readInt();
- if (IntState) {
- PopupState = *IntState;
- }
- if (consumeOptionalType(Kind::Comma)) {
- auto IntHelpID = readInt();
- if (IntHelpID) {
- PopupHelpID = *IntHelpID;
- }
+ auto IntHelpID = readInt();
+ if (IntHelpID) {
+ PopupHelpID = *IntHelpID;
}
}
}
}
- // If POPUP, read submenu items recursively.
- ASSIGN_OR_RETURN(SubMenuResult, parseMenuExItemsList());
- List.addDefinition(std::make_unique<PopupExItem>(
- *CaptionResult, PopupId, PopupType, PopupState, PopupHelpID,
- std::move(*SubMenuResult)));
- continue;
}
-
- assert(IsMenuItem);
- List.addDefinition(std::make_unique<MenuExItem>(*CaptionResult, MenuId,
- MenuType, MenuState));
+ // If POPUP, read submenu items recursively.
+ ASSIGN_OR_RETURN(SubMenuResult, parseMenuExItemsList());
+ List.addDefinition(std::make_unique<PopupExItem>(
+ *CaptionResult, PopupId, PopupType, PopupState, PopupHelpID,
+ std::move(*SubMenuResult)));
}
return std::move(List);
@@ -789,7 +788,7 @@ RCParser::ParseType RCParser::parseStringTableResource() {
RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
auto Table = std::make_unique<StringTableResource>(std::move(*OptStatements),
- MemoryFlags);
+ MemoryFlags);
// Read strings until we reach the end of the block.
while (!consumeOptionalType(Kind::BlockEnd)) {
@@ -853,7 +852,7 @@ Expected<std::unique_ptr<VersionInfoStmt>> RCParser::parseVersionInfoStmt() {
PrecedingCommas.push_back(HadComma);
}
return std::make_unique<VersionInfoValue>(*KeyResult, std::move(Values),
- std::move(PrecedingCommas));
+ std::move(PrecedingCommas));
}
return getExpectedError("BLOCK or VALUE", true);
@@ -935,7 +934,7 @@ RCParser::ParseOptionType RCParser::parseFontStmt(OptStmtType DialogType) {
}
}
return std::make_unique<FontStmt>(*SizeResult, *NameResult, FontWeight,
- FontItalic, FontCharset);
+ FontItalic, FontCharset);
}
RCParser::ParseOptionType RCParser::parseStyleStmt() {
diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.cpp b/llvm/tools/llvm-rc/ResourceScriptStmt.cpp
index 768733f71319dac..62df7999252fe19 100644
--- a/llvm/tools/llvm-rc/ResourceScriptStmt.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptStmt.cpp
@@ -104,6 +104,7 @@ raw_ostream &MenuSeparator::log(raw_ostream &OS) const {
raw_ostream &MenuExItem::log(raw_ostream &OS) const {
OS << " MenuExItem (" << Name << "), ID = " << Id;
+ OS << ", type: " << Type << ", state: " << State;
return OS << "\n";
}
@@ -116,6 +117,7 @@ raw_ostream &PopupItem::log(raw_ostream &OS) const {
raw_ostream &PopupExItem::log(raw_ostream &OS) const {
OS << " Popup (" << Name << ")";
+ OS << ", type: " << Type << ", state: " << State << ", help ID: " << HelpId;
OS << ":\n";
return SubItems.log(OS);
}
More information about the llvm-commits
mailing list