Update MCLinker to work with LLVM 3.4.
This corresponds to merging upstream MCLinker with the following SHA:
6dcbf36cdb146d6f175ba2f18a9004753cafeaff
Change-Id: I1bc8c2ce4accc563450bc71ee295a6e47a0c0469
diff --git a/include/mcld/Support/CommandLine.h b/include/mcld/Support/CommandLine.h
index 00907fe..6cb0fae 100644
--- a/include/mcld/Support/CommandLine.h
+++ b/include/mcld/Support/CommandLine.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_COMMANDLINE_H
-#define MCLD_COMMANDLINE_H
+#ifndef MCLD_SUPPORT_COMMANDLINE_H
+#define MCLD_SUPPORT_COMMANDLINE_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/DefSymParser.h b/include/mcld/Support/DefSymParser.h
deleted file mode 100644
index a721b48..0000000
--- a/include/mcld/Support/DefSymParser.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===- DefSymParser.h -----------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_DEFSYM_PARSER_H
-#define MCLD_DEFSYM_PARSER_H
-
-#include <mcld/Module.h>
-#include <llvm/ADT/StringRef.h>
-
-namespace mcld {
-
-/** \class DefSymParser
- * \brief DefSymParser parses --defsym option.
- */
-class DefSymParser
-{
-public:
- DefSymParser(const Module& pModule);
-
- // parse a valid expression and set the value in the second parameter
- bool parse(llvm::StringRef, uint64_t&);
-
-private:
- const Module& m_Module;
-};
-
-} // mcld
-
-#endif
diff --git a/include/mcld/Support/Directory.h b/include/mcld/Support/Directory.h
index 66ba118..2bf8f06 100644
--- a/include/mcld/Support/Directory.h
+++ b/include/mcld/Support/Directory.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_DIRECTORY_H
-#define MCLD_DIRECTORY_H
+#ifndef MCLD_SUPPORT_DIRECTORY_H
+#define MCLD_SUPPORT_DIRECTORY_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/FileHandle.h b/include/mcld/Support/FileHandle.h
index f9fe73a..9f551b9 100644
--- a/include/mcld/Support/FileHandle.h
+++ b/include/mcld/Support/FileHandle.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_FILE_HANDLE_H
-#define MCLD_FILE_HANDLE_H
+#ifndef MCLD_SUPPORT_FILEHANDLE_H
+#define MCLD_SUPPORT_FILEHANDLE_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/FileOutputBuffer.h b/include/mcld/Support/FileOutputBuffer.h
new file mode 100644
index 0000000..a49ffb7
--- /dev/null
+++ b/include/mcld/Support/FileOutputBuffer.h
@@ -0,0 +1,72 @@
+//===- FileOutputBuffer.h -------------------------------------------------===//
+//
+// the mclinker project
+//
+// this file is distributed under the university of illinois open source
+// license. see license.txt for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SUPPORT_FILEOUTPUTBUFFER_H
+#define MCLD_SUPPORT_FILEOUTPUTBUFFER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Support/MemoryRegion.h>
+#include <llvm/ADT/OwningPtr.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/DataTypes.h>
+#include <llvm/Support/FileSystem.h>
+#include <llvm/Support/system_error.h>
+
+namespace mcld {
+
+class FileHandle;
+
+/// FileOutputBuffer - This interface is borrowed from llvm bassically, and we
+/// may use ostream to emit output later.
+class FileOutputBuffer {
+public:
+ /// Factory method to create an OutputBuffer object which manages a read/write
+ /// buffer of the specified size. When committed, the buffer will be written
+ /// to the file at the specified path.
+ static llvm::error_code create(FileHandle& pFileHandle,
+ size_t pSize,
+ llvm::OwningPtr<FileOutputBuffer>& pResult);
+
+ /// Returns a pointer to the start of the buffer.
+ uint8_t* getBufferStart() {
+ return (uint8_t*)m_pRegion->data();
+ }
+
+ /// Returns a pointer to the end of the buffer.
+ uint8_t* getBufferEnd() {
+ return (uint8_t*)m_pRegion->data() + m_pRegion->size();
+ }
+
+ /// Returns size of the buffer.
+ size_t getBufferSize() const {
+ return m_pRegion->size();
+ }
+
+ MemoryRegion request(size_t pOffset, size_t pLength);
+
+ /// Returns path where file will show up if buffer is committed.
+ llvm::StringRef getPath() const;
+
+ ~FileOutputBuffer();
+
+private:
+ FileOutputBuffer(const FileOutputBuffer &);
+ FileOutputBuffer &operator=(const FileOutputBuffer &);
+
+ FileOutputBuffer(llvm::sys::fs::mapped_file_region* pRegion,
+ FileHandle& pFileHandle);
+
+ llvm::OwningPtr<llvm::sys::fs::mapped_file_region> m_pRegion;
+ FileHandle& m_FileHandle;
+};
+
+} // namespace mcld
+
+#endif
diff --git a/include/mcld/Support/FileSystem.h b/include/mcld/Support/FileSystem.h
index 927346e..e0dddd7 100644
--- a/include/mcld/Support/FileSystem.h
+++ b/include/mcld/Support/FileSystem.h
@@ -11,8 +11,8 @@
// path class.
//===----------------------------------------------------------------------===//
-#ifndef MCLD_FILE_SYSTEM_H
-#define MCLD_FILE_SYSTEM_H
+#ifndef MCLD_SUPPORT_FILESYSTEM_H
+#define MCLD_SUPPORT_FILESYSTEM_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/GCFactory.h b/include/mcld/Support/GCFactory.h
index 6679f41..9ae8650 100644
--- a/include/mcld/Support/GCFactory.h
+++ b/include/mcld/Support/GCFactory.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_GC_FACTORY_H
-#define MCLD_GC_FACTORY_H
+#ifndef MCLD_SUPPORT_GCFACTORY_H
+#define MCLD_SUPPORT_GCFACTORY_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/GCFactoryListTraits.h b/include/mcld/Support/GCFactoryListTraits.h
index 986f6f6..b7d44d3 100644
--- a/include/mcld/Support/GCFactoryListTraits.h
+++ b/include/mcld/Support/GCFactoryListTraits.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_GC_FACTORY_LIST_TRAITS_H
-#define MCLD_GC_FACTORY_LIST_TRAITS_H
+#ifndef MCLD_SUPPORT_GCFACTORYLISTTRAITS_H
+#define MCLD_SUPPORT_GCFACTORYLISTTRAITS_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/HandleToArea.h b/include/mcld/Support/HandleToArea.h
deleted file mode 100644
index 8c24db7..0000000
--- a/include/mcld/Support/HandleToArea.h
+++ /dev/null
@@ -1,118 +0,0 @@
-//===- HandleToArea.h -----------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_FILE_HANDLE_TO_MEMORY_AREA_H
-#define MCLD_FILE_HANDLE_TO_MEMORY_AREA_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-#include <mcld/ADT/Uncopyable.h>
-#include <mcld/ADT/TypeTraits.h>
-#include <mcld/ADT/StringHash.h>
-#include <mcld/Support/Path.h>
-#include <mcld/Support/FileHandle.h>
-#include <vector>
-
-namespace mcld {
-
-class MemoryArea;
-
-/** \class HandleToArea
- *
- * Special double-key associative container. Keys are Path and file handler,
- * associative value is MemoryArea.
- *
- * For high performance, HandleToArea is not designed to contain unique
- * <key, value> pair. The key and value may be duplicated.
- *
- * Like FileHandle, HandleToArea should neither throw exception nor call
- * expressive diagnostic.
- */
-class HandleToArea : private Uncopyable
-{
-private:
- struct Bucket {
- unsigned int hash_value;
- FileHandle* handle;
- MemoryArea* area;
- };
-
- // the best data structure is a binary search tree.
- // However, by the shrinking time-to-market constraint, I used
- // vector and sequential search here.
- typedef std::vector<Bucket> HandleToAreaMap;
-
- typedef hash::StringHash<hash::BKDR> HashFunction;
-
-public:
- typedef HandleToAreaMap::iterator iterator;
- typedef HandleToAreaMap::const_iterator const_iterator;
-
-public:
- struct Result {
- public:
- Result(FileHandle* pHandle, MemoryArea* pArea)
- : handle(pHandle), area(pArea) { }
-
- public:
- FileHandle* handle;
- MemoryArea* area;
- };
-
- struct ConstResult {
- public:
- ConstResult(const FileHandle* pHandle, const MemoryArea* pArea)
- : handle(pHandle), area(pArea) { }
-
- public:
- const FileHandle* handle;
- const MemoryArea* area;
- };
-
-public:
- bool push_back(FileHandle* pHandle, MemoryArea* pArea);
-
- bool erase(MemoryArea* pArea);
-
- bool erase(const sys::fs::Path& pPath);
-
- Result findFirst(const sys::fs::Path& pPath);
-
- ConstResult findFirst(const sys::fs::Path& pPath) const;
-
- iterator begin()
- { return m_AreaMap.begin(); }
-
- iterator end()
- { return m_AreaMap.end(); }
-
- const_iterator begin() const
- { return m_AreaMap.begin(); }
-
- const_iterator end() const
- { return m_AreaMap.end(); }
-
- // ----- capacity ----- //
- bool empty() const
- { return m_AreaMap.empty(); }
-
- size_t size() const
- { return m_AreaMap.size(); }
-
- HandleToArea() : m_AreaMap() { }
-
- ~HandleToArea() { }
-
-private:
- HandleToAreaMap m_AreaMap;
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Support/LEB128.h b/include/mcld/Support/LEB128.h
index 816ed72..e44966a 100644
--- a/include/mcld/Support/LEB128.h
+++ b/include/mcld/Support/LEB128.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_LEB128_H
-#define MCLD_LEB128_H
+#ifndef MCLD_SUPPORT_LEB128_H
+#define MCLD_SUPPORT_LEB128_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/MemoryArea.h b/include/mcld/Support/MemoryArea.h
index d3ae9b7..18ea985 100644
--- a/include/mcld/Support/MemoryArea.h
+++ b/include/mcld/Support/MemoryArea.h
@@ -6,43 +6,22 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_SUPPORT_MEMORY_AREA_H
-#define MCLD_SUPPORT_MEMORY_AREA_H
+#ifndef MCLD_SUPPORT_MEMORYAREA_H
+#define MCLD_SUPPORT_MEMORYAREA_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
#include <mcld/ADT/Uncopyable.h>
-#include <cstddef>
-#include <map>
-#if defined(ENABLE_UNITTEST)
-namespace mcldtest {
- class MemoryAreaTest;
-} // namespace of mcldtest
-#endif
+#include <llvm/ADT/OwningPtr.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/MemoryBuffer.h>
namespace mcld {
-class Space;
-class FileHandle;
-class MemoryRegion;
-
/** \class MemoryArea
- * \brief MemoryArea is used to manage distinct MemoryRegions of address space.
- *
- * Good linkers must well manipulate memory mapped I/O and dynamic memory.
- * In MCLinker, MemoryArea is the decision-maker to use memory mapped I/O or
- * dynamic memory. When a client requests MemoryArea for a piece of memory
- * to hold a part of a file, MemoryArea is going to see whether the requested
- * part of the file is already in any existing memory which is requested
- * before. If it is, MemoryArea creates a new MemoryRegion within the memory
- * requested before. Otherwise, MemoryArea uses memory mapped I/O or dynamic
- * memory to load the file.
- *
- * If the part a file being loaded is larger than 3/4 pages, MemoryArea uses
- * memory mapped I/O to load the file. Otherwise, MemoryArea uses dynamic
- * memory to read the content of file into the memory space.
+ * \brief MemoryArea is used to manage input read-only memory space.
*/
class MemoryArea : private Uncopyable
{
@@ -52,72 +31,22 @@
// If the given file handler is read-only, client can not request a region
// that out of the file size.
// @param pFileHandle - file handler
- explicit MemoryArea(FileHandle& pFileHandle);
+ explicit MemoryArea(llvm::StringRef pFilename);
- // constructor by set universal space.
- // Client can not request a region that out of the universal space.
- // @param pUniverse - file handler
- explicit MemoryArea(Space& pUniverse);
-
- // destructor
- ~MemoryArea();
+ explicit MemoryArea(const char* pMemBuffer, size_t pSize);
// request - create a MemoryRegion within a sufficient space
// find an existing space to hold the MemoryRegion.
// if MemoryArea does not find such space, then it creates a new space and
// assign a MemoryRegion into the space.
- MemoryRegion* request(size_t pOffset, size_t pLength);
+ llvm::StringRef request(size_t pOffset, size_t pLength);
- // release - release a MemoryRegion.
- // release a MemoryRegion does not cause
- void release(MemoryRegion* pRegion);
-
- // clear - release all memory regions.
- void clear();
-
- const FileHandle* handler() const { return m_pFileHandle; }
- FileHandle* handler() { return m_pFileHandle; }
-
- bool hasHandler() const { return (NULL != m_pFileHandle); }
-
- // ----- space list methods ----- //
- Space* find(size_t pOffset, size_t pLength);
-
- const Space* find(size_t pOffset, size_t pLength) const;
+ size_t size() const;
private:
- class Key {
- public:
- Key(size_t pOffset, size_t pLength)
- : m_Offset(pOffset), m_Length(pLength)
- { }
-
- size_t offset() const { return m_Offset; }
-
- size_t length() const { return m_Length; }
-
- struct Compare {
- bool operator()(const Key& KEY1, const Key& KEY2) const
- {
- return KEY1.offset() + KEY1.length() < KEY2.offset() ||
- (KEY1.offset() < KEY2.offset() &&
- (KEY1.offset() + KEY1.length() < KEY2.offset() + KEY2.length()));
- }
- };
-
- private:
- size_t m_Offset;
- size_t m_Length;
- };
-
- typedef std::multimap<Key, Space*, Key::Compare> SpaceMapType;
-
-private:
- SpaceMapType m_SpaceMap;
- FileHandle* m_pFileHandle;
+ llvm::OwningPtr<llvm::MemoryBuffer> m_pMemoryBuffer;
};
} // namespace of mcld
#endif
-
diff --git a/include/mcld/Support/MemoryAreaFactory.h b/include/mcld/Support/MemoryAreaFactory.h
index b28f096..302fbd1 100644
--- a/include/mcld/Support/MemoryAreaFactory.h
+++ b/include/mcld/Support/MemoryAreaFactory.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_SUPPORT_MEMORY_AREA_FACTORY_H
-#define MCLD_SUPPORT_MEMORY_AREA_FACTORY_H
+#ifndef MCLD_SUPPORT_MEMORYAREAFACTORY_H
+#define MCLD_SUPPORT_MEMORYAREAFACTORY_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
@@ -15,7 +15,7 @@
#include <mcld/Support/MemoryArea.h>
#include <mcld/Support/Path.h>
#include <mcld/Support/FileHandle.h>
-#include <mcld/Support/HandleToArea.h>
+#include <llvm/ADT/StringMap.h>
namespace mcld
{
@@ -63,12 +63,10 @@
MemoryArea* produce(int pFD, FileHandle::OpenMode pMode);
void destruct(MemoryArea* pArea);
-
private:
- HandleToArea m_HandleToArea;
+ llvm::StringMap<MemoryArea*> m_AreaMap;
};
} // namespace of mcld
#endif
-
diff --git a/include/mcld/Support/MemoryRegion.h b/include/mcld/Support/MemoryRegion.h
index 0984873..0d18f59 100644
--- a/include/mcld/Support/MemoryRegion.h
+++ b/include/mcld/Support/MemoryRegion.h
@@ -6,112 +6,24 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef LD_MEMORY_REGION_H
-#define LD_MEMORY_REGION_H
+#ifndef MCLD_SUPPORT_MEMORYREGION_H
+#define MCLD_SUPPORT_MEMORYREGION_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
-#include <mcld/Config/Config.h>
-#include <mcld/ADT/Uncopyable.h>
-#include <mcld/Support/Allocators.h>
-#include <mcld/Support/Space.h>
+#include <mcld/ADT/TypeTraits.h>
+#include <llvm/ADT/ArrayRef.h>
+#include <llvm/Support/DataTypes.h>
namespace mcld {
-class MemoryArea;
+typedef NonConstTraits<uint8_t>::pointer Address;
+typedef ConstTraits<uint8_t>::pointer ConstAddress;
-/** \class MemoryRegion
- * \brief MemoryRegion is a range of virtual memory which is mapped onto a
- * range of files which is opened by MemoryArea.
- *
- * MemoryArea maps a file onto virtual memory. Clients can get a range of
- * mapped memory space by requesting a MemoryRegion from MemoryArea, and
- * read/write the mapped file through the MemoryRegion.
- *
- * When two different MemoryRegion may overlap memory space, race condition
- * may occurs. Clients must call MemoryRegion::sync() explicit to tell the
- * MemoryArea when to synchronize the virtual memory space with the mapped
- * file.
- */
-class MemoryRegion : private Uncopyable
-{
-friend class Chunk<MemoryRegion, MCLD_REGION_CHUNK_SIZE>;
-friend class RegionFactory;
-friend class MemoryArea;
+typedef llvm::ArrayRef<uint8_t> ConstMemoryRegion;
+typedef llvm::MutableArrayRef<uint8_t> MemoryRegion;
-public:
- typedef Space::Address Address;
- typedef Space::ConstAddress ConstAddress;
-
-private:
- MemoryRegion();
-
- MemoryRegion(const Address pVMAStart, size_t pSize);
-
- ~MemoryRegion();
-
- void setParent(Space& pSpace) { m_pParent = &pSpace; }
-
-public:
- /// Create - To wrap a piece of memory and to create a new region.
- /// This function wraps a piece of memory and to create a new region. Region
- /// is just a wraper, it is not responsible for deallocate the given memory.
- ///
- /// @param pStart [in] The start address of a piece of memory
- /// @param pSize [in] The size of the given memory
- static MemoryRegion* Create(void* pStart, size_t pSize);
-
- /// Create - To wrap a piece of memory and to create a new region.
- /// This function wraps a piece of memory and to create a new region. Region
- /// is just a wraper, it is not responsible for deallocate the given memory.
- ///
- /// If a wrapped memory comes from a Space, then we say the space is the
- /// parent of the region. pSpace is a memory counting container. It remembers
- /// the number of regions in it. A space which has no region will be removed
- /// quickly.
- ///
- /// The wrapped memory will be deallocated by Space when the space has no
- /// region used it.
- ///
- /// @param pStart [in] The start address of a piece of memory
- /// @param pSize [in] The size of the given memory
- /// @param pSpace [in] The parent space.
- static MemoryRegion* Create(void* pStart, size_t pSize, Space& pSpace);
-
- /// Destroy - To destroy the region
- /// If the region has a parent space, it will be also remove from the space.
- ///
- /// @param pRegion [in, out] pRegion is set to NULL if the destruction is
- /// success.
- static void Destroy(MemoryRegion*& pRegion);
-
- const Space* parent() const { return m_pParent; }
- Space* parent() { return m_pParent; }
-
- bool hasParent() const { return (NULL != m_pParent); }
-
- ConstAddress start() const { return m_VMAStart; }
- Address start() { return m_VMAStart; }
-
- ConstAddress end() const { return m_VMAStart+m_Length; }
- Address end() { return m_VMAStart+m_Length; }
-
- size_t size() const { return m_Length; }
-
- ConstAddress getBuffer(size_t pOffset = 0) const
- { return m_VMAStart+pOffset; }
-
- Address getBuffer(size_t pOffset = 0)
- { return m_VMAStart+pOffset; }
-
-private:
- Space* m_pParent;
- Address m_VMAStart;
- size_t m_Length;
-};
-
-} // namespace of mcld
+} // namespace mcld
#endif
-
diff --git a/include/mcld/Support/MsgHandling.h b/include/mcld/Support/MsgHandling.h
index d00132c..778ec68 100644
--- a/include/mcld/Support/MsgHandling.h
+++ b/include/mcld/Support/MsgHandling.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_MESSAGE_HANDLING_H
-#define MCLD_MESSAGE_HANDLING_H
+#ifndef MCLD_SUPPORT_MSGHANDLING_H
+#define MCLD_SUPPORT_MSGHANDLING_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/Path.h b/include/mcld/Support/Path.h
index 13e8ddb..fe7914e 100644
--- a/include/mcld/Support/Path.h
+++ b/include/mcld/Support/Path.h
@@ -10,8 +10,8 @@
// filesystem (v3), but modified to remove exception handling and the
// path class.
//===----------------------------------------------------------------------===//
-#ifndef MCLD_PATH_H
-#define MCLD_PATH_H
+#ifndef MCLD_SUPPORT_PATH_H
+#define MCLD_SUPPORT_PATH_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/PathCache.h b/include/mcld/Support/PathCache.h
index 50c6984..37857dc 100644
--- a/include/mcld/Support/PathCache.h
+++ b/include/mcld/Support/PathCache.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_PATHCACHE_H
-#define MCLD_PATHCACHE_H
+#ifndef MCLD_SUPPORT_PATHCACHE_H
+#define MCLD_SUPPORT_PATHCACHE_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/RealPath.h b/include/mcld/Support/RealPath.h
index 6c0cd40..0369f25 100644
--- a/include/mcld/Support/RealPath.h
+++ b/include/mcld/Support/RealPath.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_REAL_PATH_H
-#define MCLD_REAL_PATH_H
+#ifndef MCLD_SUPPORT_REALPATH_H
+#define MCLD_SUPPORT_REALPATH_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/RegionFactory.h b/include/mcld/Support/RegionFactory.h
deleted file mode 100644
index fd90186..0000000
--- a/include/mcld/Support/RegionFactory.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===- RegionFactory.h ----------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_SUPPORT_REGION_FACTORY_H
-#define MCLD_SUPPORT_REGION_FACTORY_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-#include <mcld/Config/Config.h>
-#include <mcld/Support/GCFactory.h>
-#include <mcld/Support/MemoryRegion.h>
-
-namespace mcld {
-
-class MemoryArea;
-
-/** \class RegionFactory
- * \brief RegionFactory produces and destroys MemoryRegions
- *
- */
-class RegionFactory : public GCFactory<MemoryRegion, MCLD_REGION_CHUNK_SIZE>
-{
-public:
- typedef GCFactory<MemoryRegion, MCLD_REGION_CHUNK_SIZE> Alloc;
- typedef MemoryRegion::Address Address;
- typedef MemoryRegion::ConstAddress ConstAddress;
-
-public:
- MemoryRegion* produce(Address pVMAStart, size_t pSize);
-
- void destruct(MemoryRegion* pRegion);
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Support/Space.h b/include/mcld/Support/Space.h
deleted file mode 100644
index cdf69b0..0000000
--- a/include/mcld/Support/Space.h
+++ /dev/null
@@ -1,99 +0,0 @@
-//===- Space.h ------------------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_MEMORY_SPACE_H
-#define MCLD_MEMORY_SPACE_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-#include <llvm/Support/DataTypes.h>
-#include <mcld/ADT/TypeTraits.h>
-
-namespace mcld {
-
-class FileHandle;
-class MemoryRegion;
-
-/** \class Space
- * \brief Space contains a chunk of memory space that does not overlap with
- * the other Space.
- *
- */
-class Space
-{
-public:
- enum Type
- {
- ALLOCATED_ARRAY,
- MMAPED,
- EXTERNAL,
- UNALLOCATED
- };
-
- typedef NonConstTraits<uint8_t>::pointer Address;
- typedef ConstTraits<uint8_t>::pointer ConstAddress;
-
-private:
- Space();
-
- ~Space();
-
- Space(Type pType, void* pMemBuffer, size_t pSize);
-
-public:
- void setStart(size_t pOffset)
- { m_StartOffset = pOffset; }
-
- Address memory()
- { return m_Data; }
-
- ConstAddress memory() const
- { return m_Data; }
-
- size_t start() const
- { return m_StartOffset; }
-
- size_t size() const
- { return m_Size; }
-
- Type type() const
- { return m_Type; }
-
- void addRegion(MemoryRegion& pRegion)
- { ++m_RegionCount; }
-
- void removeRegion(MemoryRegion& pRegion)
- { --m_RegionCount; }
-
- size_t numOfRegions() const
- { return m_RegionCount; }
-
- /// Create - Create a Space from external memory
- static Space* Create(void* pMemBuffer, size_t pSize);
-
- /// Create - Create a Space from FileHandler
- static Space* Create(FileHandle& pHandler, size_t pOffset, size_t pSize);
-
- static void Destroy(Space*& pSpace);
-
- static void Release(Space* pSpace, FileHandle& pHandler);
-
- static void Sync(Space* pSpace, FileHandle& pHandler);
-
-private:
- Address m_Data;
- uint32_t m_StartOffset;
- uint32_t m_Size;
- uint16_t m_RegionCount;
- Type m_Type : 2;
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Support/SystemUtils.h b/include/mcld/Support/SystemUtils.h
index 8f8507a..f15fccf 100644
--- a/include/mcld/Support/SystemUtils.h
+++ b/include/mcld/Support/SystemUtils.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_SYSTEM_UTILS_H
-#define MCLD_SYSTEM_UTILS_H
+#ifndef MCLD_SUPPORT_SYSTEMUTILS_H
+#define MCLD_SUPPORT_SYSTEMUTILS_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/Target.h b/include/mcld/Support/Target.h
new file mode 100644
index 0000000..021fc2e
--- /dev/null
+++ b/include/mcld/Support/Target.h
@@ -0,0 +1,105 @@
+//===- Target.h -----------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SUPPORT_TARGET_H
+#define MCLD_SUPPORT_TARGET_H
+#include <string>
+#include <list>
+
+namespace llvm {
+class Target;
+class Triple;
+class TargetMachine;
+} // namespace of llvm
+
+namespace mcld {
+
+class MCLDTargetMachine;
+class TargetRegistry;
+class MCLinker;
+class LinkerScript;
+class LinkerConfig;
+class Module;
+class FileHandle;
+class DiagnosticLineInfo;
+class TargetLDBackend;
+
+/** \class Target
+ * \brief Target collects target specific information
+ */
+class Target
+{
+ friend class mcld::MCLDTargetMachine;
+ friend class mcld::TargetRegistry;
+
+public:
+ typedef unsigned int (*TripleMatchQualityFnTy)(const llvm::Triple& pTriple);
+
+ typedef MCLDTargetMachine *(*TargetMachineCtorTy)(const llvm::Target &,
+ const mcld::Target &,
+ llvm::TargetMachine &,
+ const std::string&);
+
+ typedef MCLinker *(*MCLinkerCtorTy)(const std::string& pTriple,
+ LinkerConfig&,
+ Module&,
+ FileHandle& pFileHandle);
+
+ typedef bool (*EmulationFnTy)(LinkerScript&, LinkerConfig&);
+
+ typedef TargetLDBackend *(*TargetLDBackendCtorTy)(const LinkerConfig&);
+
+ typedef DiagnosticLineInfo *(*DiagnosticLineInfoCtorTy)(const mcld::Target&,
+ const std::string&);
+
+public:
+ Target();
+
+ /// getName - get the target name
+ const char* name() const { return Name; }
+
+ unsigned int getTripleQuality(const llvm::Triple& pTriple) const;
+
+ /// createTargetMachine - create target-specific TargetMachine
+ MCLDTargetMachine* createTargetMachine(const std::string& pTriple,
+ const llvm::Target& pTarget,
+ llvm::TargetMachine& pTM) const;
+
+ /// createMCLinker - create target-specific MCLinker
+ MCLinker *createMCLinker(const std::string &pTriple,
+ LinkerConfig& pConfig,
+ Module& pModule,
+ FileHandle& pFileHandle) const;
+
+ /// emulate - given MCLinker default values for the other aspects of the
+ /// target system.
+ bool emulate(LinkerScript& pScript, LinkerConfig& pConfig) const;
+
+ /// createLDBackend - create target-specific LDBackend
+ TargetLDBackend* createLDBackend(const LinkerConfig& pConfig) const;
+
+ /// createDiagnosticLineInfo - create target-specific DiagnosticLineInfo
+ DiagnosticLineInfo* createDiagnosticLineInfo(const mcld::Target& pTarget,
+ const std::string& pTriple) const;
+
+private:
+ /// Name - The target name
+ const char* Name;
+
+ TripleMatchQualityFnTy TripleMatchQualityFn;
+ TargetMachineCtorTy TargetMachineCtorFn;
+ MCLinkerCtorTy MCLinkerCtorFn;
+ EmulationFnTy EmulationFn;
+ TargetLDBackendCtorTy TargetLDBackendCtorFn;
+ DiagnosticLineInfoCtorTy DiagnosticLineInfoCtorFn;
+};
+
+} //end namespace mcld
+
+#endif
+
diff --git a/include/mcld/Support/TargetRegistry.h b/include/mcld/Support/TargetRegistry.h
index aabb06d..1ae6245 100644
--- a/include/mcld/Support/TargetRegistry.h
+++ b/include/mcld/Support/TargetRegistry.h
@@ -6,9 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_TARGET_REGISTRY_H
-#define MCLD_TARGET_REGISTRY_H
-#include <llvm/Support/TargetRegistry.h>
+#ifndef MCLD_SUPPORT_TARGETREGISTRY_H
+#define MCLD_SUPPORT_TARGETREGISTRY_H
+#include <mcld/Support/Target.h>
+#include <llvm/ADT/Triple.h>
+
#include <string>
#include <list>
@@ -21,122 +23,9 @@
namespace mcld {
-class Module;
-class LinkerConfig;
-class LinkerScript;
-class MemoryArea;
-class MCLDTargetMachine;
-class TargetRegistry;
-class MCLinker;
-class TargetLDBackend;
-class AttributeFactory;
-class InputFactory;
-class ContextFactory;
-class DiagnosticLineInfo;
-
-//===----------------------------------------------------------------------===//
-/// Target - mcld::Target is an object adapter of llvm::Target
-//===----------------------------------------------------------------------===//
-class Target
-{
- friend class mcld::MCLDTargetMachine;
- friend class mcld::TargetRegistry;
-public:
- typedef mcld::MCLDTargetMachine *(*TargetMachineCtorTy)(const mcld::Target &,
- llvm::TargetMachine &,
- const std::string&);
-
- typedef MCLinker *(*MCLinkerCtorTy)(const std::string& pTriple,
- LinkerConfig&,
- Module&,
- MemoryArea& pOutput);
-
- typedef bool (*EmulationFnTy)(LinkerScript&, LinkerConfig&);
-
- typedef TargetLDBackend *(*TargetLDBackendCtorTy)(const llvm::Target&,
- const LinkerConfig&);
-
- typedef DiagnosticLineInfo *(*DiagnosticLineInfoCtorTy)(const mcld::Target&,
- const std::string&);
-
-public:
- Target();
-
- void setTarget(const llvm::Target& pTarget)
- { m_pT = &pTarget; }
-
- mcld::MCLDTargetMachine *createTargetMachine(const std::string &pTriple,
- const std::string &pCPU, const std::string &pFeatures,
- const llvm::TargetOptions &Options,
- llvm::Reloc::Model RM = llvm::Reloc::Default,
- llvm::CodeModel::Model CM = llvm::CodeModel::Default,
- llvm::CodeGenOpt::Level OL = llvm::CodeGenOpt::Default) const
- {
- if (TargetMachineCtorFn && m_pT) {
- llvm::TargetMachine *tm = m_pT->createTargetMachine(pTriple, pCPU, pFeatures, Options, RM, CM, OL);
- if (tm)
- return TargetMachineCtorFn(*this, *tm, pTriple);
- }
- return NULL;
- }
-
- /// createMCLinker - create target-specific MCLinker
- ///
- /// @return created MCLinker
- MCLinker *createMCLinker(const std::string &pTriple,
- LinkerConfig& pConfig,
- Module& pModule,
- MemoryArea& pOutput) const {
- if (!MCLinkerCtorFn)
- return NULL;
- return MCLinkerCtorFn(pTriple, pConfig, pModule, pOutput);
- }
-
- /// emulate - given MCLinker default values for the other aspects of the
- /// target system.
- bool emulate(LinkerScript& pScript, LinkerConfig& pConfig) const {
- if (!EmulationFn)
- return false;
- return EmulationFn(pScript, pConfig);
- }
-
- /// createLDBackend - create target-specific LDBackend
- ///
- /// @return created TargetLDBackend
- TargetLDBackend* createLDBackend(const LinkerConfig& pConfig) const
- {
- if (!TargetLDBackendCtorFn)
- return NULL;
- return TargetLDBackendCtorFn(*get(), pConfig);
- }
-
- /// createDiagnosticLineInfo - create target-specific DiagnosticLineInfo
- DiagnosticLineInfo* createDiagnosticLineInfo(const mcld::Target& pTarget,
- const std::string& pTriple) const
- {
- if (!DiagnosticLineInfoCtorFn)
- return NULL;
- return DiagnosticLineInfoCtorFn(pTarget, pTriple);
- }
-
- const llvm::Target* get() const { return m_pT; }
-
-private:
- // ----- function pointers ----- //
- TargetMachineCtorTy TargetMachineCtorFn;
- MCLinkerCtorTy MCLinkerCtorFn;
- EmulationFnTy EmulationFn;
- TargetLDBackendCtorTy TargetLDBackendCtorFn;
- DiagnosticLineInfoCtorTy DiagnosticLineInfoCtorFn;
-
- // ----- adapted llvm::Target ----- //
- const llvm::Target* m_pT;
-};
-
-//===----------------------------------------------------------------------===//
-/// TargetRegistry - mcld::TargetRegistry is an object adapter of
-/// llvm::TargetRegistry
-///
+/** \class TargetRegistry
+ * \brief TargetRegistry is an object adapter of llvm::TargetRegistry
+ */
class TargetRegistry
{
public:
@@ -161,7 +50,9 @@
/// this is done by initializing all targets at program startup.
///
/// @param T - The target being registered.
- static void RegisterTarget(mcld::Target &T);
+ static void RegisterTarget(Target& pTarget,
+ const char* pName,
+ Target::TripleMatchQualityFnTy pQualityFn);
/// RegisterTargetMachine - Register a TargetMachine implementation for the
/// given target.
@@ -221,16 +112,23 @@
T.DiagnosticLineInfoCtorFn = Fn;
}
- /// lookupTarget - Lookup a target based on a llvm::Target.
- ///
- /// @param T - The llvm::Target to find
- static const mcld::Target *lookupTarget(const llvm::Target& T);
-
- /// lookupTarget - function wrapper of llvm::TargetRegistry::lookupTarget
+ /// lookupTarget - Look up MCLinker target
///
/// @param Triple - The Triple string
/// @param Error - The returned error message
- static const mcld::Target *lookupTarget(const std::string &Triple,
+ static const mcld::Target *lookupTarget(const std::string& pTriple,
+ std::string& pError);
+
+ /// lookupTarget - Look up MCLinker target by an architecture name
+ /// and a triple. If the architecture name is not empty, then the
+ /// the lookup is done mainly by architecture. Otherwise, the target
+ /// triple is used.
+ ///
+ /// @param pArch - The architecture name
+ /// @param pTriple - The target triple
+ /// @param pError - The returned error message
+ static const mcld::Target *lookupTarget(const std::string& pArchName,
+ llvm::Triple& pTriple,
std::string &Error);
};
@@ -240,22 +138,27 @@
/// Target TheFooTarget; // The global target instance.
///
/// extern "C" void MCLDInitializeFooTargetInfo() {
-/// RegisterTarget X(TheFooTarget, "foo", "Foo description");
+/// RegisterTarget<llvm::Foo> X(TheFooTarget, "foo", "Foo description");
/// }
+template<llvm::Triple::ArchType TargetArchType = llvm::Triple::UnknownArch>
struct RegisterTarget
{
- RegisterTarget(mcld::Target &T, const char *Name) {
- llvm::TargetRegistry::iterator TIter, TEnd = llvm::TargetRegistry::end();
- // lookup llvm::Target
- for( TIter=llvm::TargetRegistry::begin(); TIter!=TEnd; ++TIter ) {
- if( 0==strcmp(TIter->getName(), Name) )
- break;
+public:
+ RegisterTarget(mcld::Target &pTarget, const char* pName) {
+ // if we've registered one, then return immediately.
+ TargetRegistry::iterator target, ie = TargetRegistry::end();
+ for (target = TargetRegistry::begin(); target != ie; ++target) {
+ if (0 == strcmp((*target)->name(), pName))
+ return;
}
- if (TIter != TEnd)
- T.setTarget(*TIter);
+ TargetRegistry::RegisterTarget(pTarget, pName, &getTripleMatchQuality);
+ }
- TargetRegistry::RegisterTarget(T);
+ static unsigned int getTripleMatchQuality(const llvm::Triple& pTriple) {
+ if (pTriple.getArch() == TargetArchType)
+ return 20;
+ return 0;
}
};
@@ -275,10 +178,11 @@
}
private:
- static mcld::MCLDTargetMachine *Allocator(const mcld::Target &T,
- llvm::TargetMachine& TM,
- const std::string &Triple) {
- return new TargetMachineImpl(TM, T, Triple);
+ static MCLDTargetMachine *Allocator(const llvm::Target& pLLVMTarget,
+ const mcld::Target& pMCLDTarget,
+ llvm::TargetMachine& pTM,
+ const std::string& pTriple) {
+ return new TargetMachineImpl(pTM, pLLVMTarget, pMCLDTarget, pTriple);
}
};
diff --git a/include/mcld/Support/TargetSelect.h b/include/mcld/Support/TargetSelect.h
index 7fcb74a..0b2be2a 100644
--- a/include/mcld/Support/TargetSelect.h
+++ b/include/mcld/Support/TargetSelect.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_TARGET_SELECT_H
-#define MCLD_TARGET_SELECT_H
+#ifndef MCLD_SUPPORT_TARGETSELECT_H
+#define MCLD_SUPPORT_TARGETSELECT_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/ToolOutputFile.h b/include/mcld/Support/ToolOutputFile.h
index 4dfc4e6..f1186c3 100644
--- a/include/mcld/Support/ToolOutputFile.h
+++ b/include/mcld/Support/ToolOutputFile.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_SUPPORT_TOOL_OUTPUT_FILE_H
-#define MCLD_SUPPORT_TOOL_OUTPUT_FILE_H
+#ifndef MCLD_SUPPORT_TOOLOUTPUTFILE_H
+#define MCLD_SUPPORT_TOOLOUTPUTFILE_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
@@ -23,12 +23,9 @@
class Path;
class FileHandle;
-class MemoryArea;
-class raw_mem_ostream;
/** \class ToolOutputFile
- * \brief ToolOutputFile contains a raw_mem_ostream and adds extra new
- * features:
+ * \brief ToolOutputFile has the following features:
* - The file is automatically deleted if the process is killed.
* - The file is automatically deleted when the TooOutputFile object is
* destoryed unless the client calls keep().
@@ -36,21 +33,21 @@
class ToolOutputFile
{
public:
- ToolOutputFile(const std::string& pPath,
+ ToolOutputFile(const sys::fs::Path& pPath,
FileHandle::OpenMode pMode,
FileHandle::Permission pPermission);
~ToolOutputFile();
- /// mem_os - Return the contained raw_mem_ostream.
- raw_mem_ostream &mem_os();
+ /// fd - Retutn the output file handle
+ FileHandle& fd() { return m_FileHandle; }
- /// os - Return the contained formatted_raw_ostream
+ /// os - Return the contained raw_fd_ostream
+ llvm::raw_fd_ostream& os();
+
+ /// formatted_os - Return the contained formatted_raw_ostream
llvm::formatted_raw_ostream& formatted_os();
- /// memory - Return the contained MemoryArea.
- MemoryArea& memory();
-
/// keep - Indicate that the tool's job wrt this output file has been
/// successful and the file should not be deleted.
void keep();
@@ -59,7 +56,7 @@
class CleanupInstaller
{
public:
- explicit CleanupInstaller(const std::string& pPath);
+ explicit CleanupInstaller(const sys::fs::Path& pPath);
~CleanupInstaller();
@@ -67,19 +64,16 @@
bool Keep;
private:
- std::string m_Path;
+ sys::fs::Path m_Path;
};
private:
FileHandle m_FileHandle;
CleanupInstaller m_Installer;
- MemoryArea* m_pMemoryArea;
- raw_mem_ostream* m_pOStream;
- llvm::formatted_raw_ostream* m_pFOStream;
-
+ llvm::raw_fd_ostream* m_pFdOstream;
+ llvm::formatted_raw_ostream* m_pFormattedOstream;
};
} // namespace of mcld
#endif
-
diff --git a/include/mcld/Support/UniqueGCFactory.h b/include/mcld/Support/UniqueGCFactory.h
index 3147bab..73c1110 100644
--- a/include/mcld/Support/UniqueGCFactory.h
+++ b/include/mcld/Support/UniqueGCFactory.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_UNIQUE_GCFACTORY_H
-#define MCLD_UNIQUE_GCFACTORY_H
+#ifndef MCLD_SUPPORT_UNIQUEGCFACTORY_H
+#define MCLD_SUPPORT_UNIQUEGCFACTORY_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
diff --git a/include/mcld/Support/raw_mem_ostream.h b/include/mcld/Support/raw_mem_ostream.h
deleted file mode 100644
index b2db64a..0000000
--- a/include/mcld/Support/raw_mem_ostream.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===- raw_mem_ostream.h --------------------------------------------------===//
-//
-// The MCLinker Project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MCLD_RAW_MEMORY_AREA_OSTREAM_H
-#define MCLD_RAW_MEMORY_AREA_OSTREAM_H
-#ifdef ENABLE_UNITTEST
-#include <gtest.h>
-#endif
-#include <string>
-
-#include <llvm/Support/raw_ostream.h>
-
-namespace mcld {
-
-class MemoryArea;
-
-class raw_mem_ostream : public llvm::raw_ostream
-{
-public:
- /// constructor - pMemoryArea must be writable.
- explicit raw_mem_ostream(MemoryArea &pMemoryArea);
-
- ~raw_mem_ostream();
-
- MemoryArea& getMemoryArea() {
- flush();
- return m_MemoryArea;
- }
-
-private:
- /// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *pPtr, size_t pSize);
-
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const;
-
-private:
- MemoryArea& m_MemoryArea;
- uint64_t m_Position;
-};
-
-} // namespace of mcld
-
-#endif
-
diff --git a/include/mcld/Support/raw_ostream.h b/include/mcld/Support/raw_ostream.h
index 0e2cc40..6274e49 100644
--- a/include/mcld/Support/raw_ostream.h
+++ b/include/mcld/Support/raw_ostream.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCLD_RAW_OSTREAM_H
-#define MCLD_RAW_OSTREAM_H
+#ifndef MCLD_SUPPORT_RAWOSTREAM_H
+#define MCLD_SUPPORT_RAWOSTREAM_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif