* @throws InternalError thrown if unexpected tokens are encountered */
| 971 | * @throws InternalError thrown if unexpected tokens are encountered |
| 972 | */ |
| 973 | static void compilePrecedence2(Token *&tok, AST_state& state) |
| 974 | { |
| 975 | auto doCompileScope = [&](const Token* tok) -> bool { |
| 976 | const bool isStartOfCpp11Init = state.cpp && tok && tok->str() == "{" && iscpp11init(tok); |
| 977 | if (isStartOfCpp11Init || Token::simpleMatch(tok, "(")) { |
| 978 | tok = tok->previous(); |
| 979 | while (Token::simpleMatch(tok, "*")) |
| 980 | tok = tok->previous(); |
| 981 | while (tok && Token::Match(tok->previous(), ":: %type%")) |
| 982 | tok = tok->tokAt(-2); |
| 983 | if (tok && !tok->isKeyword()) |
| 984 | tok = tok->previous(); |
| 985 | return !Token::Match(tok, "new ::| %type%"); |
| 986 | } |
| 987 | return !findLambdaEndTokenWithoutAST(tok); |
| 988 | }; |
| 989 | |
| 990 | bool isNew = true; |
| 991 | if (doCompileScope(tok)) { |
| 992 | compileScope(tok, state); |
| 993 | isNew = false; |
| 994 | } |
| 995 | while (tok) { |
| 996 | if (tok->tokType() == Token::eIncDecOp && !isPrefixUnary(tok, state.cpp)) { |
| 997 | compileUnaryOp(tok, state, compileScope); |
| 998 | } else if (tok->str() == "...") { |
| 999 | if (!Token::simpleMatch(tok->previous(), ")")) |
| 1000 | state.op.push(tok); |
| 1001 | tok = tok->next(); |
| 1002 | break; |
| 1003 | } else if (tok->str() == "." && tok->strAt(1) != "*") { |
| 1004 | if (tok->strAt(1) == ".") { |
| 1005 | state.op.push(tok); |
| 1006 | tok = tok->tokAt(3); |
| 1007 | break; |
| 1008 | } |
| 1009 | if (!Token::Match(tok->tokAt(-1), "[{,]")) |
| 1010 | compileBinOp(tok, state, compileScope); |
| 1011 | else |
| 1012 | compileUnaryOp(tok, state, compileScope); |
| 1013 | } else if (tok->str() == "[") { |
| 1014 | if (state.cpp && isPrefixUnary(tok, /*cpp*/ true) && Token::Match(tok->link(), "] (|{|<")) { // Lambda |
| 1015 | // What we do here: |
| 1016 | // - Nest the round bracket under the square bracket. |
| 1017 | // - Nest what follows the lambda (if anything) with the lambda opening [ |
| 1018 | // - Compile the content of the lambda function as separate tree (this is done later) |
| 1019 | // this must be consistent with isLambdaCaptureList |
| 1020 | Token* const squareBracket = tok; |
| 1021 | // Parse arguments in the capture list |
| 1022 | if (tok->strAt(1) != "]") { |
| 1023 | Token* tok2 = tok->next(); |
| 1024 | AST_state state2(state.cpp); |
| 1025 | compileExpression(tok2, state2); |
| 1026 | if (!state2.op.empty()) { |
| 1027 | squareBracket->astOperand2(state2.op.top()); |
| 1028 | } |
| 1029 | } |
| 1030 |
no test coverage detected