[llvm] r314468 - [llvm-rc] Add VERSIONINFO parsing ability. [6/8]

Marek Sokolowski via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 28 15:41:39 PDT 2017


Author: mnbvmar
Date: Thu Sep 28 15:41:38 2017
New Revision: 314468

URL: http://llvm.org/viewvc/llvm-project?rev=314468&view=rev
Log:
[llvm-rc] Add VERSIONINFO parsing ability. [6/8]

This extends the set of llvm-rc parser's available resources by
another one, VERSIONINFO.

Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381058.aspx

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

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

Added:
    llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-bad-type.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-named-main-block.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-repeated-fixed.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-unnamed-inner-block.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-unnamed-value.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-wrong-fixed.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=314468&r1=314467&r2=314468&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 Thu Sep 28 15:41:38 2017
@@ -78,3 +78,36 @@ BEGIN
 END
 
 26 DIALOGEX 1, 2, 3, 4 {}
+
+1 VERSIONINFO
+FILEVERSION 1, 2, 3, 4
+PRODUCTVERSION 5, 6, 7, 8
+FILEFLAGSMASK 50
+FILEFLAGS 555
+FILEOS 110
+FILETYPE 555555
+FILESUBTYPE 14
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904E4"
+        {
+            VALUE "CompanyName",      "a"
+            VALUE "FileDescription",  "b"
+            VALUE "FileVersion",      "c"
+            VALUE "InternalName",     "d"
+            VALUE "LegalCopyright",   "e"
+            VALUE "LegalTrademarks1", "f"
+            VALUE "LegalTrademarks2", "g"
+            VALUE "OriginalFilename", L"h"
+            VALUE "ProductName",      "ii", 2, 3
+            VALUE "ProductVersion"
+        }
+    END
+
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1252
+
+    END
+END

Added: llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-bad-type.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-bad-type.rc?rev=314468&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-bad-type.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-bad-type.rc Thu Sep 28 15:41:38 2017
@@ -0,0 +1,4 @@
+1 VERSIONINFO
+BEGIN
+  INCORRECT "1", "2"
+END

Added: llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-named-main-block.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-named-main-block.rc?rev=314468&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-named-main-block.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-named-main-block.rc Thu Sep 28 15:41:38 2017
@@ -0,0 +1,4 @@
+1 VERSIONINFO
+BLOCK "hello"
+BEGIN
+END

Added: llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-repeated-fixed.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-repeated-fixed.rc?rev=314468&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-repeated-fixed.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-repeated-fixed.rc Thu Sep 28 15:41:38 2017
@@ -0,0 +1,6 @@
+1 VERSIONINFO
+FileVersion 1, 2, 3, 4
+PRODUCTVERSION 5, 6, 7, 8
+FILEVERSION 9, 10, 11, 12
+BEGIN
+END

Added: llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-unnamed-inner-block.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-unnamed-inner-block.rc?rev=314468&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-unnamed-inner-block.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-unnamed-inner-block.rc Thu Sep 28 15:41:38 2017
@@ -0,0 +1,4 @@
+1 VERSIONINFO
+BEGIN
+  BLOCK {}
+END

Added: llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-unnamed-value.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-unnamed-value.rc?rev=314468&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-unnamed-value.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-unnamed-value.rc Thu Sep 28 15:41:38 2017
@@ -0,0 +1,7 @@
+1 VERSIONINFO
+BEGIN
+  BLOCK "VarFileInfo"
+  BEGIN
+    VALUE
+  END
+END

Added: llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-wrong-fixed.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-wrong-fixed.rc?rev=314468&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-wrong-fixed.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-versioninfo-wrong-fixed.rc Thu Sep 28 15:41:38 2017
@@ -0,0 +1,3 @@
+1 VERSIONINFO
+WEIRDFIXED 5
+BEGIN END

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=314468&r1=314467&r2=314468&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/parser.test (original)
+++ llvm/trunk/test/tools/llvm-rc/parser.test Thu Sep 28 15:41:38 2017
@@ -64,6 +64,34 @@
 ; 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
