[llvm] r332329 - [llvm-rc] Add support for parsing memory flags

Martin Storsjo via llvm-commits llvm-commits at lists.llvm.org
Mon May 14 23:35:29 PDT 2018


Author: mstorsjo
Date: Mon May 14 23:35:29 2018
New Revision: 332329

URL: http://llvm.org/viewvc/llvm-project?rev=332329&view=rev
Log:
[llvm-rc] Add support for parsing memory flags

Most of the handling is pretty straightforward; fetch the default
memory flags for the specific resource type before parsing the flags
and apply them on top of that, except that some flags imply others
and some flags clear more than one flag.

For icons and cursors, the flags set get passed on to all individual
single icon/cursor resources, while only some flags affect the icon/cursor
group resource.

For stringtables, the behaviour is pretty simple; the first stringtable
resource of a bundle sets the flags for the whole bundle.

The output of these tests match rc.exe byte for byte.

The actual use of these memory flags is deprecated and they have no
effect since Win16, but some resource script files may still happen
to have them in place.

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

Added:
    llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags-stringtable.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags.rc
    llvm/trunk/test/tools/llvm-rc/memoryflags-stringtable.test
    llvm/trunk/test/tools/llvm-rc/memoryflags.test
Modified:
    llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp
    llvm/trunk/tools/llvm-rc/ResourceFileWriter.h
    llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp
    llvm/trunk/tools/llvm-rc/ResourceScriptParser.h
    llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h

Added: llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags-stringtable.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags-stringtable.rc?rev=332329&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags-stringtable.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags-stringtable.rc Mon May 14 23:35:29 2018
@@ -0,0 +1,28 @@
+// Flags set on the first stringtable of a bundle gets set
+STRINGTABLE IMPURE {
+  0 "a"
+}
+
+// and end up in effect over whatever data is added here.
+STRINGTABLE
+{
+  1 "b"
+}
+
+STRINGTABLE
+LANGUAGE 4, 7 {
+  2 "c"
+}
+
+// Flags set on a later stringtable as part of an earlier bundle
+// have no effect.
+STRINGTABLE FIXED PRELOAD
+LANGUAGE 4, 7 {
+  3 "d"
+}
+
+// While the same flag on a new bundle does have effect.
+STRINGTABLE FIXED PRELOAD
+LANGUAGE 4, 8 {
+  4 "e"
+}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags.rc?rev=332329&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags.rc Mon May 14 23:35:29 2018
@@ -0,0 +1,35 @@
+1 CURSOR PRELOAD "cursor.cur"
+2 CURSOR LOADONCALL "cursor.cur"
+3 CURSOR FIXED "cursor.cur"
+4 CURSOR MOVEABLE "cursor.cur"
+5 CURSOR DISCARDABLE "cursor.cur"
+6 CURSOR PURE "cursor.cur"
+7 CURSOR IMPURE "cursor.cur"
+8 CURSOR SHARED "cursor.cur"
+9 CURSOR NONSHARED "cursor.cur"
+10 ICON PRELOAD "icon-old.ico"
+11 ICON LOADONCALL "icon-old.ico"
+12 ICON FIXED "icon-old.ico"
+13 ICON MOVEABLE "icon-old.ico"
+14 ICON DISCARDABLE "icon-old.ico"
+15 ICON PURE "icon-old.ico"
+16 ICON IMPURE "icon-old.ico"
+17 ICON SHARED "icon-old.ico"
+18 ICON NONSHARED "icon-old.ico"
+19 BITMAP PRELOAD "bitmap.bmp"
+20 BITMAP LOADONCALL "bitmap.bmp"
+21 BITMAP FIXED "bitmap.bmp"
+22 BITMAP MOVEABLE "bitmap.bmp"
+23 BITMAP DISCARDABLE "bitmap.bmp"
+24 BITMAP PURE "bitmap.bmp"
+25 BITMAP IMPURE "bitmap.bmp"
+26 BITMAP SHARED "bitmap.bmp"
+27 BITMAP NONSHARED "bitmap.bmp"
+28 BITMAP FIXED IMPURE "bitmap.bmp"
+29 BITMAP DISCARDABLE FIXED IMPURE "bitmap.bmp"
+30 BITMAP DISCARDABLE FIXED "bitmap.bmp"
+31 BITMAP DISCARDABLE IMPURE "bitmap.bmp"
+32 BITMAP DISCARDABLE LOADONCALL "bitmap.bmp"
+33 BITMAP FIXED SHARED "bitmap.bmp"
+34 BITMAP FIXED IMPURE SHARED "bitmap.bmp"
+35 BITMAP FIXED IMPURE DISCARDABLE "bitmap.bmp"

