@@ -1352,6 +1352,83 @@ void CppCheck::getErrorMessages()
13521352 Preprocessor::getErrorMessages (this , &s);
13531353}
13541354
1355+ void CppCheck::analyseClangTidy (const ImportProject::FileSettings &fileSettings )
1356+ {
1357+ std::string allIncludes = " " ;
1358+ std::string allDefines = " -D" +fileSettings.defines ;
1359+ for (const std::string &inc : fileSettings.includePaths ) {
1360+ allIncludes = allIncludes + " -I\" " + inc + " \" " ;
1361+ }
1362+
1363+ std::string::size_type pos = 0u ;
1364+ while ((pos = allDefines.find (" ;" , pos)) != std::string::npos)
1365+ {
1366+ allDefines.replace (pos, 1 , " -D" );
1367+ pos += 3 ;
1368+ }
1369+
1370+ const std::string cmd = " clang-tidy -quiet -checks=*,-clang-analyzer-*,-llvm* \" " + fileSettings.filename + " \" -- " + allIncludes + allDefines;
1371+ std::pair<bool , std::string> result = executeCommand (cmd);
1372+ if (!result.first ) {
1373+ std::cerr << " Failed to execute '" + cmd + " '" << std::endl;
1374+ return ;
1375+ }
1376+
1377+ // parse output and create error messages
1378+ std::istringstream istr (result.second );
1379+ std::string line;
1380+
1381+ if (!mSettings .buildDir .empty ())
1382+ {
1383+ const std::string analyzerInfoFile = AnalyzerInformation::getAnalyzerInfoFile (mSettings .buildDir , fileSettings.filename , " " );
1384+ std::ofstream fcmd (analyzerInfoFile + " .clang-tidy-cmd" );
1385+ fcmd << istr.str ();
1386+ }
1387+
1388+ while (std::getline (istr, line)) {
1389+ if (line.find (" error" ) == std::string::npos && line.find (" warning" ) == std::string::npos)
1390+ continue ;
1391+
1392+ std::size_t endColumnPos = line.find (" : error:" );
1393+ if (endColumnPos == std::string::npos) {
1394+ endColumnPos = line.find (" : warning:" );
1395+ }
1396+
1397+ const std::size_t endLinePos = line.rfind (" :" , endColumnPos-1 );
1398+ const std::size_t endNamePos = line.rfind (" :" , endLinePos - 1 );
1399+ const std::size_t endMsgTypePos = line.find (' :' , endColumnPos + 2 );
1400+ const std::size_t endErrorPos = line.rfind (' [' , std::string::npos);
1401+
1402+ const std::string lineNumString = line.substr (endNamePos + 1 , endLinePos - endNamePos - 1 );
1403+ const std::string columnNumString = line.substr (endLinePos + 1 , endColumnPos - endLinePos - 1 );
1404+ const std::string errorTypeString = line.substr (endColumnPos + 1 , endMsgTypePos - endColumnPos - 1 );
1405+ const std::string messageString = line.substr (endMsgTypePos + 1 , endErrorPos - endMsgTypePos - 1 );
1406+ const std::string errorString = line.substr (endErrorPos, line.length ());
1407+
1408+ std::string fixedpath = Path::simplifyPath (line.substr (0 , endNamePos));
1409+ const int64_t lineNumber = std::atol (lineNumString.c_str ());
1410+ const int64_t column = std::atol (columnNumString.c_str ());
1411+ fixedpath = Path::toNativeSeparators (fixedpath);
1412+
1413+ ErrorLogger::ErrorMessage errmsg;
1414+ errmsg.callStack .emplace_back (ErrorLogger::ErrorMessage::FileLocation (fixedpath, lineNumber, column));
1415+
1416+ errmsg.id = " clang-tidy-" + errorString.substr (1 , errorString.length () - 2 );
1417+ if (errmsg.id .find (" performance" ) != std::string::npos)
1418+ errmsg.severity = Severity::SeverityType::performance;
1419+ else if (errmsg.id .find (" portability" ) != std::string::npos)
1420+ errmsg.severity = Severity::SeverityType::portability;
1421+ else if (errmsg.id .find (" cert" ) != std::string::npos || errmsg.id .find (" misc" ) != std::string::npos || errmsg.id .find (" unused" ) != std::string::npos)
1422+ errmsg.severity = Severity::SeverityType::warning;
1423+ else
1424+ errmsg.severity = Severity::SeverityType::style;
1425+
1426+ errmsg.file0 = fixedpath;
1427+ errmsg.setmsg (messageString);
1428+ reportErr (errmsg);
1429+ }
1430+ }
1431+
13551432bool CppCheck::analyseWholeProgram ()
13561433{
13571434 bool errors = false ;
0 commit comments