Include the "issue context" (e.g. function or method) where a static analyzer issue occurred in the plist output.

Fixes <rdar://problem/11004527>

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154030 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
index 9dd8da5..aa6f97b 100644
--- a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
@@ -112,8 +112,8 @@
       << " | Empty WorkList: "
       << (Eng.hasEmptyWorkList() ? "yes" : "no");
 
-  B.EmitBasicReport("Analyzer Statistics", "Internal Statistics", output.str(),
-      PathDiagnosticLocation(D, SM));
+  B.EmitBasicReport(D, "Analyzer Statistics", "Internal Statistics",
+                    output.str(), PathDiagnosticLocation(D, SM));
 
   // Emit warning for each block we bailed out on.
   typedef CoreEngine::BlocksExhausted::const_iterator ExhaustedIterator;
@@ -128,8 +128,9 @@
       llvm::raw_svector_ostream outputI(bufI);
       outputI << "(" << NameOfRootFunction << ")" <<
                  ": The analyzer generated a sink at this point";
-      B.EmitBasicReport("Sink Point", "Internal Statistics", outputI.str(),
-          PathDiagnosticLocation::createBegin(CS->getStmt(), SM, LC));
+      B.EmitBasicReport(D, "Sink Point", "Internal Statistics", outputI.str(),
+                        PathDiagnosticLocation::createBegin(CS->getStmt(),
+                                                            SM, LC));
     }
   }
 }
diff --git a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
index 6005ecd..befc935 100644
--- a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
@@ -157,7 +157,7 @@
         os << "U";
       os << "se a safer 'strlcat' API";
 
-      BR.EmitBasicReport("Anti-pattern in the argument", "C String API",
+      BR.EmitBasicReport(FD, "Anti-pattern in the argument", "C String API",
                          os.str(), Loc, &R, 1);
     }
   }
diff --git a/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
index 257dcca..690e2ce 100644
--- a/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
@@ -179,7 +179,7 @@
     llvm::raw_string_ostream os(buf);
     os << "Objective-C class '" << *D << "' lacks a 'dealloc' instance method";
 
-    BR.EmitBasicReport(name, os.str(), DLoc);
+    BR.EmitBasicReport(D, name, os.str(), DLoc);
     return;
   }
 
@@ -196,7 +196,7 @@
        << "' does not send a 'dealloc' message to its super class"
            " (missing [super dealloc])";
 
-    BR.EmitBasicReport(name, os.str(), DLoc);
+    BR.EmitBasicReport(MD, name, os.str(), DLoc);
     return;
   }
 
@@ -263,7 +263,7 @@
       PathDiagnosticLocation SDLoc =
         PathDiagnosticLocation::createBegin((*I), BR.getSourceManager());
 
-      BR.EmitBasicReport(name, category, os.str(), SDLoc);
+      BR.EmitBasicReport(MD, name, category, os.str(), SDLoc);
     }
   }
 }
diff --git a/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp b/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp
index c076c1e..d7321fa 100644
--- a/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp
@@ -70,7 +70,8 @@
       PathDiagnosticLocation::createBegin(MethDerived,
                                           BR.getSourceManager());
 
-    BR.EmitBasicReport("Incompatible instance method return type",
+    BR.EmitBasicReport(MethDerived,
+                       "Incompatible instance method return type",
                        os.str(), MethDLoc);
   }
 }
