[llvm-rc] Serialize user-defined resources to .res files.

This allows rc to serialize user-defined resources, as
documented at:

msdn.microsoft.com/en-us/library/windows/desktop/aa381054.aspx

Escape sequences are yet unavailable, and are to be added in one of
child patches.

Patch by: Marek Sokolowski

Differential Revision: https://reviews.llvm.org/D38423

llvm-svn: 315117
diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.cpp b/llvm/tools/llvm-rc/ResourceFileWriter.cpp
index f41ffcc..1d23fb9 100644
--- a/llvm/tools/llvm-rc/ResourceFileWriter.cpp
+++ b/llvm/tools/llvm-rc/ResourceFileWriter.cpp
@@ -298,6 +298,10 @@
   return Error::success();
 }
 
+Error ResourceFileWriter::visitUserDefinedResource(const RCResource *Res) {
+  return writeResource(Res, &ResourceFileWriter::writeUserDefinedBody);
+}
+
 Error ResourceFileWriter::visitVersionInfoResource(const RCResource *Res) {
   return writeResource(Res, &ResourceFileWriter::writeVersionInfoBody);
 }
@@ -1048,6 +1052,43 @@
   return Error::success();
 }
 
+// --- UserDefinedResource helpers. --- //
+
+Error ResourceFileWriter::writeUserDefinedBody(const RCResource *Base) {
+  auto *Res = cast<UserDefinedResource>(Base);
+
+  if (Res->IsFileResource)
+    return appendFile(Res->FileLoc);
+
+  for (auto &Elem : Res->Contents) {
+    if (Elem.isInt()) {
+      RETURN_IF_ERROR(
+          checkRCInt(Elem.getInt(), "Number in user-defined resource"));
+      writeRCInt(Elem.getInt());
+      continue;
+    }
+
+    SmallVector<UTF16, 128> ProcessedString;
+    bool IsLongString;
+    RETURN_IF_ERROR(processString(Elem.getString(),
+                                  NullHandlingMethod::UserResource,
+                                  IsLongString, ProcessedString));
+
+    for (auto Ch : ProcessedString) {
+      if (IsLongString) {
+        writeObject(ulittle16_t(Ch));
+        continue;
+      }
+
+      RETURN_IF_ERROR(checkNumberFits<uint8_t>(
+          Ch, "Character in narrow string in user-defined resoutce"));
+      writeObject(uint8_t(Ch));
+    }
+  }
+
+  return Error::success();
+}
+
 // --- VersionInfoResourceResource helpers. --- //
 
 Error ResourceFileWriter::writeVersionInfoBlock(const VersionInfoBlock &Blk) {