| 2922 | } |
| 2923 | |
| 2924 | bool Tokenizer::simplifyUsing() |
| 2925 | { |
| 2926 | if (!isCPP()) |
| 2927 | return false; |
| 2928 | |
| 2929 | // simplify using N::x; to using x = N::x; |
| 2930 | for (Token* tok = list.front(); tok; tok = tok->next()) { |
| 2931 | if (!Token::Match(tok, "using ::| %name% ::")) |
| 2932 | continue; |
| 2933 | const Token* ns = tok->tokAt(tok->strAt(1) == "::" ? 2 : 1); |
| 2934 | if (ns->isKeyword()) |
| 2935 | continue; |
| 2936 | Token* end = tok->tokAt(3); |
| 2937 | while (end && !Token::Match(end, "[;,]")) { |
| 2938 | if (end->str() == "<") // skip template args |
| 2939 | end = end->findClosingBracket(); |
| 2940 | else |
| 2941 | end = end->next(); |
| 2942 | } |
| 2943 | if (!end) |
| 2944 | continue; |
| 2945 | if (!end->tokAt(-1)->isNameOnly() || end->tokAt(-2)->isLiteral()) // e.g. operator=, operator""sv |
| 2946 | continue; |
| 2947 | tok->insertToken(end->strAt(-1))->insertToken("=")->isSimplifiedTypedef(true); |
| 2948 | if (end->str() == ",") { // comma-separated list |
| 2949 | end->str(";"); |
| 2950 | end->insertToken("using"); |
| 2951 | } |
| 2952 | tok = end; |
| 2953 | } |
| 2954 | |
| 2955 | const unsigned int maxReplacementTokens = 1000; // limit the number of tokens we replace |
| 2956 | |
| 2957 | bool substitute = false; |
| 2958 | ScopeInfo3 scopeInfo; |
| 2959 | ScopeInfo3 *currentScope = &scopeInfo; |
| 2960 | struct Using { |
| 2961 | Using(Token *start, Token *end) : startTok(start), endTok(end) {} |
| 2962 | Token *startTok; |
| 2963 | Token *endTok; |
| 2964 | }; |
| 2965 | std::list<Using> usingList; |
| 2966 | |
| 2967 | ProgressReporter progressReporter(mErrorLogger, mSettings.reportProgress, list.getSourceFilePath(), "Tokenize (using)"); |
| 2968 | |
| 2969 | for (Token *tok = list.front(); tok; tok = tok->next()) { |
| 2970 | progressReporter.report(tok->progressValue()); |
| 2971 | |
| 2972 | if (Settings::terminated()) |
| 2973 | return substitute; |
| 2974 | |
| 2975 | if (Token::Match(tok, "enum class|struct")) { |
| 2976 | Token *bodyStart = tok; |
| 2977 | while (Token::Match(bodyStart, "%name%|:|::|<")) { |
| 2978 | if (bodyStart->str() == "<") |
| 2979 | bodyStart = bodyStart->findClosingBracket(); |
| 2980 | bodyStart = bodyStart ? bodyStart->next() : nullptr; |
| 2981 | } |
no test coverage detected