summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/test/tools/llvm-rc/Inputs/memoryflags-stringtable.rc28
-rw-r--r--llvm/test/tools/llvm-rc/Inputs/memoryflags.rc35
-rw-r--r--llvm/test/tools/llvm-rc/memoryflags-stringtable.test15
-rw-r--r--llvm/test/tools/llvm-rc/memoryflags.test323
-rw-r--r--llvm/tools/llvm-rc/ResourceFileWriter.cpp24
-rw-r--r--llvm/tools/llvm-rc/ResourceFileWriter.h4
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptParser.cpp81
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptParser.h2
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptStmt.h73
9 files changed, 533 insertions, 52 deletions
diff --git a/llvm/test/tools/llvm-rc/Inputs/memoryflags-stringtable.rc b/llvm/test/tools/llvm-rc/Inputs/memoryflags-stringtable.rc
new file mode 100644
index 00000000000..098953f1031
--- /dev/null
+++ b/llvm/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"
+}
diff --git a/llvm/test/tools/llvm-rc/Inputs/memoryflags.rc b/llvm/test/tools/llvm-rc/Inputs/memoryflags.rc
new file mode 100644
index 00000000000..7e15f3d57a7
--- /dev/null
+++ b/llvm/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"
diff --git a/llvm/test/tools/llvm-rc/memoryflags-stringtable.test b/llvm/test/tools/llvm-rc/memoryflags-stringtable.test
new file mode 100644
index 00000000000..f168beda7b9
--- /dev/null
+++ b/llvm/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
diff --git a/llvm/test/tools/llvm-rc/memoryflags.test b/llvm/test/tools/llvm-rc/memoryflags.test
new file mode 100644
index 00000000000..c36fb9bda8e
--- /dev/null
+++ b/llvm/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
diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.cpp b/llvm/tools/llvm-rc/ResourceFileWriter.cpp
index 70274b6e051..99fdb82f793 100644
--- a/llvm/tools/llvm-rc/ResourceFileWriter.cpp
+++ b/llvm/tools/llvm-rc/ResourceFileWriter.cpp
@@ -482,8 +482,8 @@ Error ResourceFileWriter::visitStringTableResource(const RCResource *Base) {
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::visitIconOrCursorResource(const RCResource *Base) {
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::visitIconOrCursorResource(const RCResource *Base) {
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; }
diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.h b/llvm/tools/llvm-rc/ResourceFileWriter.h
index ccec41e611b..695d455b6eb 100644
--- a/llvm/tools/llvm-rc/ResourceFileWriter.h
+++ b/llvm/tools/llvm-rc/ResourceFileWriter.h
@@ -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.
diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.cpp b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
index dbdb2210f9c..cdb56f45081 100644
--- a/llvm/tools/llvm-rc/ResourceScriptParser.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
@@ -329,6 +329,37 @@ Expected<uint32_t> RCParser::parseFlags(ArrayRef<StringRef> FlagDesc,
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::parseLanguageResource() {
}
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::parseAcceleratorsResource() {
}
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::parseDialogResource(bool IsExtended) {
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::parseDialogResource(bool IsExtended) {
}
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::parseUserDefinedResource(IntOrString Type) {
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::parseUserDefinedResource(IntOrString Type) {
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::parseMenuItemsList() {
}
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)) {
diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.h b/llvm/tools/llvm-rc/ResourceScriptParser.h
index 639ef63863c..8e3cc55499e 100644
--- a/llvm/tools/llvm-rc/ResourceScriptParser.h
+++ b/llvm/tools/llvm-rc/ResourceScriptParser.h
@@ -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);
diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.h b/llvm/tools/llvm-rc/ResourceScriptStmt.h
index 22a569c34f5..c9a0de09f20 100644
--- a/llvm/tools/llvm-rc/ResourceScriptStmt.h
+++ b/llvm/tools/llvm-rc/ResourceScriptStmt.h
@@ -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 RCResource {
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 OptStatementsRCResource {
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 OptStatementsRCResource {
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);
OpenPOWER on IntegriCloud