Added: llvm/trunk/test/tools/llvm-rc/memoryflags-stringtable.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/memoryflags-stringtable.test?rev=332329&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/memoryflags-stringtable.test (added)
+++ llvm/trunk/test/tools/llvm-rc/memoryflags-stringtable.test Mon May 14 23:35:29 2018
@@ -0,0 +1,15 @@
+; RUN: llvm-rc /FO %t %p/Inputs/memoryflags-stringtable.rc
+; RUN: llvm-readobj %t | FileCheck %s
+
+; CHECK:      Resource type (int): 6
+; CHECK-NEXT: Resource name (int): 1
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 6
+; CHECK-NEXT: Resource name (int): 1
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 6
+; CHECK-NEXT: Resource name (int): 1
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x60

Added: llvm/trunk/test/tools/llvm-rc/memoryflags.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/memoryflags.test?rev=332329&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/memoryflags.test (added)
+++ llvm/trunk/test/tools/llvm-rc/memoryflags.test Mon May 14 23:35:29 2018
@@ -0,0 +1,323 @@
+; RUN: llvm-rc /FO %t %p/Inputs/memoryflags.rc
+; RUN: llvm-readobj %t | FileCheck %s
+
+; CHECK:      Resource type (int): 1
+; CHECK-NEXT: Resource name (int): 1
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1050
+; CHECK:      Resource type (int): 12
+; CHECK-NEXT: Resource name (int): 1
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1050
+; CHECK:      Resource type (int): 1
+; CHECK-NEXT: Resource name (int): 2
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1010
+; CHECK:      Resource type (int): 12
+; CHECK-NEXT: Resource name (int): 2
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 1
+; CHECK-NEXT: Resource name (int): 3
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x0
+; CHECK:      Resource type (int): 12
+; CHECK-NEXT: Resource name (int): 3
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 1
+; CHECK-NEXT: Resource name (int): 4
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1010
+; CHECK:      Resource type (int): 12
+; CHECK-NEXT: Resource name (int): 4
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 1
+; CHECK-NEXT: Resource name (int): 5
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 12
+; CHECK-NEXT: Resource name (int): 5
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 1
+; CHECK-NEXT: Resource name (int): 6
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 12
+; CHECK-NEXT: Resource name (int): 6
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 1
+; CHECK-NEXT: Resource name (int): 7
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 12
+; CHECK-NEXT: Resource name (int): 7
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 1
+; CHECK-NEXT: Resource name (int): 8
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 12
+; CHECK-NEXT: Resource name (int): 8
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 1
+; CHECK-NEXT: Resource name (int): 9
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 12
+; CHECK-NEXT: Resource name (int): 9
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 10
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1050
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 11
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1050
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 12
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1050
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 13
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1050
+; CHECK:      Resource type (int): 14
+; CHECK-NEXT: Resource name (int): 10
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1050
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 14
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1010
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 15
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1010
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 16
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1010
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 17
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1010
+; CHECK:      Resource type (int): 14
+; CHECK-NEXT: Resource name (int): 11
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 18
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x0
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 19
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x0
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 20
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x0
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 21
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x0
+; CHECK:      Resource type (int): 14
+; CHECK-NEXT: Resource name (int): 12
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 22
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1010
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 23
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1010
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 24
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1010
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 25
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1010
+; CHECK:      Resource type (int): 14
+; CHECK-NEXT: Resource name (int): 13
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 26
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 27
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 28
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 29
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 14
+; CHECK-NEXT: Resource name (int): 14
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 30
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 31
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 32
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 33
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 14
+; CHECK-NEXT: Resource name (int): 15
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 34
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 35
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 36
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 37
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 14
+; CHECK-NEXT: Resource name (int): 16
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 38
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 39
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 40
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 41
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 14
+; CHECK-NEXT: Resource name (int): 17
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 42
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 43
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 44
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 3
+; CHECK-NEXT: Resource name (int): 45
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 14
+; CHECK-NEXT: Resource name (int): 18
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 19
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x70
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 20
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x30
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 21
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x20
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 22
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x30
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 23
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 24
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x30
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 25
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 26
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x30
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 27
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 28
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x0
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 29
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x0
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 30
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x20
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 31
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x10
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 32
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 33
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x20
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 34
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x20
+; CHECK:      Resource type (int): 2
+; CHECK-NEXT: Resource name (int): 35
+; CHECK-NEXT: Data version: 0
+; CHECK-NEXT: Memory flags: 0x1030

