@@ -1026,25 +1026,6 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10261026 preprocessor.inlineSuppressions (mSuppressions .nomsg );
10271027 preprocessor.removeComments ();
10281028
1029- if (!mSettings .buildDir .empty ()) {
1030- analyzerInformation.reset (new AnalyzerInformation);
1031- mLogger ->setAnalyzerInfo (analyzerInformation.get ());
1032- }
1033-
1034- if (analyzerInformation) {
1035- // Calculate hash so it can be compared with old hash / future hashes
1036- const std::size_t hash = calculateHash (preprocessor, file.spath ());
1037- std::list<ErrorMessage> errors;
1038- if (!analyzerInformation->analyzeFile (mSettings .buildDir , file.spath (), cfgname, file.fsFileId (), hash, errors, mSettings .debugainfo )) {
1039- while (!errors.empty ()) {
1040- mErrorLogger .reportErr (errors.front ());
1041- errors.pop_front ();
1042- }
1043- mLogger ->setAnalyzerInfo (nullptr );
1044- return mLogger ->exitcode (); // known results => no need to reanalyze file
1045- }
1046- }
1047-
10481029 // Get directives
10491030 std::list<Directive> directives;
10501031 preprocessor.createDirectives (directives);
@@ -1062,7 +1043,11 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10621043 std::inserter (configDefines, configDefines.end ()),
10631044 getDefineName);
10641045
1046+ // Keep track of all included files
1047+ std::set<std::string> includedFiles;
1048+
10651049 preprocessor.setLoadCallback ([&](simplecpp::FileData &data, bool loaded) {
1050+ includedFiles.insert (data.filename );
10661051 if (loaded) {
10671052 // Do preprocessing on included file
10681053 mLogger ->addRemarkComments (preprocessor.getRemarkComments (data.tokens ));
@@ -1078,12 +1063,37 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10781063
10791064 preprocessor.setPlatformInfo ();
10801065
1066+ if (!mSettings .buildDir .empty ()) {
1067+ analyzerInformation.reset (new AnalyzerInformation);
1068+ mLogger ->setAnalyzerInfo (analyzerInformation.get ());
1069+ }
1070+
1071+ if (analyzerInformation) {
1072+ // Load all included files to get correct hashes and suppressions
1073+ for (const std::string &filename : analyzerInformation->getIncludes (mSettings .buildDir , file.spath (), cfgname, file.fsFileId ()))
1074+ preprocessor.loadFile (files, filename);
1075+ // Calculate hash so it can be compared with old hash / future hashes
1076+ const std::size_t hash = calculateHash (preprocessor, file.spath ());
1077+ std::list<ErrorMessage> errors;
1078+ if (!analyzerInformation->analyzeFile (mSettings .buildDir , file.spath (), cfgname, file.fsFileId (), hash, errors, mSettings .debugainfo )) {
1079+ while (!errors.empty ()) {
1080+ mErrorLogger .reportErr (errors.front ());
1081+ errors.pop_front ();
1082+ }
1083+ mLogger ->setAnalyzerInfo (nullptr );
1084+ return mLogger ->exitcode (); // known results => no need to reanalyze file
1085+ }
1086+ // Clear included file list; we don't want to keep includes that have been removed from the source
1087+ // Any includes that are still present will be readded
1088+ includedFiles.clear ();
1089+ }
1090+
10811091 // Get configurations..
10821092 if (maxConfigs > 1 ) {
10831093 Timer::run (" Preprocessor::getConfigs" , mTimerResults , [&]() {
10841094 configurations = { " " };
10851095 preprocessor.getConfigs (configDefines, configurations);
1086- preprocessor.loadFiles (files);
1096+ preprocessor.loadAllIncludes (files);
10871097 });
10881098 } else {
10891099 configurations = { mSettings .userDefines };
@@ -1306,6 +1316,10 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
13061316 mLogger ->setPlistFilenames (std::move (files));
13071317 }
13081318
1319+ if (analyzerInformation) {
1320+ analyzerInformation->writeIncludes (includedFiles);
1321+ }
1322+
13091323 executeAddons (dumpFile, file);
13101324 } catch (const TerminateException &) {
13111325 // Analysis is terminated
0 commit comments