Hook up the Plist diagnostic client to the driver.

Fix Plist output.

llvm-svn: 58652
This commit is contained in:
Ted Kremenek 2008-11-03 23:18:07 +00:00
parent f33f8a8606
commit 14f18653f6
6 changed files with 59 additions and 18 deletions

View File

@ -15,10 +15,6 @@
#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)
#endif
#ifndef ANALYSIS_STORE
#define ANALYSIS_STORE(NAME, CMDFLAG, DESC)
#endif
ANALYSIS(CFGDump, "cfg-dump",
"Display Control-Flow Graphs", Code)
@ -52,8 +48,22 @@ ANALYSIS(CheckerCFRef, "checker-cfref",
"Run the [Core] Foundation reference count checker", Code)
#ifndef ANALYSIS_STORE
#define ANALYSIS_STORE(NAME, CMDFLAG, DESC)
#endif
ANALYSIS_STORE(BasicStore, "basic", "Use basic analyzer store")
ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store")
#ifndef ANALYSIS_DIAGNOSTICS
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)
#endif
ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", CreateHTMLDiagnosticClient)
ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", CreatePlistDiagnosticClient)
#undef ANALYSIS
#undef ANALYSIS_STORE
#undef ANALYSIS_DIAGNOSTICS

View File

@ -75,20 +75,21 @@ namespace {
llvm::OwningPtr<PathDiagnosticClient> PD;
bool AnalyzeAll;
AnalysisStores SM;
AnalysisDiagClients DC;
AnalysisConsumer(Diagnostic &diags, Preprocessor* pp,
PreprocessorFactory* ppf,
const LangOptions& lopts,
const std::string& fname,
const std::string& htmldir,
AnalysisStores sm,
AnalysisStores sm, AnalysisDiagClients dc,
bool visgraphviz, bool visubi, bool trim, bool analyzeAll)
: VisGraphviz(visgraphviz), VisUbigraph(visubi), TrimGraph(trim),
LOpts(lopts), Diags(diags),
Ctx(0), PP(pp), PPF(ppf),
HTMLDir(htmldir),
FName(fname),
AnalyzeAll(analyzeAll), SM(sm) {}
AnalyzeAll(analyzeAll), SM(sm), DC(dc) {}
void addCodeAction(CodeAction action) {
FunctionActions.push_back(action);
@ -165,9 +166,14 @@ case NAME##Model: return Create##NAME##Manager;
}
virtual PathDiagnosticClient* getPathDiagnosticClient() {
if (C.PD.get() == 0 && !C.HTMLDir.empty())
C.PD.reset(CreateHTMLDiagnosticClient(C.HTMLDir, C.PP, C.PPF));
if (C.PD.get() == 0 && !C.HTMLDir.empty()) {
switch (C.DC) {
default:
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)\
case PD_##NAME: C.PD.reset(CREATEFN(C.HTMLDir, C.PP, C.PPF)); break;
#include "Analyses.def"
}
}
return C.PD.get();
}
@ -449,6 +455,7 @@ static void ActionWarnObjCMethSigs(AnalysisManager& mgr) {
ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End,
AnalysisStores SM,
AnalysisDiagClients DC,
Diagnostic &diags, Preprocessor* pp,
PreprocessorFactory* ppf,
const LangOptions& lopts,
@ -459,7 +466,7 @@ ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End,
bool analyzeAll) {
llvm::OwningPtr<AnalysisConsumer>
C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir, SM,
C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir, SM, DC,
VisGraphviz, VisUbi, trim, analyzeAll));
for ( ; Beg != End ; ++Beg)

View File

@ -28,8 +28,14 @@ enum AnalysisStores {
NumStores
};
enum AnalysisDiagClients {
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
#include "Analyses.def"
NUM_ANALYSIS_DIAG_CLIENTS
};
ASTConsumer* CreateAnalysisConsumer(Analyses* Beg, Analyses* End,
AnalysisStores SM,
AnalysisStores SM, AnalysisDiagClients DC,
Diagnostic &diags, Preprocessor* pp,
PreprocessorFactory* ppf,
const LangOptions& lopts,

View File

@ -220,6 +220,15 @@ clEnumValN(NAME##Model, "analyzer-store-" CMDFLAG, DESC),
#include "Analyses.def"
clEnumValEnd));
static llvm::cl::opt<AnalysisDiagClients>
AnalysisDiagOpt(llvm::cl::desc("SCA Output Options:"),
llvm::cl::init(PD_HTML),
llvm::cl::values(
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN)\
clEnumValN(PD_##NAME, "analyzer-output-" CMDFLAG, DESC),
#include "Analyses.def"
clEnumValEnd));
//===----------------------------------------------------------------------===//
// Language Options
//===----------------------------------------------------------------------===//
@ -1224,7 +1233,7 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile,
assert (!AnalysisList.empty());
return CreateAnalysisConsumer(&AnalysisList[0],
&AnalysisList[0]+AnalysisList.size(),
AnalysisStoreOpt,
AnalysisStoreOpt, AnalysisDiagOpt,
Diag, PP, PPF, LangOpts,
AnalyzeSpecificFunction,
OutputFile, VisualizeEGDot, VisualizeEGUbi,

View File

@ -26,7 +26,9 @@ PathDiagnosticClient* CreateHTMLDiagnosticClient(const std::string& prefix,
Preprocessor* PP,
PreprocessorFactory* PPF);
PathDiagnosticClient* CreatePlistDiagnosticClient(const std::string& prefix);
PathDiagnosticClient* CreatePlistDiagnosticClient(const std::string& prefix,
Preprocessor* PP,
PreprocessorFactory* PPF);
}
#endif

View File

@ -24,6 +24,11 @@
using namespace clang;
typedef llvm::DenseMap<unsigned,unsigned> FIDMap;
namespace clang {
class Preprocessor;
class PreprocessorFactory;
}
namespace {
class VISIBILITY_HIDDEN PlistDiagnostics : public PathDiagnosticClient {
llvm::sys::Path Directory, FilePrefix;
@ -40,7 +45,9 @@ PlistDiagnostics::PlistDiagnostics(const std::string& prefix)
FilePrefix.appendComponent("report"); // All Plist files begin with "report"
}
PathDiagnosticClient* clang::CreatePlistDiagnosticClient(const std::string& s) {
PathDiagnosticClient*
clang::CreatePlistDiagnosticClient(const std::string& s,
Preprocessor*, PreprocessorFactory*) {
return new PlistDiagnostics(s);
}
@ -118,7 +125,7 @@ static void ReportDiag(llvm::raw_ostream& o, const PathDiagnosticPiece& P,
// Output the text.
Indent(o, indent) << "<key>message</key>\n";
Indent(o, indent) << "<string>" << P.getString() << "</string>";
Indent(o, indent) << "<string>" << P.getString() << "</string>\n";
// Output the hint.
Indent(o, indent) << "<key>displayhint</key>\n";
@ -222,9 +229,9 @@ void PlistDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) {
o << " </array>\n";
// Output the bug type and bug category.
o << " <key>description</key><string>" << D->getDescription() << "</string>\n"
" <key>category</key><string>" << D->getCategory() << "</string>\n";
o << " <key>description</key>\n <string>" << D->getDescription() << "</string>\n"
" <key>category</key>\n <string>" << D->getCategory() << "</string>\n";
// Finish.
o << "</dict>\n";
o << "</dict>\n</plist>";
}