Modified: llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp?rev=332329&r1=332328&r2=332329&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp (original)
+++ llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp Mon May 14 23:35:29 2018
@@ -482,8 +482,8 @@ Error ResourceFileWriter::visitStringTab
     if (Iter == BundleData.end()) {
       // Need to create a bundle.
       StringTableData.BundleList.push_back(Key);
-      auto EmplaceResult =
-          BundleData.emplace(Key, StringTableInfo::Bundle(ObjectData));
+      auto EmplaceResult = BundleData.emplace(
+          Key, StringTableInfo::Bundle(ObjectData, Res->MemoryFlags));
       assert(EmplaceResult.second && "Could not create a bundle");
       Iter = EmplaceResult.first;
     }
@@ -556,7 +556,7 @@ Error ResourceFileWriter::writeResource(
   padStream(sizeof(uint32_t));
   object::WinResHeaderSuffix HeaderSuffix{
       ulittle32_t(0), // DataVersion; seems to always be 0
-      ulittle16_t(Res->getMemoryFlags()), ulittle16_t(ObjectData.LanguageInfo),
+      ulittle16_t(Res->MemoryFlags), ulittle16_t(ObjectData.LanguageInfo),
       ulittle32_t(ObjectData.VersionInfo),
       ulittle32_t(ObjectData.Characteristics)};
   writeObject(HeaderSuffix);
@@ -785,16 +785,14 @@ public:
 
   SingleIconCursorResource(IconCursorGroupType ResourceType,
                            const ResourceDirEntryStart &HeaderEntry,
-                           ArrayRef<uint8_t> ImageData)
-      : Type(ResourceType), Header(HeaderEntry), Image(ImageData) {}
+                           ArrayRef<uint8_t> ImageData, uint16_t Flags)
+      : RCResource(Flags), Type(ResourceType), Header(HeaderEntry),
+        Image(ImageData) {}
 
   Twine getResourceTypeName() const override { return "Icon/cursor image"; }
   IntOrString getResourceType() const override {
     return Type == IconCursorGroupType::Icon ? RkSingleIcon : RkSingleCursor;
   }
-  uint16_t getMemoryFlags() const override {
-    return MfDiscardable | MfMoveable;
-  }
   ResourceKind getKind() const override { return RkSingleCursorOrIconRes; }
   static bool classof(const RCResource *Res) {
     return Res->getKind() == RkSingleCursorOrIconRes;
@@ -915,7 +913,8 @@ Error ResourceFileWriter::visitIconOrCur
     Reader.setOffset(ItemOffsets[ID]);
     ArrayRef<uint8_t> Image;
     RETURN_IF_ERROR(Reader.readArray(Image, ItemEntries[ID].Size));
-    SingleIconCursorResource SingleRes(Type, ItemEntries[ID], Image);
+    SingleIconCursorResource SingleRes(Type, ItemEntries[ID], Image,
+                                       Base->MemoryFlags);
     SingleRes.setName(IconCursorID + ID);
     RETURN_IF_ERROR(visitSingleIconOrCursor(&SingleRes));
   }
@@ -961,6 +960,10 @@ Error ResourceFileWriter::visitIconOrCur
 
   IconCursorGroupResource HeaderRes(Type, *Header, std::move(ItemEntries));
   HeaderRes.setName(ResName);
