#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)
"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
+
+
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);
}
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();
}
ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End,
AnalysisStores SM,
+ AnalysisDiagClients DC,
Diagnostic &diags, Preprocessor* pp,
PreprocessorFactory* ppf,
const LangOptions& lopts,
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)
#include "Analyses.def"
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,
#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
//===----------------------------------------------------------------------===//
assert (!AnalysisList.empty());
return CreateAnalysisConsumer(&AnalysisList[0],
&AnalysisList[0]+AnalysisList.size(),
- AnalysisStoreOpt,
+ AnalysisStoreOpt, AnalysisDiagOpt,
Diag, PP, PPF, LangOpts,
AnalyzeSpecificFunction,
OutputFile, VisualizeEGDot, VisualizeEGUbi,
Preprocessor* PP,
PreprocessorFactory* PPF);
-PathDiagnosticClient* CreatePlistDiagnosticClient(const std::string& prefix);
+PathDiagnosticClient* CreatePlistDiagnosticClient(const std::string& prefix,
+ Preprocessor* PP,
+ PreprocessorFactory* PPF);
}
#endif
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;
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);
}
// 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";
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>";
}