diff options
author | Martin Storsjo <martin@martin.st> | 2018-05-15 06:35:29 +0000 |
---|---|---|
committer | Martin Storsjo <martin@martin.st> | 2018-05-15 06:35:29 +0000 |
commit | 11adbacac86a740724d3bfe8f7de6563bf71a617 (patch) | |
tree | b3bed74b0aad995a2d3eb8c72c56c8d6b813de6a /llvm/tools/llvm-rc/ResourceScriptParser.cpp | |
parent | 860e5fcdf4305c0681c4e77e17b22d2e54fe163b (diff) | |
download | bcm5719-llvm-11adbacac86a740724d3bfe8f7de6563bf71a617.tar.gz bcm5719-llvm-11adbacac86a740724d3bfe8f7de6563bf71a617.zip |
[llvm-rc] Add support for parsing memory flags
Most of the handling is pretty straightforward; fetch the default
memory flags for the specific resource type before parsing the flags
and apply them on top of that, except that some flags imply others
and some flags clear more than one flag.
For icons and cursors, the flags set get passed on to all individual
single icon/cursor resources, while only some flags affect the icon/cursor
group resource.
For stringtables, the behaviour is pretty simple; the first stringtable
resource of a bundle sets the flags for the whole bundle.
The output of these tests match rc.exe byte for byte.
The actual use of these memory flags is deprecated and they have no
effect since Win16, but some resource script files may still happen
to have them in place.
Differential Revision: https://reviews.llvm.org/D46818
llvm-svn: 332329
Diffstat (limited to 'llvm/tools/llvm-rc/ResourceScriptParser.cpp')
-rw-r--r-- | llvm/tools/llvm-rc/ResourceScriptParser.cpp | 81 |
1 files changed, 67 insertions, 14 deletions
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)) { |