+; PGOOD-NEXT:  VersionInfo (1):
+; PGOOD-NEXT:    Fixed: FILEVERSION: 1 2 3 4
+; PGOOD-NEXT:    Fixed: PRODUCTVERSION: 5 6 7 8
+; PGOOD-NEXT:    Fixed: FILEFLAGSMASK: 50
+; PGOOD-NEXT:    Fixed: FILEFLAGS: 555
+; PGOOD-NEXT:    Fixed: FILEOS: 110
+; PGOOD-NEXT:    Fixed: FILETYPE: 555555
+; PGOOD-NEXT:    Fixed: FILESUBTYPE: 14
+; PGOOD-NEXT:    Start of block (name: )
+; PGOOD-NEXT:    Start of block (name: "StringFileInfo")
+; PGOOD-NEXT:    Start of block (name: "040904E4")
+; PGOOD-NEXT:    "CompanyName" => "a"
+; PGOOD-NEXT:    "FileDescription" => "b"
+; PGOOD-NEXT:    "FileVersion" => "c"
+; PGOOD-NEXT:    "InternalName" => "d"
+; PGOOD-NEXT:    "LegalCopyright" => "e"
+; PGOOD-NEXT:    "LegalTrademarks1" => "f"
+; PGOOD-NEXT:    "LegalTrademarks2" => "g"
+; PGOOD-NEXT:    "OriginalFilename" => L"h"
+; PGOOD-NEXT:    "ProductName" => "ii" 2 3
+; PGOOD-NEXT:    "ProductVersion" =>
+; PGOOD-NEXT:    End of block
+; PGOOD-NEXT:    End of block
+; PGOOD-NEXT:    Start of block (name: "VarFileInfo")
+; PGOOD-NEXT:    "Translation" => 1033 1252
+; PGOOD-NEXT:    End of block
+; PGOOD-NEXT:    End of block
+
 
 
 ; RUN: not llvm-rc /V %p/Inputs/parser-stringtable-no-string.rc 2>&1 | FileCheck %s --check-prefix PSTRINGTABLE1
@@ -184,3 +212,33 @@
 ; 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"
+
+
+; RUN: not llvm-rc /V %p/Inputs/parser-versioninfo-wrong-fixed.rc 2>&1 | FileCheck %s --check-prefix PVERSIONINFO1
+
+; PVERSIONINFO1:  llvm-rc: Error parsing file: expected fixed VERSIONINFO statement type, got WEIRDFIXED
+
+
+; RUN: not llvm-rc /V %p/Inputs/parser-versioninfo-named-main-block.rc 2>&1 | FileCheck %s --check-prefix PVERSIONINFO2
+
+; PVERSIONINFO2:  llvm-rc: Error parsing file: expected fixed VERSIONINFO statement type, got BLOCK
+
+
+; RUN: not llvm-rc /V %p/Inputs/parser-versioninfo-unnamed-inner-block.rc 2>&1 | FileCheck %s --check-prefix PVERSIONINFO3
+
+; PVERSIONINFO3:  llvm-rc: Error parsing file: expected string, got {
+
+
+; RUN: not llvm-rc /V %p/Inputs/parser-versioninfo-unnamed-value.rc 2>&1 | FileCheck %s --check-prefix PVERSIONINFO4
+
+; PVERSIONINFO4:  llvm-rc: Error parsing file: expected string, got END
+
+
+; RUN: not llvm-rc /V %p/Inputs/parser-versioninfo-bad-type.rc 2>&1 | FileCheck %s --check-prefix PVERSIONINFO5
+
+; PVERSIONINFO5:  llvm-rc: Error parsing file: expected BLOCK or VALUE, got INCORRECT
+
+
+; RUN: not llvm-rc /V %p/Inputs/parser-versioninfo-repeated-fixed.rc 2>&1 | FileCheck %s --check-prefix PVERSIONINFO6
+
+; PVERSIONINFO6:  llvm-rc: Error parsing file: expected yet unread fixed VERSIONINFO statement type, got FILEVERSION

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp?rev=314468&r1=314467&r2=314468&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp Thu Sep 28 15:41:38 2017
@@ -77,6 +77,8 @@ RCParser::ParseType RCParser::parseSingl
     Result = parseHTMLResource();
   else if (TypeToken->equalsLower("MENU"))
     Result = parseMenuResource();
+  else if (TypeToken->equalsLower("VERSIONINFO"))
+    Result = parseVersionInfoResource();
   else
     return getExpectedError("resource type", /* IsAlreadyRead = */ true);
 
@@ -322,6 +324,13 @@ RCParser::ParseType RCParser::parseDialo
   return std::move(Dialog);
 }
 
+RCParser::ParseType RCParser::parseVersionInfoResource() {
+  ASSIGN_OR_RETURN(FixedResult, parseVersionInfoFixed());
+  ASSIGN_OR_RETURN(BlockResult, parseVersionInfoBlockContents(StringRef()));
+  return make_unique<VersionInfoResource>(std::move(**BlockResult),
+                                          std::move(*FixedResult));
+}
+
 Expected<Control> RCParser::parseControl() {
   // Each control definition (except CONTROL) follows one of the schemes below
   // depending on the control class:
@@ -446,6 +455,72 @@ RCParser::ParseType RCParser::parseStrin
   return std::move(Table);
 }
 
