typedef const SourceRange *ranges_iterator;
typedef llvm::ImmutableList<BugReporterVisitor*>::iterator visitor_iterator;
+ typedef SmallVector<StringRef, 2> ExtraTextList;
protected:
friend class BugReporter;
FullSourceLoc Location;
const ExplodedNode *ErrorNode;
SmallVector<SourceRange, 4> Ranges;
+ ExtraTextList ExtraText;
// Not the most efficient data structure, but we use an ImmutableList for the
// Callbacks because it is safe to make additions to list during iteration.
/// \brief This allows for addition of meta data to the diagnostic.
///
/// Currently, only the HTMLDiagnosticClient knows how to display it.
- virtual std::pair<const char**,const char**> getExtraDescriptiveText() {
- return std::make_pair((const char**)0,(const char**)0);
+ void addExtraText(StringRef S) {
+ ExtraText.push_back(S);
+ }
+
+ virtual const ExtraTextList &getExtraText() {
+ return ExtraText;
}
/// \brief Return the "definitive" location of the reported bug.
return;
// Get the meta data.
- std::pair<const char**, const char**> Meta =
- exampleReport->getExtraDescriptiveText();
- for (const char** s = Meta.first; s != Meta.second; ++s)
- D->addMeta(*s);
+ const BugReport::ExtraTextList &Meta =
+ exampleReport->getExtraText();
+ for (BugReport::ExtraTextList::const_iterator i = Meta.begin(),
+ e = Meta.end(); i != e; ++i) {
+ D->addMeta(*i);
+ }
// Emit a summary diagnostic to the regular Diagnostics engine.
BugReport::ranges_iterator Beg, End;
//===----------------------------------------------------------------------===//
// Error reporting.
//===----------------------------------------------------------------------===//
+static void addExtraTextToCFReport(BugReport &R);
namespace {
-
//===-------------===//
// Bug Descriptions. //
//===-------------===//
: BugReport(D, D.getDescription(), n) {
if (registerVisitor)
addVisitor(new CFRefReportVisitor(sym, tf));
+ addExtraTextToCFReport(*this);
}
CFRefReport(CFRefBug& D, const CFRefCount &tf,
ExplodedNode *n, SymbolRef sym, StringRef endText)
: BugReport(D, D.getDescription(), endText, n) {
addVisitor(new CFRefReportVisitor(sym, tf));
+ addExtraTextToCFReport(*this);
}
virtual ~CFRefReport() {}
else
return std::make_pair(ranges_iterator(), ranges_iterator());
}
-
- std::pair<const char**,const char**> getExtraDescriptiveText();
};
class CFRefLeakReport : public CFRefReport {
};
} // end anonymous namespace
-
-
static const char* Msgs[] = {
// GC only
"Code is compiled to only use garbage collection",
" (non-GC). The bug occurs in non-GC mode"
};
-std::pair<const char**,const char**> CFRefReport::getExtraDescriptiveText() {
- CFRefCount& TF = static_cast<CFRefBug&>(getBugType()).getTF();
+// Add the metadata text.
+static void addExtraTextToCFReport(BugReport &R) {
+ CFRefCount& TF = static_cast<CFRefBug&>(R.getBugType()).getTF();
switch (TF.getLangOptions().getGCMode()) {
- default:
- assert(false);
+ default:
+ assert(false);
- case LangOptions::GCOnly:
- assert (TF.isGCEnabled());
- return std::make_pair(&Msgs[0], &Msgs[0]+1);
+ case LangOptions::GCOnly:
+ assert (TF.isGCEnabled());
+ R.addExtraText(Msgs[0]);
+ return;
- case LangOptions::NonGC:
- assert (!TF.isGCEnabled());
- return std::make_pair(&Msgs[1], &Msgs[1]+1);
+ case LangOptions::NonGC:
+ assert (!TF.isGCEnabled());
+ R.addExtraText(Msgs[1]);
+ return;
- case LangOptions::HybridGC:
- if (TF.isGCEnabled())
- return std::make_pair(&Msgs[2], &Msgs[2]+1);
- else
- return std::make_pair(&Msgs[3], &Msgs[3]+1);
+ case LangOptions::HybridGC:
+ if (TF.isGCEnabled()) {
+ R.addExtraText(Msgs[2]);
+ return;
+ }
+ else {
+ R.addExtraText(Msgs[3]);
+ return;
+ }
}
}