diff --git a/llvm/test/tools/llvm-rc/Inputs/split-path.rc b/llvm/test/tools/llvm-rc/Inputs/split-path.rc new file mode 100644 index 0000000000000..fb510e89698f7 --- /dev/null +++ b/llvm/test/tools/llvm-rc/Inputs/split-path.rc @@ -0,0 +1,2 @@ +100 ICON "subdir" "/icon-new.ico" +101 24 "subdir" "/empty.manifest" diff --git a/llvm/test/tools/llvm-rc/split-path.test b/llvm/test/tools/llvm-rc/split-path.test new file mode 100644 index 0000000000000..a12fd2bc32c11 --- /dev/null +++ b/llvm/test/tools/llvm-rc/split-path.test @@ -0,0 +1,7 @@ +; RUN: rm -rf %t +; RUN: mkdir %t +; RUN: cd %t +; RUN: mkdir subdir +; RUN: cp %p/Inputs/icon-new.ico subdir +; RUN: touch subdir/empty.manifest +; RUN: llvm-windres --no-preprocess %p/Inputs/split-path.rc %t/split-path.res diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.cpp b/llvm/tools/llvm-rc/ResourceScriptParser.cpp index 9e1047448831b..4f02fa502d24f 100644 --- a/llvm/tools/llvm-rc/ResourceScriptParser.cpp +++ b/llvm/tools/llvm-rc/ResourceScriptParser.cpp @@ -238,7 +238,24 @@ Expected RCParser::readString() { Expected RCParser::readFilename() { if (!isNextTokenKind(Kind::String) && !isNextTokenKind(Kind::Identifier)) return getExpectedError("string"); - return read().value(); + const RCToken &Token = read(); + StringRef Str = Token.value(); + if (Token.kind() != Kind::String) + return Str; + while (isNextTokenKind(Kind::String)) { + const RCToken &NextToken = read(); + StringRef Next = NextToken.value(); + bool IsWide = Str.consume_front_insensitive("L"); + Next.consume_front_insensitive("L"); + bool StrUnquoted = Str.consume_front("\"") && Str.consume_back("\""); + bool NextUnquoted = Next.consume_front("\"") && Next.consume_back("\""); + assert(StrUnquoted && NextUnquoted); + (void)StrUnquoted; + (void)NextUnquoted; + + Str = Saver.save(Twine(IsWide ? "L" : "") + "\"" + Str + Next + "\""); + } + return Str; } Expected RCParser::readIdentifier() { @@ -499,9 +516,10 @@ RCParser::ParseType RCParser::parseUserDefinedResource(IntOrString Type) { // Check if this is a file resource. switch (look().kind()) { case Kind::String: - case Kind::Identifier: - return std::make_unique(Type, read().value(), - MemoryFlags); + case Kind::Identifier: { + ASSIGN_OR_RETURN(Filename, readFilename()); + return std::make_unique(Type, *Filename, MemoryFlags); + } default: break; } diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.h b/llvm/tools/llvm-rc/ResourceScriptParser.h index 5c01cec0f151e..603afd8d73fb1 100644 --- a/llvm/tools/llvm-rc/ResourceScriptParser.h +++ b/llvm/tools/llvm-rc/ResourceScriptParser.h @@ -18,6 +18,7 @@ #include "ResourceScriptToken.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/StringSaver.h" #include "llvm/Support/raw_ostream.h" #include @@ -185,6 +186,9 @@ class RCParser { std::vector Tokens; LocIter CurLoc; const LocIter End; + + BumpPtrAllocator Alloc; + StringSaver Saver{Alloc}; }; } // namespace rc