+  if (Base->MemoryFlags & MfPreload) {
+    HeaderRes.MemoryFlags |= MfPreload;
+    HeaderRes.MemoryFlags &= ~MfPure;
+  }
   RETURN_IF_ERROR(visitIconOrCursorGroup(&HeaderRes));
 
   return Error::success();
@@ -1214,7 +1217,8 @@ public:
   using BundleType = ResourceFileWriter::StringTableInfo::Bundle;
   BundleType Bundle;
 
-  BundleResource(const BundleType &StrBundle) : Bundle(StrBundle) {}
+  BundleResource(const BundleType &StrBundle)
+      : RCResource(StrBundle.MemoryFlags), Bundle(StrBundle) {}
   IntOrString getResourceType() const override { return 6; }
 
   ResourceKind getKind() const override { return RkStringTableBundle; }

Modified: llvm/trunk/tools/llvm-rc/ResourceFileWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceFileWriter.h?rev=332329&r1=332328&r2=332329&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceFileWriter.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceFileWriter.h Mon May 14 23:35:29 2018
@@ -100,7 +100,9 @@ public:
     struct Bundle {
       std::array<Optional<StringRef>, 16> Data;
       ObjectInfo DeclTimeInfo;
-      Bundle(const ObjectInfo &Info) : DeclTimeInfo(Info) {}
+      uint16_t MemoryFlags;
+      Bundle(const ObjectInfo &Info, uint16_t Flags)
+          : DeclTimeInfo(Info), MemoryFlags(Flags) {}
     };
     std::map<BundleKey, Bundle> BundleData;
     // Bundles are listed in the order of their first occurrence.

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp?rev=332329&r1=332328&r2=332329&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp Mon May 14 23:35:29 2018
@@ -329,6 +329,37 @@ Expected<uint32_t> RCParser::parseFlags(
   return Result;
 }
 
+uint16_t RCParser::parseMemoryFlags(uint16_t Flags) {
+  while (!isEof()) {
+    const RCToken &Token = look();
+    if (Token.kind() != Kind::Identifier)
+      return Flags;
+    const StringRef Ident = Token.value();
+    if (Ident.equals_lower("PRELOAD"))
+      Flags |= MfPreload;
+    else if (Ident.equals_lower("LOADONCALL"))
+      Flags &= ~MfPreload;
+    else if (Ident.equals_lower("FIXED"))
+      Flags &= ~(MfMoveable | MfDiscardable);
+    else if (Ident.equals_lower("MOVEABLE"))
+      Flags |= MfMoveable;
+    else if (Ident.equals_lower("DISCARDABLE"))
+      Flags |= MfDiscardable | MfMoveable | MfPure;
+    else if (Ident.equals_lower("PURE"))
+      Flags |= MfPure;
+    else if (Ident.equals_lower("IMPURE"))
+      Flags &= ~(MfPure | MfDiscardable);
+    else if (Ident.equals_lower("SHARED"))
+      Flags |= MfPure;
+    else if (Ident.equals_lower("NONSHARED"))
+      Flags &= ~(MfPure | MfDiscardable);
+    else
+      return Flags;
+    consume();
+  }
+  return Flags;
+}
+
 Expected<OptionalStmtList>
 RCParser::parseOptionalStatements(OptStmtType StmtsType) {
   OptionalStmtList Result;
@@ -372,11 +403,13 @@ RCParser::ParseType RCParser::parseLangu
 }
 
 RCParser::ParseType RCParser::parseAcceleratorsResource() {
+  uint16_t MemoryFlags =
+      parseMemoryFlags(AcceleratorsResource::getDefaultMemoryFlags());
   ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements());
   RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
 
