summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-rc/ResourceFileWriter.cpp
diff options
context:
space:
mode:
authorMarek Sokolowski <mnbvmar@gmail.com>2017-09-29 22:25:05 +0000
committerMarek Sokolowski <mnbvmar@gmail.com>2017-09-29 22:25:05 +0000
commit42f494d6a65d0dfe5a62cdf2c15d6e71745237ef (patch)
tree0f35b053337f1ba506c8c7d9fec826f44adb1166 /llvm/tools/llvm-rc/ResourceFileWriter.cpp
parent5b9d96825b86fdd4063d03f78cc8fa5db9ba4f2c (diff)
downloadbcm5719-llvm-42f494d6a65d0dfe5a62cdf2c15d6e71745237ef.tar.gz
bcm5719-llvm-42f494d6a65d0dfe5a62cdf2c15d6e71745237ef.zip
[llvm-rc] Serialize MENU resources to .res files (serialization, pt 3).
This allows MENU resources to be serialized. MENU resource statement doc: msdn.microsoft.com/en-us/library/windows/desktop/aa381025.aspx POPUP sub-statement doc: msdn.microsoft.com/en-us/library/windows/desktop/aa381030.aspx MENUITEM sub-statement doc: msdn.microsoft.com/en-us/library/windows/desktop/aa381024.aspx MENUHEADER structure: msdn.microsoft.com/en-us/library/windows/desktop/ms648018.aspx (and NORMALMENUITEM, POPUPMENUITEM structs). Thanks for Nico Weber for his original work in this area. Differential Revision: https://reviews.llvm.org/D37828 llvm-svn: 314562
Diffstat (limited to 'llvm/tools/llvm-rc/ResourceFileWriter.cpp')
-rw-r--r--llvm/tools/llvm-rc/ResourceFileWriter.cpp54
1 files changed, 54 insertions, 0 deletions
diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.cpp b/llvm/tools/llvm-rc/ResourceFileWriter.cpp
index f8ba2a7694a..af002e347be 100644
--- a/llvm/tools/llvm-rc/ResourceFileWriter.cpp
+++ b/llvm/tools/llvm-rc/ResourceFileWriter.cpp
@@ -205,6 +205,10 @@ Error ResourceFileWriter::visitHTMLResource(const RCResource *Res) {
return writeResource(Res, &ResourceFileWriter::writeHTMLBody);
}
+Error ResourceFileWriter::visitMenuResource(const RCResource *Res) {
+ return writeResource(Res, &ResourceFileWriter::writeMenuBody);
+}
+
Error ResourceFileWriter::visitCharacteristicsStmt(
const CharacteristicsStmt *Stmt) {
ObjectData.Characteristics = Stmt->Value;
@@ -382,5 +386,55 @@ Error ResourceFileWriter::writeHTMLBody(const RCResource *Base) {
return appendFile(cast<HTMLResource>(Base)->HTMLLoc);
}
+// --- MenuResource helpers. --- //
+
+Error ResourceFileWriter::writeMenuDefinition(
+ const std::unique_ptr<MenuDefinition> &Def, uint16_t Flags) {
+ assert(Def);
+ const MenuDefinition *DefPtr = Def.get();
+
+ if (auto *MenuItemPtr = dyn_cast<MenuItem>(DefPtr)) {
+ writeInt<uint16_t>(Flags);
+ RETURN_IF_ERROR(
+ checkNumberFits<uint16_t>(MenuItemPtr->Id, "MENUITEM action ID"));
+ writeInt<uint16_t>(MenuItemPtr->Id);
+ RETURN_IF_ERROR(writeCString(MenuItemPtr->Name));
+ return Error::success();
+ }
+
+ if (isa<MenuSeparator>(DefPtr)) {
+ writeInt<uint16_t>(Flags);
+ writeInt<uint32_t>(0);
+ return Error::success();
+ }
+
+ auto *PopupPtr = cast<PopupItem>(DefPtr);
+ writeInt<uint16_t>(Flags);
+ RETURN_IF_ERROR(writeCString(PopupPtr->Name));
+ return writeMenuDefinitionList(PopupPtr->SubItems);
+}
+
+Error ResourceFileWriter::writeMenuDefinitionList(
+ 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(writeMenuDefinition(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
+ writeObject<uint32_t>(0);
+
+ return writeMenuDefinitionList(cast<MenuResource>(Base)->Elements);
+}
+
} // namespace rc
} // namespace llvm
OpenPOWER on IntegriCloud