Create a new logger class for all messages w.r.t. SPIR-V build.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index b4d5fb1..bf0b430 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -52,12 +52,12 @@
 #include "../glslang/MachineIndependent/SymbolTable.h"
 #include "../glslang/Include/Common.h"
 
-#include <string>
-#include <map>
-#include <list>
-#include <vector>
-#include <stack>
 #include <fstream>
+#include <list>
+#include <map>
+#include <stack>
+#include <string>
+#include <vector>
 
 namespace {
 
@@ -94,7 +94,7 @@
 //
 class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
 public:
-    TGlslangToSpvTraverser(const glslang::TIntermediate*);
+    TGlslangToSpvTraverser(const glslang::TIntermediate*, spv::SpvBuildLogger* logger);
     virtual ~TGlslangToSpvTraverser();
 
     bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate*);
@@ -109,8 +109,6 @@
 
     void dumpSpv(std::vector<unsigned int>& out);
 
-    std::string getWarningsAndErrors() const { return warningsErrors.str(); }
-
 protected:
     spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
     spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable);
@@ -161,7 +159,7 @@
     spv::Instruction* entryPoint;
     int sequenceDepth;
 
-    std::ostringstream warningsErrors;
+    spv::SpvBuildLogger* logger;
 
     // There is a 1:1 mapping between a spv builder and a module; this is thread safe
     spv::Builder builder;
@@ -437,7 +435,7 @@
     case glslang::EbvBaseInstance:
     case glslang::EbvDrawId:
         // TODO: Add SPIR-V builtin ID.
-        spv::MissingFunctionality(warningsErrors, "Draw parameters");
+        logger->missingFunctionality("Draw parameters");
         return (spv::BuiltIn)spv::BadValue;
     case glslang::EbvPrimitiveId:          return spv::BuiltInPrimitiveId;
     case glslang::EbvInvocationId:         return spv::BuiltInInvocationId;
@@ -610,9 +608,9 @@
 // Implement the TGlslangToSpvTraverser class.
 //
 
-TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate)
-    : TIntermTraverser(true, false, true), shaderEntry(0), sequenceDepth(0),
-      builder((glslang::GetKhronosToolId() << 16) | GeneratorVersion, warningsErrors),
+TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate, spv::SpvBuildLogger* buildLogger)
+    : TIntermTraverser(true, false, true), shaderEntry(0), sequenceDepth(0), logger(buildLogger),
+      builder((glslang::GetKhronosToolId() << 16) | GeneratorVersion, logger),
       inMain(false), mainTerminated(false), linkageOnly(false),
       glslangIntermediate(glslangIntermediate)
 {
@@ -988,7 +986,7 @@
 
     builder.clearAccessChain();
     if (! result) {
-        spv::MissingFunctionality(warningsErrors, "unknown glslang binary operation");
+        logger->missingFunctionality("unknown glslang binary operation");
         return true;  // pick up a child as the place-holder result
     } else {
         builder.setAccessChainRValue(result);
@@ -1113,7 +1111,7 @@
         return false;
 
     default:
-        spv::MissingFunctionality(warningsErrors, "unknown glslang unary");
+        logger->missingFunctionality("unknown glslang unary");
         return true;  // pick up operand as placeholder result
     }
 }
@@ -1224,7 +1222,7 @@
             builder.clearAccessChain();
             builder.setAccessChainRValue(result);
         } else
-            spv::MissingFunctionality(warningsErrors, "missing user function; linker needs to catch that");
+            logger->missingFunctionality("missing user function; linker needs to catch that");
 
         return false;
     }
@@ -1472,7 +1470,7 @@
         return false;
 
     if (! result) {
-        spv::MissingFunctionality(warningsErrors, "unknown glslang aggregate");
+        logger->missingFunctionality("unknown glslang aggregate");
         return true;  // pick up a child as a placeholder operand
     } else {
         builder.clearAccessChain();
@@ -1765,7 +1763,7 @@
         spvType = builder.makeUintType(64);
         break;
     case glslang::EbtAtomicUint:
-        spv::TbdFunctionality(warningsErrors, "Is atomic_uint an opaque handle in the uniform storage class, or an addresses in the atomic storage class?");
+        logger->tbdFunctionality("Is atomic_uint an opaque handle in the uniform storage class, or an addresses in the atomic storage class?");
         spvType = builder.makeUintType(32);
         break;
     case glslang::EbtSampler:
@@ -3151,7 +3149,7 @@
     case glslang::EOpUnpackInt2x32:
     case glslang::EOpPackUint2x32:
     case glslang::EOpUnpackUint2x32:
-        spv::MissingFunctionality(warningsErrors, "shader int64");
+        logger->missingFunctionality("shader int64");
         libCall = spv::GLSLstd450Bad; // TODO: This is a placeholder.
         break;
 
@@ -3782,7 +3780,7 @@
         builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsCrossWorkgroupMemoryMask);
         return 0;
     default:
-        spv::MissingFunctionality(warningsErrors, "unknown operation with no arguments");
+        logger->missingFunctionality("unknown operation with no arguments");
         return 0;
     }
 }
@@ -3943,7 +3941,7 @@
 
     // Neither a front-end constant node, nor a specialization constant node with constant union array or
     // constant sub tree as initializer.
-    spv::MissingFunctionality(warningsErrors, "Neither a front-end constant nor a spec constant.");
+    logger->missingFunctionality("Neither a front-end constant nor a spec constant.");
     exit(1);
     return spv::NoResult;
 }
@@ -4198,10 +4196,11 @@
 //
 void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv)
 {
-    GlslangToSpv(intermediate, spirv, nullptr);
+    spv::SpvBuildLogger logger;
+    GlslangToSpv(intermediate, spirv, &logger);
 }
 
-void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, std::string* messages)
+void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger)
 {
     TIntermNode* root = intermediate.getTreeRoot();
 
@@ -4210,14 +4209,12 @@
 
     glslang::GetThreadPoolAllocator().push();
 
-    TGlslangToSpvTraverser it(&intermediate);
+    TGlslangToSpvTraverser it(&intermediate, logger);
 
     root->traverse(&it);
 
     it.dumpSpv(spirv);
 
-    if (messages != nullptr) *messages = it.getWarningsAndErrors();
-
     glslang::GetThreadPoolAllocator().pop();
 }