[llvm] r312009 - [llvm-rc] Add DIALOG(EX) parsing ability (parser, pt 5/8).

Marek Sokolowski via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 29 09:49:59 PDT 2017


Author: mnbvmar
Date: Tue Aug 29 09:49:59 2017
New Revision: 312009

URL: http://llvm.org/viewvc/llvm-project?rev=312009&view=rev
Log:
[llvm-rc] Add DIALOG(EX) parsing ability (parser, pt 5/8).

This extends the set of resources parsed by llvm-rc by DIALOG and
DIALOGEX.

Additionally, three optional resource statements specific to these two
resources are added: CAPTION, FONT, and STYLE.

Thanks for Nico Weber for his original work in this area.

Differential Revision: https://reviews.llvm.org/D36905

Added:
    llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-cant-give-helpid.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-too-few-args.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-too-many-args.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-unknown-type.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-unnecessary-string.rc
Modified:
    llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc
    llvm/trunk/test/tools/llvm-rc/parser.test
    llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp
    llvm/trunk/tools/llvm-rc/ResourceScriptParser.h
    llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp
    llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h

Modified: llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc?rev=312009&r1=312008&r2=312009&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc (original)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc Tue Aug 29 09:49:59 2017
@@ -56,3 +56,25 @@ LANGUAGE 4, 1
     MENUITEM "&Word", 502
   }
 }
+
+14 DIALOGEX 50, 60, 10, 20, 500
+LANGUAGE 1, 2
+CHARACTERISTICS 50
+VERSION 100
+FONT 12, "Arial"
+CAPTION "RC parser dialog"
+STYLE 0x51234
+BEGIN
+  LTEXT "Hello world!", 14, 20, 20, 50, 50
+  RTEXT "Heh", 50, 51, 52, 53, 54, 55, 56
+  CTEXT "Muuuu", 1, 2, 3, 4, 5, 6, 7, 8
+  PUSHBUTTON "Muuuu", 1, 2, 3, 4, 5, 6, 7, 8
+  DEFPUSHBUTTON "Muuuu", 1, 2, 3, 4, 5, 6
+  EDITTEXT 5, 1, 2, 4, 7, 8
+END
+
+25 DIALOG 1, 2, 3, 4
+BEGIN
+END
+
+26 DIALOGEX 1, 2, 3, 4 {}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-cant-give-helpid.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-cant-give-helpid.rc?rev=312009&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-cant-give-helpid.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-cant-give-helpid.rc Tue Aug 29 09:49:59 2017
@@ -0,0 +1 @@
+3 DIALOG 1, 2, 3, 4, 500 {}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-too-few-args.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-too-few-args.rc?rev=312009&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-too-few-args.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-too-few-args.rc Tue Aug 29 09:49:59 2017
@@ -0,0 +1,3 @@
+1 DIALOG 1, 2, 3, 4 {
+  LTEXT "Too short", 1, 2, 3
+}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-too-many-args.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-too-many-args.rc?rev=312009&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-too-many-args.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-too-many-args.rc Tue Aug 29 09:49:59 2017
@@ -0,0 +1,3 @@
+1 DIALOGEX 1, 2, 3, 4 {
+  LTEXT "Too long", 1, 2, 3, 4, 5, 6, 7, 8, 9
+}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-unknown-type.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-unknown-type.rc?rev=312009&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-unknown-type.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-unknown-type.rc Tue Aug 29 09:49:59 2017
@@ -0,0 +1,3 @@
+1 DIALOGEX 1, 2, 3, 4 {
+  UNKNOWN 1, 2, 3, 4, 5, 6, 7, 8
+}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-unnecessary-string.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-unnecessary-string.rc?rev=312009&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-unnecessary-string.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-dialog-unnecessary-string.rc Tue Aug 29 09:49:59 2017
@@ -0,0 +1,3 @@
+1 DIALOGEX 1, 2, 3, 4 {
+  EDITTEXT "This shouldn't be here", 1, 2, 3, 4
+}

Modified: llvm/trunk/test/tools/llvm-rc/parser.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/parser.test?rev=312009&r1=312008&r2=312009&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/parser.test (original)
+++ llvm/trunk/test/tools/llvm-rc/parser.test Tue Aug 29 09:49:59 2017
@@ -49,6 +49,21 @@
 ; PGOOD-NEXT:    MenuItem ("&Word"), ID = 502
 ; PGOOD-NEXT:    Menu list ends
 ; PGOOD-NEXT:    Menu list ends
