Skip to content

Commit b35bdb1

Browse files
authored
llvm-rc: add support for MENU in DIALOG(EX) (#89409)
Adds support for `MENU` in `DIALOG(EX)` to `llvm-rc`. Fixes #49559.
1 parent 37f2928 commit b35bdb1

File tree

9 files changed

+86
-4
lines changed

9 files changed

+86
-4
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
101 DIALOG 0, 0, 362, 246
2+
STYLE 0x40l | 0x0004l | 0x0008l | 0x0800l | 0x00020000l |
3+
0x00010000l | 0x80000000l | 0x10000000l | 0x02000000l | 0x00C00000l |
4+
0x00080000l | 0x00040000l
5+
CAPTION "MakeNSISW"
6+
MENU 104
7+
FONT 8, "MS Shell Dlg"
8+
BEGIN
9+
CONTROL "",202,"RichEdit20A",0x0004l | 0x0040l |
10+
0x0100l | 0x0800l | 0x00008000 |
11+
0x00010000l | 0x00800000l | 0x00200000l,7,22,348,190
12+
CONTROL "",-1,"Static",0x00000010l,7,220,346,1
13+
LTEXT "",200,7,230,200,12,0x08000000l
14+
DEFPUSHBUTTON "Test &Installer",203,230,226,60,15,0x08000000l | 0x00010000l
15+
PUSHBUTTON "&Close",2,296,226,49,15,0x00010000l
16+
END
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; RUN: llvm-rc -no-preprocess /FO %t -- %p/Inputs/dialog-with-menu.rc
2+
; RUN: llvm-readobj %t | FileCheck %s
3+
4+
CHECK: Resource type (int): DIALOG (ID 5)
5+
CHECK-NEXT: Resource name (int): 101
6+
CHECK-NEXT: Data version: 0
7+
CHECK-NEXT: Memory flags: 0x1030
8+
CHECK-NEXT: Language ID: 1033
9+
CHECK-NEXT: Version (major): 0
10+
CHECK-NEXT: Version (minor): 0
11+
CHECK-NEXT: Characteristics: 0
12+
CHECK-NEXT: Data size: 278
13+
CHECK-NEXT: Data: (
14+
CHECK-NEXT: 0000: 4C08CF92 00000000 05000000 00006A01 |L.............j.|
15+
CHECK-NEXT: 0010: F600FFFF 68000000 4D006100 6B006500 |....h...M.a.k.e.|
16+
CHECK-NEXT: 0020: 4E005300 49005300 57000000 08004D00 |N.S.I.S.W.....M.|
17+
CHECK-NEXT: 0030: 53002000 53006800 65006C00 6C002000 |S. .S.h.e.l.l. .|
18+
CHECK-NEXT: 0040: 44006C00 67000000 4489A150 00000000 |D.l.g...D..P....|
19+
CHECK-NEXT: 0050: 07001600 5C01BE00 CA005200 69006300 |....\.....R.i.c.|
20+
CHECK-NEXT: 0060: 68004500 64006900 74003200 30004100 |h.E.d.i.t.2.0.A.|
21+
CHECK-NEXT: 0070: 00000000 00000000 10000050 00000000 |...........P....|
22+
CHECK-NEXT: 0080: 0700DC00 5A010100 FFFF5300 74006100 |....Z.....S.t.a.|
23+
CHECK-NEXT: 0090: 74006900 63000000 00000000 00000258 |t.i.c..........X|
24+
CHECK-NEXT: 00A0: 00000000 0700E600 C8000C00 C800FFFF |................|
25+
CHECK-NEXT: 00B0: 82000000 00000000 01000158 00000000 |...........X....|
26+
CHECK-NEXT: 00C0: E600E200 3C000F00 CB00FFFF 80005400 |....<.........T.|
27+
CHECK-NEXT: 00D0: 65007300 74002000 26004900 6E007300 |e.s.t. .&.I.n.s.|
28+
CHECK-NEXT: 00E0: 74006100 6C006C00 65007200 00000000 |t.a.l.l.e.r.....|
29+
CHECK-NEXT: 00F0: 00000150 00000000 2801E200 31000F00 |...P....(...1...|
30+
CHECK-NEXT: 0100: 0200FFFF 80002600 43006C00 6F007300 |......&.C.l.o.s.|
31+
CHECK-NEXT: 0110: 65000000 0000 |e.....|
32+
CHECK-NEXT: )

llvm/tools/llvm-rc/ResourceFileWriter.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,11 @@ Error ResourceFileWriter::visitVersionStmt(const VersionStmt *Stmt) {
550550
return Error::success();
551551
}
552552

553+
Error ResourceFileWriter::visitMenuStmt(const MenuStmt *Stmt) {
554+
ObjectData.Menu = Stmt->Value;
555+
return Error::success();
556+
}
557+
553558
Error ResourceFileWriter::writeResource(
554559
const RCResource *Res,
555560
Error (ResourceFileWriter::*BodyWriter)(const RCResource *)) {
@@ -1132,9 +1137,8 @@ Error ResourceFileWriter::writeDialogBody(const RCResource *Base) {
11321137
ulittle16_t(Res->Height)};
11331138
writeObject(Middle);
11341139

1135-
// MENU field. As of now, we don't keep them in the state and can peacefully
1136-
// think there is no menu attached to the dialog.
1137-
writeInt<uint16_t>(0);
1140+
// MENU field.
1141+
RETURN_IF_ERROR(writeIntOrString(ObjectData.Menu));
11381142

11391143
// Window CLASS field.
11401144
RETURN_IF_ERROR(writeIntOrString(ObjectData.Class));

llvm/tools/llvm-rc/ResourceFileWriter.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "ResourceScriptStmt.h"
1717
#include "ResourceVisitor.h"
1818

19+
#include "llvm/ADT/StringRef.h"
1920
#include "llvm/Support/Endian.h"
2021

2122
namespace llvm {
@@ -68,6 +69,7 @@ class ResourceFileWriter : public Visitor {
6869
Error visitLanguageStmt(const LanguageResource *) override;
6970
Error visitStyleStmt(const StyleStmt *) override;
7071
Error visitVersionStmt(const VersionStmt *) override;
72+
Error visitMenuStmt(const MenuStmt *) override;
7173

7274
// Stringtables are output at the end of .res file. We need a separate
7375
// function to do it.
@@ -92,10 +94,11 @@ class ResourceFileWriter : public Visitor {
9294
};
9395
std::optional<FontInfo> Font;
9496
IntOrString Class;
97+
IntOrString Menu;
9598

9699
ObjectInfo()
97100
: LanguageInfo(0), Characteristics(0), VersionInfo(0),
98-
Class(StringRef()) {}
101+
Class(StringRef()), Menu(StringRef()) {}
99102
} ObjectData;
100103

101104
struct StringTableInfo {

llvm/tools/llvm-rc/ResourceScriptParser.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,8 @@ RCParser::parseSingleOptionalStatement(OptStmtType StmtsType) {
430430
return parseFontStmt(StmtsType);
431431
if (TypeToken->equals_insensitive("STYLE"))
432432
return parseStyleStmt();
433+
if (TypeToken->equals_insensitive("MENU"))
434+
return parseMenuStmt();
433435
}
434436

435437
return getExpectedError("optional statement type, BEGIN or '{'",
@@ -965,6 +967,11 @@ RCParser::ParseOptionType RCParser::parseExStyleStmt() {
965967
return std::make_unique<ExStyleStmt>(*Arg);
966968
}
967969

970+
RCParser::ParseOptionType RCParser::parseMenuStmt() {
971+
ASSIGN_OR_RETURN(Arg, readIntOrString());
972+
return std::make_unique<MenuStmt>(*Arg);
973+
}
974+
968975
Error RCParser::getExpectedError(const Twine &Message, bool IsAlreadyRead) {
969976
return make_error<ParserError>(
970977
Message, IsAlreadyRead ? std::prev(CurLoc) : CurLoc, End);

llvm/tools/llvm-rc/ResourceScriptParser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ class RCParser {
176176
ParseOptionType parseExStyleStmt();
177177
ParseOptionType parseFontStmt(OptStmtType DialogType);
178178
ParseOptionType parseStyleStmt();
179+
ParseOptionType parseMenuStmt();
179180

180181
// Raises an error. If IsAlreadyRead = false (default), this complains about
181182
// the token that couldn't be parsed. If the flag is on, this complains about

llvm/tools/llvm-rc/ResourceScriptStmt.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,5 +309,9 @@ raw_ostream &ExStyleStmt::log(raw_ostream &OS) const {
309309
return OS << "ExStyle: " << Value << "\n";
310310
}
311311

312+
raw_ostream &MenuStmt::log(raw_ostream &OS) const {
313+
return OS << "Menu: " << Value << "\n";
314+
}
315+
312316
} // namespace rc
313317
} // namespace llvm

llvm/tools/llvm-rc/ResourceScriptStmt.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,19 @@ class ExStyleStmt : public OptionalStmt {
993993
Error visit(Visitor *V) const override { return V->visitExStyleStmt(this); }
994994
};
995995

996+
// MENU optional statement.
997+
//
998+
// Ref: https://learn.microsoft.com/en-us/windows/win32/menurc/menu-statement
999+
class MenuStmt : public OptionalStmt {
1000+
public:
1001+
IntOrString Value;
1002+
1003+
MenuStmt(IntOrString NameOrId) : Value(NameOrId) {}
1004+
raw_ostream &log(raw_ostream &) const override;
1005+
Twine getResourceTypeName() const override { return "MENU"; }
1006+
Error visit(Visitor *V) const override { return V->visitMenuStmt(this); }
1007+
};
1008+
9961009
// CLASS optional statement.
9971010
//
9981011
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380883(v=vs.85).aspx

llvm/tools/llvm-rc/ResourceVisitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class FontStmt;
2828
class LanguageResource;
2929
class StyleStmt;
3030
class VersionStmt;
31+
class MenuStmt;
3132

3233
class Visitor {
3334
public:
@@ -52,6 +53,7 @@ class Visitor {
5253
virtual Error visitLanguageStmt(const LanguageResource *) = 0;
5354
virtual Error visitStyleStmt(const StyleStmt *) = 0;
5455
virtual Error visitVersionStmt(const VersionStmt *) = 0;
56+
virtual Error visitMenuStmt(const MenuStmt *) = 0;
5557

5658
virtual ~Visitor() {}
5759
};

0 commit comments

Comments
 (0)