[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

llvm-svn: 312009
diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.h b/llvm/tools/llvm-rc/ResourceScriptStmt.h
index 7166138..0812c26 100644
--- a/llvm/tools/llvm-rc/ResourceScriptStmt.h
+++ b/llvm/tools/llvm-rc/ResourceScriptStmt.h
@@ -16,6 +16,8 @@
 
 #include "ResourceScriptToken.h"
 
+#include "llvm/ADT/StringSet.h"
+
 namespace llvm {
 namespace rc {
 
@@ -268,6 +270,55 @@
   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 @@
   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