From: Ted Kremenek Date: Mon, 14 Jul 2008 17:40:50 +0000 (+0000) Subject: Added method "EmitBasicReport" to BugReporter to simplify the emission of simple... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=57202071e477530e9348bc76671ee369b2399b92;p=clang Added method "EmitBasicReport" to BugReporter to simplify the emission of simple bug diagnostics. Refactored error reporting in CheckObjCDealloc and CheckObjCInstMethSignature to use this new bug reporting interface (major code simplification). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53560 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h index d1c430fc96..1bbba40418 100644 --- a/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/include/clang/Analysis/PathSensitive/BugReporter.h @@ -189,6 +189,9 @@ public: void EmitWarning(BugReport& R); + void EmitBasicReport(const char* BugName, const char* BugStr, + SourceLocation Loc); + static bool classof(const BugReporter* R) { return true; } }; diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index 081e7925ee..cbd61f8d25 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -731,12 +731,12 @@ void BugReporter::EmitWarning(BugReport& R) { // Determine the range. const SourceRange *Beg, *End; - + if (!D->empty()) { Beg = D->back()->ranges_begin(); End = D->back()->ranges_end(); } - else + else R.getRanges(*this, Beg, End); if (PD) { @@ -745,18 +745,18 @@ void BugReporter::EmitWarning(BugReport& R) { for ( ; Beg != End; ++Beg) piece->addRange(*Beg); - D->push_back(piece); + D->push_back(piece); PD->HandlePathDiagnostic(D.take()); } else { - std::ostringstream os; - + std::ostringstream os; + if (D->empty()) os << R.getDescription(); else os << D->back()->getString(); - - + + Diagnostic& Diag = getDiagnostic(); unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, os.str().c_str()); @@ -764,3 +764,19 @@ void BugReporter::EmitWarning(BugReport& R) { Diag.Report(L, ErrorDiag, NULL, 0, Beg, End - Beg); } } + +void +BugReporter::EmitBasicReport(const char* name, const char* str, + SourceLocation Loc) { + + SimpleBugType BT(name); + DiagCollector C(BT); + Diagnostic& Diag = getDiagnostic(); + Diag.Report(&C, getContext().getFullLoc(Loc), + Diag.getCustomDiagID(Diagnostic::Warning, str), + 0, 0, 0, 0); + + for (DiagCollector::iterator I = C.begin(), E = C.end(); I != E; ++I) + EmitWarning(*I); +} + diff --git a/lib/Analysis/CheckObjCDealloc.cpp b/lib/Analysis/CheckObjCDealloc.cpp index 3e21f016df..0c9100951c 100644 --- a/lib/Analysis/CheckObjCDealloc.cpp +++ b/lib/Analysis/CheckObjCDealloc.cpp @@ -83,8 +83,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D, // Get the "dealloc" selector. IdentifierInfo* II = &Ctx.Idents.get("dealloc"); - Selector S = Ctx.Selectors.getSelector(0, &II); - + Selector S = Ctx.Selectors.getSelector(0, &II); ObjCMethodDecl* MD = 0; // Scan the instance methods for "dealloc". @@ -99,52 +98,32 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D, if (!MD) { // No dealloc found. - // FIXME: This code should be reduced to three lines if possible (Refactor). - SimpleBugType BT(LOpts.getGCMode() == LangOptions::NonGC - ? "missing -dealloc" - : "missing -dealloc (Hybrid MM, non-GC)"); - - DiagCollector C(BT); + const char* name = LOpts.getGCMode() == LangOptions::NonGC + ? "missing -dealloc" + : "missing -dealloc (Hybrid MM, non-GC)"; std::ostringstream os; os << "Objective-C class '" << D->getName() << "' lacks a 'dealloc' instance method"; - Diagnostic& Diag = BR.getDiagnostic(); - Diag.Report(&C, - Ctx.getFullLoc(D->getLocStart()), - Diag.getCustomDiagID(Diagnostic::Warning, os.str().c_str()), - NULL, 0, NULL, 0); - - for (DiagCollector::iterator I = C.begin(), E = C.end(); I != E; ++I) - BR.EmitWarning(*I); - + BR.EmitBasicReport(name, os.str().c_str(), D->getLocStart()); return; } // dealloc found. Scan for missing [super dealloc]. if (MD->getBody() && !scan_dealloc(MD->getBody(), S)) { - // FIXME: This code should be reduced to three lines if possible (Refactor). - SimpleBugType BT(LOpts.getGCMode() == LangOptions::NonGC - ? "missing [super dealloc]" - : "missing [super dealloc] (Hybrid MM, non-GC)"); - - DiagCollector C(BT); + const char* name = LOpts.getGCMode() == LangOptions::NonGC + ? "missing [super dealloc]" + : "missing [super dealloc] (Hybrid MM, non-GC)"; std::ostringstream os; os << "The 'dealloc' instance method in Objective-C class '" << D->getName() << "' does not send a 'dealloc' message to its super class" " (missing [super dealloc])"; - Diagnostic& Diag = BR.getDiagnostic(); - Diag.Report(&C, - Ctx.getFullLoc(MD->getLocStart()), - Diag.getCustomDiagID(Diagnostic::Warning, os.str().c_str()), - NULL, 0, NULL, 0); - - for (DiagCollector::iterator I = C.begin(), E = C.end(); I != E; ++I) - BR.EmitWarning(*I); - } + BR.EmitBasicReport(name, os.str().c_str(), D->getLocStart()); + return; + } } diff --git a/lib/Analysis/CheckObjCInstMethSignature.cpp b/lib/Analysis/CheckObjCInstMethSignature.cpp index f5966ecc72..ffaef42b23 100644 --- a/lib/Analysis/CheckObjCInstMethSignature.cpp +++ b/lib/Analysis/CheckObjCInstMethSignature.cpp @@ -64,16 +64,8 @@ static void CompareReturnTypes(ObjCMethodDecl* MethDerived, << "'. These two types are incompatible, and may result in undefined " "behavior for clients of these classes."; - // Refactor. - SimpleBugType BT("incompatible instance method return type"); - DiagCollector C(BT); - Diagnostic& Diag = BR.getDiagnostic(); - Diag.Report(&C, Ctx.getFullLoc(MethDerived->getLocStart()), - Diag.getCustomDiagID(Diagnostic::Warning, os.str().c_str()), - NULL, 0, NULL, 0); - - for (DiagCollector::iterator I = C.begin(), E = C.end(); I != E; ++I) - BR.EmitWarning(*I); + BR.EmitBasicReport("incompatible instance method return type", + os.str().c_str(), MethDerived->getLocStart()); } }