[llvm] [llvm-rc] Add support for multiplication and division in expressions (PR #143373)
Martin Storsjö via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 9 05:00:13 PDT 2025
https://github.com/mstorsjo created https://github.com/llvm/llvm-project/pull/143373
This is supported by both MS rc.exe and GNU windres.
This fixes one aspect of
https://github.com/llvm/llvm-project/issues/143157.
>From 8fc808134a60591a00feef8a4bc0fa305fe6bc65 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Mon, 9 Jun 2025 00:11:33 +0300
Subject: [PATCH] [llvm-rc] Add support for multiplication and division in
expressions
This is supported by both MS rc.exe and GNU windres.
This fixes one aspect of
https://github.com/llvm/llvm-project/issues/143157.
---
llvm/test/tools/llvm-rc/Inputs/parser-expr.rc | 2 ++
llvm/test/tools/llvm-rc/Inputs/tokens.rc | 1 +
llvm/test/tools/llvm-rc/parser-expr.test | 2 ++
llvm/test/tools/llvm-rc/tokenizer.test | 5 ++++
llvm/tools/llvm-rc/ResourceScriptParser.cpp | 11 ++++++++-
llvm/tools/llvm-rc/ResourceScriptStmt.h | 24 +++++++++++++++++++
llvm/tools/llvm-rc/ResourceScriptToken.cpp | 2 ++
.../tools/llvm-rc/ResourceScriptTokenList.def | 2 ++
8 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/llvm/test/tools/llvm-rc/Inputs/parser-expr.rc b/llvm/test/tools/llvm-rc/Inputs/parser-expr.rc
index 8e69c1cd1fa16..54767c8a24059 100644
--- a/llvm/test/tools/llvm-rc/Inputs/parser-expr.rc
+++ b/llvm/test/tools/llvm-rc/Inputs/parser-expr.rc
@@ -5,6 +5,8 @@ LANGUAGE 1|1&0, 0&0|1
LANGUAGE 3+4-5, 3-4+5
LANGUAGE 1+2|3, 3|1+2
LANGUAGE 6&~5, 6&-8
+LANGUAGE 7/3, 7*3
+LANGUAGE (5/2)*2, (7*3)/4
LANGUAGE -1, --1
LANGUAGE ----1, -----1
LANGUAGE ~1, ~~1
diff --git a/llvm/test/tools/llvm-rc/Inputs/tokens.rc b/llvm/test/tools/llvm-rc/Inputs/tokens.rc
index 6a781202a7e37..20f77912477d9 100644
--- a/llvm/test/tools/llvm-rc/Inputs/tokens.rc
+++ b/llvm/test/tools/llvm-rc/Inputs/tokens.rc
@@ -1,4 +1,5 @@
1 + 2 - 3214L & 0x120894 032173 2|&~+(-7){0xabcdef 0xABCDEFl} Begin End
+1*3/4
He11o LLVM
identifier-with-dashes
diff --git a/llvm/test/tools/llvm-rc/parser-expr.test b/llvm/test/tools/llvm-rc/parser-expr.test
index ed6796529fdfa..184edeb6decea 100644
--- a/llvm/test/tools/llvm-rc/parser-expr.test
+++ b/llvm/test/tools/llvm-rc/parser-expr.test
@@ -7,6 +7,8 @@
; CHECK-NEXT: Language: 2, Sublanguage: 4
; CHECK-NEXT: Language: 3, Sublanguage: 5
; CHECK-NEXT: Language: 2, Sublanguage: 0
+; CHECK-NEXT: Language: 2, Sublanguage: 21
+; CHECK-NEXT: Language: 4, Sublanguage: 5
; CHECK-NEXT: Language: 4294967295, Sublanguage: 1
; CHECK-NEXT: Language: 1, Sublanguage: 4294967295
; CHECK-NEXT: Language: 4294967294, Sublanguage: 1
diff --git a/llvm/test/tools/llvm-rc/tokenizer.test b/llvm/test/tools/llvm-rc/tokenizer.test
index 8486f8bd78690..82531eaa52447 100644
--- a/llvm/test/tools/llvm-rc/tokenizer.test
+++ b/llvm/test/tools/llvm-rc/tokenizer.test
@@ -25,6 +25,11 @@
; CHECK-NEXT: BlockEnd: }
; CHECK-NEXT: BlockBegin: Begin
; CHECK-NEXT: BlockEnd: End
+; CHECK-NEXT: Int: 1; int value = 1
+; CHECK-NEXT: Times: *
+; CHECK-NEXT: Int: 3; int value = 3
+; CHECK-NEXT: Slash: /
+; CHECK-NEXT: Int: 4; int value = 4
; CHECK-NEXT: Identifier: He11o
; CHECK-NEXT: Identifier: LLVM
; CHECK-NEXT: Identifier: identifier-with-dashes
diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.cpp b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
index 69798152c1f25..a8d63cada1c09 100644
--- a/llvm/tools/llvm-rc/ResourceScriptParser.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
@@ -154,7 +154,8 @@ Expected<RCInt> RCParser::readInt() {
}
Expected<IntWithNotMask> RCParser::parseIntExpr1() {
- // Exp1 ::= Exp2 || Exp1 + Exp2 || Exp1 - Exp2 || Exp1 | Exp2 || Exp1 & Exp2.
+ // Exp1 ::= Exp2 || Exp1 + Exp2 || Exp1 - Exp2 || Exp1 | Exp2 || Exp1 & Exp2
+ // || Exp1 * Exp2 || Exp1 / Exp2.
ASSIGN_OR_RETURN(FirstResult, parseIntExpr2());
IntWithNotMask Result = *FirstResult;
@@ -171,6 +172,14 @@ Expected<IntWithNotMask> RCParser::parseIntExpr1() {
Result -= *NextResult;
break;
+ case Kind::Times:
+ Result *= *NextResult;
+ break;
+
+ case Kind::Slash:
+ Result /= *NextResult;
+ break;
+
case Kind::Pipe:
Result |= *NextResult;
break;
diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.h b/llvm/tools/llvm-rc/ResourceScriptStmt.h
index 8f099202c0b47..a81e384fda365 100644
--- a/llvm/tools/llvm-rc/ResourceScriptStmt.h
+++ b/llvm/tools/llvm-rc/ResourceScriptStmt.h
@@ -49,6 +49,16 @@ class RCInt {
return *this;
}
+ RCInt &operator*=(const RCInt &Rhs) {
+ std::tie(Val, Long) = std::make_pair(Val * Rhs.Val, Long | Rhs.Long);
+ return *this;
+ }
+
+ RCInt &operator/=(const RCInt &Rhs) {
+ std::tie(Val, Long) = std::make_pair(Val / Rhs.Val, Long | Rhs.Long);
+ return *this;
+ }
+
RCInt &operator|=(const RCInt &Rhs) {
std::tie(Val, Long) = std::make_pair(Val | Rhs.Val, Long | Rhs.Long);
return *this;
@@ -98,6 +108,20 @@ class IntWithNotMask {
return *this;
}
+ IntWithNotMask &operator*=(const IntWithNotMask &Rhs) {
+ Value &= ~Rhs.NotMask;
+ Value *= Rhs.Value;
+ NotMask |= Rhs.NotMask;
+ return *this;
+ }
+
+ IntWithNotMask &operator/=(const IntWithNotMask &Rhs) {
+ Value &= ~Rhs.NotMask;
+ Value /= Rhs.Value;
+ NotMask |= Rhs.NotMask;
+ return *this;
+ }
+
IntWithNotMask &operator|=(const IntWithNotMask &Rhs) {
Value &= ~Rhs.NotMask;
Value |= Rhs.Value;
diff --git a/llvm/tools/llvm-rc/ResourceScriptToken.cpp b/llvm/tools/llvm-rc/ResourceScriptToken.cpp
index aad1060c4a381..df755a1b35752 100644
--- a/llvm/tools/llvm-rc/ResourceScriptToken.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptToken.cpp
@@ -70,6 +70,8 @@ bool RCToken::isBinaryOp() const {
case Kind::Minus:
case Kind::Pipe:
case Kind::Amp:
+ case Kind::Times:
+ case Kind::Slash:
return true;
default:
return false;
diff --git a/llvm/tools/llvm-rc/ResourceScriptTokenList.def b/llvm/tools/llvm-rc/ResourceScriptTokenList.def
index a61a96461f0fb..8641920ee99f3 100644
--- a/llvm/tools/llvm-rc/ResourceScriptTokenList.def
+++ b/llvm/tools/llvm-rc/ResourceScriptTokenList.def
@@ -29,6 +29,8 @@ SHORT_TOKEN(BlockEnd, '}') // End of the block; can also be END.
SHORT_TOKEN(Comma, ',') // Comma - resource arguments separator.
SHORT_TOKEN(Plus, '+') // Addition operator.
SHORT_TOKEN(Minus, '-') // Subtraction operator.
+SHORT_TOKEN(Times, '*') // Multiplication operator.
+SHORT_TOKEN(Slash, '/') // Division operator.
SHORT_TOKEN(Pipe, '|') // Bitwise-OR operator.
SHORT_TOKEN(Amp, '&') // Bitwise-AND operator.
SHORT_TOKEN(Tilde, '~') // Bitwise-NOT operator.
More information about the llvm-commits
mailing list