+Expected<std::unique_ptr<VersionInfoBlock>>
+RCParser::parseVersionInfoBlockContents(StringRef BlockName) {
+  RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
+
+  auto Contents = make_unique<VersionInfoBlock>(BlockName);
+
+  while (!isNextTokenKind(Kind::BlockEnd)) {
+    ASSIGN_OR_RETURN(Stmt, parseVersionInfoStmt());
+    Contents->addStmt(std::move(*Stmt));
+  }
+
+  consume(); // Consume BlockEnd.
+
+  return std::move(Contents);
+}
+
+Expected<std::unique_ptr<VersionInfoStmt>> RCParser::parseVersionInfoStmt() {
+  // Expect either BLOCK or VALUE, then a name or a key (a string).
+  ASSIGN_OR_RETURN(TypeResult, readIdentifier());
+
+  if (TypeResult->equals_lower("BLOCK")) {
+    ASSIGN_OR_RETURN(NameResult, readString());
+    return parseVersionInfoBlockContents(*NameResult);
+  }
+
+  if (TypeResult->equals_lower("VALUE")) {
+    ASSIGN_OR_RETURN(KeyResult, readString());
+    // Read a (possibly empty) list of strings and/or ints, each preceded by
+    // a comma.
+    std::vector<IntOrString> Values;
+
+    while (consumeOptionalType(Kind::Comma)) {
+      ASSIGN_OR_RETURN(ValueResult, readIntOrString());
+      Values.push_back(*ValueResult);
+    }
+    return make_unique<VersionInfoValue>(*KeyResult, std::move(Values));
+  }
+
+  return getExpectedError("BLOCK or VALUE", true);
+}
+
+Expected<VersionInfoResource::VersionInfoFixed>
+RCParser::parseVersionInfoFixed() {
+  using RetType = VersionInfoResource::VersionInfoFixed;
+  RetType Result;
+
+  // Read until the beginning of the block.
+  while (!isNextTokenKind(Kind::BlockBegin)) {
+    ASSIGN_OR_RETURN(TypeResult, readIdentifier());
+    auto FixedType = RetType::getFixedType(*TypeResult);
+
+    if (!RetType::isTypeSupported(FixedType))
+      return getExpectedError("fixed VERSIONINFO statement type", true);
+    if (Result.IsTypePresent[FixedType])
+      return getExpectedError("yet unread fixed VERSIONINFO statement type",
+                              true);
+
+    // VERSION variations take multiple integers.
+    size_t NumInts = RetType::isVersionType(FixedType) ? 4 : 1;
+    ASSIGN_OR_RETURN(ArgsResult, readIntsWithCommas(NumInts, NumInts));
+    Result.setValue(FixedType, *ArgsResult);
+  }
+
+  return Result;
+}
+
 RCParser::ParseOptionType RCParser::parseLanguageStmt() {
   ASSIGN_OR_RETURN(Args, readIntsWithCommas(/* min = */ 2, /* max = */ 2));
   return make_unique<LanguageResource>((*Args)[0], (*Args)[1]);

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptParser.h?rev=314468&r1=314467&r2=314468&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptParser.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.h Thu Sep 28 15:41:38 2017
@@ -133,6 +133,7 @@ private:
   ParseType parseHTMLResource();
   ParseType parseMenuResource();
   ParseType parseStringTableResource();
+  ParseType parseVersionInfoResource();
 
   // Helper DIALOG parser - a single control.
   Expected<Control> parseControl();
@@ -140,6 +141,15 @@ private:
   // Helper MENU parser.
   Expected<MenuDefinitionList> parseMenuItemsList();
 
+  // Helper VERSIONINFO parser - read the contents of a single BLOCK statement,
+  // from BEGIN to END.
+  Expected<std::unique_ptr<VersionInfoBlock>>
+  parseVersionInfoBlockContents(StringRef BlockName);
+  // Helper VERSIONINFO parser - read either VALUE or BLOCK statement.
+  Expected<std::unique_ptr<VersionInfoStmt>> parseVersionInfoStmt();
+  // Helper VERSIONINFO parser - read fixed VERSIONINFO statements.
+  Expected<VersionInfoResource::VersionInfoFixed> parseVersionInfoFixed();
+
   // Optional statement parsers.
   ParseOptionType parseLanguageStmt();
   ParseOptionType parseCharacteristicsStmt();

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp?rev=314468&r1=314467&r2=314468&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp Thu Sep 28 15:41:38 2017
@@ -142,6 +142,78 @@ raw_ostream &DialogResource::log(raw_ost
   return OS;
 }
 
+raw_ostream &VersionInfoBlock::log(raw_ostream &OS) const {
+  OS << "  Start of block (name: " << Name << ")\n";
+  for (auto &Stmt : Stmts)
+    Stmt->log(OS);
+  return OS << "  End of block\n";
+}
+
+raw_ostream &VersionInfoValue::log(raw_ostream &OS) const {
+  OS << "  " << Key << " =>";
+  for (auto &Value : Values)
+    OS << " " << Value;
+  return OS << "\n";
+}
+
+using VersionInfoFixed = VersionInfoResource::VersionInfoFixed;
+using VersionInfoFixedType = VersionInfoFixed::VersionInfoFixedType;
+
+const StringRef
+    VersionInfoFixed::FixedFieldsNames[VersionInfoFixed::FtNumTypes] = {
+        "",          "FILEVERSION", "PRODUCTVERSION", "FILEFLAGSMASK",
+        "FILEFLAGS", "FILEOS",      "FILETYPE",       "FILESUBTYPE"};
+
+const StringMap<VersionInfoFixedType> VersionInfoFixed::FixedFieldsInfoMap = {
+    {FixedFieldsNames[FtFileVersion], FtFileVersion},
+    {FixedFieldsNames[FtProductVersion], FtProductVersion},
+    {FixedFieldsNames[FtFileFlagsMask], FtFileFlagsMask},
+    {FixedFieldsNames[FtFileFlags], FtFileFlags},
+    {FixedFieldsNames[FtFileOS], FtFileOS},
+    {FixedFieldsNames[FtFileType], FtFileType},
+    {FixedFieldsNames[FtFileSubtype], FtFileSubtype}};
+
+VersionInfoFixedType VersionInfoFixed::getFixedType(StringRef Type) {
+  auto UpperType = Type.upper();
+  auto Iter = FixedFieldsInfoMap.find(UpperType);
+  if (Iter != FixedFieldsInfoMap.end())
+    return Iter->getValue();
+  return FtUnknown;
+}
+
+bool VersionInfoFixed::isTypeSupported(VersionInfoFixedType Type) {
+  return FtUnknown < Type && Type < FtNumTypes;
+}
+
+bool VersionInfoFixed::isVersionType(VersionInfoFixedType Type) {
+  switch (Type) {
+  case FtFileVersion:
+  case FtProductVersion:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
+raw_ostream &VersionInfoFixed::log(raw_ostream &OS) const {
+  for (int Type = FtUnknown; Type < FtNumTypes; ++Type) {
+    if (!isTypeSupported((VersionInfoFixedType)Type))
+      continue;
+    OS << "  Fixed: " << FixedFieldsNames[Type] << ":";
+    for (uint32_t Val : FixedInfo[Type])
+      OS << " " << Val;
+    OS << "\n";
+  }
+  return OS;
+}
+
+raw_ostream &VersionInfoResource::log(raw_ostream &OS) const {
+  OS << "VersionInfo (" << ResName << "):\n";
+  FixedData.log(OS);
+  return MainBlock.log(OS);
+}
+
 raw_ostream &CharacteristicsStmt::log(raw_ostream &OS) const {
   return OS << "Characteristics: " << Value << "\n";
 }

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h?rev=314468&r1=314467&r2=314468&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h Thu Sep 28 15:41:38 2017
@@ -319,6 +319,106 @@ public:
   raw_ostream &log(raw_ostream &) const override;
 };
 
+// -- 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:
+  virtual raw_ostream &log(raw_ostream &OS) const { return OS << "VI stmt\n"; }
+  virtual ~VersionInfoStmt() {}
+};
+
+// 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 {
+  std::vector<std::unique_ptr<VersionInfoStmt>> Stmts;
+  StringRef Name;
+
+public:
+  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;
+};
+
+class VersionInfoValue : public VersionInfoStmt {
+  StringRef Key;
+  std::vector<IntOrString> Values;
+
+public:
+  VersionInfoValue(StringRef InfoKey, std::vector<IntOrString> &&Vals)
+      : Key(InfoKey), Values(std::move(Vals)) {}
+  raw_ostream &log(raw_ostream &) const override;
+};
+
+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;
+  };
+
+private:
+  VersionInfoBlock MainBlock;
+  VersionInfoFixed FixedData;
+
+public:
+  VersionInfoResource(VersionInfoBlock &&TopLevelBlock,
+                      VersionInfoFixed &&FixedInfo)
+      : MainBlock(std::move(TopLevelBlock)), FixedData(std::move(FixedInfo)) {}
+
+  raw_ostream &log(raw_ostream &) const override;
+};
+
 // CHARACTERISTICS optional statement.
 //
 // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380872(v=vs.85).aspx




More information about the llvm-commits mailing list