+; PGOOD-NEXT:  DialogEx (14): loc: (50, 60), size: [10, 20], help ID: 500
+; PGOOD-NEXT:    Option: Language: 1, Sublanguage: 2
+; PGOOD-NEXT:    Option: Characteristics: 50
+; PGOOD-NEXT:    Option: Version: 100
+; PGOOD-NEXT:    Option: Font: size = 12, face = "Arial"
+; PGOOD-NEXT:    Option: Caption: "RC parser dialog"
+; PGOOD-NEXT:    Option: Style: 332340
+; PGOOD-NEXT:    Control (14): LTEXT, title: "Hello world!", loc: (20, 20), size: [50, 50]
+; PGOOD-NEXT:    Control (50): RTEXT, title: "Heh", loc: (51, 52), size: [53, 54], style: 55, ext. style: 56
+; PGOOD-NEXT:    Control (1): CTEXT, title: "Muuuu", loc: (2, 3), size: [4, 5], style: 6, ext. style: 7, help ID: 8
+; PGOOD-NEXT:    Control (1): PUSHBUTTON, title: "Muuuu", loc: (2, 3), size: [4, 5], style: 6, ext. style: 7, help ID: 8
+; PGOOD-NEXT:    Control (1): DEFPUSHBUTTON, title: "Muuuu", loc: (2, 3), size: [4, 5], style: 6
+; PGOOD-NEXT:    Control (5): EDITTEXT, title: , loc: (1, 2), size: [4, 7], style: 8
+; PGOOD-NEXT:  Dialog (25): loc: (1, 2), size: [3, 4], help ID: 0
+; PGOOD-NEXT:  DialogEx (26): loc: (1, 2), size: [3, 4], help ID: 0
 
 
 ; RUN: not llvm-rc /V %p/Inputs/parser-stringtable-no-string.rc 2>&1 | FileCheck %s --check-prefix PSTRINGTABLE1
@@ -144,3 +159,28 @@
 ; RUN: not llvm-rc /V %p/Inputs/parser-menu-misspelled-separator.rc 2>&1 | FileCheck %s --check-prefix PMENU4
 
 ; PMENU4:  llvm-rc: Error parsing file: expected SEPARATOR or string, got NOTSEPARATOR
+
+
+; RUN: not llvm-rc /V %p/Inputs/parser-dialog-cant-give-helpid.rc 2>&1 | FileCheck %s --check-prefix PDIALOG1
+
+; PDIALOG1:  llvm-rc: Error parsing file: expected identifier, got ,
+
+
+; RUN: not llvm-rc /V %p/Inputs/parser-dialog-too-few-args.rc 2>&1 | FileCheck %s --check-prefix PDIALOG2
+
+; PDIALOG2:  llvm-rc: Error parsing file: expected ',', got }
+
+
+; RUN: not llvm-rc /V %p/Inputs/parser-dialog-too-many-args.rc 2>&1 | FileCheck %s --check-prefix PDIALOG3
+
+; PDIALOG3:  llvm-rc: Error parsing file: expected identifier, got ,
+
+
+; RUN: not llvm-rc /V %p/Inputs/parser-dialog-unknown-type.rc 2>&1 | FileCheck %s --check-prefix PDIALOG4
+
+; PDIALOG4:  llvm-rc: Error parsing file: expected control type, END or '}', got UNKNOWN
+
+
+; RUN: not llvm-rc /V %p/Inputs/parser-dialog-unnecessary-string.rc 2>&1 | FileCheck %s --check-prefix PDIALOG5
+
+; PDIALOG5:  llvm-rc: Error parsing file: expected integer, got "This shouldn't be here"

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp?rev=312009&r1=312008&r2=312009&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp Tue Aug 29 09:49:59 2017
@@ -67,6 +67,10 @@ RCParser::ParseType RCParser::parseSingl
     Result = parseAcceleratorsResource();
   else if (TypeToken->equalsLower("CURSOR"))
     Result = parseCursorResource();