-  auto Accels =
-      llvm::make_unique<AcceleratorsResource>(std::move(*OptStatements));
+  auto Accels = llvm::make_unique<AcceleratorsResource>(
+      std::move(*OptStatements), MemoryFlags);
 
   while (!consumeOptionalType(Kind::BlockEnd)) {
     ASSIGN_OR_RETURN(EventResult, readIntOrString());
@@ -393,11 +426,15 @@ RCParser::ParseType RCParser::parseAccel
 }
 
 RCParser::ParseType RCParser::parseCursorResource() {
+  uint16_t MemoryFlags =
+      parseMemoryFlags(CursorResource::getDefaultMemoryFlags());
   ASSIGN_OR_RETURN(Arg, readFilename());
-  return llvm::make_unique<CursorResource>(*Arg);
+  return llvm::make_unique<CursorResource>(*Arg, MemoryFlags);
 }
 
 RCParser::ParseType RCParser::parseDialogResource(bool IsExtended) {
+  uint16_t MemoryFlags =
+      parseMemoryFlags(DialogResource::getDefaultMemoryFlags());
   // 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...}
@@ -420,7 +457,7 @@ RCParser::ParseType RCParser::parseDialo
 
   auto Dialog = llvm::make_unique<DialogResource>(
       (*LocResult)[0], (*LocResult)[1], (*LocResult)[2], (*LocResult)[3],
-      HelpID, std::move(*OptStatements), IsExtended);
+      HelpID, std::move(*OptStatements), IsExtended, MemoryFlags);
 
   while (!consumeOptionalType(Kind::BlockEnd)) {
     ASSIGN_OR_RETURN(ControlDefResult, parseControl());
@@ -431,6 +468,8 @@ RCParser::ParseType RCParser::parseDialo
 }
 
 RCParser::ParseType RCParser::parseUserDefinedResource(IntOrString Type) {
+  uint16_t MemoryFlags =
+      parseMemoryFlags(UserDefinedResource::getDefaultMemoryFlags());
   if (isEof())
     return getExpectedError("filename, '{' or BEGIN");
 
@@ -438,7 +477,8 @@ RCParser::ParseType RCParser::parseUserD
   switch (look().kind()) {
   case Kind::String:
   case Kind::Identifier:
-    return llvm::make_unique<UserDefinedResource>(Type, read().value());
+    return llvm::make_unique<UserDefinedResource>(Type, read().value(),
+                                                  MemoryFlags);
   default:
     break;
   }
@@ -457,14 +497,17 @@ RCParser::ParseType RCParser::parseUserD
     Data.push_back(*Item);
   }
 
-  return llvm::make_unique<UserDefinedResource>(Type, std::move(Data));
+  return llvm::make_unique<UserDefinedResource>(Type, std::move(Data),
+                                                MemoryFlags);
 }
 
 RCParser::ParseType RCParser::parseVersionInfoResource() {
+  uint16_t MemoryFlags =
+      parseMemoryFlags(VersionInfoResource::getDefaultMemoryFlags());
   ASSIGN_OR_RETURN(FixedResult, parseVersionInfoFixed());
   ASSIGN_OR_RETURN(BlockResult, parseVersionInfoBlockContents(StringRef()));
-  return llvm::make_unique<VersionInfoResource>(std::move(**BlockResult),
-                                                std::move(*FixedResult));
+  return llvm::make_unique<VersionInfoResource>(
+      std::move(**BlockResult), std::move(*FixedResult), MemoryFlags);
 }
 
 Expected<Control> RCParser::parseControl() {
@@ -531,25 +574,33 @@ Expected<Control> RCParser::parseControl
 }
 
 RCParser::ParseType RCParser::parseBitmapResource() {
+  uint16_t MemoryFlags =
+      parseMemoryFlags(BitmapResource::getDefaultMemoryFlags());
   ASSIGN_OR_RETURN(Arg, readFilename());
-  return llvm::make_unique<BitmapResource>(*Arg);
+  return llvm::make_unique<BitmapResource>(*Arg, MemoryFlags);
 }
 
 RCParser::ParseType RCParser::parseIconResource() {
+  uint16_t MemoryFlags =
+      parseMemoryFlags(IconResource::getDefaultMemoryFlags());
   ASSIGN_OR_RETURN(Arg, readFilename());
-  return llvm::make_unique<IconResource>(*Arg);
+  return llvm::make_unique<IconResource>(*Arg, MemoryFlags);
 }
 
 RCParser::ParseType RCParser::parseHTMLResource() {
+  uint16_t MemoryFlags =
+      parseMemoryFlags(HTMLResource::getDefaultMemoryFlags());
   ASSIGN_OR_RETURN(Arg, readFilename());
-  return llvm::make_unique<HTMLResource>(*Arg);
+  return llvm::make_unique<HTMLResource>(*Arg, MemoryFlags);
 }
 
 RCParser::ParseType RCParser::parseMenuResource() {
+  uint16_t MemoryFlags =
+      parseMemoryFlags(MenuResource::getDefaultMemoryFlags());
   ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements());
   ASSIGN_OR_RETURN(Items, parseMenuItemsList());
   return llvm::make_unique<MenuResource>(std::move(*OptStatements),
-                                         std::move(*Items));
+                                         std::move(*Items), MemoryFlags);
 }
 
 Expected<MenuDefinitionList> RCParser::parseMenuItemsList() {
@@ -612,11 +663,13 @@ Expected<MenuDefinitionList> RCParser::p
 }
 
 RCParser::ParseType RCParser::parseStringTableResource() {
+  uint16_t MemoryFlags =
+      parseMemoryFlags(StringTableResource::getDefaultMemoryFlags());
   ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements());
   RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
 
