Index: llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags-stringtable.rc
===================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags-stringtable.rc
+++ llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags-stringtable.rc
@@ -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"
+}
Index: llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags.rc
===================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags.rc
+++ llvm/trunk/test/tools/llvm-rc/Inputs/memoryflags.rc
@@ -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"
Index: llvm/trunk/test/tools/llvm-rc/memoryflags-stringtable.test
===================================================================
--- llvm/trunk/test/tools/llvm-rc/memoryflags-stringtable.test
+++ llvm/trunk/test/tools/llvm-rc/memoryflags-stringtable.test
@@ -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
Index: llvm/trunk/test/tools/llvm-rc/memoryflags.test
===================================================================
--- llvm/trunk/test/tools/llvm-rc/memoryflags.test
+++ llvm/trunk/test/tools/llvm-rc/memoryflags.test
@@ -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
Index: llvm/trunk/tools/llvm-rc/ResourceFileWriter.h
===================================================================
--- llvm/trunk/tools/llvm-rc/ResourceFileWriter.h
+++ llvm/trunk/tools/llvm-rc/ResourceFileWriter.h
@@ -100,7 +100,9 @@
     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.
Index: llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp
===================================================================
--- llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp
+++ llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp
@@ -482,8 +482,8 @@
     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 @@
   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 @@
 
   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 @@
     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 @@
 
   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 @@
   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; }
Index: llvm/trunk/tools/llvm-rc/ResourceScriptParser.h
===================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptParser.h
+++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.h
@@ -129,6 +129,8 @@
   //    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);
 
Index: llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp
===================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp
+++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp
@@ -329,6 +329,37 @@
   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::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::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 @@
 
   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::parseUserDefinedResource(IntOrString Type) {
+  uint16_t MemoryFlags =
+      parseMemoryFlags(UserDefinedResource::getDefaultMemoryFlags());
   if (isEof())
     return getExpectedError("filename, '{' or BEGIN");
 
@@ -438,7 +477,8 @@
   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 @@
     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 @@
 }
 
 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 @@
 }
 
 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)) {
Index: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h
===================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h
+++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h
@@ -160,10 +160,13 @@
 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 @@
   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 @@
 // 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 @@
 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 @@
     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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 
   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 @@
   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 @@
   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);