diff --git a/llvm/test/tools/llvm-rc/Inputs/tag-stringtable-basic.rc b/llvm/test/tools/llvm-rc/Inputs/tag-stringtable-basic.rc --- a/llvm/test/tools/llvm-rc/Inputs/tag-stringtable-basic.rc +++ b/llvm/test/tools/llvm-rc/Inputs/tag-stringtable-basic.rc @@ -13,8 +13,8 @@ STRINGTABLE VERSION 100 LANGUAGE 4, 7 { - 16 "hello" - 17 "world" + 16 "hel" "lo" + 17 "wor" L"ld" } STRINGTABLE diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.h b/llvm/tools/llvm-rc/ResourceFileWriter.h --- a/llvm/tools/llvm-rc/ResourceFileWriter.h +++ b/llvm/tools/llvm-rc/ResourceFileWriter.h @@ -103,7 +103,7 @@ using BundleKey = std::pair; // Each bundle is in fact an array of 16 strings. struct Bundle { - std::array, 16> Data; + std::array>, 16> Data; ObjectInfo DeclTimeInfo; uint16_t MemoryFlags; Bundle(const ObjectInfo &Info, uint16_t Flags) @@ -157,7 +157,8 @@ Error visitStringTableBundle(const RCResource *); Error writeStringTableBundleBody(const RCResource *); Error insertStringIntoBundle(StringTableInfo::Bundle &Bundle, - uint16_t StringID, StringRef String); + uint16_t StringID, + const std::vector &String); // User defined resource Error writeUserDefinedBody(const RCResource *); diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.cpp b/llvm/tools/llvm-rc/ResourceFileWriter.cpp --- a/llvm/tools/llvm-rc/ResourceFileWriter.cpp +++ b/llvm/tools/llvm-rc/ResourceFileWriter.cpp @@ -1246,7 +1246,8 @@ } Error ResourceFileWriter::insertStringIntoBundle( - StringTableInfo::Bundle &Bundle, uint16_t StringID, StringRef String) { + StringTableInfo::Bundle &Bundle, uint16_t StringID, + const std::vector &String) { uint16_t StringLoc = StringID & 15; if (Bundle.Data[StringLoc]) return createError("Multiple STRINGTABLE strings located under ID " + @@ -1261,13 +1262,15 @@ // The string format is a tiny bit different here. We // first output the size of the string, and then the string itself // (which is not null-terminated). - bool IsLongString; SmallVector Data; - RETURN_IF_ERROR(processString(Res->Bundle.Data[ID].getValueOr(StringRef()), - NullHandlingMethod::CutAtDoubleNull, - IsLongString, Data, Params.CodePage)); - if (AppendNull && Res->Bundle.Data[ID]) - Data.push_back('\0'); + if (Res->Bundle.Data[ID]) { + bool IsLongString; + for (StringRef S : *Res->Bundle.Data[ID]) + RETURN_IF_ERROR(processString(S, NullHandlingMethod::CutAtDoubleNull, + IsLongString, Data, Params.CodePage)); + if (AppendNull) + Data.push_back('\0'); + } RETURN_IF_ERROR( checkNumberFits(Data.size(), "STRINGTABLE string size")); writeInt(Data.size()); diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.cpp b/llvm/tools/llvm-rc/ResourceScriptParser.cpp --- a/llvm/tools/llvm-rc/ResourceScriptParser.cpp +++ b/llvm/tools/llvm-rc/ResourceScriptParser.cpp @@ -698,8 +698,14 @@ // between, however we strictly adhere to the single statement definition. ASSIGN_OR_RETURN(IDResult, readInt()); consumeOptionalType(Kind::Comma); + + std::vector Strings; ASSIGN_OR_RETURN(StrResult, readString()); - Table->addString(*IDResult, *StrResult); + Strings.push_back(*StrResult); + while (isNextTokenKind(Kind::String)) + Strings.push_back(read().value()); + + Table->addStrings(*IDResult, std::move(Strings)); } return std::move(Table); diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.h b/llvm/tools/llvm-rc/ResourceScriptStmt.h --- a/llvm/tools/llvm-rc/ResourceScriptStmt.h +++ b/llvm/tools/llvm-rc/ResourceScriptStmt.h @@ -583,12 +583,12 @@ // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381050(v=vs.85).aspx class StringTableResource : public OptStatementsRCResource { public: - std::vector> Table; + std::vector>> Table; StringTableResource(OptionalStmtList &&List, uint16_t Flags) : OptStatementsRCResource(std::move(List), Flags) {} - void addString(uint32_t ID, StringRef String) { - Table.emplace_back(ID, String); + void addStrings(uint32_t ID, std::vector &&Strings) { + Table.emplace_back(ID, Strings); } raw_ostream &log(raw_ostream &) const override; Twine getResourceTypeName() const override { return "STRINGTABLE"; } diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.cpp b/llvm/tools/llvm-rc/ResourceScriptStmt.cpp --- a/llvm/tools/llvm-rc/ResourceScriptStmt.cpp +++ b/llvm/tools/llvm-rc/ResourceScriptStmt.cpp @@ -118,8 +118,12 @@ raw_ostream &StringTableResource::log(raw_ostream &OS) const { OS << "StringTable:\n"; OptStatements->log(OS); - for (const auto &String : Table) - OS << " " << String.first << " => " << String.second << "\n"; + for (const auto &String : Table) { + OS << " " << String.first << " =>"; + for (const auto &S : String.second) + OS << " " << S; + OS << "\n"; + } return OS; }