+  else if (TypeToken->equalsLower("DIALOG"))
+    Result = parseDialogResource(false);
+  else if (TypeToken->equalsLower("DIALOGEX"))
+    Result = parseDialogResource(true);
   else if (TypeToken->equalsLower("ICON"))
     Result = parseIconResource();
   else if (TypeToken->equalsLower("HTML"))
@@ -235,17 +239,26 @@ Expected<OptionalStmtList> RCParser::par
 }
 
 Expected<std::unique_ptr<OptionalStmt>>
-RCParser::parseSingleOptionalStatement(bool) {
+RCParser::parseSingleOptionalStatement(bool IsExtended) {
   ASSIGN_OR_RETURN(TypeToken, readIdentifier());
   if (TypeToken->equals_lower("CHARACTERISTICS"))
     return parseCharacteristicsStmt();
-  else if (TypeToken->equals_lower("LANGUAGE"))
+  if (TypeToken->equals_lower("LANGUAGE"))
     return parseLanguageStmt();
-  else if (TypeToken->equals_lower("VERSION"))
+  if (TypeToken->equals_lower("VERSION"))
     return parseVersionStmt();
-  else
-    return getExpectedError("optional statement type, BEGIN or '{'",
-                            /* IsAlreadyRead = */ true);
+
+  if (IsExtended) {
+    if (TypeToken->equals_lower("CAPTION"))
+      return parseCaptionStmt();
+    if (TypeToken->equals_lower("FONT"))
+      return parseFontStmt();
+    if (TypeToken->equals_lower("STYLE"))
+      return parseStyleStmt();
+  }
+
+  return getExpectedError("optional statement type, BEGIN or '{'",
+                          /* IsAlreadyRead = */ true);
 }
 
 RCParser::ParseType RCParser::parseLanguageResource() {
@@ -277,6 +290,68 @@ RCParser::ParseType RCParser::parseCurso
   return make_unique<CursorResource>(*Arg);
 }
 
+RCParser::ParseType RCParser::parseDialogResource(bool IsExtended) {
+  // Dialog resources have the following format of the arguments:
+  //  DIALOG:   x, y, width, height [opt stmts...] {controls...}
+  //  DIALOGEX: x, y, width, height [, helpID] [opt stmts...] {controls...}
+  // These are very similar, so we parse them together.
+  ASSIGN_OR_RETURN(LocResult, readIntsWithCommas(4, 4));
+
+  uint32_t HelpID = 0; // When HelpID is unset, it's assumed to be 0.
+  if (IsExtended && consumeOptionalType(Kind::Comma)) {
+    ASSIGN_OR_RETURN(HelpIDResult, readInt());
+    HelpID = *HelpIDResult;
+  }
+
+  ASSIGN_OR_RETURN(OptStatements,
+                   parseOptionalStatements(/*UseExtendedStmts = */ true));
+
+  assert(isNextTokenKind(Kind::BlockBegin) &&
+         "parseOptionalStatements, when successful, halts on BlockBegin.");
+  consume();
+
+  auto Dialog = make_unique<DialogResource>(
+      (*LocResult)[0], (*LocResult)[1], (*LocResult)[2], (*LocResult)[3],
+      HelpID, std::move(*OptStatements), IsExtended);
+
+  while (!consumeOptionalType(Kind::BlockEnd)) {
+    ASSIGN_OR_RETURN(ControlDefResult, parseControl());
+    Dialog->addControl(std::move(*ControlDefResult));
+  }
+
+  return std::move(Dialog);
+}
+
+Expected<Control> RCParser::parseControl() {
+  // Each control definition (except CONTROL) follows one of the schemes below
+  // depending on the control class:
+  //  [class] text, id, x, y, width, height [, style] [, exstyle] [, helpID]
+  //  [class]       id, x, y, width, height [, style] [, exstyle] [, helpID]
+  // Note that control ids must be integers.
+  ASSIGN_OR_RETURN(ClassResult, readIdentifier());
+  StringRef ClassUpper = ClassResult->upper();
+  if (Control::SupportedCtls.find(ClassUpper) == Control::SupportedCtls.end())
+    return getExpectedError("control type, END or '}'", true);
+
+  // Read caption if necessary.
+  StringRef Caption;
+  if (Control::CtlsWithTitle.find(ClassUpper) != Control::CtlsWithTitle.end()) {
+    ASSIGN_OR_RETURN(CaptionResult, readString());
+    RETURN_IF_ERROR(consumeType(Kind::Comma));
+    Caption = *CaptionResult;
+  }
+
+  ASSIGN_OR_RETURN(Args, readIntsWithCommas(5, 8));
+
+  auto TakeOptArg = [&Args](size_t Id) -> Optional<uint32_t> {
+    return Args->size() > Id ? (*Args)[Id] : Optional<uint32_t>();
+  };
+
+  return Control(*ClassResult, Caption, (*Args)[0], (*Args)[1], (*Args)[2],
+                 (*Args)[3], (*Args)[4], TakeOptArg(5), TakeOptArg(6),
+                 TakeOptArg(7));
+}
+
 RCParser::ParseType RCParser::parseIconResource() {
   ASSIGN_OR_RETURN(Arg, readString());
   return make_unique<IconResource>(*Arg);
@@ -386,6 +461,23 @@ RCParser::ParseOptionType RCParser::pars
   return make_unique<VersionStmt>(*Arg);
 }
 
+RCParser::ParseOptionType RCParser::parseCaptionStmt() {
+  ASSIGN_OR_RETURN(Arg, readString());
+  return make_unique<CaptionStmt>(*Arg);
+}
+
+RCParser::ParseOptionType RCParser::parseFontStmt() {
+  ASSIGN_OR_RETURN(SizeResult, readInt());
+  RETURN_IF_ERROR(consumeType(Kind::Comma));
+  ASSIGN_OR_RETURN(NameResult, readString());
+  return make_unique<FontStmt>(*SizeResult, *NameResult);
+}
+
+RCParser::ParseOptionType RCParser::parseStyleStmt() {
+  ASSIGN_OR_RETURN(Arg, readInt());
+  return make_unique<StyleStmt>(*Arg);
+}
+
 Error RCParser::getExpectedError(const Twine Message, bool IsAlreadyRead) {
   return make_error<ParserError>(
       Message, IsAlreadyRead ? std::prev(CurLoc) : CurLoc, End);

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptParser.h?rev=312009&r1=312008&r2=312009&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptParser.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.h Tue Aug 29 09:49:59 2017
@@ -128,11 +128,15 @@ private:
   ParseType parseLanguageResource();
   ParseType parseAcceleratorsResource();
   ParseType parseCursorResource();
+  ParseType parseDialogResource(bool IsExtended);
   ParseType parseIconResource();
   ParseType parseHTMLResource();
   ParseType parseMenuResource();
   ParseType parseStringTableResource();
 
+  // Helper DIALOG parser - a single control.
+  Expected<Control> parseControl();
+
   // Helper MENU parser.
   Expected<MenuDefinitionList> parseMenuItemsList();
 
@@ -140,6 +144,9 @@ private:
   ParseOptionType parseLanguageStmt();
   ParseOptionType parseCharacteristicsStmt();
   ParseOptionType parseVersionStmt();
+  ParseOptionType parseCaptionStmt();
+  ParseOptionType parseFontStmt();
+  ParseOptionType parseStyleStmt();
 
   // Raises an error. If IsAlreadyRead = false (default), this complains about
   // the token that couldn't be parsed. If the flag is on, this complains about

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp?rev=312009&r1=312008&r2=312009&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp Tue Aug 29 09:49:59 2017
@@ -113,6 +113,35 @@ raw_ostream &StringTableResource::log(ra
   return OS;
 }
 
+const StringSet<> Control::SupportedCtls = {
+    "LTEXT", "RTEXT", "CTEXT", "PUSHBUTTON", "DEFPUSHBUTTON", "EDITTEXT"};
+
+const StringSet<> Control::CtlsWithTitle = {"LTEXT", "RTEXT", "CTEXT",
+                                            "PUSHBUTTON", "DEFPUSHBUTTON"};
+
+raw_ostream &Control::log(raw_ostream &OS) const {
+  OS << "  Control (" << ID << "): " << Type << ", title: " << Title
+     << ", loc: (" << X << ", " << Y << "), size: [" << Width << ", " << Height
+     << "]";
+  if (Style)
+    OS << ", style: " << *Style;
+  if (ExtStyle)
+    OS << ", ext. style: " << *ExtStyle;
+  if (HelpID)
+    OS << ", help ID: " << *HelpID;
+  return OS << "\n";
+}
+
+raw_ostream &DialogResource::log(raw_ostream &OS) const {
+  OS << "Dialog" << (IsExtended ? "Ex" : "") << " (" << ResName << "): loc: ("
+     << X << ", " << Y << "), size: [" << Width << ", " << Height
+     << "], help ID: " << HelpID << "\n";
+  OptStatements.log(OS);
+  for (auto &Ctl : Controls)
+    Ctl.log(OS);
+  return OS;
+}
+
 raw_ostream &CharacteristicsStmt::log(raw_ostream &OS) const {
   return OS << "Characteristics: " << Value << "\n";
 }
@@ -121,5 +150,17 @@ raw_ostream &VersionStmt::log(raw_ostrea
   return OS << "Version: " << Value << "\n";
 }
 
+raw_ostream &CaptionStmt::log(raw_ostream &OS) const {
+  return OS << "Caption: " << Value << "\n";
+}
+
+raw_ostream &FontStmt::log(raw_ostream &OS) const {
+  return OS << "Font: size = " << Size << ", face = " << Typeface << "\n";
+}
+
+raw_ostream &StyleStmt::log(raw_ostream &OS) const {
+  return OS << "Style: " << Value << "\n";
+}
+
 } // namespace rc
 } // namespace llvm

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h?rev=312009&r1=312008&r2=312009&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h Tue Aug 29 09:49:59 2017
@@ -16,6 +16,8 @@
 
 #include "ResourceScriptToken.h"
 
