forked from OSchip/llvm-project
[analyzer][NFC] Refactor functions in PlistDiagnostics to take Preproc as parameter
This is patch is a preparation for the proposed inclusion of macro expansions in the plist output. Differential Revision: https://reviews.llvm.org/D52735 llvm-svn: 343511
This commit is contained in:
parent
dc0624844f
commit
4f9fdba4f6
|
@ -31,13 +31,13 @@ using namespace markup;
|
|||
namespace {
|
||||
class PlistDiagnostics : public PathDiagnosticConsumer {
|
||||
const std::string OutputFile;
|
||||
const LangOptions &LangOpts;
|
||||
const Preprocessor &PP;
|
||||
const bool SupportsCrossFileDiagnostics;
|
||||
const bool SerializeStatistics;
|
||||
public:
|
||||
PlistDiagnostics(AnalyzerOptions &AnalyzerOpts,
|
||||
const std::string& prefix,
|
||||
const LangOptions &LangOpts,
|
||||
const Preprocessor &PP,
|
||||
bool supportsMultipleFiles);
|
||||
|
||||
~PlistDiagnostics() override {}
|
||||
|
@ -61,10 +61,9 @@ namespace {
|
|||
|
||||
PlistDiagnostics::PlistDiagnostics(AnalyzerOptions &AnalyzerOpts,
|
||||
const std::string& output,
|
||||
const LangOptions &LO,
|
||||
const Preprocessor &PP,
|
||||
bool supportsMultipleFiles)
|
||||
: OutputFile(output),
|
||||
LangOpts(LO),
|
||||
: OutputFile(output), PP(PP),
|
||||
SupportsCrossFileDiagnostics(supportsMultipleFiles),
|
||||
SerializeStatistics(AnalyzerOpts.shouldSerializeStats()) {}
|
||||
|
||||
|
@ -72,23 +71,20 @@ void ento::createPlistDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
|
|||
PathDiagnosticConsumers &C,
|
||||
const std::string& s,
|
||||
const Preprocessor &PP) {
|
||||
C.push_back(new PlistDiagnostics(AnalyzerOpts, s,
|
||||
PP.getLangOpts(), false));
|
||||
C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP, false));
|
||||
}
|
||||
|
||||
void ento::createPlistMultiFileDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
|
||||
PathDiagnosticConsumers &C,
|
||||
const std::string &s,
|
||||
const Preprocessor &PP) {
|
||||
C.push_back(new PlistDiagnostics(AnalyzerOpts, s,
|
||||
PP.getLangOpts(), true));
|
||||
C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP, true));
|
||||
}
|
||||
|
||||
static void EmitRanges(raw_ostream &o,
|
||||
const ArrayRef<SourceRange> Ranges,
|
||||
const FIDMap& FM,
|
||||
const SourceManager &SM,
|
||||
const LangOptions &LangOpts,
|
||||
const Preprocessor &PP,
|
||||
unsigned indent) {
|
||||
|
||||
if (Ranges.empty())
|
||||
|
@ -97,6 +93,10 @@ static void EmitRanges(raw_ostream &o,
|
|||
Indent(o, indent) << "<key>ranges</key>\n";
|
||||
Indent(o, indent) << "<array>\n";
|
||||
++indent;
|
||||
|
||||
const SourceManager &SM = PP.getSourceManager();
|
||||
const LangOptions &LangOpts = PP.getLangOpts();
|
||||
|
||||
for (auto &R : Ranges)
|
||||
EmitRange(o, SM,
|
||||
Lexer::getAsCharRange(SM.getExpansionRange(R), SM, LangOpts),
|
||||
|
@ -122,10 +122,12 @@ static void EmitMessage(raw_ostream &o, StringRef Message, unsigned indent) {
|
|||
static void ReportControlFlow(raw_ostream &o,
|
||||
const PathDiagnosticControlFlowPiece& P,
|
||||
const FIDMap& FM,
|
||||
const SourceManager &SM,
|
||||
const LangOptions &LangOpts,
|
||||
const Preprocessor &PP,
|
||||
unsigned indent) {
|
||||
|
||||
const SourceManager &SM = PP.getSourceManager();
|
||||
const LangOptions &LangOpts = PP.getLangOpts();
|
||||
|
||||
Indent(o, indent) << "<dict>\n";
|
||||
++indent;
|
||||
|
||||
|
@ -175,12 +177,13 @@ static void ReportControlFlow(raw_ostream &o,
|
|||
|
||||
static void ReportEvent(raw_ostream &o, const PathDiagnosticEventPiece& P,
|
||||
const FIDMap& FM,
|
||||
const SourceManager &SM,
|
||||
const LangOptions &LangOpts,
|
||||
const Preprocessor &PP,
|
||||
unsigned indent,
|
||||
unsigned depth,
|
||||
bool isKeyEvent = false) {
|
||||
|
||||
const SourceManager &SM = PP.getSourceManager();
|
||||
|
||||
Indent(o, indent) << "<dict>\n";
|
||||
++indent;
|
||||
|
||||
|
@ -198,7 +201,7 @@ static void ReportEvent(raw_ostream &o, const PathDiagnosticEventPiece& P,
|
|||
|
||||
// Output the ranges (if any).
|
||||
ArrayRef<SourceRange> Ranges = P.getRanges();
|
||||
EmitRanges(o, Ranges, FM, SM, LangOpts, indent);
|
||||
EmitRanges(o, Ranges, FM, PP, indent);
|
||||
|
||||
// Output the call depth.
|
||||
Indent(o, indent) << "<key>depth</key>";
|
||||
|
@ -214,8 +217,8 @@ static void ReportEvent(raw_ostream &o, const PathDiagnosticEventPiece& P,
|
|||
|
||||
static void ReportPiece(raw_ostream &o,
|
||||
const PathDiagnosticPiece &P,
|
||||
const FIDMap& FM, const SourceManager &SM,
|
||||
const LangOptions &LangOpts,
|
||||
const FIDMap& FM,
|
||||
const Preprocessor &PP,
|
||||
unsigned indent,
|
||||
unsigned depth,
|
||||
bool includeControlFlow,
|
||||
|
@ -223,51 +226,54 @@ static void ReportPiece(raw_ostream &o,
|
|||
|
||||
static void ReportCall(raw_ostream &o,
|
||||
const PathDiagnosticCallPiece &P,
|
||||
const FIDMap& FM, const SourceManager &SM,
|
||||
const LangOptions &LangOpts,
|
||||
const FIDMap& FM,
|
||||
const Preprocessor &PP,
|
||||
unsigned indent,
|
||||
unsigned depth) {
|
||||
|
||||
if (auto callEnter = P.getCallEnterEvent())
|
||||
ReportPiece(o, *callEnter, FM, SM, LangOpts, indent, depth, true,
|
||||
P.isLastInMainSourceFile());
|
||||
ReportPiece(o, *callEnter, FM, PP, indent, depth,
|
||||
/*includeControlFlow*/ true, P.isLastInMainSourceFile());
|
||||
|
||||
|
||||
++depth;
|
||||
|
||||
if (auto callEnterWithinCaller = P.getCallEnterWithinCallerEvent())
|
||||
ReportPiece(o, *callEnterWithinCaller, FM, SM, LangOpts,
|
||||
indent, depth, true);
|
||||
ReportPiece(o, *callEnterWithinCaller, FM, PP, indent, depth,
|
||||
/*includeControlFlow*/ true);
|
||||
|
||||
for (PathPieces::const_iterator I = P.path.begin(), E = P.path.end();I!=E;++I)
|
||||
ReportPiece(o, **I, FM, SM, LangOpts, indent, depth, true);
|
||||
ReportPiece(o, **I, FM, PP, indent, depth,
|
||||
/*includeControlFlow*/ true);
|
||||
|
||||
--depth;
|
||||
|
||||
if (auto callExit = P.getCallExitEvent())
|
||||
ReportPiece(o, *callExit, FM, SM, LangOpts, indent, depth, true);
|
||||
ReportPiece(o, *callExit, FM, PP, indent, depth,
|
||||
/*includeControlFlow*/ true);
|
||||
}
|
||||
|
||||
static void ReportMacro(raw_ostream &o,
|
||||
const PathDiagnosticMacroPiece& P,
|
||||
const FIDMap& FM, const SourceManager &SM,
|
||||
const LangOptions &LangOpts,
|
||||
const FIDMap& FM,
|
||||
const Preprocessor &PP,
|
||||
unsigned indent,
|
||||
unsigned depth) {
|
||||
|
||||
for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end();
|
||||
I!=E; ++I) {
|
||||
ReportPiece(o, **I, FM, SM, LangOpts, indent, depth, false);
|
||||
ReportPiece(o, **I, FM, PP, indent, depth, /*includeControlFlow*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
static void ReportNote(raw_ostream &o, const PathDiagnosticNotePiece& P,
|
||||
const FIDMap& FM,
|
||||
const SourceManager &SM,
|
||||
const LangOptions &LangOpts,
|
||||
const Preprocessor &PP,
|
||||
unsigned indent,
|
||||
unsigned depth) {
|
||||
|
||||
const SourceManager &SM = PP.getSourceManager();
|
||||
|
||||
Indent(o, indent) << "<dict>\n";
|
||||
++indent;
|
||||
|
||||
|
@ -279,7 +285,7 @@ static void ReportNote(raw_ostream &o, const PathDiagnosticNotePiece& P,
|
|||
|
||||
// Output the ranges (if any).
|
||||
ArrayRef<SourceRange> Ranges = P.getRanges();
|
||||
EmitRanges(o, Ranges, FM, SM, LangOpts, indent);
|
||||
EmitRanges(o, Ranges, FM, PP, indent);
|
||||
|
||||
// Output the text.
|
||||
EmitMessage(o, P.getString(), indent);
|
||||
|
@ -290,15 +296,15 @@ static void ReportNote(raw_ostream &o, const PathDiagnosticNotePiece& P,
|
|||
}
|
||||
|
||||
static void ReportDiag(raw_ostream &o, const PathDiagnosticPiece& P,
|
||||
const FIDMap& FM, const SourceManager &SM,
|
||||
const LangOptions &LangOpts) {
|
||||
ReportPiece(o, P, FM, SM, LangOpts, 4, 0, true);
|
||||
const FIDMap& FM, const Preprocessor &PP) {
|
||||
ReportPiece(o, P, FM, PP, /*indent*/ 4, /*depth*/ 0,
|
||||
/*includeControlFlow*/ true);
|
||||
}
|
||||
|
||||
static void ReportPiece(raw_ostream &o,
|
||||
const PathDiagnosticPiece &P,
|
||||
const FIDMap& FM, const SourceManager &SM,
|
||||
const LangOptions &LangOpts,
|
||||
const FIDMap& FM,
|
||||
const Preprocessor &PP,
|
||||
unsigned indent,
|
||||
unsigned depth,
|
||||
bool includeControlFlow,
|
||||
|
@ -306,24 +312,21 @@ static void ReportPiece(raw_ostream &o,
|
|||
switch (P.getKind()) {
|
||||
case PathDiagnosticPiece::ControlFlow:
|
||||
if (includeControlFlow)
|
||||
ReportControlFlow(o, cast<PathDiagnosticControlFlowPiece>(P), FM, SM,
|
||||
LangOpts, indent);
|
||||
ReportControlFlow(o, cast<PathDiagnosticControlFlowPiece>(P), FM, PP,
|
||||
indent);
|
||||
break;
|
||||
case PathDiagnosticPiece::Call:
|
||||
ReportCall(o, cast<PathDiagnosticCallPiece>(P), FM, SM, LangOpts,
|
||||
indent, depth);
|
||||
ReportCall(o, cast<PathDiagnosticCallPiece>(P), FM, PP, indent, depth);
|
||||
break;
|
||||
case PathDiagnosticPiece::Event:
|
||||
ReportEvent(o, cast<PathDiagnosticEventPiece>(P), FM, SM, LangOpts,
|
||||
indent, depth, isKeyEvent);
|
||||
ReportEvent(o, cast<PathDiagnosticEventPiece>(P), FM, PP, indent, depth,
|
||||
isKeyEvent);
|
||||
break;
|
||||
case PathDiagnosticPiece::Macro:
|
||||
ReportMacro(o, cast<PathDiagnosticMacroPiece>(P), FM, SM, LangOpts,
|
||||
indent, depth);
|
||||
ReportMacro(o, cast<PathDiagnosticMacroPiece>(P), FM, PP, indent, depth);
|
||||
break;
|
||||
case PathDiagnosticPiece::Note:
|
||||
ReportNote(o, cast<PathDiagnosticNotePiece>(P), FM, SM, LangOpts,
|
||||
indent, depth);
|
||||
ReportNote(o, cast<PathDiagnosticNotePiece>(P), FM, PP, indent, depth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -368,17 +371,15 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
|
|||
// ranges of the diagnostics.
|
||||
FIDMap FM;
|
||||
SmallVector<FileID, 10> Fids;
|
||||
const SourceManager* SM = nullptr;
|
||||
const SourceManager& SM = PP.getSourceManager();
|
||||
const LangOptions &LangOpts = PP.getLangOpts();
|
||||
|
||||
if (!Diags.empty())
|
||||
SM = &Diags.front()->path.front()->getLocation().getManager();
|
||||
|
||||
auto AddPieceFID = [&FM, &Fids, SM](const PathDiagnosticPiece &Piece) {
|
||||
AddFID(FM, Fids, *SM, Piece.getLocation().asLocation());
|
||||
auto AddPieceFID = [&FM, &Fids, &SM](const PathDiagnosticPiece &Piece) {
|
||||
AddFID(FM, Fids, SM, Piece.getLocation().asLocation());
|
||||
ArrayRef<SourceRange> Ranges = Piece.getRanges();
|
||||
for (const SourceRange &Range : Ranges) {
|
||||
AddFID(FM, Fids, *SM, Range.getBegin());
|
||||
AddFID(FM, Fids, *SM, Range.getEnd());
|
||||
AddFID(FM, Fids, SM, Range.getBegin());
|
||||
AddFID(FM, Fids, SM, Range.getEnd());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -437,27 +438,27 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
|
|||
o << " <dict>\n";
|
||||
|
||||
const PathDiagnostic *D = *DI;
|
||||
const PathPieces &PP = D->path;
|
||||
const PathPieces &Path = D->path;
|
||||
|
||||
assert(std::is_partitioned(
|
||||
PP.begin(), PP.end(),
|
||||
Path.begin(), Path.end(),
|
||||
[](const std::shared_ptr<PathDiagnosticPiece> &E)
|
||||
{ return E->getKind() == PathDiagnosticPiece::Note; }) &&
|
||||
"PathDiagnostic is not partitioned so that notes precede the rest");
|
||||
|
||||
PathPieces::const_iterator FirstNonNote = std::partition_point(
|
||||
PP.begin(), PP.end(),
|
||||
Path.begin(), Path.end(),
|
||||
[](const std::shared_ptr<PathDiagnosticPiece> &E)
|
||||
{ return E->getKind() == PathDiagnosticPiece::Note; });
|
||||
|
||||
PathPieces::const_iterator I = PP.begin();
|
||||
PathPieces::const_iterator I = Path.begin();
|
||||
|
||||
if (FirstNonNote != PP.begin()) {
|
||||
if (FirstNonNote != Path.begin()) {
|
||||
o << " <key>notes</key>\n"
|
||||
" <array>\n";
|
||||
|
||||
for (; I != FirstNonNote; ++I)
|
||||
ReportDiag(o, **I, FM, *SM, LangOpts);
|
||||
ReportDiag(o, **I, FM, PP);
|
||||
|
||||
o << " </array>\n";
|
||||
}
|
||||
|
@ -466,8 +467,8 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
|
|||
|
||||
o << " <array>\n";
|
||||
|
||||
for (PathPieces::const_iterator E = PP.end(); I != E; ++I)
|
||||
ReportDiag(o, **I, FM, *SM, LangOpts);
|
||||
for (PathPieces::const_iterator E = Path.end(); I != E; ++I)
|
||||
ReportDiag(o, **I, FM, PP);
|
||||
|
||||
o << " </array>\n";
|
||||
|
||||
|
@ -484,12 +485,12 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
|
|||
o << " <!-- This hash is experimental and going to change! -->\n";
|
||||
o << " <key>issue_hash_content_of_line_in_context</key>";
|
||||
PathDiagnosticLocation UPDLoc = D->getUniqueingLoc();
|
||||
FullSourceLoc L(SM->getExpansionLoc(UPDLoc.isValid()
|
||||
FullSourceLoc L(SM.getExpansionLoc(UPDLoc.isValid()
|
||||
? UPDLoc.asLocation()
|
||||
: D->getLocation().asLocation()),
|
||||
*SM);
|
||||
SM);
|
||||
const Decl *DeclWithIssue = D->getDeclWithIssue();
|
||||
EmitString(o, GetIssueHash(*SM, L, D->getCheckName(), D->getBugType(),
|
||||
EmitString(o, GetIssueHash(SM, L, D->getCheckName(), D->getBugType(),
|
||||
DeclWithIssue, LangOpts))
|
||||
<< '\n';
|
||||
|
||||
|
@ -534,16 +535,16 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
|
|||
// site and the end of scope (leak report location).
|
||||
if (UPDLoc.isValid()) {
|
||||
FullSourceLoc UFunL(
|
||||
SM->getExpansionLoc(
|
||||
SM.getExpansionLoc(
|
||||
D->getUniqueingDecl()->getBody()->getBeginLoc()),
|
||||
*SM);
|
||||
SM);
|
||||
o << " <key>issue_hash_function_offset</key><string>"
|
||||
<< L.getExpansionLineNumber() - UFunL.getExpansionLineNumber()
|
||||
<< "</string>\n";
|
||||
|
||||
// Otherwise, use the location on which the bug is reported.
|
||||
} else {
|
||||
FullSourceLoc FunL(SM->getExpansionLoc(Body->getBeginLoc()), *SM);
|
||||
FullSourceLoc FunL(SM.getExpansionLoc(Body->getBeginLoc()), SM);
|
||||
o << " <key>issue_hash_function_offset</key><string>"
|
||||
<< L.getExpansionLineNumber() - FunL.getExpansionLineNumber()
|
||||
<< "</string>\n";
|
||||
|
@ -555,7 +556,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
|
|||
|
||||
// Output the location of the bug.
|
||||
o << " <key>location</key>\n";
|
||||
EmitLocation(o, *SM, D->getLocation().asLocation(), FM, 2);
|
||||
EmitLocation(o, SM, D->getLocation().asLocation(), FM, 2);
|
||||
|
||||
// Output the diagnostic to the sub-diagnostic client, if any.
|
||||
if (!filesMade->empty()) {
|
||||
|
@ -590,7 +591,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
|
|||
o << " <key>files</key>\n"
|
||||
" <array>\n";
|
||||
for (FileID FID : Fids)
|
||||
EmitString(o << " ", SM->getFileEntryForID(FID)->getName()) << '\n';
|
||||
EmitString(o << " ", SM.getFileEntryForID(FID)->getName()) << '\n';
|
||||
o << " </array>\n";
|
||||
|
||||
if (llvm::AreStatisticsEnabled() && SerializeStatistics) {
|
||||
|
|
Loading…
Reference in New Issue