diff options
author | Jordan Rose <jordan_rose@apple.com> | 2013-01-18 18:27:21 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2013-01-18 18:27:21 +0000 |
commit | e02be97811c785f91ac43a0feed2db862de1867f (patch) | |
tree | 0ac03e0789e8ab043a86435bb4e12f362ec93ead /lib/StaticAnalyzer/Core/PathDiagnostic.cpp | |
parent | dc47c9a71c99ce2e5b9d84f1cd3487b6852b3543 (diff) |
[analyzer] Special path notes for C++ special member functions.
Examples:
Calling implicit default constructor for Foo
Calling defaulted move constructor for Foo
Calling copy constructor for Foo
Calling implicit destructor for Foo
Calling defaulted move assignment operator for Foo
Calling copy assignment operator for Foo
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172833 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/PathDiagnostic.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/PathDiagnostic.cpp | 70 |
1 files changed, 56 insertions, 14 deletions
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index 30b7d64290..a584a84eea 100644 --- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -788,27 +788,68 @@ void PathDiagnosticCallPiece::setCallee(const CallEnter &CE, callEnter = getLocationForCaller(CalleeCtx, CE.getLocationContext(), SM); } +static inline void describeClass(raw_ostream &Out, const CXXRecordDecl *D, + StringRef Prefix = StringRef()) { + if (!D->getIdentifier()) + return; + Out << Prefix << '\'' << *D << '\''; +} + static bool describeCodeDecl(raw_ostream &Out, const Decl *D, - bool ShouldDescribeBlock, + bool ExtendedDescription, StringRef Prefix = StringRef()) { if (!D) return false; if (isa<BlockDecl>(D)) { - if (ShouldDescribeBlock) + if (ExtendedDescription) Out << Prefix << "anonymous block"; - return ShouldDescribeBlock; + return ExtendedDescription; } if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { - if (isa<CXXConstructorDecl>(MD)) - Out << Prefix << "constructor for '" << *MD << "'"; - else if (isa<CXXDestructorDecl>(MD)) - Out << Prefix << "'" << *MD << "'"; - else if (MD->getParent()->getIdentifier()) - Out << Prefix << "'" << *MD->getParent() << "::" << *MD << "'"; - else - Out << Prefix << "'" << *MD << "'"; + Out << Prefix; + if (ExtendedDescription && !MD->isUserProvided()) { + if (MD->isExplicitlyDefaulted()) + Out << "defaulted "; + else + Out << "implicit "; + } + + if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(MD)) { + if (CD->isDefaultConstructor()) + Out << "default "; + else if (CD->isCopyConstructor()) + Out << "copy "; + else if (CD->isMoveConstructor()) + Out << "move "; + + Out << "constructor"; + describeClass(Out, MD->getParent(), " for "); + + } else if (isa<CXXDestructorDecl>(MD)) { + if (!MD->isUserProvided()) { + Out << "destructor"; + describeClass(Out, MD->getParent(), " for "); + } else { + // Use ~Foo for explicitly-written destructors. + Out << "'" << *MD << "'"; + } + + } else if (MD->isCopyAssignmentOperator()) { + Out << "copy assignment operator"; + describeClass(Out, MD->getParent(), " for "); + + } else if (MD->isMoveAssignmentOperator()) { + Out << "move assignment operator"; + describeClass(Out, MD->getParent(), " for "); + + } else { + if (MD->getParent()->getIdentifier()) + Out << "'" << *MD->getParent() << "::" << *MD << "'"; + else + Out << "'" << *MD << "'"; + } return true; } @@ -826,7 +867,7 @@ PathDiagnosticCallPiece::getCallEnterEvent() const { llvm::raw_svector_ostream Out(buf); Out << "Calling "; - describeCodeDecl(Out, Callee, /*DescribeBlocks=*/true); + describeCodeDecl(Out, Callee, /*ExtendedDescription=*/true); assert(callEnter.asLocation().isValid()); return new PathDiagnosticEventPiece(callEnter, Out.str()); @@ -841,7 +882,7 @@ PathDiagnosticCallPiece::getCallEnterWithinCallerEvent() const { llvm::raw_svector_ostream Out(buf); Out << "Entered call"; - describeCodeDecl(Out, Caller, /*DescribeBlocks=*/false, " from "); + describeCodeDecl(Out, Caller, /*ExtendedDescription=*/false, " from "); return new PathDiagnosticEventPiece(callEnterWithin, Out.str()); } @@ -857,7 +898,8 @@ PathDiagnosticCallPiece::getCallExitEvent() const { if (!CallStackMessage.empty()) { Out << CallStackMessage; } else { - bool DidDescribe = describeCodeDecl(Out, Callee, /*DescribeBlocks=*/false, + bool DidDescribe = describeCodeDecl(Out, Callee, + /*ExtendedDescription=*/false, "Returning from "); if (!DidDescribe) Out << "Returning to caller"; |