[llvm-rc] Serialize ACCELERATORS to .res files (serialization, pt 2).
This allows llvm-rc to serialize ACCELERATORS resources.
Additionally, as this is the first type of resource to support basic
optional resource statements (LANGUAGE, CHARACTERISTICS, VERSION),
ACCELERATORS statement documentation:
msdn.microsoft.com/en-us/library/windows/desktop/aa380610.aspx
Accelerator table structure documentation:
msdn.microsoft.com/en-us/library/windows/desktop/ms648010.aspx
Optional resource statement fields are described in:
msdn.microsoft.com/en-us/library/windows/desktop/ms648027.aspx
Thanks for Nico Weber for his original work in this area.
Differential Revision: https://reviews.llvm.org/D37824
llvm-svn: 314549
diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.h b/llvm/tools/llvm-rc/ResourceScriptStmt.h
index 90fe0ac..6f83d72 100644
--- a/llvm/tools/llvm-rc/ResourceScriptStmt.h
+++ b/llvm/tools/llvm-rc/ResourceScriptStmt.h
@@ -104,9 +104,6 @@
class RCResource {
public:
IntOrString ResName;
-
- RCResource() = default;
- RCResource(RCResource &&) = default;
void setName(const IntOrString &Name) { ResName = Name; }
virtual raw_ostream &log(raw_ostream &OS) const {
return OS << "Base statement\n";
@@ -117,6 +114,10 @@
llvm_unreachable("This is unable to call methods from Visitor base");
}
+ // Apply the statements attached to this resource. Generic resources
+ // don't have any.
+ virtual Error applyStmts(Visitor *) const { return Error::success(); }
+
// By default, memory flags are DISCARDABLE | PURE | MOVEABLE.
virtual uint16_t getMemoryFlags() const {
return MfDiscardable | MfPure | MfMoveable;
@@ -153,11 +154,18 @@
public:
OptionalStmtList() {}
- virtual raw_ostream &log(raw_ostream &OS) const;
+ raw_ostream &log(raw_ostream &OS) const override;
void addStmt(std::unique_ptr<OptionalStmt> Stmt) {
Statements.push_back(std::move(Stmt));
}
+
+ Error visit(Visitor *V) const override {
+ for (auto &StmtPtr : Statements)
+ if (auto Err = StmtPtr->visit(V))
+ return Err;
+ return Error::success();
+ }
};
class OptStatementsRCResource : public RCResource {
@@ -166,6 +174,8 @@
OptStatementsRCResource(OptionalStmtList &&Stmts)
: OptStatements(llvm::make_unique<OptionalStmtList>(std::move(Stmts))) {}
+
+ virtual Error applyStmts(Visitor *V) const { return OptStatements->visit(V); }
};
// LANGUAGE statement. It can occur both as a top-level statement (in such
@@ -218,14 +228,27 @@
static uint32_t OptionsFlags[NumFlags];
};
+ std::vector<Accelerator> Accelerators;
+
using OptStatementsRCResource::OptStatementsRCResource;
void addAccelerator(IntOrString Event, uint32_t Id, uint16_t Flags) {
Accelerators.push_back(Accelerator{Event, Id, Flags});
}
raw_ostream &log(raw_ostream &) const override;
-private:
- std::vector<Accelerator> Accelerators;
+ IntOrString getResourceType() const override { return RkAccelerators; }
+ uint16_t getMemoryFlags() const override {
+ return MfPure | MfMoveable;
+ }
+ Twine getResourceTypeName() const override { return "ACCELERATORS"; }
+
+ Error visit(Visitor *V) const override {
+ return V->visitAcceleratorsResource(this);
+ }
+ ResourceKind getKind() const override { return RkAccelerators; }
+ static bool classof(const RCResource *Res) {
+ return Res->getKind() == RkAccelerators;
+ }
};
// CURSOR resource. Represents a single cursor (".cur") file.
@@ -546,22 +569,30 @@
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380872(v=vs.85).aspx
class CharacteristicsStmt : public OptionalStmt {
+public:
uint32_t Value;
-public:
CharacteristicsStmt(uint32_t Characteristic) : Value(Characteristic) {}
raw_ostream &log(raw_ostream &) const override;
+
+ Twine getResourceTypeName() const override { return "CHARACTERISTICS"; }
+ Error visit(Visitor *V) const override {
+ return V->visitCharacteristicsStmt(this);
+ }
};
// VERSION optional statement.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381059(v=vs.85).aspx
class VersionStmt : public OptionalStmt {
+public:
uint32_t Value;
-public:
VersionStmt(uint32_t Version) : Value(Version) {}
raw_ostream &log(raw_ostream &) const override;
+
+ Twine getResourceTypeName() const override { return "VERSION"; }
+ Error visit(Visitor *V) const override { return V->visitVersionStmt(this); }
};
// CAPTION optional statement.