-  auto Table =
-      llvm::make_unique<StringTableResource>(std::move(*OptStatements));
+  auto Table = llvm::make_unique<StringTableResource>(std::move(*OptStatements),
+                                                      MemoryFlags);
 
   // Read strings until we reach the end of the block.
   while (!consumeOptionalType(Kind::BlockEnd)) {

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptParser.h?rev=332329&r1=332328&r2=332329&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptParser.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.h Mon May 14 23:35:29 2018
@@ -129,6 +129,8 @@ private:
   //    msdn.microsoft.com/en-us/library/windows/desktop/aa381002(v=vs.85).aspx
   enum class OptStmtType { BasicStmt, DialogStmt, DialogExStmt };
 
+  uint16_t parseMemoryFlags(uint16_t DefaultFlags);
+
   Expected<OptionalStmtList>
   parseOptionalStatements(OptStmtType StmtsType = OptStmtType::BasicStmt);
 

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h?rev=332329&r1=332328&r2=332329&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h Mon May 14 23:35:29 2018
@@ -160,10 +160,13 @@ enum MemoryFlags {
 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 {
@@ -175,9 +178,10 @@ public:
   virtual Error applyStmts(Visitor *) const { return Error::success(); }
 
   // By default, memory flags are DISCARDABLE | PURE | MOVEABLE.
-  virtual uint16_t getMemoryFlags() const {
+  static uint16_t getDefaultMemoryFlags() {
     return MfDiscardable | MfPure | MfMoveable;
   }
+
   virtual ResourceKind getKind() const { return RkBase; }
   static bool classof(const RCResource *Res) { return true; }
 
@@ -193,13 +197,13 @@ public:
 // 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)"; }
-  uint16_t getMemoryFlags() const override { return 0; }
 };
 
 // Optional statement base. All such statements should derive from this base.
@@ -228,8 +232,10 @@ class OptStatementsRCResource : public R
 public:
   std::unique_ptr<OptionalStmtList> OptStatements;
 
-  OptStatementsRCResource(OptionalStmtList &&Stmts)
-      : OptStatements(llvm::make_unique<OptionalStmtList>(std::move(Stmts))) {}
+  OptStatementsRCResource(OptionalStmtList &&Stmts,
+                          uint16_t Flags = RCResource::getDefaultMemoryFlags())
+      : RCResource(Flags),
+        OptStatements(llvm::make_unique<OptionalStmtList>(std::move(Stmts))) {}
 
   virtual Error applyStmts(Visitor *V) const { return OptStatements->visit(V); }
 };
@@ -284,18 +290,18 @@ public:
     static uint32_t OptionsFlags[NumFlags];
   };
 
+  AcceleratorsResource(OptionalStmtList &&List, uint16_t Flags)
+      : OptStatementsRCResource(std::move(List), Flags) {}
+
   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;
-  }
+  static uint16_t getDefaultMemoryFlags() { return MfPure | MfMoveable; }
   Twine getResourceTypeName() const override { return "ACCELERATORS"; }
 
   Error visit(Visitor *V) const override {
@@ -314,11 +320,12 @@ class BitmapResource : public RCResource
 public:
   StringRef BitmapLoc;
 
-  BitmapResource(StringRef Location) : BitmapLoc(Location) {}
+  BitmapResource(StringRef Location, uint16_t Flags)
+      : RCResource(Flags), BitmapLoc(Location) {}
   raw_ostream &log(raw_ostream &) const override;
 
   IntOrString getResourceType() const override { return RkBitmap; }
-  uint16_t getMemoryFlags() const override { return MfPure | MfMoveable; }
+  static uint16_t getDefaultMemoryFlags() { return MfPure | MfMoveable; }
 
   Twine getResourceTypeName() const override { return "BITMAP"; }
   Error visit(Visitor *V) const override {
@@ -337,10 +344,12 @@ class CursorResource : public RCResource
 public:
   StringRef CursorLoc;
 
-  CursorResource(StringRef Location) : CursorLoc(Location) {}
+  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);
   }