diff --git a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
index 10f86a1..dde9071 100644
--- a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -286,7 +286,8 @@
 
   PathDiagnosticLocation FSLoc =
     PathDiagnosticLocation::createBegin(FS, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(bugType, "Security", os.str(),
+  BR.EmitBasicReport(AC->getDecl(),
+                     bugType, "Security", os.str(),
                      FSLoc, ranges.data(), ranges.size());
 }
 
@@ -322,7 +323,8 @@
   SourceRange R = CE->getCallee()->getSourceRange();
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport("Potential buffer overflow in call to 'gets'",
+  BR.EmitBasicReport(AC->getDecl(),
+                     "Potential buffer overflow in call to 'gets'",
                      "Security",
                      "Call to function 'gets' is extremely insecure as it can "
                      "always result in a buffer overflow",
@@ -363,7 +365,8 @@
   SourceRange R = CE->getCallee()->getSourceRange();
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport("Potential buffer overflow in call to 'getpw'",
+  BR.EmitBasicReport(AC->getDecl(),
+                     "Potential buffer overflow in call to 'getpw'",
                      "Security",
                      "The getpw() function is dangerous as it may overflow the "
                      "provided buffer. It is obsoleted by getpwuid().",
@@ -405,10 +408,12 @@
   SourceRange R = CE->getCallee()->getSourceRange();
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport("Potential insecure temporary file in call 'mktemp'",
+  BR.EmitBasicReport(AC->getDecl(),
+                     "Potential insecure temporary file in call 'mktemp'",
                      "Security",
                      "Call to function 'mktemp' is insecure as it always "
-                     "creates or uses insecure temporary file.  Use 'mkstemp' instead",
+                     "creates or uses insecure temporary file.  Use 'mkstemp' "
+                     "instead",
                      CELoc, &R, 1);
 }
 
@@ -490,7 +495,8 @@
     out << " used as a suffix";
   }
   out << ')';
-  BR.EmitBasicReport("Insecure temporary file creation", "Security",
+  BR.EmitBasicReport(AC->getDecl(),
+                     "Insecure temporary file creation", "Security",
                      out.str(), CELoc, &R, 1);
 }
 
@@ -511,13 +517,14 @@
   SourceRange R = CE->getCallee()->getSourceRange();
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport("Potential insecure memory buffer bounds restriction in "
+  BR.EmitBasicReport(AC->getDecl(),
+                     "Potential insecure memory buffer bounds restriction in "
                      "call 'strcpy'",
                      "Security",
                      "Call to function 'strcpy' is insecure as it does not "
-		     "provide bounding of the memory buffer. Replace "
-		     "unbounded copy functions with analogous functions that "
-		     "support length arguments such as 'strlcpy'. CWE-119.",
+                     "provide bounding of the memory buffer. Replace "
+                     "unbounded copy functions with analogous functions that "
+                     "support length arguments such as 'strlcpy'. CWE-119.",
                      CELoc, &R, 1);
 }
 
@@ -538,13 +545,14 @@
   SourceRange R = CE->getCallee()->getSourceRange();
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport("Potential insecure memory buffer bounds restriction in "
-		     "call 'strcat'",
-		     "Security",
-		     "Call to function 'strcat' is insecure as it does not "
-		     "provide bounding of the memory buffer. Replace "
-		     "unbounded copy functions with analogous functions that "
-		     "support length arguments such as 'strlcat'. CWE-119.",
+  BR.EmitBasicReport(AC->getDecl(),
+                     "Potential insecure memory buffer bounds restriction in "
+                     "call 'strcat'",
+                     "Security",
+                     "Call to function 'strcat' is insecure as it does not "
+                     "provide bounding of the memory buffer. Replace "
+                     "unbounded copy functions with analogous functions that "
+                     "support length arguments such as 'strlcat'. CWE-119.",
                      CELoc, &R, 1);
 }
 
@@ -619,7 +627,8 @@
   SourceRange R = CE->getCallee()->getSourceRange();
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(os1.str(), "Security", os2.str(), CELoc, &R, 1);
+  BR.EmitBasicReport(AC->getDecl(), os1.str(), "Security", os2.str(),
+                     CELoc, &R, 1);
 }
 
 //===----------------------------------------------------------------------===//
@@ -644,7 +653,8 @@
   SourceRange R = CE->getCallee()->getSourceRange();
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport("'random' is not a secure random number generator",
+  BR.EmitBasicReport(AC->getDecl(),
+                     "'random' is not a secure random number generator",
                      "Security",
                      "The 'random' function produces a sequence of values that "
                      "an adversary may be able to predict.  Use 'arc4random' "
@@ -664,7 +674,8 @@
   SourceRange R = CE->getCallee()->getSourceRange();
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport("Potential insecure implementation-specific behavior in "
+  BR.EmitBasicReport(AC->getDecl(),
+                     "Potential insecure implementation-specific behavior in "
                      "call 'vfork'",
                      "Security",
                      "Call to function 'vfork' is insecure as it can lead to "
@@ -736,7 +747,8 @@
   SourceRange R = CE->getCallee()->getSourceRange();
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(os1.str(), "Security", os2.str(), CELoc, &R, 1);
+  BR.EmitBasicReport(AC->getDecl(), os1.str(), "Security", os2.str(),
+                     CELoc, &R, 1);
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp b/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
index 55945e6..cc7fd37 100644
--- a/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
@@ -63,7 +63,8 @@
     SourceRange R = ArgEx->getSourceRange();
     PathDiagnosticLocation ELoc =
       PathDiagnosticLocation::createBegin(E, BR.getSourceManager(), AC);
-    BR.EmitBasicReport("Potential unintended use of sizeof() on pointer type",
+    BR.EmitBasicReport(AC->getDecl(),
+                       "Potential unintended use of sizeof() on pointer type",
                        "Logic",
                        "The code calls sizeof() on a pointer type. "
                        "This can produce an unexpected result.",
diff --git a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
index 7202a1f..7457e44 100644
--- a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
@@ -130,7 +130,7 @@
         return;
     }
 
-    BR.EmitBasicReport(BugType, "Dead store", os.str(), L, R);
+    BR.EmitBasicReport(AC->getDecl(), BugType, "Dead store", os.str(), L, R);
   }
 
   void CheckVarDecl(const VarDecl *VD, const Expr *Ex, const Expr *Val,
diff --git a/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp b/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
index 3e0ef21..757a4ce 100644
--- a/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
@@ -115,8 +115,10 @@
 namespace {
 class StringRefCheckerVisitor : public StmtVisitor<StringRefCheckerVisitor> {
   BugReporter &BR;
+  const Decl *DeclWithIssue;
 public:
-  StringRefCheckerVisitor(BugReporter &br) : BR(br) {}
+  StringRefCheckerVisitor(const Decl *declWithIssue, BugReporter &br)
+    : BR(br), DeclWithIssue(declWithIssue) {}
   void VisitChildren(Stmt *S) {
     for (Stmt::child_iterator I = S->child_begin(), E = S->child_end() ;
       I != E; ++I)
@@ -131,7 +133,7 @@
 } // end anonymous namespace
 
 static void CheckStringRefAssignedTemporary(const Decl *D, BugReporter &BR) {
-  StringRefCheckerVisitor walker(BR);
+  StringRefCheckerVisitor walker(D, BR);
   walker.Visit(D->getBody());
 }
 
@@ -176,7 +178,7 @@
                      "std::string that it outlives";
   PathDiagnosticLocation VDLoc =
     PathDiagnosticLocation::createBegin(VD, BR.getSourceManager());
-  BR.EmitBasicReport(desc, "LLVM Conventions", desc,
+  BR.EmitBasicReport(DeclWithIssue, desc, "LLVM Conventions", desc,
                      VDLoc, Init->getSourceRange());
 }
 
@@ -281,7 +283,7 @@
   // the class may be in the header file, for example).
   PathDiagnosticLocation L = PathDiagnosticLocation::createBegin(
                                FieldChain.front(), BR.getSourceManager());
-  BR.EmitBasicReport("AST node allocates heap memory", "LLVM Conventions",
+  BR.EmitBasicReport(Root, "AST node allocates heap memory", "LLVM Conventions",
                      os.str(), L);
 }
 
diff --git a/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
index c9d315a..b11c947 100644
--- a/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
@@ -214,11 +214,10 @@
        i != e;
        ++i) {
     SourceRange R = i->mulop->getSourceRange();
-    BR.EmitBasicReport("MallocOverflowSecurityChecker",
+    BR.EmitBasicReport(D, "malloc() size overflow",
       "the computation of the size of the memory allocation may overflow",
       PathDiagnosticLocation::createOperatorLoc(i->mulop,
-                                                BR.getSourceManager()),
-      &R, 1);
+                                                BR.getSourceManager()), &R, 1);
   }
 }
 
diff --git a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
index 28f8993..4e10633 100644
--- a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
@@ -194,8 +194,8 @@
             PathDiagnosticLocation::createBegin(i->AllocCall->getCallee(),
                                                 BR.getSourceManager(), ADC);
 
-          BR.EmitBasicReport("allocator sizeof operand mismatch", OS.str(), L,
-                             Ranges.data(), Ranges.size());
+          BR.EmitBasicReport(D, "allocator sizeof operand mismatch", OS.str(),
+                             L, Ranges.data(), Ranges.size());
         }
       }
     }
diff --git a/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp b/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
index 7d4520d..f826573 100644
--- a/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
@@ -74,7 +74,7 @@
         "error occurred";
     PathDiagnosticLocation L =
       PathDiagnosticLocation::create(D, BR.getSourceManager());
-    BR.EmitBasicReport("Bad return type when passing NSError**",
+    BR.EmitBasicReport(D, "Bad return type when passing NSError**",
                        "Coding conventions (Apple)", err, L);
   }
 }
@@ -122,7 +122,7 @@
         "error occurred";
     PathDiagnosticLocation L =
       PathDiagnosticLocation::create(D, BR.getSourceManager());
-    BR.EmitBasicReport("Bad return type when passing CFErrorRef*",
+    BR.EmitBasicReport(D, "Bad return type when passing CFErrorRef*",
                        "Coding conventions (Apple)", err, L);
   }
 }
diff --git a/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
index 5508a49..aeb90a6 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
@@ -142,7 +142,8 @@
     SourceRange R = Arg->getSourceRange();
     PathDiagnosticLocation CELoc =
         PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-    BR.EmitBasicReport(OsName.str(), "Core Foundation/Objective-C",
+    BR.EmitBasicReport(AC->getDecl(),
+                       OsName.str(), "Core Foundation/Objective-C",
                        Os.str(), CELoc, &R, 1);
   }
 
diff --git a/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp
index bbc262f..4718dc7 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp
@@ -161,7 +161,7 @@
 
       PathDiagnosticLocation L =
         PathDiagnosticLocation::create(I->first, BR.getSourceManager());
-      BR.EmitBasicReport("Unused instance variable", "Optimization",
+      BR.EmitBasicReport(D, "Unused instance variable", "Optimization",
                          os.str(), L);
     }
 }
diff --git a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
index c40912c..5a13ed0 100644
--- a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
@@ -162,8 +162,8 @@
     if (SM.isInSystemHeader(SL) || SM.isInExternCSystemHeader(SL))
       continue;
 
-    B.EmitBasicReport("Unreachable code", "Dead code", "This statement is never"
-        " executed", DL, SR);
+    B.EmitBasicReport(D, "Unreachable code", "Dead code",
+                      "This statement is never executed", DL, SR);
   }
 }
 
diff --git a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
index 1d1803c..f7c7c0c 100644
--- a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
@@ -186,7 +186,8 @@
   if (isPure) {
     os << "\n" <<  "Call pure virtual functions during construction or "
        << "destruction may leads undefined behaviour";
-    BR.EmitBasicReport("Call pure virtual function during construction or "
+    BR.EmitBasicReport(AC->getDecl(),
+                       "Call pure virtual function during construction or "
                        "Destruction",
                        "Cplusplus",
                        os.str(), CELoc, &R, 1);
@@ -195,7 +196,8 @@
   else {
     os << "\n" << "Call virtual functions during construction or "
        << "destruction will never go to a more derived class";
-    BR.EmitBasicReport("Call virtual function during construction or "
+    BR.EmitBasicReport(AC->getDecl(),
+                       "Call virtual function during construction or "
                        "Destruction",
                        "Cplusplus",
                        os.str(), CELoc, &R, 1);