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, 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 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 ImageData) - : Type(ResourceType), Header(HeaderEntry), Image(ImageData) {} + ArrayRef 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 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 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 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(std::move(*OptStatements)); + auto Accels = llvm::make_unique( + 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(*Arg); + return llvm::make_unique(*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( (*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(Type, read().value()); + return llvm::make_unique(Type, read().value(), + MemoryFlags); default: break; } @@ -457,14 +497,17 @@ Data.push_back(*Item); } - return llvm::make_unique(Type, std::move(Data)); + return llvm::make_unique(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(std::move(**BlockResult), - std::move(*FixedResult)); + return llvm::make_unique( + std::move(**BlockResult), std::move(*FixedResult), MemoryFlags); } Expected 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(*Arg); + return llvm::make_unique(*Arg, MemoryFlags); } RCParser::ParseType RCParser::parseIconResource() { + uint16_t MemoryFlags = + parseMemoryFlags(IconResource::getDefaultMemoryFlags()); ASSIGN_OR_RETURN(Arg, readFilename()); - return llvm::make_unique(*Arg); + return llvm::make_unique(*Arg, MemoryFlags); } RCParser::ParseType RCParser::parseHTMLResource() { + uint16_t MemoryFlags = + parseMemoryFlags(HTMLResource::getDefaultMemoryFlags()); ASSIGN_OR_RETURN(Arg, readFilename()); - return llvm::make_unique(*Arg); + return llvm::make_unique(*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(std::move(*OptStatements), - std::move(*Items)); + std::move(*Items), MemoryFlags); } Expected 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(std::move(*OptStatements)); + auto Table = llvm::make_unique(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 OptStatements; - OptStatementsRCResource(OptionalStmtList &&Stmts) - : OptStatements(llvm::make_unique(std::move(Stmts))) {} + OptStatementsRCResource(OptionalStmtList &&Stmts, + uint16_t Flags = RCResource::getDefaultMemoryFlags()) + : RCResource(Flags), + OptStatements(llvm::make_unique(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 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> 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 Contents; bool IsFileResource; - UserDefinedResource(IntOrString ResourceType, StringRef FileLocation) - : Type(ResourceType), FileLoc(FileLocation), IsFileResource(true) {} - UserDefinedResource(IntOrString ResourceType, std::vector &&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 &&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);