static void ReportCall(raw_ostream &o, const PathDiagnosticCallPiece &P, const FIDMap& FM, const SourceManager &SM, const LangOptions &LangOpts, unsigned indent, unsigned depth) { IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnter = P.getCallEnterEvent(); if (callEnter) ReportPiece(o, *callEnter, FM, SM, LangOpts, indent, depth, true, P.isLastInMainSourceFile()); IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnterWithinCaller = P.getCallEnterWithinCallerEvent(); ++depth; if (callEnterWithinCaller) ReportPiece(o, *callEnterWithinCaller, FM, SM, LangOpts, indent, depth, 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); --depth; IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit = P.getCallExitEvent(); if (callExit) ReportPiece(o, *callExit, FM, SM, LangOpts, indent, depth, true); }
void PathPieces::flattenTo(PathPieces &Primary, PathPieces &Current, bool ShouldFlattenMacros) const { for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) { PathDiagnosticPiece *Piece = I->getPtr(); switch (Piece->getKind()) { case PathDiagnosticPiece::Call: { PathDiagnosticCallPiece *Call = cast<PathDiagnosticCallPiece>(Piece); IntrusiveRefCntPtr<PathDiagnosticEventPiece> CallEnter = Call->getCallEnterEvent(); if (CallEnter) Current.push_back(CallEnter); Call->path.flattenTo(Primary, Primary, ShouldFlattenMacros); IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit = Call->getCallExitEvent(); if (callExit) Current.push_back(callExit); break; } case PathDiagnosticPiece::Macro: { PathDiagnosticMacroPiece *Macro = cast<PathDiagnosticMacroPiece>(Piece); if (ShouldFlattenMacros) { Macro->subPieces.flattenTo(Primary, Primary, ShouldFlattenMacros); } else { Current.push_back(Piece); PathPieces NewPath; Macro->subPieces.flattenTo(Primary, NewPath, ShouldFlattenMacros); // FIXME: This probably shouldn't mutate the original path piece. Macro->subPieces = NewPath; } break; } case PathDiagnosticPiece::Event: case PathDiagnosticPiece::ControlFlow: Current.push_back(Piece); break; } } }