summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-rc/ResourceScriptParser.cpp
diff options
context:
space:
mode:
authorMarek Sokolowski <mnbvmar@gmail.com>2017-08-28 22:58:31 +0000
committerMarek Sokolowski <mnbvmar@gmail.com>2017-08-28 22:58:31 +0000
commit7f110527415edc30c2abd027736347a80708cb98 (patch)
treee9f895228bd5f85c3fd09788de7c7d67afb5eae8 /llvm/tools/llvm-rc/ResourceScriptParser.cpp
parentc07008653c109345b1446f27f2ccc72dbfe5da41 (diff)
downloadbcm5719-llvm-7f110527415edc30c2abd027736347a80708cb98.tar.gz
bcm5719-llvm-7f110527415edc30c2abd027736347a80708cb98.zip
[llvm-rc] Add ACCELERATORS parsing ability. (parser, pt 3/8).
This improves the current llvm-rc parser by the ability of parsing ACCELERATORS statement. Moreover, some small improvements to the original parsing commit were made. Thanks for Nico Weber for his original work in this area. Differential Revision: https://reviews.llvm.org/D36894 llvm-svn: 311946
Diffstat (limited to 'llvm/tools/llvm-rc/ResourceScriptParser.cpp')
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptParser.cpp61
1 files changed, 54 insertions, 7 deletions
diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.cpp b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
index e4c0f2a7f7c..8d08396e615 100644
--- a/llvm/tools/llvm-rc/ResourceScriptParser.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
@@ -63,7 +63,9 @@ RCParser::ParseType RCParser::parseSingleResource() {
ParseType Result = std::unique_ptr<RCResource>();
(void)!Result;
- if (TypeToken->equalsLower("CURSOR"))
+ if (TypeToken->equalsLower("ACCELERATORS"))
+ Result = parseAcceleratorsResource();
+ else if (TypeToken->equalsLower("CURSOR"))
Result = parseCursorResource();
else if (TypeToken->equalsLower("ICON"))
Result = parseIconResource();
@@ -115,17 +117,18 @@ Expected<StringRef> RCParser::readIdentifier() {
return read().value();
}
+Expected<IntOrString> RCParser::readIntOrString() {
+ if (!isNextTokenKind(Kind::Int) && !isNextTokenKind(Kind::String))
+ return getExpectedError("int or string");
+ return IntOrString(read());
+}
+
Expected<IntOrString> RCParser::readTypeOrName() {
// We suggest that the correct resource name or type should be either an
// identifier or an integer. The original RC tool is much more liberal.
if (!isNextTokenKind(Kind::Identifier) && !isNextTokenKind(Kind::Int))
return getExpectedError("int or identifier");
-
- const RCToken &Tok = read();
- if (Tok.kind() == Kind::Int)
- return IntOrString(Tok.intValue());
- else
- return IntOrString(Tok.value());
+ return IntOrString(read());
}
Error RCParser::consumeType(Kind TokenKind) {
@@ -190,6 +193,32 @@ RCParser::readIntsWithCommas(size_t MinCount, size_t MaxCount) {
return std::move(Result);
}
+Expected<uint32_t> RCParser::parseFlags(ArrayRef<StringRef> FlagDesc) {
+ assert(FlagDesc.size() <= 32 && "More than 32 flags won't fit in result.");
+ assert(!FlagDesc.empty());
+
+ uint32_t Result = 0;
+ while (isNextTokenKind(Kind::Comma)) {
+ consume();
+ ASSIGN_OR_RETURN(FlagResult, readIdentifier());
+ bool FoundFlag = false;
+
+ for (size_t FlagId = 0; FlagId < FlagDesc.size(); ++FlagId) {
+ if (!FlagResult->equals_lower(FlagDesc[FlagId]))
+ continue;
+
+ Result |= (1U << FlagId);
+ FoundFlag = true;
+ break;
+ }
+
+ if (!FoundFlag)
+ return getExpectedError(join(FlagDesc, "/"), true);
+ }
+
+ return Result;
+}
+
// As for now, we ignore the extended set of statements.
Expected<OptionalStmtList> RCParser::parseOptionalStatements(bool IsExtended) {
OptionalStmtList Result;
@@ -223,6 +252,24 @@ RCParser::ParseType RCParser::parseLanguageResource() {
return parseLanguageStmt();
}
+RCParser::ParseType RCParser::parseAcceleratorsResource() {
+ ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements());
+ RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
+
+ auto Accels = make_unique<AcceleratorsResource>(std::move(*OptStatements));
+
+ while (!consumeOptionalType(Kind::BlockEnd)) {
+ ASSIGN_OR_RETURN(EventResult, readIntOrString());
+ RETURN_IF_ERROR(consumeType(Kind::Comma));
+ ASSIGN_OR_RETURN(IDResult, readInt());
+ ASSIGN_OR_RETURN(FlagsResult,
+ parseFlags(AcceleratorsResource::Accelerator::OptionsStr));
+ Accels->addAccelerator(*EventResult, *IDResult, *FlagsResult);
+ }
+
+ return std::move(Accels);
+}
+
RCParser::ParseType RCParser::parseCursorResource() {
ASSIGN_OR_RETURN(Arg, readString());
return make_unique<CursorResource>(*Arg);
OpenPOWER on IntegriCloud