Add LLVMContext::emitWarning methods and use them. <rdar://problem/12867368>
authorBob Wilson <bob.wilson@apple.com>
Mon, 24 Dec 2012 18:15:21 +0000 (18:15 +0000)
committerBob Wilson <bob.wilson@apple.com>
Mon, 24 Dec 2012 18:15:21 +0000 (18:15 +0000)
When the backend is used from clang, it should produce proper diagnostics
instead of just printing messages to errs(). Other clients may also want to
register their own error handlers with the LLVMContext, and the same handler
should work for warnings in the same way as the existing emitError methods.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171041 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/LLVMContext.h
lib/Analysis/ProfileDataLoaderPass.cpp
lib/Analysis/ProfileInfoLoaderPass.cpp
lib/CodeGen/IntrinsicLowering.cpp
lib/Transforms/InstCombine/InstCombineCalls.cpp
lib/Transforms/Instrumentation/EdgeProfiling.cpp
lib/Transforms/Instrumentation/OptimalEdgeProfiling.cpp
lib/Transforms/Instrumentation/PathProfiling.cpp
lib/VMCore/LLVMContext.cpp

index 5903e2e55e1f0120e80c43301677e4a96764159e..a5a26946b77de29e1a502e636de56c42491d0a34 100644 (file)
@@ -89,6 +89,12 @@ public:
   void emitError(const Instruction *I, const Twine &ErrorStr);
   void emitError(const Twine &ErrorStr);
 
+  /// emitWarning - This is similar to emitError but it emits a warning instead
+  /// of an error.
+  void emitWarning(unsigned LocCookie, const Twine &ErrorStr);
+  void emitWarning(const Instruction *I, const Twine &ErrorStr);
+  void emitWarning(const Twine &ErrorStr);
+
 private:
   LLVMContext(LLVMContext&) LLVM_DELETED_FUNCTION;
   void operator=(LLVMContext&) LLVM_DELETED_FUNCTION;
index 604541f4fdcb4a8ed79b3cf25c987636577179cc..af12c4d4a398b6cbb1e2a30f3a64b4c7b9033cd9 100644 (file)
@@ -177,8 +177,8 @@ bool ProfileMetadataLoaderPass::runOnModule(Module &M) {
   unsigned ReadCount = matchEdges(M, PB, Counters);
 
   if (ReadCount != Counters.size()) {
-    errs() << "WARNING: profile information is inconsistent with "
-           << "the current program!\n";
+    M.getContext().emitWarning("profile information is inconsistent "
+                               "with the current program");
   }
   NumEdgesRead = ReadCount;
 
index 2f3486cb449655ad219a5f10ba0b3ad717c679d7..8e6d1c2ecb9bf2d5f5c819b05fc4156a77b4c9b8 100644 (file)
@@ -19,6 +19,7 @@
 #include "llvm/Analysis/ProfileInfoLoader.h"
 #include "llvm/BasicBlock.h"
 #include "llvm/InstrTypes.h"
+#include "llvm/LLVMContext.h"
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CFG.h"
@@ -170,8 +171,8 @@ bool LoaderPass::runOnModule(Module &M) {
       }
     }
     if (ReadCount != Counters.size()) {
-      errs() << "WARNING: profile information is inconsistent with "
-             << "the current program!\n";
+      M.getContext().emitWarning("profile information is inconsistent "
+                                 "with the current program");
     }
     NumEdgesRead = ReadCount;
   }
@@ -218,8 +219,8 @@ bool LoaderPass::runOnModule(Module &M) {
       }
     }
     if (ReadCount != Counters.size()) {
-      errs() << "WARNING: profile information is inconsistent with "
-             << "the current program!\n";
+      M.getContext().emitWarning("profile information is inconsistent "
+                                 "with the current program");
     }
     NumEdgesRead = ReadCount;
   }
@@ -239,8 +240,8 @@ bool LoaderPass::runOnModule(Module &M) {
           BlockInformation[F][BB] = (double)Counters[ReadCount++];
     }
     if (ReadCount != Counters.size()) {
-      errs() << "WARNING: profile information is inconsistent with "
-             << "the current program!\n";
+      M.getContext().emitWarning("profile information is inconsistent "
+                                 "with the current program");
     }
   }
 
