Obtaining translation unit file names from plugins

I've got a PluginASTAction which runs and produces some extra diagnostics which are stored in an SQLite database, together with file identification information. If the user changes the file in such a way that the plugin does not report any diagnostics, the reporting tool cannot tell this scenario from the case where the plugin has not run at all on the changed file. So I would like to gather all file names which contribute to the translation unit and mark them as processed in the database. I could transverse the entire AST to collect all file names, but surely there is a simpler way to do it?

Assuming you care only about the source files that are directly read by Clang when compiling the TU and not files referenced by preprocessing line control directives, a loop like the following will work:

     const clang::SourceManager &source_manager = ...
     clang::SourceManager::fileinfo_iterator fi_iter;
     for (fi_iter = source_manager.fileinfo_begin();
          fi_iter != source_manager.fileinfo_end();
          ++fi_iter)
     {
         const clang::SrcMgr::ContentCache *content_cache = fi_iter->second;
         const clang::FileEntry *file_entry =
             content_cache->ContentsEntry;
         if (!file_entry)
             file_entry = content_cache->OrigEntry;
         if (!file_entry)
             continue;
         const char *file_name = file_entry->getName();
         // Do something with file_name and/or file_entry
     }

If you are loading a .ast file (typically a pre-compiled header), then add the following loops before the loop above. This is necessary to coerce the source manager into fully populating its FileInfos map. Without this, only a subset of all source files contributing to the TU will be enumerated.

     for (unsigned i = 0; i < source_manager.local_sloc_entry_size(); ++i) {
         source_manager.getLocalSLocEntry(i);
     }
     for (unsigned i = 0; i < source_manager.loaded_sloc_entry_size(); ++i) {
         source_manager.getLoadedSLocEntry(i);
     }

Tom.

Thanks, this works. I didn't realize at first that the CompilerInstance and ASTContext have different SourceManagers, and only the latter contains the file list.