| 1043 | } |
| 1044 | |
| 1045 | void Tokenizer::simplifyTypedef() |
| 1046 | { |
| 1047 | // Simplify global typedefs that are not redefined with the fast 1-pass simplification. |
| 1048 | // Then use the slower old typedef simplification. |
| 1049 | std::map<std::string, std::set<std::string>> numberOfTypedefs; |
| 1050 | for (Token* tok = list.front(); tok; tok = tok->next()) { |
| 1051 | if (tok->str() == "typedef") { |
| 1052 | TypedefSimplifier ts(tok); |
| 1053 | if (ts.fail() || !ts.nameToken()) |
| 1054 | continue; |
| 1055 | std::string existing_data_type; |
| 1056 | for (const Token* t = ts.getTypedefToken()->next(); t != ts.endToken(); t = t->next()) { |
| 1057 | if (t != ts.nameToken()) |
| 1058 | existing_data_type += t->str() + " "; |
| 1059 | } |
| 1060 | numberOfTypedefs[ts.name()].emplace(std::move(existing_data_type)); |
| 1061 | continue; |
| 1062 | } |
| 1063 | } |
| 1064 | |
| 1065 | int indentlevel = 0; |
| 1066 | std::map<std::string, TypedefSimplifier> typedefs; |
| 1067 | std::map<int, std::string> inType; |
| 1068 | for (Token* tok = list.front(); tok; tok = tok->next()) { |
| 1069 | if (!tok->isName()) { |
| 1070 | if (tok->str()[0] == '{') { |
| 1071 | ++indentlevel; |
| 1072 | if (const Token* typeStart = isClassStructUnionEnumStart(tok)) { |
| 1073 | inType.emplace(indentlevel, typeStart->strAt(1)); |
| 1074 | } |
| 1075 | } |
| 1076 | else if (tok->str()[0] == '}') { |
| 1077 | inType.erase(indentlevel); |
| 1078 | --indentlevel; |
| 1079 | } |
| 1080 | continue; |
| 1081 | } |
| 1082 | |
| 1083 | if (indentlevel == 0 && tok->str() == "typedef") { |
| 1084 | TypedefSimplifier ts(tok); |
| 1085 | if (!ts.fail() && numberOfTypedefs[ts.name()].size() == 1) { |
| 1086 | if (mSettings.severity.isEnabled(Severity::portability) && ts.isInvalidConstFunctionType(typedefs)) |
| 1087 | invalidConstFunctionTypeError(tok->next()); |
| 1088 | typedefs.emplace(ts.name(), ts); |
| 1089 | if (!ts.isStructEtc()) |
| 1090 | tok = ts.endToken(); |
| 1091 | } |
| 1092 | continue; |
| 1093 | } |
| 1094 | |
| 1095 | auto it = typedefs.find(tok->str()); |
| 1096 | if (it != typedefs.end() && it->second.canReplace(tok) && !matchCurrentType(tok, inType)) { |
| 1097 | std::set<std::string> r; |
| 1098 | std::string originalname; |
| 1099 | while (it != typedefs.end() && r.insert(tok->str()).second) { |
| 1100 | if (originalname.empty()) |
| 1101 | originalname = tok->str(); |
| 1102 | it->second.replace(tok, originalname); |
nothing calls this directly
no test coverage detected