/* * Cppcheck - A tool for static C/C++ code analysis * Copyright (C) 2007-2023 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "config.h" #include "errortypes.h" #include "helpers.h" #include "platform.h" #include "preprocessor.h" // usually tests here should not use preprocessor... #include "settings.h" #include "standards.h" #include "fixture.h" #include "token.h" #include "tokenize.h" #include "tokenlist.h" #include #include #include #include #include #include class TestTokenizer : public TestFixture { public: TestTokenizer() : TestFixture("TestTokenizer") {} private: const Settings settings0 = settingsBuilder().library("qt.cfg").build(); const Settings settings1 = settingsBuilder().library("qt.cfg").library("std.cfg").build(); const Settings settings_windows = settingsBuilder().library("windows.cfg").build(); void run() override { TEST_CASE(tokenize1); TEST_CASE(tokenize2); TEST_CASE(tokenize4); TEST_CASE(tokenize5); TEST_CASE(tokenize7); TEST_CASE(tokenize8); TEST_CASE(tokenize9); TEST_CASE(tokenize11); TEST_CASE(tokenize13); // bailout if the code contains "@" - that is not handled well. TEST_CASE(tokenize14); // tokenize "0X10" => 16 TEST_CASE(tokenizeHexWithSuffix); // tokenize 0xFFFFFFul TEST_CASE(tokenize15); // tokenize ".123" TEST_CASE(tokenize17); // #2759 TEST_CASE(tokenize18); // tokenize "(X&&Y)" into "( X && Y )" instead of "( X & & Y )" TEST_CASE(tokenize19); // #3006 (segmentation fault) TEST_CASE(tokenize21); // tokenize 0x0E-7 TEST_CASE(tokenize22); // special marker $ from preprocessor TEST_CASE(tokenize25); // #4239 (segmentation fault) TEST_CASE(tokenize26); // #4245 (segmentation fault) TEST_CASE(tokenize27); // #4525 (segmentation fault) TEST_CASE(tokenize31); // #3503 (Wrong handling of member function taking function pointer as argument) TEST_CASE(tokenize32); // #5884 (fsanitize=undefined: left shift of negative value -10000 in lib/templatesimplifier.cpp:852:46) TEST_CASE(tokenize33); // #5780 Various crashes on valid template code TEST_CASE(tokenize34); // #8031 TEST_CASE(tokenize35); // #8361 TEST_CASE(tokenize36); // #8436 TEST_CASE(tokenize37); // #8550 TEST_CASE(tokenize38); // #9569 TEST_CASE(tokenize39); // #9771 TEST_CASE(validate); TEST_CASE(objectiveC); // Syntax error should be written for objective C/C++ code. TEST_CASE(syntax_case_default); TEST_CASE(removePragma); TEST_CASE(foreach); // #3690 TEST_CASE(ifconstexpr); TEST_CASE(combineOperators); TEST_CASE(concatenateNegativeNumber); TEST_CASE(longtok); TEST_CASE(simplifyHeadersAndUnusedTemplates1); TEST_CASE(simplifyHeadersAndUnusedTemplates2); TEST_CASE(simplifyAt); TEST_CASE(inlineasm); TEST_CASE(simplifyAsm2); // #4725 (writing asm() around "^{}") TEST_CASE(ifAddBraces1); TEST_CASE(ifAddBraces2); TEST_CASE(ifAddBraces3); TEST_CASE(ifAddBraces4); TEST_CASE(ifAddBraces5); TEST_CASE(ifAddBraces7); TEST_CASE(ifAddBraces9); TEST_CASE(ifAddBraces11); TEST_CASE(ifAddBraces12); TEST_CASE(ifAddBraces13); TEST_CASE(ifAddBraces15); // #2616 - unknown macro before if TEST_CASE(ifAddBraces16); TEST_CASE(ifAddBraces17); // '} else' should be in the same line TEST_CASE(ifAddBraces18); // #3424 - if if { } else else TEST_CASE(ifAddBraces19); // #3928 - if for if else TEST_CASE(ifAddBraces20); // #5012 - syntax error 'else }' TEST_CASE(ifAddBracesLabels); // #5332 - if (x) label: {} .. TEST_CASE(switchAddBracesLabels); TEST_CASE(whileAddBraces); TEST_CASE(whileAddBracesLabels); TEST_CASE(doWhileAddBraces); TEST_CASE(doWhileAddBracesLabels); TEST_CASE(forAddBraces1); TEST_CASE(forAddBraces2); // #5088 TEST_CASE(forAddBracesLabels); TEST_CASE(simplifyExternC); TEST_CASE(simplifyKeyword); // #5842 - remove C99 static keyword between [] TEST_CASE(isOneNumber); TEST_CASE(simplifyFunctionParameters); TEST_CASE(simplifyFunctionParameters1); // #3721 TEST_CASE(simplifyFunctionParameters2); // #4430 TEST_CASE(simplifyFunctionParameters3); // #4436 TEST_CASE(simplifyFunctionParameters4); // #9421 TEST_CASE(simplifyFunctionParametersMultiTemplate); TEST_CASE(simplifyFunctionParametersErrors); TEST_CASE(simplifyFunctionTryCatch); TEST_CASE(removeParentheses1); // Ticket #61 TEST_CASE(removeParentheses3); TEST_CASE(removeParentheses4); // Ticket #390 TEST_CASE(removeParentheses5); // Ticket #392 TEST_CASE(removeParentheses6); TEST_CASE(removeParentheses7); TEST_CASE(removeParentheses8); // Ticket #1865 TEST_CASE(removeParentheses9); // Ticket #1962 TEST_CASE(removeParentheses10); // Ticket #2320 TEST_CASE(removeParentheses11); // Ticket #2505 TEST_CASE(removeParentheses12); // Ticket #2760 ',(b)=' TEST_CASE(removeParentheses13); TEST_CASE(removeParentheses14); // Ticket #3309 TEST_CASE(removeParentheses15); // Ticket #4142 TEST_CASE(removeParentheses16); // Ticket #4423 '*(x.y)=' TEST_CASE(removeParentheses17); // Don't remove parentheses in 'a ? b : (c>0 ? d : e);' TEST_CASE(removeParentheses18); // 'float(*a)[2]' => 'float *a[2]' TEST_CASE(removeParentheses19); // ((typeof(x) *)0) TEST_CASE(removeParentheses20); // Ticket #5479: a>(2); TEST_CASE(removeParentheses21); // Don't "simplify" casts TEST_CASE(removeParentheses22); TEST_CASE(removeParentheses23); // Ticket #6103 - Infinite loop upon valid input TEST_CASE(removeParentheses24); // Ticket #7040 TEST_CASE(removeParentheses25); // daca@home - a=(b,c) TEST_CASE(removeParentheses26); // Ticket #8875 a[0](0) TEST_CASE(removeParentheses27); TEST_CASE(removeParentheses28); // #12164 - don't remove parentheses in '(expr1) ? (expr2) : (expr3);' TEST_CASE(tokenize_double); TEST_CASE(tokenize_strings); TEST_CASE(simplifyStructDecl); TEST_CASE(vardecl1); TEST_CASE(vardecl2); TEST_CASE(vardecl3); TEST_CASE(vardecl4); TEST_CASE(vardecl5); // #7048 TEST_CASE(vardec_static); TEST_CASE(vardecl6); TEST_CASE(vardecl7); TEST_CASE(vardecl8); TEST_CASE(vardecl9); TEST_CASE(vardecl10); TEST_CASE(vardecl11); TEST_CASE(vardecl12); TEST_CASE(vardecl13); TEST_CASE(vardecl14); TEST_CASE(vardecl15); TEST_CASE(vardecl16); TEST_CASE(vardecl17); TEST_CASE(vardecl18); TEST_CASE(vardecl19); TEST_CASE(vardecl20); // #3700 - register const int H = 0; TEST_CASE(vardecl21); // #4042 - a::b const *p = 0; TEST_CASE(vardecl22); // #4211 - segmentation fault TEST_CASE(vardecl23); // #4276 - segmentation fault TEST_CASE(vardecl24); // #4187 - variable declaration within lambda function TEST_CASE(vardecl25); // #4799 - segmentation fault TEST_CASE(vardecl26); // #5907 - incorrect handling of extern declarations TEST_CASE(vardecl27); // #7850 - crash on valid C code TEST_CASE(vardecl28); TEST_CASE(vardecl29); // #9282 TEST_CASE(vardecl30); TEST_CASE(vardecl31); // function pointer init TEST_CASE(vardecl_stl_1); TEST_CASE(vardecl_stl_2); TEST_CASE(vardecl_stl_3); TEST_CASE(vardecl_template_1); TEST_CASE(vardecl_template_2); TEST_CASE(vardecl_union); TEST_CASE(vardecl_par); // #2743 - set links if variable type contains parentheses TEST_CASE(vardecl_par2); // #3912 - set correct links TEST_CASE(vardecl_par3); // #6556 - Fred x1(a), x2(b); TEST_CASE(vardecl_class_ref); TEST_CASE(volatile_variables); // unsigned i; => unsigned int i; TEST_CASE(implicitIntConst); TEST_CASE(implicitIntExtern); TEST_CASE(implicitIntSigned1); TEST_CASE(implicitIntUnsigned1); TEST_CASE(implicitIntUnsigned2); TEST_CASE(implicitIntUnsigned3); // template arguments TEST_CASE(simplifyStdType); // #4947, #4950, #4951 TEST_CASE(createLinks); TEST_CASE(createLinks2); TEST_CASE(simplifyString); TEST_CASE(simplifyConst); TEST_CASE(switchCase); TEST_CASE(simplifyPointerToStandardType); TEST_CASE(simplifyFunctionPointers1); TEST_CASE(simplifyFunctionPointers2); TEST_CASE(simplifyFunctionPointers3); TEST_CASE(simplifyFunctionPointers4); TEST_CASE(simplifyFunctionPointers5); TEST_CASE(simplifyFunctionPointers6); TEST_CASE(simplifyFunctionPointers7); TEST_CASE(simplifyFunctionPointers8); // #7410 - throw TEST_CASE(simplifyFunctionPointers9); // #6113 - function call with function pointer TEST_CASE(removedeclspec); TEST_CASE(removeattribute); TEST_CASE(functionAttributeBefore1); TEST_CASE(functionAttributeBefore2); TEST_CASE(functionAttributeBefore3); TEST_CASE(functionAttributeBefore4); TEST_CASE(functionAttributeBefore5); // __declspec(dllexport) TEST_CASE(functionAttributeAfter1); TEST_CASE(functionAttributeAfter2); TEST_CASE(functionAttributeListBefore); TEST_CASE(functionAttributeListAfter); TEST_CASE(splitTemplateRightAngleBrackets); TEST_CASE(cpp03template1); TEST_CASE(cpp0xtemplate1); TEST_CASE(cpp0xtemplate2); TEST_CASE(cpp0xtemplate3); TEST_CASE(cpp0xtemplate4); // Ticket #6181: Mishandled C++11 syntax TEST_CASE(cpp0xtemplate5); // Ticket #9154 change >> to > > TEST_CASE(cpp14template); // Ticket #6708 TEST_CASE(arraySize); TEST_CASE(arraySizeAfterValueFlow); TEST_CASE(labels); TEST_CASE(simplifyInitVar); TEST_CASE(simplifyInitVar2); TEST_CASE(simplifyInitVar3); TEST_CASE(bitfields1); TEST_CASE(bitfields2); TEST_CASE(bitfields3); TEST_CASE(bitfields4); // ticket #1956 TEST_CASE(bitfields5); // ticket #1956 TEST_CASE(bitfields6); // ticket #2595 TEST_CASE(bitfields7); // ticket #1987 TEST_CASE(bitfields8); TEST_CASE(bitfields9); // ticket #2706 TEST_CASE(bitfields10); TEST_CASE(bitfields12); // ticket #3485 (segmentation fault) TEST_CASE(bitfields13); // ticket #3502 (segmentation fault) TEST_CASE(bitfields15); // ticket #7747 (enum Foo {A,B}:4;) TEST_CASE(bitfields16); // Save bitfield bit count TEST_CASE(simplifyNamespaceStd); TEST_CASE(microsoftMemory); TEST_CASE(microsoftString); TEST_CASE(borland); TEST_CASE(simplifySQL); TEST_CASE(simplifyCAlternativeTokens); // x = ({ 123; }); => { x = 123; } TEST_CASE(simplifyRoundCurlyParentheses); TEST_CASE(simplifyOperatorName1); TEST_CASE(simplifyOperatorName2); TEST_CASE(simplifyOperatorName3); TEST_CASE(simplifyOperatorName4); TEST_CASE(simplifyOperatorName5); TEST_CASE(simplifyOperatorName6); // ticket #3194 TEST_CASE(simplifyOperatorName7); // ticket #4619 TEST_CASE(simplifyOperatorName8); // ticket #5706 TEST_CASE(simplifyOperatorName9); // ticket #5709 - comma operator not properly tokenized TEST_CASE(simplifyOperatorName10); // #8746 - using a::operator= TEST_CASE(simplifyOperatorName11); // #8889 TEST_CASE(simplifyOperatorName12); // #9110 TEST_CASE(simplifyOperatorName13); // user defined literal TEST_CASE(simplifyOperatorName14); // std::complex operator "" if TEST_CASE(simplifyOperatorName15); // ticket #9468 syntaxError TEST_CASE(simplifyOperatorName16); // ticket #9472 TEST_CASE(simplifyOperatorName17); TEST_CASE(simplifyOperatorName18); // global namespace TEST_CASE(simplifyOperatorName19); TEST_CASE(simplifyOperatorName20); TEST_CASE(simplifyOperatorName21); TEST_CASE(simplifyOperatorName22); TEST_CASE(simplifyOperatorName23); TEST_CASE(simplifyOperatorName24); TEST_CASE(simplifyOperatorName25); TEST_CASE(simplifyOperatorName26); TEST_CASE(simplifyOperatorName27); TEST_CASE(simplifyOperatorName28); TEST_CASE(simplifyOperatorName29); // spaceship operator TEST_CASE(simplifyOperatorName31); // #6342 TEST_CASE(simplifyOperatorName32); // #10256 TEST_CASE(simplifyOperatorName33); // #10138 TEST_CASE(simplifyOverloadedOperators1); TEST_CASE(simplifyOverloadedOperators2); // (*this)(123) TEST_CASE(simplifyOverloadedOperators3); // #9881 - hang TEST_CASE(simplifyNullArray); // Some simple cleanups of unhandled macros in the global scope TEST_CASE(removeMacrosInGlobalScope); TEST_CASE(addSemicolonAfterUnknownMacro); // a = b = 0; TEST_CASE(multipleAssignment); TEST_CASE(platformWin); TEST_CASE(platformWin32A); TEST_CASE(platformWin32W); TEST_CASE(platformWin32AStringCat); // ticket #5015 TEST_CASE(platformWin32WStringCat); // ticket #5015 TEST_CASE(platformWinWithNamespace); TEST_CASE(simplifyStaticConst); TEST_CASE(simplifyCPPAttribute); TEST_CASE(simplifyCaseRange); TEST_CASE(simplifyEmptyNamespaces); TEST_CASE(compileLimits); // #5592 crash: gcc: testsuit: gcc.c-torture/compile/limits-declparen.c TEST_CASE(prepareTernaryOpForAST); // AST data TEST_CASE(astexpr); TEST_CASE(astexpr2); // limit large expressions TEST_CASE(astpar); TEST_CASE(astnewdelete); TEST_CASE(astbrackets); TEST_CASE(astunaryop); TEST_CASE(astfunction); TEST_CASE(asttemplate); TEST_CASE(astcast); TEST_CASE(astlambda); TEST_CASE(astcase); TEST_CASE(astrefqualifier); TEST_CASE(astvardecl); TEST_CASE(astnewscoped); TEST_CASE(startOfExecutableScope); TEST_CASE(removeMacroInClassDef); // #6058 TEST_CASE(sizeofAddParentheses); TEST_CASE(reportUnknownMacros); // Make sure the Tokenizer::findGarbageCode() does not have false positives // The TestGarbage ensures that there are true positives TEST_CASE(findGarbageCode); TEST_CASE(checkEnableIf); TEST_CASE(checkTemplates); TEST_CASE(checkNamespaces); TEST_CASE(checkLambdas); TEST_CASE(checkIfCppCast); TEST_CASE(checkRefQualifiers); TEST_CASE(checkConditionBlock); TEST_CASE(checkUnknownCircularVar); // #9052 TEST_CASE(noCrash1); TEST_CASE(noCrash2); TEST_CASE(noCrash3); TEST_CASE(noCrash4); TEST_CASE(noCrash5); // #10603 TEST_CASE(noCrash6); // #10212 TEST_CASE(noCrash7); // --check-config TEST_CASE(checkConfiguration); TEST_CASE(unknownType); // #8952 TEST_CASE(unknownMacroBeforeReturn); TEST_CASE(cppcast); TEST_CASE(checkHeader1); TEST_CASE(removeExtraTemplateKeywords); TEST_CASE(removeAlignas1); TEST_CASE(removeAlignas2); // Do not remove alignof in the same way TEST_CASE(simplifyCoroutines); TEST_CASE(simplifySpaceshipOperator); TEST_CASE(simplifyIfSwitchForInit1); TEST_CASE(simplifyIfSwitchForInit2); TEST_CASE(simplifyIfSwitchForInit3); TEST_CASE(simplifyIfSwitchForInit4); TEST_CASE(simplifyIfSwitchForInit5); TEST_CASE(cpp20_default_bitfield_initializer); TEST_CASE(cpp11init); } #define tokenizeAndStringify(...) tokenizeAndStringify_(__FILE__, __LINE__, __VA_ARGS__) std::string tokenizeAndStringify_(const char* file, int linenr, const char code[], bool expand = true, Platform::Type platform = Platform::Type::Native, const char* filename = "test.cpp", Standards::cppstd_t std = Standards::CPP11) { errout.str(""); const Settings settings = settingsBuilder(settings1).debugwarnings().cpp(std).platform(platform).build(); // tokenize.. Tokenizer tokenizer(&settings, this); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, filename), file, linenr); // TODO: handle in a better way // filter out ValueFlow messages.. const std::string debugwarnings = errout.str(); errout.str(""); std::istringstream istr2(debugwarnings); std::string line; while (std::getline(istr2,line)) { if (line.find("bailout") == std::string::npos) errout << line << "\n"; } if (tokenizer.tokens()) return tokenizer.tokens()->stringifyList(false, expand, false, true, false, nullptr, nullptr); return ""; } #define tokenizeAndStringifyWindows(...) tokenizeAndStringifyWindows_(__FILE__, __LINE__, __VA_ARGS__) std::string tokenizeAndStringifyWindows_(const char* file, int linenr, const char code[], bool expand = true, Platform::Type platform = Platform::Type::Native, const char* filename = "test.cpp", bool cpp11 = true) { errout.str(""); const Settings settings = settingsBuilder(settings_windows).debugwarnings().cpp(cpp11 ? Standards::CPP11 : Standards::CPP03).platform(platform).build(); // tokenize.. Tokenizer tokenizer(&settings, this); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, filename), file, linenr); // filter out ValueFlow messages.. const std::string debugwarnings = errout.str(); errout.str(""); std::istringstream istr2(debugwarnings); std::string line; while (std::getline(istr2,line)) { if (line.find("valueflow.cpp") == std::string::npos) errout << line << "\n"; } if (tokenizer.tokens()) return tokenizer.tokens()->stringifyList(false, expand, false, true, false, nullptr, nullptr); return ""; } std::string tokenizeAndStringify_(const char* file, int line, const char code[], const Settings &settings, const char filename[] = "test.cpp") { errout.str(""); // tokenize.. Tokenizer tokenizer(&settings, this); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, filename), file, line); if (!tokenizer.tokens()) return ""; return tokenizer.tokens()->stringifyList(false, true, false, true, false, nullptr, nullptr); } #define tokenizeDebugListing(...) tokenizeDebugListing_(__FILE__, __LINE__, __VA_ARGS__) std::string tokenizeDebugListing_(const char* file, int line, const char code[], const char filename[] = "test.cpp") { errout.str(""); const Settings settings = settingsBuilder(settings0).c(Standards::C89).cpp(Standards::CPP03).build(); Tokenizer tokenizer(&settings, this); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, filename), file, line); // result.. return tokenizer.tokens()->stringifyList(true,true,true,true,false); } void tokenize1() { const char code[] = "void f ( )\n" "{ if ( p . y ( ) > yof ) { } }"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); } void tokenize2() { const char code[] = "{ sizeof a, sizeof b }"; ASSERT_EQUALS("{ sizeof ( a ) , sizeof ( b ) }", tokenizeAndStringify(code)); } void tokenize4() { const char code[] = "class foo\n" "{\n" "public:\n" " const int i;\n" "}"; ASSERT_EQUALS("class foo\n" "{\n" "public:\n" "const int i ;\n" "}", tokenizeAndStringify(code)); ASSERT_EQUALS("", errout.str()); } void tokenize5() { // Tokenize values ASSERT_EQUALS("; + 1E3 ;", tokenizeAndStringify("; +1E3 ;")); ASSERT_EQUALS("; 1E-2 ;", tokenizeAndStringify("; 1E-2 ;")); } void tokenize7() { const char code[] = "void f() {\n" " int x1 = 1;\n" " int x2(x1);\n" "}\n"; ASSERT_EQUALS("void f ( ) {\nint x1 ; x1 = 1 ;\nint x2 ; x2 = x1 ;\n}", tokenizeAndStringify(code)); } void tokenize8() { const char code[] = "void f() {\n" " int x1(g());\n" " int x2(x1);\n" "}\n"; ASSERT_EQUALS("1: void f ( ) {\n" "2: int x1@1 ; x1@1 = g ( ) ;\n" "3: int x2@2 ; x2@2 = x1@1 ;\n" "4: }\n", tokenizeDebugListing(code)); } void tokenize9() { const char code[] = "typedef void (*fp)();\n" "typedef fp (*fpp)();\n" "void f() {\n" " fpp x = (fpp)f();\n" "}"; tokenizeAndStringify(code); ASSERT_EQUALS("", errout.str()); } void tokenize11() { ASSERT_EQUALS("X * sizeof ( Y ( ) ) ;", tokenizeAndStringify("X * sizeof(Y());")); } // bailout if there is "@" - it is not handled well void tokenize13() { const char code[] = "@implementation\n" "-(Foo *)foo: (Bar *)bar\n" "{ }\n" "@end\n"; ASSERT_THROW(tokenizeAndStringify(code), InternalError); } // Ticket #2361: 0X10 => 16 void tokenize14() { ASSERT_EQUALS("; 0x10 ;", tokenizeAndStringify(";0x10;")); ASSERT_EQUALS("; 0X10 ;", tokenizeAndStringify(";0X10;")); ASSERT_EQUALS("; 0444 ;", tokenizeAndStringify(";0444;")); } // Ticket #8050 void tokenizeHexWithSuffix() { ASSERT_EQUALS("; 0xFFFFFF ;", tokenizeAndStringify(";0xFFFFFF;")); ASSERT_EQUALS("; 0xFFFFFFu ;", tokenizeAndStringify(";0xFFFFFFu;")); ASSERT_EQUALS("; 0xFFFFFFul ;", tokenizeAndStringify(";0xFFFFFFul;")); // Number of digits decides about internal representation... ASSERT_EQUALS("; 0xFFFFFFFF ;", tokenizeAndStringify(";0xFFFFFFFF;")); ASSERT_EQUALS("; 0xFFFFFFFFu ;", tokenizeAndStringify(";0xFFFFFFFFu;")); ASSERT_EQUALS("; 0xFFFFFFFFul ;", tokenizeAndStringify(";0xFFFFFFFFul;")); } // Ticket #2429: 0.125 void tokenize15() { ASSERT_EQUALS("0.125 ;", tokenizeAndStringify(".125;")); ASSERT_EQUALS("005.125 ;", tokenizeAndStringify("005.125;")); // Don't confuse with octal values } void tokenize17() { // #2759 ASSERT_EQUALS("class B : private :: A { } ;", tokenizeAndStringify("class B : private ::A { };")); } void tokenize18() { // tokenize "(X&&Y)" into "( X && Y )" instead of "( X & & Y )" ASSERT_EQUALS("( X && Y ) ;", tokenizeAndStringify("(X&&Y);")); } void tokenize19() { // #3006 - added hasComplicatedSyntaxErrorsInTemplates to avoid segmentation fault ASSERT_THROW(tokenizeAndStringify("x < () <"), InternalError); // #3496 - make sure hasComplicatedSyntaxErrorsInTemplates works ASSERT_EQUALS("void a ( Fred * f ) { for ( ; n < f . x ( ) ; ) { } }", tokenizeAndStringify("void a(Fred* f) MACRO { for (;n < f->x();) {} }")); // #6216 - make sure hasComplicatedSyntaxErrorsInTemplates works ASSERT_EQUALS("C :: C ( )\n" ": v { }\n" "{\n" "for ( int dim = 0 ; dim < v . size ( ) ; ++ dim ) {\n" "v [ dim ] . f ( ) ;\n" "}\n" "} ;", tokenizeAndStringify("C::C()\n" ":v{}\n" "{\n" " for (int dim = 0; dim < v.size(); ++dim) {\n" " v[dim]->f();\n" " }\n" "};")); } void tokenize21() { // tokenize 0x0E-7 ASSERT_EQUALS("0x0E - 7 ;", tokenizeAndStringify("0x0E-7;")); } void tokenize22() { // tokenize special marker $ from preprocessor ASSERT_EQUALS("a$b", tokenizeAndStringify("a$b")); ASSERT_EQUALS("a $b\nc", tokenizeAndStringify("a $b\nc")); ASSERT_EQUALS("a = $0 ;", tokenizeAndStringify("a = $0;")); ASSERT_EQUALS("a$ ++ ;", tokenizeAndStringify("a$++;")); ASSERT_EQUALS("$if ( ! p )", tokenizeAndStringify("$if(!p)")); } // #4239 - segfault for "f ( struct { int typedef T x ; } ) { }" void tokenize25() { ASSERT_THROW(tokenizeAndStringify("f ( struct { int typedef T x ; } ) { }"), InternalError); } // #4245 - segfault void tokenize26() { ASSERT_THROW(tokenizeAndStringify("class x { protected : template < int y = } ;"), InternalError); // Garbage code } void tokenize27() { // #4525 - segfault tokenizeAndStringify("struct except_spec_d_good : except_spec_a, except_spec_b {\n" "~except_spec_d_good();\n" "};\n" "struct S { S(); };\n" "S::S() __attribute((pure)) = default;" ); // original code: glibc-2.18/posix/bug-regex20.c tokenizeAndStringify("static unsigned int re_string_context_at (const re_string_t *input, int idx, int eflags) internal_function __attribute__ ((pure));"); } // #3503 - don't "simplify" SetFunction member function to a variable void tokenize31() { ASSERT_EQUALS("struct TTestClass { TTestClass ( ) { }\n" "void SetFunction ( Other ( * m_f ) ( ) ) { }\n" "} ;", tokenizeAndStringify("struct TTestClass { TTestClass() { }\n" " void SetFunction(Other(*m_f)()) { }\n" "};")); ASSERT_EQUALS("struct TTestClass { TTestClass ( ) { }\n" "void SetFunction ( Other ( * m_f ) ( ) ) ;\n" "} ;", tokenizeAndStringify("struct TTestClass { TTestClass() { }\n" " void SetFunction(Other(*m_f)());\n" "};")); } // #5884 - Avoid left shift of negative integer value. void tokenize32() { // Do not simplify negative integer left shifts. const char * code = "void f ( ) { int max_x ; max_x = -10000 << 16 ; }"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); } // #5780 Various crashes on valid template code in Tokenizer::setVarId() void tokenize33() { const char * code = "template> struct vector {};\n" "void z() {\n" " vector VI;\n" "}\n"; tokenizeAndStringify(code); } void tokenize34() { // #8031 { const char code[] = "struct Container {\n" " Container();\n" " int* mElements;\n" "};\n" "Container::Container() : mElements(nullptr) {}\n" "Container intContainer;"; const char exp[] = "1: struct Container {\n" "2: Container ( ) ;\n" "3: int * mElements@1 ;\n" "4: } ;\n" "5: Container :: Container ( ) : mElements@1 ( nullptr ) { }\n" "6: Container intContainer@2 ;\n"; ASSERT_EQUALS(exp, tokenizeDebugListing(code)); } { const char code[] = "template struct Container {\n" " Container();\n" " int* mElements;\n" "};\n" "template Container::Container() : mElements(nullptr) {}\n" "Container intContainer;"; const char exp[] = "1: struct Container ;\n" "2:\n" "|\n" "5:\n" "6: Container intContainer@1 ;\n" "1: struct Container {\n" "2: Container ( ) ;\n" "3: int * mElements@2 ;\n" "4: } ;\n" "5: Container :: Container ( ) : mElements@2 ( nullptr ) { }\n"; ASSERT_EQUALS(exp, tokenizeDebugListing(code)); } } void tokenize35() { // #8361 tokenizeAndStringify("typedef int CRCWord; " "template ::CRCWord const Compute(T const t) { return 0; }"); } void tokenize36() { // #8436 const char code[] = "int foo ( int i ) { return i ? * new int { 5 } : int { i ? 0 : 1 } ; }"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); } void tokenize37() { // #8550 const char codeC[] = "class name { public: static void init ( ) {} } ; " "typedef class name N; " "void foo ( ) { return N :: init ( ) ; }"; const char expC[] = "class name { public: static void init ( ) { } } ; " "void foo ( ) { return name :: init ( ) ; }"; ASSERT_EQUALS(expC, tokenizeAndStringify(codeC)); const char codeS[] = "class name { public: static void init ( ) {} } ; " "typedef struct name N; " "void foo ( ) { return N :: init ( ) ; }"; const char expS[] = "class name { public: static void init ( ) { } } ; " "void foo ( ) { return name :: init ( ) ; }"; ASSERT_EQUALS(expS, tokenizeAndStringify(codeS)); } void tokenize38() { // #9569 const char code[] = "using Binary = std::vector; enum Type { Binary };"; const char exp[] = "enum Type { Binary } ;"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } void tokenize39() { // #9771 const char code[] = "template class Foo;" "template bool operator!=(const Foo &, const Foo &);" "template class Foo { friend bool operator!= <> (const Foo &, const Foo &); };"; const char exp[] = "template < typename T > class Foo ; " "template < typename T > bool operator!= ( const Foo < T > & , const Foo < T > & ) ; " "template < typename T > class Foo { friend bool operator!= < > ( const Foo < T > & , const Foo < T > & ) ; } ;"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } void validate() { // C++ code in C file ASSERT_THROW(tokenizeAndStringify(";using namespace std;",false,Platform::Type::Native,"test.c"), InternalError); ASSERT_THROW(tokenizeAndStringify(";std::map m;",false,Platform::Type::Native,"test.c"), InternalError); ASSERT_THROW(tokenizeAndStringify(";template class X { };",false,Platform::Type::Native,"test.c"), InternalError); ASSERT_THROW(tokenizeAndStringify("int X() {};",false,Platform::Type::Native,"test.c"), InternalError); ASSERT_THROW(tokenizeAndStringify("void foo(int i) { reinterpret_cast(i) };",false,Platform::Type::Native,"test.h"), InternalError); } void objectiveC() { ASSERT_THROW(tokenizeAndStringify("void f() { [foo bar]; }"), InternalError); } void syntax_case_default() { // correct syntax tokenizeAndStringify("void f() {switch (n) { case 0: z(); break;}}"); ASSERT_EQUALS("", errout.str()); tokenizeAndStringify("void f() {switch (n) { case 0:; break;}}"); ASSERT_EQUALS("", errout.str()); // TODO: Do not throw AST validation exception TODO_ASSERT_THROW(tokenizeAndStringify("void f() {switch (n) { case 0?1:2 : z(); break;}}"), InternalError); //ASSERT_EQUALS("", errout.str()); // TODO: Do not throw AST validation exception TODO_ASSERT_THROW(tokenizeAndStringify("void f() {switch (n) { case 0?(1?3:4):2 : z(); break;}}"), InternalError); ASSERT_EQUALS("", errout.str()); //allow GCC '({ %name%|%num%|%bool% ; })' statement expression extension // TODO: Do not throw AST validation exception TODO_ASSERT_THROW(tokenizeAndStringify("void f() {switch (n) { case 0?({0;}):1: z(); break;}}"), InternalError); ASSERT_EQUALS("", errout.str()); //'b' can be or a macro or an undefined enum tokenizeAndStringify("void f() {switch (n) { case b: z(); break;}}"); ASSERT_EQUALS("", errout.str()); //valid, when there's this declaration: 'constexpr int g() { return 2; }' tokenizeAndStringify("void f() {switch (n) { case g(): z(); break;}}"); ASSERT_EQUALS("", errout.str()); //valid, when there's also this declaration: 'constexpr int g[1] = {0};' tokenizeAndStringify("void f() {switch (n) { case g[0]: z(); break;}}"); ASSERT_EQUALS("", errout.str()); //valid, similar to above case tokenizeAndStringify("void f() {switch (n) { case *g: z(); break;}}"); ASSERT_EQUALS("", errout.str()); //valid, when 'x' and 'y' are constexpr. tokenizeAndStringify("void f() {switch (n) { case sqrt(x+y): z(); break;}}"); ASSERT_EQUALS("", errout.str()); } void removePragma() { const char code[] = "_Pragma(\"abc\") int x;"; const Settings s_c89 = settingsBuilder().c(Standards::C89).build(); ASSERT_EQUALS("_Pragma ( \"abc\" ) int x ;", tokenizeAndStringify(code, s_c89, "test.c")); const Settings s_clatest = settingsBuilder().c(Standards::CLatest).build(); ASSERT_EQUALS("int x ;", tokenizeAndStringify(code, s_clatest, "test.c")); const Settings s_cpp03 = settingsBuilder().cpp(Standards::CPP03).build(); ASSERT_EQUALS("_Pragma ( \"abc\" ) int x ;", tokenizeAndStringify(code, s_cpp03, "test.cpp")); const Settings s_cpplatest = settingsBuilder().cpp(Standards::CPPLatest).build(); ASSERT_EQUALS("int x ;", tokenizeAndStringify(code, s_cpplatest, "test.cpp")); } void foreach () { // #3690,#5154 const char code[] ="void f() { for each ( char c in MyString ) { Console::Write(c); } }"; ASSERT_EQUALS("void f ( ) { asm ( \"char c in MyString\" ) { Console :: Write ( c ) ; } }", tokenizeAndStringify(code)); } void ifconstexpr() { ASSERT_EQUALS("void f ( ) { if ( FOO ) { bar ( c ) ; } }", tokenizeAndStringify("void f() { if constexpr ( FOO ) { bar(c); } }")); } void combineOperators() { ASSERT_EQUALS("; private: ;", tokenizeAndStringify(";private:;")); ASSERT_EQUALS("; protected: ;", tokenizeAndStringify(";protected:;")); ASSERT_EQUALS("; public: ;", tokenizeAndStringify(";public:;")); ASSERT_EQUALS("; __published: ;", tokenizeAndStringify(";__published:;")); ASSERT_EQUALS("a . public : ;", tokenizeAndStringify("a.public:;")); ASSERT_EQUALS("void f ( x & = 2 ) ;", tokenizeAndStringify("void f(x &= 2);")); ASSERT_EQUALS("const_cast < a * > ( & e )", tokenizeAndStringify("const_cast(&e)")); } void concatenateNegativeNumber() { ASSERT_EQUALS("i = -12 ;", tokenizeAndStringify("i = -12;")); ASSERT_EQUALS("1 - 2 ;", tokenizeAndStringify("1-2;")); ASSERT_EQUALS("foo ( -1 ) - 2 ;", tokenizeAndStringify("foo(-1)-2;")); ASSERT_EQUALS("int f ( ) { return -2 ; }", tokenizeAndStringify("int f(){return -2;}")); ASSERT_EQUALS("int x [ 2 ] = { -2 , 1 }", tokenizeAndStringify("int x[2] = {-2,1}")); ASSERT_EQUALS("f ( 123 )", tokenizeAndStringify("f(+123)")); } void longtok() { const std::string filedata(10000, 'a'); ASSERT_EQUALS(filedata, tokenizeAndStringify(filedata.c_str())); } void simplifyHeadersAndUnusedTemplates1() { const Settings s = settingsBuilder().checkUnusedTemplates(false).build(); ASSERT_EQUALS(";", tokenizeAndStringify("; template uint8_t b(std::tuple d) {\n" " std::tuple c{std::move(d)};\n" " return std::get<0>(c);\n" "}", s)); ASSERT_EQUALS("int g ( int ) ;", tokenizeAndStringify("int g(int);\n" "template auto h(F f, Ts... xs) {\n" " auto e = f(g(xs)...);\n" " return e;\n" "}", s)); } void simplifyHeadersAndUnusedTemplates2() { const char code[] = "; template< typename T, u_int uBAR = 0 >\n" "class Foo {\n" "public:\n" " void FooBar() {\n" " new ( (uBAR ? uBAR : sizeof(T))) T;\n" " }\n" "};"; { const Settings s = settingsBuilder().checkUnusedTemplates(false).build(); ASSERT_EQUALS(";", tokenizeAndStringify(code, s)); } { const Settings s; ASSERT_EQUALS("; template < typename T , u_int uBAR = 0 >\n" "class Foo {\n" "public:\n" "void FooBar ( ) {\n" "new ( uBAR ? uBAR : sizeof ( T ) ) T ;\n" "}\n" "} ;", tokenizeAndStringify(code, s)); } } void simplifyAt() { ASSERT_EQUALS("int x ;", tokenizeAndStringify("int x@123;")); ASSERT_EQUALS("bool x ;", tokenizeAndStringify("bool x@123:1;")); ASSERT_EQUALS("char PORTB ; bool PB3 ;", tokenizeAndStringify("char PORTB @ 0x10; bool PB3 @ PORTB:3;\n")); ASSERT_EQUALS("int x ;", tokenizeAndStringify("int x @ (0x1000 + 18);")); ASSERT_EQUALS("int x [ 10 ] ;", tokenizeAndStringify("int x[10]@0x100;")); ASSERT_EQUALS("interrupt@ f ( ) { }", tokenizeAndStringify("@interrupt f() {}")); } void inlineasm() { ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("asm { mov ax,bx };")); ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("_asm { mov ax,bx };")); ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("_asm mov ax,bx")); ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("__asm { mov ax,bx };")); ASSERT_EQUALS("asm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify("__asm__ __volatile__ ( \"mov ax,bx\" );")); ASSERT_EQUALS("asm ( \"_emit 12h\" ) ;", tokenizeAndStringify("__asm _emit 12h ;")); ASSERT_EQUALS("asm ( \"mov a , b\" ) ;", tokenizeAndStringify("__asm mov a, b ;")); ASSERT_EQUALS("asm ( \"\"fnstcw %0\" : \"= m\" ( old_cw )\" ) ;", tokenizeAndStringify("asm volatile (\"fnstcw %0\" : \"= m\" (old_cw));")); ASSERT_EQUALS("asm ( \"\"fnstcw %0\" : \"= m\" ( old_cw )\" ) ;", tokenizeAndStringify(" __asm__ (\"fnstcw %0\" : \"= m\" (old_cw));")); ASSERT_EQUALS("asm ( \"\"ddd\"\" ) ;", tokenizeAndStringify(" __asm __volatile__ (\"ddd\") ;")); ASSERT_EQUALS("asm ( \"\"ddd\"\" ) ;", tokenizeAndStringify(" __asm __volatile (\"ddd\") ;")); ASSERT_EQUALS("asm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify("__asm__ volatile ( \"mov ax,bx\" );")); ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ; int a ;", tokenizeAndStringify("asm { mov ax,bx } int a;")); ASSERT_EQUALS("asm\n\n( \"mov ax , bx\" ) ;", tokenizeAndStringify("__asm\nmov ax,bx\n__endasm;")); ASSERT_EQUALS("asm\n\n( \"push b ; for if\" ) ;", tokenizeAndStringify("__asm\npush b ; for if\n__endasm;")); // 'asm ( ) ;' should be in the same line ASSERT_EQUALS(";\n\nasm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify(";\n\n__asm__ volatile ( \"mov ax,bx\" );")); ASSERT_EQUALS("void func1 ( ) ;", tokenizeAndStringify("void func1() __asm__(\"...\") __attribute__();")); } // #4725 - ^{} void simplifyAsm2() { ASSERT_THROW(ASSERT_EQUALS("void f ( ) { asm ( \"^{}\" ) ; }", tokenizeAndStringify("void f() { ^{} }")), InternalError); ASSERT_THROW(ASSERT_EQUALS("void f ( ) { x ( asm ( \"^{}\" ) ) ; }", tokenizeAndStringify("void f() { x(^{}); }")), InternalError); ASSERT_THROW(ASSERT_EQUALS("void f ( ) { foo ( A ( ) , asm ( \"^{bar();}\" ) ) ; }", tokenizeAndStringify("void f() { foo(A(), ^{ bar(); }); }")), InternalError); ASSERT_THROW(ASSERT_EQUALS("int f0 ( Args args ) { asm ( \"asm(\"return^{returnsizeof...(Args);}()\")+^{returnsizeof...(args);}()\" )\n" "2:\n" "|\n" "5:\n" "6: ;\n" "} ;", tokenizeAndStringify("int f0(Args args) {\n" " return ^{\n" " return sizeof...(Args);\n" " }() + ^ {\n" " return sizeof...(args);\n" " }();\n" "};")), InternalError); ASSERT_THROW(ASSERT_EQUALS("int ( ^ block ) ( void ) = asm ( \"^{staticinttest=0;returntest;}\" )\n\n\n;", tokenizeAndStringify("int(^block)(void) = ^{\n" " static int test = 0;\n" " return test;\n" "};")), InternalError); ASSERT_THROW(ASSERT_EQUALS("; return f ( a [ b = c ] , asm ( \"^{}\" ) ) ;", tokenizeAndStringify("; return f(a[b=c],^{});")), InternalError); // #7185 ASSERT_EQUALS("{ return f ( asm ( \"^(void){somecode}\" ) ) ; }", tokenizeAndStringify("{ return f(^(void){somecode}); }")); ASSERT_THROW(ASSERT_EQUALS("; asm ( \"a?(b?(c,asm(\"^{}\")):0):^{}\" ) ;", tokenizeAndStringify(";a?(b?(c,^{}):0):^{};")), InternalError); ASSERT_EQUALS("template < typename T > " "CImg < T > operator| ( const char * const expression , const CImg < T > & img ) { " "return img | expression ; " "} " "template < typename T > " "CImg < T > operator^ ( const char * const expression , const CImg < T > & img ) { " "return img ^ expression ; " "} " "template < typename T > " "CImg < T > operator== ( const char * const expression , const CImg < T > & img ) { " "return img == expression ; " "}", tokenizeAndStringify("template < typename T >" "inline CImg operator|(const char *const expression, const CImg& img) {" " return img | expression ;" "}" "template" "inline CImg operator^(const char *const expression, const CImg& img) {" " return img ^ expression;" "}" "template" "inline CImg operator==(const char *const expression, const CImg& img) {" " return img == expression;" "}")); } void ifAddBraces1() { const char code[] = "void f()\n" "{\n" " if (a);\n" " else ;\n" "}\n"; ASSERT_EQUALS("void f ( )\n" "{\n" "if ( a ) { ; }\n" "else { ; }\n" "}", tokenizeAndStringify(code)); } void ifAddBraces2() { const char code[] = "void f()\n" "{\n" " if (a) if (b) { }\n" "}\n"; ASSERT_EQUALS("void f ( )\n" "{\n" "if ( a ) { if ( b ) { } }\n" "}", tokenizeAndStringify(code)); } void ifAddBraces3() { const char code[] = "void f()\n" "{\n" " if (a) for (;;) { }\n" "}\n"; ASSERT_EQUALS("void f ( )\n" "{\n" "if ( a ) { for ( ; ; ) { } }\n" "}", tokenizeAndStringify(code)); } void ifAddBraces4() { const char code[] = "char * foo ()\n" "{\n" " char *str = malloc(10);\n" " if (somecondition)\n" " for ( ; ; )\n" " { }\n" " return str;\n" "}\n"; ASSERT_EQUALS("char * foo ( )\n" "{\n" "char * str ; str = malloc ( 10 ) ;\n" "if ( somecondition ) {\n" "for ( ; ; )\n" "{ } }\n" "return str ;\n" "}", tokenizeAndStringify(code)); } void ifAddBraces5() { const char code[] = "void f()\n" "{\n" "for(int i = 0; i < 2; i++)\n" "if(true)\n" "return;\n" "\n" "return;\n" "}\n"; ASSERT_EQUALS("void f ( )\n" "{\n" "for ( int i = 0 ; i < 2 ; i ++ ) {\n" "if ( true ) {\n" "return ; } }\n\n" "return ;\n" "}", tokenizeAndStringify(code)); } void ifAddBraces7() { const char code[] = "void f()\n" "{\n" "int a;\n" "if( a )\n" " ({a=4;}),({a=5;});\n" "}\n"; ASSERT_EQUALS("void f ( )\n" "{\n" "int a ;\n" "if ( a ) {\n" "( { a = 4 ; } ) , ( { a = 5 ; } ) ; }\n" "}", tokenizeAndStringify(code)); } void ifAddBraces9() { // ticket #990 const char code[] = "void f() {" " for (int k=0; k 0 ) ;\n" " return 0 ;\n" "}\n"; const char result[] = "void foo ( int c , int d ) {\n" "do {\n" "if ( c ) {\n" "while ( c ) { c -- ; }\n" "} }\n" "while ( -- d > 0 ) ;\n" "return 0 ;\n" "}"; ASSERT_EQUALS(result, tokenizeAndStringify(code)); } { const char code[] = "void foo ( int c , int d ) {\n" " do\n" " do c -- ; while ( c ) ;\n" " while ( -- d > 0 ) ;\n" " return 0 ;\n" "}\n"; const char result[] = "void foo ( int c , int d ) {\n" "do {\n" "do { c -- ; } while ( c ) ; }\n" "while ( -- d > 0 ) ;\n" "return 0 ;\n" "}"; ASSERT_EQUALS(result, tokenizeAndStringify(code)); } { // #8148 - while inside the do-while body const char code[] = "void foo() {\n" " do { while (x) f(); } while (y);\n" "}"; const char result[] = "void foo ( ) {\n" "do { while ( x ) { f ( ) ; } } while ( y ) ;\n" "}"; ASSERT_EQUALS(result, tokenizeAndStringify(code)); } } void doWhileAddBracesLabels() { // Labels before statement ASSERT_EQUALS("void f ( int x ) {\n" "do {\n" "l1 : ; l2 : ; -- x ; }\n" "while ( x ) ;\n" "}", tokenizeAndStringify("void f(int x) {\n" " do\n" " l1: l2: --x;\n" " while (x);\n" "}")); // Labels before { ASSERT_EQUALS("void f ( int x ) {\n" "do\n" "{ l1 : ; l2 : ; -- x ; }\n" "while ( x ) ;\n" "}", tokenizeAndStringify("void f(int x) {\n" " do\n" " l1: l2: { -- x; }\n" " while (x);\n" "}")); // Labels before try/catch ASSERT_EQUALS("void f ( int x ) {\n" "do {\n" "l1 : ; l2 : ;\n" "try { throw 1 ; }\n" "catch ( ... ) { -- x ; } }\n" "while ( x ) ;\n" "}", tokenizeAndStringify("void f(int x) {\n" " do\n" " l1: l2:\n" " try { throw 1; }\n" " catch(...) { --x; }\n" " while (x);\n" "}")); } void forAddBraces1() { { const char code[] = "void f() {\n" " for(;;)\n" " if (a) { }\n" " else { }\n" "}"; const char expected[] = "void f ( ) {\n" "for ( ; ; ) {\n" "if ( a ) { }\n" "else { } }\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "void f() {\n" " for(;;)\n" " if (a) { }\n" " else if (b) { }\n" " else { }\n" "}"; const char expected[] = "void f ( ) {\n" "for ( ; ; ) {\n" "if ( a ) { }\n" "else { if ( b ) { }\n" "else { } } }\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } } void forAddBraces2() { // #5088 const char code[] = "void f() {\n" " for(;;) try { } catch (...) { }\n" "}"; const char expected[] = "void f ( ) {\n" "for ( ; ; ) { try { } catch ( ... ) { } }\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } void forAddBracesLabels() { // Labels before statement ASSERT_EQUALS("void f ( int x ) {\n" "for ( ; x ; ) {\n" "l1 : ; l2 : ; -- x ; }\n" "}", tokenizeAndStringify("void f(int x) {\n" " for ( ; x; )\n" " l1: l2: --x;\n" "}")); // Labels before { ASSERT_EQUALS("void f ( int x ) {\n" "for ( ; x ; )\n" "{ l1 : ; l2 : ; -- x ; }\n" "}", tokenizeAndStringify("void f(int x) {\n" " for ( ; x; )\n" " l1: l2: { -- x; }\n" "}")); // Labels before try/catch ASSERT_EQUALS("void f ( int x ) {\n" "for ( ; x ; ) {\n" "l1 : ; l2 : ;\n" "try { throw 1 ; }\n" "catch ( ... ) { -- x ; } }\n" "}", tokenizeAndStringify("void f(int x) {\n" " for ( ; x; )\n" " l1: l2:\n" " try { throw 1; }\n" " catch(...) { --x; }\n" "}")); } void simplifyExternC() { const char expected[] = "int foo ( ) ;"; { const char code[] = "extern \"C\" int foo();"; // tokenize.. Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); // Expected result.. ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); ASSERT(tokenizer.tokens()->next()->isExternC()); } { const char code[] = "extern \"C\" { int foo(); }"; // tokenize.. Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); // Expected result.. ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); ASSERT(tokenizer.tokens()->next()->isExternC()); } { const char code[] = "extern \"C++\" int foo();"; // tokenize.. Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); // Expected result.. ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); ASSERT(!tokenizer.tokens()->next()->isExternC()); } { const char code[] = "extern \"C++\" { int foo(); }"; // tokenize.. Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); // Expected result.. ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); ASSERT(!tokenizer.tokens()->next()->isExternC()); } } void simplifyFunctionParameters() { { const char code[] = "char a [ ABC ( DEF ) ] ;"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); } { const char code[] = "module ( a , a , sizeof ( a ) , 0444 ) ;"; ASSERT_EQUALS("module ( a , a , sizeof ( a ) , 0444 ) ;", tokenizeAndStringify(code)); } ASSERT_EQUALS("void f ( int x ) { }", tokenizeAndStringify("void f(x) int x; { }")); ASSERT_EQUALS("void f ( int x , char y ) { }", tokenizeAndStringify("void f(x,y) int x; char y; { }")); ASSERT_EQUALS("int main ( int argc , char * argv [ ] ) { }", tokenizeAndStringify("int main(argc,argv) int argc; char *argv[]; { }")); ASSERT_EQUALS("int f ( int p , int w , float d ) { }", tokenizeAndStringify("int f(p,w,d) float d; { }")); // #1067 - Not simplified. Feel free to fix so it is simplified correctly but this syntax is obsolescent. ASSERT_EQUALS("int ( * d ( a , b , c ) ) ( ) int a ; int b ; int c ; { }", tokenizeAndStringify("int (*d(a,b,c))()int a,b,c; { }")); { // This is not a function but the pattern is similar.. const char code[] = "void foo()" "{" " if (x)" " int x;" " { }" "}"; ASSERT_EQUALS("void foo ( ) { if ( x ) { int x ; } { } }", tokenizeAndStringify(code)); } } void simplifyFunctionParameters1() { // ticket #3721 const char code[] = "typedef float ufloat;\n" "typedef short ftnlen;\n" "int f(p,w,d,e,len) ufloat *p; ftnlen len;\n" "{\n" "}\n"; ASSERT_EQUALS("int f ( float * p , int w , int d , int e , short len )\n" "{\n" "}", tokenizeAndStringify(code)); } void simplifyFunctionParameters2() { // #4430 const char code[] = "class Item { " "int i ; " "public: " "Item ( int i ) ; " "} ; " "Item :: Item ( int i ) : i ( i ) { }"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); } void simplifyFunctionParameters3() { // #4436 const char code[] = "class Item { " "int i ; " "int j ; " "public: " "Item ( int i , int j ) ; " "} ; " "Item :: Item ( int i , int j ) : i ( i ) , j ( j ) { }"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); } void simplifyFunctionParameters4() { // #9421 const char code[] = "int foo :: bar ( int , int ) const ;"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); } void simplifyFunctionParametersMultiTemplate() { const char code[] = "template < typename T1 > template < typename T2 > " "void A < T1 > :: foo ( T2 ) { }"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); } void simplifyFunctionParametersErrors() { //same parameters... ASSERT_THROW(tokenizeAndStringify("void foo(x, x)\n" " int x;\n" " int x;\n" "{}\n"), InternalError); ASSERT_THROW(tokenizeAndStringify("void foo(x, y)\n" " int x;\n" " int x;\n" "{}\n"), InternalError); tokenizeAndStringify("void foo(int, int)\n" "{}"); ASSERT_EQUALS("", errout.str()); // #3848 - Don't hang tokenizeAndStringify("sal_Bool ShapeHasText(sal_uLong, sal_uLong) const {\n" " return sal_True;\n" "}\n" "void CreateSdrOLEFromStorage() {\n" " comphelper::EmbeddedObjectContainer aCnt( xDestStorage );\n" " { }\n" "}"); ASSERT_EQUALS("", errout.str()); } void simplifyFunctionTryCatch() { ASSERT_EQUALS("void foo ( ) { try {\n" "} catch ( int ) {\n" "} catch ( char ) {\n" "} }", tokenizeAndStringify("void foo() try {\n" "} catch (int) {\n" "} catch (char) {\n" "}")); ASSERT_EQUALS("void foo ( ) { try {\n" "struct S {\n" "void bar ( ) { try {\n" "} catch ( int ) {\n" "} catch ( char ) {\n" "} }\n" "} ;\n" "} catch ( long ) {\n" "} }", tokenizeAndStringify("void foo() try {\n" " struct S {\n" " void bar() try {\n" " } catch (int) {\n" " } catch (char) {\n" " }\n" " };\n" "} catch (long) {\n" "}")); } // Simplify "((..))" into "(..)" void removeParentheses1() { const char code[] = "void foo()" "{" " free(((void*)p));" "}"; ASSERT_EQUALS("void foo ( ) { free ( ( void * ) p ) ; }", tokenizeAndStringify(code)); } void removeParentheses3() { { const char code[] = "void foo()" "{" " if (( true )==(true)){}" "}"; ASSERT_EQUALS("void foo ( ) { if ( true == true ) { } }", tokenizeAndStringify(code)); } { const char code[] = "void foo()" "{" " if (( 2 )==(2)){}" "}"; ASSERT_EQUALS("void foo ( ) { if ( 2 == 2 ) { } }", tokenizeAndStringify(code)); } { const char code[] = "void foo()" "{" " if( g(10)){}" "}"; ASSERT_EQUALS("void foo ( ) { if ( g ( 10 ) ) { } }", tokenizeAndStringify(code)); } } // Simplify "( function (..))" into "function (..)" void removeParentheses4() { const char code[] = "void foo()" "{" " (free(p));" "}"; ASSERT_EQUALS("void foo ( ) { free ( p ) ; }", tokenizeAndStringify(code)); } void removeParentheses5() { // Simplify "( delete x )" into "delete x" { const char code[] = "void foo()" "{" " (delete p);" "}"; ASSERT_EQUALS("void foo ( ) { delete p ; }", tokenizeAndStringify(code)); } // Simplify "( delete [] x )" into "delete [] x" { const char code[] = "void foo()" "{" " (delete [] p);" "}"; ASSERT_EQUALS("void foo ( ) { delete [ ] p ; }", tokenizeAndStringify(code)); } } // "!(abc.a)" => "!abc.a" void removeParentheses6() { { const char code[] = "(!(abc.a));"; ASSERT_EQUALS("( ! abc . a ) ;", tokenizeAndStringify(code)); } //handle more complex member selections { const char code[] = "(!(a.b.c.d));"; ASSERT_EQUALS("( ! a . b . c . d ) ;", tokenizeAndStringify(code)); } } void removeParentheses7() { const char code[] = ";char *p; (delete(p), (p)=0);"; ASSERT_EQUALS("; char * p ; delete ( p ) , p = 0 ;", tokenizeAndStringify(code)); } void removeParentheses8() { const char code[] = "struct foo {\n" " void operator delete(void *obj, size_t sz);\n" "}\n"; const std::string actual(tokenizeAndStringify(code, true, Platform::Type::Win32A)); const char expected[] = "struct foo {\n" "void operatordelete ( void * obj , unsigned long sz ) ;\n" "}"; ASSERT_EQUALS(expected, actual); } void removeParentheses9() { ASSERT_EQUALS("void delete ( double num ) ;", tokenizeAndStringify("void delete(double num);")); } void removeParentheses10() { ASSERT_EQUALS("p = buf + 8 ;", tokenizeAndStringify("p = (buf + 8);")); } void removeParentheses11() { // #2502 ASSERT_EQUALS("{ } x ( ) ;", tokenizeAndStringify("{}(x());")); } void removeParentheses12() { // #2760 ASSERT_EQUALS(", x = 0 ;", tokenizeAndStringify(",(x)=0;")); } void removeParentheses13() { ASSERT_EQUALS("; f ( a + b , c ) ;", tokenizeAndStringify(";f((a+b),c);")); ASSERT_EQUALS("; x = y [ a + b ] ;", tokenizeAndStringify(";x=y[(a+b)];")); } void removeParentheses14() { ASSERT_EQUALS("{ if ( ( i & 1 ) == 0 ) { ; } }", tokenizeAndStringify("{ if ( (i & 1) == 0 ); }")); } void removeParentheses15() { ASSERT_EQUALS("a = b ? c : 123 ;", tokenizeAndStringify("a = b ? c : (123);")); ASSERT_EQUALS("a = b ? c : ( 123 + 456 ) ;", tokenizeAndStringify("a = b ? c : ((123)+(456));")); ASSERT_EQUALS("a = b ? ( 123 ) : c ;", tokenizeAndStringify("a = b ? (123) : c;")); // #4316 ASSERT_EQUALS("a = b ? c : ( d = 1 , 0 ) ;", tokenizeAndStringify("a = b ? c : (d=1,0);")); } void removeParentheses16() { // *(x.y)= // #4423 ASSERT_EQUALS("; * x = 0 ;", tokenizeAndStringify(";*(x)=0;")); ASSERT_EQUALS("; * x . y = 0 ;", tokenizeAndStringify(";*(x.y)=0;")); } void removeParentheses17() { // a ? b : (c > 0 ? d : e) ASSERT_EQUALS("a ? b : ( c > 0 ? d : e ) ;", tokenizeAndStringify("a?b:(c>0?d:e);")); } void removeParentheses18() { ASSERT_EQUALS("float ( * a ) [ 2 ] ;", tokenizeAndStringify("float(*a)[2];")); } void removeParentheses19() { ASSERT_EQUALS("( ( ( typeof ( X ) ) * ) 0 ) ;", tokenizeAndStringify("(((typeof(X))*)0);")); } void removeParentheses20() { ASSERT_EQUALS("a < b < int > > ( 2 ) ;", tokenizeAndStringify("a>(2);")); } void removeParentheses21() { ASSERT_EQUALS("a = ( int ) - b ;", tokenizeAndStringify("a = ((int)-b);")); } void removeParentheses22() { static char code[] = "struct S { " "char *(a); " "char &(b); " "const static char *(c); " "} ;"; static const char exp[] = "struct S { " "char * a ; " "char & b ; " "static const char * c ; " "} ;"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } void removeParentheses23() { // Ticket #6103 // Reported case { static char code[] = "; * * p f ( ) int = { new int ( * [ 2 ] ) ; void }"; static const char exp[] = "; * * p f ( ) int = { new int ( * [ 2 ] ) ; void }"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } // Various valid cases { static char code[] = "int * f [ 1 ] = { new ( int ) } ;"; static const char exp[] = "int * f [ 1 ] = { new int } ;"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } { static char code[] = "int * * f [ 1 ] = { new ( int ) [ 1 ] } ;"; static const char exp[] = "int * * f [ 1 ] = { new int [ 1 ] } ;"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } { static char code[] = "list < int > * f [ 1 ] = { new ( list < int > ) } ;"; static const char exp[] = "list < int > * f [ 1 ] = { new list < int > } ;"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } // don't remove parentheses in operator new overload { static char code[] = "void *operator new(__SIZE_TYPE__, int);"; static const char exp[] = "void * operatornew ( __SIZE_TYPE__ , int ) ;"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } } void removeParentheses24() { // Ticket #7040 static char code[] = "std::hash()(t._data);"; static const char exp[] = "std :: hash < decltype ( t . _data ) > ( ) ( t . _data ) ;"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } void removeParentheses25() { // daca@home - a=(b,c) static char code[] = "a=(b,c);"; static const char exp[] = "a = ( b , c ) ;"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } void removeParentheses26() { // Ticket #8875 a[0](0) static char code[] = "a[0](0);"; static const char exp[] = "a [ 0 ] ( 0 ) ;"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } void removeParentheses27() { static char code[] = "struct S { int i; };\n" "void g(int, int);\n" "void f(S s, int j) {\n" " g(j, (decltype(s.i))j * s.i);\n" "}\n"; static const char exp[] = "struct S { int i ; } ;\n" "void g ( int , int ) ;\n" "void f ( S s , int j ) {\n" "g ( j , ( decltype ( s . i ) ) j * s . i ) ;\n" "}"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } void removeParentheses28() { // Ticket #12164 static char code[] = "temp1 = (value > 100U) ? (value+100U) : (value-50U);"; static const char exp[] = "temp1 = ( value > 100U ) ? ( value + 100U ) : ( value - 50U ) ;"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } void tokenize_double() { const char code[] = "void f() {\n" " double a = 4.2;\n" " float b = 4.2f;\n" " double c = 4.2e+10;\n" " double d = 4.2e-10;\n" " int e = 4+2;\n" "}"; ASSERT_EQUALS("void f ( ) {\n" "double a ; a = 4.2 ;\n" "float b ; b = 4.2f ;\n" "double c ; c = 4.2e+10 ;\n" "double d ; d = 4.2e-10 ;\n" "int e ; e = 4 + 2 ;\n" "}", tokenizeAndStringify(code)); } void tokenize_strings() { const char code[] = "void f() {\n" "const char *a =\n" "{\n" "\"hello \"\n" "\"more \"\n" "\"world\"\n" "};\n" "}"; ASSERT_EQUALS("void f ( ) {\n" "const char * a ; a =\n" "{\n" "\"hello more world\"\n" "\n" "\n" "} ;\n" "}", tokenizeAndStringify(code)); } void simplifyStructDecl() { const char code[] = "const struct A { int a; int b; } a;"; ASSERT_EQUALS("struct A { int a ; int b ; } ; const struct A a ;", tokenizeAndStringify(code)); // #9519 const char code2[] = "enum A {} (a);"; const char expected2[] = "enum A { } ; enum A a ;"; ASSERT_EQUALS(expected2, tokenizeAndStringify(code2)); // #11052 const char code3[] = "struct a { int b; } static e[1];"; const char expected3[] = "struct a { int b ; } ; struct a static e [ 1 ] ;"; ASSERT_EQUALS(expected3, tokenizeAndStringify(code3)); // #11013 - Do not remove unnamed struct in union const char code4[] = "union U { struct { int a; int b; }; int ab[2]; };"; const char expected4[] = "union U { struct { int a ; int b ; } ; int ab [ 2 ] ; } ;"; ASSERT_EQUALS(expected4, tokenizeAndStringify(code4)); } void vardecl1() { const char code[] = "unsigned int a, b;"; const std::string actual(tokenizeAndStringify(code)); ASSERT_EQUALS("unsigned int a ; unsigned int b ;", actual); } void vardecl2() { const char code[] = "void foo(a,b) unsigned int a, b; { }"; const std::string actual(tokenizeAndStringify(code)); ASSERT_EQUALS("void foo ( unsigned int a , unsigned int b ) { }", actual); } void vardecl3() { const char code[] = "void f() { char * p = foo<10,char>(); }"; const std::string actual(tokenizeAndStringify(code)); ASSERT_EQUALS("void f ( ) { char * p ; p = foo < 10 , char > ( ) ; }", actual); } void vardecl4() { // ticket #346 const char code1[] = "void *p = NULL;"; const char res1[] = "void * p ; p = NULL ;"; ASSERT_EQUALS(res1, tokenizeAndStringify(code1)); const char code2[] = "const void *p = NULL;"; const char res2[] = "const void * p ; p = NULL ;"; ASSERT_EQUALS(res2, tokenizeAndStringify(code2)); const char code3[] = "void * const p = NULL;"; const char res3[] = "void * const p ; p = NULL ;"; ASSERT_EQUALS(res3, tokenizeAndStringify(code3)); const char code4[] = "const void * const p = NULL;"; const char res4[] = "const void * const p ; p = NULL ;"; ASSERT_EQUALS(res4, tokenizeAndStringify(code4)); const char code5[] = "const void * volatile p = NULL;"; const char res5[] = "const void * volatile p ; p = NULL ;"; ASSERT_EQUALS(res5, tokenizeAndStringify(code5)); } void vardecl5() { ASSERT_EQUALS("void foo ( int nX ) {\n" "int addI ; addI = frontPoint == 2 || frontPoint == 1 ? ( i = 0 , 1 ) : ( i = nX - 2 , -1 ) ;\n" "}", tokenizeAndStringify("void foo(int nX) {\n" " int addI = frontPoint == 2 || frontPoint == 1 ? i = 0, 1 : (i = nX - 2, -1);\n" "}")); } void vardecl_stl_1() { // ticket #520 const char code1[] = "std::vectora, b;"; const char res1[] = "std :: vector < std :: string > a ; std :: vector < std :: string > b ;"; ASSERT_EQUALS(res1, tokenizeAndStringify(code1)); const char code2[] = "std::vector::const_iterator it, cit;"; const char res2[] = "std :: vector < std :: string > :: const_iterator it ; std :: vector < std :: string > :: const_iterator cit ;"; ASSERT_EQUALS(res2, tokenizeAndStringify(code2)); const char code3[] = "std::vector > *c, d;"; const char res3[] = "std :: vector < std :: pair < std :: string , std :: string > > * c ; std :: vector < std :: pair < std :: string , std :: string > > d ;"; ASSERT_EQUALS(res3, tokenizeAndStringify(code3)); } void vardecl_stl_2() { const char code1[] = "{ std::string x = \"abc\"; }"; ASSERT_EQUALS("{ std :: string x ; x = \"abc\" ; }", tokenizeAndStringify(code1)); const char code2[] = "{ std::vector x = y; }"; ASSERT_EQUALS("{ std :: vector < int > x ; x = y ; }", tokenizeAndStringify(code2)); } void vardecl_stl_3() { const char code1[] = "{ std::string const x = \"abc\"; }"; ASSERT_EQUALS("{ const std :: string x = \"abc\" ; }", tokenizeAndStringify(code1)); const char code2[] = "{ std::vector const x = y; }"; ASSERT_EQUALS("{ const std :: vector < int > x = y ; }", tokenizeAndStringify(code2)); } void vardecl_template_1() { // ticket #1046 const char code1[] = "b<(1<<24),10,24> u, v;"; const char res1[] = "b < 16777216 , 10 , 24 > u ; b < 16777216 , 10 , 24 > v ;"; ASSERT_EQUALS(res1, tokenizeAndStringify(code1)); // ticket #3571 (segmentation fault) tokenizeAndStringify("template 4) > class X4 {};"); } void vardecl_template_2() { // ticket #3650 const char code[] = "const string str = x<8,int>();"; const char expected[] = "const string str = x < 8 , int > ( ) ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } void vardecl_union() { // ticket #1976 const char code1[] = "class Fred { public: union { int a ; int b ; } ; } ;"; ASSERT_EQUALS(code1, tokenizeAndStringify(code1)); // ticket #2039 const char code2[] = "void f() {\n" " union {\n" " int x;\n" " long y;\n" " };\n" "}"; ASSERT_EQUALS("void f ( ) {\nunion {\nint x ;\nlong y ;\n} ;\n}", tokenizeAndStringify(code2)); // ticket #3927 const char code3[] = "union xy *p = NULL;"; ASSERT_EQUALS("union xy * p ; p = NULL ;", tokenizeAndStringify(code3)); } void vardecl_par() { // ticket #2743 - set links if variable type contains parentheses const char code[] = "Fred fred1=a, fred2=b;"; ASSERT_EQUALS("Fred < int ( * ) ( ) > fred1 ; fred1 = a ; Fred < int ( * ) ( ) > fred2 ; fred2 = b ;", tokenizeAndStringify(code)); } void vardecl_par2() { // ticket #3912 - set correct links const char code[] = "function)> v;"; ASSERT_EQUALS("function < void ( shared_ptr < MyClass > ) > v ;", tokenizeAndStringify(code)); } void vardecl_par3() { // ticket #6556- Fred x1(a), x2(b); const char code[] = "Fred x1(a), x2(b);"; ASSERT_EQUALS("Fred x1 ( a ) ; Fred x2 ( b ) ;", tokenizeAndStringify(code)); } void vardecl_class_ref() { const char code[] = "class A { B &b1,&b2; };"; ASSERT_EQUALS("class A { B & b1 ; B & b2 ; } ;", tokenizeAndStringify(code)); } void vardec_static() { { // don't simplify declarations of static variables // "static int i = 0;" is not the same as "static int i; i = 0;" const char code[] = "static int i = 0 ;"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); } { const char code[] = "static int a, b;"; ASSERT_EQUALS("static int a ; static int b ;", tokenizeAndStringify(code)); } { const char code[] = "static unsigned int a, b;"; ASSERT_EQUALS("static unsigned int a ; static unsigned int b ;", tokenizeAndStringify(code)); } { const char code[] = "static int a=1, b=1;"; ASSERT_EQUALS("static int a = 1 ; static int b = 1 ;", tokenizeAndStringify(code)); } { const char code[] = "static int *a, *b;"; ASSERT_EQUALS("static int * a ; static int * b ;", tokenizeAndStringify(code)); } { const char code[] = "static unsigned int *a=0, *b=0;"; ASSERT_EQUALS("static unsigned int * a = 0 ; static unsigned int * b = 0 ;", tokenizeAndStringify(code)); } { // Ticket #4450 const char code[] = "static int large_eeprom_type = (13 | (5)), " "default_flash_type = 42;"; ASSERT_EQUALS("static int large_eeprom_type = 13 | 5 ; static int default_flash_type = 42 ;", tokenizeAndStringify(code)); } { // Ticket #5121 const char code[] = "unsigned int x;" "static const unsigned int A = 1, B = A, C = 0, D = (A), E = 0;" "void f() {" " unsigned int *foo = &x;" "}"; ASSERT_EQUALS("unsigned int x ; " "static const unsigned int A = 1 ; " "static const unsigned int B = A ; " "static const unsigned int C = 0 ; " "static const unsigned int D = A ; " "static const unsigned int E = 0 ; " "void f ( ) { " "unsigned int * foo ; " "foo = & x ; " "}", tokenizeAndStringify(code)); } { // Ticket #5266 const char code[] = "class Machine {\n" " static int const STACK_ORDER = 10, STACK_MAX = 1 << STACK_ORDER," " STACK_GUARD = 2;\n" "};"; ASSERT_EQUALS("class Machine {\n" "static const int STACK_ORDER = 10 ; static const int STACK_MAX = 1 << STACK_ORDER ; " "static const int STACK_GUARD = 2 ;\n" "} ;", tokenizeAndStringify(code)); } { // Ticket #9515 const char code[] = "void(a)(void) {\n" " static int b;\n" " if (b) {}\n" "}\n"; ASSERT_EQUALS("void ( a ) ( void ) {\n" "static int b ;\n" "if ( b ) { }\n" "}", tokenizeAndStringify(code)); } } void vardecl6() { // ticket #565 const char code1[] = "int z = x >> 16;"; const char res1[] = "int z ; z = x >> 16 ;"; ASSERT_EQUALS(res1, tokenizeAndStringify(code1)); } void vardecl7() { // ticket #603 const char code[] = "void f() {\n" " for (int c = 0; c < 0; ++c) {}\n" " int t;\n" " D(3 > t, \"T\");\n" "}"; const char res[] = "void f ( ) {\n" "for ( int c = 0 ; c < 0 ; ++ c ) { }\n" "int t ;\n" "D ( 3 > t , \"T\" ) ;\n" "}"; ASSERT_EQUALS(res, tokenizeAndStringify(code)); } void vardecl8() { // ticket #696 const char code[] = "char a[10]={'\\0'}, b[10]={'\\0'};"; const char res[] = "char a [ 10 ] = { '\\0' } ; char b [ 10 ] = { '\\0' } ;"; ASSERT_EQUALS(res, tokenizeAndStringify(code)); } void vardecl9() { const char code[] = "char a[2] = {'A', '\\0'}, b[2] = {'B', '\\0'};"; const char res[] = "char a [ 2 ] = { 'A' , '\\0' } ; char b [ 2 ] = { 'B' , '\\0' } ;"; ASSERT_EQUALS(res, tokenizeAndStringify(code)); } void vardecl10() { // ticket #732 const char code[] = "char a [ 2 ] = { '-' } ; memset ( a , '-' , sizeof ( a ) ) ;"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); } void vardecl11() { // ticket #1684 const char code[] = "char a[5][8], b[5][8];"; ASSERT_EQUALS("char a [ 5 ] [ 8 ] ; char b [ 5 ] [ 8 ] ;", tokenizeAndStringify(code)); } void vardecl12() { const char code[] = "struct A { public: B a, b, c, d; };"; ASSERT_EQUALS("struct A { public: B a ; B b ; B c ; B d ; } ;", tokenizeAndStringify(code)); } void vardecl13() { const char code[] = "void f() {\n" " int a = (x < y) ? 1 : 0;\n" "}"; ASSERT_EQUALS("void f ( ) {\nint a ; a = ( x < y ) ? 1 : 0 ;\n}", tokenizeAndStringify(code)); } void vardecl14() { const char code[] = "::std::tr1::shared_ptr pNum1, pNum2;\n"; ASSERT_EQUALS(":: std :: tr1 :: shared_ptr < int > pNum1 ; :: std :: tr1 :: shared_ptr < int > pNum2 ;", tokenizeAndStringify(code, false, Platform::Type::Native, "test.cpp", Standards::CPP03)); } void vardecl15() { const char code[] = "const char x[] = \"foo\", y[] = \"bar\";\n"; ASSERT_EQUALS("const char x [ 4 ] = \"foo\" ; const char y [ 4 ] = \"bar\" ;", tokenizeAndStringify(code)); } void vardecl16() { { const char code[] = "const a::b::g::h::l *x [] = foo(),y [][] = bar();\n"; ASSERT_EQUALS("const a :: b < c , d ( e ) , f > :: g :: h < i > :: l * x [ ] = foo ( ) ; " "const a :: b < c , d ( e ) , f > :: g :: h < i > :: l y [ ] [ ] = bar ( ) ;", tokenizeAndStringify(code)); } { const char code[] = "const ::b::g::h::l *x [] = foo(),y [][] = bar();\n"; ASSERT_EQUALS("const :: b < c , d ( e ) , f > :: g :: h < i > :: l * x [ ] = foo ( ) ; " "const :: b < c , d ( e ) , f > :: g :: h < i > :: l y [ ] [ ] = bar ( ) ;", tokenizeAndStringify(code)); } } void vardecl17() { const char code[] = "a < b > :: c :: d :: e < f > x = foo(), y = bar();\n"; ASSERT_EQUALS("a < b > :: c :: d :: e < f > x ; x = foo ( ) ; " "a < b > :: c :: d :: e < f > y ; y = bar ( ) ;", tokenizeAndStringify(code)); } void vardecl18() { const char code[] = "void f() {\n" " g((double)v1*v2, v3, v4);\n" "}\n"; ASSERT_EQUALS("void f ( ) {\n" "g ( ( double ) v1 * v2 , v3 , v4 ) ;\n" "}", tokenizeAndStringify(code)); } void vardecl19() { { const char code[] = "void func(in, r, m)\n" "int in;" "int r,m;" "{\n" "}\n"; ASSERT_EQUALS("void func (\n" "int in , int r , int m\n" ")\n" "{\n" "}", tokenizeAndStringify(code)); } { const char code[] = "void f(r,f)\n" "char *r;\n" "{\n" "}\n"; ASSERT_EQUALS("void f (\n" "char * r\n" ")\n" "\n" "{\n" "}", tokenizeAndStringify(code)); } { const char code[] = "void f(f)\n" "{\n" "}\n"; ASSERT_EQUALS("void f ( )\n" "{\n" "}", tokenizeAndStringify(code)); } { const char code[] = "void f(f,r)\n" "char *r;\n" "{\n" "}\n"; ASSERT_EQUALS("void f (\n" "char * r\n" ")\n" "\n" "{\n" "}", tokenizeAndStringify(code)); } { const char code[] = "void f(r,f,s)\n" "char *r;\n" "char *s;\n" "{\n" "}\n"; ASSERT_EQUALS("void f (\n" "char * r ,\n" "char * s\n" ")\n" "\n" "\n" "{\n" "}", tokenizeAndStringify(code)); } { const char code[] = "void f(r,s,t)\n" "char *r,*s,*t;\n" "{\n" "}\n"; ASSERT_EQUALS("void f (\n" "char * r , char * s , char * t\n" ")\n" "\n" "{\n" "}", tokenizeAndStringify(code)); } { const char code[] = "void f(a, b) register char *a, *b;\n" "{\n" "}\n"; ASSERT_EQUALS("void f ( char * a , char * b )\n" "{\n" "}", tokenizeAndStringify(code)); } } void vardecl20() { // #3700 const char code[] = "void a::b() const\n" "{\n" " register const int X = 0;\n" "}\n"; ASSERT_EQUALS("void a :: b ( ) const\n" "{\n" "const int X = 0 ;\n" "}", tokenizeAndStringify(code)); } void vardecl21() { // type in namespace // #4042 - a::b const *p = 0; const char code1[] = "void f() {\n" " a::b const *p = 0;\n" "}\n"; ASSERT_EQUALS("void f ( ) {\n" "const a :: b * p ; p = 0 ;\n" "}" , tokenizeAndStringify(code1)); // #4226 - ::a::b const *p = 0; const char code2[] = "void f() {\n" " ::a::b const *p = 0;\n" "}\n"; ASSERT_EQUALS("void f ( ) {\n" "const :: a :: b * p ; p = 0 ;\n" "}" , tokenizeAndStringify(code2)); } void vardecl22() { // #4211 - segmentation fault tokenizeAndStringify("A> >* p = 0;"); } void vardecl23() { // #4276 - segmentation fault ASSERT_THROW(tokenizeAndStringify("class a { protected : template < class int x = 1 ; public : int f ( ) ; }"), InternalError); } void vardecl24() { // #4187 - variable declaration within lambda function const char code1[] = "void f() {\n" " std::for_each(ints.begin(), ints.end(), [](int val)\n" " {\n" " int temp = 0;\n" " });\n" "}"; const char expected1[] = "void f ( ) {\n" "std :: for_each ( ints . begin ( ) , ints . end ( ) , [ ] ( int val )\n" "{\n" "int temp ; temp = 0 ;\n" "} ) ;\n" "}"; ASSERT_EQUALS(expected1, tokenizeAndStringify(code1)); const char code2[] = "void f(int j) {\n" " g( [](){int temp = 0;} , j );\n" "}"; const char expected2[] = "void f ( int j ) {\n" "g ( [ ] ( ) { int temp ; temp = 0 ; } , j ) ;\n" "}"; ASSERT_EQUALS(expected2, tokenizeAndStringify(code2)); } void vardecl25() { // #4799 - segmentation fault tokenizeAndStringify("void A::func(P g) const {}\n" "void A::a() {\n" " b = new d( [this]( const P & p) -> double { return this->func(p);} );\n" "}"); } void vardecl26() { // #5907 const char code[] = "extern int *new, obj, player;"; const char expected[] = "extern int * new ; extern int obj ; extern int player ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Type::Native, "test.c")); ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } void vardecl27() { // #7850 const char code[] = "extern int foo(char);\n" "void* class(char c) {\n" " if (foo(c))\n" " return 0;\n" " return 0;\n" "}"; tokenizeAndStringify(code, /*expand=*/ true, Platform::Type::Native, "test.c"); } void vardecl28() { const char code[] = "unsigned short f(void) {\n" " unsigned short const int x = 1;\n" " return x;\n" "}"; ASSERT_EQUALS("unsigned short f ( ) {\n" "const unsigned short x ; x = 1 ;\n" "return x ;\n" "}", tokenizeAndStringify(code, /*expand=*/ true, Platform::Type::Native, "test.c")); } void vardecl29() { // #9282 const char* code = "double f1() noexcept, f2(double) noexcept;"; ASSERT_EQUALS("double f1 ( ) noexcept ( true ) ; double f2 ( double ) noexcept ( true ) ;", tokenizeAndStringify(code)); code = "class C {\n" " double f1() const noexcept, f2 (double) const noexcept;\n" "};\n"; ASSERT_EQUALS("class C {\n" "double f1 ( ) const noexcept ( true ) ; double f2 ( double ) const noexcept ( true ) ;\n" "} ;", tokenizeAndStringify(code)); } void vardecl30() { const char code[] = "struct D {} const d;"; ASSERT_EQUALS("struct D { } ; struct D const d ;", tokenizeAndStringify(code, true, Platform::Type::Native, "test.cpp")); ASSERT_EQUALS("struct D { } ; struct D const d ;", tokenizeAndStringify(code, true, Platform::Type::Native, "test.c")); } void vardecl31() { const char code1[] = "void foo() { int (*fptr)() = 0; }"; ASSERT_EQUALS("void foo ( ) { int ( * fptr ) ( ) ; fptr = 0 ; }", tokenizeAndStringify(code1)); const char code2[] = "void foo() { int (*fptr)(int) = 0; }"; ASSERT_EQUALS("void foo ( ) { int ( * fptr ) ( int ) ; fptr = 0 ; }", tokenizeAndStringify(code2)); } void volatile_variables() { { const char code[] = "volatile int a=0;\n" "volatile int b=0;\n" "volatile int c=0;\n"; const std::string actual(tokenizeAndStringify(code)); ASSERT_EQUALS("volatile int a ; a = 0 ;\nvolatile int b ; b = 0 ;\nvolatile int c ; c = 0 ;", actual); } { const char code[] = "char *volatile s1, *volatile s2;\n"; // #11004 const std::string actual(tokenizeAndStringify(code)); ASSERT_EQUALS("char * volatile s1 ; char * volatile s2 ;", actual); } } void simplifyKeyword() { { const char code[] = "void f (int a [ static 5] );"; ASSERT_EQUALS("void f ( int a [ 5 ] ) ;", tokenizeAndStringify(code)); } { const char in4[] = "struct B final : A { void foo(); };"; const char out4[] = "struct B : A { void foo ( ) ; } ;"; ASSERT_EQUALS(out4, tokenizeAndStringify(in4)); const char in5[] = "struct ArrayItemsValidator final {\n" " SchemaError validate() const override {\n" " for (; pos < value.size(); ++pos) {\n" " }\n" " return none;\n" " }\n" "};\n"; const char out5[] = "struct ArrayItemsValidator {\n" "SchemaError validate ( ) const override {\n" "for ( ; pos < value . size ( ) ; ++ pos ) {\n" "}\n" "return none ;\n" "}\n" "} ;"; ASSERT_EQUALS(out5, tokenizeAndStringify(in5)); } { // Ticket #8679 const char code[] = "thread_local void *thread_local_var; " "__thread void *thread_local_var_2;"; ASSERT_EQUALS("static void * thread_local_var ; " "void * thread_local_var_2 ;", tokenizeAndStringify(code)); } ASSERT_EQUALS("class Fred { } ;", tokenizeAndStringify("class DLLEXPORT Fred final { };")); } void implicitIntConst() { ASSERT_EQUALS("const int x ;", tokenizeAndStringify("const x;", true, Platform::Type::Native, "test.c")); ASSERT_EQUALS("const int * x ;", tokenizeAndStringify("const *x;", true, Platform::Type::Native, "test.c")); ASSERT_EQUALS("const int * f ( ) ;", tokenizeAndStringify("const *f();", true, Platform::Type::Native, "test.c")); } void implicitIntExtern() { ASSERT_EQUALS("extern int x ;", tokenizeAndStringify("extern x;", true, Platform::Type::Native, "test.c")); ASSERT_EQUALS("extern int * x ;", tokenizeAndStringify("extern *x;", true, Platform::Type::Native, "test.c")); ASSERT_EQUALS("const int * f ( ) ;", tokenizeAndStringify("const *f();", true, Platform::Type::Native, "test.c")); } /** * tokenize "signed i" => "signed int i" */ void implicitIntSigned1() { { const char code1[] = "void foo ( signed int , float ) ;"; ASSERT_EQUALS(code1, tokenizeAndStringify(code1)); } { const char code1[] = "signed i ;"; const char code2[] = "signed int i ;"; ASSERT_EQUALS(code2, tokenizeAndStringify(code1)); } { const char code1[] = "signed int i ;"; ASSERT_EQUALS(code1, tokenizeAndStringify(code1)); } { const char code1[] = "int signed i ;"; const char code2[] = "signed int i ;"; ASSERT_EQUALS(code2, tokenizeAndStringify(code1)); } { const char code1[] = "void f() { for (signed i=0; i<10; i++) {} }"; const char code2[] = "void f ( ) { for ( signed int i = 0 ; i < 10 ; i ++ ) { } }"; ASSERT_EQUALS(code2, tokenizeAndStringify(code1)); } } /** * tokenize "unsigned i" => "unsigned int i" * tokenize "unsigned" => "unsigned int" */ void implicitIntUnsigned1() { // No changes.. { const char code[] = "void foo ( unsigned int , float ) ;"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); } // insert "int" after "unsigned".. { const char code1[] = "unsigned i ;"; const char code2[] = "unsigned int i ;"; ASSERT_EQUALS(code2, tokenizeAndStringify(code1)); } { const char code1[] = "int unsigned i ;"; const char code2[] = "unsigned int i ;"; ASSERT_EQUALS(code2, tokenizeAndStringify(code1)); } // insert "int" after "unsigned".. { const char code1[] = "void f() { for (unsigned i=0; i<10; i++) {} }"; const char code2[] = "void f ( ) { for ( unsigned int i = 0 ; i < 10 ; i ++ ) { } }"; ASSERT_EQUALS(code2, tokenizeAndStringify(code1)); } // "extern unsigned x;" => "extern int x;" { const char code1[] = "; extern unsigned x;"; const char code2[] = "; extern unsigned int x ;"; ASSERT_EQUALS(code2, tokenizeAndStringify(code1)); } } void implicitIntUnsigned2() { const char code[] = "i = (unsigned)j;"; const char expected[] = "i = ( unsigned int ) j ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } // simplify "unsigned" when using templates.. void implicitIntUnsigned3() { { const char code[] = "; foo();"; const char expected[] = "; foo < unsigned int > ( ) ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "; foo();"; const char expected[] = "; foo < unsigned int > ( ) ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } } void simplifyStdType() { // #4947, #4950, #4951 // unsigned long long { const char code[] = "long long unsigned int x;"; const char expected[] = "unsigned long long x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "long long int unsigned x;"; const char expected[] = "unsigned long long x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "unsigned long long int x;"; const char expected[] = "unsigned long long x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "unsigned int long long x;"; const char expected[] = "unsigned long long x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "int unsigned long long x;"; const char expected[] = "unsigned long long x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "int long long unsigned x;"; const char expected[] = "unsigned long long x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } // signed long long { const char code[] = "long long signed int x;"; const char expected[] = "signed long long x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "long long int signed x;"; const char expected[] = "signed long long x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "signed long long int x;"; const char expected[] = "signed long long x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "signed int long long x;"; const char expected[] = "signed long long x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "int signed long long x;"; const char expected[] = "signed long long x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "int long long signed x;"; const char expected[] = "signed long long x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } // unsigned short { const char code[] = "short unsigned int x;"; const char expected[] = "unsigned short x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "short int unsigned x;"; const char expected[] = "unsigned short x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "unsigned short int x;"; const char expected[] = "unsigned short x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "unsigned int short x;"; const char expected[] = "unsigned short x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "int unsigned short x;"; const char expected[] = "unsigned short x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "int short unsigned x;"; const char expected[] = "unsigned short x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } // signed short { const char code[] = "short signed int x;"; const char expected[] = "signed short x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "short int signed x;"; const char expected[] = "signed short x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "signed short int x;"; const char expected[] = "signed short x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "signed int short x;"; const char expected[] = "signed short x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "int signed short x;"; const char expected[] = "signed short x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "int short signed x;"; const char expected[] = "signed short x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "unsigned static short const int i;"; const char expected[] = "static const unsigned short i ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "float complex x;"; const char expected[] = "float complex x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { const char code[] = "float complex x;"; const char expected[] = "_Complex float x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Native, "test.c")); } { const char code[] = "complex float x;"; const char expected[] = "_Complex float x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Native, "test.c")); } { const char code[] = "complex long double x;"; const char expected[] = "_Complex long double x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Native, "test.c")); } { const char code[] = "long double complex x;"; const char expected[] = "_Complex long double x ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Native, "test.c")); } { const char code[] = "double complex;"; const char expected[] = "double complex ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Native, "test.c")); } } void createLinks() { { const char code[] = "class A{\n" " void f() {}\n" "};"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); // A body {} ASSERT_EQUALS(true, tok->linkAt(2) == tok->tokAt(9)); ASSERT_EQUALS(true, tok->linkAt(9) == tok->tokAt(2)); // f body {} ASSERT_EQUALS(true, tok->linkAt(7) == tok->tokAt(8)); ASSERT_EQUALS(true, tok->linkAt(8) == tok->tokAt(7)); // f () ASSERT_EQUALS(true, tok->linkAt(5) == tok->tokAt(6)); ASSERT_EQUALS(true, tok->linkAt(6) == tok->tokAt(5)); ASSERT_EQUALS("", errout.str()); } { const char code[] = "void f(){\n" " char a[10];\n" " char *b ; b = new char[a[0]];\n" "};"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); // a[10] ASSERT_EQUALS(true, tok->linkAt(7) == tok->tokAt(9)); ASSERT_EQUALS(true, tok->linkAt(9) == tok->tokAt(7)); // new char[] ASSERT_EQUALS(true, tok->linkAt(19) == tok->tokAt(24)); ASSERT_EQUALS(true, tok->linkAt(24) == tok->tokAt(19)); // a[0] ASSERT_EQUALS(true, tok->linkAt(21) == tok->tokAt(23)); ASSERT_EQUALS(true, tok->linkAt(23) == tok->tokAt(21)); ASSERT_EQUALS("", errout.str()); } { const char code[] = "void f(){\n" " foo(g());\n" "};"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); // foo( ASSERT_EQUALS(true, tok->linkAt(6) == tok->tokAt(10)); ASSERT_EQUALS(true, tok->linkAt(10) == tok->tokAt(6)); // g( ASSERT_EQUALS(true, tok->linkAt(8) == tok->tokAt(9)); ASSERT_EQUALS(true, tok->linkAt(9) == tok->tokAt(8)); ASSERT_EQUALS("", errout.str()); } { const char code[] = "bool foo(C a, bar>& f, int b) {\n" " return(af);\n" "}"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); // template< ASSERT_EQUALS(true, tok->tokAt(6) == tok->linkAt(4)); ASSERT_EQUALS(true, tok->tokAt(4) == tok->linkAt(6)); // bar< ASSERT_EQUALS(true, tok->tokAt(17) == tok->linkAt(10)); ASSERT_EQUALS(true, tok->tokAt(10) == tok->linkAt(17)); // x< ASSERT_EQUALS(true, tok->tokAt(16) == tok->linkAt(14)); ASSERT_EQUALS(true, tok->tokAt(14) == tok->linkAt(16)); // af ASSERT_EQUALS(true, nullptr == tok->linkAt(28)); ASSERT_EQUALS(true, nullptr == tok->linkAt(32)); ASSERT_EQUALS("", errout.str()); } { const char code[] = "void foo() {\n" " return static_cast(a);\n" "}"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); // static_cast< ASSERT_EQUALS(true, tok->tokAt(9) == tok->linkAt(7)); ASSERT_EQUALS(true, tok->tokAt(7) == tok->linkAt(9)); ASSERT_EQUALS("", errout.str()); } { const char code[] = "void foo() {\n" " nvwa<(x > y)> ERROR_nnn;\n" "}"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); // nvwa<(x > y)> ASSERT_EQUALS(true, tok->tokAt(12) == tok->linkAt(6)); ASSERT_EQUALS(true, tok->tokAt(6) == tok->linkAt(12)); ASSERT_EQUALS("", errout.str()); } { // #4860 const char code[] = "class A : public B {};"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); // B<..> ASSERT_EQUALS(true, tok->tokAt(5) == tok->linkAt(7)); ASSERT_EQUALS(true, tok->linkAt(5) == tok->tokAt(7)); ASSERT_EQUALS("", errout.str()); } { // #4860 const char code[] = "Bar>>>::set(1, 2, 3);"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->tokAt(1) == tok->linkAt(18)); ASSERT_EQUALS(true, tok->tokAt(3) == tok->linkAt(17)); ASSERT_EQUALS(true, tok->tokAt(7) == tok->linkAt(16)); ASSERT_EQUALS(true, tok->tokAt(11) == tok->linkAt(15)); ASSERT_EQUALS("", errout.str()); } { // #5627 const char code[] = "new Foo[10];"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->tokAt(2) == tok->linkAt(4)); ASSERT_EQUALS(true, tok->tokAt(4) == tok->linkAt(2)); ASSERT_EQUALS(true, tok->tokAt(5) == tok->linkAt(7)); ASSERT_EQUALS(true, tok->tokAt(7) == tok->linkAt(5)); ASSERT_EQUALS("", errout.str()); } { // #6242 const char code[] = "func = integral_;"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->tokAt(3) == tok->linkAt(9)); ASSERT_EQUALS(true, tok->linkAt(3) == tok->tokAt(9)); ASSERT_EQUALS("", errout.str()); } { // if (a < b || c > d) { } const char code[] = "{ if (a < b || c > d); }"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->linkAt(3) == nullptr); } { // bool f = a < b || c > d const char code[] = "bool f = a < b || c > d;"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->linkAt(4) == nullptr); } { // template const char code[] = "a < b || c > d;"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(5)); } { // if (a < ... > d) { } const char code[] = "{ if (a < b || c == 3 || d > e); }"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->linkAt(3) == nullptr); } { // template const char code[] = "a d;"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(7)); } { // template const char code[] = "a d;"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(7)); } { const char code[] = "template < f = b || c > struct S;"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(7)); ASSERT_EQUALS(true, tok->tokAt(1) == tok->linkAt(7)); } { const char code[] = "struct A : B {};"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->linkAt(4) == tok->tokAt(8)); ASSERT_EQUALS(true, tok->tokAt(4) == tok->linkAt(8)); } { const char code[] = "Data;"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(4)); ASSERT_EQUALS(true, tok->tokAt(1) == tok->linkAt(4)); } { // #6601 const char code[] = "template struct FuncType : FuncType { };"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = tokenizer.tokens(); ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(4)); // ASSERT_EQUALS(true, tok->linkAt(7) == tok->tokAt(14)); // ASSERT_EQUALS(true, tok->linkAt(9) == tok->tokAt(11)); // (&) ASSERT_EQUALS(true, tok->linkAt(12) == tok->tokAt(13)); // () ASSERT_EQUALS(true, tok->linkAt(17) == tok->tokAt(21)); // ASSERT_EQUALS(true, tok->linkAt(19) == tok->tokAt(20)); // () ASSERT_EQUALS(true, tok->linkAt(22) == tok->tokAt(23)); // {} } } void createLinks2() { { // #7158 const char code[] = "enum { value = boost::mpl::at_c };"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok = Token::findsimplematch(tokenizer.tokens(), "<"); ASSERT_EQUALS(true, tok->link() == tok->tokAt(4)); ASSERT_EQUALS(true, tok->linkAt(4) == tok); } { // #7865 const char code[] = "template \n" "struct CheckedDivOp< T, U, typename std::enable_if::value || std::is_floating_point::value>::type> {\n" "};\n"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok1 = Token::findsimplematch(tokenizer.tokens(), "struct")->tokAt(2); const Token *tok2 = Token::findsimplematch(tokenizer.tokens(), "{")->previous(); ASSERT_EQUALS(true, tok1->link() == tok2); ASSERT_EQUALS(true, tok2->link() == tok1); } { // #7975 const char code[] = "template X copy() {};\n"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok1 = Token::findsimplematch(tokenizer.tokens(), "< Y"); const Token *tok2 = Token::findsimplematch(tok1, "> copy"); ASSERT_EQUALS(true, tok1->link() == tok2); ASSERT_EQUALS(true, tok2->link() == tok1); } { // #8006 const char code[] = "C && a = b;"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok1 = tokenizer.tokens()->next(); const Token *tok2 = tok1->tokAt(2); ASSERT_EQUALS(true, tok1->link() == tok2); ASSERT_EQUALS(true, tok2->link() == tok1); } { // #8115 const char code[] = "void Test(C && c);"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok1 = Token::findsimplematch(tokenizer.tokens(), "<"); const Token *tok2 = tok1->tokAt(2); ASSERT_EQUALS(true, tok1->link() == tok2); ASSERT_EQUALS(true, tok2->link() == tok1); } { // #8654 const char code[] = "template struct A {}; " "template struct foo : A... {};"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *A = Token::findsimplematch(tokenizer.tokens(), "A <"); ASSERT_EQUALS(true, A->next()->link() == A->tokAt(3)); } { // #8851 const char code[] = "template::type>" "void basic_json() {}"; errout.str(""); Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); ASSERT_EQUALS(true, Token::simpleMatch(tokenizer.tokens()->next()->link(), "> void")); } { // #9094 - template usage or comparison? const char code[] = "a = f(x%x<--a==x>x);"; Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); ASSERT(nullptr == Token::findsimplematch(tokenizer.tokens(), "<")->link()); } { // #11319 const char code[] = "using std::same_as;\n" "template T>\n" "void f();"; Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); const Token *tok1 = Token::findsimplematch(tokenizer.tokens(), "template <"); const Token *tok2 = Token ::findsimplematch(tokenizer.tokens(), "same_as <"); ASSERT(tok1->next()->link() == tok1->tokAt(7)); ASSERT(tok2->next()->link() == tok2->tokAt(3)); } { // #9131 - template usage or comparison? const char code[] = "using std::list; list l;"; Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "<")->link()); } { const char code[] = "using std::set;\n" "void foo()\n" "{\n" " for (set::iterator i = sources.begin(); i != sources.end(); ++i) {}\n" "}"; Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "<")->link()); } { // #8890 const char code[] = "void f() {\n" " a<> b;\n" " b.a<>::c();\n" "}\n"; Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "> ::")->link()); } { // #9136 const char code[] = "template char * a;\n" "template struct c {\n" " void d() { a[0]; }\n" "};\n"; Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "> [")->link()); } { // #9057 const char code[] = "template struct a;\n" "template using c = typename a::d;\n" "template using f = c;\n" "template > struct g {};\n" "template using baz = g;\n"; Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "> ;")->link()); } { // #9141 const char code[] = "struct a {\n" " typedef int b;\n" " operator b();\n" "};\n" "template using c = a;\n" "template c e;\n" "auto f = -e<1> == 0;\n"; Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "> ==")->link()); } { // #9145 const char code[] = "template struct b {\n" " template constexpr void operator()(c &&) const;\n" "};\n" "template struct e { b f; };\n" "template using h = e;\n" "template h i;\n" "template \n" "template \n" "constexpr void b::operator()(c &&) const {\n" " i<3>.f([] {});\n" "}\n"; Tokenizer tokenizer(&settings0, this); std::istringstream istr(code); ASSERT(tokenizer.tokenize(istr, "test.cpp")); ASSERT(nullptr != Token::findsimplematch(tokenizer.tokens(), "> . f (")->link()); } { // #10491 const char code[] = "template