@@ -258,8 +259,8 @@ bool LoaderPass::runOnModule(Module &M) {
         FunctionInformation[F] = (double)Counters[ReadCount++];
     }
     if (ReadCount != Counters.size()) {
-      errs() << "WARNING: profile information is inconsistent with "
-             << "the current program!\n";
+      M.getContext().emitWarning("profile information is inconsistent "
+                                 "with the current program");
     }
   }
 
index 698d289f13c7efae9a62954972d00a622a571c14..f289a9beacbdd7ec1f2c73509770ffd405fbeefd 100644 (file)
@@ -413,22 +413,30 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
   }
 
   case Intrinsic::stacksave:
-  case Intrinsic::stackrestore: {
     if (!Warned)
-      errs() << "WARNING: this target does not support the llvm.stack"
-             << (Callee->getIntrinsicID() == Intrinsic::stacksave ?
-               "save" : "restore") << " intrinsic.\n";
+      Context.emitWarning("this target does not support the "
+                          "llvm.stacksave intrinsic");
+    Warned = true;
+    CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
+    break;
+
+  case Intrinsic::stackrestore:
+    if (!Warned)
+      Context.emitWarning("this target does not support the "
+                          "llvm.stackrestore intrinsic");
     Warned = true;
-    if (Callee->getIntrinsicID() == Intrinsic::stacksave)
-      CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
     break;
-  }
     
   case Intrinsic::returnaddress:
+    Context.emitWarning("this target does not support the "
+                        "llvm.returnaddress intrinsic");
+    CI->replaceAllUsesWith(ConstantPointerNull::get(
+                                            cast<PointerType>(CI->getType())));
+    break;
+
   case Intrinsic::frameaddress:
-    errs() << "WARNING: this target does not support the llvm."
-           << (Callee->getIntrinsicID() == Intrinsic::returnaddress ?
-             "return" : "frame") << "address intrinsic.\n";
+    Context.emitWarning("this target does not support the "
+                        "llvm.frameaddress intrinsic");
     CI->replaceAllUsesWith(ConstantPointerNull::get(
                                             cast<PointerType>(CI->getType())));
     break;
@@ -438,12 +446,12 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
 
   case Intrinsic::pcmarker:
     break;    // Simply strip out pcmarker on unsupported architectures
-  case Intrinsic::readcyclecounter: {
-    errs() << "WARNING: this target does not support the llvm.readcyclecoun"
-           << "ter intrinsic.  It is being lowered to a constant 0\n";
+  case Intrinsic::readcyclecounter:
+    Context.emitWarning("this target does not support the "
+                        "llvm.readcyclecounter intrinsic; "
+                        "it is being lowered to a constant 0");
     CI->replaceAllUsesWith(ConstantInt::get(Type::getInt64Ty(Context), 0));
     break;
-  }
 
   case Intrinsic::dbg_declare:
     break;    // Simply strip out debugging intrinsics
