[analyzer] Add the type of the leaked object to the diagnostic message

If the object is a temporary, and there is no variable it binds to,
let's at least print out the object name in order to help differentiate
it from other temporaries.

rdar://45175098

Differential Revision: https://reviews.llvm.org/D55033

llvm-svn: 347943
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index 608ed88..8758091 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -28,6 +28,17 @@
          isa<CXXBoolLiteralExpr>(E);
 }
 
+/// If type represents a pointer to CXXRecordDecl,
+/// and is not a typedef, return the decl name.
+/// Otherwise, return the serialization of type.
+static StringRef getPrettyTypeName(QualType QT) {
+  QualType PT = QT->getPointeeType();
+  if (!PT.isNull() && !QT->getAs<TypedefType>())
+    if (const auto *RD = PT->getAsCXXRecordDecl())
+      return RD->getName();
+  return QT.getAsString();
+}
+
 /// Write information about the type state change to {@code os},
 /// return whether the note should be generated.
 static bool shouldGenerateNote(llvm::raw_string_ostream &os,
@@ -193,7 +204,7 @@
            << Sym->getType().getAsString() << " with a ";
       } else if (CurrV.getObjKind() == RetEffect::OS) {
         os << " returns an OSObject of type "
-           << Sym->getType().getAsString() << " with a ";
+           << getPrettyTypeName(Sym->getType()) << " with a ";
       } else if (CurrV.getObjKind() == RetEffect::Generalized) {
         os << " returns an object of type " << Sym->getType().getAsString()
            << " with a ";
@@ -432,7 +443,7 @@
   if (RegionDescription) {
     os << "object allocated and stored into '" << *RegionDescription << '\'';
   } else {
-    os << "allocated object";
+    os << "allocated object of type " << getPrettyTypeName(Sym->getType());
   }
 
   // Get the retain count.
@@ -472,10 +483,10 @@
               " Foundation";
       }
     }
-  }
-  else
+  } else {
     os << " is not referenced later in this execution path and has a retain "
           "count of +" << RV->getCount();
+  }
 
   return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
 }
@@ -555,6 +566,10 @@
       FullSourceLoc SL(AllocStmt->getBeginLoc(), Ctx.getSourceManager());
       os << " (allocated on line " << SL.getSpellingLineNumber() << ")";
     }
+  } else {
+
+    // If we can't figure out the name, just supply the type information.
+    os << " of type " << getPrettyTypeName(Sym->getType());
   }
 }