55 #include <unordered_map> 
   56 #include <unordered_set> 
   60 #include <simplecpp.h> 
   67     struct VarIdScopeInfo {
 
   68         VarIdScopeInfo() = 
default;
 
   69         VarIdScopeInfo(
bool isExecutable, 
bool isStructInit, 
bool isEnum, 
nonneg int startVarid)
 
   70             : isExecutable(isExecutable), isStructInit(isStructInit), isEnum(isEnum), startVarid(startVarid) {}
 
   72         const bool isExecutable{};
 
   73         const bool isStructInit{};
 
   75         const nonneg int startVarid{};
 
   82     if (!tok || tok->
str() != 
"{")
 
   92         defStart = defStart->next();
 
   93     if (defStart && defStart->str() == 
"{")
 
   94         tok = defStart->link()->next();
 
  101     if (tok->
str() == 
"(")
 
  103     if (tok->
str() != 
")")
 
  109         while (tok && tok->
str() == 
"[" && tok->
link()) {
 
  110             if (
endsWith.find(tok->
str()) != std::string::npos)
 
  112             tok = tok->
link()->next();
 
  114         return (tok && 
endsWith.find(tok->
str()) != std::string::npos) ? tok : 
nullptr;
 
  116     if (tok->
isCpp() && tok->
str() == 
")") {
 
  118         while (
Token::Match(tok, 
"const|noexcept|override|final|volatile|mutable|&|&& !!(") ||
 
  121         if (tok && tok->
str() == 
")")
 
  123         while (tok && tok->
str() == 
"[")
 
  124             tok = tok->
link()->next();
 
  141         return (tok && 
endsWith.find(tok->
str()) != std::string::npos) ? tok : 
nullptr;
 
  154     while (tok2 && !
Token::Match(tok2, 
"class|struct|union|enum|{|}|;"))
 
  164     mErrorLogger(errorLogger),
 
  181     const std::map<std::string, int>::const_iterator it = 
mTypeSize.find(type);
 
  187         return podtype->
size;
 
  194     if (!type || type->
str().empty())
 
  200     const std::map<std::string, int>::const_iterator it = 
mTypeSize.find(type->
str());
 
  206         return podtype->
size;
 
  209         if (type->
str() == 
"double")
 
  211         if (type->
str() == 
"long")
 
  223     Token * tok = tokPtr;
 
  227         if (end->
str() == 
"[") {
 
  230             end = end->
link()->next();
 
  231         } 
else if (end->
str() == 
",") {
 
  241                 end = (end)?end->
next():
nullptr;
 
  245         } 
else if (end->
str() == 
"(") {
 
  261                 tokPtr = end->
link();
 
  275             } 
else if (end->
str() == 
">") { 
 
  280                     while (end && end->
str() != 
"{")
 
  283                         tokPtr = end->
link();
 
  293                      (!
Token::Match(tok->
previous(), 
"return|new|const|friend|public|private|protected|throw|extern") &&
 
  304                             if (tok->
strAt(-2) == 
"typedef" &&
 
  306                                 typeDef->
strAt(3) != 
"{") {
 
  320                             return tok->
next()->
str() != 
";";
 
  322                             return tok->
next()->
str() != 
";";
 
  343     std::ostringstream str;
 
  344     const Token *tok1 = tok;
 
  347         if (level == 0 && tok->
str() == 
";")
 
  349         if (tok->
str() == 
"{")
 
  351         else if (tok->
str() == 
"}") {
 
  366                 "Failed to parse \'" + str.str() + 
"\'. The checking continues anyway.");
 
  371     Token *tok = 
nullptr;
 
  374     while (typeDef->
next()) {
 
  375         if (typeDef->
next()->
str() == 
";") {
 
  379         if (typeDef->
next()->
str() == 
"{")
 
  381         else if (typeDef->
next()->
str() == 
"}")
 
  399         std::string className;
 
  400         const Token* bodyEnd{};  
 
  401         const Token* bodyEnd2{}; 
 
  403         std::set<std::string> recordTypes;
 
  410     std::set<std::string> qualifiers;
 
  413         qualifiers.insert(tok->
next()->
str());
 
  429     if (tok1->
str() == 
":") {
 
  431         while (tok1 && tok1->
str() != 
"{")
 
  446                 name = 
"Unnamed" + std::to_string((*unnamedCount)++);
 
  463     for (
const std::string &qualifier : qualifiers) {
 
  491             tok2 = tok2->
tokAt(5);
 
  501             if (tok2->
next()->
str() == 
"(")
 
  512                     tok2 = tok2->
tokAt(2);
 
  517                 if (tok2->
str() == 
"(" &&
 
  518                     tok2->
link()->next() &&
 
  519                     tok2->
link()->next()->str() == 
"(") {
 
  522                     if (tok2->
next()->
str() == 
"(")
 
  532                     if (tok2->
next()->
str() == 
"(")
 
  553         if ((
Token::Match(tok, 
"[;{}] using %name% :: %name% ::|;") && !tok->tokAt(2)->isKeyword()) ||
 
  554             (
Token::Match(tok, 
"[;{}] using :: %name% :: %name% ::|;") && !tok->tokAt(3)->isKeyword())) {
 
  557                 endtok = endtok->
next();
 
  559                 endtok = endtok->
tokAt(2);
 
  560             if (endtok && endtok->
str() == 
";") {
 
  575         if (tok->str() == 
"typedef") {
 
  576             bool doSimplify = !
Token::Match(tok->previous(), 
";|{|}|:|public:|private:|protected:");
 
  579             bool haveStart = 
false;
 
  600                     start = start->
next();
 
  611     class TypedefSimplifier {
 
  613         Token* mTypedefToken;  
 
  614         Token* mEndToken{
nullptr};  
 
  615         std::pair<Token*, Token*> mRangeType;
 
  616         std::pair<Token*, Token*> mRangeTypeQualifiers;
 
  617         std::pair<Token*, Token*> mRangeAfterVar;
 
  618         Token* mNameToken{
nullptr};
 
  620         bool mReplaceFailed = 
false;
 
  624         explicit TypedefSimplifier(
Token* typedefToken) : mTypedefToken(typedefToken) {
 
  627                 start = start->
next();
 
  630             if (
Token::Match(start, 
"const| enum|struct|union|class %name%| {")) {
 
  634                 Token* nameToken = rangeBefore.second->
link()->next();
 
  636                     nameToken = nameToken->
next();
 
  637                 const std::pair<Token*, Token*> rangeQualifiers(rangeBefore.second->link()->next(), nameToken);
 
  640                     if (
Token::Match(rangeBefore.second->previous(), 
"enum|struct|union|class {"))
 
  641                         rangeBefore.second->previous()->insertToken(nameToken->
str());
 
  642                     mRangeType = rangeBefore;
 
  643                     mRangeTypeQualifiers = rangeQualifiers;
 
  649                     mNameToken = nameToken;
 
  650                     mEndToken = nameToken->
next();
 
  655             for (
Token* type = start; 
Token::Match(type, 
"%name%|*|&|&&"); type = type->next()) {
 
  656                 if (type != start && 
Token::Match(type, 
"%name% ;") && !type->isStandardType()) {
 
  657                     mRangeType.first = start;
 
  658                     mRangeType.second = type;
 
  660                     mEndToken = mNameToken->
next();
 
  669                     mRangeType.first = start;
 
  670                     mRangeType.second = type;
 
  672                     mEndToken = end->
next();
 
  673                     mRangeAfterVar.first = mNameToken->
next();
 
  674                     mRangeAfterVar.second = mEndToken;
 
  680                     mRangeType.first = start;
 
  681                     mRangeType.second = mNameToken;
 
  682                     mRangeAfterVar.first = mNameToken->
next();
 
  683                     mRangeAfterVar.second = mEndToken;
 
  689                     mRangeType.first = start;
 
  690                     mRangeType.second = type;
 
  691                     mRangeAfterVar.first = mNameToken->
next();
 
  692                     mRangeAfterVar.second = mEndToken;
 
  698                 printTypedef(typedefToken);
 
  702         const Token* getTypedefToken()
 const {
 
  703             return mTypedefToken;
 
  706         bool isUsed()
 const {
 
  710         bool isInvalidConstFunctionType(
const std::map<std::string, TypedefSimplifier>& m)
 const {
 
  711             if (!
Token::Match(mTypedefToken, 
"typedef const %name% %name% ;"))
 
  713             const auto it = m.find(mTypedefToken->
strAt(2));
 
  723         bool replaceFailed()
 const {
 
  724             return mReplaceFailed;
 
  727         bool isStructEtc()
 const {
 
  728             return mRangeType.second && mRangeType.second->str() == 
"{";
 
  731         std::string name()
 const {
 
  732             return mNameToken ? mNameToken->str() : 
"";
 
  736             if (tok == mNameToken)
 
  743                 bool pointerType = 
false;
 
  744                 for (
const Token* type = mRangeType.first; type != mRangeType.second; type = type->
next()) {
 
  745                     if (type->str() == 
"*" || type->str() == 
"&") {
 
  750                 for (
const Token* type = mRangeTypeQualifiers.first; type != mRangeTypeQualifiers.second; type = type->
next()) {
 
  751                     if (type->str() == 
"*" || type->str() == 
"&") {
 
  759                     Token* tok2 = insertTokens(tok, mRangeType);
 
  760                     insertTokens(tok2, mRangeTypeQualifiers);
 
  766             const bool isFunctionPointer = 
Token::Match(mNameToken, 
"%name% )");
 
  767             if (isFunctionPointer && isCast(tok->
previous())) {
 
  769                 insertTokens(tok, std::pair<Token*, Token*>(mRangeType.first, mNameToken->linkAt(1)));
 
  777                 tok->
str(mRangeType.second->previous()->str());
 
  782                 if (
Token::Match(mRangeType.first, 
"const| struct|class %name% %name% ;")) {
 
  784                     tok->
str(mRangeType.second->previous()->str());
 
  786                     mReplaceFailed = 
true;
 
  793                 bool pointerType = 
false;
 
  794                 for (
const Token* type = mRangeType.first; type != mRangeType.second; type = type->
next()) {
 
  795                     if (type->str() == 
"*") {
 
  812                 for (
const Token* type = mRangeType.first; type != mRangeType.second; type = type->
next()) {
 
  813                     if (type->str() == kw) {
 
  821                     mReplaceFailed = 
true;
 
  827             auto rangeType = mRangeType;
 
  829                 while (
Token::Match(rangeType.first, 
"const|class|struct|union"))
 
  830                     rangeType.first = rangeType.first->next();
 
  833             Token* 
const tok2 = insertTokens(tok, rangeType);
 
  834             Token* 
const tok3 = insertTokens(tok2, mRangeTypeQualifiers);
 
  840                 after = after->
next();
 
  843                     after = after->
link()->next();
 
  851             bool useAfterVarRange = 
true;
 
  854                     useAfterVarRange = 
false;
 
  862                     if (prev->
isName() && prev != tok3)
 
  873             if (isFunctionPointer) {
 
  875                     after = after->
link()->linkAt(1)->next();
 
  876                 else if (after->
str() == 
"(") {
 
  877                     useAfterVarRange = 
false;
 
  881                 else if (after->
str() == 
"[") {
 
  882                     while (after && after->
str() == 
"[")
 
  883                         after = after->
link()->next();
 
  888                     after = after->
link()->next();
 
  892                 throw InternalError(tok, 
"Failed to simplify typedef. Is the code valid?");
 
  894             Token* 
const tok4 = useAfterVarRange ? insertTokens(after->
previous(), mRangeAfterVar)->
next() : tok3->
next();
 
  906             std::stack<Token*> brackets;
 
  907             for (; tok != tok4; tok = tok->
next()) {
 
  917         void removeDeclaration() {
 
  928         static int canReplaceStatic(
const Token* tok) {
 
  929             if (!
Token::Match(tok, 
"%name% %name%|*|&|&&|;|(|)|,|::")) {
 
  944                         if (prev->
str() == 
")")
 
  952                     bool isGeneric = 
false;
 
  953                     for (; tok; tok = tok->
previous()) {
 
  968         bool canReplace(
const Token* tok) {
 
  969             if (mNameToken == tok)
 
  974                 const int res = canReplaceStatic(tok);
 
  975                 if (res == 0 || res == 1)
 
  984                 tok->
str() != mRangeType.second->previous()->str())
 
  990             for (
const Token* after = tok->
next(); after; after = after->
next()) {
 
  993                 if (after->
str() == 
"<" && after->
link())
 
 1004                 if (
Token::Match(before, 
"struct|union|class|enum") || before->isStandardType())
 
 1006                 if (before->str() == 
"::")
 
 1008                 if (before->isName())
 
 1015         Token* endToken()
 const {
 
 1020         static bool isCast(
const Token* tok) {
 
 1028         static Token* insertTokens(
Token* to, std::pair<Token*,Token*> range) {
 
 1029             for (
const Token* from = range.first; from != range.second; from = from->
next()) {
 
 1039         static void printTypedef(
const Token *tok) {
 
 1041             while (tok && (
indent > 0 || tok->
str() != 
";")) {
 
 1042                 if (tok->
str() == 
"{")
 
 1044                 else if (tok->
str() == 
"}")
 
 1046                 std::cout << 
" " << tok->
str();
 
 1058     std::map<std::string, int> numberOfTypedefs;
 
 1060         if (tok->
str() == 
"typedef") {
 
 1061             TypedefSimplifier ts(tok);
 
 1063                 numberOfTypedefs[ts.name()]++;
 
 1068     int indentlevel = 0;
 
 1069     std::map<std::string, TypedefSimplifier> typedefs;
 
 1072             if (tok->
str()[0] == 
'{')
 
 1074             else if (tok->
str()[0] == 
'}')
 
 1079         if (indentlevel == 0 && tok->
str() == 
"typedef") {
 
 1080             TypedefSimplifier ts(tok);
 
 1081             if (!ts.fail() && numberOfTypedefs[ts.name()] == 1 &&
 
 1082                 (numberOfTypedefs.find(ts.getTypedefToken()->strAt(1)) == numberOfTypedefs.end() || ts.getTypedefToken()->strAt(2) == 
"(")) {
 
 1085                                 "It is unspecified behavior to const qualify a function type.");
 
 1086                 typedefs.emplace(ts.name(), ts);
 
 1087                 if (!ts.isStructEtc())
 
 1088                     tok = ts.endToken();
 
 1093         auto it = typedefs.find(tok->
str());
 
 1094         if (it != typedefs.end() && it->second.canReplace(tok)) {
 
 1095             std::set<std::string> r;
 
 1096             while (it != typedefs.end() && r.insert(tok->
str()).second) {
 
 1098                 it = typedefs.find(tok->
str());
 
 1100         } 
else if (tok->
str() == 
"enum") {
 
 1105             if (tok->
str() == 
"{")
 
 1110     if (!typedefs.empty())
 
 1113         for (
auto &t: typedefs) {
 
 1114             if (!t.second.replaceFailed()) {
 
 1115                 const Token* 
const typedefToken = t.second.getTypedefToken();
 
 1117                 typedefInfo.
name = t.second.name();
 
 1121                 typedefInfo.
used = t.second.isUsed();
 
 1124                 t.second.removeDeclaration();
 
 1149     bool isNamespace = 
false;
 
 1150     std::string className, fullClassName;
 
 1151     bool hasClass = 
false;
 
 1152     bool goback = 
false;
 
 1155     std::vector<Space> spaceInfo(1);
 
 1169         if (maxTime > 0 && std::time(
nullptr) > maxTime) {
 
 1175                                     "Typedef simplification instantiation maximum time exceeded",
 
 1189         if (tok->
str() != 
"typedef") {
 
 1193             } 
else if (
Token::Match(tok, 
"class|struct|namespace %any%") &&
 
 1195                 isNamespace = (tok->
str() == 
"namespace");
 
 1197                 className = tok->
next()->
str();
 
 1199                 fullClassName = className;
 
 1201                     tok1 = tok1->
tokAt(2);
 
 1202                     fullClassName += 
" :: " + tok1->
str();
 
 1204             } 
else if (hasClass && tok->
str() == 
";") {
 
 1206             } 
else if (hasClass && tok->
str() == 
"{") {
 
 1208                     spaceInfo.back().recordTypes.insert(fullClassName);
 
 1211                 info.isNamespace = isNamespace;
 
 1212                 info.className = className;
 
 1213                 info.bodyEnd = tok->
link();
 
 1214                 info.bodyEnd2 = tok->
link();
 
 1215                 spaceInfo.push_back(std::move(info));
 
 1218             } 
else if (spaceInfo.size() > 1 && tok->
str() == 
"}" && spaceInfo.back().bodyEnd == tok) {
 
 1219                 spaceInfo.pop_back();
 
 1228             tokClass = tokClass->
next();
 
 1229         if (
Token::Match(tokClass, 
"struct|enum|union|class %type%| {|:")) {
 
 1248         Token *typeStart = 
nullptr;
 
 1249         Token *typeEnd = 
nullptr;
 
 1250         Token *argStart = 
nullptr;
 
 1251         Token *argEnd = 
nullptr;
 
 1252         Token *arrayStart = 
nullptr;
 
 1253         Token *arrayEnd = 
nullptr;
 
 1254         Token *specStart = 
nullptr;
 
 1255         Token *specEnd = 
nullptr;
 
 1256         Token *typeDef = tok;
 
 1257         Token *argFuncRetStart = 
nullptr;
 
 1258         Token *argFuncRetEnd = 
nullptr;
 
 1259         Token *funcStart = 
nullptr;
 
 1260         Token *funcEnd = 
nullptr;
 
 1262         bool function = 
false;
 
 1263         bool functionPtr = 
false;
 
 1264         bool functionRetFuncPtr = 
false;
 
 1265         bool functionPtrRetFuncPtr = 
false;
 
 1266         bool ptrToArray = 
false;
 
 1267         bool refToArray = 
false;
 
 1268         bool ptrMember = 
false;
 
 1269         bool typeOf = 
false;
 
 1270         Token *namespaceStart = 
nullptr;
 
 1271         Token *namespaceEnd = 
nullptr;
 
 1277         if (tokOffset->
str() == 
"::") {
 
 1278             typeStart = tokOffset;
 
 1279             tokOffset = tokOffset->
next();
 
 1282                 tokOffset = tokOffset->
tokAt(2);
 
 1284             typeEnd = tokOffset;
 
 1287                 tokOffset = tokOffset->
next();
 
 1289             typeStart = tokOffset;
 
 1292                 tokOffset = tokOffset->
tokAt(2);
 
 1295             typeEnd = tokOffset;
 
 1298                 tokOffset = tokOffset->
next();
 
 1300             typeStart = tokOffset;
 
 1302             while (
Token::Match(tokOffset, 
"const|struct|enum %type%") ||
 
 1304                 tokOffset = tokOffset->
next();
 
 1306             typeEnd = tokOffset;
 
 1308                 tokOffset = tokOffset->
next();
 
 1313                 typeEnd = tokOffset;
 
 1314                 tokOffset = tokOffset->
next();
 
 1319                 if (tokOffset && tokOffset->
str() == 
"::") {
 
 1320                     typeEnd = tokOffset;
 
 1321                     tokOffset = tokOffset->
next();
 
 1326                     typeEnd = tokOffset;
 
 1327                     tokOffset = tokOffset->
next();
 
 1329                     typeEnd = tokOffset;
 
 1330                     tokOffset = tokOffset->
next();
 
 1343         if (!
isC() && tokOffset->
str() == 
"<") {
 
 1347                 typeEnd = typeEnd->
tokAt(2);
 
 1355                 typeEnd = typeEnd->
next();
 
 1358             tokOffset = tok->
next();
 
 1361         std::list<std::string> pointers;
 
 1364             pointers.push_back(tokOffset->
str());
 
 1365             tokOffset = tokOffset->
next();
 
 1374             typeName = tokOffset;
 
 1375             tokOffset = tokOffset->
next();
 
 1378             while (tokOffset && tokOffset->
str() == 
"[") {
 
 1380                     arrayStart = tokOffset;
 
 1381                 arrayEnd = tokOffset->
link();
 
 1382                 tokOffset = arrayEnd->
next();
 
 1390             else if (tokOffset && tokOffset->
str() == 
"(") {
 
 1391                 Token *tokOffset2 = 
nullptr;
 
 1393                     tokOffset2 = tokOffset->
next();
 
 1394                     if (tokOffset2->
str() == 
"typename")
 
 1395                         tokOffset2 = tokOffset2->
next();
 
 1397                         tokOffset2 = tokOffset2->
tokAt(2);
 
 1401                 if (typeName->
str() == 
"void") {
 
 1413                     typeEnd = typeEnd->
next();
 
 1415                     funcStart = funcEnd = tokOffset2; 
 
 1416                     tokOffset = tokOffset2->
tokAt(3); 
 
 1417                     typeName = tokOffset->
tokAt(-2);
 
 1418                     argStart = tokOffset;
 
 1419                     argEnd = tokOffset->
link();
 
 1420                     tok = argEnd->
next();
 
 1426                     if (tokOffset->
link()->next()->str() == 
"const") {
 
 1427                         specStart = tokOffset->
link()->next();
 
 1428                         specEnd = specStart;
 
 1430                     argStart = tokOffset;
 
 1431                     argEnd = tokOffset->
link();
 
 1432                     tok = argEnd->
next();
 
 1456             argStart = tokOffset;
 
 1457             argEnd = tokOffset->
link();
 
 1458             typeName = tokOffset->
link()->next();
 
 1459             tok = typeName->
next();
 
 1466         else if (tokOffset->
str() == 
"(" && (
 
 1475             if (tokOffset->
next()->
str() == 
"(")
 
 1476                 tokOffset = tokOffset->
next();
 
 1478                 pointers.emplace_back(
"*");
 
 1479                 tokOffset = tokOffset->
tokAt(2);
 
 1482             if (tokOffset->
link()->strAt(-2) == 
"*")
 
 1486             funcStart = tokOffset->
next();
 
 1487             tokOffset = tokOffset->
link();
 
 1488             funcEnd = tokOffset->
tokAt(-2);
 
 1490             argStart = tokOffset->
next();
 
 1491             argEnd = tokOffset->
next()->
link();
 
 1495             tok = argEnd->
next();
 
 1501                     specEnd = spec->
next();
 
 1504                 tok = specEnd->
next();
 
 1509             if (tok->
str() == 
")")
 
 1515             if (tokOffset->
link()->next()) {
 
 1516                 tok = tokOffset->
link()->next();
 
 1517                 tokOffset = tokOffset->
tokAt(2);
 
 1519                 argStart = tokOffset;
 
 1520                 argEnd = tokOffset->
link();
 
 1528         else if (
Token::Match(tokOffset, 
"( * ( * %type% ) (") &&
 
 1531             functionPtrRetFuncPtr = 
true;
 
 1533             tokOffset = tokOffset->
tokAt(6);
 
 1534             typeName = tokOffset->
tokAt(-2);
 
 1535             argStart = tokOffset;
 
 1536             argEnd = tokOffset->
link();
 
 1540             argFuncRetStart = argEnd->
tokAt(2);
 
 1541             argFuncRetEnd = argFuncRetStart->
link();
 
 1545             tok = argFuncRetEnd->
next();
 
 1552             functionRetFuncPtr = 
true;
 
 1554             tokOffset = tokOffset->
tokAt(3);
 
 1556             argStart = tokOffset;
 
 1557             argEnd = tokOffset->
link();
 
 1559             argFuncRetStart = argEnd->
tokAt(2);
 
 1560             if (!argFuncRetStart)
 
 1563             argFuncRetEnd = argFuncRetStart->
link();
 
 1567             tok = argFuncRetEnd->
next();
 
 1568         } 
else if (
Token::Match(tokOffset, 
"( * ( %type% ) (")) {
 
 1569             functionRetFuncPtr = 
true;
 
 1571             tokOffset = tokOffset->
tokAt(5);
 
 1572             typeName = tokOffset->
tokAt(-2);
 
 1573             argStart = tokOffset;
 
 1574             argEnd = tokOffset->
link();
 
 1578             argFuncRetStart = argEnd->
tokAt(2);
 
 1579             if (!argFuncRetStart)
 
 1582             argFuncRetEnd = argFuncRetStart->
link();
 
 1586             tok = argFuncRetEnd->
next();
 
 1590         else if (
Token::Match(tokOffset, 
"( *|& %type% ) [")) {
 
 1591             ptrToArray = (tokOffset->
next()->
str() == 
"*");
 
 1592             refToArray = !ptrToArray;
 
 1593             tokOffset = tokOffset->
tokAt(2);
 
 1594             typeName = tokOffset;
 
 1595             arrayStart = tokOffset->
tokAt(2);
 
 1596             arrayEnd = arrayStart->
link();
 
 1600             tok = arrayEnd->
next();
 
 1604         else if (
Token::Match(tokOffset, 
"( %type% :: * %type% ) ;")) {
 
 1605             tokOffset = tokOffset->
tokAt(2);
 
 1606             namespaceStart = tokOffset->
previous();
 
 1607             namespaceEnd = tokOffset;
 
 1609             tokOffset = tokOffset->
tokAt(2);
 
 1610             typeName = tokOffset;
 
 1611             tok = tokOffset->
tokAt(2);
 
 1628         typedefInfo.
name = typeName->
str();
 
 1632         typedefInfo.
used = 
false;
 
 1636             std::string pattern = typeName->
str();
 
 1638             bool simplifyType = 
false;
 
 1639             bool inMemberFunc = 
false;
 
 1640             int memberScope = 0;
 
 1641             bool globalScope = 
false;
 
 1642             int classLevel = spaceInfo.size();
 
 1643             bool inTypeDef = 
false;
 
 1644             bool inEnum = 
false;
 
 1645             std::string removed;
 
 1646             std::string classPath;
 
 1647             for (
size_t i = 1; i < spaceInfo.size(); ++i) {
 
 1648                 if (!classPath.empty())
 
 1649                     classPath += 
" :: ";
 
 1650                 classPath += spaceInfo[i].className;
 
 1653             for (
Token *tok2 = tok; tok2; tok2 = tok2->
next()) {
 
 1668                     Token* varDecl = tok2;
 
 1670                         varDecl = varDecl->
next();
 
 1679                                     tok2 = tok2->
link();
 
 1680                                 tok2 = tok2->
next();
 
 1691                     if (tok2->
str() == 
"}") {
 
 1695                             if (memberScope == 0)
 
 1696                                 inMemberFunc = 
false;
 
 1700                         if (classLevel > 1 && tok2 == spaceInfo[classLevel - 1].bodyEnd2) {
 
 1704                             for (
int i = classLevel; i < spaceInfo.size(); ++i)
 
 1705                                 pattern += (spaceInfo[i].className + 
" :: ");
 
 1707                             pattern += typeName->
str();
 
 1709                             if (scope == 0 && !(classLevel > 1 && tok2 == spaceInfo[classLevel - 1].bodyEnd))
 
 1711                             scope = std::max(scope - 1, 0);
 
 1732                             if (spaceInfo.size() > 1 && classLevel < spaceInfo.size() &&
 
 1733                                 func->
strAt(offset) == spaceInfo[classLevel].className) {
 
 1735                                 inMemberFunc = 
true;
 
 1741                     else if (tok2->
str() == 
"{") {
 
 1743                         if (tok2->
isCpp()) {
 
 1744                             if (tok2->
strAt(-2) == 
"namespace") {
 
 1745                                 if (classLevel < spaceInfo.size() &&
 
 1746                                     spaceInfo[classLevel].isNamespace &&
 
 1747                                     spaceInfo[classLevel].className == tok2->
previous()->
str()) {
 
 1748                                     spaceInfo[classLevel].bodyEnd2 = tok2->
link();
 
 1751                                     for (
int i = classLevel; i < spaceInfo.size(); ++i)
 
 1752                                         pattern += spaceInfo[i].className + 
" :: ";
 
 1754                                     pattern += typeName->
str();
 
 1772                 else if (tok2->
isCpp() &&
 
 1773                          tok2->
str() == 
"operator" &&
 
 1777                          tok2->
strAt(2) == 
"(" &&
 
 1782                         if (spaceInfo.size() > 1 && classLevel < spaceInfo.size() &&
 
 1783                             tok2->
strAt(-2) == spaceInfo[classLevel].className) {
 
 1784                             tok2 = tok2->
next();
 
 1785                             simplifyType = 
true;
 
 1797                           (inMemberFunc && tok2->
str() == typeName->
str()))) {
 
 1799                     if (!(inMemberFunc && tok2->
str() == typeName->
str()) && pattern.find(
"::") != std::string::npos) { 
 
 1800                         Token *start = tok2;
 
 1802                         int back = classLevel - 1;
 
 1809                             if (qualificationTok->
str() == spaceInfo[back].className) {
 
 1810                                 start = qualificationTok;
 
 1819                         if (good && back == 1 && start->
strAt(-1) == 
"::")
 
 1825                                 if (!removed.empty())
 
 1826                                     removed.insert(0, 
" ");
 
 1827                                 removed.insert(0, tok2->
strAt(-2) + 
" " + tok2->
strAt(-1));
 
 1833                             if (tok2->
strAt(-1) == 
"::") {
 
 1834                                 removed.insert(0, 
":: ");
 
 1840                             for (
int i = classLevel; i < spaceInfo.size(); ++i) {
 
 1841                                 if (!removed.empty())
 
 1843                                 removed += (tok2->
str() + 
" " + tok2->
strAt(1));
 
 1847                             simplifyType = 
true;
 
 1850                         if (tok2->
strAt(-1) == 
"::") {
 
 1851                             int relativeSpaceInfoSize = spaceInfo.size();
 
 1853                             while (relativeSpaceInfoSize > 1 &&
 
 1854                                    tokBeforeType && tokBeforeType->
str() == 
"::" &&
 
 1855                                    tokBeforeType->
strAt(-1) == spaceInfo[relativeSpaceInfoSize-1].className) {
 
 1856                                 tokBeforeType = tokBeforeType->
tokAt(-2);
 
 1857                                 --relativeSpaceInfoSize;
 
 1859                             if (tokBeforeType && tokBeforeType->
str() != 
"::") {
 
 1861                                 simplifyType = 
true;
 
 1864                             tok2 = tok2->
next();
 
 1867                             if (tok2->
str() != 
"}") {
 
 1868                                 while (tok2->
next()) {
 
 1869                                     if (tok2->
next()->
str() == 
"{")
 
 1871                                     else if (tok2->
next()->
str() == 
"}")
 
 1874                                     tok2 = tok2->
next();
 
 1880                             simplifyType = (TypedefSimplifier::canReplaceStatic(tok2) != 0);
 
 1892                     if (functionPtr && (tok2->
previous()->
str() == 
"operator" ||
 
 1893                                         (tok2->
next() && tok2->
next()->
str() == 
"operator"))) {
 
 1894                         simplifyType = 
false;
 
 1895                         tok2 = tok2->
next();
 
 1906                     bool inCast = 
false;
 
 1907                     bool inTemplate = 
false;
 
 1908                     bool inOperator = 
false;
 
 1909                     bool inSizeof = 
false;
 
 1911                     const bool sameStartEnd = (typeStart == typeEnd);
 
 1914                     const bool isDerived = 
Token::Match(tok2->
previous(), 
"public|protected|private|: %type% {|,");
 
 1932                     if (tok2->
strAt(-1) == 
"operator" ||
 
 1936                     if (typeStart->
str() == 
"typename" && tok2->
strAt(-1)==
"typename") {
 
 1938                         typeStart = typeStart->
next();
 
 1942                     bool structRemoved = 
false;
 
 1943                     if ((isDerived || inTemplate) && 
Token::Match(typeStart, 
"class|struct")) {
 
 1944                         if (typeStart->
str() == 
"struct")
 
 1945                             structRemoved = 
true;
 
 1946                         typeStart = typeStart->
next();
 
 1949                         typeStart = typeStart->
next();
 
 1952                         typeEnd = typeStart;
 
 1955                     const bool isPointerTypeCall = !inOperator && 
Token::Match(tok2, 
"%name% ( )") && !pointers.empty();
 
 1958                     Token* replStart = tok2; 
 
 1959                     for (
Token* tok3 = typeStart; tok3 && (tok3->
str() != 
";"); tok3 = tok3->
next())
 
 1961                     if (isPointerTypeCall) {
 
 1964                         tok2 = tok2->
next();
 
 1969                     tok2->
str(typeStart->
str());
 
 1972                     if (
Token::Match(typeStart, 
"class|struct|union") || structRemoved) {
 
 1978                             tok2 = tok2->
next();
 
 1981                         for (
int i = classLevel; i < spaceInfo.size(); ++i) {
 
 1983                             tok2 = tok2->
next();
 
 1985                             tok2 = tok2->
next();
 
 1990                     Token *start = tok2;
 
 1991                     std::string removed1 = removed;
 
 1992                     std::string::size_type idx = removed1.rfind(
" ::");
 
 1994                     if (idx != std::string::npos)
 
 1995                         removed1.resize(idx);
 
 1996                     if (removed1 == classPath && !removed1.empty()) {
 
 1997                         for (std::vector<Space>::const_reverse_iterator it = spaceInfo.crbegin(); it != spaceInfo.crend(); ++it) {
 
 1998                             if (it->recordTypes.find(start->
str()) != it->recordTypes.end()) {
 
 1999                                 std::string::size_type spaceIdx = 0;
 
 2000                                 std::string::size_type startIdx = 0;
 
 2001                                 while ((spaceIdx = removed1.find(
' ', startIdx)) != std::string::npos) {
 
 2003                                     startIdx = spaceIdx + 1;
 
 2009                             idx = removed1.rfind(
" ::");
 
 2010                             if (idx == std::string::npos)
 
 2013                             removed1.resize(idx);
 
 2021                     if (!pointers.empty()) {
 
 2022                         for (
const std::string &p : pointers) {
 
 2025                             tok2 = tok2->
next();
 
 2031                             tok2 = tok2->
next();
 
 2035                     if (funcStart && funcEnd) {
 
 2037                         tok2 = tok2->
next();
 
 2038                         Token *paren = tok2;
 
 2051                         tok2 = tok2->
next();
 
 2057                             Token *spec = specStart;
 
 2059                             tok2 = tok2->
next();
 
 2060                             while (spec != specEnd) {
 
 2061                                 spec = spec->
next();
 
 2063                                 tok2 = tok2->
next();
 
 2068                     else if (functionPtr || 
function) {
 
 2071                         bool needParen = 
true;
 
 2072                         if (!inTemplate && 
function && tok2->
next() && tok2->
next()->
str() != 
"*")
 
 2076                             tok2 = tok2->
next();
 
 2079                         if (namespaceStart) {
 
 2080                             const Token *tok4 = namespaceStart;
 
 2082                             while (tok4 != namespaceEnd) {
 
 2084                                 tok2 = tok2->
next();
 
 2085                                 tok4 = tok4->
next();
 
 2088                             tok2 = tok2->
next();
 
 2092                             tok2 = tok2->
next();
 
 2103                             tok2 = tok2->
next();
 
 2114                             tok2 = tok2->
next();
 
 2118                             Token *spec = specStart;
 
 2120                             tok2 = tok2->
next();
 
 2121                             while (spec != specEnd) {
 
 2122                                 spec = spec->
next();
 
 2124                                 tok2 = tok2->
next();
 
 2127                     } 
else if (functionRetFuncPtr || functionPtrRetFuncPtr) {
 
 2129                         tok2 = tok2->
next();
 
 2132                         tok2 = tok2->
next();
 
 2134                         Token * tok4 = 
nullptr;
 
 2135                         if (functionPtrRetFuncPtr) {
 
 2137                             tok2 = tok2->
next();
 
 2140                             tok2 = tok2->
next();
 
 2145                             if (!tok2 || !tok2->
next())
 
 2148                             if (tok2->
next()->
str() != 
")")
 
 2149                                 tok2 = tok2->
next();
 
 2152                         if (tok4 && functionPtrRetFuncPtr) {
 
 2154                             tok2 = tok2->
next();
 
 2161                         tok2 = tok2->
next();
 
 2165                     } 
else if (ptrToArray || refToArray) {
 
 2167                         tok2 = tok2->
next();
 
 2174                         tok2 = tok2->
next();
 
 2176                         bool hasName = 
false;
 
 2181                             if (tok2->
next()->
str() != 
"(")
 
 2182                                 tok2 = tok2->
next();
 
 2185                             if (tok2 && tok2->
next() && tok2->
next()->
str() == 
"(")
 
 2189                             if (tok2 && tok2->
next() && tok2->
next()->
str() == 
"[")
 
 2197                             tok2 = tok2->
next();
 
 2198                     } 
else if (ptrMember) {
 
 2201                             tok2 = tok2->
next();
 
 2206                             const bool castOperator = inOperator && 
Token::Match(tok2, 
"%type% (");
 
 2207                             Token *openParenthesis = 
nullptr;
 
 2209                             if (!castOperator) {
 
 2211                                 tok2 = tok2->
next();
 
 2213                                 openParenthesis = tok2;
 
 2216                             const Token *tok4 = namespaceStart;
 
 2218                             while (tok4 != namespaceEnd) {
 
 2220                                 tok2 = tok2->
next();
 
 2221                                 tok4 = tok4->
next();
 
 2224                             tok2 = tok2->
next();
 
 2227                             tok2 = tok2->
next();
 
 2229                             if (openParenthesis) {
 
 2232                                     tok2 = tok2->
next();
 
 2235                                 tok2 = tok2->
next();
 
 2240                     } 
else if (typeOf) {
 
 2249                     if (arrayStart && arrayEnd) {
 
 2254                             if (!inCast && !inSizeof && !inTemplate)
 
 2255                                 tok2 = tok2->
next();
 
 2257                             if (tok2->
str() == 
"const")
 
 2258                                 tok2 = tok2->
next();
 
 2268                                     tok2 = tok3->
tokAt(3);
 
 2270                                     tok2 = tok2->
tokAt(2);
 
 2272                                     tok2 = tok2->
tokAt(2);
 
 2274                                     tok2 = tok2->
tokAt(3);
 
 2278                                 while (tok2->
strAt(1) == 
"::")
 
 2279                                     tok2 = tok2->
tokAt(2);
 
 2282                                 if (tok2->
str() == 
"(")
 
 2283                                     tok2 = tok2->
link();
 
 2285                                 if (tok2->
strAt(1) == 
"(")
 
 2290                                     tok2 = tok2->
next();
 
 2292                                         tok2 = tok2->
tokAt(3);
 
 2296                                 tok2 = tok2->
next();
 
 2304                             while (tok2->
next()->
str() == 
"[")
 
 2311                             if (tok2->
str() == 
"=") {
 
 2312                                 if (tok2->
next()->
str() == 
"{")
 
 2313                                     tok2 = tok2->
next()->
link()->next();
 
 2314                                 else if (tok2->
next()->
str().at(0) == 
'\"')
 
 2315                                     tok2 = tok2->
tokAt(2);
 
 2320                     simplifyType = 
false;
 
 2329             if (tok->
str() == 
";")
 
 2331             else if (tok->
str() == 
",") {
 
 2332                 arrayStart = 
nullptr;
 
 2334                 tokOffset = tok->
next();
 
 2338                     pointers.push_back(tokOffset->
str());
 
 2339                     tokOffset = tokOffset->
next();
 
 2343                     typeName = tokOffset;
 
 2344                     tokOffset = tokOffset->
next();
 
 2346                     if (tokOffset && tokOffset->
str() == 
"[") {
 
 2347                         arrayStart = tokOffset;
 
 2351                                 tokOffset = tokOffset->
next();
 
 2353                             if (!tokOffset->
next())
 
 2355                             if (tokOffset->
next()->
str() == 
";")
 
 2357                             if (tokOffset->
str() == 
"]")
 
 2359                             tokOffset = tokOffset->
next();
 
 2362                         arrayEnd = tokOffset;
 
 2363                         tokOffset = tokOffset->
next();
 
 2411         ScopeInfo3() : parent(nullptr), type(
Global), bodyStart(nullptr), bodyEnd(nullptr) {}
 
 2412         ScopeInfo3(ScopeInfo3 *parent_, 
Type type_, std::string name_, 
const Token *bodyStart_, 
const Token *bodyEnd_)
 
 2413             : parent(parent_), type(type_), name(std::move(name_)), bodyStart(bodyStart_), bodyEnd(bodyEnd_) {
 
 2417             ScopeInfo3 *scope = parent;
 
 2418             while (scope && scope->parent) {
 
 2419                 if (scope->name.empty())
 
 2421                 fullName = scope->name + 
" :: " + fullName;
 
 2422                 scope = scope->parent;
 
 2426         std::list<ScopeInfo3> children;
 
 2428         std::string fullName;
 
 2430         const Token * bodyStart;
 
 2431         const Token * bodyEnd;
 
 2432         std::set<std::string> usingNamespaces;
 
 2433         std::set<std::string> recordTypes;
 
 2434         std::set<std::string> baseTypes;
 
 2436         ScopeInfo3 *addChild(
Type scopeType, 
const std::string &scopeName, 
const Token *bodyStartToken, 
const Token *bodyEndToken) {
 
 2437             children.emplace_back(
this, scopeType, scopeName, bodyStartToken, bodyEndToken);
 
 2438             return &children.back();
 
 2441         bool hasChild(
const std::string &childName)
 const {
 
 2442             return std::any_of(children.cbegin(), children.cend(), [&](
const ScopeInfo3& child) {
 
 2443                 return child.name == childName;
 
 2447         const ScopeInfo3 * findInChildren(
const std::string & scope)
 const {
 
 2448             for (
const auto & child : children) {
 
 2449                 if (child.type == Record && (child.name == scope || child.fullName == scope))
 
 2452                 const ScopeInfo3 * temp = child.findInChildren(scope);
 
 2459         const ScopeInfo3 * findScope(
const std::string & scope)
 const {
 
 2460             const ScopeInfo3 * tempScope = 
this;
 
 2463                 auto it = std::find_if(tempScope->children.cbegin(), tempScope->children.cend(), [&](
const ScopeInfo3& child) {
 
 2464                     return &child != this && child.type == Record && (child.name == scope || child.fullName == scope);
 
 2466                 if (it != tempScope->children.end())
 
 2469                 if (tempScope->parent) {
 
 2470                     for (
const auto &sibling : tempScope->parent->children) {
 
 2471                         if (sibling.name == tempScope->name && &sibling != 
this) {
 
 2472                             const ScopeInfo3 * temp = sibling.findInChildren(scope);
 
 2478                 tempScope = tempScope->parent;
 
 2483         bool findTypeInBase(
const std::string &scope)
 const {
 
 2487             if (baseTypes.find(scope) != baseTypes.end())
 
 2490             for (
const std::string & base : baseTypes) {
 
 2491                 const ScopeInfo3 * baseScope = findScope(base);
 
 2493                 if (baseScope == 
this)
 
 2495                 if (baseScope && baseScope->fullName == scope)
 
 2497                 if (baseScope && baseScope->findTypeInBase(scope))
 
 2503         ScopeInfo3 * findScope(
const ScopeInfo3 * scope) {
 
 2504             if (scope->bodyStart == bodyStart)
 
 2506             for (
auto & child : children) {
 
 2507                 ScopeInfo3 * temp = child.findScope(scope);
 
 2515     void setScopeInfo(
Token *tok, ScopeInfo3 *&scopeInfo, 
bool debug=
false)
 
 2519         if (tok->
str() == 
"{" && scopeInfo->parent && tok == scopeInfo->bodyStart)
 
 2521         if (tok->
str() == 
"}") {
 
 2522             if (scopeInfo->parent && tok == scopeInfo->bodyEnd)
 
 2523                 scopeInfo = scopeInfo->parent;
 
 2526                 ScopeInfo3 *parent = scopeInfo->parent;
 
 2527                 while (parent && parent->bodyEnd != tok)
 
 2528                     parent = parent->parent;
 
 2532                         throw std::runtime_error(
"Internal error: unmatched }");
 
 2537         if (!
Token::Match(tok, 
"namespace|class|struct|union %name% {|:|::|<")) {
 
 2539             if (
Token::Match(tok, 
"using namespace %name% ;|::")) {
 
 2541                 std::string nameSpace;
 
 2542                 while (tok1 && tok1->
str() != 
";") {
 
 2543                     if (!nameSpace.empty())
 
 2545                     nameSpace += tok1->
str();
 
 2546                     tok1 = tok1->
next();
 
 2548                 scopeInfo->usingNamespaces.insert(std::move(nameSpace));
 
 2551             else if (tok->
str() == 
"{") {
 
 2562                         if (tok1->
strAt(-1) != 
")")
 
 2567                             tok1 = tok1->
tokAt(-2);
 
 2568                             if (tok1->
strAt(-1) != 
")" && tok1->
strAt(-1) != 
"}")
 
 2573                     if (tok1->
strAt(-1) == 
">")
 
 2577                         tok1 = tok1->
tokAt(-2);
 
 2578                         if (tok1->
str() == 
"~")
 
 2580                         std::string scope = tok1->
strAt(-1);
 
 2582                             scope = tok1->
strAt(-3) + 
" :: " + scope;
 
 2583                             tok1 = tok1->
tokAt(-2);
 
 2585                         scopeInfo = scopeInfo->addChild(ScopeInfo3::MemberFunction, scope, tok, tok->
link());
 
 2591                     scopeInfo = scopeInfo->addChild(ScopeInfo3::Other, 
emptyString, tok, tok->
link());
 
 2596         const bool record = 
Token::Match(tok, 
"class|struct|union %name%");
 
 2598         std::string classname = tok->
str();
 
 2600             tok = tok->
tokAt(2);
 
 2601             classname += 
" :: " + tok->
str();
 
 2606             scopeInfo->recordTypes.insert(classname);
 
 2610         if (tok && tok->
str() == 
"<") {
 
 2617         std::set<std::string> baseTypes;
 
 2618         if (tok && tok->
str() == 
":") {
 
 2621                 while (
Token::Match(tok, 
"public|protected|private|virtual"))
 
 2630                     if (tok && tok->
str() == 
"<") {
 
 2633                             endTok = endTok->
next();
 
 2634                             while (tok != endTok) {
 
 2641                 baseTypes.insert(std::move(base));
 
 2645         if (tok && tok->
str() == 
"{") {
 
 2646             scopeInfo = scopeInfo->addChild(record ? ScopeInfo3::Record : ScopeInfo3::Namespace, classname, tok, tok->
link());
 
 2647             scopeInfo->baseTypes = std::move(baseTypes);
 
 2655         for (; tok && (level > 0 || tok->
str() != 
";"); tok = tok->
next()) {
 
 2656             if (tok->
str() == 
"{")
 
 2658             else if (level > 0 && tok->
str() == 
"}")
 
 2666         const Token *nameToken,
 
 2667         const std::string &scope,
 
 2669         const std::string &scope1,
 
 2670         const ScopeInfo3 *currentScope,
 
 2671         const ScopeInfo3 *memberClassScope)
 
 2675         if (tok1 && tok1->
str() != nameToken->
str())
 
 2679         if (tok1 == nameToken) {
 
 2680             tok = findSemicolon(tok1);
 
 2685         if (tok1->
strAt(-1) == 
"using") {
 
 2688             if (currentScope->bodyEnd)
 
 2689                 tok = 
const_cast<Token*
>(currentScope->bodyEnd->previous());
 
 2699         std::string qualification;
 
 2700         const Token* tok2 = tok1;
 
 2701         std::string::size_type index = scope.size();
 
 2702         std::string::size_type new_index = std::string::npos;
 
 2706             if (
match && !scope1.empty()) {
 
 2707                 new_index = scope1.rfind(
' ', index - 1);
 
 2708                 if (new_index != std::string::npos)
 
 2709                     last = scope1.substr(new_index, index - new_index);
 
 2710                 else if (!qualification.empty())
 
 2719                 if (!qualification.empty())
 
 2720                     qualification = 
" :: " + qualification;
 
 2721                 qualification = tok2->
strAt(-2) + qualification;
 
 2723             tok2 = tok2->
tokAt(-2);
 
 2726         std::string fullScope1 = scope1;
 
 2727         if (!scope1.empty() && !qualification.empty())
 
 2728             fullScope1 += 
" :: ";
 
 2729         fullScope1 += qualification;
 
 2731         if (scope == fullScope1)
 
 2734         const ScopeInfo3 *scopeInfo = memberClassScope ? memberClassScope : currentScope;
 
 2737         if (qualification.empty() && scopeInfo->findTypeInBase(scope))
 
 2741         const ScopeInfo3 * tempScope = scopeInfo;
 
 2744             const std::set<std::string>& usingNS = tempScope->usingNamespaces;
 
 2745             if (!usingNS.empty()) {
 
 2746                 if (qualification.empty()) {
 
 2747                     if (usingNS.find(scope) != usingNS.end())
 
 2750                     const std::string suffix = 
" :: " + qualification;
 
 2751                     if (std::any_of(usingNS.cbegin(), usingNS.cend(), [&](
const std::string& ns) {
 
 2752                         return scope == ns + suffix;
 
 2757             tempScope = tempScope->parent;
 
 2760         std::string newScope1 = scope1;
 
 2763         index = newScope1.size();
 
 2764         while (!newScope1.empty()) {
 
 2765             const std::string::size_type separator = newScope1.rfind(
" :: ", index - 1);
 
 2766             if (separator != std::string::npos)
 
 2767                 newScope1.resize(separator);
 
 2771             std::string newFullScope1 = newScope1;
 
 2772             if (!newScope1.empty() && !qualification.empty())
 
 2773                 newFullScope1 += 
" :: ";
 
 2774             newFullScope1 += qualification;
 
 2776             if (scope == newFullScope1)
 
 2783     std::string memberFunctionScope(
const Token *tok)
 
 2785         std::string qualification;
 
 2788             if (!qualification.empty())
 
 2789                 qualification = 
" :: " + qualification;
 
 2790             qualification = qualTok->
str() + qualification;
 
 2791             qualTok = qualTok->
tokAt(-2);
 
 2793         return qualification;
 
 2796     const Token * memberFunctionEnd(
const Token *tok)
 
 2798         if (tok->
str() != 
"(")
 
 2804             if (end->
str() == 
";")
 
 2819 static bool scopesMatch(
const std::string &scope1, 
const std::string &scope2, 
const ScopeInfo3 *globalScope)
 
 2821     if (scope1.empty() || scope2.empty())
 
 2825     if (scope1 == scope2)
 
 2829     if (scope1 == (
":: " + scope2)) {
 
 2830         std::string::size_type end = scope2.find_first_of(
' ');
 
 2831         if (end == std::string::npos)
 
 2832             end = scope2.size();
 
 2833         if (globalScope->hasChild(scope2.substr(0, end)))
 
 2835     } 
else if (scope2 == (
":: " + scope1)) {
 
 2836         std::string::size_type end = scope1.find_first_of(
' ');
 
 2837         if (end == std::string::npos)
 
 2838             end = scope1.size();
 
 2839         if (globalScope->hasChild(scope1.substr(0, end)))
 
 2847     unsigned int dist = 0;
 
 2848     const Token* tok = tok1;
 
 2849     while (tok != tok2) {
 
 2870             if (end->
str() == 
"<") 
 
 2880         if (end->
str() == 
",") { 
 
 2887     const unsigned int maxReplacementTokens = 1000; 
 
 2889     bool substitute = 
false;
 
 2890     ScopeInfo3 scopeInfo;
 
 2891     ScopeInfo3 *currentScope = &scopeInfo;
 
 2893         Using(
Token *start, 
Token *end) : startTok(start), endTok(end) {}
 
 2897     std::list<Using> usingList;
 
 2907             Token *bodyStart = tok;
 
 2909                 if (bodyStart->
str() == 
"<")
 
 2911                 bodyStart = bodyStart ? bodyStart->
next() : 
nullptr;
 
 2914                 tok = bodyStart->
link();
 
 2918         if (
Token::Match(tok, 
"{|}|namespace|class|struct|union") ||
 
 2922             } 
catch (
const std::runtime_error &) {
 
 2924                             "simplifyUsing: unmatched body end");
 
 2934                 currentScope->recordTypes.insert(end->
strAt(2));
 
 2943         if (!(tok->
strAt(-1) != 
">" &&
 
 2949         const std::string& name = tok->
strAt(1);
 
 2951         std::string scope = currentScope->fullName;
 
 2952         Token *usingStart = tok;
 
 2954         if (tok->
strAt(2) == 
"=") {
 
 2957             start = tok->
tokAt(3);
 
 2961         Token *usingEnd = findSemicolon(start);
 
 2968         if (
Token::Match(start, 
"class|struct|union|enum %name%| {|:")) {
 
 2970             const bool hasName = 
Token::Match(structEnd, 
"%name%");
 
 2974                 structEnd = structEnd->
next();
 
 2977             if (structEnd->
str() == 
":") {
 
 2978                 structEnd = structEnd->
next(); 
 
 2979                 while (structEnd && structEnd->
str() != 
"{")
 
 2980                     structEnd = structEnd->
next();
 
 2986             structEnd = structEnd->
link();
 
 2993                 std::string newName;
 
 2994                 if (structEnd->
strAt(2) == 
";")
 
 3005             usingStart = structEnd->
tokAt(2);
 
 3006             nameToken = usingStart->
next();
 
 3007             if (usingStart->
strAt(2) == 
"=")
 
 3008                 start = usingStart->
tokAt(3);
 
 3011             usingEnd = findSemicolon(start);
 
 3021         else if (start->
str() == 
"typename") {
 
 3023             Token *temp = start;
 
 3025                 temp = temp->
tokAt(2);
 
 3036         ScopeInfo3 scopeInfo1;
 
 3037         ScopeInfo3 *currentScope1 = &scopeInfo1;
 
 3039         Token *endToken = 
nullptr;
 
 3040         bool inMemberFunc = 
false;
 
 3041         const ScopeInfo3 * memberFuncScope = 
nullptr;
 
 3042         const Token * memberFuncEnd = 
nullptr;
 
 3046         if (currentScope->type == ScopeInfo3::Other ||
 
 3047             currentScope->type == ScopeInfo3::MemberFunction) {
 
 3048             scopeInfo1 = scopeInfo;
 
 3049             currentScope1 = scopeInfo1.findScope(currentScope);
 
 3052             startToken = usingEnd->
next();
 
 3053             endToken = 
const_cast<Token*
>(currentScope->bodyEnd->next());
 
 3054             if (currentScope->type == ScopeInfo3::MemberFunction) {
 
 3055                 const ScopeInfo3 * temp = currentScope->findScope(currentScope->fullName);
 
 3057                     inMemberFunc = 
true;
 
 3058                     memberFuncScope = temp;
 
 3059                     memberFuncEnd = endToken;
 
 3064         std::string scope1 = currentScope1->fullName;
 
 3066         Token *enumOpenBrace = 
nullptr;
 
 3067         for (
Token* tok1 = startToken; !skip && tok1 && tok1 != endToken; tok1 = tok1->
next()) {
 
 3069             if (tok1 && tok1 == enumOpenBrace) {
 
 3070                 tok1 = tok1->
link();
 
 3071                 enumOpenBrace = 
nullptr;
 
 3075             if ((
Token::Match(tok1, 
"{|}|namespace|class|struct|union") && tok1->
strAt(-1) != 
"using") ||
 
 3079                 } 
catch (
const std::runtime_error &) {
 
 3081                                 "simplifyUsing: unmatched body end");
 
 3083                 scope1 = currentScope1->fullName;
 
 3084                 if (inMemberFunc && memberFuncEnd && tok1 == memberFuncEnd) {
 
 3085                     inMemberFunc = 
false;
 
 3086                     memberFuncScope = 
nullptr;
 
 3087                     memberFuncEnd = 
nullptr;
 
 3096                     tok1 = declEndToken;
 
 3101             if (tok1->
str() == 
"enum") {
 
 3103                     tok1 = tok1->
next();
 
 3104                 Token *defStart = tok1;
 
 3106                     defStart = defStart->
next();
 
 3108                     enumOpenBrace = defStart;
 
 3114                 if (!scope1.empty())
 
 3116                 scope1 += memberFunctionScope(tok1);
 
 3117                 const ScopeInfo3 * temp = currentScope1->findScope(scope1);
 
 3119                     const Token *end = memberFunctionEnd(tok1);
 
 3121                         inMemberFunc = 
true;
 
 3122                         memberFuncScope = temp;
 
 3123                         memberFuncEnd = end;
 
 3128             if (inMemberFunc && memberFuncScope) {
 
 3129                 if (!usingMatch(nameToken, scope, tok1, scope1, currentScope1, memberFuncScope))
 
 3131             } 
else if (!usingMatch(nameToken, scope, tok1, scope1, currentScope1, 
nullptr))
 
 3134             const auto nReplace = 
tokDistance(start, usingEnd);
 
 3135             if (nReplace > maxReplacementTokens) {
 
 3141             std::string fullScope = scope;
 
 3142             std::string removed;
 
 3144                 removed = (tok1->
strAt(-2) + 
" :: ") + removed;
 
 3145                 if (fullScope == tok1->
strAt(-2)) {
 
 3150                 const std::string::size_type idx = fullScope.rfind(
"::");
 
 3152                 if (idx == std::string::npos)
 
 3155                 if (tok1->
strAt(-2) == fullScope.substr(idx + 3)) {
 
 3158                     fullScope.resize(idx - 1);
 
 3164             if (tok1->
strAt(-1) == 
"::") {
 
 3165                 removed.insert(0, 
":: ");
 
 3169             Token * arrayStart = 
nullptr;
 
 3172             Token *type = start;
 
 3173             if (type->
str() == 
"::") {
 
 3174                 type = type->
next();
 
 3176                     type = type->
tokAt(2);
 
 3178                     type = type->
next();
 
 3181                     type = type->
tokAt(2);
 
 3184                     type = type->
next();
 
 3186                 while (
Token::Match(type, 
"const|class|struct|union|enum %type%") ||
 
 3188                     type = type->
next();
 
 3190                 type = type->
next();
 
 3194                     type = type->
next();
 
 3199                     if (type && type->
str() == 
"::") {
 
 3200                         type = type->
next();
 
 3205                         type = type->
next();
 
 3207                         type = type->
next();
 
 3220             if (type->
str() == 
"<") {
 
 3224                     type = type->
tokAt(2);
 
 3231                     type = type->
next();
 
 3233                 type = type->
next();
 
 3237             std::list<std::string> pointers;
 
 3239                 pointers.push_back(type->
str());
 
 3240                 type = type->
next();
 
 3244             if (type && type->
str() == 
"[") {
 
 3252                             type = type->
next();
 
 3257                         else if (type->
next()->
str() == 
";")
 
 3259                         else if (type->
str() == 
"]")
 
 3262                             type = type->
next();
 
 3265                     type = type->
next();
 
 3266                 } 
while (type && type->
str() == 
"[");
 
 3270             if (!tok1 || !tok1->
next())
 
 3275             if (type && type == usingEnd) {
 
 3286                     std::string removed1 = std::move(removed);
 
 3287                     std::string::size_type idx = removed1.rfind(
" ::");
 
 3288                     if (idx != std::string::npos)
 
 3289                         removed1.resize(idx);
 
 3291                         ScopeInfo3 * tempScope = currentScope;
 
 3292                         while (tempScope->parent) {
 
 3293                             if (tempScope->recordTypes.find(start->
str()) != tempScope->recordTypes.end()) {
 
 3294                                 std::string::size_type spaceIdx = 0;
 
 3295                                 std::string::size_type startIdx = 0;
 
 3296                                 while ((spaceIdx = removed1.find(
' ', startIdx)) != std::string::npos) {
 
 3298                                     startIdx = spaceIdx + 1;
 
 3304                             idx = removed1.rfind(
" ::");
 
 3305                             if (idx == std::string::npos)
 
 3308                             removed1.resize(idx);
 
 3309                             tempScope = tempScope->parent;
 
 3314                     if (
Token::Match(tok1, 
"%name% ( )") && !pointers.empty()) {
 
 3319                         after = tok2->
next();
 
 3335             usingList.emplace_back(usingStart, usingEnd);
 
 3339     for (std::list<Using>::reverse_iterator it = usingList.rbegin(); it != usingList.rend(); ++it) {
 
 3340         Token *usingStart = it->startTok;
 
 3341         Token *usingEnd = it->endTok;
 
 3343             if (usingEnd->
next())
 
 3350             if (usingEnd->
next()) {
 
 3368         for (
const Token *tok = usingStart; tok && tok != usingEnd; tok = tok->
next()) {
 
 3374         std::list<const Token *> callstack(1, usingStart);
 
 3376                                             "Failed to parse \'" + str + 
"\'. The checking continues anyway.", 
Certainty::normal));
 
 3425     const char* disableValueflowEnv = std::getenv(
"DISABLE_VALUEFLOW");
 
 3426     const bool doValueFlow = !disableValueflowEnv || (std::strcmp(disableValueflowEnv, 
"1") != 0);
 
 3444                     simplecpp::characterLiteralToLL(tok->
str());
 
 3445                 } 
catch (
const std::exception &e) {
 
 3473             tok = tok->
tokAt(2);
 
 3502     const bool cpp = 
isCPP();
 
 3506         const char c1 = tok->
str()[0];
 
 3508         if (tok->
str().length() == 1 && tok->
next()->
str().length() == 1) {
 
 3509             const char c2 = tok->
next()->
str()[0];
 
 3512             if (c2 == 
'=' && (std::strchr(
"+-*/%|^=!<>", c1)) && !
Token::Match(tok->
previous(), 
"%type% *")) {
 
 3515                     const Token* opening =
 
 3520                 tok->
str(tok->
str() + c2);
 
 3524         } 
else if (tok->
next()->
str() == 
"=") {
 
 3525             if (tok->
str() == 
">>") {
 
 3528             } 
else if (tok->
str() == 
"<<") {
 
 3532         } 
else if (cpp && (c1 == 
'p' || c1 == 
'_') &&
 
 3533                    Token::Match(tok, 
"private|protected|public|__published : !!:")) {
 
 3534             bool simplify = 
false;
 
 3537                 if (prev->
str() == 
")") {
 
 3539                 } 
else if (prev->
str() == 
"(") {
 
 3544                 if (par != 0U || prev->
str() == 
"(")
 
 3557                 tok->
str(tok->
str() + 
":");
 
 3560         } 
else if (tok->
str() == 
"->") {
 
 3624             const bool isExtC = tok->
next()->
str().size() == 3;
 
 3625             if (tok->
strAt(2) == 
"{") {
 
 3626                 tok2 = tok2->
next(); 
 
 3627                 while ((tok2 = tok2->
next()) && tok2 != tok->
linkAt(2))
 
 3654         if (
Token::Match(tok, 
"( { %bool%|%char%|%num%|%str%|%name% ; } )")) {
 
 3685         tok = tok->
tokAt(3);
 
 3694             const std::string number(tok->
str());
 
 3696             tok->
str(indexTok->
str());
 
 3698             indexTok->
str(number);
 
 3732         while (tok->
next()) {
 
 3733             if (tok->
str() == 
"+") {
 
 3734                 if (tok->
next()->
str()[0] == 
'-') {
 
 3736                     if (tok->
str().size() == 1) {
 
 3741                         tok->
str(tok->
str().substr(1));
 
 3747             } 
else if (tok->
str() == 
"-") {
 
 3748                 if (tok->
next()->
str()[0] == 
'-') {
 
 3750                     if (tok->
str().size() == 1) {
 
 3755                         tok->
str(tok->
str().substr(1));
 
 3772     auto getStrTok = [](
Token* tok, 
bool addLength, 
Token*& endStmt) -> 
Token* {
 
 3774             endStmt = tok->
tokAt(5);
 
 3775             return tok->
tokAt(4);
 
 3778             tok = tok->
tokAt(4);
 
 3785                 endStmt = tok->
tokAt(parCount + 1);
 
 3795         bool addlength = 
false;
 
 3804         if (
const Token* strTok = getStrTok(tok, addlength, endStmt)) {
 
 3814             for (
Token *tok2 = tok->
tokAt(4); tok2 && tok2 != end; tok2 = tok2->
next()) {
 
 3816                     if (tok2->
str() == 
"[" && tok2->
link()->strAt(1) == 
"=") { 
 
 3824                     tok2 = tok2->
link();
 
 3825                 } 
else if (tok2->
str() == 
",") {
 
 3838             tok = end->
next() ? end->
next() : end;
 
 3847         if (!var || !var->isArray())
 
 3849         if (!
Token::Match(var->nameToken(), 
"%name% [ ] = { ["))
 
 3852         const Token* 
const startToken = var->nameToken()->
tokAt(4);
 
 3853         const Token* 
const endToken = startToken->
link();
 
 3854         for (
const Token* tok = startToken; tok != endToken; tok = tok->
next()) {
 
 3861         if (maxIndex >= 0) {
 
 3863             Token* tok = 
const_cast<Token*
>(var->nameToken()->next());
 
 3875             d.
num = maxIndex + 1;
 
 3876             std::vector<Dimension> dimensions{d};
 
 3877             const_cast<Variable*
>(var)->setDimensions(dimensions);
 
 3885     while (
nullptr != (tok = tok->
next())) {
 
 3886         if (tok->
str() == 
"?") {
 
 3888         } 
else if (tok->
str() == 
":") {
 
 3890             if (colonLevel == 0) {
 
 3910     assert(tok->
str() == 
"case");
 
 3911     while (
nullptr != (tok = tok->
next())) {
 
 3914         else if (tok->
str() == 
"?") {
 
 3928     if (tok->
str() != 
")")
 
 3938     return (tok && tok->
str() == 
"{") ? tok : 
nullptr;
 
 3946     const bool cpp = 
isCPP();
 
 3947     bool executablescope = 
false;
 
 3948     int indentLevel = 0;
 
 3954             executablescope = 
true;
 
 3957         if (!executablescope)
 
 3960         if (tok->
str() == 
"{") {
 
 3965         } 
else if (tok->
str() == 
"}") {
 
 3967             if (indentLevel == 0) {
 
 3968                 executablescope = 
false;
 
 3978             if (tok->
str() != 
":" || tok->
strAt(-1) == 
"case" || !tok->
next())
 
 3986                 tok = tok->
tokAt(2);
 
 3997         if (
Token::Match(tok, 
"case %num%|%char% ... %num%|%char% :")) {
 
 4000             end = std::min(start + 50, end); 
 
 4002                 tok = tok->
tokAt(2);
 
 4020     std::string nextScopeNameAddition;
 
 4021     std::shared_ptr<ScopeInfo2> primaryScope = std::make_shared<ScopeInfo2>(
"", 
nullptr);
 
 4029             if (
Token::Match(tok, 
"using namespace %name% ::|<|;")) {
 
 4030                 std::string usingNamespaceName;
 
 4031                 for (
const Token* namespaceNameToken = tok->
tokAt(2);
 
 4032                      namespaceNameToken && namespaceNameToken->
str() != 
";";
 
 4033                      namespaceNameToken = namespaceNameToken->next()) {
 
 4034                     usingNamespaceName += namespaceNameToken->str();
 
 4035                     usingNamespaceName += 
" ";
 
 4037                 if (!usingNamespaceName.empty())
 
 4038                     usingNamespaceName.pop_back();
 
 4039                 tok->
scopeInfo()->usingNamespaces.insert(std::move(usingNamespaceName));
 
 4040             } 
else if (
Token::Match(tok, 
"namespace|class|struct|union %name% {|::|:|<")) {
 
 4041                 for (
Token* nameTok = tok->
next(); nameTok && !
Token::Match(nameTok, 
"{|:"); nameTok = nameTok->next()) {
 
 4043                         nextScopeNameAddition = 
"";
 
 4046                     nextScopeNameAddition.append(nameTok->str());
 
 4047                     nextScopeNameAddition.append(
" ");
 
 4049                 if (!nextScopeNameAddition.empty())
 
 4050                     nextScopeNameAddition.pop_back();
 
 4065                         if (tok1->
strAt(-1) != 
")")
 
 4068                         tok1 = tok1->
tokAt(-2);
 
 4069                         if (tok1->
strAt(-1) != 
")")
 
 4073                         if (tok1->
strAt(-1) == 
">")
 
 4076                             tok1 = tok1->
tokAt(-2);
 
 4077                             std::string scope = tok1->
strAt(-1);
 
 4079                                 scope = tok1->
strAt(-3) + 
" :: " + scope;
 
 4080                                 tok1 = tok1->
tokAt(-2);
 
 4083                             if (!nextScopeNameAddition.empty() && !scope.empty())
 
 4084                                 nextScopeNameAddition += 
" :: ";
 
 4085                             nextScopeNameAddition += scope;
 
 4091                 std::shared_ptr<ScopeInfo2> newScopeInfo = std::make_shared<ScopeInfo2>(tok->
scopeInfo()->name, tok->
link(), tok->
scopeInfo()->usingNamespaces);
 
 4093                 if (!newScopeInfo->name.empty() && !nextScopeNameAddition.empty())
 
 4094                     newScopeInfo->name.append(
" :: ");
 
 4095                 newScopeInfo->name.append(nextScopeNameAddition);
 
 4096                 nextScopeNameAddition = 
"";
 
 4100                 tok->
scopeInfo(std::move(newScopeInfo));
 
 4122         std::unordered_map<std::string, nonneg int> mVariableId;
 
 4123         std::unordered_map<std::string, nonneg int> mVariableId_global;
 
 4124         std::stack<std::vector<std::pair<std::string, nonneg int>>> mScopeInfo;
 
 4125         mutable nonneg int mVarId{};
 
 4127         VariableMap() = 
default;
 
 4130         void addVariable(
const std::string& varname, 
bool globalNamespace);
 
 4131         bool hasVariable(
const std::string& varname)
 const {
 
 4132             return mVariableId.find(varname) != mVariableId.end();
 
 4135         const std::unordered_map<std::string, nonneg int>& map(
bool global)
 const {
 
 4136             return global ? mVariableId_global : mVariableId;
 
 4145 void VariableMap::enterScope()
 
 4147     mScopeInfo.emplace();
 
 4150 bool VariableMap::leaveScope()
 
 4152     if (mScopeInfo.empty())
 
 4155     for (
const std::pair<std::string, nonneg int>& outerVariable : mScopeInfo.top()) {
 
 4156         if (outerVariable.second != 0)
 
 4157             mVariableId[outerVariable.first] = outerVariable.second;
 
 4159             mVariableId.erase(outerVariable.first);
 
 4165 void VariableMap::addVariable(
const std::string& varname, 
bool globalNamespace)
 
 4167     if (mScopeInfo.empty()) {
 
 4168         mVariableId[varname] = ++mVarId;
 
 4169         if (globalNamespace)
 
 4170             mVariableId_global[varname] = mVariableId[varname];
 
 4173     std::unordered_map<std::string, nonneg int>::iterator it = mVariableId.find(varname);
 
 4174     if (it == mVariableId.end()) {
 
 4175         mScopeInfo.top().emplace_back(varname, 0);
 
 4176         mVariableId[varname] = ++mVarId;
 
 4177         if (globalNamespace)
 
 4178             mVariableId_global[varname] = mVariableId[varname];
 
 4181     mScopeInfo.top().emplace_back(varname, it->second);
 
 4182     it->second = ++mVarId;
 
 4187     const Token* 
const tok1 = tok;
 
 4192     nonneg int typeCount = 0;
 
 4193     nonneg int singleNameCount = 0;
 
 4194     bool hasstruct = 
false;   
 
 4195     bool bracket = 
false;
 
 4213                 singleNameCount = 0;
 
 4216             } 
else if (!hasstruct && variableMap.map(
false).count(tok2->
str()) && tok2->
previous()->
str() != 
"::") {
 
 4218                 tok2 = tok2->
next();
 
 4219                 if (!tok2 || tok2->
str() != 
"::")
 
 4228             const Token *start = tok;
 
 4232             if (closingBracket == 
nullptr) { 
 
 4235             tok2 = closingBracket;
 
 4236             if (tok2->
str() != 
">")
 
 4238             singleNameCount = 1;
 
 4252                     tok3 = tok3->
link();
 
 4253                 if (tok3->
str() == 
",")
 
 4261         } 
else if (tok2->
str() == 
"::") {
 
 4262             singleNameCount = 0;
 
 4263         } 
else if (tok2->
str() != 
"*" && tok2->
str() != 
"...") {
 
 4266         tok2 = tok2->
next();
 
 4270         bool isLambdaArg = 
false;
 
 4273             if (tok3 && tok3->
str() == 
",") {
 
 4276                         tok3 = tok3->
link();
 
 4287                     if (!
Token::Match(fdecl, 
"[;{}] %name%") || count <= 1)
 
 4302         if (executableScope && ref && !isLambdaArg) {
 
 4305             else if (tok2->
str() != 
")" || tok2->
link()->strAt(-1) != 
"catch")
 
 4312     if (typeCount >= 2 && executableScope && 
Token::Match(tok2, 
")| [")) {
 
 4313         const Token *tok3 = tok2->
str() == 
")" ? tok2->
next() : tok2;
 
 4314         while (tok3 && tok3->
str() == 
"[") {
 
 4315             tok3 = tok3->
link()->next();
 
 4323     return (typeCount >= 2 && tok2 && 
Token::Match(tok2->
tokAt(-2), 
"!!:: %type%"));
 
 4328                                   std::map<
nonneg int, std::map<std::string, nonneg int>>& structMembers,
 
 4335         if (struct_varid == 0)
 
 4338         std::map<std::string, nonneg int>& members = structMembers[struct_varid];
 
 4340         tok = tok->
tokAt(3);
 
 4341         while (tok->
str() != 
"}") {
 
 4346                 const std::map<std::string, nonneg int>::iterator it = members.find(tok->
str());
 
 4347                 if (it == members.end()) {
 
 4348                     members[tok->
str()] = ++varId;
 
 4351                     tok->
varId(it->second);
 
 4364             tok = tok->
tokAt(3);
 
 4368         tok = tok->
tokAt(2);
 
 4369         if (struct_varid == 0)
 
 4372         if (tok->
str() == 
".")
 
 4379         std::map<std::string, nonneg int>& members = structMembers[struct_varid];
 
 4380         const std::map<std::string, nonneg int>::iterator it = members.find(tok->
str());
 
 4381         if (it == members.end()) {
 
 4382             members[tok->
str()] = ++varId;
 
 4385             tok->
varId(it->second);
 
 4393                                      VariableMap& variableMap,
 
 4394                                      const nonneg int scopeStartVarId,
 
 4395                                      std::map<
nonneg int, std::map<std::string, nonneg int>>& structMembers)
 
 4398     const Token* 
const endToken = startToken->
link();
 
 4401     std::string className;
 
 4403         if (!tok->
isName() && tok->
str() != 
":")
 
 4405         if (
Token::Match(tok, 
"class|struct|enum %type% [:{]")) {
 
 4406             className = tok->
next()->
str();
 
 4412     int indentlevel = 0;
 
 4413     bool initList = 
false;
 
 4414     bool inEnum = 
false;
 
 4415     const Token *initListArgLastToken = 
nullptr;
 
 4416     for (
Token *tok = startToken->
next(); tok != endToken; tok = tok->
next()) {
 
 4420             if (tok == initListArgLastToken)
 
 4421                 initListArgLastToken = 
nullptr;
 
 4422             else if (!initListArgLastToken &&
 
 4425                 initListArgLastToken = tok->
link();
 
 4427         if (tok->
str() == 
"{") {
 
 4429             if (initList && !initListArgLastToken)
 
 4432         } 
else if (tok->
str() == 
"}") {
 
 4435         } 
else if (initList && indentlevel == 0 && 
Token::Match(tok->
previous(), 
"[,:] %name% [({]")) {
 
 4436             const std::unordered_map<std::string, nonneg int>::const_iterator it = variableMap.map(
false).find(tok->
str());
 
 4437             if (it != variableMap.map(
false).end()) {
 
 4438                 tok->
varId(it->second);
 
 4440         } 
else if (tok->
isName() && tok->
varId() <= scopeStartVarId) {
 
 4441             if (indentlevel > 0 || initList) {
 
 4446                 if (tok->
next()->
str() == 
"::") {
 
 4447                     if (tok->
str() == className)
 
 4448                         tok = tok->
tokAt(2);
 
 4454                     const std::unordered_map<std::string, nonneg int>::const_iterator it = variableMap.map(
false).find(tok->
str());
 
 4455                     if (it != variableMap.map(
false).end()) {
 
 4456                         tok->
varId(it->second);
 
 4461         } 
else if (indentlevel == 0 && tok->
str() == 
":" && !initListArgLastToken)
 
 4472                                       Token * 
const startToken,
 
 4473                                       const Token * 
const endToken,
 
 4474                                       const std::map<std::string, nonneg int> &varlist,
 
 4475                                       std::map<
nonneg int, std::map<std::string, nonneg int>>& structMembers,
 
 4478     const auto pos = classname.rfind(
' '); 
 
 4479     const std::string lastScope = classname.substr(pos == std::string::npos ? 0 : pos + 1);
 
 4480     for (
Token *tok2 = startToken; tok2 && tok2 != endToken; tok2 = tok2->
next()) {
 
 4492         const std::map<std::string, nonneg int>::const_iterator it = varlist.find(tok2->
str());
 
 4493         if (it != varlist.end()) {
 
 4494             tok2->
varId(it->second);
 
 4519 #define NOTSTART_C "NOT", "case", "default", "goto", "not", "return", "sizeof", "typedef"
 
 4522                                                               "delete", 
"friend", 
"new", 
"throw", 
"using", 
"virtual", 
"explicit", 
"const_cast", 
"dynamic_cast", 
"reinterpret_cast", 
"static_cast", 
"template" 
 4530     VariableMap variableMap;
 
 4531     std::map<nonneg int, std::map<std::string, nonneg int>> structMembers;
 
 4533     std::stack<VarIdScopeInfo> scopeStack;
 
 4535     scopeStack.emplace();
 
 4536     std::stack<const Token *> functionDeclEndStack;
 
 4537     const Token *functionDeclEndToken = 
nullptr;
 
 4538     bool initlist = 
false;
 
 4539     bool inlineFunction = 
false;
 
 4546                 tok = closingBracket;
 
 4550         if (tok == functionDeclEndToken) {
 
 4551             functionDeclEndStack.pop();
 
 4552             functionDeclEndToken = functionDeclEndStack.empty() ? nullptr : functionDeclEndStack.top();
 
 4553             if (tok->
str() == 
":")
 
 4555             else if (tok->
str() == 
";") {
 
 4556                 if (!variableMap.leaveScope())
 
 4558             } 
else if (tok->
str() == 
"{") {
 
 4559                 scopeStack.emplace(
true, scopeStack.top().isStructInit || tok->
strAt(-1) == 
"=",  
false, variableMap.getVarId());
 
 4563                 if (ifToken && ifToken->
str() == 
")")
 
 4564                     ifToken = ifToken->
link();
 
 4569                 if (ifToken && ifToken->
str() == 
"if") {
 
 4571                     variableMap.enterScope();
 
 4574         } 
else if (!initlist && tok->
str()==
"(") {
 
 4575             const Token * newFunctionDeclEnd = 
nullptr;
 
 4576             if (!scopeStack.top().isExecutable)
 
 4579                 const Token* tokenLinkNext = tok->
link()->next();
 
 4581                     tokenLinkNext = tokenLinkNext->
next();
 
 4583                         tokenLinkNext = tokenLinkNext->
next();
 
 4585                             tokenLinkNext = tokenLinkNext->
link()->next();
 
 4588                 if (tokenLinkNext && tokenLinkNext->
str() == 
"{") 
 
 4589                     newFunctionDeclEnd = tokenLinkNext;
 
 4591             if (newFunctionDeclEnd && newFunctionDeclEnd != functionDeclEndToken) {
 
 4592                 functionDeclEndStack.push(newFunctionDeclEnd);
 
 4593                 functionDeclEndToken = newFunctionDeclEnd;
 
 4594                 variableMap.enterScope();
 
 4597             inlineFunction = 
false;
 
 4599             const Token * 
const startToken = (tok->
str() == 
"{") ? tok : tok->
link();
 
 4605                 if (tok->
str() == 
"{") {
 
 4612                         (initlist && tok->
strAt(-1) == 
"}")) {
 
 4613                         isExecutable = 
true;
 
 4615                         isExecutable = ((scopeStack.top().isExecutable || initlist || tok->
strAt(-1) == 
"else") &&
 
 4617                         if (!(scopeStack.top().isStructInit || tok->
strAt(-1) == 
"="))
 
 4618                             variableMap.enterScope();
 
 4621                     scopeStack.emplace(isExecutable, scopeStack.top().isStructInit || tok->
strAt(-1) == 
"=", 
isEnumStart(tok), variableMap.getVarId());
 
 4623                     bool isNamespace = 
false;
 
 4625                         if (tok1->
str() == 
"namespace") {
 
 4631                     if (!initlist && !
isC() && !scopeStack.top().isExecutable && tok->
link() && !isNamespace) {
 
 4634                                                       scopeStack.top().startVarid,
 
 4640                     if (!scopeStack.top().isStructInit) {
 
 4641                         variableMap.leaveScope();
 
 4645                         if (ifToken && ifToken->
str() == 
")")
 
 4646                             ifToken = ifToken->
link()->previous();
 
 4649                         if (startToken->
strAt(-1) == 
"else" || (ifToken && ifToken->
str() == 
"if" && tok->
strAt(1) != 
"else")) {
 
 4651                             variableMap.leaveScope();
 
 4656                     if (scopeStack.empty()) {  
 
 4657                         scopeStack.emplace();
 
 4663         if ((!scopeStack.top().isStructInit &&
 
 4666               (tok->
str() == 
"(" && !scopeStack.top().isExecutable && 
isFunctionHead(tok,
";:")) ||
 
 4667               (tok->
str() == 
"," && (!scopeStack.top().isExecutable || inlineFunction || !tok->
previous()->
varId())) ||
 
 4684                 tok2 = tok2->
next();
 
 4690             if (notstart.find(tok2->
str()) != notstart.end())
 
 4702                     while (tok2 && tok2->
str() != 
"]") {
 
 4704                             variableMap.addVariable(tok2->
str(), 
false);
 
 4705                         tok2 = tok2->
next();
 
 4713             } 
catch (
const Token * errTok) {
 
 4717             if (tok->
str() == 
"(" && 
isFunctionHead(tok, 
"{") && scopeStack.top().isExecutable)
 
 4718                 inlineFunction = 
true;
 
 4723                         for (
Token *declTok = declTypeTok->
linkAt(1); declTok != declTypeTok; declTok = declTok->
previous()) {
 
 4724                             if (declTok->isName() && !
Token::Match(declTok->previous(), 
"::|.") && variableMap.hasVariable(declTok->str()))
 
 4725                                 declTok->varId(variableMap.map(
false).find(declTok->str())->second);
 
 4737                     if (prev2->
isCpp() &&
 
 4743                         if (!scopeStack.top().isExecutable) {
 
 4748                                 if (tok3->
str() == 
"=") {
 
 4753                                 if (tok3->
str() == 
",") {
 
 4762                                     (tok3->
isName() && (variableMap.hasVariable(tok3->
str()) ||
 
 4765                                     tok3->
str() == 
"(" ||
 
 4766                                     notstart.find(tok3->
str()) != notstart.end()) {
 
 4775                     if (tok2->
link() != tok2->
next() && 
 
 4784                     variableMap.addVariable(prev2->
str(), scopeStack.size() <= 1);
 
 4787                         for (
const Token *tok3 = prev2->
next(); tok3 && tok3->
str() != 
";"; tok3 = tok3->
next()) {
 
 4789                                 tok3 = tok3->
link();
 
 4791                                 variableMap.addVariable(tok3->
next()->
str(), 
false);
 
 4799                     if (tok && tok->
str() == 
"<") {
 
 4801                         while (tok != end) {
 
 4804                                 const std::unordered_map<std::string, nonneg int>::const_iterator it = variableMap.map(
false).find(tok->
str());
 
 4805                                 if (it != variableMap.map(
false).end())
 
 4806                                     tok->
varId(it->second);
 
 4822             bool globalNamespace = 
false;
 
 4827                     globalNamespace = 
true;
 
 4836             if (scopeStack.top().isExecutable && 
Token::Match(tok, 
"%name% [,)[]")) {
 
 4843                     if (start->
str() == 
"(") {
 
 4852                     if (start->
varId() > 0)
 
 4860                 const bool isNotstartKeyword = start->
next() && notstart.find(start->
next()->
str()) != notstart.end();
 
 4872                 const std::unordered_map<std::string, nonneg int>::const_iterator it = variableMap.map(globalNamespace).find(tok->
str());
 
 4873                 if (it != variableMap.map(globalNamespace).end()) {
 
 4874                     tok->
varId(it->second);
 
 4884             } 
while (tok && (tok->
isName() || tok->
str() == 
","));
 
 4891     mVarId = variableMap.getVarId();
 
 4896         Member(std::list<std::string> s, std::list<const Token *> ns, 
Token *t) : usingnamespaces(std::move(ns)), scope(std::move(s)), tok(t) {}
 
 4897         std::list<const Token *> usingnamespaces;
 
 4898         std::list<std::string> scope;
 
 4907         ret += (ret.empty() ? 
"" : 
" :: ") + (si.name);
 
 4913     std::list<ScopeInfo2>::const_iterator scopeIt = scopeInfo.cbegin();
 
 4916     for (std::list<std::string>::const_iterator it = scope.cbegin(); it != scope.cend(); ++it) {
 
 4917         if (scopeIt == scopeInfo.cend() || scopeIt->name != *it)
 
 4925             if (scopeIt != scopeInfo.end() && nsToken->
str() == scopeIt->name) {
 
 4926                 nsToken = nsToken->
tokAt(2);
 
 4934         if (scopeIt == scopeInfo.end() || nsToken->
str() != scopeIt->name)
 
 4940     while (scopeIt != scopeInfo.end()) {
 
 4943         if (memberToken->
str() != scopeIt->name)
 
 4945         if (memberToken->
next()->
str() == 
"<") {
 
 4950         memberToken = memberToken->
tokAt(2);
 
 4954     return Token::Match(memberToken, 
"~| %name%") ? memberToken : 
nullptr;
 
 4959     if (scopeInfo.empty())
 
 4968     for (
const Token *ns : member.usingnamespaces) {
 
 4990     return Token::Match(tok, 
"~| %name% (") ? tok : 
nullptr;
 
 4993 template<
typename T>
 
 4996     T* 
const start = tok;
 
 4998         tok = tok->
tokAt(tok->strAt(1) == 
"::" ? 1 : 2);
 
 5000             tok = tok->
tokAt(2);
 
 5003         const bool isTemplate = tok->
str() == 
"<";
 
 5004         tok = tok->link()->next();
 
 5005         if (isTemplate && tok && tok->link())
 
 5006             tok = tok->link()->next();
 
 5013     std::map<nonneg int, std::map<std::string, nonneg int>> structMembers;
 
 5016     std::list<Member> allMemberFunctions;
 
 5017     std::list<Member> allMemberVars;
 
 5019         std::map<const Token *, std::string> endOfScope;
 
 5020         std::list<std::string> scope;
 
 5021         std::list<const Token *> usingnamespaces;
 
 5024                 if (
Token::Match(tok, 
"using namespace %name% ::|;")) {
 
 5027                         endtok = endtok->
tokAt(2);
 
 5029                         usingnamespaces.push_back(tok->
tokAt(2));
 
 5034                     scope.push_back(tok->
strAt(1));
 
 5039             if (tok->
str() == 
"}") {
 
 5040                 const std::map<const Token *, std::string>::iterator it = endOfScope.find(tok);
 
 5041                 if (it != endOfScope.end())
 
 5042                     scope.remove(it->second);
 
 5045             Token* 
const tok1 = tok;
 
 5060                 if (tok->
str() == 
"~")
 
 5072                 allMemberFunctions.emplace_back(scope, usingnamespaces, tok1);
 
 5074                 allMemberVars.emplace_back(scope, usingnamespaces, tok1);
 
 5078     std::list<ScopeInfo2> scopeInfo;
 
 5081     std::map<std::string, std::map<std::string, nonneg int>> varsByClass;
 
 5083         while (tok->
str() == 
"}" && !scopeInfo.empty() && tok == scopeInfo.back().bodyEnd)
 
 5084             scopeInfo.pop_back();
 
 5086         if (!
Token::Match(tok, 
"namespace|class|struct %name% {|:|::|<"))
 
 5090         const std::string scopeName2(scopeName.empty() ? std::string() : (scopeName + 
" :: "));
 
 5092         std::list<const Token*> classnameTokens{ tok->
next() };
 
 5094         while (
Token::Match(tokStart, 
":: %name%") || tokStart->
str() == 
"<") {
 
 5095             if (tokStart->
str() == 
"<") {
 
 5100                 tokStart = closeTok->
next();
 
 5102                 classnameTokens.push_back(tokStart->
next());
 
 5103                 tokStart = tokStart->
tokAt(2);
 
 5107         std::string classname;
 
 5108         for (
const Token *it : classnameTokens)
 
 5109             classname += (classname.empty() ? 
"" : 
" :: ") + it->
str();
 
 5111         std::map<std::string, nonneg int> &thisClassVars = varsByClass[scopeName2 + classname];
 
 5116                     tokStart = tokStart->
next();
 
 5120                 std::string baseClassName = tokStart->
str();
 
 5121                 const Token* baseStart = tokStart;
 
 5123                     baseClassName.insert(0, baseStart->
strAt(-2) + 
" :: ");
 
 5124                     baseStart = baseStart->
tokAt(-2);
 
 5126                 std::string scopeName3(scopeName2);
 
 5127                 while (!scopeName3.empty()) {
 
 5128                     const std::string name = scopeName3 + baseClassName;
 
 5129                     if (varsByClass.find(name) != varsByClass.end()) {
 
 5130                         baseClassName = name;
 
 5134                     if (scopeName3.size() <= 8)
 
 5136                     scopeName3.erase(scopeName3.size() - 4);
 
 5137                     const std::string::size_type pos = scopeName3.rfind(
" :: ");
 
 5138                     if (pos == std::string::npos)
 
 5140                     scopeName3.erase(pos + 4);
 
 5142                 const std::map<std::string, nonneg int>& baseClassVars = varsByClass[baseClassName];
 
 5143                 thisClassVars.insert(baseClassVars.cbegin(), baseClassVars.cend());
 
 5145             tokStart = tokStart->
next();
 
 5151         std::transform(classnameTokens.cbegin(), classnameTokens.cend(), std::back_inserter(scopeInfo), [&](
const Token* tok) {
 
 5152             return ScopeInfo2(tok->str(), tokStart->link());
 
 5155         for (
Token *tok2 = tokStart->
next(); tok2 && tok2 != tokStart->
link(); tok2 = tok2->
next()) {
 
 5158                 if (tok2->
str() == 
"(") {
 
 5162                         tok2 = funcstart->
link();
 
 5167                     if (tok2->
strAt(-1) == 
")")
 
 5169                     tok2 = tok2->
link();
 
 5171                     tok2 = tok2->
link();
 
 5177                             tok2 = tok2->
link();
 
 5183             else if (tok2->
varId() > 0)
 
 5184                 thisClassVars[tok2->
str()] = tok2->
varId();
 
 5188         if (thisClassVars.empty())
 
 5192         for (
const Member &var : allMemberVars) {
 
 5196             if (tok2->
varId() == 0)
 
 5197                 tok2->
varId(thisClassVars[tok2->
str()]);
 
 5200         if (
isC() || tok->
str() == 
"namespace")
 
 5204         for (
const Member &func : allMemberFunctions) {
 
 5209             if (tok2->
str() == 
"~")
 
 5229                 tok3 = tok3->
tokAt(2);
 
 5231                     tok3 = tok3->
next();
 
 5233                     tok3 = tok3->
tokAt(2);
 
 5238                 const std::map<std::string, nonneg int>::const_iterator varpos = thisClassVars.find(tok3->
str());
 
 5239                 if (varpos != thisClassVars.end())
 
 5240                     tok3->
varId(varpos->second);
 
 5243                 if (tok3->
strAt(1) == 
"<") {
 
 5257 static void linkBrackets(
const Tokenizer & tokenizer, std::stack<const Token*>& type, std::stack<Token*>& links, 
Token * 
const token, 
const char open, 
const char close)
 
 5259     if (token->
str()[0] == open) {
 
 5262     } 
else if (token->
str()[0] == close) {
 
 5263         if (links.empty()) {
 
 5267         if (type.top()->str()[0] != open) {
 
 5279     std::stack<const Token*> type;
 
 5280     std::stack<Token*> links1;
 
 5281     std::stack<Token*> links2;
 
 5282     std::stack<Token*> links3;
 
 5284         if (token->link()) {
 
 5285             token->link(
nullptr);
 
 5295     if (!links1.empty()) {
 
 5300     if (!links2.empty()) {
 
 5305     if (!links3.empty()) {
 
 5316     bool isStruct = 
false;
 
 5318     std::stack<Token*> type;
 
 5319     std::stack<Token*> templateTokens;
 
 5326         if (token->link()) {
 
 5329             else if (!type.empty() && 
Token::Match(token, 
"}|]|)")) {
 
 5330                 while (type.top()->str() == 
"<") {
 
 5331                     if (!templateTokens.empty() && templateTokens.top()->next() == type.top())
 
 5332                         templateTokens.pop();
 
 5337         } 
else if (templateTokens.empty() && !isStruct && 
Token::Match(token, 
"%oror%|&&|;")) {
 
 5342             if (token->tokType() == 
Token::eLogicalOp && !type.empty() && type.top()->str() == 
"<") {
 
 5344                 bool foundComparison = 
false;
 
 5345                 while (
Token::Match(prev, 
"%name%|%num%|%str%|%cop%|)|]") && prev != type.top()) {
 
 5346                     if (prev->
str() == 
")" || prev->
str() == 
"]")
 
 5347                         prev = prev->
link();
 
 5351                         foundComparison = 
true;
 
 5354                 if (prev == type.top() && foundComparison)
 
 5357                 foundComparison = 
false;
 
 5358                 while (
Token::Match(next, 
"%name%|%num%|%str%|%cop%|(|[") && next->
str() != 
">") {
 
 5359                     if (next->
str() == 
"(" || next->
str() == 
"[")
 
 5360                         next = next->
link();
 
 5364                         foundComparison = 
true;
 
 5365                     next = next->
next();
 
 5367                 if (next && next->
str() == 
">" && foundComparison)
 
 5371             while (!type.empty() && type.top()->str() == 
"<") {
 
 5376                 if (
Token::Match(end, 
"> %var% ;") && (type.top()->tokAt(-2) == 
nullptr || 
Token::Match(type.top()->tokAt(-2), 
";|}|{")))
 
 5380         } 
else if (token->str() == 
"<" &&
 
 5381                    ((token->previous() && (token->previous()->isTemplate() ||
 
 5382                                            (token->previous()->isName() && !token->previous()->varId()) ||
 
 5383                                            (token->strAt(-1) == 
"]" && (!
Token::Match(token->linkAt(-1)->previous(), 
"%name%|)") || token->linkAt(-1)->previous()->isKeyword())) ||
 
 5384                                            (token->strAt(-1) == 
")" && token->linkAt(-1)->strAt(-1) == 
"operator"))) ||
 
 5387             if (token->previous()->str() == 
"template")
 
 5388                 templateTokens.push(token);
 
 5389         } 
else if (token->str() == 
">" || token->str() == 
">>") {
 
 5390             if (type.empty() || type.top()->str() != 
"<") 
 
 5392             Token * 
const top1 = type.top();
 
 5394             Token * 
const top2 = type.empty() ? nullptr : type.top();
 
 5396             if (!top2 || top2->
str() != 
"<") {
 
 5397                 if (token->str() == 
">>")
 
 5399                 if (!
Token::Match(token->next(), 
"%name%|%cop%|%assign%|::|,|(|)|{|}|;|[|]|:|.|=|?|...") &&
 
 5404             if (token->str() == 
">>" && top1 && top2) {
 
 5411                 if (templateTokens.size() == 2 && (top1 == templateTokens.top() || top2 == templateTokens.top())) {
 
 5412                     templateTokens.pop();
 
 5413                     templateTokens.pop();
 
 5417                 if (
Token::Match(token, 
"> %name%") && !token->next()->isKeyword() &&
 
 5419                     (templateTokens.empty() || top1 != templateTokens.top()))
 
 5422                 if (!templateTokens.empty() && top1 == templateTokens.top())
 
 5423                     templateTokens.pop();
 
 5434         if (
Token::Match(tok, 
"const_cast|dynamic_cast|reinterpret_cast|static_cast")) {
 
 5452                 endToken = endToken->
next();
 
 5453             while (
Token::Match(endToken->
next(), 
"%name%|%num%|%str%|[|(|.|::|++|--|!|~") || (
Token::Match(endToken, 
"%type% * %op%|?|:|const|;|,"))) {
 
 5455                     endToken = endToken->
linkAt(1);
 
 5457                     endToken = endToken->
next();
 
 5475         if (
Token::Match(tok, 
"if|for|while|BOOST_FOREACH %name% (")) {
 
 5480             } 
else if (tok->
strAt(1) == 
"constexpr") {
 
 5620         Token *lt = 
nullptr;
 
 5626             else if (lt && 
Token::Match(tok, 
">|>> %name%|::|(")) {
 
 5627                 const Token * 
const end = tok;
 
 5628                 for (tok = lt; tok != end; tok = tok->
next()) {
 
 5743         if (tok->
str() == 
"(") {
 
 5744             const Token *tok1 = tok;
 
 5748         } 
else if (tok->
str() == 
"@") {
 
 5890             std::cout << 
"<debug>" << std::endl;
 
 5906             std::cout << 
"</debug>" << std::endl;
 
 5917             const Token * typetok = var->typeStartToken();
 
 5918             while (typetok && typetok != var->typeEndToken())
 
 5919                 typetok = typetok->
next();
 
 5921             if (typetok != var->typeEndToken()) {
 
 5925                             "Variable::typeStartToken() of variable '" + var->name() + 
"' is not located before Variable::typeEndToken(). The location of the typeStartToken() is '" + var->typeStartToken()->str() + 
"' at line " + std::to_string(var->typeStartToken()->linenr()));
 
 5939     std::set<const Library::Container*> containers;
 
 5941     outs += 
"  <directivelist>";
 
 5944         outs += 
"    <directive ";
 
 5948         outs += 
"linenr=\"";
 
 5949         outs += std::to_string(dir.linenr);
 
 5958     outs += 
"  </directivelist>";
 
 5962     outs += 
"  <tokenlist>";
 
 5965         outs += 
"    <token id=\"";
 
 5967         outs += 
"\" file=\"";
 
 5969         outs += 
"\" linenr=\"";
 
 5970         outs += std::to_string(tok->
linenr());
 
 5971         outs += 
"\" column=\"";
 
 5972         outs += std::to_string(tok->
column());
 
 5979         outs += 
" scope=\"";
 
 5983             outs += 
" type=\"name\"";
 
 5985                 outs += 
" isUnsigned=\"true\"";
 
 5987                 outs += 
" isSigned=\"true\"";
 
 5989             outs += 
" type=\"number\"";
 
 5991                 outs += 
" isInt=\"true\"";
 
 5993                 outs += 
" isFloat=\"true\"";
 
 5995             outs += 
" type=\"string\" strlen=\"";
 
 6000             outs += 
" type=\"char\"";
 
 6002             outs += 
" type=\"boolean\"";
 
 6003         else if (tok->
isOp()) {
 
 6004             outs += 
" type=\"op\"";
 
 6006                 outs += 
" isArithmeticalOp=\"true\"";
 
 6008                 outs += 
" isAssignmentOp=\"true\"";
 
 6010                 outs += 
" isComparisonOp=\"true\"";
 
 6012                 outs += 
" isLogicalOp=\"true\"";
 
 6015             outs += 
" isCast=\"true\"";
 
 6017             outs += 
" externLang=\"C\"";
 
 6021             outs += 
" isTemplateArg=\"true\"";
 
 6023             outs += 
" isRemovedVoidParameter=\"true\"";
 
 6025             outs += 
" isSplittedVarDeclComma=\"true\"";
 
 6027             outs += 
" isSplittedVarDeclEq=\"true\"";
 
 6029             outs += 
" isImplicitInt=\"true\"";
 
 6031             outs += 
" isComplex=\"true\"";
 
 6033             outs += 
" isRestrict=\"true\"";
 
 6035             outs += 
" isAtomic=\"true\"";
 
 6037             outs += 
" isAttributeExport=\"true\"";
 
 6039             outs += 
" isAttributeMaybeUnused=\"true\"";
 
 6041             outs += 
" isAttributeUnused=\"true\"";
 
 6047         if (tok->
varId() > 0) {
 
 6048             outs += 
" varId=\"";
 
 6049             outs += std::to_string(tok->
varId());
 
 6053             outs += 
" exprId=\"";
 
 6054             outs += std::to_string(tok->
exprId());
 
 6058             outs += 
" variable=\"";
 
 6063             outs += 
" function=\"";
 
 6067         if (!tok->
values().empty()) {
 
 6068             outs += 
" values=\"";
 
 6073             outs += 
" type-scope=\"";
 
 6078             outs += 
" astParent=\"";
 
 6083             outs += 
" astOperand1=\"";
 
 6088             outs += 
" astOperand2=\"";
 
 6093             outs += 
" originalName=\"";
 
 6107                 outs += 
" noreturn=\"true\"";
 
 6113     outs += 
"  </tokenlist>";
 
 6122     containers.erase(
nullptr);
 
 6123     if (!containers.empty()) {
 
 6124         outs += 
"  <containers>";
 
 6127             outs += 
"    <container id=\"";
 
 6129             outs += 
"\" array-like-index-op=\"";
 
 6132             outs += 
"std-string-like=\"";
 
 6137         outs += 
"  </containers>";
 
 6145         outs += 
"  <typedef-info>";
 
 6151             outs += typedefInfo.name;
 
 6159             outs += std::to_string(typedefInfo.lineNumber);
 
 6162             outs += 
" column=\"";
 
 6163             outs += std::to_string(typedefInfo.column);
 
 6167             outs += std::to_string(typedefInfo.used?1:0);
 
 6173         outs += 
"  </typedef-info>";
 
 6205     std::set<std::string> keep;
 
 6209             if (
Token::Match(closingBracket, 
"> class|struct %name% {"))
 
 6210                 tok = closingBracket->
linkAt(3);
 
 6216         if (!checkHeaders && tok->
fileIndex() != 0)
 
 6220             keep.insert(tok->
str());
 
 6225             keep.insert(tok->
str());
 
 6229     const std::set<std::string> functionStart{
"static", 
"const", 
"unsigned", 
"signed", 
"void", 
"bool", 
"char", 
"short", 
"int", 
"long", 
"float", 
"*"};
 
 6232         const bool isIncluded = (tok->
fileIndex() != 0);
 
 6238             while (prev && prev->
isName())
 
 6250             if (isIncluded && removeUnusedIncludedFunctions) {
 
 6253                     while (start && functionStart.find(start->
str()) != functionStart.end())
 
 6254                         start = start->
next();
 
 6263             if (isIncluded && removeUnusedIncludedClasses) {
 
 6264                 if (
Token::Match(tok, 
"class|struct %name% [:{]") && keep.find(tok->
strAt(1)) == keep.end()) {
 
 6267                     if (endToken->
str() == 
":") {
 
 6268                         endToken = endToken->
next();
 
 6270                             endToken = endToken->
next();
 
 6279             if (removeUnusedTemplates || (isIncluded && removeUnusedIncludedTemplates)) {
 
 6282                     if (
Token::Match(closingBracket, 
"> class|struct %name% [;:{]") && keep.find(closingBracket->
strAt(2)) == keep.end()) {
 
 6283                         const Token *endToken = closingBracket->
tokAt(3);
 
 6284                         if (endToken->
str() == 
":") {
 
 6285                             endToken = endToken->
next();
 
 6287                                 endToken = endToken->
next();
 
 6289                         if (endToken && endToken->
str() == 
"{")
 
 6290                             endToken = endToken->
link()->next();
 
 6291                         if (endToken && endToken->
str() == 
";") {
 
 6310             if (
Token::Match(tok, 
"%name%|>|) .|:: template %name%")) {
 
 6315                     templateName = templateName->
next();
 
 6321                     if (templateName->
str() == 
"(" && templateName->
link())
 
 6322                         templateName->
link()->isTemplate(
true);
 
 6333         line = prev->
str() + 
" " + line;
 
 6334     line += 
"!!!" + tok->
str() + 
"!!!";
 
 6336         line += 
" " + next->str();
 
 6342     std::vector<std::pair<std::string, int>> vars;
 
 6346         if (tok->
str() == 
"{")
 
 6348         else if (tok->
str() == 
"}") {
 
 6349             vars.erase(std::remove_if(vars.begin(), vars.end(), [scopeLevel](
const std::pair<std::string, int>& v) {
 
 6350                 return v.second == scopeLevel;
 
 6355             vars.emplace_back(tok->
strAt(2), scopeLevel);
 
 6359             return v.first == tok->previous()->str();
 
 6367             if (endTok && endTok->
str() == 
">>") {
 
 6370             } 
else if (endTok && endTok->
str() == 
">>=") {
 
 6375         } 
else if (
Token::Match(tok, 
"class|struct|union|=|:|public|protected|private %name% <") && std::none_of(vars.begin(), vars.end(), [&](
const std::pair<std::string, int>& v) {
 
 6376             return v.first == tok->next()->str();
 
 6395         if (tok->
str() == 
"(") {
 
 6408             if (tok2 && tok2->
str() == 
"(")
 
 6409                 tok2 = tok2->
link()->next();
 
 6416                 !
Token::Match(tok2, 
"requires|namespace|class|struct|union|private:|protected:|public:"))
 
 6423             if (
Token::Match(tok2, 
"namespace|class|struct|union")) {
 
 6425                 const Token *tok3 = tok2;
 
 6427                     tok3 = tok3->
next();
 
 6428                 if (tok3 && tok3->
str() == 
"{") {
 
 6447                 const Token *tok3 = tok2;
 
 6449                     tok3 = tok3->
tokAt(2);
 
 6459         if (tok->
str() == 
"{") {
 
 6461             while (prev && prev->
isName())
 
 6463             if (prev && prev->
str() == 
")")
 
 6490         if (!
Token::Match(tok, 
"class|struct %name% %name% final| {|:"))
 
 6495         if (nextIsUppercase && !afterNextIsUppercase)
 
 6497         else if (!nextIsUppercase && afterNextIsUppercase)
 
 6509         if (tok->
str() != 
")")
 
 6511         const Token *macro = tok->
link() ? tok->
link()->previous() : 
nullptr;
 
 6512         if (!macro || !macro->
isName())
 
 6527     bool goback = 
false;
 
 6539         const bool isAnonymousNS = tok->
strAt(1) == 
"{";
 
 6540         if (tok->
strAt(3 - isAnonymousNS) == 
"}") {
 
 6549                 if (tok->
str() == 
"{") {
 
 6556             tok = tok->
tokAt(2 - isAnonymousNS);
 
 6564         if (tok->
link() && tok->
str() == 
"(") {
 
 6596     } 
else if (tok->
str()==
"while") {
 
 6599             tokPossibleDo = 
nullptr;
 
 6601             tokPossibleDo = tokPossibleDo->
link();
 
 6602         if (!tokPossibleDo || tokPossibleDo->
strAt(-1) != 
"do")
 
 6604     } 
else if (tok->
str()==
"do") {
 
 6611                 tokEnd=tokEnd->
next();
 
 6612                 if (!tokEnd || tokEnd->
str()!=
"while") 
 
 6620         if (tokEnd->
strAt(1) == 
"else") {
 
 6622             if (!tokEndNextNext || tokEndNextNext->
str() == 
"}")
 
 6624             if (tokEndNextNext->
str() == 
"if")
 
 6641     Token *tokAfterCondition=tokCondition;
 
 6642     if (commandWithCondition) {
 
 6643         if (tokCondition->
str()==
"(")
 
 6644             tokAfterCondition=tokCondition->
link();
 
 6648         if (!tokAfterCondition || tokAfterCondition->
strAt(1) == 
"]")
 
 6651         tokAfterCondition=tokAfterCondition->
next();
 
 6652         if (!tokAfterCondition || 
Token::Match(tokAfterCondition, 
")|}|,")) {
 
 6658     Token * tokStatement = tokAfterCondition;
 
 6661             tokStatement = tokStatement->
tokAt(2);
 
 6662         else if (tokStatement->
str() == 
"case") {
 
 6666             if (tokStatement->
str() != 
":")
 
 6668             tokStatement = tokStatement->
next();
 
 6674     Token * tokBracesEnd=
nullptr;
 
 6675     if (tokStatement->
str() == 
"{") {
 
 6677         if (tokStatement != tokAfterCondition) {
 
 6681         tokBracesEnd = tokStatement->
link();
 
 6694         tokBracesEnd = tokCloseBrace;
 
 6699         if (tokEnd->
str()!=
"}") {
 
 6704                     tokEnd = tokEnd->
link();
 
 6710                 tokEnd=tokEnd->
next();
 
 6712             if (!tokEnd || tokEnd->
str() != 
";") {
 
 6728         tokBracesEnd=tokCloseBrace;
 
 6731     return tokBracesEnd;
 
 6743                  !(tok->
strAt(-1) == 
":" || tok->
strAt(-1) == 
"," || tok->
strAt(-1) == 
"::")) {
 
 6747             std::map<std::string, Token *> argumentNames;
 
 6748             bool bailOut = 
false;
 
 6749             Token * tokparam = 
nullptr;
 
 6752             const std::string& funcName(tok->
str());
 
 6757             while (
nullptr != (tok1 = tok1->
tokAt(2))) {
 
 6764                 if (argumentNames.find(tok1->
str()) != argumentNames.end())
 
 6766                 else if (tok1->
str() != funcName)
 
 6767                     argumentNames[tok1->
str()] = tok1;
 
 6769                     if (tok1->
next()->
str() == 
")") {
 
 6771                             tok1 = tok1->
tokAt(-2);
 
 6780                         tok1 = tok1->
tokAt(-2);
 
 6785                 if (tok1->
next()->
str() == 
")") {
 
 6786                     tok1 = tok1->
tokAt(2);
 
 6788                     if (!tok1 || !tok1->
isName())
 
 6802             tok1 = tok->
link()->next();
 
 6805             for (
const Token* tok2 = tok1; tok2; tok2 = tok2->
next()) {
 
 6808                 if (tok2->
str() == 
"{") {
 
 6820             std::map<std::string, Token *> argumentNames2;
 
 6822             while (tok1 && tok1->
str() != 
"{") {
 
 6827                 if (tok1->
str() == 
";") {
 
 6832                     while (tok2->
str() == 
"]")
 
 6833                         tok2 = tok2->
link()->previous();
 
 6841                     if (argumentNames2.find(tok2->
str()) != argumentNames2.end()) {
 
 6845                         argumentNames2[tok2->
str()] = tok2;
 
 6847                     if (argumentNames.find(tok2->
str()) == argumentNames.end()) {
 
 6853                 tok1 = tok1->
next();
 
 6856             if (bailOut || !tok1) {
 
 6863             if (argumentNames.size() != argumentNames2.size()) {
 
 6866                 for (
const std::pair<const std::string, Token *>& argumentName : argumentNames) {
 
 6867                     if (argumentNames2.find(argumentName.first) == argumentNames2.end()) {
 
 6872                         argumentNames2[argumentName.first] = tok1->
next();
 
 6878             while (tok->
str() != 
")") {
 
 6881                 Token *declEnd = declStart;
 
 6884                 while (declEnd->
next()->
str() != 
";" && declEnd->
next()->
str() != 
"{")
 
 6885                     declEnd = declEnd->
next();
 
 6894                 tok = declEnd->
next();
 
 6897                 if (tok->
str() == 
",")
 
 6939         if (
Token::Match(tok, 
"( %type% %type%| *| *| ( * ) (") ||
 
 6940             Token::Match(tok, 
"static_cast < %type% %type%| *| *| ( * ) (")) {
 
 6943             if (tok1->
isCpp() && tok1->
str() == 
"static_cast")
 
 6944                 tok1 = tok1->
next();
 
 6946             tok1 = tok1->
next();
 
 6949                 tok1 = tok1->
next();
 
 6951             while (tok1->
next()->
str() == 
"*")
 
 6952                 tok1 = tok1->
next();
 
 6969         if (
Token::Match(tok, 
"delete|else|return|throw|typedef"))
 
 6977             tok2 = tok2->
next();
 
 6978         if (!tok2 || tok2->
str() != 
"(")
 
 6981             tok2 = tok2->
tokAt(2);
 
 6984         tok2 = tok2->
tokAt(2);
 
 6985         if (tok2->
str() == 
"*")
 
 6986             tok2 = tok2->
next();
 
 6988             tok2 = tok2->
next();
 
 6995         while (tok && tok->
str() != 
"(")
 
 6999         if (!tok || !tok->
link() || !tok->
link()->next()) {
 
 7002         Token *endTok = tok->
link()->next()->link();
 
 7004             endTok = endTok->
linkAt(2);
 
 7005         if (!
Token::Match(endTok, 
") const|volatile| const|volatile| ;|,|)|=|[|{"))
 
 7016             tok->
link()->deleteThis();
 
 7026                 if (tok3->
str() == 
"<" && tok3->
link())
 
 7027                     tok3 = tok3->
link();
 
 7029                     tok3 = tok3->
link();
 
 7030                 else if (tok3->
str() == 
"(") {
 
 7031                     tok3 = tok3->
link();
 
 7033                         tok3 = tok3->
next();
 
 7060     bool finishedwithkr = 
true;
 
 7061     bool scopeDecl = 
false;
 
 7062     for (
Token *tok = tokBegin; tok != tokEnd; tok = tok->
next()) {
 
 7075                         !
Token::Match(tok, 
"else|try|do|const|constexpr|override|volatile|noexcept"))) {
 
 7083                         lambdaStart = lambdaStart->
link();
 
 7104         if (only_k_r_fpar && finishedwithkr) {
 
 7113         } 
else if (tok->
str() == 
"(") {
 
 7115                 for (
Token * tok2 = tok; tok2 && tok2 != tok->
link(); tok2 = tok2->
next()) {
 
 7119                         Token * lambdaBody = tok2;
 
 7120                         while (lambdaBody && lambdaBody != tok2->
link() && lambdaBody->
str() != 
"{")
 
 7121                             lambdaBody = lambdaBody->
next();
 
 7122                         if (lambdaBody && lambdaBody != tok2->
link() && lambdaBody->
link())
 
 7140         if (
Token::Match(type0, 
"else|return|public:|protected:|private:"))
 
 7142         if (isCPP11 && type0->
str() == 
"using")
 
 7147         bool isconst = 
false;
 
 7148         bool isstatic = 
false;
 
 7149         Token *tok2 = type0;
 
 7153             tok2 = tok2->
next();
 
 7160                 tok2 = tok2->
next();
 
 7171                 tok2 = tok2->
next();
 
 7178             if (tok2->
strAt(1) == 
"*")
 
 7184             tok2 = tok2->
next();
 
 7189         if (
Token::Match(tok2, 
"%type% *|&| %name% , %type% *|&| %name%"))
 
 7193             tok2 = tok2->
next();
 
 7200             tok2 = tok2->
next();
 
 7210             tok2 = tok2->
tokAt(2);
 
 7213             int indentlevel = 0;
 
 7216             for (
Token *tok3 = tok2; tok3; tok3 = tok3->
next()) {
 
 7219                 if (!parens && tok3->
str() == 
"<") {
 
 7221                 } 
else if (!parens && tok3->
str() == 
">") {
 
 7222                     if (indentlevel == 0) {
 
 7223                         tok2 = tok3->
next();
 
 7227                 } 
else if (!parens && tok3->
str() == 
">>") {
 
 7228                     if (indentlevel <= 1) {
 
 7229                         tok2 = tok3->
next();
 
 7233                 } 
else if (tok3->
str() == 
"(") {
 
 7235                 } 
else if (tok3->
str() == 
")") {
 
 7241                 } 
else if (tok3->
str() == 
";") {
 
 7248                 tok2 = tok2->
next();
 
 7259             Token *varName = tok2;
 
 7261                 varName = varName->
next();
 
 7267             bool isPointerOrRef = 
false;
 
 7269                 isPointerOrRef = 
true;
 
 7270                 varName = varName->
next();
 
 7274                 if (varName->
str() != 
"const" && varName->
str() != 
"volatile") {
 
 7277                 varName = varName->
next();
 
 7283                 Token *endDecl = varName->
link()->linkAt(1);
 
 7284                 varName = varName->
link()->previous();
 
 7286                 endDecl = endDecl->
next();
 
 7294                 if (varName->
str() != 
"operator") {
 
 7295                     tok2 = varName->
next(); 
 
 7297                     if (tok2->
str() == 
"=" && (isstatic || (isconst && !isPointerOrRef))) {
 
 7299                         while (tok2 && tok2->
str() != 
"," && tok2->
str() != 
";") {
 
 7301                                 tok2 = tok2->
link();
 
 7302                             const Token *tok3 = tok2;
 
 7308                             tok2 = tok2->
next();
 
 7310                         if (tok2 && tok2->
str() == 
";")
 
 7319                 tok2 = varName->
next();
 
 7322                     tok2 = tok2->
link()->next();
 
 7325                 if (tok2 && tok2->
str() == 
"=") {
 
 7326                     while (tok2 && tok2->
str() != 
"," && tok2->
str() != 
";") {
 
 7328                             tok2 = tok2->
link();
 
 7329                         tok2 = tok2->
next();
 
 7331                     if (tok2 && tok2->
str() == 
";")
 
 7338                 tok2 = varName->
next();
 
 7339                 tok2 = tok2->
link();
 
 7341                     tok2 = tok2->
next();
 
 7342                 if (tok2 && tok2->
str() != 
",")
 
 7349                 while (
Token::Match(commaTok, 
"const|noexcept|override|final")) {
 
 7350                     commaTok = commaTok->
next();
 
 7352                         commaTok = commaTok->
link()->next();
 
 7365                 finishedwithkr = 
false;
 
 7369         if (tok2->
str() == 
",") {
 
 7381                     tok2 = tok2->
link();
 
 7386                 else if (std::strchr(
";,", tok2->
str()[0])) {
 
 7390                         varTok = varTok->
next();
 
 7398                     if (tok2->
str() == 
",") {
 
 7406                     tok2 = tok2->
next();
 
 7409         finishedwithkr = (only_k_r_fpar && tok2 && tok2->
strAt(1) == 
"{");
 
 7417     const std::string qualifiers[] = {
"extern", 
"static", 
"const"};
 
 7422         bool continue2 = 
false;
 
 7423         for (
int i = 0; i < 
sizeof(qualifiers)/
sizeof(qualifiers[0]); i++) {
 
 7426             if (!tok->
next() || tok->
next()->
str() != qualifiers[i])
 
 7430             Token* leftTok = tok;
 
 7431             bool behindOther = 
false;
 
 7432             for (; leftTok; leftTok = leftTok->
previous()) {
 
 7433                 for (
int j = 0; j <= i; j++) {
 
 7434                     if (leftTok->
str() == qualifiers[j]) {
 
 7449                     (
isCPP() && 
Token::Match(leftTok, 
"private:|protected:|public:|operator|template"))) {
 
 7458             if (leftTok && !behindOther && !
Token::Match(leftTok, 
";|{|}|(|,|private:|protected:|public:")) {
 
 7469             } 
else if (leftTok->
next()) {
 
 7471                 tok = leftTok->
next();
 
 7485         if (
Token::Match(tok, 
"%name% = %name% = %num%|%name% ;")) {
 
 7489                    tok2->
str() == 
"=" &&
 
 7491                 tok2 = tok2->
tokAt(-2);
 
 7494             if (!tok2 || tok2->
str() != 
";") {
 
 7500             const std::string& value(valueTok->
str());
 
 7501             tok2 = tok2->
next();
 
 7503             while (tok2 != stopAt) {
 
 7506                 tok2 = tok2->
tokAt(4);
 
 7514     std::make_pair(
"and", 
"&&")
 
 7515     , std::make_pair(
"and_eq", 
"&=")
 
 7516     , std::make_pair(
"bitand", 
"&")
 
 7517     , std::make_pair(
"bitor", 
"|")
 
 7518     , std::make_pair(
"not_eq", 
"!=")
 
 7519     , std::make_pair(
"or", 
"||")
 
 7520     , std::make_pair(
"or_eq", 
"|=")
 
 7521     , std::make_pair(
"xor", 
"^")
 
 7522     , std::make_pair(
"xor_eq", 
"^=")
 
 7540     int executableScopeLevel = 0;
 
 7542     std::vector<Token *> alt;
 
 7543     bool replaceAll = 
false;  
 
 7546         if (tok->
str() == 
")") {
 
 7548                 ++executableScopeLevel;
 
 7549                 tok = 
const_cast<Token *
>(end);
 
 7554         if (tok->
str() == 
"{") {
 
 7555             if (executableScopeLevel > 0)
 
 7556                 ++executableScopeLevel;
 
 7560         if (tok->
str() == 
"}") {
 
 7561             if (executableScopeLevel > 0)
 
 7562                 --executableScopeLevel;
 
 7569         const std::unordered_map<std::string, std::string>::const_iterator cOpIt = 
cAlternativeTokens.find(tok->
str());
 
 7577             if (!
Token::Match(tok->
previous(), 
"%name%|%num%|%char%|)|]|> %name% %name%|%num%|%char%|%op%|("))
 
 7581             if (executableScopeLevel == 0 && 
Token::Match(tok, 
"%name% (")) {
 
 7582                 const Token *start = tok;
 
 7600                 (executableScopeLevel == 0U && tok->
strAt(-1) == 
"("))
 
 7610     for (
Token *tok: alt) {
 
 7611         const std::unordered_map<std::string, std::string>::const_iterator cOpIt = 
cAlternativeTokens.find(tok->
str());
 
 7613             tok->
str(cOpIt->second);
 
 7614         else if (tok->
str() == 
"not")
 
 7620     return !alt.empty();
 
 7634         if (tok->
str() == 
"return")
 
 7637         if (
Token::Match(tok, 
"class|struct|union| %type% *| %name% ( &| %any% ) ;")) {
 
 7639         } 
else if (
Token::Match(tok, 
"%type% *| %name% ( %type% (")) {
 
 7642                 tok2 = tok2->
next();
 
 7645         } 
else if (
Token::Match(tok, 
"class|struct|union| %type% *| %name% ( &| %any% ) ,") && tok->
str() != 
"new") {
 
 7647             while (tok1->
str() != 
",")
 
 7648                 tok1 = tok1->
next();
 
 7651             const int numTokens = (
Token::Match(tok, 
"class|struct|union")) ? 2U : 1U;
 
 7662         if (tok->
strAt(2) != 
"*")
 
 7671     if (tok->
str() == 
"*")
 
 7675     if (tok->
str() == 
"sizeof")
 
 7688     tok = tok->
tokAt(2);
 
 7692     tok = tok->
tokAt(2);
 
 7695     tok->
link()->deleteThis();
 
 7706         if (tok->
str() != 
"else")
 
 7715         if (tok->
strAt(1) != 
"if")
 
 7718         for (
Token *tok2 = tok; tok2; tok2 = tok2->
next()) {
 
 7720                 tok2 = tok2->
link();
 
 7723                 if (tok2->
next() && tok2->
next()->
str() != 
"else") {
 
 7749                 semicolon = semicolon->
link();
 
 7750             semicolon = semicolon->
next();
 
 7752         if (semicolon->
str() != 
";")
 
 7755         if (tok->
str() ==  
"for") {
 
 7761             bool rangeFor = 
false;
 
 7763                 if (tok2->
str() == 
"(")
 
 7764                     tok2 = tok2->
link();
 
 7765                 else if (!rangeFor && tok2->
str() == 
"?")
 
 7767                 else if (tok2->
str() == 
":")
 
 7769                 tok2 = tok2->
next();
 
 7771             if (!rangeFor || tok2->
str() != 
")")
 
 7781             endscope = endscope->
linkAt(2);
 
 7800         if (tok->
str() != 
"(")
 
 7819             bool innerComma = 
false;
 
 7820             for (
const Token *inner = tok->
link()->previous(); inner != tok; inner = inner->
previous()) {
 
 7821                 if (inner->str() == 
")")
 
 7822                     inner = inner->link();
 
 7823                 if (inner->str() == 
",") {
 
 7833         if (tok->
strAt(-2) != 
"operator" &&
 
 7837             tok->
link()->deleteThis();
 
 7847             tok->
link()->tokAt(-2)->deleteNext();
 
 7853             tok->
link()->deleteThis();
 
 7876             tok->
link()->deleteThis();
 
 7884             tok->
link()->deleteThis();
 
 7893             tok->
link()->deleteThis();
 
 7909                 tok2 = tok2->
tokAt(2);
 
 7911             if (tok2 != tok->
link())
 
 7925             tok->
link()->deleteThis();
 
 7932             tok->
link()->deleteThis();
 
 7938         if (
Token::Match(tok, 
"( %bool%|%num% ) %cop%|;|,|)") &&
 
 7939             tok->
strAt(-2) != 
"operator" &&
 
 7943             tok->
link()->deleteThis();
 
 7951             while (
Token::Match(tok2, 
"%type%|static|const|extern") && tok2->
str() != 
"operator") {
 
 7967     static const std::unordered_map<std::string, std::string> intrinsics = {
 
 7968         { 
"__has_nothrow_assign", 
"has_nothrow_assign" },
 
 7969         { 
"__has_nothrow_constructor", 
"has_nothrow_constructor" },
 
 7970         { 
"__has_nothrow_copy", 
"has_nothrow_copy" },
 
 7971         { 
"__has_trivial_assign", 
"has_trivial_assign" },
 
 7972         { 
"__has_trivial_constructor", 
"has_trivial_constructor" },
 
 7973         { 
"__has_trivial_copy", 
"has_trivial_copy" },
 
 7974         { 
"__has_trivial_destructor", 
"has_trivial_destructor" },
 
 7975         { 
"__has_virtual_destructor", 
"has_virtual_destructor" },
 
 7976         { 
"__is_abstract", 
"is_abstract" },
 
 7977         { 
"__is_aggregate", 
"is_aggregate" },
 
 7978         { 
"__is_assignable", 
"is_assignable" },
 
 7979         { 
"__is_base_of", 
"is_base_of" },
 
 7980         { 
"__is_class", 
"is_class" },
 
 7981         { 
"__is_constructible", 
"is_constructible" },
 
 7982         { 
"__is_convertible_to", 
"is_convertible_to" },
 
 7983         { 
"__is_destructible", 
"is_destructible" },
 
 7984         { 
"__is_empty", 
"is_empty" },
 
 7985         { 
"__is_enum", 
"is_enum" },
 
 7986         { 
"__is_final", 
"is_final" },
 
 7987         { 
"__is_nothrow_assignable", 
"is_nothrow_assignable" },
 
 7988         { 
"__is_nothrow_constructible", 
"is_nothrow_constructible" },
 
 7989         { 
"__is_nothrow_destructible", 
"is_nothrow_destructible" },
 
 7990         { 
"__is_pod", 
"is_pod" },
 
 7991         { 
"__is_polymorphic", 
"is_polymorphic" },
 
 7992         { 
"__is_trivially_assignable", 
"is_trivially_assignable" },
 
 7993         { 
"__is_trivially_constructible", 
"is_trivially_constructible" },
 
 7994         { 
"__is_union", 
"is_union" },
 
 7999         auto p = intrinsics.find(tok->
str());
 
 8000         if (p == intrinsics.end())
 
 8004         tok->
str(p->second);
 
 8023     std::string unknownFunc;
 
 8029         *unknown = !unknownFunc.empty();
 
 8041                         "checkLibraryNoReturn",
 
 8042                         "--check-library: Function " + unknownFunc + 
"() should have <noreturn> configuration");
 
 8083                 tok->
strAt(1) + 
" " +
 
 8084                 tok->
strAt(2) + 
" " +
 
 8085                 tok->
strAt(3) + 
"' is not handled. You can use -I or --include to add handling of this code.");
 
 8092                 "macroWithSemicolon",
 
 8093                 "Ensure that '" + macroName + 
"' is defined either using -I, --include or -D.");
 
 8104     std::string s = tok ? (
" " + tok->
str()) : 
"";
 
 8105     for (
int i = 0; i < s.size(); ++i) {
 
 8106         if ((
unsigned char)s[i] >= 0x80)
 
 8112                 "nonStandardCharLiteral",
 
 8113                 "Non-standard character literal" + s + 
". " + msg);
 
 8157         for (
const Token *tok2 = tok->
tokAt(2); tok2 && tok2->
str() != 
")"; tok2 = tok2->
next()) {
 
 8158             if (tok2->
str() == 
";") {
 
 8163                 tok2 = tok2->
link();
 
 8174         if (
Token::Match(tok, 
"const_cast|dynamic_cast|reinterpret_cast|static_cast <"))
 
 8180                 tok2 = tok2->
next();
 
 8188         if (
Token::Match(tok, 
"template < class|typename %name% [,>]"))
 
 8199     std::stack<const Token *> linkTokens;
 
 8200     const Token *lastTok = 
nullptr;
 
 8204             if (tok->
link() == 
nullptr)
 
 8207             linkTokens.push(tok);
 
 8211             if (tok->
link() == 
nullptr)
 
 8214             if (linkTokens.empty())
 
 8217             if (tok->
link() != linkTokens.top())
 
 8220             if (tok != tok->
link()->link())
 
 8226         else if (tok->
link() != 
nullptr)
 
 8230     if (!linkTokens.empty())
 
 8240     std::stack<const Token *> ternaryOp;
 
 8241     for (
const Token *tok = begin; tok != end && tok->
str() != 
";"; tok = tok->
next()) {
 
 8242         if (tok->
str() == 
"?")
 
 8243             ternaryOp.push(tok);
 
 8244         else if (!ternaryOp.empty() && tok->
str() == 
":")
 
 8253     return ternaryOp.empty() ? nullptr : ternaryOp.top();
 
 8266 template<
typename T>
 
 8272         return tok->next()->link();
 
 8324         for (
const Token *inner = tok->
tokAt(2); inner != endTok; inner = inner->
next()) {
 
 8326                 inner = inner->
link();
 
 8327             else if (inner->str() == 
";")
 
 8337         for (
const Token *inner = tok->
tokAt(2); inner != endTok; inner = inner->
next()) {
 
 8339                 inner = inner->
link();
 
 8340             else if (
Token::Match(inner->previous(), 
"[,(] . %name% =|{"))
 
 8346     std::set<std::string> possible;
 
 8349         if (tok->
str() == 
"{") {
 
 8351             while (prev && prev->
isName())
 
 8353             if (prev && prev->
str() == 
")")
 
 8357         } 
else if (tok->
str() == 
"}")
 
 8367             for (
const Token *tok2 = bodyStart; tok2 && tok2 != bodyEnd; tok2 = tok2->
next()) {
 
 8373                 if (possible.count(tok->
str()) == 0)
 
 8374                     possible.insert(tok->
str());
 
 8417         if (tok2->
next()->
str() == 
"(") {
 
 8430     static const std::unordered_set<std::string> nonConsecutiveKeywords{ 
"break",
 
 8447         else if (tok->
str() == 
"[") {
 
 8448             for (
const Token* inner = tok->
next(); inner != tok->
link(); inner = inner->next()) {
 
 8450                     inner = inner->link();
 
 8471         else if (
Token::Match(tok, 
"%name% throw|return") && std::isupper(tok->
str()[0]))
 
 8475         else if (
Token::Match(tok, 
"!!) %num%|%str%|%char% %assign%|++|--")) {
 
 8480             if (tok->
link()->previous() && tok->
link()->previous()->isUpperCaseName())
 
 8490                     while (prev && prev->
str() != 
"(") {
 
 8491                         if (prev->
str() == 
")")
 
 8492                             prev = prev->
link();
 
 8503             if (tok->
str() != 
"for") {
 
 8510         if (tok->
isKeyword() && nonConsecutiveKeywords.count(tok->
str()) != 0) {
 
 8511             if (
Token::Match(tok, 
"%name% %name%") && nonConsecutiveKeywords.count(tok->
next()->
str()) == 1)
 
 8513             const Token* prev = tok;
 
 8514             while (prev && prev->
isName())
 
 8530                 tok2 = tok2->
next();
 
 8534                     tok2 = tok2->
next();
 
 8536                     syntaxError(tok2, 
"Unexpected token '" + (tok2 ? tok2->
str() : 
"") + 
"'");
 
 8544     static const std::unordered_set<std::string> nonGlobalKeywords{
"break",
 
 8555         if (tok->
str() == 
"{")
 
 8558             syntaxError(tok, 
"keyword '" + tok->
str() + 
"' is not allowed in global scope");
 
 8568             const Token *switchToken = tok;
 
 8573             for (; tok; tok = tok->
next()) {
 
 8574                 if (tok->
str() == 
"{") {
 
 8579                     if (tok->
str() == 
"}" && tok->
strAt(-1) == 
":") 
 
 8586         } 
else if (tok->
str() == 
"(") {
 
 8588         } 
else if (tok->
str() == 
"case") {
 
 8597         int semicolons = 0, colons = 0;
 
 8598         const Token* 
const startTok = tok;
 
 8599         tok = tok->
next()->
link()->previous(); 
 
 8601         for (; tok != startTok; tok = tok->
previous()) {
 
 8602             if (tok->
str() == 
";") { 
 
 8604             } 
else if (tok->
str() == 
":") {
 
 8606             } 
else if (tok->
str() == 
")") { 
 
 8615         if (semicolons == 0 && colons == 0)
 
 8620     const Token *templateEndToken = 
nullptr;
 
 8622         if (!templateEndToken) {
 
 8626             if (templateEndToken == tok)
 
 8627                 templateEndToken = 
nullptr;
 
 8637             bool match1 = 
Token::Match(tok, 
"%or%|%oror%|==|!=|+|-|/|!|>=|<=|~|^|++|--|::|sizeof");
 
 8638             bool match2 = 
Token::Match(tok->
next(), 
"{|if|else|while|do|for|return|switch|break");
 
 8640                 match1 = match1 || 
Token::Match(tok, 
"throw|decltype|typeof");
 
 8646             if (match1 && match2)
 
 8649         if (
Token::Match(tok, 
"%or%|%oror%|~|^|!|%comp%|+|-|/|%")) {
 
 8654                 code = tok->
str() + 
"()";
 
 8655             if (!code.empty()) {
 
 8662         if (
Token::Match(tok, 
"%assign% typename|class %assign%"))
 
 8668         if (
Token::Match(tok, 
"[;([{] %comp%|%oror%|%or%|%|/"))
 
 8676             if (
Token::Match(tok->
previous(), 
"(|[|{|<|%assign%|%or%|%oror%|==|!=|+|-|/|!|>=|<=|~|^|::|sizeof"))
 
 8680             if (
Token::Match(tok->
next(), 
")|]|>|%assign%|%or%|%oror%|==|!=|/|>=|<=|&&"))
 
 8719             for (
const Token* inner = tok->
next(); inner != end; inner = inner->
next()) {
 
 8720                 if (inner->str() == 
"{")
 
 8721                     inner = inner->link();
 
 8733         if (tok->
str() == 
"typedef") {
 
 8734             for (
const Token* tok2 = tok->
next(); tok2 && tok2->
str() != 
";"; tok2 = tok2->
next()) {
 
 8735                 if (tok2->
str() == 
"{") {
 
 8736                     tok2 = tok2->
link();
 
 8763         if (
Token::Match(end, 
"void|char|short|int|long|float|double|const|volatile|static|inline|struct|class|enum|union|template|sizeof|case|break|continue|typedef"))
 
 8782             const Token * 
const tok1 = tok;
 
 8803     for (
const Token *tok = start; tok != end; tok = tok->
next()) {
 
 8806         if (!allowSemicolon && tok->
str() == 
";")
 
 8808         if (tok->
str() == 
"{")
 
 8816     std::string str = source;
 
 8818     for (std::string::size_type i = 0; i + 1U < str.size(); ++i) {
 
 8824         if (str[i+1] == 
'x') {
 
 8826             while (sz < 4 && std::isxdigit((
unsigned char)str[i+sz]))
 
 8829                 std::istringstream istr(str.substr(i+2, sz-2));
 
 8830                 istr >> std::hex >> c;
 
 8836             std::istringstream istr(str.substr(i+1, sz-1));
 
 8837             istr >> std::oct >> c;
 
 8838             str = str.replace(i, sz, std::string(1U, (
char)c));
 
 8844         else if (i+sz < str.size())
 
 8845             str.replace(i, sz, std::string(1U, (
char)c));
 
 8847             str.replace(i, str.size() - i - 1U, 
"a");
 
 8867             syntaxError(tryStartToken, 
"Invalid function-try-catch block code. Did not find '{' for try body.");
 
 8870         Token * 
const tryEndToken = tryStartToken->
link();
 
 8871         Token * endToken = tryEndToken;
 
 8876             if (endToken->
str() != 
"{") {
 
 8880             endToken = endToken->
link();
 
 8882         if (!endToken || endToken == tryEndToken)
 
 8891 static bool isAnonymousEnum(
const Token* tok)
 
 8898     if (end->
str() == 
":") {
 
 8908     const bool cpp = 
isCPP();
 
 8920                 tok->
insertToken(
"Anonymous" + std::to_string(count++));
 
 8926             if (tok1 && 
Token::Match(tok1->
link(), 
"} const| *|&| const| %type% ,|;|[|(|{")) {
 
 8927                 tok->
insertToken(
"Anonymous" + std::to_string(count++));
 
 8931         else if (isAnonymousEnum(tok)) {
 
 8934                 start->
next()->
link()->deleteThis();
 
 8937             tok->
insertToken(
"Anonymous" + std::to_string(count++));
 
 8942     std::stack<const Token*> scopeStart;
 
 8943     const Token* functionEnd = 
nullptr;
 
 8948         if (tok->
str() == 
"{") {
 
 8949             scopeStart.push(tok);
 
 8951                 functionEnd = tok->
link();
 
 8955         else if (tok->
str() == 
"}") {
 
 8956             if (!scopeStart.empty())
 
 8958             if (tok == functionEnd)
 
 8959                 functionEnd = 
nullptr;
 
 8963         else if (
Token::Match(tok, 
"class|struct|union|enum %type% :|{")) {
 
 8971                 next = next->
next();
 
 8972             if (!next || next->
str() == 
";")
 
 8979             if (
Token::Match(after->
next(), 
"const|static|volatile| *|&| const| (| %type% )| ,|;|[|=|(|{")) {
 
 8981                 after = after->
next();
 
 8982                 while (!
Token::Match(start, 
"struct|class|union|enum")) {
 
 8984                     after = after->
next();
 
 8991                 if (start->
str() != 
"class") {
 
 8993                     after = after->
next();
 
 8996                 after = after->
tokAt(2);
 
 8999                     after->
link()->deleteThis();
 
 9006                     after = after->
next();
 
 9007                     const bool isEnum = start->
str() == 
"enum";
 
 9008                     if (!isEnum && cpp) {
 
 9010                         after = after->
next();
 
 9031                 bool isClassStructUnionScope = 
false;
 
 9032                 if (!scopeStart.empty()) {
 
 9035                             isClassStructUnionScope = 
true;
 
 9059         while (
Token::Match(tok, 
"__cdecl|__stdcall|__fastcall|__thiscall|__clrcall|__syscall|__pascal|__fortran|__far|__near") || (windows && 
Token::Match(tok, 
"WINAPI|APIENTRY|CALLBACK"))) {
 
 9065 static bool isAttribute(
const Token* tok, 
bool gcc) {
 
 9066     return gcc ? 
Token::Match(tok, 
"__attribute__|__attribute (") : 
Token::Match(tok, 
"__declspec|_declspec (");
 
 9069 static Token* getTokenAfterAttributes(
Token* tok, 
bool gccattr) {
 
 9071     while (isAttribute(after, gccattr))
 
 9079     Token* 
const after = getTokenAfterAttributes(tok, gccattr);
 
 9084         Token *ftok = after;
 
 9086             if (ftok->
str() == 
"<") {
 
 9091             ftok = ftok->
next();
 
 9094             ftok = ftok->
tokAt(2);
 
 9103                 return prev->
link()->previous();
 
 9105                 return prev->
link()->tokAt(-2);
 
 9108             return prev->
link()->tokAt(-2);
 
 9118         while (isAttribute(tok, 
false)) {
 
 9122                     if (tok->
strAt(2) == 
"noreturn")
 
 9124                     else if (tok->
strAt(2) == 
"nothrow")
 
 9129             } 
else if (tok->
strAt(2) == 
"property")
 
 9130                 tok->
next()->
link()->insertToken(
"__property");
 
 9147         while (isAttribute(tok, 
true)) {
 
 9150             for (
Token *attr = tok->
tokAt(2); attr->
str() != 
")"; attr = attr->next()) {
 
 9152                     attr = attr->linkAt(1);
 
 9154                 if (
Token::Match(attr, 
"[(,] constructor|__constructor__ [,()]")) {
 
 9160                 else if (
Token::Match(attr, 
"[(,] destructor|__destructor__ [,()]")) {
 
 9166                 else if (
Token::Match(attr, 
"[(,] unused|__unused__|used|__used__ [,)]")) {
 
 9167                     Token *vartok = 
nullptr;
 
 9168                     Token *after = getTokenAfterAttributes(tok, 
true);
 
 9174                             prev = prev->
link()->previous();
 
 9184                         const std::string &attribute(attr->next()->str());
 
 9185                         if (attribute.find(
"unused") != std::string::npos)
 
 9192                 else if (
Token::Match(attr, 
"[(,] pure|__pure__|const|__const__|noreturn|__noreturn__|nothrow|__nothrow__|warn_unused_result [,)]")) {
 
 9196                     const std::string &attribute(attr->next()->str());
 
 9197                     if (attribute.find(
"pure") != std::string::npos)
 
 9199                     else if (attribute.find(
"const") != std::string::npos)
 
 9201                     else if (attribute.find(
"noreturn") != std::string::npos)
 
 9203                     else if (attribute.find(
"nothrow") != std::string::npos)
 
 9205                     else if (attribute.find(
"warn_unused_result") != std::string::npos)
 
 9225         if (tok->
str() != 
"(")
 
 9232         if (attr.compare(attr.size()-2, 2, 
"__") != 0) 
 
 9237             vartok = vartok->
next();
 
 9239                 vartok = vartok->
linkAt(1);
 
 9252         if (tok->
tokAt(-2)) {
 
 9253             tok = tok->
tokAt(-2);
 
 9279                     head = head->
next();
 
 9288                     head = head->
next();
 
 9297             } 
else if (
Token::Match(tok->
previous(), 
") [ [ expects|ensures|assert default|audit|axiom| : %name% <|<=|>|>= %num% ] ]")) {
 
 9299                 if (vartok->
str() == 
":")
 
 9300                     vartok = vartok->
next();
 
 9302                 while (argtok && argtok->
str() != 
"(") {
 
 9303                     if (argtok->
str() == vartok->
str())
 
 9305                     if (argtok->
str() == 
")")
 
 9306                         argtok = argtok->
link();
 
 9309                 if (argtok && argtok->
str() == vartok->
str()) {
 
 9310                     if (vartok->
next()->
str() == 
">=")
 
 9313                     else if (vartok->
next()->
str() == 
">")
 
 9316                     else if (vartok->
next()->
str() == 
"<=")
 
 9319                     else if (vartok->
next()->
str() == 
"<")
 
 9346 static const std::unordered_set<std::string> keywords = {
 
 9373         if (keywords.find(tok->
str()) != keywords.end()) {
 
 9376                 const bool isinline = (tok->
str().find(
"inline") != std::string::npos);
 
 9377                 const bool isrestrict = (tok->
str().find(
"restrict") != std::string::npos);
 
 9378                 if (isinline || isrestrict) {
 
 9381                             temp->isInline(
true);
 
 9383                             temp->isRestrict(
true);
 
 9391             if (tok->
str() == 
"auto")
 
 9401             auto getTypeTokens = [tok]() {
 
 9402                 std::vector<Token*> ret;
 
 9403                 for (
Token *temp = tok; 
Token::Match(temp, 
"%name%"); temp = temp->previous()) {
 
 9404                     if (!temp->isKeyword())
 
 9405                         ret.emplace_back(temp);
 
 9408                     if (!temp->isKeyword())
 
 9409                         ret.emplace_back(temp);
 
 9414             if (tok->
str() == 
"restrict") {
 
 9415                 for (
Token* temp: getTypeTokens())
 
 9416                     temp->isRestrict(
true);
 
 9421                 while (tok->
str() == 
"_Atomic") {
 
 9422                     for (
Token* temp: getTypeTokens())
 
 9423                         temp->isAtomic(
true);
 
 9430             if (cpp20 && tok->
str() == 
"consteval") {
 
 9432                 tok->
str(
"constexpr");
 
 9433             } 
else if (cpp20 && tok->
str() == 
"constinit") {
 
 9443                     finalTok = finalTok->
next();
 
 9448                         finalTok = finalTok->
next();
 
 9458             else if (
Token::Match(tok, 
") const|override|final| noexcept :|{|;|,|const|override|final")) {
 
 9462                 while (tokNoExcept->
str() != 
"noexcept")
 
 9463                     tokNoExcept = tokNoExcept->
next();
 
 9468                 Token * braceStart = tokNoExcept->
next();
 
 9469                 tok = tok->
tokAt(3);
 
 9475             else if (tok->
str() == 
"thread_local") {
 
 9489     for (
Token* tok = start; tok != end; tok = tok->
next()) {
 
 9500     static const std::unordered_map<std::string, TokenDebug> m = {{
"debug_valueflow", 
TokenDebug::ValueFlow},
 
 9505         auto it = m.find(tok->
str());
 
 9506         if (it != m.end()) {
 
 9508             tok = setTokenDebug(tok, it->second);
 
 9517             const std::string &varname = tok->
next()->
str();
 
 9520             int indentlevel = 0;
 
 9522             while (
nullptr != (tok2 = tok2->
next())) {
 
 9526                     if (indentlevel <= 2)
 
 9534                 tok2 = tok2->
tokAt(-3);
 
 9550     std::string instruction;
 
 9558         else if (
Token::Match(tok, 
"asm|__asm|__asm__ volatile|__volatile|__volatile__| (")) {
 
 9561             if (partok->
str() != 
"(")
 
 9562                 partok = partok->
next();
 
 9569             const Token *firstSemiColon = 
nullptr;
 
 9571             while (
Token::Match(endasm, 
"%num%|%name%|,|:|;") || (endasm && endasm->
linenr() == comment)) {
 
 9574                 if (endasm->
str() == 
";") {
 
 9575                     comment = endasm->
linenr();
 
 9576                     if (!firstSemiColon)
 
 9577                         firstSemiColon = endasm;
 
 9579                 endasm = endasm->
next();
 
 9586             } 
else if (firstSemiColon) {
 
 9589             } 
else if (!endasm) {
 
 9607         if (tok->
strAt(1) != 
";" && tok->
strAt(1) != 
"{")
 
 9617         tok = tok->
tokAt(2);
 
 9620             const int endposition = tok->
next()->
linenr();
 
 9621             tok = tok->
tokAt(-3);
 
 9622             for (
int i = 0; i < 4; ++i) {
 
 9624                 tok->
linenr(endposition);
 
 9637         if (tok->
str() != 
"^")
 
 9641             Token * start = tok;
 
 9644                     start = start->
link();
 
 9651             last = last->
next();
 
 9652             while (last && !
Token::Match(last, 
"%cop%|,|;|{|}|)")) {
 
 9654                     last = last->
link();
 
 9655                 last = last->
next();
 
 9658             if (start && last) {
 
 9659                 std::string asmcode;
 
 9660                 while (start->
next() != last) {
 
 9661                     asmcode += start->
next()->
str();
 
 9664                 if (last->
str() == 
"}")
 
 9672                 tok = start->
tokAt(4);
 
 9680     std::set<std::string> var;
 
 9683         if (
Token::Match(tok, 
"%name%|] @ %num%|%name%|%str%|(")) {
 
 9687             else if (end->
str() == 
"(") {
 
 9689                 while ((end = end->
next()) != 
nullptr) {
 
 9690                     if (end->
str() == 
"(")
 
 9692                     else if (end->
str() == 
")") {
 
 9697                 end = end ? end->
next() : 
nullptr;
 
 9698             } 
else if (var.find(end->
str()) != var.end())
 
 9704                 end = end->
tokAt(2);
 
 9708                     var.insert(tok->
str());
 
 9716         if (
Token::Match(tok, 
"@ builtin|eeprom|far|inline|interrupt|near|noprd|nostack|nosvf|packed|stack|svlreg|tiny|vector")) {
 
 9726     bool goback = 
false;
 
 9732         Token *last = 
nullptr;
 
 9737         if (!
Token::Match(tok, 
";|{|}|public:|protected:|private:"))
 
 9740         bool isEnum = 
false;
 
 9741         if (tok->
str() == 
"}") {
 
 9742             const Token *type = tok->
link()->previous();
 
 9743             while (type && type->
isName()) {
 
 9744                 if (type->
str() == 
"enum") {
 
 9753             !
Token::Match(tok->
next(), 
"case|public|protected|private|class|struct") &&
 
 9758             if (tok1 && tok1->
tokAt(2) &&
 
 9760                  !
Token::Match(tok1->
tokAt(2), 
"public|protected|private| %type% ::|<|,|{|;"))) {
 
 9767                 last = tok1->
next();
 
 9769         } 
else if (isEnum && 
Token::Match(tok, 
"} %name%| : %num% ;")) {
 
 9770             if (tok->
next()->
str() == 
":") {
 
 9777                    tok->
next()->
str() != 
"default") {
 
 9778             const int offset = (tok->
next()->
str() == 
"const") ? 1 : 0;
 
 9785         if (last && last->
str() == 
",") {
 
 9786             Token * tok1 = last;
 
 9791             tok1 = tok1->
next();
 
 9799 static bool isStdContainerOrIterator(
const Token* tok, 
const Settings& settings)
 
 9805 static bool isStdSmartPointer(
const Token* tok, 
const Settings& settings)
 
 9817     std::set<std::string> userFunctions;
 
 9820         bool insert = 
false;
 
 9821         if (
Token::Match(tok, 
"enum class|struct| %name%| :|{")) { 
 
 9830                 userFunctions.insert(tok->
str());
 
 9832                 const Token *start = tok;
 
 9836                     userFunctions.insert(tok->
str());
 
 9845                  isStdContainerOrIterator(tok, 
mSettings))
 
 9872         if (tok->
strAt(1) != 
"(")
 
 9875         if (
Token::Match(tok, 
"CopyMemory|RtlCopyMemory|RtlCopyBytes")) {
 
 9877         } 
else if (
Token::Match(tok, 
"MoveMemory|RtlMoveMemory")) {
 
 9878             tok->
str(
"memmove");
 
 9879         } 
else if (
Token::Match(tok, 
"FillMemory|RtlFillMemory|RtlFillBytes")) {
 
 9892         } 
else if (
Token::Match(tok, 
"ZeroMemory|RtlZeroMemory|RtlZeroBytes|RtlSecureZeroMemory")) {
 
 9903                 tok1 = tok1->
next();
 
 9920         triplet(
const char* m, 
const char* u) :  mbcs(m), unicode(u) {}
 
 9921         std::string mbcs, unicode;
 
 9924     const std::map<std::string, triplet> apis = {
 
 9925         std::make_pair(
"_topen", triplet(
"open", 
"_wopen")),
 
 9926         std::make_pair(
"_tsopen_s", triplet(
"_sopen_s", 
"_wsopen_s")),
 
 9927         std::make_pair(
"_tfopen", triplet(
"fopen", 
"_wfopen")),
 
 9928         std::make_pair(
"_tfopen_s", triplet(
"fopen_s", 
"_wfopen_s")),
 
 9929         std::make_pair(
"_tfreopen", triplet(
"freopen", 
"_wfreopen")),
 
 9930         std::make_pair(
"_tfreopen_s", triplet(
"freopen_s", 
"_wfreopen_s")),
 
 9931         std::make_pair(
"_tcscat", triplet(
"strcat", 
"wcscat")),
 
 9932         std::make_pair(
"_tcschr", triplet(
"strchr", 
"wcschr")),
 
 9933         std::make_pair(
"_tcscmp", triplet(
"strcmp", 
"wcscmp")),
 
 9934         std::make_pair(
"_tcsdup", triplet(
"strdup", 
"wcsdup")),
 
 9935         std::make_pair(
"_tcscpy", triplet(
"strcpy", 
"wcscpy")),
 
 9936         std::make_pair(
"_tcslen", triplet(
"strlen", 
"wcslen")),
 
 9937         std::make_pair(
"_tcsncat", triplet(
"strncat", 
"wcsncat")),
 
 9938         std::make_pair(
"_tcsncpy", triplet(
"strncpy", 
"wcsncpy")),
 
 9939         std::make_pair(
"_tcsnlen", triplet(
"strnlen", 
"wcsnlen")),
 
 9940         std::make_pair(
"_tcsrchr", triplet(
"strrchr", 
"wcsrchr")),
 
 9941         std::make_pair(
"_tcsstr", triplet(
"strstr", 
"wcsstr")),
 
 9942         std::make_pair(
"_tcstok", triplet(
"strtok", 
"wcstok")),
 
 9943         std::make_pair(
"_ftprintf", triplet(
"fprintf", 
"fwprintf")),
 
 9944         std::make_pair(
"_tprintf", triplet(
"printf", 
"wprintf")),
 
 9945         std::make_pair(
"_stprintf", triplet(
"sprintf", 
"swprintf")),
 
 9946         std::make_pair(
"_sntprintf", triplet(
"_snprintf", 
"_snwprintf")),
 
 9947         std::make_pair(
"_ftscanf", triplet(
"fscanf", 
"fwscanf")),
 
 9948         std::make_pair(
"_tscanf", triplet(
"scanf", 
"wscanf")),
 
 9949         std::make_pair(
"_stscanf", triplet(
"sscanf", 
"swscanf")),
 
 9950         std::make_pair(
"_ftprintf_s", triplet(
"fprintf_s", 
"fwprintf_s")),
 
 9951         std::make_pair(
"_tprintf_s", triplet(
"printf_s", 
"wprintf_s")),
 
 9952         std::make_pair(
"_stprintf_s", triplet(
"sprintf_s", 
"swprintf_s")),
 
 9953         std::make_pair(
"_sntprintf_s", triplet(
"_snprintf_s", 
"_snwprintf_s")),
 
 9954         std::make_pair(
"_ftscanf_s", triplet(
"fscanf_s", 
"fwscanf_s")),
 
 9955         std::make_pair(
"_tscanf_s", triplet(
"scanf_s", 
"wscanf_s")),
 
 9956         std::make_pair(
"_stscanf_s", triplet(
"sscanf_s", 
"swscanf_s"))
 
 9968         if (tok->
strAt(1) != 
"(")
 
 9971         const std::map<std::string, triplet>::const_iterator 
match = apis.find(tok->
str());
 
 9972         if (
match!=apis.end()) {
 
 9973             tok->
str(ansi ? 
match->second.mbcs : 
match->second.unicode);
 
 9975         } 
else if (
Token::Match(tok, 
"_T|_TEXT|TEXT ( %char%|%str% )")) {
 
 9981                 if (tok->
str()[0] != 
'L')
 
 9982                     tok->
str(
"L" + tok->
str());
 
10017             while (tok && tok->
str() != 
"{" && tok->
str() != 
";")
 
10021             if (tok->
str() == 
";")
 
10024             const Token* end = tok->
link()->next();
 
10025             for (
Token *tok2 = tok->
next(); tok2 != end; tok2 = tok2->
next()) {
 
10026                 if (tok2->
str() == 
"__property" &&
 
10031                     if (tok2->
str() == 
"{") {
 
10056     if (tok && tok->
str() == 
")") {
 
10064             } 
else if (tok->
str() == 
"noexcept") {
 
10066                 if (tok && tok->
str() == 
"(") {
 
10067                     tok = tok->
link()->next();
 
10069             } 
else if (tok->
str() == 
"throw" && tok->
next() && tok->
next()->
str() == 
"(") {
 
10070                 tok = tok->
next()->
link()->next();
 
10075                 if (tok && tok->
str() == 
"(") {
 
10076                     tok = tok->
link()->next();
 
10097         if (
Token::Match(tok, 
"using|:: operator %op%|%name% ;")) {
 
10103         if (tok->
str() != 
"operator")
 
10114         while (!
done && par) {
 
10127                 if (par->
str() == 
"," && !op.empty())
 
10136                 par = par->
tokAt(2);
 
10143                 while (par->
str() != 
")") {
 
10155             } 
else if (
Token::Match(par, 
"\"\" %name% )| (|;|<")) {
 
10157                 op += par->
strAt(1);
 
10158                 par = par->
tokAt(2);
 
10159                 if (par->
str() == 
")") {
 
10160                     par->
link()->deleteThis();
 
10163                     tok = par->
tokAt(-3);
 
10166             } 
else if (par->
str() == 
"::") {
 
10170             } 
else if (par->
str() == 
";" || par->
str() == 
")") {
 
10172             } 
else if (par->
str() != 
"(") {
 
10178         if (par && !op.empty()) {
 
10184                 tok->
str(
"operator" + op);
 
10189         if (!op.empty() && !returnsRef)
 
10195             const std::string name = tok->
strAt(2);
 
10214                         "simplifyOperatorName: found unsimplified operator name");
 
10224     std::set<std::string> classNames;
 
10225     std::set<nonneg int> classVars;
 
10240             for (
const Token *tok2 = tok->
next(); tok2; tok2 = tok2->
next()) {
 
10241                 if (tok2->
str() == 
"}")
 
10245                 if (tok2->
str() == 
"{") {
 
10249                         tok2 = tok2->
link();
 
10251                     classNames.insert(tok->
strAt(1));
 
10258         if (
Token::Match(tok, 
"%type% &| %var%") && classNames.find(tok->
str()) != classNames.end()) {
 
10262             classVars.insert(tok->
varId());
 
10266         if (
Token::Match(tok, 
"%var% (") && classVars.find(tok->
varId()) != classVars.end()) {
 
10272                         start = start->
linkAt(-1);
 
10276                         start = start->
tokAt(-2);
 
10282                     after = after->
linkAt(3);
 
10301     std::vector<Space> classInfo;
 
10303         if (
Token::Match(tok, 
"class|struct|namespace %type% :|{") &&
 
10306             info.isNamespace = tok->
str() == 
"namespace";
 
10308             info.className = tok->
str();
 
10310             while (tok && tok->
str() != 
"{")
 
10314             info.bodyEnd = tok->
link();
 
10315             classInfo.push_back(std::move(info));
 
10316         } 
else if (!classInfo.empty()) {
 
10317             if (tok == classInfo.back().bodyEnd)
 
10318                 classInfo.pop_back();
 
10319             else if (tok->
str() == classInfo.back().className &&
 
10320                      !classInfo.back().isNamespace && tok->
previous()->
str() != 
":" &&
 
10324                 if (tok->
strAt(2) == 
"operator") {
 
10326                     if (tok1->
str() == 
"(")
 
10327                         tok1 = tok1->
next();
 
10329                     while (tok1 && tok1->
str() != 
"(") {
 
10330                         if (tok1->
str() == 
";")
 
10332                         tok1 = tok1->
next();
 
10334                     if (!tok1 || tok1->
str() != 
"(")
 
10336                 } 
else if (tok->
strAt(2) == 
"~")
 
10337                     tok1 = tok1->
next();
 
10343                 const bool isConstructorOrDestructor =
 
10345                 if (!isConstructorOrDestructor) {
 
10347                     if (!isPrependedByType) {
 
10351                     if (!isPrependedByType) {
 
10353                         isPrependedByType = 
Token::Match(tok3, 
"%type% * *|&");
 
10355                     if (!isPrependedByType) {
 
10371     std::vector<std::pair<std::string, const Token *>> unknowns;
 
10373     for (
int i = 1; i <= 
mVarId; ++i) {
 
10382         const Token * nameTok;
 
10387             name = nameTok->
str();
 
10402                 name += tok->
str();
 
10408                 else if (tok->
str() == 
"<")
 
10410                 else if (tok->
str() == 
">")
 
10420         unknowns.emplace_back(std::move(name), nameTok);
 
10423     if (!unknowns.empty()) {
 
10427         for (
auto it = unknowns.cbegin(); it != unknowns.cend(); ++it) {
 
10429             if (it->first.find(
"std::") != 0) {
 
10430                 if (it->first != last) {
 
10450         if (tok->
str() == 
"?") {
 
10451             bool parenthesesNeeded = 
false;
 
10454             for (; tok2; tok2 = tok2->
next()) {
 
10456                     tok2 = tok2->
link();
 
10457                 else if (tok2->
str() == 
":") {
 
10461                 } 
else if (tok2->
str() == 
";" || (tok2->
link() && tok2->
str() != 
"{" && tok2->
str() != 
"}"))
 
10463                 else if (tok2->
str() == 
",")
 
10464                     parenthesesNeeded = 
true;
 
10465                 else if (tok2->
str() == 
"<")
 
10466                     parenthesesNeeded = 
true;
 
10467                 else if (tok2->
str() == 
"?") {
 
10469                     parenthesesNeeded = 
true;
 
10472             if (parenthesesNeeded && tok2 && tok2->
str() == 
":") {
 
10483     const std::list<const Token*> callstack(1, tok);
 
10487 void Tokenizer::reportError(
const std::list<const Token*>& callstack, 
Severity severity, 
const std::string& 
id, 
const std::string& msg, 
bool inconclusive)
 const 
10503             while (prev && prev->
isName())
 
10514     const Token *tokLastEnd = 
nullptr;
 
10515     for (
const Token *tok = tokSQLStart->
tokAt(2); tok != 
nullptr; tok = tok->
next()) {
 
10516         if (tokLastEnd == 
nullptr && tok->
str() == 
";")
 
10518         else if (tok->
str() == 
"__CPPCHECK_EMBEDDED_SQL_EXEC__") {
 
10520                 return tok->
next();
 
10522         } 
else if (
Token::Match(tok, 
"{|}|==|&&|!|^|<<|>>|++|+=|-=|/=|*=|>>=|<<=|~"))
 
10540                 tok2 = tok2->
tokAt(2);
 
10542             if (!tok2 || tok2->
str() != 
"{")
 
10545             std::stack<Token *> links;
 
10546             tok2 = tok->
tokAt(2);
 
10548             while (tok2->
str() == 
"::") {
 
10552                 tok2 = tok2->
tokAt(3);
 
10557             if (!links.empty() && tok2->
str() == 
"{") {
 
10558                 tok2 = tok2->
link();
 
10559                 while (!links.empty()) {
 
10561                     tok2 = tok2->
next();
 
10578         while (end && end->
str() != 
";") {
 
10593 static bool sameTokens(
const Token *first, 
const Token *last, 
const Token *other)
 
10595     while (other && first->
str() == other->
str()) {
 
10598         first = first->
next();
 
10599         other = other->
next();
 
10605 static bool alreadyHasNamespace(
const Token *first, 
const Token *last, 
const Token *end)
 
10607     while (end && last->
str() == end->
str()) {
 
10639         if (tok->
str() == 
"{")
 
10641         else if (tok->
str() == 
"}")
 
10648             const std::string name(tok->
next()->
str());
 
10650             Token * tokNameEnd = tokNameStart;
 
10652             while (tokNameEnd && tokNameEnd->
next() && tokNameEnd->
next()->
str() != 
";") {
 
10653                 if (tokNameEnd->
str() == 
"(") {
 
10659                 tokNameEnd = tokNameEnd->
next();
 
10665             int endScope = scope;
 
10670             Token * tok2 = tokNext;
 
10672             while (tok2 && endScope >= scope) {
 
10677                 else if (tok2->
str() == name) {
 
10680                         if (sameTokens(tokNameStart, tokNameEnd, tok2->
tokAt(2))) {
 
10682                             tok2 = deleteAlias(tok2->
previous());
 
10687                         if (endScope == scope) {
 
10689                             tok2 = deleteAlias(tok2->
previous());
 
10695                             tok2 = deleteAlias(tok2->
previous());
 
10700                     if (tok2->
strAt(1) == 
"::" && !alreadyHasNamespace(tokNameStart, tokNameEnd, tok2)) {
 
10703                         tok2->
str(tokNameStart->
str());
 
10704                         Token * tok3 = tokNameStart;
 
10705                         while (tok3 != tokNameEnd) {
 
10707                             tok2 = tok2->
next();
 
10708                             tok3 = tok3->
next();
 
10712                 tok2 = tok2->
next();
 
10721             } 
else if (tokNext) {
 
10740     return std::any_of(directives.cbegin(), directives.cend(), [&](
const Directive& d) {
 
10741         return startsWith(d.str, 
"#if") &&
 
10742         d.linenr >= start->linenr() &&
 
10743         d.linenr <= end->linenr() &&
 
10744         start->fileIndex() < list.getFiles().size() &&
 
10745         d.file == list.getFiles()[start->fileIndex()];
 
10753     return std::any_of(directives.cbegin(), directives.cend(), [&](
const Directive& d) {
 
10754         return d.linenr < bodyStart->linenr() && d.str == 
"#pragma pack(1)" && d.file == list.getFiles().front();
 
static bool match(const Token *tok, const std::string &rhs)
 
bool isUnevaluated(const Token *tok)
 
This is an interface, which the class responsible of error logging should implement.
 
virtual void reportErr(const ErrorMessage &msg)=0
Information about found errors and warnings is directed here.
 
static std::string toxml(const std::string &str)
Convert XML-sensitive characters into XML entities.
 
virtual void reportProgress(const std::string &filename, const char stage[], const std::size_t value)
Report progress to client.
 
File name and line number.
 
Wrapper for error messages, provided by reportErr()
 
const Container * detectContainerOrIterator(const Token *typeStart, bool *isIterator=nullptr, bool withoutStd=false) const
 
const SmartPointer * detectSmartPointer(const Token *tok, bool withoutStd=false) const
 
bool hasAnyTypeCheck(const std::string &typeName) const
 
bool isnoreturn(const Token *ftok) const
 
bool isScopeNoReturn(const Token *end, std::string *unknownFunc) const
 
const PodType * podtype(const std::string &name) const
 
bool markupFile(const std::string &path) const
 
bool isNotLibraryFunction(const Token *ftok) const
 
bool matchArguments(const Token *ftok, const std::string &functionName) const
 
bool isFunctionConst(const std::string &functionName, bool pure) const
 
static std::string toString(T value)=delete
 
static biguint toBigUNumber(const std::string &str)
for conversion of numeric literals - for atoi-like conversions please use strToInt()
 
static bool isOctalDigit(char c)
Return true if given character is 0,1,2,3,4,5,6 or 7.
 
static bigint toBigNumber(const std::string &str)
for conversion of numeric literals - for atoi-like conversions please use strToInt()
 
static bool isFloat(const std::string &str)
 
static bool isInt(const std::string &str)
 
static double toDoubleNumber(const std::string &str)
for conversion of numeric literals
 
unsigned long long biguint
 
static bool isPositive(const std::string &str)
 
static std::string getRelativePath(const std::string &absolutePath, const std::vector< std::string > &basePaths)
Create a relative path from an absolute one, if absolute path is inside the basePaths.
 
This is just a container for general settings so that we don't need to pass individual values to func...
 
bool checkLibrary
Check for incomplete info in library files?
 
bool checkHeaders
Check code in the headers, this is on by default but can be turned off to save CPU.
 
std::vector< std::string > basePaths
Paths used as base for conversion to relative paths.
 
bool xml
write XML results (–xml)
 
bool checkConfiguration
Is the 'configuration checking' wanted?
 
static bool terminated()
termination requested?
 
std::size_t typedefMaxTime
The maximum time in seconds for the typedef simplification.
 
std::string buildDir
–cppcheck-build-dir.
 
std::set< std::string > summaryReturn
 
bool debugnormal
Is –debug-normal given?
 
bool daca
Are we running from DACA script?
 
bool verbose
Is –verbose given?
 
SHOWTIME_MODES showtime
show timing information (–showtime=file|summary|top5)
 
SimpleEnableGroup< Severity > severity
 
std::size_t templateMaxTime
The maximum time in seconds for the template instantiation.
 
bool debugSimplified
Is –debug-simplified given?
 
bool checkUnusedTemplates
Check unused/uninstantiated templates.
 
bool debugwarnings
Is –debug-warnings given?
 
Standards standards
Struct contains standards settings.
 
bool isEnabled(T flag) const
 
const Variable * getVariableFromVarId(nonneg int varId) const
 
const std::vector< const Variable * > & variableList() const
 
void setValueTypeInTokenList(bool reportDebugWarnings, Token *tokens=nullptr)
Set valuetype in provided tokenlist.
 
void printXml(std::ostream &out) const
 
void setArrayDimensionsUsingValueFlow()
Set array dimensions when valueflow analysis is completed.
 
void printOut(const char *title=nullptr) const
 
Simplify templates from the preprocessed and partially simplified code.
 
void simplifyTemplates(const std::time_t maxtime)
Simplify templates.
 
static Token * findTemplateDeclarationEnd(Token *tok)
Find last token of a template declaration.
 
void checkComplicatedSyntaxErrorsInTemplates()
 
static unsigned int templateParameters(const Token *tok)
is the token pointing at a template parameters block < int , 3 > => yes
 
static bool simplifyNumericCalculations(Token *tok, bool isTemplate=true)
Simplify constant calculations such as "1+2" => "3".
 
const std::string & dump() const
 
static Token * copyTokens(Token *dest, const Token *first, const Token *last, bool one_line=true)
Copy tokens.
 
void createAst() const
Create abstract syntax tree.
 
const Token * back() const
get last token of list
 
void simplifyPlatformTypes()
Convert platform dependent types to standard types.
 
const std::string & file(const Token *tok) const
get filename for given token
 
static void insertTokens(Token *dest, const Token *src, nonneg int n)
 
void simplifyStdType()
Collapse compound standard types into a single token.
 
const std::vector< std::string > & getFiles() const
Get filenames (the sourcefile + the files it include).
 
const Token * front() const
get first token of list
 
void validateAst(bool print) const
Check abstract syntax tree.
 
The token list that the TokenList generates is a linked-list of this class.
 
bool isRemovedVoidParameter() const
 
static bool Match(const Token *tok, const char pattern[], nonneg int varid=0)
Match given token (or list of tokens) to a pattern list.
 
bool isSimplifiedScope() const
 
void deleteThis()
Remove the contents for this token from the token list.
 
nonneg int exprId() const
 
void setMacroName(std::string name)
 
const std::string & originalName() const
 
void setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint value)
 
void printOut(const char *title=nullptr) const
For debugging purposes, prints token and all tokens followed by it.
 
bool isAttributeUsed() const
 
bool addValue(const ValueFlow::Value &value)
Add token value.
 
bool hasKnownIntValue() const
 
static void replace(Token *replaceThis, Token *start, Token *end)
Replace token replaceThis with tokens between start and end, including start and end.
 
MathLib::bigint getKnownIntValue() const
 
bool isSimplifiedTypedef() const
 
bool isExpandedMacro() const
 
void concatStr(std::string const &b)
Concatenate two (quoted) strings.
 
bool isTemplateArg() const
Is current token a template argument?
 
void setTokenDebug(TokenDebug td)
 
bool isArithmeticalOp() const
 
std::string stringifyList(const stringifyOptions &options, const std::vector< std::string > *fileNames=nullptr, const Token *end=nullptr) const
 
bool isUpperCaseName() const
 
static void createMutualLinks(Token *begin, Token *end)
Links two elements against each other.
 
bool isAttributeDestructor() const
 
nonneg int progressValue() const
Get progressValue (0 - 100)
 
bool isControlFlowKeyword() const
 
void setBits(const unsigned char b)
 
static nonneg int getStrLength(const Token *tok)
 
bool isImplicitInt() const
 
const ValueType * valueType() const
 
const std::string & strAt(int index) const
 
bool isAttributeUnused() const
 
static void assignProgressValues(Token *tok)
Calculate progress values for all tokens.
 
void astOperand1(Token *tok)
 
void function(const Function *f)
Associate this token with given function.
 
static void move(Token *srcStart, Token *srcEnd, Token *newLocation)
Move srcStart and srcEnd tokens and all tokens between them into new a location.
 
const Token * findClosingBracket() const
Returns the closing bracket of opening '<'.
 
bool isSplittedVarDeclComma() const
 
bool isAttributeNodiscard() const
 
bool isAttributeExport() const
 
bool isOperatorKeyword() const
 
void printValueFlow(bool xml, std::ostream &out) const
 
bool isAttributeConstructor() const
 
void setRemovedVoidParameter(bool b)
 
static nonneg int getStrArraySize(const Token *tok)
 
void scopeInfo(std::shared_ptr< ScopeInfo2 > newScopeInfo)
 
static const Token * findsimplematch(const Token *const startTok, const char(&pattern)[count])
 
const Token * tokAt(int index) const
 
Token * insertTokenBefore(const std::string &tokenStr, const std::string &originalNameStr=emptyString, const std::string ¯oNameStr=emptyString)
 
void deleteNext(nonneg int count=1)
Unlink and delete the next 'count' tokens.
 
Token * insertToken(const std::string &tokenStr, const std::string &originalNameStr=emptyString, const std::string ¯oNameStr=emptyString, bool prepend=false)
Insert new token after this token.
 
Token::Type tokType() const
 
void astOperand2(Token *tok)
 
void scope(const Scope *s)
Associate this token with given scope.
 
void link(Token *linkToToken)
Create link to given token.
 
const Token * linkAt(int index) const
 
void printAst(bool verbose, bool xml, const std::vector< std::string > &fileNames, std::ostream &out) const
 
void type(const ::Type *t)
Associate this token with given type.
 
bool isAssignmentOp() const
 
bool isSplittedVarDeclEq() const
 
static void eraseTokens(Token *begin, const Token *end)
Delete tokens between begin and end.
 
nonneg int linenr() const
 
bool isStandardType() const
 
const Token * nextArgumentBeforeCreateLinks2() const
 
void variable(const Variable *v)
Associate this token with given variable.
 
bool isAttributeMaybeUnused() const
 
bool isComparisonOp() const
 
const std::list< ValueFlow::Value > & values() const
 
bool isAttributeNoreturn() const
 
bool isAttributeConst() const
 
const Token * nextArgument() const
 
void swapWithNext()
Swap the contents of this token with the next token.
 
const Token * findOpeningBracket() const
 
static bool simpleMatch(const Token *tok, const char(&pattern)[count])
Match given token (or list of tokens) to a pattern list.
 
nonneg int fileIndex() const
 
bool isAttributePacked() const
 
bool isAttributeNothrow() const
 
std::string getMacroName() const
 
void deletePrevious(nonneg int count=1)
Unlink and delete the previous 'count' tokens.
 
nonneg int column() const
 
bool isAttributePure() const
 
void astParent(Token *tok)
 
The main purpose is to tokenize the source code.
 
bool isScopeNoReturn(const Token *endScopeToken, bool *unknown=nullptr) const
Check if inner scope ends with a call to a noreturn function.
 
nonneg int sizeOfType(const Token *type) const
Calculates sizeof value for given type.
 
void simplifyLabelsCaseDefault()
Simplify labels and 'case|default' syntaxes.
 
void simplifyRoundCurlyParentheses()
 
void simplifyOverloadedOperators()
simplify overloaded operators: 'obj(123)' => 'obj .
 
void simplifyMicrosoftStringFunctions()
Convert Microsoft string functions _tcscpy -> strcpy.
 
std::string mConfiguration
E.g.
 
void simplifyIfSwitchForInit()
Simplify C++17/C++20 if/switch/for initialization expression.
 
void simplifyBitfields()
Simplify bitfields - the field width is removed as we don't use it.
 
NORETURN void unknownMacroError(const Token *tok1) const
Warn about unknown macro(s), configuration is recommended.
 
void splitTemplateRightAngleBrackets(bool check)
Split up template right angle brackets.
 
Token * deleteInvalidTypedef(Token *typeDef)
 
void printDebugOutput(int simplification) const
print –debug output if debug flags match the simplification: 0=unknown/both simplifications 1=1st sim...
 
void elseif()
Simplify "if else".
 
void simplifyRedundantConsecutiveBraces()
 
void removeMacrosInGlobalScope()
Remove macros in global scope.
 
void simplifyHeadersAndUnusedTemplates()
If –check-headers=no has been given; then remove unneeded code in headers.
 
void simplifyTemplates()
Simplify templates.
 
void simplifyUsingError(const Token *usingStart, const Token *usingEnd)
 
bool isPacked(const Token *bodyStart) const
 
const Token * tokens() const
 
void simplifyAttribute()
Remove __attribute__ ((?))
 
static const Token * findSQLBlockEnd(const Token *tokSQLStart)
Find end of SQL (or PL/SQL) block.
 
void simplifyNamespaceAliases()
Convert namespace aliases.
 
void simplifyInitVar()
Simplify variable initialization '; int *p(0);' => '; int *p = 0;'.
 
static bool isGarbageExpr(const Token *start, const Token *end, bool allowSemicolon)
Detect garbage expression.
 
void removeUnnecessaryQualification()
Remove unnecessary member qualification.
 
void simplifyVarDecl(const bool only_k_r_fpar)
Simplify variable declarations (split up)
 
static bool isOneNumber(const std::string &s)
Helper function to check whether number is one (1 or 0.1E+1 or 1E+0) or not?
 
void simplifyTypedef()
typedef A mytype; mytype c;
 
void createSymbolDatabase()
 
void prepareTernaryOpForAST()
Prepare ternary operators with parentheses so that the AST can be created.
 
bool simplifyTokens1(const std::string &configuration)
 
static std::string simplifyString(const std::string &source)
Modify strings in the token list by replacing hex and oct values.
 
bool simplifyTokenList1(const char FileName[])
Basic simplification of tokenlist.
 
void simplifyFunctionTryCatch()
Simplify function level try blocks: Convert "void f() try {} catch (int) {}" to "void f() { try {} ca...
 
void simplifyDoublePlusAndDoubleMinus()
 
void removeExtraTemplateKeywords()
Remove extra "template" keywords that are not used by Cppcheck.
 
void simplifyTypedefLHS()
Move typedef token to the left og the expression.
 
std::list< Directive > mDirectives
 
void simplifyCaseRange()
simplify case ranges (gcc extension)
 
ErrorLogger & mErrorLogger
errorlogger
 
bool simplifyRedundantParentheses()
Remove redundant parentheses:
 
void simplifyTypedefCpp()
 
void addSemicolonAfterUnknownMacro()
 
void simplifyCppcheckAttribute()
Remove __cppcheck__ ((?))
 
Token * getAttributeFuncTok(Token *tok, bool gccattr) const
Get function token for a attribute.
 
Tokenizer(const Settings &settings, ErrorLogger &errorLogger)
 
void simplifyEmptyNamespaces()
Simplify useless C++ empty namespaces, like: 'namespace name% { }'.
 
void findGarbageCode() const
Detect garbage code and call syntaxError() if found.
 
Token * simplifyAddBracesPair(Token *tok, bool commandWithCondition)
Add pair of braces to an single if-block, else-block, for-block, etc.
 
void simplifyMicrosoftMemoryFunctions()
Convert Microsoft memory functions CopyMemory(dst, src, len) -> memcpy(dst, src, len) FillMemory(dst,...
 
void setVarId()
Set variable id.
 
void setDirectives(std::list< Directive > directives)
 
void simplifyAssignmentBlock()
Simplify assignment where rhs is a block : "x=({123;});" => "{x=123;}".
 
void findComplicatedSyntaxErrorsInTemplates()
 
std::map< std::string, int > mTypeSize
sizeof information for known types
 
friend class SymbolDatabase
 
TokenList list
Token list: stores all tokens.
 
void simplifyNamespaceStd()
Add std:: in front of std classes, when using namespace std; was given.
 
static Token * initVar(Token *tok)
 
Token * simplifyAddBracesToCommand(Token *tok)
Add braces to an if-block, for-block, etc.
 
nonneg int mVarId
variable count
 
static bool isMemberFunction(const Token *openParen)
 
void simplifyKeyword()
Remove keywords "volatile", "inline", "register", and "restrict".
 
void macroWithSemicolonError(const Token *tok, const std::string ¯oName) const
 
nonneg int mUnnamedCount
unnamed count "Unnamed0", "Unnamed1", "Unnamed2", ...
 
bool isC() const
Is the code C.
 
void simplifyUsingToTypedef()
 
bool simplifyAddBraces()
Add braces to an if-block, for-block, etc.
 
void unhandled_macro_class_x_y(const Token *tok) const
Report that there is an unhandled "class x y {" code.
 
void reportUnknownMacros() const
Detect unknown macros and throw unknownMacro.
 
void arraySize()
Insert array size where it isn't given.
 
void createLinks2()
Setup links between < and >.
 
static void setVarIdClassFunction(const std::string &classname, Token *const startToken, const Token *const endToken, const std::map< std::string, nonneg int > &varlist, std::map< nonneg int, std::map< std::string, nonneg int >> &structMembers, nonneg int &varId_)
 
const Settings & mSettings
settings
 
void simplifyParameterVoid()
 
void sizeofAddParentheses()
Add parentheses for sizeof: sizeof x => sizeof(x)
 
void dump(std::ostream &out) const
 
void validateC() const
Is there C++ code in C file?
 
static bool operatorEnd(const Token *tok)
 
void simplifyStaticConst()
Simplify the location of "static" and "const" qualifiers in a variable declaration or definition.
 
void simplifyDeclspec()
Remove __declspec()
 
void createLinks()
Setup links for tokens so that one can call Token::link().
 
NORETURN void cppcheckError(const Token *tok) const
Send error message to error logger about internal bug.
 
void markCppCasts()
Set isCast() for C++ casts.
 
NORETURN void unmatchedToken(const Token *tok) const
Syntax error.
 
void simplifyPointerToStandardType()
Simplify pointer to standard type (C only)
 
void simplifySpaceshipOperator()
Simplify c++20 spaceship operator.
 
void combineStringAndCharLiterals()
 
void printUnknownTypes() const
Output list of unknown types.
 
void simplifyBorland()
Remove Borland code.
 
TemplateSimplifier *const mTemplateSimplifier
 
void removeRedundantSemicolons()
Reduces "; ;" to ";", except in "( ; ; )".
 
void simplifyCallingConvention()
Remove calling convention.
 
void arraySizeAfterValueFlow()
 
void simplifyFunctionPointers()
Simplify function pointers.
 
void setPodTypes()
Set pod types.
 
void unsupportedTypedef(const Token *tok) const
 
void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg, bool inconclusive=false) const
report error message
 
void simplifyAsm()
Remove __asm.
 
const Token * processFunc(const Token *tok2, bool inOperator) const
 
static const Token * isFunctionHead(const Token *tok, const std::string &endsWith)
is token pointing at function head?
 
bool simplifyCAlternativeTokens()
Simplify the 'C Alternative Tokens' Examples: "if(s and t)" => "if(s && t)" "while((r bitand s) and n...
 
void simplifyAt()
Simplify @… (compiler extension)
 
void concatenateNegativeNumberAndAnyPositive()
 
void validate() const
assert that tokens are ok - used during debugging for example to catch problems in simplifyTokenList1...
 
bool isCPP() const
Is the code CPP.
 
bool hasIfdef(const Token *start, const Token *end) const
 
NORETURN void syntaxErrorC(const Token *tok, const std::string &what) const
Syntax error.
 
void simplifyStructDecl()
Struct simplification "struct S { } s;" => "struct S { }; S s;".
 
SymbolDatabase * mSymbolDatabase
Symbol database that all checks etc can use.
 
bool duplicateTypedef(Token *&tokPtr, const Token *name, const Token *typeDef) const
 
void simplifyTypeIntrinsics()
 
static const Token * startOfExecutableScope(const Token *tok)
Helper function to check for start of function execution scope.
 
void simplifyAsm2()
asm heuristics, Put ^{} statements in asm()
 
void simplifyOperatorName()
Collapse operator name tokens into single token operator = => operator=.
 
std::vector< TypedefInfo > mTypedefInfo
 
void removeMacroInClassDef()
Remove undefined macro in class definition: class DLLEXPORT Fred { }; class Fred FINAL : Base { };.
 
void simplifyCoroutines()
Simplify coroutines - just put parentheses around arguments for co_* keywords so they can be handled ...
 
NORETURN void syntaxError(const Token *tok, const std::string &code=emptyString) const
Syntax error.
 
void checkForEnumsWithTypedef()
 
TimerResults * mTimerResults
TimerResults.
 
void simplifyNestedNamespace()
Convert C++17 style nested namespace to older style.
 
void simplifyArrayAccessSyntax()
 
void unhandledCharLiteral(const Token *tok, const std::string &msg) const
 
void simplifyCPPAttribute()
Remove [[attribute]] (C++11, C23) from TokenList.
 
void simplifyVariableMultipleAssign()
Simplify multiple assignments.
 
void checkConfiguration() const
Check configuration (unknown macros etc)
 
void simplifyFunctionParameters()
Simplify functions like "void f(x) int x; {" into "void f(int x) {".
 
Information about a class type.
 
const Library::Container * container
If the type is a container defined in a cfg file, this is the used.
 
Information about a member variable.
 
const Type * type() const
Get Type pointer of known type.
 
const Token * typeEndToken() const
Get type end token.
 
const Token * typeStartToken() const
Get type start token.
 
static const std::string emptyString
 
static void replace(std::string &source, const std::unordered_map< std::string, std::string > &substitutionMap)
 
Severity
enum class for severity.
 
Token * findLambdaEndScope(Token *tok)
 
@ portability
Portability warning.
 
@ information
Checking information.
 
CPPCHECKLIB std::string create(const Tokenizer &tokenizer, const std::string &cfg)
 
void setValues(TokenList &tokenlist, SymbolDatabase &symboldatabase, ErrorLogger &errorLogger, const Settings &settings, TimerResultsIntf *timerResults)
Perform valueflow analysis.
 
Array dimension information.
 
MathLib::bigint num
(assumed) dimension length when size is a number, 0 if not known
 
A preprocessor directive Each preprocessor directive (#include, #define, #undef, #if,...
 
Simple container to be thrown when internal error is detected.
 
enum Standards::cppstd_t cpp
 
static void indent(std::string &str, const nonneg int indent1, const nonneg int indent2)
 
static std::string getExpression(const Token *tok)
 
static Token * splitDefinitionFromTypedef(Token *tok, nonneg int *unnamedCount)
 
static void setVarIdStructMembers(Token *&tok1, std::map< nonneg int, std::map< std::string, nonneg int >> &structMembers, nonneg int &varId)
 
static Token * skipTernaryOp(Token *tok)
 
static Token * matchMemberFunctionName(const Member &func, const std::list< ScopeInfo2 > &scopeInfo)
 
static const std::unordered_set< std::string > notstart_cpp
 
static bool isCPPAttribute(const Token *tok)
 
static const std::unordered_map< std::string, std::string > cAlternativeTokens
 
static bool isClassStructUnionEnumStart(const Token *tok)
is tok the start brace { of a class, struct, union, or enum
 
static bool setVarIdParseDeclaration(Token *&tok, const VariableMap &variableMap, bool executableScope)
 
static unsigned int tokDistance(const Token *tok1, const Token *tok2)
 
static Token * matchMemberName(const std::list< std::string > &scope, const Token *nsToken, Token *memberToken, const std::list< ScopeInfo2 > &scopeInfo)
 
static T * skipCPPOrAlignAttribute(T *tok)
 
static const Token * findUnmatchedTernaryOp(const Token *const begin, const Token *const end, int depth=0)
 
static Token * matchMemberVarName(const Member &var, const std::list< ScopeInfo2 > &scopeInfo)
 
static T * skipInitializerList(T *tok)
 
static bool isEnumStart(const Token *tok)
Return whether tok is the "{" that starts an enumerator list.
 
static const std::unordered_set< std::string > notstart_c
 
static bool isEnumScope(const Token *tok)
 
static std::string getScopeName(const std::list< ScopeInfo2 > &scopeInfo)
 
static bool isNonMacro(const Token *tok)
 
static bool scopesMatch(const std::string &scope1, const std::string &scope2, const ScopeInfo3 *globalScope)
 
static void linkBrackets(const Tokenizer &tokenizer, std::stack< const Token * > &type, std::stack< Token * > &links, Token *const token, const char open, const char close)
 
static bool setVarIdClassDeclaration(Token *const startToken, VariableMap &variableMap, const nonneg int scopeStartVarId, std::map< nonneg int, std::map< std::string, nonneg int >> &structMembers)
 
static bool isAlignAttribute(const Token *tok)
 
static Token * skipCaseLabel(Token *tok)
 
static void skipEnumBody(T *&tok)
 
static bool isNumberOneOf(const std::string &s, MathLib::bigint intConstant, const char *floatConstant)
Helper function to check whether number is equal to integer constant X or floating point pattern X....
 
static bool isStringLiteral(const std::string &str)
 
static std::string id_string(const void *p)
 
bool startsWith(const std::string &str, const char start[], std::size_t startlen)
 
bool endsWith(const std::string &str, char c)
 
static const char * bool_to_string(bool b)