+#include "llvm/ADT/StringSet.h"
+
 namespace llvm {
 namespace rc {
 
@@ -268,6 +270,55 @@ public:
   raw_ostream &log(raw_ostream &) const override;
 };
 
+// -- 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 {
+  StringRef Type, Title;
+  uint32_t ID, X, Y, Width, Height;
+  Optional<uint32_t> Style, ExtStyle, HelpID;
+
+public:
+  Control(StringRef CtlType, StringRef 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 StringSet<> SupportedCtls;
+  static const StringSet<> CtlsWithTitle;
+
+  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 RCResource {
+  uint32_t X, Y, Width, Height, HelpID;
+  OptionalStmtList OptStatements;
+  std::vector<Control> Controls;
+  bool IsExtended;
+
+public:
+  DialogResource(uint32_t PosX, uint32_t PosY, uint32_t DlgWidth,
+                 uint32_t DlgHeight, uint32_t DlgHelpID,
+                 OptionalStmtList &&OptStmts, bool IsDialogEx)
+      : X(PosX), Y(PosY), Width(DlgWidth), Height(DlgHeight), HelpID(DlgHelpID),
+        OptStatements(std::move(OptStmts)), IsExtended(IsDialogEx) {}
+
+  void addControl(Control &&Ctl) { Controls.push_back(std::move(Ctl)); }
+
+  raw_ostream &log(raw_ostream &) const override;
+};
+
 // CHARACTERISTICS optional statement.
 //
 // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380872(v=vs.85).aspx
@@ -290,6 +341,44 @@ public:
   raw_ostream &log(raw_ostream &) const override;
 };
 
+// CAPTION optional statement.
+//
+// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380778(v=vs.85).aspx
+class CaptionStmt : public OptionalStmt {
+  StringRef Value;
+
+public:
+  CaptionStmt(StringRef Caption) : Value(Caption) {}
+  raw_ostream &log(raw_ostream &) const override;
+};
+
+// 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 {
+  uint32_t Size;
+  StringRef Typeface;
+
+public:
+  FontStmt(uint32_t FontSize, StringRef FontName)
+      : Size(FontSize), Typeface(FontName) {}
+  raw_ostream &log(raw_ostream &) const override;
+};
+
+// STYLE optional statement.
+//
+// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381051(v=vs.85).aspx
+class StyleStmt : public OptionalStmt {
+  uint32_t Value;
+
+public:
+  StyleStmt(uint32_t Style) : Value(Style) {}
+  raw_ostream &log(raw_ostream &) const override;
+};
+
 } // namespace rc
 } // namespace llvm
 




More information about the llvm-commits mailing list