@@ -1022,25 +1022,6 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10221022 preprocessor.inlineSuppressions (mSuppressions .nomsg );
10231023 preprocessor.removeComments ();
10241024
1025- if (!mSettings .buildDir .empty ()) {
1026- analyzerInformation.reset (new AnalyzerInformation);
1027- mLogger ->setAnalyzerInfo (analyzerInformation.get ());
1028- }
1029-
1030- if (analyzerInformation) {
1031- // Calculate hash so it can be compared with old hash / future hashes
1032- const std::size_t hash = calculateHash (preprocessor, file.spath ());
1033- std::list<ErrorMessage> errors;
1034- if (!analyzerInformation->analyzeFile (mSettings .buildDir , file.spath (), cfgname, file.fsFileId (), hash, errors, mSettings .debugainfo )) {
1035- while (!errors.empty ()) {
1036- mErrorLogger .reportErr (errors.front ());
1037- errors.pop_front ();
1038- }
1039- mLogger ->setAnalyzerInfo (nullptr );
1040- return mLogger ->exitcode (); // known results => no need to reanalyze file
1041- }
1042- }
1043-
10441025 // Get directives
10451026 std::list<Directive> directives;
10461027 preprocessor.createDirectives (directives);
@@ -1058,26 +1039,57 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
10581039 std::inserter (configDefines, configDefines.end ()),
10591040 getDefineName);
10601041
1061- preprocessor.setLoadCallback ([&](simplecpp::FileData &data) {
1062- // Do preprocessing on included file
1063- mLogger ->addRemarkComments (preprocessor.getRemarkComments (data.tokens ));
1064- preprocessor.inlineSuppressions (data.tokens , mSuppressions .nomsg );
1065- Preprocessor::removeComments (data.tokens );
1066- Preprocessor::createDirectives (data.tokens , directives);
1067- Preprocessor::simplifyPragmaAsm (data.tokens );
1068- // Discover new configurations from included file
1069- if (configurations.size () < maxConfigs)
1070- preprocessor.getConfigs (data.filename , data.tokens , configDefines, configurations);
1042+ // Keep track of all included files
1043+ std::set<std::string> includedFiles;
1044+
1045+ preprocessor.setLoadCallback ([&](simplecpp::FileData &data, bool loaded) {
1046+ includedFiles.insert (data.filename );
1047+ if (loaded) {
1048+ // Do preprocessing on included file
1049+ mLogger ->addRemarkComments (preprocessor.getRemarkComments (data.tokens ));
1050+ preprocessor.inlineSuppressions (data.tokens , mSuppressions .nomsg );
1051+ Preprocessor::removeComments (data.tokens );
1052+ Preprocessor::createDirectives (data.tokens , directives);
1053+ Preprocessor::simplifyPragmaAsm (data.tokens );
1054+ // Discover new configurations from included file
1055+ if (configurations.size () < maxConfigs)
1056+ preprocessor.getConfigs (data.filename , data.tokens , configDefines, configurations);
1057+ }
10711058 });
10721059
10731060 preprocessor.setPlatformInfo ();
10741061
1062+ if (!mSettings .buildDir .empty ()) {
1063+ analyzerInformation.reset (new AnalyzerInformation);
1064+ mLogger ->setAnalyzerInfo (analyzerInformation.get ());
1065+ }
1066+
1067+ if (analyzerInformation) {
1068+ // Load all included files to get correct hashes and suppressions
1069+ for (const std::string &filename : analyzerInformation->getIncludes (mSettings .buildDir , file.spath (), cfgname, file.fsFileId ()))
1070+ preprocessor.loadFile (files, filename);
1071+ // Calculate hash so it can be compared with old hash / future hashes
1072+ const std::size_t hash = calculateHash (preprocessor, file.spath ());
1073+ std::list<ErrorMessage> errors;
1074+ if (!analyzerInformation->analyzeFile (mSettings .buildDir , file.spath (), cfgname, file.fsFileId (), hash, errors, mSettings .debugainfo )) {
1075+ while (!errors.empty ()) {
1076+ mErrorLogger .reportErr (errors.front ());
1077+ errors.pop_front ();
1078+ }
1079+ mLogger ->setAnalyzerInfo (nullptr );
1080+ return mLogger ->exitcode (); // known results => no need to reanalyze file
1081+ }
1082+ // Clear included file list; we don't want to keep includes that have been removed from the source
1083+ // Any includes that are still present will be readded
1084+ includedFiles.clear ();
1085+ }
1086+
10751087 // Get configurations..
10761088 if (maxConfigs > 1 ) {
10771089 Timer::run (" Preprocessor::getConfigs" , mTimerResults , [&]() {
10781090 configurations = { " " };
10791091 preprocessor.getConfigs (configDefines, configurations);
1080- preprocessor.loadFiles (files);
1092+ preprocessor.loadAllIncludes (files);
10811093 });
10821094 } else {
10831095 configurations = { mSettings .userDefines };
@@ -1300,6 +1312,10 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
13001312 mLogger ->setPlistFilenames (std::move (files));
13011313 }
13021314
1315+ if (analyzerInformation) {
1316+ analyzerInformation->writeIncludes (includedFiles);
1317+ }
1318+
13031319 executeAddons (dumpFile, file);
13041320 } catch (const TerminateException &) {
13051321 // Analysis is terminated
0 commit comments