@@ -357,10 +366,12 @@ class IconResource : public RCResource {
 public:
   StringRef IconLoc;
 
-  IconResource(StringRef Location) : IconLoc(Location) {}
+  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) {
@@ -377,13 +388,14 @@ class HTMLResource : public RCResource {
 public:
   StringRef HTMLLoc;
 
-  HTMLResource(StringRef Location) : HTMLLoc(Location) {}
+  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.
-  uint16_t getMemoryFlags() const override { return MfPure | MfMoveable; }
+  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; }
@@ -497,8 +509,9 @@ class MenuResource : public OptStatement
 public:
   MenuDefinitionList Elements;
 
-  MenuResource(OptionalStmtList &&OptStmts, MenuDefinitionList &&Items)
-      : OptStatementsRCResource(std::move(OptStmts)),
+  MenuResource(OptionalStmtList &&OptStmts, MenuDefinitionList &&Items,
+               uint16_t Flags)
+      : OptStatementsRCResource(std::move(OptStmts), Flags),
         Elements(std::move(Items)) {}
   raw_ostream &log(raw_ostream &) const override;
 
@@ -518,7 +531,8 @@ class StringTableResource : public OptSt
 public:
   std::vector<std::pair<uint32_t, StringRef>> Table;
 
-  using OptStatementsRCResource::OptStatementsRCResource;
+  StringTableResource(OptionalStmtList &&List, uint16_t Flags)
+      : OptStatementsRCResource(std::move(List), Flags) {}
   void addString(uint32_t ID, StringRef String) {
     Table.emplace_back(ID, String);
   }
@@ -588,8 +602,8 @@ public:
 
   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),
+                 OptionalStmtList &&OptStmts, bool IsDialogEx, uint16_t Flags)
+      : OptStatementsRCResource(std::move(OptStmts), Flags), X(PosX), Y(PosY),
         Width(DlgWidth), Height(DlgHeight), HelpID(DlgHelpID),
         IsExtended(IsDialogEx) {}
 
@@ -623,15 +637,19 @@ public:
   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) {}
+  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; }
-  uint16_t getMemoryFlags() const override { return MfPure | MfMoveable; }
+  static uint16_t getDefaultMemoryFlags() { return MfPure | MfMoveable; }
 
   Error visit(Visitor *V) const override {
     return V->visitUserDefinedResource(this);
@@ -754,12 +772,13 @@ public:
   VersionInfoFixed FixedData;
 
   VersionInfoResource(VersionInfoBlock &&TopLevelBlock,
-                      VersionInfoFixed &&FixedInfo)
-      : MainBlock(std::move(TopLevelBlock)), FixedData(std::move(FixedInfo)) {}
+                      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; }
-  uint16_t getMemoryFlags() const override { return MfMoveable | MfPure; }
+  static uint16_t getDefaultMemoryFlags() { return MfMoveable | MfPure; }
   Twine getResourceTypeName() const override { return "VERSIONINFO"; }
   Error visit(Visitor *V) const override {
     return V->visitVersionInfoResource(this);




More information about the llvm-commits mailing list