static SourceLocation getValidSourceLocation(const Stmt* S, LocationOrAnalysisDeclContext LAC, bool UseEnd = false) { SourceLocation L = UseEnd ? S->getLocEnd() : S->getLocStart(); assert(!LAC.isNull() && "A valid LocationContext or AnalysisDeclContext should " "be passed to PathDiagnosticLocation upon creation."); // S might be a temporary statement that does not have a location in the // source code, so find an enclosing statement and use its location. if (!L.isValid()) { AnalysisDeclContext *ADC; if (LAC.is<const LocationContext*>()) ADC = LAC.get<const LocationContext*>()->getAnalysisDeclContext(); else ADC = LAC.get<AnalysisDeclContext*>(); ParentMap &PM = ADC->getParentMap(); const Stmt *Parent = S; do { Parent = PM.getParent(Parent); // In rare cases, we have implicit top-level expressions, // such as arguments for implicit member initializers. // In this case, fall back to the start of the body (even if we were // asked for the statement end location). if (!Parent) { const Stmt *Body = ADC->getBody(); if (Body) L = Body->getLocStart(); else L = ADC->getDecl()->getLocEnd(); break; } L = UseEnd ? Parent->getLocEnd() : Parent->getLocStart(); } while (!L.isValid()); } return L; }
static SourceLocation getValidSourceLocation(const Stmt* S, LocationOrAnalysisDeclContext LAC) { SourceLocation L = S->getLocStart(); assert(!LAC.isNull() && "A valid LocationContext or AnalysisDeclContext should " "be passed to PathDiagnosticLocation upon creation."); // S might be a temporary statement that does not have a location in the // source code, so find an enclosing statement and use it's location. if (!L.isValid()) { ParentMap *PM = 0; if (LAC.is<const LocationContext*>()) PM = &LAC.get<const LocationContext*>()->getParentMap(); else PM = &LAC.get<AnalysisDeclContext*>()->getParentMap(); while (!L.isValid()) { S = PM->getParent(S); L = S->getLocStart(); } } return L; }