@@ -227,9 +227,10 @@ static void processFile(ArgumentsVector baseArgs, ArgumentsVector requestArgs) {
227227
228228/* Walk the reverse-include graph from a stale header up to compilation units,
229229 * using TypeCppInclude references in the reference table (populated by prior
230- * parsing or loaded from disk db). Reparse those CUs so they pick up the
231- * modified header content. */
232- static void reparseStaleHeaderIncluders (int headerFileNumber , ArgumentsVector baseArgs ) {
230+ * parsing or loaded from disk db). Collect CU file numbers into the provided
231+ * array, deduplicating against entries already present. */
232+ static int collectIncludersOfStaleHeader (int headerFileNumber ,
233+ int cuFileNumbers [], int cuCount , int maxCUs ) {
233234 FileItem * headerItem = getFileItemWithFileNumber (headerFileNumber );
234235 log_debug ("Looking for CUs that include stale header '%s'" , headerItem -> name );
235236
@@ -242,9 +243,6 @@ static void reparseStaleHeaderIncluders(int headerFileNumber, ArgumentsVector ba
242243 int walkCount = 1 ;
243244 filesToWalk [0 ] = headerFileNumber ;
244245
245- int cuFileNumbers [MAX_CUS_TO_REPARSE ];
246- int cuCount = 0 ;
247-
248246 for (int i = 0 ; i < walkCount ; i ++ ) {
249247 ReferenceableItem searchItem = makeReferenceableItem (
250248 LINK_NAME_INCLUDE_REFS , TypeCppInclude , StorageExtern ,
@@ -272,27 +270,30 @@ static void reparseStaleHeaderIncluders(int headerFileNumber, ArgumentsVector ba
272270 filesToWalk [walkCount ++ ] = includerFileNum ;
273271
274272 FileItem * includer = getFileItemWithFileNumber (includerFileNum );
275- if (isCompilationUnit (includer -> name ) && cuCount < MAX_CUS_TO_REPARSE ) {
276- cuFileNumbers [cuCount ++ ] = includerFileNum ;
277- log_debug ("CU '%s' (transitively) includes stale header '%s'" ,
278- includer -> name , headerItem -> name );
273+ if (isCompilationUnit (includer -> name )) {
274+ /* Deduplicate against CUs already collected (from other stale headers) */
275+ bool alreadyCollected = false;
276+ for (int j = 0 ; j < cuCount ; j ++ ) {
277+ if (cuFileNumbers [j ] == includerFileNum ) {
278+ alreadyCollected = true;
279+ break ;
280+ }
281+ }
282+ if (!alreadyCollected && cuCount < maxCUs ) {
283+ cuFileNumbers [cuCount ++ ] = includerFileNum ;
284+ log_debug ("CU '%s' (transitively) includes stale header '%s'" ,
285+ includer -> name , headerItem -> name );
286+ }
279287 }
280288 }
281289 }
282290
283- if (cuCount == 0 ) {
291+ if (cuCount == 0 )
284292 log_debug ("No CUs found that include '%s'" , headerItem -> name );
285- return ;
286- }
287293
288294 removeReferenceableItemsForFile (headerFileNumber );
289295
290- for (int i = 0 ; i < cuCount ; i ++ ) {
291- log_debug ("Reparsing CU file number %d because of stale header '%s'" ,
292- cuFileNumbers [i ], headerItem -> name );
293- reparseStaleFile (cuFileNumbers [i ], baseArgs );
294- getFileItemWithFileNumber (cuFileNumbers [i ])-> needsBrowsingStackRefresh = true;
295- }
296+ return cuCount ;
296297}
297298
298299static int countStalePreloadedFiles (void ) {
@@ -310,10 +311,16 @@ static void reparseStalePreloadedFiles(ArgumentsVector baseArgs) {
310311 return ;
311312
312313 log_info ("Refreshing %d stale preloaded file(s)" , staleCount );
313- int reparsed = 0 ;
314+
315+ /* Reset progress state so values aren't suppressed by the static
316+ * lastprogress left over from previous requests (e.g. cold start). */
317+ if (options .xref2 )
318+ writeRelativeProgress (0 );
314319
315320 /* Pass 1: Reparse stale CUs directly. This also refreshes their
316- * TypeCppInclude references, which Pass 2 depends on. */
321+ * TypeCppInclude references, which Pass 2 depends on.
322+ * No progress reporting here — Pass 1 is fast (only directly
323+ * preloaded CUs, typically 1-2 files). */
317324 for (int i = 0 ; i != -1 ; i = getNextExistingEditorBufferIndex (i + 1 )) {
318325 for (EditorBufferList * l = getEditorBufferListElementAt (i ); l != NULL ; l = l -> next ) {
319326 int fileNumber = l -> buffer -> fileNumber ;
@@ -325,36 +332,46 @@ static void reparseStalePreloadedFiles(ArgumentsVector baseArgs) {
325332 if (buffer != NULL )
326333 fileItem -> lastParsedMtime = buffer -> modificationTime ;
327334 fileItem -> needsBrowsingStackRefresh = true;
328- reparsed ++ ;
329- if (options .xref2 )
330- writeRelativeProgress ((100 * reparsed ) / staleCount );
331335 }
332336 }
333337 }
334338
335339 /* Pass 2: For stale headers, find CUs that include them and reparse.
336340 * Must come after Pass 1: Pass 1 reparses stale CUs, refreshing their
337341 * TypeCppInclude references. Pass 2 queries those references to find
338- * which CUs include the stale header (transitively). */
342+ * which CUs include the stale header (transitively).
343+ *
344+ * First collect all CUs across all stale headers (deduplicated),
345+ * then reparse with per-CU progress reporting. */
346+ int cuFileNumbers [MAX_CUS_TO_REPARSE ];
347+ int cuCount = 0 ;
348+
339349 for (int i = 0 ; i != -1 ; i = getNextExistingEditorBufferIndex (i + 1 )) {
340350 for (EditorBufferList * l = getEditorBufferListElementAt (i ); l != NULL ; l = l -> next ) {
341351 int fileNumber = l -> buffer -> fileNumber ;
342352 FileItem * fileItem = getFileItemWithFileNumber (fileNumber );
343353 if (fileNumberIsStale (fileNumber ) && !isCompilationUnit (fileItem -> name )) {
344- log_debug ( "Reparsing includers of stale header '%s'" , fileItem -> name );
345- reparseStaleHeaderIncluders ( fileNumber , baseArgs );
354+ cuCount = collectIncludersOfStaleHeader ( fileNumber , cuFileNumbers , cuCount ,
355+ MAX_CUS_TO_REPARSE );
346356 EditorBuffer * buffer = getOpenedAndLoadedEditorBuffer (fileItem -> name );
347357 if (buffer != NULL )
348358 fileItem -> lastParsedMtime = buffer -> modificationTime ;
349359 fileItem -> needsBrowsingStackRefresh = true;
350- reparsed ++ ;
351- if (options .xref2 )
352- writeRelativeProgress ((100 * reparsed ) / staleCount );
353360 }
354361 }
355362 }
356- if (options .xref2 )
357- writeRelativeProgress (100 );
363+
364+ if (cuCount > 0 ) {
365+ log_info ("Reparsing %d CU(s) for stale header includers" , cuCount );
366+ for (int i = 0 ; i < cuCount ; i ++ ) {
367+ reparseStaleFile (cuFileNumbers [i ], baseArgs );
368+ getFileItemWithFileNumber (cuFileNumbers [i ])-> needsBrowsingStackRefresh = true;
369+ if (options .xref2 )
370+ writeRelativeProgress ((100 * (i + 1 )) / cuCount );
371+ }
372+ }
373+ /* No trailing writeRelativeProgress(100) — the loop's last
374+ * iteration already outputs 100 and closes the progress range. */
358375}
359376
360377static bool fileNeedsParsing (FileItem * fileItem ) {
@@ -387,8 +404,6 @@ static void parseDiscoveredCompilationUnits(ArgumentsVector baseArgs) {
387404 fileItem -> isScheduled = false;
388405 }
389406 }
390- if (options .xref2 )
391- writeRelativeProgress (100 );
392407 log_info ("Startup: parsed %d compilation units" , parsed );
393408}
394409
0 commit comments