123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953 |
- //===-- ResourceScriptStmt.h ------------------------------------*- C++-*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===---------------------------------------------------------------------===//
- //
- // This lists all the resource and statement types occurring in RC scripts.
- //
- //===---------------------------------------------------------------------===//
- #ifndef LLVM_TOOLS_LLVMRC_RESOURCESCRIPTSTMT_H
- #define LLVM_TOOLS_LLVMRC_RESOURCESCRIPTSTMT_H
- #include "ResourceScriptToken.h"
- #include "ResourceVisitor.h"
- #include "llvm/ADT/StringSet.h"
- namespace llvm {
- namespace rc {
- // Integer wrapper that also holds information whether the user declared
- // the integer to be long (by appending L to the end of the integer) or not.
- // It allows to be implicitly cast from and to uint32_t in order
- // to be compatible with the parts of code that don't care about the integers
- // being marked long.
- class RCInt {
- uint32_t Val;
- bool Long;
- public:
- RCInt(const RCToken &Token)
- : Val(Token.intValue()), Long(Token.isLongInt()) {}
- RCInt(uint32_t Value) : Val(Value), Long(false) {}
- RCInt(uint32_t Value, bool IsLong) : Val(Value), Long(IsLong) {}
- operator uint32_t() const { return Val; }
- bool isLong() const { return Long; }
- 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;
- }
- RCInt &operator&=(const RCInt &Rhs) {
- std::tie(Val, Long) = std::make_pair(Val & Rhs.Val, Long | Rhs.Long);
- return *this;
- }
- RCInt operator-() const { return {-Val, Long}; }
- RCInt operator~() const { return {~Val, Long}; }
- friend raw_ostream &operator<<(raw_ostream &OS, const RCInt &Int) {
- return OS << Int.Val << (Int.Long ? "L" : "");
- }
- };
- class IntWithNotMask {
- private:
- RCInt Value;
- int32_t NotMask;
- public:
- IntWithNotMask() : IntWithNotMask(RCInt(0)) {}
- IntWithNotMask(RCInt Value, int32_t NotMask = 0) : Value(Value), NotMask(NotMask) {}
- RCInt getValue() const {
- return Value;
- }
- uint32_t getNotMask() const {
- return NotMask;
- }
- 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;
- NotMask |= Rhs.NotMask;
- return *this;
- }
- IntWithNotMask &operator&=(const IntWithNotMask &Rhs) {
- Value &= ~Rhs.NotMask;
- Value &= Rhs.Value;
- NotMask |= Rhs.NotMask;
- return *this;
- }
- IntWithNotMask operator-() const { return {-Value, NotMask}; }
- IntWithNotMask operator~() const { return {~Value, 0}; }
- friend raw_ostream &operator<<(raw_ostream &OS, const IntWithNotMask &Int) {
- return OS << Int.Value;
- }
- };
- // A class holding a name - either an integer or a reference to the string.
- class IntOrString {
- private:
- union Data {
- RCInt Int;
- StringRef String;
- Data(RCInt Value) : Int(Value) {}
- Data(const StringRef Value) : String(Value) {}
- Data(const RCToken &Token) {
- if (Token.kind() == RCToken::Kind::Int)
- Int = RCInt(Token);
- else
- String = Token.value();
- }
- } Data;
- bool IsInt;
- public:
- IntOrString() : IntOrString(RCInt(0)) {}
- IntOrString(uint32_t Value) : Data(Value), IsInt(1) {}
- IntOrString(RCInt Value) : Data(Value), IsInt(1) {}
- IntOrString(StringRef Value) : Data(Value), IsInt(0) {}
- IntOrString(const RCToken &Token)
- : Data(Token), IsInt(Token.kind() == RCToken::Kind::Int) {}
- bool equalsLower(const char *Str) {
- return !IsInt && Data.String.equals_lower(Str);
- }
- bool isInt() const { return IsInt; }
- RCInt getInt() const {
- assert(IsInt);
- return Data.Int;
- }
- const StringRef &getString() const {
- assert(!IsInt);
- return Data.String;
- }
- operator Twine() const {
- return isInt() ? Twine(getInt()) : Twine(getString());
- }
- friend raw_ostream &operator<<(raw_ostream &, const IntOrString &);
- };
- enum ResourceKind {
- // These resource kinds have corresponding .res resource type IDs
- // (TYPE in RESOURCEHEADER structure). The numeric value assigned to each
- // kind is equal to this type ID.
- RkNull = 0,
- RkSingleCursor = 1,
- RkBitmap = 2,
- RkSingleIcon = 3,
- RkMenu = 4,
- RkDialog = 5,
- RkStringTableBundle = 6,
- RkAccelerators = 9,
- RkRcData = 10,
- RkCursorGroup = 12,
- RkIconGroup = 14,
- RkVersionInfo = 16,
- RkHTML = 23,
- // These kinds don't have assigned type IDs (they might be the resources
- // of invalid kind, expand to many resource structures in .res files,
- // or have variable type ID). In order to avoid ID clashes with IDs above,
- // we assign the kinds the values 256 and larger.
- RkInvalid = 256,
- RkBase,
- RkCursor,
- RkIcon,
- RkStringTable,
- RkUser,
- RkSingleCursorOrIconRes,
- RkCursorOrIconGroupRes,
- };
- // Non-zero memory flags.
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648027(v=vs.85).aspx
- enum MemoryFlags {
- MfMoveable = 0x10,
- MfPure = 0x20,
- MfPreload = 0x40,
- MfDiscardable = 0x1000
- };
- // Base resource. All the resources should derive from this base.
- class RCResource {
- public:
- IntOrString ResName;
- uint16_t MemoryFlags = getDefaultMemoryFlags();
- void setName(const IntOrString &Name) { ResName = Name; }
- virtual raw_ostream &log(raw_ostream &OS) const {
- return OS << "Base statement\n";
- };
- RCResource() {}
- RCResource(uint16_t Flags) : MemoryFlags(Flags) {}
- virtual ~RCResource() {}
- virtual Error visit(Visitor *) const {
- 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.
- static uint16_t getDefaultMemoryFlags() {
- return MfDiscardable | MfPure | MfMoveable;
- }
- virtual ResourceKind getKind() const { return RkBase; }
- static bool classof(const RCResource *Res) { return true; }
- virtual IntOrString getResourceType() const {
- llvm_unreachable("This cannot be called on objects without types.");
- }
- virtual Twine getResourceTypeName() const {
- llvm_unreachable("This cannot be called on objects without types.");
- };
- };
- // An empty resource. It has no content, type 0, ID 0 and all of its
- // characteristics are equal to 0.
- class NullResource : public RCResource {
- public:
- NullResource() : RCResource(0) {}
- raw_ostream &log(raw_ostream &OS) const override {
- return OS << "Null resource\n";
- }
- Error visit(Visitor *V) const override { return V->visitNullResource(this); }
- IntOrString getResourceType() const override { return 0; }
- Twine getResourceTypeName() const override { return "(NULL)"; }
- };
- // Optional statement base. All such statements should derive from this base.
- class OptionalStmt : public RCResource {};
- class OptionalStmtList : public OptionalStmt {
- std::vector<std::unique_ptr<OptionalStmt>> Statements;
- public:
- OptionalStmtList() {}
- 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 {
- public:
- std::unique_ptr<OptionalStmtList> OptStatements;
- OptStatementsRCResource(OptionalStmtList &&Stmts,
- uint16_t Flags = RCResource::getDefaultMemoryFlags())
- : RCResource(Flags),
- OptStatements(std::make_unique<OptionalStmtList>(std::move(Stmts))) {}
- Error applyStmts(Visitor *V) const override {
- return OptStatements->visit(V);
- }
- };
- // LANGUAGE statement. It can occur both as a top-level statement (in such
- // a situation, it changes the default language until the end of the file)
- // and as an optional resource statement (then it changes the language
- // of a single resource).
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381019(v=vs.85).aspx
- class LanguageResource : public OptionalStmt {
- public:
- uint32_t Lang, SubLang;
- LanguageResource(uint32_t LangId, uint32_t SubLangId)
- : Lang(LangId), SubLang(SubLangId) {}
- raw_ostream &log(raw_ostream &) const override;
- // This is not a regular top-level statement; when it occurs, it just
- // modifies the language context.
- Error visit(Visitor *V) const override { return V->visitLanguageStmt(this); }
- Twine getResourceTypeName() const override { return "LANGUAGE"; }
- };
- // ACCELERATORS resource. Defines a named table of accelerators for the app.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380610(v=vs.85).aspx
- class AcceleratorsResource : public OptStatementsRCResource {
- public:
- class Accelerator {
- public:
- IntOrString Event;
- uint32_t Id;
- uint16_t Flags;
- enum Options {
- // This is actually 0x0000 (accelerator is assumed to be ASCII if it's
- // not VIRTKEY). However, rc.exe behavior is different in situations
- // "only ASCII defined" and "neither ASCII nor VIRTKEY defined".
- // Therefore, we include ASCII as another flag. This must be zeroed
- // when serialized.
- ASCII = 0x8000,
- VIRTKEY = 0x0001,
- NOINVERT = 0x0002,
- ALT = 0x0010,
- SHIFT = 0x0004,
- CONTROL = 0x0008
- };
- static constexpr size_t NumFlags = 6;
- static StringRef OptionsStr[NumFlags];
- static uint32_t OptionsFlags[NumFlags];
- };
- AcceleratorsResource(OptionalStmtList &&List, uint16_t Flags)
- : OptStatementsRCResource(std::move(List), Flags) {}
- std::vector<Accelerator> Accelerators;
- void addAccelerator(IntOrString Event, uint32_t Id, uint16_t Flags) {
- Accelerators.push_back(Accelerator{Event, Id, Flags});
- }
- raw_ostream &log(raw_ostream &) const override;
- IntOrString getResourceType() const override { return RkAccelerators; }
- static uint16_t getDefaultMemoryFlags() { 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;
- }
- };
- // BITMAP resource. Represents a bitmap (".bmp") file.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380680(v=vs.85).aspx
- class BitmapResource : public RCResource {
- public:
- StringRef BitmapLoc;
- BitmapResource(StringRef Location, uint16_t Flags)
- : RCResource(Flags), BitmapLoc(Location) {}
- raw_ostream &log(raw_ostream &) const override;
- IntOrString getResourceType() const override { return RkBitmap; }
- static uint16_t getDefaultMemoryFlags() { return MfPure | MfMoveable; }
- Twine getResourceTypeName() const override { return "BITMAP"; }
- Error visit(Visitor *V) const override {
- return V->visitBitmapResource(this);
- }
- ResourceKind getKind() const override { return RkBitmap; }
- static bool classof(const RCResource *Res) {
- return Res->getKind() == RkBitmap;
- }
- };
- // CURSOR resource. Represents a single cursor (".cur") file.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380920(v=vs.85).aspx
- class CursorResource : public RCResource {
- public:
- StringRef CursorLoc;
- CursorResource(StringRef Location, uint16_t Flags)
- : RCResource(Flags), CursorLoc(Location) {}
- raw_ostream &log(raw_ostream &) const override;
- Twine getResourceTypeName() const override { return "CURSOR"; }
- static uint16_t getDefaultMemoryFlags() { return MfDiscardable | MfMoveable; }
- Error visit(Visitor *V) const override {
- return V->visitCursorResource(this);
- }
- ResourceKind getKind() const override { return RkCursor; }
- static bool classof(const RCResource *Res) {
- return Res->getKind() == RkCursor;
- }
- };
- // ICON resource. Represents a single ".ico" file containing a group of icons.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381018(v=vs.85).aspx
- class IconResource : public RCResource {
- public:
- StringRef IconLoc;
- IconResource(StringRef Location, uint16_t Flags)
- : RCResource(Flags), IconLoc(Location) {}
- raw_ostream &log(raw_ostream &) const override;
- Twine getResourceTypeName() const override { return "ICON"; }
- static uint16_t getDefaultMemoryFlags() { return MfDiscardable | MfMoveable; }
- Error visit(Visitor *V) const override { return V->visitIconResource(this); }
- ResourceKind getKind() const override { return RkIcon; }
- static bool classof(const RCResource *Res) {
- return Res->getKind() == RkIcon;
- }
- };
- // HTML resource. Represents a local webpage that is to be embedded into the
- // resulting resource file. It embeds a file only - no additional resources
- // (images etc.) are included with this resource.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa966018(v=vs.85).aspx
- class HTMLResource : public RCResource {
- public:
- StringRef HTMLLoc;
- HTMLResource(StringRef Location, uint16_t Flags)
- : RCResource(Flags), HTMLLoc(Location) {}
- raw_ostream &log(raw_ostream &) const override;
- Error visit(Visitor *V) const override { return V->visitHTMLResource(this); }
- // Curiously, file resources don't have DISCARDABLE flag set.
- static uint16_t getDefaultMemoryFlags() { return MfPure | MfMoveable; }
- IntOrString getResourceType() const override { return RkHTML; }
- Twine getResourceTypeName() const override { return "HTML"; }
- ResourceKind getKind() const override { return RkHTML; }
- static bool classof(const RCResource *Res) {
- return Res->getKind() == RkHTML;
- }
- };
- // -- MENU resource and its helper classes --
- // This resource describes the contents of an application menu
- // (usually located in the upper part of the dialog.)
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381025(v=vs.85).aspx
- // Description of a single submenu item.
- class MenuDefinition {
- public:
- enum Options {
- CHECKED = 0x0008,
- GRAYED = 0x0001,
- HELP = 0x4000,
- INACTIVE = 0x0002,
- MENUBARBREAK = 0x0020,
- MENUBREAK = 0x0040
- };
- enum MenuDefKind { MkBase, MkSeparator, MkMenuItem, MkPopup };
- static constexpr size_t NumFlags = 6;
- static StringRef OptionsStr[NumFlags];
- static uint32_t OptionsFlags[NumFlags];
- static raw_ostream &logFlags(raw_ostream &, uint16_t Flags);
- virtual raw_ostream &log(raw_ostream &OS) const {
- return OS << "Base menu definition\n";
- }
- virtual ~MenuDefinition() {}
- virtual uint16_t getResFlags() const { return 0; }
- virtual MenuDefKind getKind() const { return MkBase; }
- };
- // Recursive description of a whole submenu.
- class MenuDefinitionList : public MenuDefinition {
- public:
- std::vector<std::unique_ptr<MenuDefinition>> Definitions;
- void addDefinition(std::unique_ptr<MenuDefinition> Def) {
- Definitions.push_back(std::move(Def));
- }
- raw_ostream &log(raw_ostream &) const override;
- };
- // Separator in MENU definition (MENUITEM SEPARATOR).
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381024(v=vs.85).aspx
- class MenuSeparator : public MenuDefinition {
- public:
- raw_ostream &log(raw_ostream &) const override;
- MenuDefKind getKind() const override { return MkSeparator; }
- static bool classof(const MenuDefinition *D) {
- return D->getKind() == MkSeparator;
- }
- };
- // MENUITEM statement definition.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381024(v=vs.85).aspx
- class MenuItem : public MenuDefinition {
- public:
- StringRef Name;
- uint32_t Id;
- uint16_t Flags;
- MenuItem(StringRef Caption, uint32_t ItemId, uint16_t ItemFlags)
- : Name(Caption), Id(ItemId), Flags(ItemFlags) {}
- raw_ostream &log(raw_ostream &) const override;
- uint16_t getResFlags() const override { return Flags; }
- 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
- class PopupItem : public MenuDefinition {
- public:
- StringRef Name;
- uint16_t Flags;
- MenuDefinitionList SubItems;
- PopupItem(StringRef Caption, uint16_t ItemFlags,
- MenuDefinitionList &&SubItemsList)
- : 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.
- uint16_t getResFlags() const override { return Flags | 0x10; }
- MenuDefKind getKind() const override { return MkPopup; }
- static bool classof(const MenuDefinition *D) {
- return D->getKind() == MkPopup;
- }
- };
- // Menu resource definition.
- class MenuResource : public OptStatementsRCResource {
- public:
- MenuDefinitionList Elements;
- MenuResource(OptionalStmtList &&OptStmts, MenuDefinitionList &&Items,
- uint16_t Flags)
- : OptStatementsRCResource(std::move(OptStmts), Flags),
- Elements(std::move(Items)) {}
- raw_ostream &log(raw_ostream &) const override;
- IntOrString getResourceType() const override { return RkMenu; }
- Twine getResourceTypeName() const override { return "MENU"; }
- Error visit(Visitor *V) const override { return V->visitMenuResource(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
- class StringTableResource : public OptStatementsRCResource {
- public:
- std::vector<std::pair<uint32_t, std::vector<StringRef>>> Table;
- StringTableResource(OptionalStmtList &&List, uint16_t Flags)
- : OptStatementsRCResource(std::move(List), Flags) {}
- void addStrings(uint32_t ID, std::vector<StringRef> &&Strings) {
- Table.emplace_back(ID, Strings);
- }
- raw_ostream &log(raw_ostream &) const override;
- Twine getResourceTypeName() const override { return "STRINGTABLE"; }
- Error visit(Visitor *V) const override {
- return V->visitStringTableResource(this);
- }
- };
- // -- DIALOG(EX) resource and its helper classes --
- //
- // This resource describes dialog boxes and controls residing inside them.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381003(v=vs.85).aspx
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381002(v=vs.85).aspx
- // Single control definition.
- class Control {
- public:
- StringRef Type;
- IntOrString Title;
- uint32_t ID, X, Y, Width, Height;
- Optional<IntWithNotMask> Style;
- Optional<uint32_t> ExtStyle, HelpID;
- IntOrString Class;
- // Control classes as described in DLGITEMTEMPLATEEX documentation.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms645389.aspx
- enum CtlClasses {
- ClsButton = 0x80,
- ClsEdit = 0x81,
- ClsStatic = 0x82,
- ClsListBox = 0x83,
- ClsScrollBar = 0x84,
- ClsComboBox = 0x85
- };
- // Simple information about a single control type.
- struct CtlInfo {
- uint32_t Style;
- uint16_t CtlClass;
- bool HasTitle;
- };
- Control(StringRef CtlType, IntOrString CtlTitle, uint32_t CtlID,
- uint32_t PosX, uint32_t PosY, uint32_t ItemWidth, uint32_t ItemHeight,
- Optional<IntWithNotMask> ItemStyle, Optional<uint32_t> ExtItemStyle,
- Optional<uint32_t> CtlHelpID, IntOrString CtlClass)
- : Type(CtlType), Title(CtlTitle), ID(CtlID), X(PosX), Y(PosY),
- Width(ItemWidth), Height(ItemHeight), Style(ItemStyle),
- ExtStyle(ExtItemStyle), HelpID(CtlHelpID), Class(CtlClass) {}
- static const StringMap<CtlInfo> SupportedCtls;
- raw_ostream &log(raw_ostream &) const;
- };
- // Single dialog definition. We don't create distinct classes for DIALOG and
- // DIALOGEX because of their being too similar to each other. We only have a
- // flag determining the type of the dialog box.
- class DialogResource : public OptStatementsRCResource {
- public:
- uint32_t X, Y, Width, Height, HelpID;
- std::vector<Control> Controls;
- bool IsExtended;
- DialogResource(uint32_t PosX, uint32_t PosY, uint32_t DlgWidth,
- uint32_t DlgHeight, uint32_t DlgHelpID,
- OptionalStmtList &&OptStmts, bool IsDialogEx, uint16_t Flags)
- : OptStatementsRCResource(std::move(OptStmts), Flags), X(PosX), Y(PosY),
- Width(DlgWidth), Height(DlgHeight), HelpID(DlgHelpID),
- IsExtended(IsDialogEx) {}
- void addControl(Control &&Ctl) { Controls.push_back(std::move(Ctl)); }
- raw_ostream &log(raw_ostream &) const override;
- // It was a weird design decision to assign the same resource type number
- // both for DIALOG and DIALOGEX (and the same structure version number).
- // It makes it possible for DIALOG to be mistaken for DIALOGEX.
- IntOrString getResourceType() const override { return RkDialog; }
- Twine getResourceTypeName() const override {
- return "DIALOG" + Twine(IsExtended ? "EX" : "");
- }
- Error visit(Visitor *V) const override {
- return V->visitDialogResource(this);
- }
- ResourceKind getKind() const override { return RkDialog; }
- static bool classof(const RCResource *Res) {
- return Res->getKind() == RkDialog;
- }
- };
- // User-defined resource. It is either:
- // * a link to the file, e.g. NAME TYPE "filename",
- // * or contains a list of integers and strings, e.g. NAME TYPE {1, "a", 2}.
- class UserDefinedResource : public RCResource {
- public:
- IntOrString Type;
- StringRef FileLoc;
- std::vector<IntOrString> Contents;
- bool IsFileResource;
- UserDefinedResource(IntOrString ResourceType, StringRef FileLocation,
- uint16_t Flags)
- : RCResource(Flags), Type(ResourceType), FileLoc(FileLocation),
- IsFileResource(true) {}
- UserDefinedResource(IntOrString ResourceType, std::vector<IntOrString> &&Data,
- uint16_t Flags)
- : RCResource(Flags), Type(ResourceType), Contents(std::move(Data)),
- IsFileResource(false) {}
- raw_ostream &log(raw_ostream &) const override;
- IntOrString getResourceType() const override { return Type; }
- Twine getResourceTypeName() const override { return Type; }
- static uint16_t getDefaultMemoryFlags() { return MfPure | MfMoveable; }
- Error visit(Visitor *V) const override {
- return V->visitUserDefinedResource(this);
- }
- ResourceKind getKind() const override { return RkUser; }
- static bool classof(const RCResource *Res) {
- return Res->getKind() == RkUser;
- }
- };
- // -- VERSIONINFO resource and its helper classes --
- //
- // This resource lists the version information on the executable/library.
- // The declaration consists of the following items:
- // * A number of fixed optional version statements (e.g. FILEVERSION, FILEOS)
- // * BEGIN
- // * A number of BLOCK and/or VALUE statements. BLOCK recursively defines
- // another block of version information, whereas VALUE defines a
- // key -> value correspondence. There might be more than one value
- // corresponding to the single key.
- // * END
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381058(v=vs.85).aspx
- // A single VERSIONINFO statement;
- class VersionInfoStmt {
- public:
- enum StmtKind { StBase = 0, StBlock = 1, StValue = 2 };
- virtual raw_ostream &log(raw_ostream &OS) const { return OS << "VI stmt\n"; }
- virtual ~VersionInfoStmt() {}
- virtual StmtKind getKind() const { return StBase; }
- static bool classof(const VersionInfoStmt *S) {
- return S->getKind() == StBase;
- }
- };
- // BLOCK definition; also the main VERSIONINFO declaration is considered a
- // BLOCK, although it has no name.
- // The correct top-level blocks are "VarFileInfo" and "StringFileInfo". We don't
- // care about them at the parsing phase.
- class VersionInfoBlock : public VersionInfoStmt {
- public:
- std::vector<std::unique_ptr<VersionInfoStmt>> Stmts;
- StringRef Name;
- VersionInfoBlock(StringRef BlockName) : Name(BlockName) {}
- void addStmt(std::unique_ptr<VersionInfoStmt> Stmt) {
- Stmts.push_back(std::move(Stmt));
- }
- raw_ostream &log(raw_ostream &) const override;
- StmtKind getKind() const override { return StBlock; }
- static bool classof(const VersionInfoStmt *S) {
- return S->getKind() == StBlock;
- }
- };
- class VersionInfoValue : public VersionInfoStmt {
- public:
- StringRef Key;
- std::vector<IntOrString> Values;
- std::vector<bool> HasPrecedingComma;
- VersionInfoValue(StringRef InfoKey, std::vector<IntOrString> &&Vals,
- std::vector<bool> &&CommasBeforeVals)
- : Key(InfoKey), Values(std::move(Vals)),
- HasPrecedingComma(std::move(CommasBeforeVals)) {}
- raw_ostream &log(raw_ostream &) const override;
- StmtKind getKind() const override { return StValue; }
- static bool classof(const VersionInfoStmt *S) {
- return S->getKind() == StValue;
- }
- };
- class VersionInfoResource : public RCResource {
- public:
- // A class listing fixed VERSIONINFO statements (occuring before main BEGIN).
- // If any of these is not specified, it is assumed by the original tool to
- // be equal to 0.
- class VersionInfoFixed {
- public:
- enum VersionInfoFixedType {
- FtUnknown,
- FtFileVersion,
- FtProductVersion,
- FtFileFlagsMask,
- FtFileFlags,
- FtFileOS,
- FtFileType,
- FtFileSubtype,
- FtNumTypes
- };
- private:
- static const StringMap<VersionInfoFixedType> FixedFieldsInfoMap;
- static const StringRef FixedFieldsNames[FtNumTypes];
- public:
- SmallVector<uint32_t, 4> FixedInfo[FtNumTypes];
- SmallVector<bool, FtNumTypes> IsTypePresent;
- static VersionInfoFixedType getFixedType(StringRef Type);
- static bool isTypeSupported(VersionInfoFixedType Type);
- static bool isVersionType(VersionInfoFixedType Type);
- VersionInfoFixed() : IsTypePresent(FtNumTypes, false) {}
- void setValue(VersionInfoFixedType Type, ArrayRef<uint32_t> Value) {
- FixedInfo[Type] = SmallVector<uint32_t, 4>(Value.begin(), Value.end());
- IsTypePresent[Type] = true;
- }
- raw_ostream &log(raw_ostream &) const;
- };
- VersionInfoBlock MainBlock;
- VersionInfoFixed FixedData;
- VersionInfoResource(VersionInfoBlock &&TopLevelBlock,
- VersionInfoFixed &&FixedInfo, uint16_t Flags)
- : RCResource(Flags), MainBlock(std::move(TopLevelBlock)),
- FixedData(std::move(FixedInfo)) {}
- raw_ostream &log(raw_ostream &) const override;
- IntOrString getResourceType() const override { return RkVersionInfo; }
- static uint16_t getDefaultMemoryFlags() { return MfMoveable | MfPure; }
- Twine getResourceTypeName() const override { return "VERSIONINFO"; }
- Error visit(Visitor *V) const override {
- return V->visitVersionInfoResource(this);
- }
- ResourceKind getKind() const override { return RkVersionInfo; }
- static bool classof(const RCResource *Res) {
- return Res->getKind() == RkVersionInfo;
- }
- };
- // CHARACTERISTICS optional statement.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380872(v=vs.85).aspx
- class CharacteristicsStmt : public OptionalStmt {
- public:
- uint32_t Value;
- 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;
- 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.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380778(v=vs.85).aspx
- class CaptionStmt : public OptionalStmt {
- public:
- StringRef Value;
- CaptionStmt(StringRef Caption) : Value(Caption) {}
- raw_ostream &log(raw_ostream &) const override;
- Twine getResourceTypeName() const override { return "CAPTION"; }
- Error visit(Visitor *V) const override { return V->visitCaptionStmt(this); }
- };
- // FONT optional statement.
- // Note that the documentation is inaccurate: it expects five arguments to be
- // given, however the example provides only two. In fact, the original tool
- // expects two arguments - point size and name of the typeface.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381013(v=vs.85).aspx
- class FontStmt : public OptionalStmt {
- public:
- uint32_t Size, Weight, Charset;
- StringRef Name;
- bool Italic;
- FontStmt(uint32_t FontSize, StringRef FontName, uint32_t FontWeight,
- bool FontItalic, uint32_t FontCharset)
- : Size(FontSize), Weight(FontWeight), Charset(FontCharset),
- Name(FontName), Italic(FontItalic) {}
- raw_ostream &log(raw_ostream &) const override;
- Twine getResourceTypeName() const override { return "FONT"; }
- Error visit(Visitor *V) const override { return V->visitFontStmt(this); }
- };
- // STYLE optional statement.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381051(v=vs.85).aspx
- class StyleStmt : public OptionalStmt {
- public:
- uint32_t Value;
- StyleStmt(uint32_t Style) : Value(Style) {}
- raw_ostream &log(raw_ostream &) const override;
- Twine getResourceTypeName() const override { return "STYLE"; }
- Error visit(Visitor *V) const override { return V->visitStyleStmt(this); }
- };
- // EXSTYLE optional statement.
- //
- // Ref: docs.microsoft.com/en-us/windows/desktop/menurc/exstyle-statement
- class ExStyleStmt : public OptionalStmt {
- public:
- uint32_t Value;
- ExStyleStmt(uint32_t ExStyle) : Value(ExStyle) {}
- raw_ostream &log(raw_ostream &) const override;
- Twine getResourceTypeName() const override { return "EXSTYLE"; }
- Error visit(Visitor *V) const override { return V->visitExStyleStmt(this); }
- };
- // CLASS optional statement.
- //
- // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380883(v=vs.85).aspx
- class ClassStmt : public OptionalStmt {
- public:
- IntOrString Value;
- ClassStmt(IntOrString Class) : Value(Class) {}
- raw_ostream &log(raw_ostream &) const override;
- Twine getResourceTypeName() const override { return "CLASS"; }
- Error visit(Visitor *V) const override { return V->visitClassStmt(this); }
- };
- } // namespace rc
- } // namespace llvm
- #endif
|