index 7babf32159737f4a050a393ae635d70054837e54..4849463b5a1c50a3bead3428f6c6f926ce19a1da 100644 (file)
@@ -1154,8 +1154,9 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
   // If we are removing arguments to the function, emit an obnoxious warning.
   if (FT->getNumParams() < NumActualArgs) {
     if (!FT->isVarArg()) {
-      errs() << "WARNING: While resolving call to function '"
-             << Callee->getName() << "' arguments were dropped!\n";
+      FT->getContext().emitWarning("while resolving call to function '" +
+                                   Callee->getName() +
+                                   "' arguments were dropped");
     } else {
       // Add all of the arguments in their promoted form to the arg list.
       for (unsigned i = FT->getNumParams(); i != NumActualArgs; ++i, ++AI) {
index 41e42aff490bace361f718195a675f066e9b37a7..cf12b1f75873f6f11543a558edf9d4561c59bab6 100644 (file)
@@ -21,6 +21,7 @@
 #include "llvm/Transforms/Instrumentation.h"
 #include "ProfilingUtils.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/LLVMContext.h"
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/raw_ostream.h"
@@ -54,8 +55,8 @@ ModulePass *llvm::createEdgeProfilerPass() { return new EdgeProfiler(); }
 bool EdgeProfiler::runOnModule(Module &M) {
   Function *Main = M.getFunction("main");
   if (Main == 0) {
-    errs() << "WARNING: cannot insert edge profiling into a module"
-           << " with no main function!\n";
+    M.getContext().emitWarning("cannot insert edge profiling into a module"
+                               " with no main function");
     return false;  // No main, no instrumentation!
   }
 
index 8f8d027dca7e29e8423727047e9f721cfe26f9bc..3c851681b90e9e311c81757cced4ed8b5606ed2d 100644 (file)
@@ -22,6 +22,7 @@
 #include "llvm/Analysis/ProfileInfo.h"
 #include "llvm/Analysis/ProfileInfoLoader.h"
 #include "llvm/Constants.h"
+#include "llvm/LLVMContext.h"
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/Debug.h"
@@ -75,8 +76,8 @@ inline static void printEdgeCounter(ProfileInfo::Edge e,
 bool OptimalEdgeProfiler::runOnModule(Module &M) {
   Function *Main = M.getFunction("main");
   if (Main == 0) {
-    errs() << "WARNING: cannot insert edge profiling into a module"
-           << " with no main function!\n";
+    M.getContext().emitWarning("cannot insert edge profiling into a module"
+                               " with no main function");
     return false;  // No main, no instrumentation!
   }
 
index 2a0e89ce6a1e31e9eb923e1fc60ec74cfda1277a..2d324b89b109f0f16d92d9c2b74ec561561214d9 100644 (file)
@@ -1345,8 +1345,8 @@ bool PathProfiler::runOnModule(Module &M) {
     Main = M.getFunction("MAIN__");
 
   if (!Main) {
-    errs() << "WARNING: cannot insert path profiling into a module"
-           << " with no main function!\n";
+    Context->emitWarning("cannot insert edge profiling into a module"
+                         " with no main function");
     return false;
   }
 
index 68c4a766f6d2dabac8defc0aa2ed80a5048529ab..bdb1b4ba2ee47c7a6e9f2773815d18db0e18f9e9 100644 (file)
@@ -97,16 +97,30 @@ void LLVMContext::emitError(const Twine &ErrorStr) {
   emitError(0U, ErrorStr);
 }
 
-void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
+void LLVMContext::emitWarning(const Twine &ErrorStr) {
+  emitWarning(0U, ErrorStr);
+}
+
+static unsigned getSrcLocation(const Instruction *I) {
   unsigned LocCookie = 0;
   if (const MDNode *SrcLoc = I->getMetadata("srcloc")) {
     if (SrcLoc->getNumOperands() != 0)
       if (const ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0)))
         LocCookie = CI->getZExtValue();
   }
+  return LocCookie;
+}
+
+void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
+  unsigned LocCookie = getSrcLocation(I);
   return emitError(LocCookie, ErrorStr);
 }
 
+void LLVMContext::emitWarning(const Instruction *I, const Twine &ErrorStr) {
+  unsigned LocCookie = getSrcLocation(I);
+  return emitWarning(LocCookie, ErrorStr);
+}
+
 void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
   // If there is no error handler installed, just print the error and exit.
   if (pImpl->InlineAsmDiagHandler == 0) {
@@ -120,6 +134,19 @@ void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
   pImpl->InlineAsmDiagHandler(Diag, pImpl->InlineAsmDiagContext, LocCookie);
 }
 
+void LLVMContext::emitWarning(unsigned LocCookie, const Twine &ErrorStr) {
+  // If there is no handler installed, just print the warning.
+  if (pImpl->InlineAsmDiagHandler == 0) {
+    errs() << "warning: " << ErrorStr << "\n";
+    return;
+  }
+
+  // If we do have a handler, we can report the warning.
+  SMDiagnostic Diag("", SourceMgr::DK_Warning, ErrorStr.str());
+
+  pImpl->InlineAsmDiagHandler(Diag, pImpl->InlineAsmDiagContext, LocCookie);
+}
+
 //===----------------------------------------------------------------------===//
 // Metadata Kind Uniquing
 //===----------------------------------------------------------------------===//