Index: llvm/trunk/include/llvm/Support/WindowsManifestMerger.h =================================================================== --- llvm/trunk/include/llvm/Support/WindowsManifestMerger.h +++ llvm/trunk/include/llvm/Support/WindowsManifestMerger.h @@ -1,80 +0,0 @@ -//===-- WindowsManifestMerger.h ---------------------------------*- C++-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===---------------------------------------------------------------------===// -// -// This file provides a utility for merging Microsoft .manifest files. These -// files are xml documents which contain meta-information about applications, -// such as whether or not admin access is required, system compatibility, -// versions, etc. Part of the linking process of an executable may require -// merging several of these .manifest files using a tree-merge following -// specific rules. Unfortunately, these rules are not documented well -// anywhere. However, a careful investigation of the behavior of the original -// Microsoft Manifest Tool (mt.exe) revealed the rules of this merge. As the -// saying goes, code is the best documentation, so please look below if you are -// interested in the exact merging requirements. -// -// Ref: -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa374191(v=vs.85).aspx -// -//===---------------------------------------------------------------------===// - -#ifndef LLVM_INCLUDE_LLVM_SUPPORT_WINDOWS_MANIFEST_MERGER_H -#define LLVM_INCLUDE_LLVM_SUPPORT_WINDOWS_MANIFEST_MERGER_H - -#include "llvm/Config/config.h" -#include "llvm/Support/Error.h" - -#if LLVM_LIBXML2_ENABLED -#include -#endif - -namespace llvm { - -class MemoryBuffer; - -#if LLVM_LIBXML2_ENABLED -typedef xmlDocPtr XMLDocumentImpl; -typedef xmlNodePtr XMLNodeImpl; -#else -typedef void *XMLDocumentImpl; -typedef void *XMLNodeImpl; -#endif - -class WindowsManifestError : public ErrorInfo { -public: - static char ID; - WindowsManifestError(const Twine &Msg); - void log(raw_ostream &OS) const override; - -private: - std::string Msg; -}; - -class WindowsManifestMerger { -public: - ~WindowsManifestMerger(); - - Error merge(const MemoryBuffer &Manifest); - - // Returns vector containing merged xml manifest, or uninitialized vector for - // empty manifest. - std::unique_ptr getMergedManifest(); - -private: - static void errorCallback(void *Ctx, const char *Format, ...); - Error getParseError(); - -#if LLVM_LIBXML2_ENABLED - XMLDocumentImpl CombinedDoc = nullptr; - std::vector MergedDocs; -#endif - bool ParseErrorOccurred = false; -}; - -} // namespace llvm -#endif Index: llvm/trunk/include/llvm/WindowsManifest/WindowsManifestMerger.h =================================================================== --- llvm/trunk/include/llvm/WindowsManifest/WindowsManifestMerger.h +++ llvm/trunk/include/llvm/WindowsManifest/WindowsManifestMerger.h @@ -0,0 +1,80 @@ +//===-- WindowsManifestMerger.h ---------------------------------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +// +// This file provides a utility for merging Microsoft .manifest files. These +// files are xml documents which contain meta-information about applications, +// such as whether or not admin access is required, system compatibility, +// versions, etc. Part of the linking process of an executable may require +// merging several of these .manifest files using a tree-merge following +// specific rules. Unfortunately, these rules are not documented well +// anywhere. However, a careful investigation of the behavior of the original +// Microsoft Manifest Tool (mt.exe) revealed the rules of this merge. As the +// saying goes, code is the best documentation, so please look below if you are +// interested in the exact merging requirements. +// +// Ref: +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa374191(v=vs.85).aspx +// +//===---------------------------------------------------------------------===// + +#ifndef LLVM_INCLUDE_LLVM_SUPPORT_WINDOWS_MANIFEST_MERGER_H +#define LLVM_INCLUDE_LLVM_SUPPORT_WINDOWS_MANIFEST_MERGER_H + +#include "llvm/Config/config.h" +#include "llvm/Support/Error.h" + +#if LLVM_LIBXML2_ENABLED +#include +#endif + +namespace llvm { + +class MemoryBuffer; + +#if LLVM_LIBXML2_ENABLED +typedef xmlDocPtr XMLDocumentImpl; +typedef xmlNodePtr XMLNodeImpl; +#else +typedef void *XMLDocumentImpl; +typedef void *XMLNodeImpl; +#endif + +class WindowsManifestError : public ErrorInfo { +public: + static char ID; + WindowsManifestError(const Twine &Msg); + void log(raw_ostream &OS) const override; + +private: + std::string Msg; +}; + +class WindowsManifestMerger { +public: + ~WindowsManifestMerger(); + + Error merge(const MemoryBuffer &Manifest); + + // Returns vector containing merged xml manifest, or uninitialized vector for + // empty manifest. + std::unique_ptr getMergedManifest(); + +private: + static void errorCallback(void *Ctx, const char *Format, ...); + Error getParseError(); + +#if LLVM_LIBXML2_ENABLED + XMLDocumentImpl CombinedDoc = nullptr; + std::vector MergedDocs; +#endif + bool ParseErrorOccurred = false; +}; + +} // namespace llvm +#endif Index: llvm/trunk/include/llvm/module.modulemap =================================================================== --- llvm/trunk/include/llvm/module.modulemap +++ llvm/trunk/include/llvm/module.modulemap @@ -306,3 +306,9 @@ header "llvm/Support/DataTypes.h" export * } + +module LLVM_WindowsManifest { + requires cplusplus + umbrella "WindowsManifest" + module * { export * } +} Index: llvm/trunk/lib/CMakeLists.txt =================================================================== --- llvm/trunk/lib/CMakeLists.txt +++ llvm/trunk/lib/CMakeLists.txt @@ -25,3 +25,4 @@ add_subdirectory(ToolDrivers) add_subdirectory(XRay) add_subdirectory(Testing) +add_subdirectory(WindowsManifest) Index: llvm/trunk/lib/LLVMBuild.txt =================================================================== --- llvm/trunk/lib/LLVMBuild.txt +++ llvm/trunk/lib/LLVMBuild.txt @@ -42,6 +42,7 @@ Testing ToolDrivers Transforms + WindowsManifest [component_0] type = Group Index: llvm/trunk/lib/Support/CMakeLists.txt =================================================================== --- llvm/trunk/lib/Support/CMakeLists.txt +++ llvm/trunk/lib/Support/CMakeLists.txt @@ -27,9 +27,6 @@ if( UNIX AND NOT (BEOS OR HAIKU) ) set(system_libs ${system_libs} m) endif() - if( LLVM_LIBXML2_ENABLED ) - set(system_libs ${system_libs} ${LIBXML2_LIBS}) - endif() endif( MSVC OR MINGW ) add_llvm_library(LLVMSupport @@ -113,7 +110,6 @@ Triple.cpp Twine.cpp Unicode.cpp - WindowsManifestMerger.cpp YAMLParser.cpp YAMLTraits.cpp raw_os_ostream.cpp Index: llvm/trunk/lib/Support/WindowsManifestMerger.cpp =================================================================== --- llvm/trunk/lib/Support/WindowsManifestMerger.cpp +++ llvm/trunk/lib/Support/WindowsManifestMerger.cpp @@ -1,212 +0,0 @@ -//===-- WindowsManifestMerger.cpp ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===---------------------------------------------------------------------===// -// -// This file implements the .manifest merger class. -// -//===---------------------------------------------------------------------===// - -#include "llvm/Support/WindowsManifestMerger.h" -#include "llvm/Support/MemoryBuffer.h" - -#include - -#define TO_XML_CHAR(X) reinterpret_cast(X) -#define FROM_XML_CHAR(X) reinterpret_cast(X) - -using namespace llvm; - -namespace llvm { - -char WindowsManifestError::ID = 0; - -WindowsManifestError::WindowsManifestError(const Twine &Msg) : Msg(Msg.str()) {} - -void WindowsManifestError::log(raw_ostream &OS) const { OS << Msg; } - -#if LLVM_LIBXML2_ENABLED -static bool xmlStringsEqual(const unsigned char *A, const unsigned char *B) { - return strcmp(FROM_XML_CHAR(A), FROM_XML_CHAR(B)) == 0; -} -#endif - -bool isMergeableElement(const unsigned char *ElementName) { - for (StringRef S : {"application", "assembly", "assemblyIdentity", - "compatibility", "noInherit", "requestedExecutionLevel", - "requestedPrivileges", "security", "trustInfo"}) { - if (S == FROM_XML_CHAR(ElementName)) - return true; - } - return false; -} - -XMLNodeImpl getChildWithName(XMLNodeImpl Parent, - const unsigned char *ElementName) { -#if LLVM_LIBXML2_ENABLED - for (XMLNodeImpl Child = Parent->children; Child; Child = Child->next) - if (xmlStringsEqual(Child->name, ElementName)) { - return Child; - } -#endif - return nullptr; -} - -const unsigned char *getAttribute(XMLNodeImpl Node, - const unsigned char *AttributeName) { -#if LLVM_LIBXML2_ENABLED - for (xmlAttrPtr Attribute = Node->properties; Attribute != nullptr; - Attribute = Attribute->next) { - if (xmlStringsEqual(Attribute->name, AttributeName)) - return Attribute->children->content; - } -#endif - return nullptr; -} - -Error mergeAttributes(XMLNodeImpl OriginalNode, XMLNodeImpl AdditionalNode) { -#if LLVM_LIBXML2_ENABLED - for (xmlAttrPtr Attribute = AdditionalNode->properties; Attribute != nullptr; - Attribute = Attribute->next) { - if (const unsigned char *OriginalValue = - getAttribute(OriginalNode, Attribute->name)) { - // Attributes of the same name must also have the same value. Otherwise - // an error is thrown. - if (!xmlStringsEqual(OriginalValue, Attribute->children->content)) - return make_error( - Twine("conflicting attributes for ") + - FROM_XML_CHAR(OriginalNode->name)); - } else { - char *NameCopy = strdup(FROM_XML_CHAR(Attribute->name)); - char *ContentCopy = strdup(FROM_XML_CHAR(Attribute->children->content)); - xmlNewProp(OriginalNode, TO_XML_CHAR(NameCopy), TO_XML_CHAR(ContentCopy)); - } - } -#endif - return Error::success(); -} - -Error treeMerge(XMLNodeImpl OriginalRoot, XMLNodeImpl AdditionalRoot) { -#if LLVM_LIBXML2_ENABLED - XMLNodeImpl AdditionalFirstChild = AdditionalRoot->children; - for (XMLNodeImpl Child = AdditionalFirstChild; Child; Child = Child->next) { - XMLNodeImpl OriginalChildWithName; - if (!isMergeableElement(Child->name) || - !(OriginalChildWithName = - getChildWithName(OriginalRoot, Child->name))) { - XMLNodeImpl NewChild = xmlCopyNode(Child, 1); - if (!NewChild) - return make_error(Twine("error when copying ") + - FROM_XML_CHAR(Child->name)); - if (NewChild->ns) - xmlFreeNs(NewChild->ns); // xmlCopyNode explicitly defines default - // namespace, undo this here. - if (!xmlAddChild(OriginalRoot, NewChild)) - return make_error(Twine("could not merge ") + - FROM_XML_CHAR(NewChild->name)); - } else if (auto E = treeMerge(OriginalChildWithName, Child)) { - return E; - } - } - if (auto E = mergeAttributes(OriginalRoot, AdditionalRoot)) - return E; -#endif - return Error::success(); -} - -void stripCommentsAndText(XMLNodeImpl Root) { -#if LLVM_LIBXML2_ENABLED - xmlNode StoreNext; - for (XMLNodeImpl Child = Root->children; Child; Child = Child->next) { - if (!xmlStringsEqual(Child->name, TO_XML_CHAR("text")) && - !xmlStringsEqual(Child->name, TO_XML_CHAR("comment"))) { - stripCommentsAndText(Child); - } else { - StoreNext.next = Child->next; - XMLNodeImpl Remove = Child; - Child = &StoreNext; - xmlUnlinkNode(Remove); - xmlFreeNode(Remove); - } - } -#endif -} - -WindowsManifestMerger::~WindowsManifestMerger() { -#if LLVM_LIBXML2_ENABLED - for (auto &Doc : MergedDocs) - xmlFreeDoc(Doc); -#endif -} - -Error WindowsManifestMerger::merge(const MemoryBuffer &Manifest) { -#if LLVM_LIBXML2_ENABLED - if (Manifest.getBufferSize() == 0) - return make_error( - "attempted to merge empty manifest"); - xmlSetGenericErrorFunc((void *)this, WindowsManifestMerger::errorCallback); - XMLDocumentImpl ManifestXML = - xmlReadMemory(Manifest.getBufferStart(), Manifest.getBufferSize(), - "manifest.xml", nullptr, XML_PARSE_NOBLANKS); - xmlSetGenericErrorFunc(nullptr, nullptr); - if (auto E = getParseError()) - return E; - XMLNodeImpl AdditionalRoot = xmlDocGetRootElement(ManifestXML); - stripCommentsAndText(AdditionalRoot); - if (CombinedDoc == nullptr) { - CombinedDoc = ManifestXML; - } else { - XMLNodeImpl CombinedRoot = xmlDocGetRootElement(CombinedDoc); - if (xmlStringsEqual(CombinedRoot->name, AdditionalRoot->name) && - isMergeableElement(AdditionalRoot->name)) { - if (auto E = treeMerge(CombinedRoot, AdditionalRoot)) { - return E; - } - } else { - XMLNodeImpl NewChild = xmlCopyNode(AdditionalRoot, 1); - if (!NewChild) - return make_error("could not copy manifest"); - if (!xmlAddChild(CombinedRoot, NewChild)) - return make_error("could not append manifest"); - } - } - MergedDocs.push_back(ManifestXML); -#endif - return Error::success(); -} - -std::unique_ptr WindowsManifestMerger::getMergedManifest() { -#if LLVM_LIBXML2_ENABLED - unsigned char *XmlBuff; - int BufferSize = 0; - if (CombinedDoc) { - std::unique_ptr OutputDoc(xmlNewDoc((const unsigned char *)"1.0")); - xmlDocSetRootElement(OutputDoc.get(), xmlDocGetRootElement(CombinedDoc)); - xmlKeepBlanksDefault(0); - xmlDocDumpFormatMemory(OutputDoc.get(), &XmlBuff, &BufferSize, 1); - } - if (BufferSize == 0) - return nullptr; - return MemoryBuffer::getMemBuffer( - StringRef(FROM_XML_CHAR(XmlBuff), (size_t)BufferSize)); -#else - return nullptr; -#endif -} - -void WindowsManifestMerger::errorCallback(void *Ctx, const char *Format, ...) { - auto *Merger = (WindowsManifestMerger *)Ctx; - Merger->ParseErrorOccurred = true; -} - -Error WindowsManifestMerger::getParseError() { - if (!ParseErrorOccurred) - return Error::success(); - return make_error("invalid xml document"); -} - -} // namespace llvm Index: llvm/trunk/lib/WindowsManifest/CMakeLists.txt =================================================================== --- llvm/trunk/lib/WindowsManifest/CMakeLists.txt +++ llvm/trunk/lib/WindowsManifest/CMakeLists.txt @@ -0,0 +1,18 @@ +set(system_libs) +if( CMAKE_HOST_UNIX ) + if( LLVM_LIBXML2_ENABLED ) + set(system_libs ${system_libs} ${LIBXML2_LIBS}) + endif() +endif() + +add_llvm_library(LLVMWindowsManifest + WindowsManifestMerger.cpp + + ADDITIONAL_HEADER_DIRS + ${LLVM_MAIN_INCLUDE_DIR}/llvm/WindowsManifest + ${Backtrace_INCLUDE_DIRS} + + LINK_LIBS ${system_libs} + ) + +set_property(TARGET LLVMWindowsManifest PROPERTY LLVM_SYSTEM_LIBS "${system_libs}") Index: llvm/trunk/lib/WindowsManifest/LLVMBuild.txt =================================================================== --- llvm/trunk/lib/WindowsManifest/LLVMBuild.txt +++ llvm/trunk/lib/WindowsManifest/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./lib/WindowsManifest/LLVMBuild.txt ----------------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = WindowsManifest +parent = Libraries +required_libraries = Support Index: llvm/trunk/lib/WindowsManifest/WindowsManifestMerger.cpp =================================================================== --- llvm/trunk/lib/WindowsManifest/WindowsManifestMerger.cpp +++ llvm/trunk/lib/WindowsManifest/WindowsManifestMerger.cpp @@ -0,0 +1,212 @@ +//===-- WindowsManifestMerger.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +// +// This file implements the .manifest merger class. +// +//===---------------------------------------------------------------------===// + +#include "llvm/WindowsManifest/WindowsManifestMerger.h" +#include "llvm/Support/MemoryBuffer.h" + +#include + +#define TO_XML_CHAR(X) reinterpret_cast(X) +#define FROM_XML_CHAR(X) reinterpret_cast(X) + +using namespace llvm; + +namespace llvm { + +char WindowsManifestError::ID = 0; + +WindowsManifestError::WindowsManifestError(const Twine &Msg) : Msg(Msg.str()) {} + +void WindowsManifestError::log(raw_ostream &OS) const { OS << Msg; } + +#if LLVM_LIBXML2_ENABLED +static bool xmlStringsEqual(const unsigned char *A, const unsigned char *B) { + return strcmp(FROM_XML_CHAR(A), FROM_XML_CHAR(B)) == 0; +} +#endif + +bool isMergeableElement(const unsigned char *ElementName) { + for (StringRef S : {"application", "assembly", "assemblyIdentity", + "compatibility", "noInherit", "requestedExecutionLevel", + "requestedPrivileges", "security", "trustInfo"}) { + if (S == FROM_XML_CHAR(ElementName)) + return true; + } + return false; +} + +XMLNodeImpl getChildWithName(XMLNodeImpl Parent, + const unsigned char *ElementName) { +#if LLVM_LIBXML2_ENABLED + for (XMLNodeImpl Child = Parent->children; Child; Child = Child->next) + if (xmlStringsEqual(Child->name, ElementName)) { + return Child; + } +#endif + return nullptr; +} + +const unsigned char *getAttribute(XMLNodeImpl Node, + const unsigned char *AttributeName) { +#if LLVM_LIBXML2_ENABLED + for (xmlAttrPtr Attribute = Node->properties; Attribute != nullptr; + Attribute = Attribute->next) { + if (xmlStringsEqual(Attribute->name, AttributeName)) + return Attribute->children->content; + } +#endif + return nullptr; +} + +Error mergeAttributes(XMLNodeImpl OriginalNode, XMLNodeImpl AdditionalNode) { +#if LLVM_LIBXML2_ENABLED + for (xmlAttrPtr Attribute = AdditionalNode->properties; Attribute != nullptr; + Attribute = Attribute->next) { + if (const unsigned char *OriginalValue = + getAttribute(OriginalNode, Attribute->name)) { + // Attributes of the same name must also have the same value. Otherwise + // an error is thrown. + if (!xmlStringsEqual(OriginalValue, Attribute->children->content)) + return make_error( + Twine("conflicting attributes for ") + + FROM_XML_CHAR(OriginalNode->name)); + } else { + char *NameCopy = strdup(FROM_XML_CHAR(Attribute->name)); + char *ContentCopy = strdup(FROM_XML_CHAR(Attribute->children->content)); + xmlNewProp(OriginalNode, TO_XML_CHAR(NameCopy), TO_XML_CHAR(ContentCopy)); + } + } +#endif + return Error::success(); +} + +Error treeMerge(XMLNodeImpl OriginalRoot, XMLNodeImpl AdditionalRoot) { +#if LLVM_LIBXML2_ENABLED + XMLNodeImpl AdditionalFirstChild = AdditionalRoot->children; + for (XMLNodeImpl Child = AdditionalFirstChild; Child; Child = Child->next) { + XMLNodeImpl OriginalChildWithName; + if (!isMergeableElement(Child->name) || + !(OriginalChildWithName = + getChildWithName(OriginalRoot, Child->name))) { + XMLNodeImpl NewChild = xmlCopyNode(Child, 1); + if (!NewChild) + return make_error(Twine("error when copying ") + + FROM_XML_CHAR(Child->name)); + if (NewChild->ns) + xmlFreeNs(NewChild->ns); // xmlCopyNode explicitly defines default + // namespace, undo this here. + if (!xmlAddChild(OriginalRoot, NewChild)) + return make_error(Twine("could not merge ") + + FROM_XML_CHAR(NewChild->name)); + } else if (auto E = treeMerge(OriginalChildWithName, Child)) { + return E; + } + } + if (auto E = mergeAttributes(OriginalRoot, AdditionalRoot)) + return E; +#endif + return Error::success(); +} + +void stripCommentsAndText(XMLNodeImpl Root) { +#if LLVM_LIBXML2_ENABLED + xmlNode StoreNext; + for (XMLNodeImpl Child = Root->children; Child; Child = Child->next) { + if (!xmlStringsEqual(Child->name, TO_XML_CHAR("text")) && + !xmlStringsEqual(Child->name, TO_XML_CHAR("comment"))) { + stripCommentsAndText(Child); + } else { + StoreNext.next = Child->next; + XMLNodeImpl Remove = Child; + Child = &StoreNext; + xmlUnlinkNode(Remove); + xmlFreeNode(Remove); + } + } +#endif +} + +WindowsManifestMerger::~WindowsManifestMerger() { +#if LLVM_LIBXML2_ENABLED + for (auto &Doc : MergedDocs) + xmlFreeDoc(Doc); +#endif +} + +Error WindowsManifestMerger::merge(const MemoryBuffer &Manifest) { +#if LLVM_LIBXML2_ENABLED + if (Manifest.getBufferSize() == 0) + return make_error( + "attempted to merge empty manifest"); + xmlSetGenericErrorFunc((void *)this, WindowsManifestMerger::errorCallback); + XMLDocumentImpl ManifestXML = + xmlReadMemory(Manifest.getBufferStart(), Manifest.getBufferSize(), + "manifest.xml", nullptr, XML_PARSE_NOBLANKS); + xmlSetGenericErrorFunc(nullptr, nullptr); + if (auto E = getParseError()) + return E; + XMLNodeImpl AdditionalRoot = xmlDocGetRootElement(ManifestXML); + stripCommentsAndText(AdditionalRoot); + if (CombinedDoc == nullptr) { + CombinedDoc = ManifestXML; + } else { + XMLNodeImpl CombinedRoot = xmlDocGetRootElement(CombinedDoc); + if (xmlStringsEqual(CombinedRoot->name, AdditionalRoot->name) && + isMergeableElement(AdditionalRoot->name)) { + if (auto E = treeMerge(CombinedRoot, AdditionalRoot)) { + return E; + } + } else { + XMLNodeImpl NewChild = xmlCopyNode(AdditionalRoot, 1); + if (!NewChild) + return make_error("could not copy manifest"); + if (!xmlAddChild(CombinedRoot, NewChild)) + return make_error("could not append manifest"); + } + } + MergedDocs.push_back(ManifestXML); +#endif + return Error::success(); +} + +std::unique_ptr WindowsManifestMerger::getMergedManifest() { +#if LLVM_LIBXML2_ENABLED + unsigned char *XmlBuff; + int BufferSize = 0; + if (CombinedDoc) { + std::unique_ptr OutputDoc(xmlNewDoc((const unsigned char *)"1.0")); + xmlDocSetRootElement(OutputDoc.get(), xmlDocGetRootElement(CombinedDoc)); + xmlKeepBlanksDefault(0); + xmlDocDumpFormatMemory(OutputDoc.get(), &XmlBuff, &BufferSize, 1); + } + if (BufferSize == 0) + return nullptr; + return MemoryBuffer::getMemBuffer( + StringRef(FROM_XML_CHAR(XmlBuff), (size_t)BufferSize)); +#else + return nullptr; +#endif +} + +void WindowsManifestMerger::errorCallback(void *Ctx, const char *Format, ...) { + auto *Merger = (WindowsManifestMerger *)Ctx; + Merger->ParseErrorOccurred = true; +} + +Error WindowsManifestMerger::getParseError() { + if (!ParseErrorOccurred) + return Error::success(); + return make_error("invalid xml document"); +} + +} // namespace llvm Index: llvm/trunk/tools/llvm-mt/CMakeLists.txt =================================================================== --- llvm/trunk/tools/llvm-mt/CMakeLists.txt +++ llvm/trunk/tools/llvm-mt/CMakeLists.txt @@ -1,6 +1,7 @@ set(LLVM_LINK_COMPONENTS Option Support + WindowsManifest ) set(LLVM_TARGET_DEFINITIONS Opts.td) Index: llvm/trunk/tools/llvm-mt/LLVMBuild.txt =================================================================== --- llvm/trunk/tools/llvm-mt/LLVMBuild.txt +++ llvm/trunk/tools/llvm-mt/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = llvm-mt parent = Tools -required_libraries = Option Support +required_libraries = Option Support WindowsManifest Index: llvm/trunk/tools/llvm-mt/llvm-mt.cpp =================================================================== --- llvm/trunk/tools/llvm-mt/llvm-mt.cpp +++ llvm/trunk/tools/llvm-mt/llvm-mt.cpp @@ -22,8 +22,8 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" -#include "llvm/Support/WindowsManifestMerger.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/WindowsManifest/WindowsManifestMerger.h" #include