//===-- ResourceScriptStmt.h ------------------------------------*- C++-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
//
// 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" : "");
  }
};

// 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,
  RkSingleIcon = 3,
  RkMenu = 4,
  RkDialog = 5,
  RkStringTableBundle = 6,
  RkAccelerators = 9,
  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;
  void setName(const IntOrString &Name) { ResName = Name; }
  virtual raw_ostream &log(raw_ostream &OS) const {
    return OS << "Base statement\n";
  };
  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.
  virtual uint16_t getMemoryFlags() const {
    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:
  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)"; }
  uint16_t getMemoryFlags() const override { return 0; }
};

// 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)
      : 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
// 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];
  };

  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;

  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.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380920(v=vs.85).aspx
class CursorResource : public RCResource {
public:
  StringRef CursorLoc;

  CursorResource(StringRef Location) : CursorLoc(Location) {}
  raw_ostream &log(raw_ostream &) const override;

  Twine getResourceTypeName() const override { return "CURSOR"; }
  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) : IconLoc(Location) {}
  raw_ostream &log(raw_ostream &) const override;

  Twine getResourceTypeName() const override { return "ICON"; }
  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) : 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.
  uint16_t getMemoryFlags() const override { 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)
      : OptStatementsRCResource(std::move(OptStmts)),
        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, StringRef>> Table;

  using OptStatementsRCResource::OptStatementsRCResource;
  void addString(uint32_t ID, StringRef String) {
    Table.emplace_back(ID, String);
  }
  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<uint32_t> Style, ExtStyle, HelpID;

  // 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<uint32_t> ItemStyle, Optional<uint32_t> ExtItemStyle,
          Optional<uint32_t> CtlHelpID)
      : Type(CtlType), Title(CtlTitle), ID(CtlID), X(PosX), Y(PosY),
        Width(ItemWidth), Height(ItemHeight), Style(ItemStyle),
        ExtStyle(ExtItemStyle), HelpID(CtlHelpID) {}

  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)
      : OptStatementsRCResource(std::move(OptStmts)), 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)
      : Type(ResourceType), FileLoc(FileLocation), IsFileResource(true) {}
  UserDefinedResource(IntOrString ResourceType, std::vector<IntOrString> &&Data)
      : 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; }
  uint16_t getMemoryFlags() const override { 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)
      : MainBlock(std::move(TopLevelBlock)), FixedData(std::move(FixedInfo)) {}

  raw_ostream &log(raw_ostream &) const override;
  IntOrString getResourceType() const override { return RkVersionInfo; }
  uint16_t getMemoryFlags() const override { 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); }
};

} // namespace rc
} // namespace llvm

#endif
