Add support for warnings (#319)

Enable all warnings.

Support the two standard OpenCL options -w and -Werror.

CompileFromSourceString prints warnings only when there
are errors. It probably shouldn't print anything to stderr
but that's another story.

Signed-off-by: Kévin Petit <kpet@free.fr>
diff --git a/lib/Compiler.cpp b/lib/Compiler.cpp
index 74c6d9a..d4dc8ce 100644
--- a/lib/Compiler.cpp
+++ b/lib/Compiler.cpp
@@ -151,6 +151,14 @@
 static llvm::cl::opt<bool> verify("verify", llvm::cl::init(false),
                                   llvm::cl::desc("Verify diagnostic outputs"));
 
+static llvm::cl::opt<bool>
+    IgnoreWarnings("w", llvm::cl::init(false),
+                   llvm::cl::desc("Disable all warnings"));
+
+static llvm::cl::opt<bool>
+    WarningsAsErrors("Werror", llvm::cl::init(false),
+                   llvm::cl::desc("Turn warnings into errors"));
+
 // Populates |SamplerMapEntries| with data from the input sampler map. Returns 0
 // if successful.
 int ParseSamplerMap(const std::string &sampler_map,
@@ -392,7 +400,7 @@
   instance.getCodeGenOpts().SimplifyLibCalls = false;
   instance.getCodeGenOpts().EmitOpenCLArgMetadata = false;
   instance.getCodeGenOpts().DisableO0ImplyOptNone = true;
-  instance.getDiagnosticOpts().IgnoreWarnings = false;
+  instance.getDiagnosticOpts().IgnoreWarnings = IgnoreWarnings;
 
   instance.getLangOpts().SinglePrecisionConstants =
       cl_single_precision_constants;
@@ -443,10 +451,14 @@
   // Override the C99 inline semantics to accommodate for more OpenCL C
   // programs in the wild.
   instance.getLangOpts().GNUInline = true;
+
+  // Set up diagnostics
   instance.createDiagnostics(
       new clang::TextDiagnosticPrinter(*diagnosticsStream,
                                        &instance.getDiagnosticOpts()),
       true);
+  instance.getDiagnostics().setWarningsAsErrors(WarningsAsErrors);
+  instance.getDiagnostics().setEnableAllWarnings(true);
 
   instance.getTargetOpts().Triple = triple.str();
 
@@ -713,9 +725,12 @@
       instance.getDiagnostics().getClient();
   consumer->finish();
 
+  auto num_warnings = consumer->getNumWarnings();
   auto num_errors = consumer->getNumErrors();
+  if ((num_errors > 0) || (num_warnings > 0)) {
+    llvm::errs() << log;
+  }
   if (num_errors > 0) {
-    llvm::errs() << log << "\n";
     return -1;
   }
 
@@ -726,6 +741,12 @@
     return -1;
   }
 
+  // Don't run the passes or produce any output in verify mode.
+  // Clang doesn't always produce a valid module.
+  if (verify) {
+    return 0;
+  }
+
   llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
   llvm::initializeCore(Registry);
   llvm::initializeScalarOpts(Registry);