@@ -239,24 +239,45 @@ void InitTimers();
239239 }
240240 }
241241
242- static SourceLocation getAttachedLoopLoc (const FunctionDecl* FD ,
243- SourceLocation pragmaLoc,
244- SourceManager& SM ) {
245- const auto * body = cast<CompoundStmt>(FD ->getBody ());
242+ class AttachedLoopStmtFinder
243+ : public RecursiveASTVisitor<AttachedLoopStmtFinder> {
244+ SourceLocation m_PragmaLoc;
245+ SourceManager& m_SM;
246+ Stmt* m_AttachedStmt = nullptr ;
247+ SourceLocation m_AttachedLoopLoc;
246248
247- const Stmt* nextStmt = nullptr ;
248- for (const Stmt* S : body->body ()) {
249+ public:
250+ AttachedLoopStmtFinder (SourceLocation pragmaLoc, SourceManager& SM )
251+ : m_PragmaLoc(pragmaLoc), m_SM(SM ) {}
252+
253+ bool VisitStmt (Stmt* S) {
249254 SourceLocation beginLoc = S->getBeginLoc ();
250- if (!SM .isBeforeInTranslationUnit (pragmaLoc, beginLoc))
251- continue ;
252- nextStmt = S;
253- break ;
255+ if (!beginLoc.isValid () ||
256+ !m_SM.isBeforeInTranslationUnit (m_PragmaLoc, beginLoc))
257+ return true ;
258+
259+ if (!m_AttachedStmt || m_SM.isBeforeInTranslationUnit (
260+ beginLoc, m_AttachedStmt->getBeginLoc ())) {
261+ m_AttachedStmt = S;
262+ m_AttachedLoopLoc = {};
263+ if (isa<ForStmt>(S) || isa<WhileStmt>(S) || isa<DoStmt>(S))
264+ m_AttachedLoopLoc = beginLoc;
265+ }
266+ return true ;
267+ }
268+
269+ [[nodiscard]] SourceLocation getAttachedLoopLoc () const {
270+ return m_AttachedLoopLoc;
254271 }
272+ };
255273
256- if (nextStmt && (isa<ForStmt>(nextStmt) || isa<WhileStmt>(nextStmt) ||
257- isa<DoStmt>(nextStmt)))
258- return nextStmt->getBeginLoc ();
259- return {};
274+ static SourceLocation getAttachedLoopLoc (const FunctionDecl* FD ,
275+ SourceLocation pragmaLoc,
276+ SourceManager& SM ) {
277+ Stmt* body = FD ->getBody ();
278+ AttachedLoopStmtFinder finder (pragmaLoc, SM );
279+ finder.TraverseStmt (body);
280+ return finder.getAttachedLoopLoc ();
260281 }
261282
262283 static void addCladLoopCheckpoints (ASTContext& C, DiffRequest& request) {
0 commit comments