2008-12-18 22:28:57 +01:00
/*
2009-01-21 21:04:20 +01:00
* Cppcheck - A tool for static C / C + + code analysis
2021-03-21 20:58:32 +01:00
* Copyright ( C ) 2007 - 2021 Cppcheck team .
2008-12-18 22:28:57 +01:00
*
* 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
2009-09-27 17:08:31 +02:00
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
2008-12-18 22:28:57 +01:00
*/
2017-05-27 04:33:47 +02:00
# include "config.h"
# include "platform.h"
# include "preprocessor.h" // usually tests here should not use preprocessor...
# include "settings.h"
# include "standards.h"
2008-12-18 22:28:57 +01:00
# include "testsuite.h"
2009-10-25 12:49:06 +01:00
# include "token.h"
2017-05-27 04:33:47 +02:00
# include "tokenize.h"
# include "tokenlist.h"
# include <list>
# include <set>
2016-05-14 22:52:43 +02:00
# include <sstream>
2017-05-27 04:33:47 +02:00
# include <string>
struct InternalError ;
2014-09-24 13:23:44 +02:00
2011-10-13 20:53:06 +02:00
class TestTokenizer : public TestFixture {
2008-12-18 22:28:57 +01:00
public :
2021-08-07 20:51:18 +02:00
TestTokenizer ( ) : TestFixture ( " TestTokenizer " ) { }
2008-12-18 22:28:57 +01:00
private :
2015-10-07 18:33:57 +02:00
Settings settings0 ;
Settings settings1 ;
Settings settings2 ;
2014-10-19 07:34:40 +02:00
Settings settings_windows ;
2008-12-18 22:28:57 +01:00
2019-01-12 15:45:25 +01:00
void run ( ) OVERRIDE {
2014-10-19 07:34:40 +02:00
LOAD_LIB_2 ( settings_windows . library , " windows.cfg " ) ;
2020-11-22 16:43:36 +01:00
// If there are unused templates, keep those
settings0 . checkUnusedTemplates = true ;
settings1 . checkUnusedTemplates = true ;
settings2 . checkUnusedTemplates = true ;
settings_windows . checkUnusedTemplates = true ;
2009-11-12 18:53:26 +01:00
TEST_CASE ( tokenize1 ) ;
2009-11-22 09:06:39 +01:00
TEST_CASE ( tokenize2 ) ;
2010-01-29 19:34:43 +01:00
TEST_CASE ( tokenize4 ) ;
2010-04-04 08:01:05 +02:00
TEST_CASE ( tokenize5 ) ;
2010-08-27 22:58:21 +02:00
TEST_CASE ( tokenize7 ) ;
2010-08-28 13:32:43 +02:00
TEST_CASE ( tokenize8 ) ;
2010-08-29 13:54:26 +02:00
TEST_CASE ( tokenize9 ) ;
2010-09-04 11:49:56 +02:00
TEST_CASE ( tokenize11 ) ;
2010-12-26 15:07:14 +01:00
TEST_CASE ( tokenize13 ) ; // bailout if the code contains "@" - that is not handled well.
2010-12-27 08:09:05 +01:00
TEST_CASE ( tokenize14 ) ; // tokenize "0X10" => 16
2017-05-06 11:57:02 +02:00
TEST_CASE ( tokenizeHexWithSuffix ) ; // tokenize 0xFFFFFFul
2011-01-09 10:09:54 +01:00
TEST_CASE ( tokenize15 ) ; // tokenize ".123"
2011-04-29 15:19:22 +02:00
TEST_CASE ( tokenize17 ) ; // #2759
2011-07-15 19:37:39 +02:00
TEST_CASE ( tokenize18 ) ; // tokenize "(X&&Y)" into "( X && Y )" instead of "( X & & Y )"
2011-08-15 13:19:49 +02:00
TEST_CASE ( tokenize19 ) ; // #3006 (segmentation fault)
2011-12-18 07:37:20 +01:00
TEST_CASE ( tokenize21 ) ; // tokenize 0x0E-7
2011-12-18 13:33:23 +01:00
TEST_CASE ( tokenize22 ) ; // special marker $ from preprocessor
2012-09-27 06:35:36 +02:00
TEST_CASE ( tokenize25 ) ; // #4239 (segmentation fault)
2012-10-08 21:49:25 +02:00
TEST_CASE ( tokenize26 ) ; // #4245 (segmentation fault)
2013-02-19 21:56:13 +01:00
TEST_CASE ( tokenize27 ) ; // #4525 (segmentation fault)
2014-04-12 10:36:01 +02:00
TEST_CASE ( tokenize31 ) ; // #3503 (Wrong handling of member function taking function pointer as argument)
2014-06-16 10:58:41 +02:00
TEST_CASE ( tokenize32 ) ; // #5884 (fsanitize=undefined: left shift of negative value -10000 in lib/templatesimplifier.cpp:852:46)
2014-08-26 09:12:10 +02:00
TEST_CASE ( tokenize33 ) ; // #5780 Various crashes on valid template code
2017-04-30 08:59:47 +02:00
TEST_CASE ( tokenize34 ) ; // #8031
2018-01-26 22:06:07 +01:00
TEST_CASE ( tokenize35 ) ; // #8361
2018-04-21 11:30:07 +02:00
TEST_CASE ( tokenize36 ) ; // #8436
2018-05-12 10:20:33 +02:00
TEST_CASE ( tokenize37 ) ; // #8550
2020-01-25 10:18:37 +01:00
TEST_CASE ( tokenize38 ) ; // #9569
2020-08-26 18:39:33 +02:00
TEST_CASE ( tokenize39 ) ; // #9771
2009-11-12 20:04:11 +01:00
2017-04-06 08:50:35 +02:00
TEST_CASE ( validate ) ;
2018-01-24 18:06:11 +01:00
TEST_CASE ( objectiveC ) ; // Syntax error should be written for objective C/C++ code.
2012-10-12 17:08:21 +02:00
TEST_CASE ( syntax_case_default ) ;
2013-04-18 16:13:58 +02:00
2020-11-15 14:57:18 +01:00
TEST_CASE ( removePragma ) ;
2012-09-03 20:23:53 +02:00
TEST_CASE ( foreach ) ; // #3690
2018-04-09 11:42:38 +02:00
TEST_CASE ( ifconstexpr ) ;
2012-09-03 20:23:53 +02:00
2015-10-19 10:01:57 +02:00
TEST_CASE ( combineOperators ) ;
2012-11-28 07:09:56 +01:00
TEST_CASE ( concatenateNegativeNumber ) ;
2009-03-17 20:50:06 +01:00
2009-01-05 16:49:57 +01:00
TEST_CASE ( longtok ) ;
2008-12-18 22:28:57 +01:00
2020-11-22 16:43:36 +01:00
TEST_CASE ( simplifyHeadersAndUnusedTemplates1 ) ;
TEST_CASE ( simplifyHeadersAndUnusedTemplates2 ) ;
2019-04-07 08:37:04 +02:00
2018-12-04 16:52:41 +01:00
TEST_CASE ( simplifyAt ) ;
2009-01-05 16:49:57 +01:00
TEST_CASE ( inlineasm ) ;
2016-01-04 09:59:53 +01:00
TEST_CASE ( simplifyAsm2 ) ; // #4725 (writing asm() around "^{}")
2008-12-18 22:28:57 +01:00
2009-01-05 16:49:57 +01:00
TEST_CASE ( ifAddBraces1 ) ;
TEST_CASE ( ifAddBraces2 ) ;
TEST_CASE ( ifAddBraces3 ) ;
TEST_CASE ( ifAddBraces4 ) ;
2009-03-15 13:44:57 +01:00
TEST_CASE ( ifAddBraces5 ) ;
2009-06-22 22:54:11 +02:00
TEST_CASE ( ifAddBraces7 ) ;
2009-11-20 20:38:30 +01:00
TEST_CASE ( ifAddBraces9 ) ;
2010-02-20 11:43:53 +01:00
TEST_CASE ( ifAddBraces11 ) ;
2010-02-20 13:24:50 +01:00
TEST_CASE ( ifAddBraces12 ) ;
2010-06-26 17:15:44 +02:00
TEST_CASE ( ifAddBraces13 ) ;
2011-10-27 20:54:42 +02:00
TEST_CASE ( ifAddBraces15 ) ; // #2616 - unknown macro before if
2016-07-22 16:54:24 +02:00
TEST_CASE ( ifAddBraces16 ) ;
2012-01-26 22:25:19 +01:00
TEST_CASE ( ifAddBraces17 ) ; // '} else' should be in the same line
TEST_CASE ( ifAddBraces18 ) ; // #3424 - if if { } else else
2013-01-24 16:53:20 +01:00
TEST_CASE ( ifAddBraces19 ) ; // #3928 - if for if else
2013-09-05 06:38:07 +02:00
TEST_CASE ( ifAddBraces20 ) ; // #5012 - syntax error 'else }'
2021-06-02 07:00:37 +02:00
TEST_CASE ( ifAddBracesLabels ) ; // #5332 - if (x) label: {} ..
TEST_CASE ( switchAddBracesLabels ) ;
2008-12-22 10:20:46 +01:00
2009-06-20 13:20:51 +02:00
TEST_CASE ( whileAddBraces ) ;
2021-06-02 07:00:37 +02:00
TEST_CASE ( whileAddBracesLabels ) ;
2009-08-22 12:42:19 +02:00
TEST_CASE ( doWhileAddBraces ) ;
2021-06-02 07:00:37 +02:00
TEST_CASE ( doWhileAddBracesLabels ) ;
2009-06-20 13:20:51 +02:00
2013-10-14 21:05:54 +02:00
TEST_CASE ( forAddBraces1 ) ;
TEST_CASE ( forAddBraces2 ) ; // #5088
2021-06-02 07:00:37 +02:00
TEST_CASE ( forAddBracesLabels ) ;
2010-06-13 08:00:46 +02:00
2012-04-16 16:25:04 +02:00
TEST_CASE ( simplifyExternC ) ;
2014-05-13 16:28:28 +02:00
TEST_CASE ( simplifyKeyword ) ; // #5842 - remove C99 static keyword between []
2008-12-18 22:28:57 +01:00
2013-10-01 20:30:59 +02:00
TEST_CASE ( isZeroNumber ) ;
TEST_CASE ( isOneNumber ) ;
2013-10-03 15:41:12 +02:00
TEST_CASE ( isTwoNumber ) ;
2013-10-01 20:30:59 +02:00
2012-01-23 16:10:15 +01:00
TEST_CASE ( simplifyFunctionParameters ) ;
2012-04-22 17:28:27 +02:00
TEST_CASE ( simplifyFunctionParameters1 ) ; // #3721
2012-12-23 08:04:44 +01:00
TEST_CASE ( simplifyFunctionParameters2 ) ; // #4430
2012-12-27 17:15:38 +01:00
TEST_CASE ( simplifyFunctionParameters3 ) ; // #4436
2019-10-16 20:56:53 +02:00
TEST_CASE ( simplifyFunctionParameters4 ) ; // #9421
2018-02-04 09:48:37 +01:00
TEST_CASE ( simplifyFunctionParametersMultiTemplate ) ;
2012-01-23 16:10:15 +01:00
TEST_CASE ( simplifyFunctionParametersErrors ) ;
2009-01-25 20:39:05 +01:00
2021-05-02 09:05:12 +02:00
TEST_CASE ( simplifyFunctionTryCatch ) ;
2011-03-30 16:45:31 +02:00
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
2011-05-01 08:27:59 +02:00
TEST_CASE ( removeParentheses12 ) ; // Ticket #2760 ',(b)='
2011-11-07 23:40:06 +01:00
TEST_CASE ( removeParentheses13 ) ;
2011-11-08 22:48:14 +01:00
TEST_CASE ( removeParentheses14 ) ; // Ticket #3309
2012-09-06 16:16:29 +02:00
TEST_CASE ( removeParentheses15 ) ; // Ticket #4142
2013-02-16 16:07:05 +01:00
TEST_CASE ( removeParentheses16 ) ; // Ticket #4423 '*(x.y)='
2014-01-08 20:53:33 +01:00
TEST_CASE ( removeParentheses17 ) ; // Don't remove parentheses in 'a ? b : (c>0 ? d : e);'
2014-04-21 16:14:49 +02:00
TEST_CASE ( removeParentheses18 ) ; // 'float(*a)[2]' => 'float *a[2]'
2014-05-04 18:36:04 +02:00
TEST_CASE ( removeParentheses19 ) ; // ((typeof(x) *)0)
2014-05-11 08:22:28 +02:00
TEST_CASE ( removeParentheses20 ) ; // Ticket #5479: a<b<int>>(2);
2014-05-24 19:04:47 +02:00
TEST_CASE ( removeParentheses21 ) ; // Don't "simplify" casts
2014-06-28 09:36:51 +02:00
TEST_CASE ( removeParentheses22 ) ;
2014-09-05 00:31:58 +02:00
TEST_CASE ( removeParentheses23 ) ; // Ticket #6103 - Infinite loop upon valid input
2015-10-13 20:31:17 +02:00
TEST_CASE ( removeParentheses24 ) ; // Ticket #7040
2020-09-29 12:06:30 +02:00
TEST_CASE ( removeParentheses25 ) ; // daca@home - a=(b,c)
2021-03-11 08:16:25 +01:00
TEST_CASE ( removeParentheses26 ) ; // Ticket #8875 a[0](0)
2009-02-02 07:21:48 +01:00
2009-02-08 10:51:45 +01:00
TEST_CASE ( tokenize_double ) ;
2009-02-08 11:25:33 +01:00
TEST_CASE ( tokenize_strings ) ;
2011-12-09 20:47:51 +01:00
TEST_CASE ( simplifyMulAndParens ) ; // Ticket #2784 + #3184
2009-03-13 22:38:42 +01:00
2013-01-07 19:20:15 +01:00
TEST_CASE ( simplifyStructDecl ) ;
2009-03-18 20:32:05 +01:00
TEST_CASE ( vardecl1 ) ;
TEST_CASE ( vardecl2 ) ;
2009-06-14 14:57:47 +02:00
TEST_CASE ( vardecl3 ) ;
2009-06-14 19:32:34 +02:00
TEST_CASE ( vardecl4 ) ;
2015-10-15 10:31:08 +02:00
TEST_CASE ( vardecl5 ) ; // #7048
2009-10-02 16:28:30 +02:00
TEST_CASE ( vardec_static ) ;
2009-08-08 12:33:07 +02:00
TEST_CASE ( vardecl6 ) ;
2009-08-23 08:26:16 +02:00
TEST_CASE ( vardecl7 ) ;
2009-09-20 12:28:15 +02:00
TEST_CASE ( vardecl8 ) ;
2009-09-20 13:28:56 +02:00
TEST_CASE ( vardecl9 ) ;
2009-09-26 12:02:13 +02:00
TEST_CASE ( vardecl10 ) ;
2010-05-16 20:21:22 +02:00
TEST_CASE ( vardecl11 ) ;
2010-08-25 20:17:31 +02:00
TEST_CASE ( vardecl12 ) ;
2010-09-15 19:53:47 +02:00
TEST_CASE ( vardecl13 ) ;
2011-03-25 04:06:20 +01:00
TEST_CASE ( vardecl14 ) ;
2012-01-30 23:41:43 +01:00
TEST_CASE ( vardecl15 ) ;
TEST_CASE ( vardecl16 ) ;
TEST_CASE ( vardecl17 ) ;
2012-02-18 15:05:29 +01:00
TEST_CASE ( vardecl18 ) ;
2012-03-31 18:45:29 +02:00
TEST_CASE ( vardecl19 ) ;
2012-04-09 12:55:26 +02:00
TEST_CASE ( vardecl20 ) ; // #3700 - register const int H = 0;
2012-09-14 16:46:45 +02:00
TEST_CASE ( vardecl21 ) ; // #4042 - a::b const *p = 0;
2012-09-17 19:45:42 +02:00
TEST_CASE ( vardecl22 ) ; // #4211 - segmentation fault
2012-10-20 21:39:29 +02:00
TEST_CASE ( vardecl23 ) ; // #4276 - segmentation fault
2012-11-30 10:30:26 +01:00
TEST_CASE ( vardecl24 ) ; // #4187 - variable declaration within lambda function
2013-05-14 20:56:31 +02:00
TEST_CASE ( vardecl25 ) ; // #4799 - segmentation fault
2014-06-08 14:59:58 +02:00
TEST_CASE ( vardecl26 ) ; // #5907 - incorrect handling of extern declarations
2017-01-06 21:16:28 +01:00
TEST_CASE ( vardecl27 ) ; // #7850 - crash on valid C code
2021-06-06 08:13:40 +02:00
TEST_CASE ( vardecl28 ) ;
2010-11-13 15:45:33 +01:00
TEST_CASE ( vardecl_stl_1 ) ;
TEST_CASE ( vardecl_stl_2 ) ;
2012-04-05 08:53:10 +02:00
TEST_CASE ( vardecl_template_1 ) ;
TEST_CASE ( vardecl_template_2 ) ;
2010-09-03 08:10:29 +02:00
TEST_CASE ( vardecl_union ) ;
2011-05-07 14:23:14 +02:00
TEST_CASE ( vardecl_par ) ; // #2743 - set links if variable type contains parentheses
2015-03-06 17:30:20 +01:00
TEST_CASE ( vardecl_par2 ) ; // #3912 - set correct links
TEST_CASE ( vardecl_par3 ) ; // #6556 - Fred x1(a), x2(b);
2016-01-19 15:27:11 +01:00
TEST_CASE ( vardecl_class_ref ) ;
2009-04-20 20:38:05 +02:00
TEST_CASE ( volatile_variables ) ;
2009-05-27 20:49:29 +02:00
2009-06-06 10:40:48 +02:00
// unsigned i; => unsigned int i;
2021-07-07 13:34:55 +02:00
TEST_CASE ( implicitIntConst ) ;
TEST_CASE ( implicitIntExtern ) ;
TEST_CASE ( implicitIntSigned1 ) ;
TEST_CASE ( implicitIntUnsigned1 ) ;
TEST_CASE ( implicitIntUnsigned2 ) ;
TEST_CASE ( implicitIntUnsigned3 ) ; // template arguments
2010-03-19 19:34:26 +01:00
2013-08-12 06:23:01 +02:00
TEST_CASE ( simplifyStdType ) ; // #4947, #4950, #4951
2013-08-09 23:13:04 +02:00
2009-09-20 22:13:06 +02:00
TEST_CASE ( createLinks ) ;
2016-08-01 22:26:11 +02:00
TEST_CASE ( createLinks2 ) ;
2009-10-01 19:45:48 +02:00
2009-10-09 21:11:29 +02:00
TEST_CASE ( simplifyString ) ;
2009-11-12 22:49:39 +01:00
TEST_CASE ( simplifyConst ) ;
2009-12-06 23:09:56 +01:00
TEST_CASE ( switchCase ) ;
2010-01-20 21:19:06 +01:00
2011-10-16 08:09:57 +02:00
TEST_CASE ( simplifyPointerToStandardType ) ;
2021-04-18 12:32:31 +02:00
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
2010-01-31 09:33:57 +01:00
2010-02-03 20:01:56 +01:00
TEST_CASE ( removedeclspec ) ;
2010-05-27 18:15:42 +02:00
TEST_CASE ( removeattribute ) ;
2021-06-26 14:23:39 +02:00
TEST_CASE ( functionAttributeBefore1 ) ;
TEST_CASE ( functionAttributeBefore2 ) ;
2014-04-20 20:40:55 +02:00
TEST_CASE ( functionAttributeAfter ) ;
2021-05-01 07:33:55 +02:00
TEST_CASE ( functionAttributeListBefore ) ;
TEST_CASE ( functionAttributeListAfter ) ;
2015-10-19 20:03:33 +02:00
2020-11-29 16:07:56 +01:00
TEST_CASE ( splitTemplateRightAngleBrackets ) ;
2020-11-29 12:56:13 +01:00
2015-10-19 20:03:33 +02:00
TEST_CASE ( cpp03template1 ) ;
2010-09-05 08:16:19 +02:00
TEST_CASE ( cpp0xtemplate1 ) ;
TEST_CASE ( cpp0xtemplate2 ) ;
2011-02-12 16:51:59 +01:00
TEST_CASE ( cpp0xtemplate3 ) ;
2014-12-14 14:58:54 +01:00
TEST_CASE ( cpp0xtemplate4 ) ; // Ticket #6181: Mishandled C++11 syntax
2019-06-13 13:37:55 +02:00
TEST_CASE ( cpp0xtemplate5 ) ; // Ticket #9154 change >> to > >
2015-05-26 00:28:08 +02:00
TEST_CASE ( cpp14template ) ; // Ticket #6708
2010-02-20 18:13:09 +01:00
TEST_CASE ( arraySize ) ;
2010-02-21 09:47:41 +01:00
TEST_CASE ( labels ) ;
2010-04-14 19:04:16 +02:00
TEST_CASE ( simplifyInitVar ) ;
2013-10-31 17:20:00 +01:00
TEST_CASE ( simplifyInitVar2 ) ;
TEST_CASE ( simplifyInitVar3 ) ;
2010-08-15 11:54:28 +02:00
2010-08-18 22:42:04 +02:00
TEST_CASE ( bitfields1 ) ;
TEST_CASE ( bitfields2 ) ;
TEST_CASE ( bitfields3 ) ;
2010-08-21 16:34:41 +02:00
TEST_CASE ( bitfields4 ) ; // ticket #1956
2010-08-22 09:41:22 +02:00
TEST_CASE ( bitfields5 ) ; // ticket #1956
2011-02-21 00:22:49 +01:00
TEST_CASE ( bitfields6 ) ; // ticket #2595
2011-03-19 21:00:43 +01:00
TEST_CASE ( bitfields7 ) ; // ticket #1987
2011-03-22 01:17:14 +01:00
TEST_CASE ( bitfields8 ) ;
2011-04-05 04:18:12 +02:00
TEST_CASE ( bitfields9 ) ; // ticket #2706
2011-05-19 17:04:36 +02:00
TEST_CASE ( bitfields10 ) ;
2012-01-09 16:24:11 +01:00
TEST_CASE ( bitfields12 ) ; // ticket #3485 (segmentation fault)
2012-01-23 07:39:31 +01:00
TEST_CASE ( bitfields13 ) ; // ticket #3502 (segmentation fault)
2013-02-07 17:03:08 +01:00
TEST_CASE ( bitfields14 ) ; // ticket #4561 (segfault for 'class a { signals: };')
2016-10-04 15:57:43 +02:00
TEST_CASE ( bitfields15 ) ; // ticket #7747 (enum Foo {A,B}:4;)
2018-05-02 20:55:11 +02:00
TEST_CASE ( bitfields16 ) ; // Save bitfield bit count
2010-08-18 22:42:04 +02:00
2012-07-15 11:05:19 +02:00
TEST_CASE ( simplifyNamespaceStd ) ;
2011-09-23 01:59:56 +02:00
TEST_CASE ( microsoftMemory ) ;
2018-04-12 08:52:31 +02:00
TEST_CASE ( microsoftString ) ;
2010-08-31 21:40:51 +02:00
2010-09-01 18:10:12 +02:00
TEST_CASE ( borland ) ;
2020-02-21 19:04:21 +01:00
TEST_CASE ( simplifyQtSignalsSlots1 ) ;
TEST_CASE ( simplifyQtSignalsSlots2 ) ;
2010-12-02 17:41:49 +01:00
2013-04-18 16:13:58 +02:00
TEST_CASE ( simplifySQL ) ;
2010-09-09 17:43:09 +02:00
2014-03-16 18:51:05 +01:00
TEST_CASE ( simplifyCAlternativeTokens ) ;
2010-09-09 19:40:36 +02:00
2012-09-22 18:41:33 +02:00
// x = ({ 123; }); => { x = 123; }
2013-04-19 06:42:09 +02:00
TEST_CASE ( simplifyRoundCurlyParentheses ) ;
2012-09-22 18:41:33 +02:00
2011-02-28 20:29:34 +01:00
TEST_CASE ( simplifyOperatorName1 ) ;
TEST_CASE ( simplifyOperatorName2 ) ;
TEST_CASE ( simplifyOperatorName3 ) ;
TEST_CASE ( simplifyOperatorName4 ) ;
2011-03-29 02:02:06 +02:00
TEST_CASE ( simplifyOperatorName5 ) ;
2011-10-12 15:10:34 +02:00
TEST_CASE ( simplifyOperatorName6 ) ; // ticket #3194
2013-03-01 13:06:51 +01:00
TEST_CASE ( simplifyOperatorName7 ) ; // ticket #4619
2014-04-26 18:30:09 +02:00
TEST_CASE ( simplifyOperatorName8 ) ; // ticket #5706
2014-05-03 21:35:04 +02:00
TEST_CASE ( simplifyOperatorName9 ) ; // ticket #5709 - comma operator not properly tokenized
2018-09-09 21:11:45 +02:00
TEST_CASE ( simplifyOperatorName10 ) ; // #8746 - using a::operator=
2018-12-13 06:34:10 +01:00
TEST_CASE ( simplifyOperatorName11 ) ; // #8889
2019-04-29 15:17:37 +02:00
TEST_CASE ( simplifyOperatorName12 ) ; // #9110
2019-05-09 09:52:18 +02:00
TEST_CASE ( simplifyOperatorName13 ) ; // user defined literal
2019-06-05 10:15:22 +02:00
TEST_CASE ( simplifyOperatorName14 ) ; // std::complex operator "" if
2019-11-14 09:26:21 +01:00
TEST_CASE ( simplifyOperatorName15 ) ; // ticket #9468 syntaxError
2019-11-15 07:03:57 +01:00
TEST_CASE ( simplifyOperatorName16 ) ; // ticket #9472
TEST_CASE ( simplifyOperatorName17 ) ;
2019-11-16 08:03:13 +01:00
TEST_CASE ( simplifyOperatorName18 ) ; // global namespace
TEST_CASE ( simplifyOperatorName19 ) ;
TEST_CASE ( simplifyOperatorName20 ) ;
TEST_CASE ( simplifyOperatorName21 ) ;
TEST_CASE ( simplifyOperatorName22 ) ;
2019-11-18 06:38:53 +01:00
TEST_CASE ( simplifyOperatorName23 ) ;
2019-11-20 22:13:32 +01:00
TEST_CASE ( simplifyOperatorName24 ) ;
2019-11-23 17:42:24 +01:00
TEST_CASE ( simplifyOperatorName25 ) ;
2020-05-04 21:33:30 +02:00
TEST_CASE ( simplifyOperatorName26 ) ;
2020-06-25 22:06:34 +02:00
TEST_CASE ( simplifyOperatorName27 ) ;
2021-01-14 20:56:11 +01:00
TEST_CASE ( simplifyOperatorName28 ) ;
2021-04-22 19:15:22 +02:00
TEST_CASE ( simplifyOperatorName29 ) ; // spaceship operator
2021-11-18 20:25:21 +01:00
TEST_CASE ( simplifyOperatorName31 ) ; // #6342
2011-01-30 08:34:58 +01:00
2020-09-06 21:02:06 +02:00
TEST_CASE ( simplifyOverloadedOperators1 ) ;
2020-09-07 20:07:02 +02:00
TEST_CASE ( simplifyOverloadedOperators2 ) ; // (*this)(123)
2020-09-07 21:32:29 +02:00
TEST_CASE ( simplifyOverloadedOperators3 ) ; // #9881 - hang
2020-09-06 21:02:06 +02:00
2012-08-26 10:03:05 +02:00
TEST_CASE ( simplifyNullArray ) ;
2011-01-30 08:34:58 +01:00
// Some simple cleanups of unhandled macros in the global scope
TEST_CASE ( removeMacrosInGlobalScope ) ;
2012-11-29 08:44:12 +01:00
TEST_CASE ( removeMacroInVarDecl ) ;
2011-03-26 12:20:23 +01:00
2019-11-02 19:34:19 +01:00
TEST_CASE ( addSemicolonAfterUnknownMacro ) ;
2011-03-26 12:20:23 +01:00
// a = b = 0;
TEST_CASE ( multipleAssignment ) ;
2011-06-11 21:51:12 +02:00
2011-09-24 20:51:03 +02:00
TEST_CASE ( platformWin32A ) ;
TEST_CASE ( platformWin32W ) ;
2013-09-06 05:36:33 +02:00
TEST_CASE ( platformWin32AStringCat ) ; // ticket #5015
TEST_CASE ( platformWin32WStringCat ) ; // ticket #5015
2014-10-19 07:34:40 +02:00
TEST_CASE ( platformWinWithNamespace ) ;
2012-09-03 18:51:15 +02:00
2014-07-02 08:59:04 +02:00
TEST_CASE ( simplifyStaticConst ) ;
2012-12-15 20:21:09 +01:00
2018-02-16 22:25:51 +01:00
TEST_CASE ( simplifyCPPAttribute ) ;
2015-05-10 12:35:47 +02:00
2015-11-06 18:39:03 +01:00
TEST_CASE ( simplifyCaseRange ) ;
2020-06-07 13:49:04 +02:00
TEST_CASE ( simplifyEmptyNamespaces ) ;
2014-04-13 12:47:54 +02:00
TEST_CASE ( compileLimits ) ; // #5592 crash: gcc: testsuit: gcc.c-torture/compile/limits-declparen.c
2015-10-12 18:14:56 +02:00
TEST_CASE ( prepareTernaryOpForAST ) ;
2012-12-15 20:21:09 +01:00
// AST data
TEST_CASE ( astexpr ) ;
2017-06-04 12:16:49 +02:00
TEST_CASE ( astexpr2 ) ; // limit large expressions
2012-12-15 20:21:09 +01:00
TEST_CASE ( astpar ) ;
2014-06-04 18:08:51 +02:00
TEST_CASE ( astnewdelete ) ;
2012-12-15 20:21:09 +01:00
TEST_CASE ( astbrackets ) ;
TEST_CASE ( astunaryop ) ;
2012-12-16 08:41:04 +01:00
TEST_CASE ( astfunction ) ;
TEST_CASE ( asttemplate ) ;
2014-05-24 11:28:43 +02:00
TEST_CASE ( astcast ) ;
2014-05-25 19:48:31 +02:00
TEST_CASE ( astlambda ) ;
2017-06-08 15:32:35 +02:00
TEST_CASE ( astcase ) ;
2019-12-06 04:19:46 +01:00
TEST_CASE ( astrefqualifier ) ;
2019-05-12 17:24:42 +02:00
TEST_CASE ( astvardecl ) ;
2020-05-18 19:31:13 +02:00
TEST_CASE ( astnewscoped ) ;
2014-04-26 18:31:56 +02:00
TEST_CASE ( startOfExecutableScope ) ;
2015-01-17 07:42:49 +01:00
TEST_CASE ( removeMacroInClassDef ) ; // #6058
2015-02-22 13:38:06 +01:00
TEST_CASE ( sizeofAddParentheses ) ;
2016-07-26 12:15:55 +02:00
2020-02-22 11:57:09 +01:00
TEST_CASE ( reportUnknownMacros ) ;
2020-02-19 21:11:54 +01:00
2016-07-26 12:15:55 +02:00
// Make sure the Tokenizer::findGarbageCode() does not have false positives
// The TestGarbage ensures that there are true positives
TEST_CASE ( findGarbageCode ) ;
2018-10-28 17:16:31 +01:00
TEST_CASE ( checkEnableIf ) ;
2019-05-19 10:05:34 +02:00
TEST_CASE ( checkTemplates ) ;
2019-06-10 08:22:48 +02:00
TEST_CASE ( checkNamespaces ) ;
2019-07-05 12:26:01 +02:00
TEST_CASE ( checkLambdas ) ;
2019-12-01 14:53:03 +01:00
TEST_CASE ( checkIfCppCast ) ;
2019-12-06 04:19:46 +01:00
TEST_CASE ( checkRefQualifiers ) ;
2019-12-07 21:16:25 +01:00
TEST_CASE ( checkConditionBlock ) ;
2021-09-25 11:55:49 +02:00
TEST_CASE ( checkUnknownCircularVar ) ;
2017-04-07 19:19:10 +02:00
2019-03-22 01:56:09 +01:00
// #9052
TEST_CASE ( noCrash1 ) ;
2019-06-10 08:24:09 +02:00
TEST_CASE ( noCrash2 ) ;
2020-09-14 18:44:50 +02:00
TEST_CASE ( noCrash3 ) ;
2022-01-01 00:14:36 +01:00
TEST_CASE ( noCrash4 ) ;
2020-09-14 18:44:50 +02:00
2017-04-07 19:19:10 +02:00
// --check-config
TEST_CASE ( checkConfiguration ) ;
2019-01-31 16:53:51 +01:00
TEST_CASE ( unknownType ) ; // #8952
2019-07-16 20:32:46 +02:00
TEST_CASE ( unknownMacroBeforeReturn ) ;
2020-02-16 16:46:30 +01:00
TEST_CASE ( cppcast ) ;
2020-11-11 09:50:51 +01:00
TEST_CASE ( checkHeader1 ) ;
2020-11-28 21:55:28 +01:00
TEST_CASE ( removeExtraTemplateKeywords ) ;
2021-04-15 20:26:53 +02:00
2021-04-26 11:43:49 +02:00
TEST_CASE ( removeAlignas1 ) ;
TEST_CASE ( removeAlignas2 ) ; // Do not remove alignof in the same way
2021-04-18 19:42:22 +02:00
TEST_CASE ( simplifyCoroutines ) ;
2021-04-22 19:15:22 +02:00
TEST_CASE ( simplifySpaceshipOperator ) ;
2021-04-25 14:37:27 +02:00
TEST_CASE ( simplifyIfSwitchForInit1 ) ;
TEST_CASE ( simplifyIfSwitchForInit2 ) ;
TEST_CASE ( simplifyIfSwitchForInit3 ) ;
TEST_CASE ( simplifyIfSwitchForInit4 ) ;
2021-12-15 19:34:18 +01:00
TEST_CASE ( simplifyIfSwitchForInit5 ) ;
2008-12-18 22:28:57 +01:00
}
2021-11-29 07:34:39 +01:00
# define tokenizeAndStringify(...) tokenizeAndStringify_(__FILE__, __LINE__, __VA_ARGS__)
std : : string tokenizeAndStringify_ ( const char * file , int linenr , const char code [ ] , bool expand = true , Settings : : PlatformType platform = Settings : : Native , const char * filename = " test.cpp " , bool cpp11 = true ) {
2010-11-07 11:07:56 +01:00
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
settings1 . debugwarnings = true ;
settings1 . platform ( platform ) ;
settings1 . standards . cpp = cpp11 ? Standards : : CPP11 : Standards : : CPP03 ;
2010-12-01 18:00:55 +01:00
// tokenize..
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings1 , this ) ;
2009-01-18 09:52:20 +01:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT_LOC ( tokenizer . tokenize ( istr , filename ) , file , linenr ) ;
2009-01-18 09:52:20 +01:00
2014-01-17 18:07:05 +01:00
// filter out ValueFlow messages..
const std : : string debugwarnings = errout . str ( ) ;
errout . str ( " " ) ;
2019-09-25 15:25:19 +02:00
std : : istringstream istr2 ( debugwarnings ) ;
2014-01-17 18:07:05 +01:00
std : : string line ;
while ( std : : getline ( istr2 , line ) ) {
2017-10-05 23:03:13 +02:00
if ( line . find ( " valueflow.cpp " ) = = std : : string : : npos )
2014-01-17 18:07:05 +01:00
errout < < line < < " \n " ;
}
2014-05-20 21:55:08 +02:00
if ( tokenizer . tokens ( ) )
2019-06-30 21:39:22 +02:00
return tokenizer . tokens ( ) - > stringifyList ( false , expand , false , true , false , nullptr , nullptr ) ;
2014-05-20 21:55:08 +02:00
else
return " " ;
2009-01-18 09:52:20 +01:00
}
2021-11-29 07:34:39 +01:00
# define tokenizeAndStringifyWindows(...) tokenizeAndStringifyWindows_(__FILE__, __LINE__, __VA_ARGS__)
std : : string tokenizeAndStringifyWindows_ ( const char * file , int linenr , const char code [ ] , bool expand = true , Settings : : PlatformType platform = Settings : : Native , const char * filename = " test.cpp " , bool cpp11 = true ) {
2014-10-19 07:34:40 +02:00
errout . str ( " " ) ;
settings_windows . debugwarnings = true ;
settings_windows . platform ( platform ) ;
settings_windows . standards . cpp = cpp11 ? Standards : : CPP11 : Standards : : CPP03 ;
// tokenize..
Tokenizer tokenizer ( & settings_windows , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT_LOC ( tokenizer . tokenize ( istr , filename ) , file , linenr ) ;
2014-10-19 07:34:40 +02:00
// filter out ValueFlow messages..
const std : : string debugwarnings = errout . str ( ) ;
errout . str ( " " ) ;
2019-09-25 15:25:19 +02:00
std : : istringstream istr2 ( debugwarnings ) ;
2014-10-19 07:34:40 +02:00
std : : string line ;
while ( std : : getline ( istr2 , line ) ) {
2017-10-05 23:03:13 +02:00
if ( line . find ( " valueflow.cpp " ) = = std : : string : : npos )
2014-10-19 07:34:40 +02:00
errout < < line < < " \n " ;
}
if ( tokenizer . tokens ( ) )
2019-06-30 21:39:22 +02:00
return tokenizer . tokens ( ) - > stringifyList ( false , expand , false , true , false , nullptr , nullptr ) ;
2014-10-19 07:34:40 +02:00
else
return " " ;
}
2021-11-29 07:34:39 +01:00
std : : string tokenizeAndStringify_ ( const char * file , int line , const char code [ ] , const Settings & settings , const char filename [ ] = " test.cpp " ) {
2019-04-07 08:37:04 +02:00
errout . str ( " " ) ;
// tokenize..
Tokenizer tokenizer ( & settings , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT_LOC ( tokenizer . tokenize ( istr , filename ) , file , line ) ;
2019-04-07 08:37:04 +02:00
if ( ! tokenizer . tokens ( ) )
return " " ;
2019-06-30 21:39:22 +02:00
return tokenizer . tokens ( ) - > stringifyList ( false , true , false , true , false , nullptr , nullptr ) ;
2019-04-07 08:37:04 +02:00
}
2021-11-29 07:34:39 +01:00
# define tokenizeDebugListing(...) tokenizeDebugListing_(__FILE__, __LINE__, __VA_ARGS__)
std : : string tokenizeDebugListing_ ( const char * file , int line , const char code [ ] , const char filename [ ] = " test.cpp " ) {
2015-10-07 18:33:57 +02:00
errout . str ( " " ) ;
settings2 . standards . c = Standards : : C89 ;
settings2 . standards . cpp = Standards : : CPP03 ;
Tokenizer tokenizer ( & settings2 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT_LOC ( tokenizer . tokenize ( istr , filename ) , file , line ) ;
2015-10-07 18:33:57 +02:00
// result..
2016-07-18 10:52:38 +02:00
return tokenizer . tokens ( ) - > stringifyList ( true , true , true , true , false ) ;
2015-10-07 18:33:57 +02:00
}
2014-11-20 14:20:09 +01:00
void tokenize1 ( ) {
2014-04-02 13:56:34 +02:00
const char code [ ] = " void f ( ) \n "
" { if ( p . y ( ) > yof ) { } } " ;
ASSERT_EQUALS ( code , tokenizeAndStringify ( code ) ) ;
2009-11-12 18:53:26 +01:00
}
2014-11-20 14:20:09 +01:00
void tokenize2 ( ) {
2014-04-02 13:56:34 +02:00
const char code [ ] = " { sizeof a, sizeof b } " ;
ASSERT_EQUALS ( " { sizeof ( a ) , sizeof ( b ) } " , tokenizeAndStringify ( code ) ) ;
2009-11-22 09:06:39 +01:00
}
2014-11-20 14:20:09 +01:00
void tokenize4 ( ) {
2014-04-02 13:56:34 +02:00
const char code [ ] = " class foo \n "
" { \n "
" public: \n "
" const int i; \n "
" } " ;
2010-01-29 19:34:43 +01:00
ASSERT_EQUALS ( " class foo \n "
" { \n "
" public: \n "
" const int i ; \n "
2014-04-02 13:56:34 +02:00
" } " , tokenizeAndStringify ( code ) ) ;
2010-01-29 19:34:43 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void tokenize5 ( ) {
2010-04-04 08:01:05 +02:00
// Tokenize values
ASSERT_EQUALS ( " ; + 1E3 ; " , tokenizeAndStringify ( " ; +1E3 ; " ) ) ;
ASSERT_EQUALS ( " ; 1E-2 ; " , tokenizeAndStringify ( " ; 1E-2 ; " ) ) ;
}
2014-11-20 14:20:09 +01:00
void tokenize7 ( ) {
2014-04-02 13:56:34 +02:00
const char code [ ] = " void f() { \n "
" int x1 = 1; \n "
" int x2(x1); \n "
" } \n " ;
2010-08-27 22:58:21 +02:00
ASSERT_EQUALS ( " void f ( ) { \n int x1 ; x1 = 1 ; \n int x2 ; x2 = x1 ; \n } " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( code ) ) ;
2010-08-27 22:58:21 +02:00
}
2014-11-20 14:20:09 +01:00
void tokenize8 ( ) {
2014-04-02 13:56:34 +02:00
const char code [ ] = " void f() { \n "
" int x1(g()); \n "
" int x2(x1); \n "
" } \n " ;
2016-07-18 10:52:38 +02:00
ASSERT_EQUALS ( " 1: void f ( ) { \n "
2010-08-28 13:32:43 +02:00
" 2: int x1@1 ; x1@1 = g ( ) ; \n "
" 3: int x2@2 ; x2@2 = x1@1 ; \n "
" 4: } \n " ,
2021-04-06 21:21:53 +02:00
tokenizeDebugListing ( code ) ) ;
2010-08-28 13:32:43 +02:00
}
2014-11-20 14:20:09 +01:00
void tokenize9 ( ) {
2010-08-29 13:54:26 +02:00
const char code [ ] = " typedef void (*fp)(); \n "
" typedef fp (*fpp)(); \n "
" void f() { \n "
" fpp x = (fpp)f(); \n "
" } " ;
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( code ) ;
2010-08-29 13:54:26 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void tokenize11 ( ) {
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " X * sizeof ( Y ( ) ) ; " , tokenizeAndStringify ( " X * sizeof(Y()); " ) ) ;
2010-09-04 11:49:56 +02:00
}
2010-12-26 15:07:14 +01:00
// bailout if there is "@" - it is not handled well
2014-11-20 14:20:09 +01:00
void tokenize13 ( ) {
2010-12-26 15:07:14 +01:00
const char code [ ] = " @implementation \n "
" -(Foo *)foo: (Bar *)bar \n "
" { } \n "
" @end \n " ;
2015-08-01 07:39:56 +02:00
ASSERT_THROW ( tokenizeAndStringify ( code ) , InternalError ) ;
2010-12-26 15:07:14 +01:00
}
2010-12-27 08:09:05 +01:00
// Ticket #2361: 0X10 => 16
2014-11-20 14:20:09 +01:00
void tokenize14 ( ) {
2020-02-19 07:51:39 +01:00
ASSERT_EQUALS ( " ; 0x10 ; " , tokenizeAndStringify ( " ;0x10; " ) ) ;
ASSERT_EQUALS ( " ; 0X10 ; " , tokenizeAndStringify ( " ;0X10; " ) ) ;
ASSERT_EQUALS ( " ; 0444 ; " , tokenizeAndStringify ( " ;0444; " ) ) ;
2010-12-27 08:09:05 +01:00
}
2011-01-09 18:39:59 +01:00
2017-05-06 11:57:02 +02:00
// Ticket #8050
void tokenizeHexWithSuffix ( ) {
2020-02-19 07:51:39 +01:00
ASSERT_EQUALS ( " ; 0xFFFFFF ; " , tokenizeAndStringify ( " ;0xFFFFFF; " ) ) ;
ASSERT_EQUALS ( " ; 0xFFFFFFu ; " , tokenizeAndStringify ( " ;0xFFFFFFu; " ) ) ;
ASSERT_EQUALS ( " ; 0xFFFFFFul ; " , tokenizeAndStringify ( " ;0xFFFFFFul; " ) ) ;
2017-05-06 11:57:02 +02:00
// Number of digits decides about internal representation...
2020-02-19 07:51:39 +01:00
ASSERT_EQUALS ( " ; 0xFFFFFFFF ; " , tokenizeAndStringify ( " ;0xFFFFFFFF; " ) ) ;
ASSERT_EQUALS ( " ; 0xFFFFFFFFu ; " , tokenizeAndStringify ( " ;0xFFFFFFFFu; " ) ) ;
ASSERT_EQUALS ( " ; 0xFFFFFFFFul ; " , tokenizeAndStringify ( " ;0xFFFFFFFFul; " ) ) ;
2017-05-06 11:57:02 +02:00
}
2017-05-05 14:47:58 +02:00
2011-01-09 10:09:54 +01:00
// Ticket #2429: 0.125
2014-11-20 14:20:09 +01:00
void tokenize15 ( ) {
2016-11-20 14:15:51 +01:00
ASSERT_EQUALS ( " 0.125 ; " , tokenizeAndStringify ( " .125; " ) ) ;
ASSERT_EQUALS ( " 005.125 ; " , tokenizeAndStringify ( " 005.125; " ) ) ; // Don't confuse with octal values
2011-03-06 09:33:46 +01:00
}
2014-11-20 14:20:09 +01:00
void tokenize17 ( ) { // #2759
2011-04-29 15:19:22 +02:00
ASSERT_EQUALS ( " class B : private :: A { } ; " , tokenizeAndStringify ( " class B : private ::A { }; " ) ) ;
}
2014-11-20 14:20:09 +01:00
void tokenize18 ( ) { // tokenize "(X&&Y)" into "( X && Y )" instead of "( X & & Y )"
2016-11-20 14:15:51 +01:00
ASSERT_EQUALS ( " ( X && Y ) ; " , tokenizeAndStringify ( " (X&&Y); " ) ) ;
2011-07-15 19:37:39 +02:00
}
2014-11-20 14:20:09 +01:00
void tokenize19 ( ) {
2012-01-15 14:33:53 +01:00
// #3006 - added hasComplicatedSyntaxErrorsInTemplates to avoid segmentation fault
2014-03-27 13:15:21 +01:00
ASSERT_THROW ( tokenizeAndStringify ( " x < () < " ) , InternalError ) ;
2012-01-15 19:47:51 +01:00
2012-01-15 14:33:53 +01:00
// #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();) {} } " ) ) ;
2014-10-15 21:33:07 +02:00
// #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 "
" }; " ) ) ;
2011-08-15 13:19:49 +02:00
}
2014-11-20 14:20:09 +01:00
void tokenize21 ( ) { // tokenize 0x0E-7
2020-02-19 07:51:39 +01:00
ASSERT_EQUALS ( " 0x0E - 7 ; " , tokenizeAndStringify ( " 0x0E-7; " ) ) ;
2011-12-18 07:37:20 +01:00
}
2014-11-20 14:20:09 +01:00
void tokenize22 ( ) { // tokenize special marker $ from preprocessor
2017-05-18 21:52:31 +02:00
ASSERT_EQUALS ( " a$b " , tokenizeAndStringify ( " a$b " ) ) ;
2014-01-03 18:53:37 +01:00
ASSERT_EQUALS ( " a $b \n c " , tokenizeAndStringify ( " a $b \n c " ) ) ;
ASSERT_EQUALS ( " a = $0 ; " , tokenizeAndStringify ( " a = $0; " ) ) ;
2017-05-18 21:52:31 +02:00
ASSERT_EQUALS ( " a$ ++ ; " , tokenizeAndStringify ( " a$++; " ) ) ;
2014-01-03 18:53:37 +01:00
ASSERT_EQUALS ( " $if ( ! p ) " , tokenizeAndStringify ( " $if(!p) " ) ) ;
2011-12-18 13:33:23 +01:00
}
2012-09-27 06:35:36 +02:00
// #4239 - segfault for "f ( struct { int typedef T x ; } ) { }"
2014-11-20 14:20:09 +01:00
void tokenize25 ( ) {
2017-01-06 11:53:17 +01:00
ASSERT_THROW ( tokenizeAndStringify ( " f ( struct { int typedef T x ; } ) { } " ) , InternalError ) ;
2012-09-27 06:35:36 +02:00
}
2012-10-08 21:50:21 +02:00
2012-10-08 21:49:25 +02:00
// #4245 - segfault
2014-11-20 14:20:09 +01:00
void tokenize26 ( ) {
2017-12-29 22:47:07 +01:00
ASSERT_THROW ( tokenizeAndStringify ( " class x { protected : template < int y = } ; " ) , InternalError ) ; // Garbage code
2012-10-08 21:49:25 +02:00
}
2012-09-27 06:35:36 +02:00
2014-11-20 14:20:09 +01:00
void tokenize27 ( ) {
2014-03-19 16:47:11 +01:00
// #4525 - segfault
2013-02-19 21:56:13 +01:00
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; "
2021-08-07 20:51:18 +02:00
) ;
2014-03-19 16:47:11 +01:00
// 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)); " ) ;
2013-02-19 21:56:13 +01:00
}
2014-04-12 10:36:01 +02:00
// #3503 - don't "simplify" SetFunction member function to a variable
2014-11-20 14:20:09 +01:00
void tokenize31 ( ) {
2014-04-12 10:36:01 +02:00
ASSERT_EQUALS ( " struct TTestClass { TTestClass ( ) { } \n "
2020-04-10 11:53:32 +02:00
" void SetFunction ( Other ( * m_f ) ( ) ) { } \n "
2014-04-12 10:36:01 +02:00
" } ; " ,
tokenizeAndStringify ( " struct TTestClass { TTestClass() { } \n "
" void SetFunction(Other(*m_f)()) { } \n "
" }; " ) ) ;
ASSERT_EQUALS ( " struct TTestClass { TTestClass ( ) { } \n "
2020-04-10 11:53:32 +02:00
" void SetFunction ( Other ( * m_f ) ( ) ) ; \n "
2014-04-12 10:36:01 +02:00
" } ; " ,
tokenizeAndStringify ( " struct TTestClass { TTestClass() { } \n "
" void SetFunction(Other(*m_f)()); \n "
" }; " ) ) ;
}
2014-06-16 10:58:41 +02:00
// #5884 - Avoid left shift of negative integer value.
2014-11-20 14:20:09 +01:00
void tokenize32 ( ) {
2014-06-16 10:58:41 +02:00
// Do not simplify negative integer left shifts.
const char * code = " void f ( ) { int max_x ; max_x = -10000 << 16 ; } " ;
ASSERT_EQUALS ( code , tokenizeAndStringify ( code ) ) ;
}
2014-08-26 15:21:19 +02:00
// #5780 Various crashes on valid template code in Tokenizer::setVarId()
2014-11-20 14:20:09 +01:00
void tokenize33 ( ) {
2014-08-26 09:12:10 +02:00
const char * code = " template<typename T, typename A = Alloc<T>> struct vector {}; \n "
2014-08-26 10:40:00 +02:00
" void z() { \n "
" vector<int> VI; \n "
" } \n " ;
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( code ) ;
2014-08-26 09:12:10 +02:00
}
2017-04-30 08:59:47 +02:00
void tokenize34 ( ) { // #8031
{
2019-01-06 17:15:57 +01:00
const char code [ ] = " struct Container { \n "
" Container(); \n "
2017-04-30 08:59:47 +02:00
" int* mElements; \n "
" }; \n "
2019-01-06 17:15:57 +01:00
" Container::Container() : mElements(nullptr) {} \n "
" Container intContainer; " ;
2021-08-07 20:51:18 +02:00
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 " ;
2020-05-20 18:52:46 +02:00
ASSERT_EQUALS ( exp , tokenizeDebugListing ( code ) ) ;
2017-04-30 08:59:47 +02:00
}
{
2019-01-06 17:15:57 +01:00
const char code [ ] = " template<class T> struct Container { \n "
" Container(); \n "
2017-04-30 08:59:47 +02:00
" int* mElements; \n "
" }; \n "
2019-01-06 17:15:57 +01:00
" template <class T> Container<T>::Container() : mElements(nullptr) {} \n "
" Container<int> intContainer; " ;
2021-08-07 20:51:18 +02:00
const char exp [ ] = " 1: struct Container<int> ; \n "
" 2: \n "
" | \n "
" 5: \n "
" 6: Container<int> intContainer@1 ; \n "
" 1: struct Container<int> { \n "
" 2: Container<int> ( ) ; \n "
" 3: int * mElements@2 ; \n "
" 4: } ; \n "
" 5: Container<int> :: Container<int> ( ) : mElements@2 ( nullptr ) { } \n " ;
2020-05-20 18:52:46 +02:00
ASSERT_EQUALS ( exp , tokenizeDebugListing ( code ) ) ;
2017-04-30 08:59:47 +02:00
}
}
2018-01-26 22:06:07 +01:00
void tokenize35 ( ) { // #8361
tokenizeAndStringify ( " typedef int CRCWord; "
" template<typename T> ::CRCWord const Compute(T const t) { return 0; } " ) ;
}
2018-04-21 11:30:07 +02:00
void tokenize36 ( ) { // #8436
const char code [ ] = " int foo ( int i ) { return i ? * new int { 5 } : int { i ? 0 : 1 } ; } " ;
ASSERT_EQUALS ( code , tokenizeAndStringify ( code ) ) ;
}
2018-05-12 10:20:33 +02:00
void tokenize37 ( ) { // #8550
const char codeC [ ] = " class name { public: static void init ( ) {} } ; "
2018-05-14 10:15:50 +02:00
" typedef class name N; "
" void foo ( ) { return N :: init ( ) ; } " ;
2021-08-07 20:51:18 +02:00
const char expC [ ] = " class name { public: static void init ( ) { } } ; "
" void foo ( ) { return name :: init ( ) ; } " ;
2018-05-12 10:20:33 +02:00
ASSERT_EQUALS ( expC , tokenizeAndStringify ( codeC ) ) ;
const char codeS [ ] = " class name { public: static void init ( ) {} } ; "
2018-05-14 10:15:50 +02:00
" typedef struct name N; "
" void foo ( ) { return N :: init ( ) ; } " ;
2021-08-07 20:51:18 +02:00
const char expS [ ] = " class name { public: static void init ( ) { } } ; "
" void foo ( ) { return name :: init ( ) ; } " ;
2018-05-12 10:20:33 +02:00
ASSERT_EQUALS ( expS , tokenizeAndStringify ( codeS ) ) ;
}
2020-01-25 10:18:37 +01:00
void tokenize38 ( ) { // #9569
const char code [ ] = " using Binary = std::vector<char>; enum Type { Binary }; " ;
const char exp [ ] = " enum Type { Binary } ; " ;
ASSERT_EQUALS ( exp , tokenizeAndStringify ( code ) ) ;
}
2020-08-26 18:39:33 +02:00
void tokenize39 ( ) { // #9771
const char code [ ] = " 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> &); }; " ;
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 ) ) ;
}
2017-04-06 08:50:35 +02:00
void validate ( ) {
// C++ code in C file
2021-04-06 21:21:53 +02:00
ASSERT_THROW ( tokenizeAndStringify ( " ;using namespace std; " , false , Settings : : Native , " test.c " ) , InternalError ) ;
ASSERT_THROW ( tokenizeAndStringify ( " ;std::map<int,int> m; " , false , Settings : : Native , " test.c " ) , InternalError ) ;
ASSERT_THROW ( tokenizeAndStringify ( " ;template<class T> class X { }; " , false , Settings : : Native , " test.c " ) , InternalError ) ;
ASSERT_THROW ( tokenizeAndStringify ( " int X<Y>() {}; " , false , Settings : : Native , " test.c " ) , InternalError ) ;
ASSERT_THROW ( tokenizeAndStringify ( " void foo(int i) { reinterpret_cast<char>(i) }; " , false , Settings : : Native , " test.h " ) , InternalError ) ;
2017-04-06 08:50:35 +02:00
}
2018-01-24 18:06:11 +01:00
void objectiveC ( ) {
ASSERT_THROW ( tokenizeAndStringify ( " void f() { [foo bar]; } " ) , InternalError ) ;
}
2014-11-20 14:20:09 +01:00
void syntax_case_default ( ) { // correct syntax
2014-09-24 13:45:56 +02:00
tokenizeAndStringify ( " void f() {switch (n) { case 0: z(); break;}} " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-09-10 17:33:52 +02:00
2014-09-24 13:45:56 +02:00
tokenizeAndStringify ( " void f() {switch (n) { case 0:; break;}} " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-02-20 06:58:27 +01:00
2020-03-07 21:46:38 +01:00
// 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());
2013-06-22 14:05:49 +02:00
2020-03-07 21:46:38 +01:00
// TODO: Do not throw AST validation exception
TODO_ASSERT_THROW ( tokenizeAndStringify ( " void f() {switch (n) { case 0?(1?3:4):2 : z(); break;}} " ) , InternalError ) ;
2014-09-24 13:45:56 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-06-29 14:05:49 +02:00
2015-01-31 10:50:39 +01:00
//allow GCC '({ %name%|%num%|%bool% ; })' statement expression extension
2020-03-07 21:46:38 +01:00
// TODO: Do not throw AST validation exception
TODO_ASSERT_THROW ( tokenizeAndStringify ( " void f() {switch (n) { case 0?({0;}):1: z(); break;}} " ) , InternalError ) ;
2014-09-24 13:45:56 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-12-23 12:26:12 +01:00
2014-09-24 13:45:56 +02:00
//'b' can be or a macro or an undefined enum
tokenizeAndStringify ( " void f() {switch (n) { case b: z(); break;}} " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-11-23 20:33:03 +01:00
2014-09-24 13:45:56 +02:00
//valid, when there's this declaration: 'constexpr int g() { return 2; }'
tokenizeAndStringify ( " void f() {switch (n) { case g(): z(); break;}} " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2014-01-01 19:04:02 +01:00
2014-09-24 13:45:56 +02:00
//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 ( ) ) ;
2014-03-30 11:38:01 +02:00
2014-09-24 13:45:56 +02:00
//valid, similar to above case
tokenizeAndStringify ( " void f() {switch (n) { case *g: z(); break;}} " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2014-03-17 11:50:45 +01:00
2014-09-24 13:45:56 +02:00
//valid, when 'x' and 'y' are constexpr.
tokenizeAndStringify ( " void f() {switch (n) { case sqrt(x+y): z(); break;}} " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2014-09-04 21:27:33 +02:00
}
2020-11-15 14:57:18 +01:00
void removePragma ( ) {
const char code [ ] = " _Pragma( \" abc \" ) int x; " ;
Settings s ;
s . standards . c = Standards : : C89 ;
ASSERT_EQUALS ( " _Pragma ( \" abc \" ) int x ; " , tokenizeAndStringify ( code , s , " test.c " ) ) ;
s . standards . c = Standards : : CLatest ;
ASSERT_EQUALS ( " int x ; " , tokenizeAndStringify ( code , s , " test.c " ) ) ;
s . standards . cpp = Standards : : CPP03 ;
ASSERT_EQUALS ( " _Pragma ( \" abc \" ) int x ; " , tokenizeAndStringify ( code , s , " test.cpp " ) ) ;
s . standards . cpp = Standards : : CPPLatest ;
ASSERT_EQUALS ( " int x ; " , tokenizeAndStringify ( code , s , " test.cpp " ) ) ;
}
2015-12-17 15:40:54 +01:00
void foreach ( ) {
2013-12-17 06:34:27 +01:00
// #3690,#5154
2014-04-02 13:56:34 +02:00
const char code [ ] = " void f() { for each ( char c in MyString ) { Console::Write(c); } } " ;
2018-01-08 20:20:33 +01:00
ASSERT_EQUALS ( " void f ( ) { asm ( \" char c in MyString \" ) { Console :: Write ( c ) ; } } " , tokenizeAndStringify ( code ) ) ;
2012-09-03 20:23:53 +02:00
}
2018-04-09 11:42:38 +02:00
void ifconstexpr ( ) {
ASSERT_EQUALS ( " void f ( ) { if ( FOO ) { bar ( c ) ; } } " , tokenizeAndStringify ( " void f() { if constexpr ( FOO ) { bar(c); } } " ) ) ;
}
2015-10-19 10:01:57 +02:00
void combineOperators ( ) {
2021-04-06 21:21:53 +02:00
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<a*>(&e) " ) ) ;
2015-10-19 10:01:57 +02:00
}
2014-11-20 14:20:09 +01:00
void concatenateNegativeNumber ( ) {
2016-11-20 14:15:51 +01:00
ASSERT_EQUALS ( " i = -12 ; " , tokenizeAndStringify ( " i = -12; " ) ) ;
ASSERT_EQUALS ( " 1 - 2 ; " , tokenizeAndStringify ( " 1-2; " ) ) ;
ASSERT_EQUALS ( " foo ( -1 ) - 2 ; " , tokenizeAndStringify ( " foo(-1)-2; " ) ) ;
2009-03-18 19:48:06 +01:00
ASSERT_EQUALS ( " int f ( ) { return -2 ; } " , tokenizeAndStringify ( " int f(){return -2;} " ) ) ;
2012-11-20 19:12:22 +01:00
ASSERT_EQUALS ( " int x [ 2 ] = { -2 , 1 } " , tokenizeAndStringify ( " int x[2] = {-2,1} " ) ) ;
2012-11-28 07:09:56 +01:00
ASSERT_EQUALS ( " f ( 123 ) " , tokenizeAndStringify ( " f(+123) " ) ) ;
2009-03-17 20:50:06 +01:00
}
2009-01-18 09:52:20 +01:00
2014-11-20 14:20:09 +01:00
void longtok ( ) {
2012-02-17 19:54:53 +01:00
const std : : string filedata ( 10000 , ' a ' ) ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( filedata , tokenizeAndStringify ( filedata . c_str ( ) ) ) ;
2008-12-18 22:28:57 +01:00
}
2020-11-22 16:43:36 +01:00
void simplifyHeadersAndUnusedTemplates1 ( ) {
2019-04-07 08:37:04 +02:00
Settings s ;
2019-04-10 19:17:24 +02:00
s . checkUnusedTemplates = false ;
2019-04-07 08:37:04 +02:00
ASSERT_EQUALS ( " ; " ,
tokenizeAndStringify ( " ; template <typename... a> uint8_t b(std::tuple<uint8_t> d) { \n "
" std::tuple<a...> c{std::move(d)}; \n "
" return std::get<0>(c); \n "
" } " , s ) ) ;
2020-04-20 20:48:22 +02:00
ASSERT_EQUALS ( " int g ( int ) ; " ,
tokenizeAndStringify ( " int g(int); \n "
" template <class F, class... Ts> auto h(F f, Ts... xs) { \n "
" auto e = f(g(xs)...); \n "
" return e; \n "
" } " , s ) ) ;
2019-04-07 08:37:04 +02:00
}
2020-11-22 16:43:36 +01:00
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 "
" }; " ;
Settings s ;
s . checkUnusedTemplates = false ;
ASSERT_EQUALS ( " ; " , tokenizeAndStringify ( code , s ) ) ;
s . checkUnusedTemplates = true ;
2020-11-23 22:03:50 +01:00
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 ) ) ;
2020-11-22 16:43:36 +01:00
}
2020-05-30 11:23:22 +02:00
2018-12-04 16:52:41 +01:00
void simplifyAt ( ) {
ASSERT_EQUALS ( " int x ; " , tokenizeAndStringify ( " int x@123; " ) ) ;
2018-12-04 19:56:13 +01:00
ASSERT_EQUALS ( " bool x ; " , tokenizeAndStringify ( " bool x@123:1; " ) ) ;
2018-12-04 19:33:39 +01:00
ASSERT_EQUALS ( " char PORTB ; bool PB3 ; " , tokenizeAndStringify ( " char PORTB @ 0x10; bool PB3 @ PORTB:3; \n " ) ) ;
2020-09-02 13:03:13 +02:00
ASSERT_EQUALS ( " int x ; " , tokenizeAndStringify ( " int x @ (0x1000 + 18); " ) ) ;
2018-12-04 19:33:39 +01:00
2019-01-01 09:45:41 +01:00
ASSERT_EQUALS ( " int x [ 10 ] ; " , tokenizeAndStringify ( " int x[10]@0x100; " ) ) ;
2018-12-04 16:52:41 +01:00
ASSERT_EQUALS ( " interrupt@ f ( ) { } " , tokenizeAndStringify ( " @interrupt f() {} " ) ) ;
}
2014-11-20 14:20:09 +01:00
void inlineasm ( ) {
2012-01-15 19:48:27 +01:00
ASSERT_EQUALS ( " asm ( \" mov ax , bx \" ) ; " , tokenizeAndStringify ( " asm { mov ax,bx }; " ) ) ;
ASSERT_EQUALS ( " asm ( \" mov ax , bx \" ) ; " , tokenizeAndStringify ( " _asm { mov ax,bx }; " ) ) ;
2012-02-19 16:04:35 +01:00
ASSERT_EQUALS ( " asm ( \" mov ax , bx \" ) ; " , tokenizeAndStringify ( " _asm mov ax,bx " ) ) ;
2012-01-15 19:48:27 +01:00
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 \" ) ; " ) ) ;
2013-11-13 06:04:00 +01:00
ASSERT_EQUALS ( " asm ( \" \" ddd \" \" ) ; " , tokenizeAndStringify ( " __asm __volatile ( \" ddd \" ) ; " ) ) ;
2012-01-15 19:48:27 +01:00
ASSERT_EQUALS ( " asm ( \" \" mov ax,bx \" \" ) ; " , tokenizeAndStringify ( " __asm__ volatile ( \" mov ax,bx \" ); " ) ) ;
2015-07-20 22:51:06 +02:00
ASSERT_EQUALS ( " asm ( \" mov ax , bx \" ) ; int a ; " , tokenizeAndStringify ( " asm { mov ax,bx } int a; " ) ) ;
2017-05-05 08:57:24 +02:00
ASSERT_EQUALS ( " asm \n \n ( \" mov ax , bx \" ) ; " , tokenizeAndStringify ( " __asm \n mov ax,bx \n __endasm; " ) ) ;
ASSERT_EQUALS ( " asm \n \n ( \" push b ; for if \" ) ; " , tokenizeAndStringify ( " __asm \n push b ; for if \n __endasm; " ) ) ;
2011-12-12 20:50:49 +01:00
// 'asm ( ) ;' should be in the same line
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " ; \n \n asm ( \" \" mov ax,bx \" \" ) ; " , tokenizeAndStringify ( " ; \n \n __asm__ volatile ( \" mov ax,bx \" ); " ) ) ;
2008-12-18 22:28:57 +01:00
}
2016-01-04 09:59:53 +01:00
// #4725 - ^{}
void simplifyAsm2 ( ) {
2019-04-19 20:53:07 +02:00
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 "
2021-08-07 20:51:18 +02:00
" return ^{ \n "
" return sizeof...(Args); \n "
" }() + ^ { \n "
" return sizeof...(args); \n "
" }(); \n "
" }; " ) ) , InternalError ) ;
2019-04-19 20:53:07 +02:00
ASSERT_THROW ( ASSERT_EQUALS ( " int ( ^ block ) ( void ) = asm ( \" ^{staticinttest=0;returntest;} \" ) \n \n \n ; " ,
tokenizeAndStringify ( " int(^block)(void) = ^{ \n "
2021-08-07 20:51:18 +02:00
" static int test = 0; \n "
" return test; \n "
" }; " ) ) , InternalError ) ;
2016-01-04 09:59:53 +01:00
2019-04-19 20:53:07 +02:00
ASSERT_THROW ( ASSERT_EQUALS ( " ; return f ( a [ b = c ] , asm ( \" ^{} \" ) ) ; " ,
tokenizeAndStringify ( " ; return f(a[b=c],^{}); " ) ) , InternalError ) ; // #7185
2020-04-11 17:36:11 +02:00
ASSERT_EQUALS ( " { return f ( asm ( \" ^(void){somecode} \" ) ) ; } " ,
tokenizeAndStringify ( " { return f(^(void){somecode}); } " ) ) ;
2019-04-19 20:53:07 +02:00
ASSERT_THROW ( ASSERT_EQUALS ( " ; asm ( \" a?(b?(c,asm( \" ^{} \" )):0):^{} \" ) ; " ,
tokenizeAndStringify ( " ;a?(b?(c,^{}):0):^{}; " ) ) , InternalError ) ;
2019-03-05 11:35:45 +01:00
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<T> operator|(const char *const expression, const CImg<T>& img) { "
" return img | expression ; "
" } "
" template<typename T> "
" inline CImg<T> operator^(const char *const expression, const CImg<T>& img) { "
" return img ^ expression; "
" } "
" template<typename T> "
" inline CImg<T> operator==(const char *const expression, const CImg<T>& img) { "
" return img == expression; "
" } " ) ) ;
2016-01-04 09:59:53 +01:00
}
2014-11-20 14:20:09 +01:00
void ifAddBraces1 ( ) {
2008-12-22 19:05:22 +01:00
const char code [ ] = " void f() \n "
" { \n "
" if (a); \n "
2008-12-23 09:11:33 +01:00
" else ; \n "
2008-12-22 19:05:22 +01:00
" } \n " ;
2009-06-20 13:20:51 +02:00
ASSERT_EQUALS ( " void f ( ) \n "
" { \n "
" if ( a ) { ; } \n "
" else { ; } \n "
2021-04-06 21:21:53 +02:00
" } " , tokenizeAndStringify ( code ) ) ;
2008-12-22 19:05:22 +01:00
}
2008-12-22 10:20:46 +01:00
2014-11-20 14:20:09 +01:00
void ifAddBraces2 ( ) {
2008-12-22 19:05:22 +01:00
const char code [ ] = " void f() \n "
" { \n "
" if (a) if (b) { } \n "
" } \n " ;
2009-06-20 13:20:51 +02:00
ASSERT_EQUALS ( " void f ( ) \n "
" { \n "
" if ( a ) { if ( b ) { } } \n "
2021-04-06 21:21:53 +02:00
" } " , tokenizeAndStringify ( code ) ) ;
2008-12-22 19:05:22 +01:00
}
2008-12-22 10:20:46 +01:00
2014-11-20 14:20:09 +01:00
void ifAddBraces3 ( ) {
2008-12-22 19:05:22 +01:00
const char code [ ] = " void f() \n "
" { \n "
" if (a) for (;;) { } \n "
" } \n " ;
2009-06-20 13:20:51 +02:00
ASSERT_EQUALS ( " void f ( ) \n "
" { \n "
" if ( a ) { for ( ; ; ) { } } \n "
2021-04-06 21:21:53 +02:00
" } " , tokenizeAndStringify ( code ) ) ;
2008-12-22 10:20:46 +01:00
}
2014-11-20 14:20:09 +01:00
void ifAddBraces4 ( ) {
2008-12-22 19:32:04 +01:00
const char code [ ] = " char * foo () \n "
" { \n "
" char *str = malloc(10); \n "
" if (somecondition) \n "
2010-10-27 12:14:40 +02:00
" for ( ; ; ) \n "
2008-12-22 19:32:04 +01:00
" { } \n "
" return str; \n "
" } \n " ;
2009-06-20 13:20:51 +02:00
ASSERT_EQUALS ( " char * foo ( ) \n "
" { \n "
" char * str ; str = malloc ( 10 ) ; \n "
" if ( somecondition ) { \n "
2010-10-27 12:14:40 +02:00
" for ( ; ; ) \n "
2009-06-20 13:20:51 +02:00
" { } } \n "
" return str ; \n "
2021-04-06 21:21:53 +02:00
" } " , tokenizeAndStringify ( code ) ) ;
2008-12-22 19:32:04 +01:00
}
2014-11-20 14:20:09 +01:00
void ifAddBraces5 ( ) {
2009-03-15 13:44:57 +01:00
const char code [ ] = " void f() \n "
" { \n "
" for(int i = 0; i < 2; i++) \n "
" if(true) \n "
" return; \n "
" \n "
" return; \n "
" } \n " ;
2009-06-20 13:20:51 +02:00
ASSERT_EQUALS ( " void f ( ) \n "
" { \n "
" for ( int i = 0 ; i < 2 ; i ++ ) { \n "
2021-04-06 21:21:53 +02:00
" if ( true ) { \n "
" return ; } } \n \n "
2009-06-20 13:20:51 +02:00
" return ; \n "
2021-04-06 21:21:53 +02:00
" } " , tokenizeAndStringify ( code ) ) ;
2009-03-15 13:44:57 +01:00
}
2014-11-20 14:20:09 +01:00
void ifAddBraces7 ( ) {
2009-06-22 22:54:11 +02:00
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 "
2021-04-06 21:21:53 +02:00
" } " , tokenizeAndStringify ( code ) ) ;
2009-06-22 22:54:11 +02:00
}
2014-11-20 14:20:09 +01:00
void ifAddBraces9 ( ) {
2009-11-20 20:38:30 +01:00
// ticket #990
const char code [ ] =
2010-08-25 22:10:21 +02:00
" void f() { "
2009-11-20 20:38:30 +01:00
" for (int k=0; k<VectorSize; k++) "
" LOG_OUT(ID_Vector[k]) "
" } " ;
const char expected [ ] =
2010-08-25 22:10:21 +02:00
" void f ( ) { "
2013-02-02 16:01:34 +01:00
" for ( int k = 0 ; k < VectorSize ; k ++ ) "
2009-11-20 20:38:30 +01:00
" LOG_OUT ( ID_Vector [ k ] ) "
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2009-11-20 20:38:30 +01:00
}
2014-11-20 14:20:09 +01:00
void ifAddBraces11 ( ) {
2010-02-20 11:43:53 +01:00
const char code [ ] = " { if (x) if (y) ; else ; } " ;
const char expected [ ] = " { if ( x ) { if ( y ) { ; } else { ; } } } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2010-02-20 13:24:50 +01:00
}
2014-11-20 14:20:09 +01:00
void ifAddBraces12 ( ) {
2010-02-20 13:24:50 +01:00
// ticket #1424
const char code [ ] = " { if (x) do { } while(x); } " ;
const char expected [ ] = " { if ( x ) { do { } while ( x ) ; } } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2010-02-07 15:00:19 +01:00
}
2014-11-20 14:20:09 +01:00
void ifAddBraces13 ( ) {
2010-06-26 17:15:44 +02:00
// ticket #1809
const char code [ ] = " { if (x) if (y) { } else { } else { } } " ;
2020-05-20 21:06:39 +02:00
const char expected [ ] = " { if ( x ) { if ( y ) { } else { } } else { } } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2016-11-06 14:11:08 +01:00
2020-05-20 21:06:39 +02:00
// ticket #1809
const char code2 [ ] = " { if (x) while (y) { } else { } } " ;
const char expected2 [ ] = " { if ( x ) { while ( y ) { } } else { } } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected2 , tokenizeAndStringify ( code2 ) ) ;
2020-05-30 11:23:22 +02:00
}
void ifAddBraces15 ( ) {
// ticket #2616 - unknown macro before if
// TODO: Remove "A" or change it to ";A;". Then cleanup Tokenizer::ifAddBraces().
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " { A if ( x ) { y ( ) ; } } " , tokenizeAndStringify ( " {A if(x)y();} " ) ) ;
2020-05-30 11:23:22 +02:00
}
void ifAddBraces16 ( ) {
// ticket #2873 - the fix is not needed anymore.
{
const char code [ ] = " void f() { "
" (void) ( { if(*p) (*p) = x(); } ) "
" } " ;
ASSERT_EQUALS ( " void f ( ) { ( void ) ( { if ( * p ) { ( * p ) = x ( ) ; } } ) } " ,
tokenizeAndStringify ( code ) ) ;
}
}
void ifAddBraces17 ( ) {
const char code [ ] = " void f() \n "
" { \n "
" if (a) \n "
" bar1 (); \n "
" \n "
" else \n "
" bar2 (); \n "
" } \n " ;
ASSERT_EQUALS ( " void f ( ) \n "
" { \n "
" if ( a ) { \n "
" bar1 ( ) ; } \n "
" \n "
" else { \n "
" bar2 ( ) ; } \n "
2021-04-06 21:21:53 +02:00
" } " , tokenizeAndStringify ( code ) ) ;
2020-05-30 11:23:22 +02:00
}
void ifAddBraces18 ( ) {
// ticket #3424 - if if { } else else
ASSERT_EQUALS ( " { if ( x ) { if ( y ) { } else { ; } } else { ; } } " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " { if(x) if(y){}else;else;} " ) ) ;
2020-05-30 11:23:22 +02:00
ASSERT_EQUALS ( " { if ( x ) { if ( y ) { if ( z ) { } else { ; } } else { ; } } else { ; } } " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " { if(x) if(y) if(z){}else;else;else;} " ) ) ;
2020-05-30 11:23:22 +02:00
}
void ifAddBraces19 ( ) {
// #3928 - if for if else
const char code [ ] = " void f() \n "
" { \n "
" if (a) \n "
" for (;;) \n "
" if (b) \n "
" bar1(); \n "
" else \n "
" bar2(); \n "
" } \n " ;
ASSERT_EQUALS ( " void f ( ) \n "
" { \n "
" if ( a ) { \n "
" for ( ; ; ) { \n "
" if ( b ) { \n "
" bar1 ( ) ; } \n "
" else { \n "
" bar2 ( ) ; } } } \n "
2021-04-06 21:21:53 +02:00
" } " , tokenizeAndStringify ( code ) ) ;
2020-05-30 11:23:22 +02:00
}
void ifAddBraces20 ( ) { // #5012 - syntax error 'else }'
const char code [ ] = " void f() { if(x) {} else } " ;
2021-04-06 21:21:53 +02:00
ASSERT_THROW ( tokenizeAndStringify ( code ) , InternalError ) ;
2020-05-30 11:23:22 +02:00
}
2021-06-02 07:00:37 +02:00
void ifAddBracesLabels ( ) {
// Labels before statement
ASSERT_EQUALS ( " int f ( int x ) { \n "
" if ( x ) { \n "
" l1 : ; l2 : ; return x ; } \n "
" } " ,
tokenizeAndStringify ( " int f(int x) { \n "
" if (x) \n "
" l1: l2: return x; \n "
" } " ) ) ;
// Labels before {
ASSERT_EQUALS ( " int f ( int x ) { \n "
" if ( x ) \n "
" { l1 : ; l2 : ; return x ; } \n "
" } " ,
tokenizeAndStringify ( " int f(int x) { \n "
" if (x) \n "
" l1: l2: { return x; } \n "
" } " ) ) ;
// Labels before try/catch
ASSERT_EQUALS ( " int f ( int x ) { \n "
" if ( x ) { \n "
" l1 : ; l2 : ; \n "
" try { throw 1 ; } \n "
" catch ( ... ) { return x ; } } \n "
" } " ,
tokenizeAndStringify ( " int f(int x) { \n "
" if (x) \n "
" l1: l2: \n "
" try { throw 1; } \n "
" catch(...) { return x; } \n "
" } " ) ) ;
}
void switchAddBracesLabels ( ) {
// Labels before statement
ASSERT_EQUALS ( " int f ( int x ) { \n "
" switch ( x ) { \n "
" l1 : ; case 0 : ; l2 : ; case ( 1 ) : ; return x ; } \n "
" } " ,
tokenizeAndStringify ( " int f(int x) { \n "
" switch (x) \n "
" l1: case 0: l2: case (1): return x; \n "
" } " ) ) ;
// Labels before {
ASSERT_EQUALS ( " int f ( int x ) { \n "
" switch ( x ) \n "
" { l1 : ; case 0 : ; l2 : ; case ( 1 ) : ; return x ; } \n "
" } " ,
tokenizeAndStringify ( " int f(int x) { \n "
" switch (x) \n "
" l1: case 0: l2: case (1): { return x; } \n "
" } " ) ) ;
// Labels before try/catch
ASSERT_EQUALS ( " int f ( int x ) { \n "
" switch ( x ) { \n "
" l1 : ; case 0 : ; l2 : ; case ( 1 ) : ; \n "
" try { throw 1 ; } \n "
" catch ( ... ) { return x ; } } \n "
" } " ,
tokenizeAndStringify ( " int f(int x) { \n "
" switch (x) \n "
" l1: case 0: l2: case (1): \n "
" try { throw 1; } \n "
" catch(...) { return x; } \n "
" } " ) ) ;
2020-05-30 11:23:22 +02:00
}
void whileAddBraces ( ) {
const char code [ ] = " {while(a);} " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " { while ( a ) { ; } } " , tokenizeAndStringify ( code ) ) ;
2020-05-30 11:23:22 +02:00
}
2021-06-02 07:00:37 +02:00
void whileAddBracesLabels ( ) {
// Labels before statement
ASSERT_EQUALS ( " void f ( int x ) { \n "
" while ( x ) { \n "
" l1 : ; l2 : ; -- x ; } \n "
" } " ,
tokenizeAndStringify ( " void f(int x) { \n "
" while (x) \n "
" l1: l2: --x; \n "
" } " ) ) ;
// Labels before {
ASSERT_EQUALS ( " void f ( int x ) { \n "
" while ( x ) \n "
" { l1 : ; l2 : ; -- x ; } \n "
" } " ,
tokenizeAndStringify ( " void f(int x) { \n "
" while (x) \n "
" l1: l2: { -- x; } \n "
" } " ) ) ;
// Labels before try/catch
ASSERT_EQUALS ( " void f ( int x ) { \n "
" while ( x ) { \n "
" l1 : ; l2 : ; \n "
" try { throw 1 ; } \n "
" catch ( ... ) { -- x ; } } \n "
" } " ,
tokenizeAndStringify ( " void f(int x) { \n "
" while (x) \n "
" l1: l2: \n "
" try { throw 1; } \n "
" catch(...) { --x; } \n "
" } " ) ) ;
}
2020-05-30 11:23:22 +02:00
void doWhileAddBraces ( ) {
{
const char code [ ] = " {do ; while (0);} " ;
const char result [ ] = " { do { ; } while ( 0 ) ; } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result , tokenizeAndStringify ( code ) ) ;
2020-05-30 11:23:22 +02:00
}
{
const char code [ ] = " { UNKNOWN_MACRO ( do ) ; while ( a -- ) ; } " ;
const char result [ ] = " { UNKNOWN_MACRO ( do ) ; while ( a -- ) { ; } } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result , tokenizeAndStringify ( code ) ) ;
2020-05-30 11:23:22 +02:00
}
{
const char code [ ] = " { UNKNOWN_MACRO ( do , foo ) ; while ( a -- ) ; } " ;
const char result [ ] = " { UNKNOWN_MACRO ( do , foo ) ; while ( a -- ) { ; } } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result , tokenizeAndStringify ( code ) ) ;
2020-05-30 11:23:22 +02:00
}
{
const char code [ ] = " void foo ( int c , int d ) { \n "
" do \n "
" if ( c ) { \n "
" while ( c ) { c -- ; } \n "
" } \n "
" while ( -- d > 0 ) ; \n "
" return 0 ; \n "
" } \n " ;
const char result [ ] = " void foo ( int c , int d ) { \n "
2021-08-07 20:51:18 +02:00
" do { \n "
" if ( c ) { \n "
" while ( c ) { c -- ; } \n "
" } } \n "
" while ( -- d > 0 ) ; \n "
" return 0 ; \n "
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result , tokenizeAndStringify ( code ) ) ;
2020-05-30 11:23:22 +02:00
}
{
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 "
2021-08-07 20:51:18 +02:00
" do { \n "
" do { c -- ; } while ( c ) ; } \n "
" while ( -- d > 0 ) ; \n "
" return 0 ; \n "
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result , tokenizeAndStringify ( code ) ) ;
2020-05-30 11:23:22 +02:00
}
{
// #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 "
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result , tokenizeAndStringify ( code ) ) ;
2020-05-30 11:23:22 +02:00
}
}
2021-06-02 07:00:37 +02:00
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 "
" } " ) ) ;
}
2020-05-30 11:23:22 +02:00
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 "
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2020-05-30 11:23:22 +02:00
}
{
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 "
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2020-05-30 11:23:22 +02:00
}
}
void forAddBraces2 ( ) { // #5088
const char code [ ] = " void f() { \n "
" for(;;) try { } catch (...) { } \n "
" } " ;
const char expected [ ] = " void f ( ) { \n "
" for ( ; ; ) { try { } catch ( ... ) { } } \n "
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2020-05-30 11:23:22 +02:00
}
2021-06-02 07:00:37 +02:00
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 "
" } " ) ) ;
}
2014-11-20 14:20:09 +01:00
void simplifyExternC ( ) {
2012-04-16 16:25:04 +02:00
ASSERT_EQUALS ( " int foo ( ) ; " , tokenizeAndStringify ( " extern \" C \" int foo(); " ) ) ;
ASSERT_EQUALS ( " int foo ( ) ; " , tokenizeAndStringify ( " extern \" C \" { int foo(); } " ) ) ;
}
2011-01-15 08:48:42 +01:00
2014-11-20 14:20:09 +01:00
void simplifyFunctionParameters ( ) {
2009-12-31 19:31:21 +01:00
{
const char code [ ] = " char a [ ABC ( DEF ) ] ; " ;
2012-07-29 15:11:48 +02:00
ASSERT_EQUALS ( code , tokenizeAndStringify ( code ) ) ;
2009-12-31 19:31:21 +01:00
}
2010-01-01 13:26:54 +01:00
{
const char code [ ] = " module ( a , a , sizeof ( a ) , 0444 ) ; " ;
2020-02-19 07:51:39 +01:00
ASSERT_EQUALS ( " module ( a , a , sizeof ( a ) , 0444 ) ; " , tokenizeAndStringify ( code ) ) ;
2010-01-01 13:26:54 +01:00
}
2012-07-29 15:11:48 +02:00
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; { } " ) ) ;
2009-01-24 08:56:47 +01:00
2014-09-23 16:18:04 +02:00
// #1067 - Not simplified. Feel free to fix so it is simplified correctly but this syntax is obsolescent.
2012-07-29 15:11:48 +02:00
ASSERT_EQUALS ( " int ( * d ( a , b , c ) ) ( ) int a ; int b ; int c ; { } " , tokenizeAndStringify ( " int (*d(a,b,c))()int a,b,c; { } " ) ) ;
2009-01-24 19:21:16 +01:00
{
// This is not a function but the pattern is similar..
2009-12-30 15:12:38 +01:00
const char code [ ] = " void foo() "
" { "
" if (x) "
" int x; "
" { } "
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { if ( x ) { int x ; } { } } " , tokenizeAndStringify ( code ) ) ;
2009-01-24 19:21:16 +01:00
}
2009-01-24 08:56:47 +01:00
}
2009-01-25 20:39:05 +01:00
2014-11-20 14:20:09 +01:00
void simplifyFunctionParameters1 ( ) { // ticket #3721
2012-04-22 17:28:27 +02:00
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 "
2012-07-29 15:11:48 +02:00
" } " , tokenizeAndStringify ( code ) ) ;
2012-04-22 17:28:27 +02:00
}
2014-11-20 14:20:09 +01:00
void simplifyFunctionParameters2 ( ) { // #4430
2012-12-23 08:04:44 +01:00
const char code [ ] = " class Item { "
" int i ; "
" public: "
" Item ( int i ) ; "
" } ; "
" Item :: Item ( int i ) : i ( i ) { } " ;
ASSERT_EQUALS ( code , tokenizeAndStringify ( code ) ) ;
}
2014-11-20 14:20:09 +01:00
void simplifyFunctionParameters3 ( ) { // #4436
2012-12-27 17:15:38 +01:00
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 ) ) ;
}
2019-10-16 20:56:53 +02:00
void simplifyFunctionParameters4 ( ) { // #9421
const char code [ ] = " int foo :: bar ( int , int ) const ; " ;
ASSERT_EQUALS ( code , tokenizeAndStringify ( code ) ) ;
}
2018-02-04 09:48:37 +01:00
void simplifyFunctionParametersMultiTemplate ( ) {
const char code [ ] = " template < typename T1 > template < typename T2 > "
" void A < T1 > :: foo ( T2 ) { } " ;
ASSERT_EQUALS ( code , tokenizeAndStringify ( code ) ) ;
}
2014-11-20 14:20:09 +01:00
void simplifyFunctionParametersErrors ( ) {
2012-01-23 16:10:15 +01:00
//same parameters...
2014-03-27 13:15:21 +01:00
ASSERT_THROW ( tokenizeAndStringify ( " void foo(x, x) \n "
" int x; \n "
" int x; \n "
" {} \n " ) , InternalError ) ;
2012-01-23 16:10:15 +01:00
2014-03-27 13:15:21 +01:00
ASSERT_THROW ( tokenizeAndStringify ( " void foo(x, y) \n "
" int x; \n "
" int x; \n "
" {} \n " ) , InternalError ) ;
2012-01-23 16:10:15 +01:00
tokenizeAndStringify ( " void foo(int, int) \n "
2021-02-20 12:58:42 +01:00
" {} " ) ;
2012-01-23 16:10:15 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-07-29 15:11:48 +02:00
// #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 "
" } " ) ;
2020-05-30 11:23:22 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-01-23 16:10:15 +01:00
}
2021-05-02 09:05:12 +02:00
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 "
" } " ) ) ;
}
2009-01-25 20:39:05 +01:00
// Simplify "((..))" into "(..)"
2014-11-20 14:20:09 +01:00
void removeParentheses1 ( ) {
2011-05-01 07:50:19 +02:00
const char code [ ] = " void foo() "
" { "
" free(((void*)p)); "
2009-01-25 20:39:05 +01:00
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { free ( ( void * ) p ) ; } " , tokenizeAndStringify ( code ) ) ;
2009-01-25 20:39:05 +01:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses3 ( ) {
2009-05-29 23:04:01 +02:00
{
2011-05-01 07:50:19 +02:00
const char code [ ] = " void foo() "
" { "
" if (( true )==(true)){} "
2009-05-29 23:04:01 +02:00
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { if ( true == true ) { } } " , tokenizeAndStringify ( code ) ) ;
2009-05-29 23:04:01 +02:00
}
{
2011-05-01 07:50:19 +02:00
const char code [ ] = " void foo() "
" { "
" if (( 2 )==(2)){} "
2009-05-29 23:04:01 +02:00
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { if ( 2 == 2 ) { } } " , tokenizeAndStringify ( code ) ) ;
2009-05-29 23:04:01 +02:00
}
2009-05-31 14:55:06 +02:00
{
2011-05-01 07:50:19 +02:00
const char code [ ] = " void foo() "
" { "
" if( g(10)){} "
2009-05-31 14:55:06 +02:00
" } " ;
2011-05-01 07:50:19 +02:00
ASSERT_EQUALS ( " void foo ( ) { if ( g ( 10 ) ) { } } " , tokenizeAndStringify ( code ) ) ;
2009-05-31 14:55:06 +02:00
}
2009-05-28 22:03:36 +02:00
}
2009-02-02 07:21:48 +01:00
2009-06-12 15:04:58 +02:00
// Simplify "( function (..))" into "function (..)"
2014-11-20 14:20:09 +01:00
void removeParentheses4 ( ) {
2011-05-01 07:50:19 +02:00
const char code [ ] = " void foo() "
" { "
" (free(p)); "
2009-06-12 15:04:58 +02:00
" } " ;
2011-05-01 07:50:19 +02:00
ASSERT_EQUALS ( " void foo ( ) { free ( p ) ; } " , tokenizeAndStringify ( code ) ) ;
2009-06-12 15:04:58 +02:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses5 ( ) {
2009-06-12 16:14:01 +02:00
// Simplify "( delete x )" into "delete x"
{
2011-05-01 07:50:19 +02:00
const char code [ ] = " void foo() "
" { "
" (delete p); "
2009-06-12 16:14:01 +02:00
" } " ;
2011-05-01 07:50:19 +02:00
ASSERT_EQUALS ( " void foo ( ) { delete p ; } " , tokenizeAndStringify ( code ) ) ;
2009-06-12 16:14:01 +02:00
}
// Simplify "( delete [] x )" into "delete [] x"
{
2011-05-01 07:50:19 +02:00
const char code [ ] = " void foo() "
" { "
" (delete [] p); "
2009-06-12 16:14:01 +02:00
" } " ;
2011-05-01 07:50:19 +02:00
ASSERT_EQUALS ( " void foo ( ) { delete [ ] p ; } " , tokenizeAndStringify ( code ) ) ;
2009-06-12 16:14:01 +02:00
}
}
2009-11-15 09:28:08 +01:00
// "!(abc.a)" => "!abc.a"
2014-11-20 14:20:09 +01:00
void removeParentheses6 ( ) {
2012-11-04 22:38:18 +01:00
{
2016-11-20 14:15:51 +01:00
const char code [ ] = " (!(abc.a)); " ;
ASSERT_EQUALS ( " ( ! abc . a ) ; " , tokenizeAndStringify ( code ) ) ;
2012-11-04 22:38:18 +01:00
}
//handle more complex member selections
{
const char code [ ] = " (!(a.b.c.d)); " ;
ASSERT_EQUALS ( " ( ! a . b . c . d ) ; " , tokenizeAndStringify ( code ) ) ;
}
2009-11-15 09:28:08 +01:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses7 ( ) {
2010-09-05 07:53:43 +02:00
const char code [ ] = " ;char *p; (delete(p), (p)=0); " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " ; char * p ; delete ( p ) , p = 0 ; " , tokenizeAndStringify ( code ) ) ;
2010-05-07 18:37:50 +02:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses8 ( ) {
2010-07-19 12:06:20 +02:00
const char code [ ] = " struct foo { \n "
" void operator delete(void *obj, size_t sz); \n "
" } \n " ;
2021-04-06 21:21:53 +02:00
const std : : string actual ( tokenizeAndStringify ( code , true , Settings : : Win32A ) ) ;
2010-07-19 12:06:20 +02:00
const char expected [ ] = " struct foo { \n "
2011-09-18 16:31:31 +02:00
" void operatordelete ( void * obj , unsigned long sz ) ; \n "
2010-07-19 12:06:20 +02:00
" } " ;
ASSERT_EQUALS ( expected , actual ) ;
}
2014-11-20 14:20:09 +01:00
void removeParentheses9 ( ) {
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void delete ( double num ) ; " , tokenizeAndStringify ( " void delete(double num); " ) ) ;
2010-09-05 07:53:43 +02:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses10 ( ) {
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " p = buf + 8 ; " , tokenizeAndStringify ( " p = (buf + 8); " ) ) ;
2010-12-18 09:44:58 +01:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses11 ( ) {
2011-01-28 09:19:30 +01:00
// #2502
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " { } x ( ) ; " , tokenizeAndStringify ( " {}(x()); " ) ) ;
2011-01-28 09:19:30 +01:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses12 ( ) {
2011-05-01 08:27:59 +02:00
// #2760
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " , x = 0 ; " , tokenizeAndStringify ( " ,(x)=0; " ) ) ;
2011-05-01 08:27:59 +02:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses13 ( ) {
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " ; f ( a + b , c ) ; " , tokenizeAndStringify ( " ;f((a+b),c); " ) ) ;
ASSERT_EQUALS ( " ; x = y [ a + b ] ; " , tokenizeAndStringify ( " ;x=y[(a+b)]; " ) ) ;
2011-11-07 23:40:06 +01:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses14 ( ) {
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " { if ( ( i & 1 ) == 0 ) { ; } } " , tokenizeAndStringify ( " { if ( (i & 1) == 0 ); } " ) ) ;
2011-11-08 22:48:14 +01:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses15 ( ) {
2021-04-06 21:21:53 +02:00
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; " ) ) ;
2012-12-29 17:13:06 +01:00
// #4316
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " a = b ? c : ( d = 1 , 0 ) ; " , tokenizeAndStringify ( " a = b ? c : (d=1,0); " ) ) ;
2012-09-06 16:16:29 +02:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses16 ( ) { // *(x.y)=
2013-02-16 16:07:05 +01:00
// #4423
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " ; * x = 0 ; " , tokenizeAndStringify ( " ;*(x)=0; " ) ) ;
ASSERT_EQUALS ( " ; * x . y = 0 ; " , tokenizeAndStringify ( " ;*(x.y)=0; " ) ) ;
2013-02-16 16:07:05 +01:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses17 ( ) { // a ? b : (c > 0 ? d : e)
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " a ? b : ( c > 0 ? d : e ) ; " , tokenizeAndStringify ( " a?b:(c>0?d:e); " ) ) ;
2014-01-08 20:53:33 +01:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses18 ( ) {
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " float ( * a ) [ 2 ] ; " , tokenizeAndStringify ( " float(*a)[2]; " ) ) ;
2014-04-21 16:14:49 +02:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses19 ( ) {
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " ( ( ( typeof ( X ) ) * ) 0 ) ; " , tokenizeAndStringify ( " (((typeof(X))*)0); " ) ) ;
2014-05-04 18:36:04 +02:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses20 ( ) {
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " a < b < int > > ( 2 ) ; " , tokenizeAndStringify ( " a<b<int>>(2); " ) ) ;
2014-05-11 08:22:28 +02:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses21 ( ) {
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " a = ( int ) - b ; " , tokenizeAndStringify ( " a = ((int)-b); " ) ) ;
2014-05-24 19:04:47 +02:00
}
2014-11-20 14:20:09 +01:00
void removeParentheses22 ( ) {
2014-06-28 09:36:51 +02:00
static char code [ ] = " struct S { "
" char *(a); "
" char &(b); "
" const static char *(c); "
" } ; " ;
2021-08-07 20:51:18 +02:00
static char exp [ ] = " struct S { "
" char * a ; "
" char & b ; "
" static const char * c ; "
" } ; " ;
2014-06-28 09:36:51 +02:00
ASSERT_EQUALS ( exp , tokenizeAndStringify ( code ) ) ;
}
2014-11-20 14:20:09 +01:00
void removeParentheses23 ( ) { // Ticket #6103
2014-09-05 00:31:58 +02:00
// Reported case
{
2016-11-20 17:59:50 +01:00
static char code [ ] = " ; * * p f ( ) int = { new int ( * [ 2 ] ) ; void } " ;
2021-08-07 20:51:18 +02:00
static char exp [ ] = " ; * * p f ( ) int = { new int ( * [ 2 ] ) ; void } " ;
2014-09-05 00:31:58 +02:00
ASSERT_EQUALS ( exp , tokenizeAndStringify ( code ) ) ;
}
// Various valid cases
{
static char code [ ] = " int * f [ 1 ] = { new ( int ) } ; " ;
2021-08-07 20:51:18 +02:00
static char exp [ ] = " int * f [ 1 ] = { new int } ; " ;
2014-09-05 00:31:58 +02:00
ASSERT_EQUALS ( exp , tokenizeAndStringify ( code ) ) ;
}
{
static char code [ ] = " int * * f [ 1 ] = { new ( int ) [ 1 ] } ; " ;
2021-08-07 20:51:18 +02:00
static char exp [ ] = " int * * f [ 1 ] = { new int [ 1 ] } ; " ;
2014-09-05 00:31:58 +02:00
ASSERT_EQUALS ( exp , tokenizeAndStringify ( code ) ) ;
}
{
static char code [ ] = " list < int > * f [ 1 ] = { new ( list < int > ) } ; " ;
2021-08-07 20:51:18 +02:00
static char exp [ ] = " list < int > * f [ 1 ] = { new list < int > } ; " ;
2014-09-05 00:31:58 +02:00
ASSERT_EQUALS ( exp , tokenizeAndStringify ( code ) ) ;
}
2014-10-11 09:18:43 +02:00
// don't remove parentheses in operator new overload
{
static char code [ ] = " void *operator new(__SIZE_TYPE__, int); " ;
2021-08-07 20:51:18 +02:00
static char exp [ ] = " void * operatornew ( __SIZE_TYPE__ , int ) ; " ;
2014-10-11 09:18:43 +02:00
ASSERT_EQUALS ( exp , tokenizeAndStringify ( code ) ) ;
}
2014-09-05 00:31:58 +02:00
}
2015-10-13 20:31:17 +02:00
void removeParentheses24 ( ) { // Ticket #7040
static char code [ ] = " std::hash<decltype(t._data)>()(t._data); " ;
2021-08-07 20:51:18 +02:00
static char exp [ ] = " std :: hash < decltype ( t . _data ) > ( ) ( t . _data ) ; " ;
2015-10-13 20:31:17 +02:00
ASSERT_EQUALS ( exp , tokenizeAndStringify ( code ) ) ;
}
2020-09-29 12:06:30 +02:00
void removeParentheses25 ( ) { // daca@home - a=(b,c)
static char code [ ] = " a=(b,c); " ;
2021-08-07 20:51:18 +02:00
static char exp [ ] = " a = ( b , c ) ; " ;
2020-09-29 12:06:30 +02:00
ASSERT_EQUALS ( exp , tokenizeAndStringify ( code ) ) ;
}
2021-03-11 08:16:25 +01:00
void removeParentheses26 ( ) { // Ticket #8875 a[0](0)
static char code [ ] = " a[0](0); " ;
2021-08-07 20:51:18 +02:00
static char exp [ ] = " a [ 0 ] ( 0 ) ; " ;
2021-03-11 08:16:25 +01:00
ASSERT_EQUALS ( exp , tokenizeAndStringify ( code ) ) ;
}
2014-11-20 14:20:09 +01:00
void tokenize_double ( ) {
2015-10-07 18:33:57 +02:00
const char code [ ] = " void f() { \n "
2009-02-08 10:51:45 +01:00
" double a = 4.2; \n "
" float b = 4.2f; \n "
2009-02-08 11:39:55 +01:00
" double c = 4.2e+10; \n "
" double d = 4.2e-10; \n "
2009-02-08 11:56:20 +01:00
" int e = 4+2; \n "
2015-10-07 18:33:57 +02:00
" } " ;
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 "
2018-10-20 10:51:50 +02:00
" int e ; e = 4 + 2 ; \n "
2015-10-07 18:33:57 +02:00
" } " , tokenizeAndStringify ( code ) ) ;
2009-02-08 10:51:45 +01:00
}
2009-02-08 11:25:33 +01:00
2014-11-20 14:20:09 +01:00
void tokenize_strings ( ) {
2015-10-07 18:33:57 +02:00
const char code [ ] = " void f() { \n "
2021-08-07 20:51:18 +02:00
" const char *a = \n "
" { \n "
" \" hello \" \n "
" \" more \" \n "
" \" world \" \n "
" }; \n "
" } " ;
2015-10-07 18:33:57 +02:00
ASSERT_EQUALS ( " void f ( ) { \n "
" const char * a ; a = \n "
" { \n "
" \" hello more world \" \n "
" \n "
" \n "
" } ; \n "
" } " , tokenizeAndStringify ( code ) ) ;
2009-02-08 11:25:33 +01:00
}
2009-02-11 23:15:22 +01:00
2014-11-20 14:20:09 +01:00
void simplifyMulAndParens ( ) {
2011-05-18 07:25:30 +02:00
// (error) Resource leak
2011-12-09 20:47:51 +01:00
const char code [ ] = " void f() { "
" *&n1=open(); "
" *&(n2)=open(); "
" *(&n3)=open(); "
" *&*&n4=open(); "
" *&*&*&(n5)=open(); "
" *&*&(*&n6)=open(); "
" *&*(&*&n7)=open(); "
" *(&*&n8)=open(); "
" *&(*&*&(*&n9))=open(); "
" (n10) = open(); "
" ((n11)) = open(); "
" ((*&n12))=open(); "
" *(&(*&n13))=open(); "
" ((*&(*&n14)))=open(); "
" ((*&(*&n15)))+=10; "
" } " ;
const char expected [ ] = " void f ( ) { "
" n1 = open ( ) ; "
" n2 = open ( ) ; "
" n3 = open ( ) ; "
" n4 = open ( ) ; "
" n5 = open ( ) ; "
" n6 = open ( ) ; "
" n7 = open ( ) ; "
" n8 = open ( ) ; "
" n9 = open ( ) ; "
" n10 = open ( ) ; "
" n11 = open ( ) ; "
" n12 = open ( ) ; "
" n13 = open ( ) ; "
" n14 = open ( ) ; "
2015-12-31 01:15:49 +01:00
" n15 += 10 ; "
2011-12-09 20:47:51 +01:00
" } " ;
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2011-05-18 07:25:30 +02:00
}
2014-11-20 14:20:09 +01:00
void simplifyStructDecl ( ) {
2013-01-07 19:20:15 +01:00
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 ) ) ;
2019-12-15 08:40:04 +01:00
// #9519
const char code2 [ ] = " enum A {} (a); " ;
const char expected2 [ ] = " enum A { } ; enum A a ; " ;
ASSERT_EQUALS ( expected2 , tokenizeAndStringify ( code2 ) ) ;
2013-01-07 19:20:15 +01:00
}
2014-11-20 14:20:09 +01:00
void vardecl1 ( ) {
2009-03-16 19:03:23 +01:00
const char code [ ] = " unsigned int a, b; " ;
2009-03-18 20:32:05 +01:00
const std : : string actual ( tokenizeAndStringify ( code ) ) ;
2009-03-16 19:03:23 +01:00
2009-03-18 20:32:05 +01:00
ASSERT_EQUALS ( " unsigned int a ; unsigned int b ; " , actual ) ;
2009-03-16 19:03:23 +01:00
}
2014-11-20 14:20:09 +01:00
void vardecl2 ( ) {
2009-03-16 19:03:23 +01:00
const char code [ ] = " void foo(a,b) unsigned int a, b; { } " ;
2009-03-18 20:32:05 +01:00
const std : : string actual ( tokenizeAndStringify ( code ) ) ;
2009-03-16 19:03:23 +01:00
2011-11-05 12:23:05 +01:00
ASSERT_EQUALS ( " void foo ( unsigned int a , unsigned int b ) { } " , actual ) ;
2009-03-16 19:03:23 +01:00
}
2009-04-20 20:38:05 +02:00
2014-11-20 14:20:09 +01:00
void vardecl3 ( ) {
2009-06-14 14:57:47 +02:00
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 ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl4 ( ) {
2009-06-14 19:32:34 +02:00
// ticket #346
const char code1 [ ] = " void *p = NULL; " ;
2016-10-18 21:44:02 +02:00
const char res1 [ ] = " void * p ; p = NULL ; " ;
2009-06-14 19:32:34 +02:00
ASSERT_EQUALS ( res1 , tokenizeAndStringify ( code1 ) ) ;
const char code2 [ ] = " const void *p = NULL; " ;
2016-10-18 21:44:02 +02:00
const char res2 [ ] = " const void * p ; p = NULL ; " ;
2009-06-14 19:32:34 +02:00
ASSERT_EQUALS ( res2 , tokenizeAndStringify ( code2 ) ) ;
const char code3 [ ] = " void * const p = NULL; " ;
2016-10-18 21:44:02 +02:00
const char res3 [ ] = " void * const p ; p = NULL ; " ;
2009-06-14 19:32:34 +02:00
ASSERT_EQUALS ( res3 , tokenizeAndStringify ( code3 ) ) ;
const char code4 [ ] = " const void * const p = NULL; " ;
2016-10-18 21:44:02 +02:00
const char res4 [ ] = " const void * const p ; p = NULL ; " ;
2009-06-14 19:32:34 +02:00
ASSERT_EQUALS ( res4 , tokenizeAndStringify ( code4 ) ) ;
2019-08-03 12:28:50 +02:00
const char code5 [ ] = " const void * volatile p = NULL; " ;
const char res5 [ ] = " const void * volatile p ; p = NULL ; " ;
2020-04-21 17:27:51 +02:00
ASSERT_EQUALS ( res5 , tokenizeAndStringify ( code5 ) ) ;
2009-06-14 19:32:34 +02:00
}
2015-10-15 10:31:08 +02:00
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 "
" } " ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl_stl_1 ( ) {
2009-07-28 21:46:33 +02:00
// ticket #520
const char code1 [ ] = " std::vector<std::string>a, b; " ;
const char res1 [ ] = " std :: vector < std :: string > a ; std :: vector < std :: string > b ; " ;
ASSERT_EQUALS ( res1 , tokenizeAndStringify ( code1 ) ) ;
const char code2 [ ] = " std::vector<std::string>::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<std::pair<std::string, std::string > > *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 ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl_stl_2 ( ) {
2010-11-13 15:45:33 +01:00
const char code1 [ ] = " { std::string x = \" abc \" ; } " ;
2011-03-23 12:48:18 +01:00
ASSERT_EQUALS ( " { std :: string x ; x = \" abc \" ; } " , tokenizeAndStringify ( code1 ) ) ;
2010-11-13 15:45:33 +01:00
const char code2 [ ] = " { std::vector<int> x = y; } " ;
2011-03-24 02:15:49 +01:00
ASSERT_EQUALS ( " { std :: vector < int > x ; x = y ; } " , tokenizeAndStringify ( code2 ) ) ;
2010-11-13 15:45:33 +01:00
}
2014-11-20 14:20:09 +01:00
void vardecl_template_1 ( ) {
2009-12-05 21:15:14 +01:00
// ticket #1046
const char code1 [ ] = " b<(1<<24),10,24> u, v; " ;
2012-09-08 07:01:35 +02:00
const char res1 [ ] = " b < 16777216 , 10 , 24 > u ; b < 16777216 , 10 , 24 > v ; " ;
2009-12-05 21:15:14 +01:00
ASSERT_EQUALS ( res1 , tokenizeAndStringify ( code1 ) ) ;
2012-01-31 18:41:57 +01:00
// ticket #3571 (segmentation fault)
tokenizeAndStringify ( " template <int i = (3>4) > class X4 {}; " ) ;
2009-12-05 21:15:14 +01:00
}
2014-11-20 14:20:09 +01:00
void vardecl_template_2 ( ) {
2012-04-05 08:53:10 +02:00
// 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 ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl_union ( ) {
2010-09-03 08:10:29 +02:00
// ticket #1976
const char code1 [ ] = " class Fred { public: union { int a ; int b ; } ; } ; " ;
ASSERT_EQUALS ( code1 , tokenizeAndStringify ( code1 ) ) ;
2010-09-09 20:15:00 +02:00
// ticket #2039
const char code2 [ ] = " void f() { \n "
" union { \n "
" int x; \n "
" long y; \n "
" }; \n "
" } " ;
ASSERT_EQUALS ( " void f ( ) { \n \n int x ; \n long & y = x ; \n \n } " , tokenizeAndStringify ( code2 ) ) ;
2012-07-08 13:59:00 +02:00
// ticket #3927
const char code3 [ ] = " union xy *p = NULL; " ;
2016-10-18 21:44:02 +02:00
ASSERT_EQUALS ( " union xy * p ; p = NULL ; " , tokenizeAndStringify ( code3 ) ) ;
2010-09-03 08:10:29 +02:00
}
2014-11-20 14:20:09 +01:00
void vardecl_par ( ) {
2011-05-07 14:23:14 +02:00
// ticket #2743 - set links if variable type contains parentheses
const char code [ ] = " Fred<int(*)()> fred1=a, fred2=b; " ;
2015-10-08 11:35:51 +02:00
ASSERT_EQUALS ( " Fred < int ( * ) ( ) > fred1 ; fred1 = a ; Fred < int ( * ) ( ) > fred2 ; fred2 = b ; " , tokenizeAndStringify ( code ) ) ;
2011-05-07 14:23:14 +02:00
}
2014-11-20 14:20:09 +01:00
void vardecl_par2 ( ) {
2012-07-03 06:34:14 +02:00
// ticket #3912 - set correct links
const char code [ ] = " function<void (shared_ptr<MyClass>)> v; " ;
2015-10-08 11:35:51 +02:00
ASSERT_EQUALS ( " function < void ( shared_ptr < MyClass > ) > v ; " , tokenizeAndStringify ( code ) ) ;
2012-07-03 06:34:14 +02:00
}
2015-03-06 17:30:20 +01:00
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 ) ) ;
}
2016-01-19 15:27:11 +01:00
void vardecl_class_ref ( ) {
const char code [ ] = " class A { B &b1,&b2; }; " ;
ASSERT_EQUALS ( " class A { B & b1 ; B & b2 ; } ; " , tokenizeAndStringify ( code ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardec_static ( ) {
2009-10-02 16:28:30 +02:00
{
// 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; " ;
2009-10-03 12:03:54 +02:00
ASSERT_EQUALS ( " static int a ; static int b ; " , tokenizeAndStringify ( code ) ) ;
2009-10-02 16:28:30 +02:00
}
{
const char code [ ] = " static unsigned int a, b; " ;
2009-10-03 12:03:54 +02:00
ASSERT_EQUALS ( " static unsigned int a ; static unsigned int b ; " , tokenizeAndStringify ( code ) ) ;
2009-10-02 16:28:30 +02:00
}
{
const char code [ ] = " static int a=1, b=1; " ;
2009-10-03 12:03:54 +02:00
ASSERT_EQUALS ( " static int a = 1 ; static int b = 1 ; " , tokenizeAndStringify ( code ) ) ;
2009-10-02 16:28:30 +02:00
}
{
const char code [ ] = " static int *a, *b; " ;
2009-10-03 12:03:54 +02:00
ASSERT_EQUALS ( " static int * a ; static int * b ; " , tokenizeAndStringify ( code ) ) ;
2009-10-02 16:28:30 +02:00
}
{
const char code [ ] = " static unsigned int *a=0, *b=0; " ;
2009-10-03 12:03:54 +02:00
ASSERT_EQUALS ( " static unsigned int * a = 0 ; static unsigned int * b = 0 ; " , tokenizeAndStringify ( code ) ) ;
2009-10-02 16:28:30 +02:00
}
2013-08-24 22:27:54 +02:00
{
2013-10-30 15:48:00 +01:00
// Ticket #4450
2013-08-24 22:27:54 +02:00
const char code [ ] = " static int large_eeprom_type = (13 | (5)), "
" default_flash_type = 42; " ;
2018-10-20 10:51:50 +02:00
ASSERT_EQUALS ( " static int large_eeprom_type = 13 | 5 ; static int default_flash_type = 42 ; " ,
2013-08-24 22:27:54 +02:00
tokenizeAndStringify ( code ) ) ;
}
2013-10-30 15:48:00 +01:00
{
// 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 ; "
2015-08-27 14:34:00 +02:00
" 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 ; "
2013-10-30 15:48:00 +01:00
" void f ( ) { "
" unsigned int * foo ; "
" foo = & x ; "
" } " ,
tokenizeAndStringify ( code ) ) ;
}
2014-01-04 10:49:27 +01:00
{
// 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 ) ) ;
}
2009-07-06 11:45:14 +02:00
}
2014-11-20 14:20:09 +01:00
void vardecl6 ( ) {
2009-08-08 12:33:07 +02:00
// ticket #565
const char code1 [ ] = " int z = x >> 16; " ;
const char res1 [ ] = " int z ; z = x >> 16 ; " ;
ASSERT_EQUALS ( res1 , tokenizeAndStringify ( code1 ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl7 ( ) {
2009-08-23 08:26:16 +02:00
// ticket #603
2010-08-25 22:10:21 +02:00
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 "
2009-08-23 08:26:16 +02:00
" int t ; \n "
2010-08-25 22:10:21 +02:00
" D ( 3 > t , \" T \" ) ; \n "
" } " ;
2009-08-23 08:26:16 +02:00
ASSERT_EQUALS ( res , tokenizeAndStringify ( code ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl8 ( ) {
2009-09-20 12:28:15 +02:00
// ticket #696
const char code [ ] = " char a[10]={' \\ 0'}, b[10]={' \\ 0'}; " ;
2016-10-12 10:20:24 +02:00
const char res [ ] = " char a [ 10 ] = { ' \\ 0' } ; char b [ 10 ] = { ' \\ 0' } ; " ;
2009-09-20 12:28:15 +02:00
ASSERT_EQUALS ( res , tokenizeAndStringify ( code ) ) ;
}
2009-08-23 08:26:16 +02:00
2014-11-20 14:20:09 +01:00
void vardecl9 ( ) {
2009-09-20 13:28:56 +02:00
const char code [ ] = " char a[2] = {'A', ' \\ 0'}, b[2] = {'B', ' \\ 0'}; " ;
2016-10-12 10:20:24 +02:00
const char res [ ] = " char a [ 2 ] = { 'A' , ' \\ 0' } ; char b [ 2 ] = { 'B' , ' \\ 0' } ; " ;
2009-09-20 13:28:56 +02:00
ASSERT_EQUALS ( res , tokenizeAndStringify ( code ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl10 ( ) {
2009-09-26 12:02:13 +02:00
// ticket #732
const char code [ ] = " char a [ 2 ] = { '-' } ; memset ( a , '-' , sizeof ( a ) ) ; " ;
ASSERT_EQUALS ( code , tokenizeAndStringify ( code ) ) ;
2010-05-16 20:21:22 +02:00
}
2014-11-20 14:20:09 +01:00
void vardecl11 ( ) {
2010-05-16 20:21:22 +02:00
// ticket #1684
const char code [ ] = " char a[5][8], b[5][8]; " ;
ASSERT_EQUALS ( " char a [ 5 ] [ 8 ] ; char b [ 5 ] [ 8 ] ; " , tokenizeAndStringify ( code ) ) ;
2009-09-26 12:02:13 +02:00
}
2014-11-20 14:20:09 +01:00
void vardecl12 ( ) {
2010-08-25 20:17:31 +02:00
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 ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl13 ( ) {
2010-09-15 19:53:47 +02:00
const char code [ ] = " void f() { \n "
" int a = (x < y) ? 1 : 0; \n "
" } " ;
ASSERT_EQUALS ( " void f ( ) { \n int a ; a = ( x < y ) ? 1 : 0 ; \n } " , tokenizeAndStringify ( code ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl14 ( ) {
2011-03-25 04:06:20 +01:00
const char code [ ] = " ::std::tr1::shared_ptr<int> pNum1, pNum2; \n " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " :: std :: tr1 :: shared_ptr < int > pNum1 ; :: std :: tr1 :: shared_ptr < int > pNum2 ; " , tokenizeAndStringify ( code , false , Settings : : Native , " test.cpp " , false ) ) ;
2011-03-25 04:06:20 +01:00
}
2014-11-20 14:20:09 +01:00
void vardecl15 ( ) {
2012-01-30 23:41:43 +01:00
const char code [ ] = " const char x[] = \" foo \" , y[] = \" bar \" ; \n " ;
ASSERT_EQUALS ( " const char x [ 4 ] = \" foo \" ; const char y [ 4 ] = \" bar \" ; " , tokenizeAndStringify ( code ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl16 ( ) {
2012-11-05 00:33:02 +01:00
{
const char code [ ] = " const a::b<c,d(e),f>::g::h<i>::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<c,d(e),f>::g::h<i>::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 ) ) ;
}
2012-01-30 23:41:43 +01:00
}
2014-11-20 14:20:09 +01:00
void vardecl17 ( ) {
2012-01-30 23:41:43 +01:00
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 ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl18 ( ) {
2012-02-18 15:05:29 +01:00
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 ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl19 ( ) {
2012-04-03 19:48:58 +02:00
{
const char code [ ] = " void func(in, r, m) \n "
" int in; "
" int r,m; "
" { \n "
" } \n " ;
2012-03-31 18:45:29 +02:00
2012-04-03 19:48:58 +02:00
ASSERT_EQUALS ( " void func ( \n "
2020-12-08 10:35:13 +01:00
" int in , int r , int m \n "
" ) \n "
2012-04-03 19:48:58 +02:00
" { \n "
" } " , tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " void f(r,f) \n "
" char *r; \n "
" { \n "
" } \n " ;
ASSERT_EQUALS ( " void f ( \n "
2020-12-08 10:35:13 +01:00
" char * r \n "
" ) \n "
2012-04-03 19:48:58 +02:00
" \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 "
2020-12-08 10:35:13 +01:00
" char * r \n "
" ) \n "
2012-04-03 19:48:58 +02:00
" \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 "
2012-04-16 19:51:07 +02:00
" char * r , \n "
2020-12-08 10:35:13 +01:00
" char * s \n "
" ) \n "
2012-04-03 19:48:58 +02:00
" \n "
" \n "
" { \n "
" } " , tokenizeAndStringify ( code ) ) ;
}
2012-04-03 20:12:34 +02:00
{
const char code [ ] = " void f(r,s,t) \n "
" char *r,*s,*t; \n "
" { \n "
" } \n " ;
ASSERT_EQUALS ( " void f ( \n "
2020-12-08 10:35:13 +01:00
" char * r , char * s , char * t \n "
" ) \n "
2012-04-03 20:12:34 +02:00
" \n "
" { \n "
" } " , tokenizeAndStringify ( code ) ) ;
}
2012-04-13 00:39:40 +02:00
{
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 ) ) ;
}
2012-03-31 18:45:29 +02:00
}
2014-11-20 14:20:09 +01:00
void vardecl20 ( ) {
2012-04-09 12:55:26 +02:00
// #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 ) ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl21 ( ) { // type in namespace
2012-10-15 06:53:38 +02:00
// #4042 - a::b const *p = 0;
const char code1 [ ] = " void f() { \n "
" a::b const *p = 0; \n "
" } \n " ;
2012-09-14 16:46:45 +02:00
ASSERT_EQUALS ( " void f ( ) { \n "
2016-05-04 12:33:19 +02:00
" const a :: b * p ; p = 0 ; \n "
2012-09-14 16:46:45 +02:00
" } "
2012-10-15 06:53:38 +02:00
, 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 "
2016-05-04 12:33:19 +02:00
" const :: a :: b * p ; p = 0 ; \n "
2012-10-15 06:53:38 +02:00
" } "
, tokenizeAndStringify ( code2 ) ) ;
2012-09-14 16:46:45 +02:00
}
2014-11-20 14:20:09 +01:00
void vardecl22 ( ) { // #4211 - segmentation fault
2012-09-17 19:45:42 +02:00
tokenizeAndStringify ( " A<B<C<int>> >* p = 0; " ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl23 ( ) { // #4276 - segmentation fault
2017-12-29 22:47:07 +01:00
ASSERT_THROW ( tokenizeAndStringify ( " class a { protected : template < class int x = 1 ; public : int f ( ) ; } " ) , InternalError ) ;
2012-10-20 21:39:29 +02:00
}
2014-11-20 14:20:09 +01:00
void vardecl24 ( ) { // #4187 - variable declaration within lambda function
2013-05-12 10:19:43 +02:00
const char code1 [ ] = " void f() { \n "
" std::for_each(ints.begin(), ints.end(), [](int val) \n "
" { \n "
" int temp = 0; \n "
" }); \n "
" } " ;
2012-11-30 10:30:26 +01:00
2013-05-12 10:19:43 +02:00
const char expected1 [ ] = " void f ( ) { \n "
" std :: for_each ( ints . begin ( ) , ints . end ( ) , [ ] ( int val ) \n "
" { \n "
" int temp ; temp = 0 ; \n "
" } ) ; \n "
" } " ;
2012-11-30 10:30:26 +01:00
2013-05-12 10:19:43 +02:00
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 ) ) ;
2012-11-30 10:30:26 +01:00
}
2014-11-20 14:20:09 +01:00
void vardecl25 ( ) { // #4799 - segmentation fault
2013-05-14 20:56:31 +02:00
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 "
" } " ) ;
}
2014-11-20 14:20:09 +01:00
void vardecl26 ( ) { // #5907
2014-06-08 14:59:58 +02:00
const char code [ ] = " extern int *new, obj, player; " ;
const char expected [ ] = " extern int * new ; extern int obj ; extern int player ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code , true , Settings : : Native , " test.c " ) ) ;
2014-06-08 14:59:58 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
}
2017-01-06 21:16:28 +01:00
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 "
" } " ;
2021-08-07 20:51:18 +02:00
tokenizeAndStringify ( code , /*expand=*/ true , Settings : : Native , " test.c " ) ;
2017-01-06 21:16:28 +01:00
}
2021-06-06 08:13:40 +02:00
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 ( void ) { \n "
" const unsigned short x ; x = 1 ; \n "
" return x ; \n "
" } " ,
2021-08-07 20:51:18 +02:00
tokenizeAndStringify ( code , /*expand=*/ true , Settings : : Native , " test.c " ) ) ;
2021-06-06 08:13:40 +02:00
}
2014-11-20 14:20:09 +01:00
void volatile_variables ( ) {
2009-04-20 20:38:05 +02:00
const char code [ ] = " volatile int a=0; \n "
" volatile int b=0; \n "
" volatile int c=0; \n " ;
const std : : string actual ( tokenizeAndStringify ( code ) ) ;
2018-05-10 07:40:01 +02:00
ASSERT_EQUALS ( " volatile int a ; a = 0 ; \n volatile int b ; b = 0 ; \n volatile int c ; c = 0 ; " , actual ) ;
2009-04-20 20:38:05 +02:00
}
2009-05-07 22:17:29 +02:00
2014-05-14 22:27:31 +02:00
2014-11-20 14:20:09 +01:00
void simplifyKeyword ( ) {
2015-05-17 20:02:41 +02:00
{
const char code [ ] = " void f (int a [ static 5] ); " ;
ASSERT_EQUALS ( " void f ( int a [ 5 ] ) ; " , tokenizeAndStringify ( code ) ) ;
}
2015-05-17 13:02:13 +02:00
{
2021-08-07 20:51:18 +02:00
const char in4 [ ] = " struct B final : A { void foo(); }; " ;
const char out4 [ ] = " struct B : A { void foo ( ) ; } ; " ;
2015-05-17 20:02:41 +02:00
ASSERT_EQUALS ( out4 , tokenizeAndStringify ( in4 ) ) ;
2015-05-23 20:51:15 +02:00
2021-08-07 20:51:18 +02:00
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 [ ] =
2015-05-23 20:51:15 +02:00
" struct ArrayItemsValidator { \n "
2016-01-03 12:22:07 +01:00
" SchemaError validate ( ) const override { \n "
2015-05-23 20:51:15 +02:00
" for ( ; pos < value . size ( ) ; ++ pos ) { \n "
" } \n "
" return none ; \n "
" } \n "
" } ; " ;
ASSERT_EQUALS ( out5 , tokenizeAndStringify ( in5 ) ) ;
2015-05-17 20:02:41 +02:00
}
2018-08-26 19:46:36 +02:00
{
// Ticket #8679
const char code [ ] = " thread_local void *thread_local_var; "
" __thread void *thread_local_var_2; " ;
2019-03-27 12:22:53 +01:00
ASSERT_EQUALS ( " static void * thread_local_var ; "
2018-08-26 19:46:36 +02:00
" void * thread_local_var_2 ; " , tokenizeAndStringify ( code ) ) ;
}
2014-05-13 16:28:28 +02:00
}
2009-06-06 10:40:48 +02:00
2021-07-07 13:34:55 +02:00
void implicitIntConst ( ) {
ASSERT_EQUALS ( " const int x ; " , tokenizeAndStringify ( " const x; " ) ) ;
ASSERT_EQUALS ( " const int * x ; " , tokenizeAndStringify ( " const *x; " ) ) ;
ASSERT_EQUALS ( " const int * f ( ) ; " , tokenizeAndStringify ( " const *f(); " ) ) ;
}
void implicitIntExtern ( ) {
ASSERT_EQUALS ( " extern int x ; " , tokenizeAndStringify ( " extern x; " ) ) ;
ASSERT_EQUALS ( " extern int * x ; " , tokenizeAndStringify ( " extern *x; " ) ) ;
ASSERT_EQUALS ( " const int * f ( ) ; " , tokenizeAndStringify ( " const *f(); " ) ) ;
}
2009-09-28 20:25:05 +02:00
/**
2010-03-31 17:14:49 +02:00
* tokenize " signed i " = > " signed int i "
2009-09-28 20:25:05 +02:00
*/
2021-07-07 13:34:55 +02:00
void implicitIntSigned1 ( ) {
2009-09-28 20:25:05 +02:00
{
2010-03-31 17:14:49 +02:00
const char code1 [ ] = " void foo ( signed int , float ) ; " ;
ASSERT_EQUALS ( code1 , tokenizeAndStringify ( code1 ) ) ;
2009-09-28 20:25:05 +02:00
}
{
const char code1 [ ] = " signed i ; " ;
2010-03-31 17:14:49 +02:00
const char code2 [ ] = " signed int i ; " ;
2009-09-28 20:25:05 +02:00
ASSERT_EQUALS ( code2 , tokenizeAndStringify ( code1 ) ) ;
}
{
const char code1 [ ] = " signed int i ; " ;
2010-03-31 17:14:49 +02:00
ASSERT_EQUALS ( code1 , tokenizeAndStringify ( code1 ) ) ;
2009-09-28 20:25:05 +02:00
}
{
const char code1 [ ] = " int signed i ; " ;
2010-03-31 17:14:49 +02:00
const char code2 [ ] = " signed int i ; " ;
2009-09-28 20:25:05 +02:00
ASSERT_EQUALS ( code2 , tokenizeAndStringify ( code1 ) ) ;
}
{
2010-08-25 22:10:21 +02:00
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 ++ ) { } } " ;
2009-09-28 20:25:05 +02:00
ASSERT_EQUALS ( code2 , tokenizeAndStringify ( code1 ) ) ;
}
}
2009-06-06 10:40:48 +02:00
/**
* tokenize " unsigned i " = > " unsigned int i "
2010-03-31 17:14:49 +02:00
* tokenize " unsigned " = > " unsigned int "
2009-06-06 10:40:48 +02:00
*/
2021-07-07 13:34:55 +02:00
void implicitIntUnsigned1 ( ) {
2009-06-06 10:40:48 +02:00
// No changes..
{
2010-03-31 17:14:49 +02:00
const char code [ ] = " void foo ( unsigned int , float ) ; " ;
2009-06-06 10:40:48 +02:00
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 ) ) ;
}
2009-09-28 20:25:05 +02:00
{
const char code1 [ ] = " int unsigned i ; " ;
const char code2 [ ] = " unsigned int i ; " ;
ASSERT_EQUALS ( code2 , tokenizeAndStringify ( code1 ) ) ;
}
2009-08-05 20:15:48 +02:00
// insert "int" after "unsigned"..
{
2010-08-25 22:10:21 +02:00
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 ++ ) { } } " ;
2009-08-05 20:15:48 +02:00
ASSERT_EQUALS ( code2 , tokenizeAndStringify ( code1 ) ) ;
}
2010-03-20 08:03:18 +01:00
// "extern unsigned x;" => "extern int x;"
{
const char code1 [ ] = " ; extern unsigned x; " ;
2010-03-31 17:14:49 +02:00
const char code2 [ ] = " ; extern unsigned int x ; " ;
2010-03-20 08:03:18 +01:00
ASSERT_EQUALS ( code2 , tokenizeAndStringify ( code1 ) ) ;
}
2009-06-06 10:40:48 +02:00
}
2021-07-07 13:34:55 +02:00
void implicitIntUnsigned2 ( ) {
2009-11-17 19:03:23 +01:00
const char code [ ] = " i = (unsigned)j; " ;
const char expected [ ] = " i = ( unsigned int ) j ; " ;
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
}
2010-03-19 19:34:26 +01:00
// simplify "unsigned" when using templates..
2021-07-07 13:34:55 +02:00
void implicitIntUnsigned3 ( ) {
2010-03-19 19:34:26 +01:00
{
const char code [ ] = " ; foo<unsigned>(); " ;
2020-12-31 09:33:23 +01:00
const char expected [ ] = " ; foo < unsigned int > ( ) ; " ;
2010-03-19 19:34:26 +01:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " ; foo<unsigned int>(); " ;
2020-12-31 09:33:23 +01:00
const char expected [ ] = " ; foo < unsigned int > ( ) ; " ;
2010-03-19 19:34:26 +01:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
}
}
2014-11-20 14:20:09 +01:00
void simplifyStdType ( ) { // #4947, #4950, #4951
2013-08-12 06:23:01 +02:00
// usigned long long
2013-08-09 23:13:04 +02:00
{
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 ) ) ;
}
2013-08-12 06:23:01 +02:00
// 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 ) ) ;
}
// usigned 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 ) ) ;
}
2015-08-27 14:34:00 +02:00
{
const char code [ ] = " unsigned static short const int i; " ;
const char expected [ ] = " static const unsigned short i ; " ;
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
}
2015-08-26 13:13:45 +02:00
{
const char code [ ] = " float complex x; " ;
2015-08-27 14:34:00 +02:00
const char expected [ ] = " _Complex float x ; " ;
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " complex float x; " ;
const char expected [ ] = " _Complex float x ; " ;
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " complex long double x; " ;
const char expected [ ] = " _Complex long double x ; " ;
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " long double complex x; " ;
const char expected [ ] = " _Complex long double x ; " ;
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " double complex; " ;
const char expected [ ] = " double complex ; " ;
2015-08-26 13:13:45 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
}
2013-08-09 23:13:04 +02:00
}
2014-11-20 14:20:09 +01:00
void createLinks ( ) {
2009-09-20 22:13:06 +02:00
{
const char code [ ] = " class A{ \n "
" void f() {} \n "
" }; " ;
2010-12-01 18:00:55 +01:00
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2009-09-20 22:13:06 +02:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2009-09-20 22:13:06 +02:00
const Token * tok = tokenizer . tokens ( ) ;
// A body {}
2011-11-20 14:22:39 +01:00
ASSERT_EQUALS ( true , tok - > linkAt ( 2 ) = = tok - > tokAt ( 9 ) ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 9 ) = = tok - > tokAt ( 2 ) ) ;
2009-09-20 22:13:06 +02:00
// f body {}
2011-11-20 14:22:39 +01:00
ASSERT_EQUALS ( true , tok - > linkAt ( 7 ) = = tok - > tokAt ( 8 ) ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 8 ) = = tok - > tokAt ( 7 ) ) ;
2009-09-20 22:13:06 +02:00
// f ()
2011-11-20 14:22:39 +01:00
ASSERT_EQUALS ( true , tok - > linkAt ( 5 ) = = tok - > tokAt ( 6 ) ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 6 ) = = tok - > tokAt ( 5 ) ) ;
2012-03-21 18:40:32 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-20 22:13:06 +02:00
}
{
const char code [ ] = " void f(){ \n "
" char a[10]; \n "
" char *b ; b = new char[a[0]]; \n "
" }; " ;
2010-12-01 18:00:55 +01:00
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2009-09-20 22:13:06 +02:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2009-09-20 22:13:06 +02:00
const Token * tok = tokenizer . tokens ( ) ;
// a[10]
2011-11-20 14:22:39 +01:00
ASSERT_EQUALS ( true , tok - > linkAt ( 7 ) = = tok - > tokAt ( 9 ) ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 9 ) = = tok - > tokAt ( 7 ) ) ;
2009-09-20 22:13:06 +02:00
// new char[]
2011-11-20 14:22:39 +01:00
ASSERT_EQUALS ( true , tok - > linkAt ( 19 ) = = tok - > tokAt ( 24 ) ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 24 ) = = tok - > tokAt ( 19 ) ) ;
2009-09-20 22:13:06 +02:00
// a[0]
2011-11-20 14:22:39 +01:00
ASSERT_EQUALS ( true , tok - > linkAt ( 21 ) = = tok - > tokAt ( 23 ) ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 23 ) = = tok - > tokAt ( 21 ) ) ;
2012-03-21 18:40:32 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-20 22:13:06 +02:00
}
{
const char code [ ] = " void f(){ \n "
" foo(g()); \n "
" }; " ;
2010-12-01 18:00:55 +01:00
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2009-09-20 22:13:06 +02:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2009-09-20 22:13:06 +02:00
const Token * tok = tokenizer . tokens ( ) ;
// foo(
2011-11-20 14:22:39 +01:00
ASSERT_EQUALS ( true , tok - > linkAt ( 6 ) = = tok - > tokAt ( 10 ) ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 10 ) = = tok - > tokAt ( 6 ) ) ;
2009-09-20 22:13:06 +02:00
// g(
2011-11-20 14:22:39 +01:00
ASSERT_EQUALS ( true , tok - > linkAt ( 8 ) = = tok - > tokAt ( 9 ) ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 9 ) = = tok - > tokAt ( 8 ) ) ;
2012-03-21 18:40:32 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-09-20 22:13:06 +02:00
}
2012-03-20 19:00:16 +01:00
{
const char code [ ] = " bool foo(C<z> a, bar<int, x<float>>& f, int b) { \n "
" return(a<b && b>f); \n "
" } " ;
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2012-03-20 19:00:16 +01:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2012-03-20 19:00:16 +01:00
const Token * tok = tokenizer . tokens ( ) ;
// template<
2013-02-10 07:43:09 +01:00
ASSERT_EQUALS ( true , tok - > tokAt ( 6 ) = = tok - > linkAt ( 4 ) ) ;
ASSERT_EQUALS ( true , tok - > tokAt ( 4 ) = = tok - > linkAt ( 6 ) ) ;
2012-03-20 19:00:16 +01:00
// bar<
2013-02-10 07:43:09 +01:00
ASSERT_EQUALS ( true , tok - > tokAt ( 17 ) = = tok - > linkAt ( 10 ) ) ;
ASSERT_EQUALS ( true , tok - > tokAt ( 10 ) = = tok - > linkAt ( 17 ) ) ;
2012-03-20 19:00:16 +01:00
// x<
2013-02-10 07:43:09 +01:00
ASSERT_EQUALS ( true , tok - > tokAt ( 16 ) = = tok - > linkAt ( 14 ) ) ;
ASSERT_EQUALS ( true , tok - > tokAt ( 14 ) = = tok - > linkAt ( 16 ) ) ;
2012-03-20 19:00:16 +01:00
// a<b && b>f
2019-06-30 21:39:22 +02:00
ASSERT_EQUALS ( true , nullptr = = tok - > linkAt ( 28 ) ) ;
ASSERT_EQUALS ( true , nullptr = = tok - > linkAt ( 32 ) ) ;
2012-03-21 18:40:32 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " void foo() { \n "
" return static_cast<bar>(a); \n "
" } " ;
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2012-03-21 18:40:32 +01:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2012-03-21 18:40:32 +01:00
const Token * tok = tokenizer . tokens ( ) ;
// static_cast<
2013-02-10 07:43:09 +01:00
ASSERT_EQUALS ( true , tok - > tokAt ( 9 ) = = tok - > linkAt ( 7 ) ) ;
ASSERT_EQUALS ( true , tok - > tokAt ( 7 ) = = tok - > linkAt ( 9 ) ) ;
2012-03-21 18:40:32 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-03-20 19:00:16 +01:00
}
2012-09-09 15:31:23 +02:00
{
const char code [ ] = " void foo() { \n "
" nvwa<(x > y)> ERROR_nnn; \n "
" } " ;
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2012-09-09 15:31:23 +02:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2012-09-09 15:31:23 +02:00
const Token * tok = tokenizer . tokens ( ) ;
// nvwa<(x > y)>
2013-02-10 07:43:09 +01:00
ASSERT_EQUALS ( true , tok - > tokAt ( 12 ) = = tok - > linkAt ( 6 ) ) ;
ASSERT_EQUALS ( true , tok - > tokAt ( 6 ) = = tok - > linkAt ( 12 ) ) ;
2012-09-09 15:31:23 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2013-09-02 05:58:55 +02:00
{
// #4860
const char code [ ] = " class A : public B<int> {}; " ;
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2013-09-02 05:58:55 +02:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2013-09-02 05:58:55 +02:00
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 ( ) ) ;
}
2014-03-22 13:33:34 +01:00
{
// #4860
const char code [ ] = " Bar<Typelist< int, Typelist< int, Typelist< int, FooNullType>>>>::set(1, 2, 3); " ;
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2014-03-22 13:33:34 +01:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2014-03-22 13:33:34 +01:00
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 ( ) ) ;
}
2014-03-31 15:55:54 +02:00
{
// #5627
const char code [ ] = " new Foo<Bar>[10]; " ;
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2014-03-31 15:55:54 +02:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2014-03-31 15:55:54 +02:00
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 ( ) ) ;
}
2014-10-30 11:15:24 +01:00
{
// #6242
const char code [ ] = " func = integral_<uchar, int, double>; " ;
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2014-10-30 11:15:24 +01:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2014-10-30 11:15:24 +01:00
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 ( ) ) ;
}
2014-08-17 19:03:06 +02:00
{
// if (a < b || c > d) { }
2020-04-11 17:36:11 +02:00
const char code [ ] = " { if (a < b || c > d); } " ;
2014-08-17 19:03:06 +02:00
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2014-08-17 19:03:06 +02:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2014-08-17 19:03:06 +02:00
const Token * tok = tokenizer . tokens ( ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 3 ) = = nullptr ) ;
}
2015-11-06 10:44:37 +01:00
2019-05-21 08:47:10 +02:00
{
// 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 ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2019-05-21 08:47:10 +02:00
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 ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2019-05-21 08:47:10 +02:00
const Token * tok = tokenizer . tokens ( ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 1 ) = = tok - > tokAt ( 5 ) ) ;
}
2017-12-17 22:27:05 +01:00
{
// if (a < ... > d) { }
2020-04-11 17:36:11 +02:00
const char code [ ] = " { if (a < b || c == 3 || d > e); } " ;
2017-12-17 22:27:05 +01:00
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2017-12-17 22:27:05 +01:00
const Token * tok = tokenizer . tokens ( ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 3 ) = = nullptr ) ;
}
2017-12-17 15:53:05 +01:00
{
// template
const char code [ ] = " a<b==3 || c> d; " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2017-12-17 15:53:05 +01:00
const Token * tok = tokenizer . tokens ( ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 1 ) = = tok - > tokAt ( 7 ) ) ;
}
{
// template
const char code [ ] = " a<b || c==4> d; " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2017-12-17 15:53:05 +01:00
const Token * tok = tokenizer . tokens ( ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 1 ) = = tok - > tokAt ( 7 ) ) ;
}
2016-01-20 16:10:58 +01:00
{
const char code [ ] = " template < f = b || c > struct S; " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2016-01-20 16:10:58 +01:00
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<c&&d> {}; " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2016-01-20 16:10:58 +01:00
const Token * tok = tokenizer . tokens ( ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 4 ) = = tok - > tokAt ( 8 ) ) ;
ASSERT_EQUALS ( true , tok - > tokAt ( 4 ) = = tok - > linkAt ( 8 ) ) ;
}
2016-05-14 20:40:30 +02:00
{
2016-11-20 14:15:51 +01:00
const char code [ ] = " Data<T&&>; " ;
2016-05-14 20:40:30 +02:00
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2016-05-14 20:40:30 +02:00
const Token * tok = tokenizer . tokens ( ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 1 ) = = tok - > tokAt ( 4 ) ) ;
ASSERT_EQUALS ( true , tok - > tokAt ( 1 ) = = tok - > linkAt ( 4 ) ) ;
}
2015-11-06 10:44:37 +01:00
{
// #6601
const char code [ ] = " template<class R> struct FuncType<R(&)()> : FuncType<R()> { }; " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2015-11-06 10:44:37 +01:00
const Token * tok = tokenizer . tokens ( ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 1 ) = = tok - > tokAt ( 4 ) ) ; // <class R>
ASSERT_EQUALS ( true , tok - > linkAt ( 7 ) = = tok - > tokAt ( 14 ) ) ; // <R(&)()>
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 ) ) ; // <R()>
ASSERT_EQUALS ( true , tok - > linkAt ( 19 ) = = tok - > tokAt ( 20 ) ) ; // ()
ASSERT_EQUALS ( true , tok - > linkAt ( 22 ) = = tok - > tokAt ( 23 ) ) ; // {}
}
2009-09-20 22:13:06 +02:00
}
2009-10-01 19:45:48 +02:00
2016-08-01 22:26:11 +02:00
void createLinks2 ( ) {
2016-08-02 09:03:03 +02:00
{
// #7158
2016-08-01 22:26:11 +02:00
const char code [ ] = " enum { value = boost::mpl::at_c<B, C> }; " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2016-08-01 22:26:11 +02:00
const Token * tok = Token : : findsimplematch ( tokenizer . tokens ( ) , " < " ) ;
ASSERT_EQUALS ( true , tok - > link ( ) = = tok - > tokAt ( 4 ) ) ;
ASSERT_EQUALS ( true , tok - > linkAt ( 4 ) = = tok ) ;
}
2016-12-31 22:05:29 +01:00
{
// #7865
const char code [ ] = " template <typename T, typename U> \n "
" struct CheckedDivOp< T, U, typename std::enable_if<std::is_floating_point<T>::value || std::is_floating_point<U>::value>::type> { \n "
" }; \n " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2016-12-31 22:05:29 +01:00
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 ) ;
}
2017-04-03 21:48:22 +02:00
{
// #7975
const char code [ ] = " template <class C> X<Y&&Z, C*> copy() {}; \n " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2017-04-03 21:48:22 +02:00
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 ) ;
}
2017-05-23 18:55:17 +02:00
{
// #8006
const char code [ ] = " C<int> && a = b; " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2017-05-23 18:55:17 +02:00
const Token * tok1 = tokenizer . tokens ( ) - > next ( ) ;
const Token * tok2 = tok1 - > tokAt ( 2 ) ;
ASSERT_EQUALS ( true , tok1 - > link ( ) = = tok2 ) ;
ASSERT_EQUALS ( true , tok2 - > link ( ) = = tok1 ) ;
}
2017-07-09 13:26:59 +02:00
{
// #8115
const char code [ ] = " void Test(C<int> && c); " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2017-07-09 13:26:59 +02:00
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 ) ;
}
2018-09-05 14:10:56 +02:00
{
// #8654
const char code [ ] = " template<int N> struct A {}; "
" template<int... Ns> struct foo : A<Ns>... {}; " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2018-09-05 14:10:56 +02:00
const Token * A = Token : : findsimplematch ( tokenizer . tokens ( ) , " A < " ) ;
ASSERT_EQUALS ( true , A - > next ( ) - > link ( ) = = A - > tokAt ( 3 ) ) ;
}
2018-11-18 20:18:55 +01:00
{
// #8851
const char code [ ] = " template<typename std::enable_if<!(std::value1) && std::value2>::type> "
" void basic_json() {} " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2018-11-18 20:18:55 +01:00
ASSERT_EQUALS ( true , Token : : simpleMatch ( tokenizer . tokens ( ) - > next ( ) - > link ( ) , " > void " ) ) ;
}
2019-05-11 19:11:40 +02:00
{
2019-05-14 20:30:02 +02:00
// #9094 - template usage or comparison?
2019-05-11 19:11:40 +02:00
const char code [ ] = " a = f(x%x<--a==x>x); " ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2019-05-11 19:11:40 +02:00
ASSERT ( nullptr = = Token : : findsimplematch ( tokenizer . tokens ( ) , " < " ) - > link ( ) ) ;
}
2019-05-14 20:30:02 +02:00
{
// #9131 - template usage or comparison?
const char code [ ] = " using std::list; list<t *> l; " ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2019-05-14 20:30:02 +02:00
ASSERT ( nullptr ! = Token : : findsimplematch ( tokenizer . tokens ( ) , " < " ) - > link ( ) ) ;
}
2019-05-15 21:34:56 +02:00
{
const char code [ ] = " using std::set; \n "
" void foo() \n "
" { \n "
" for (set<ParticleSource*>::iterator i = sources.begin(); i != sources.end(); ++i) {} \n "
" } " ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2019-05-15 21:34:56 +02:00
ASSERT ( nullptr ! = Token : : findsimplematch ( tokenizer . tokens ( ) , " < " ) - > link ( ) ) ;
}
2019-05-19 10:05:34 +02:00
{
// #8890
const char code [ ] = " void f() { \n "
" a<> b; \n "
" b.a<>::c(); \n "
" } \n " ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2019-05-19 10:05:34 +02:00
ASSERT ( nullptr ! = Token : : findsimplematch ( tokenizer . tokens ( ) , " > :: " ) - > link ( ) ) ;
}
2019-05-19 19:06:12 +02:00
{
// #9136
const char code [ ] = " template <char> char * a; \n "
" template <char... b> struct c { \n "
" void d() { a<b...>[0]; } \n "
" }; \n " ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2019-05-19 19:06:12 +02:00
ASSERT ( nullptr ! = Token : : findsimplematch ( tokenizer . tokens ( ) , " > [ " ) - > link ( ) ) ;
}
2019-05-21 08:47:10 +02:00
{
// #9057
const char code [ ] = " template <bool> struct a; \n "
" template <bool b, typename> using c = typename a<b>::d; \n "
" template <typename e> using f = c<e() && sizeof(int), int>; \n "
" template <typename e, typename = f<e>> struct g {}; \n "
" template <typename e> using baz = g<e>; \n " ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2019-05-21 08:47:10 +02:00
ASSERT ( nullptr ! = Token : : findsimplematch ( tokenizer . tokens ( ) , " > ; " ) - > link ( ) ) ;
}
2019-05-27 06:50:43 +02:00
{
// #9141
const char code [ ] = " struct a { \n "
" typedef int b; \n "
" operator b(); \n "
" }; \n "
" template <int> using c = a; \n "
" template <int d> c<d> e; \n "
" auto f = -e<1> == 0; \n " ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2019-05-27 06:50:43 +02:00
ASSERT ( nullptr ! = Token : : findsimplematch ( tokenizer . tokens ( ) , " > == " ) - > link ( ) ) ;
}
2019-05-31 08:05:01 +02:00
{
// #9145
const char code [ ] = " template <typename a, a> struct b { \n "
" template <typename c> constexpr void operator()(c &&) const; \n "
" }; \n "
" template <int d> struct e { b<int, d> f; }; \n "
" template <int g> using h = e<g>; \n "
" template <int g> h<g> i; \n "
" template <typename a, a d> \n "
" template <typename c> \n "
" constexpr void b<a, d>::operator()(c &&) const { \n "
" i<3>.f([] {}); \n "
" } \n " ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2019-05-31 08:05:01 +02:00
ASSERT ( nullptr ! = Token : : findsimplematch ( tokenizer . tokens ( ) , " > . f ( " ) - > link ( ) ) ;
}
2021-09-22 13:03:46 +02:00
{
// #10491
const char code [ ] = " template <template <class> class> struct a; \n " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2021-09-22 13:03:46 +02:00
const Token * tok1 = Token : : findsimplematch ( tokenizer . tokens ( ) , " < class " ) ;
const Token * tok2 = Token : : findsimplematch ( tok1 , " > class " ) ;
ASSERT_EQUALS ( true , tok1 - > link ( ) = = tok2 ) ;
ASSERT_EQUALS ( true , tok2 - > link ( ) = = tok1 ) ;
}
{
// #10491
const char code [ ] = " template <template <class> class> struct a; \n " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2021-09-22 13:03:46 +02:00
const Token * tok1 = Token : : findsimplematch ( tokenizer . tokens ( ) , " < template " ) ;
const Token * tok2 = Token : : findsimplematch ( tok1 , " > struct " ) ;
ASSERT_EQUALS ( true , tok1 - > link ( ) = = tok2 ) ;
ASSERT_EQUALS ( true , tok2 - > link ( ) = = tok1 ) ;
}
2021-12-04 12:57:59 +01:00
2021-12-05 15:46:17 +01:00
{
// #10552
const char code [ ] = " v.value<QPair<int, int>>() \n " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
const Token * tok1 = Token : : findsimplematch ( tokenizer . tokens ( ) , " < QPair " ) ;
const Token * tok2 = Token : : findsimplematch ( tok1 , " > ( " ) ;
ASSERT_EQUALS ( true , tok1 - > link ( ) = = tok2 ) ;
ASSERT_EQUALS ( true , tok2 - > link ( ) = = tok1 ) ;
}
{
// #10552
const char code [ ] = " v.value<QPair<int, int>>() \n " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
const Token * tok1 = Token : : findsimplematch ( tokenizer . tokens ( ) , " < int " ) ;
const Token * tok2 = Token : : findsimplematch ( tok1 , " > > ( " ) ;
ASSERT_EQUALS ( true , tok1 - > link ( ) = = tok2 ) ;
ASSERT_EQUALS ( true , tok2 - > link ( ) = = tok1 ) ;
}
2021-12-04 12:57:59 +01:00
{
// #10615
const char code [ ] = " struct A : public B<__is_constructible()>{}; \n " ;
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 = Token : : findsimplematch ( tok1 , " > { } > " ) ;
ASSERT_EQUALS ( true , tok1 - > link ( ) = = tok2 ) ;
ASSERT_EQUALS ( true , tok2 - > link ( ) = = tok1 ) ;
}
2016-08-01 22:26:11 +02:00
}
2014-11-20 14:20:09 +01:00
void simplifyString ( ) {
2010-12-01 18:00:55 +01:00
errout . str ( " " ) ;
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2009-12-23 12:17:48 +01:00
ASSERT_EQUALS ( " \" abc \" " , tokenizer . simplifyString ( " \" abc \" " ) ) ;
2012-09-13 16:44:10 +02:00
ASSERT_EQUALS ( " \" \n \" " , tokenizer . simplifyString ( " \" \\ xa \" " ) ) ;
ASSERT_EQUALS ( " \" 3 \" " , tokenizer . simplifyString ( " \" \\ x33 \" " ) ) ;
ASSERT_EQUALS ( " \" 33 \" " , tokenizer . simplifyString ( " \" \\ x333 \" " ) ) ;
ASSERT_EQUALS ( " \" a \" " , tokenizer . simplifyString ( " \" \\ x61 \" " ) ) ;
ASSERT_EQUALS ( " \" \n 1 \" " , tokenizer . simplifyString ( " \" \\ 0121 \" " ) ) ;
ASSERT_EQUALS ( " \" 3 \" " , tokenizer . simplifyString ( " \" \\ x33 \" " ) ) ;
ASSERT_EQUALS ( " \" 0 \" " , tokenizer . simplifyString ( " \" \\ 0400 \" " ) ) ;
ASSERT_EQUALS ( " \" \\ nhello \" " , tokenizer . simplifyString ( " \" \\ nhello \" " ) ) ;
ASSERT_EQUALS ( " \" aaa \" " , tokenizer . simplifyString ( " \" \\ x61 \\ x61 \\ x61 \" " ) ) ;
ASSERT_EQUALS ( " \" \n 1 \n 1 \n 1 \" " , tokenizer . simplifyString ( " \" \\ 0121 \\ 0121 \\ 0121 \" " ) ) ;
ASSERT_EQUALS ( " \" \\ \\ x61 \" " , tokenizer . simplifyString ( " \" \\ \\ x61 \" " ) ) ;
ASSERT_EQUALS ( " \" b \" " , tokenizer . simplifyString ( " \" \\ x62 \" " ) ) ;
ASSERT_EQUALS ( " \" 7 \" " , tokenizer . simplifyString ( " \" \\ 0407 \" " ) ) ;
// terminate a string at null character.
2012-12-26 12:08:40 +01:00
ASSERT_EQUALS ( std : : string ( " \" a " ) + ' \0 ' + " \" " , tokenizer . simplifyString ( " \" a \\ 0 \" " ) ) ;
2009-10-09 21:11:29 +02:00
}
2014-11-20 14:20:09 +01:00
void simplifyConst ( ) {
2009-11-12 22:49:39 +01:00
ASSERT_EQUALS ( " void foo ( ) { const int x ; } " ,
tokenizeAndStringify ( " void foo(){ int const x;} " ) ) ;
ASSERT_EQUALS ( " void foo ( ) { { } const long x ; } " ,
tokenizeAndStringify ( " void foo(){ {} long const x;} " ) ) ;
2014-12-27 10:53:26 +01:00
ASSERT_EQUALS ( " void foo ( int b , const unsigned int x ) { } " ,
tokenizeAndStringify ( " void foo(int b,unsigned const x){} " ) ) ;
2009-11-12 22:49:39 +01:00
ASSERT_EQUALS ( " void foo ( ) { bar ( ) ; const char x ; } " ,
tokenizeAndStringify ( " void foo(){ bar(); char const x;} " ) ) ;
ASSERT_EQUALS ( " void foo ( const char x ) { } " ,
tokenizeAndStringify ( " void foo(char const x){} " ) ) ;
ASSERT_EQUALS ( " void foo ( int b , const char x ) { } " ,
tokenizeAndStringify ( " void foo(int b,char const x){} " ) ) ;
ASSERT_EQUALS ( " void foo ( ) { int * const x ; } " ,
tokenizeAndStringify ( " void foo(){ int * const x;} " ) ) ;
2011-12-04 16:46:03 +01:00
ASSERT_EQUALS ( " const int foo ( ) ; " , tokenizeAndStringify ( " int const foo (); " ) ) ;
2012-09-07 11:41:41 +02:00
ASSERT_EQUALS ( " const int x ; " , tokenizeAndStringify ( " int const x; " ) ) ;
2014-12-27 10:53:26 +01:00
ASSERT_EQUALS ( " const unsigned int x ; " , tokenizeAndStringify ( " unsigned const x; " ) ) ;
2012-09-07 11:41:41 +02:00
ASSERT_EQUALS ( " const struct X x ; " , tokenizeAndStringify ( " struct X const x; " ) ) ;
2009-11-12 22:49:39 +01:00
}
2009-12-06 23:09:56 +01:00
2014-11-20 14:20:09 +01:00
void switchCase ( ) {
2011-10-19 14:20:09 +02:00
ASSERT_EQUALS ( " void foo ( int i ) { switch ( i ) { case -1 : ; break ; } } " ,
2009-12-06 23:09:56 +01:00
tokenizeAndStringify ( " void foo (int i) { switch(i) { case -1: break; } } " ) ) ;
2011-10-19 14:20:09 +02:00
//ticket #3227
ASSERT_EQUALS ( " void foo ( ) { switch ( n ) { label : ; case 1 : ; label1 : ; label2 : ; break ; } } " ,
tokenizeAndStringify ( " void foo(){ switch (n){ label: case 1: label1: label2: break; }} " ) ) ;
2018-01-27 22:21:26 +01:00
//ticket #8345
ASSERT_EQUALS ( " void foo ( ) { switch ( 0 ) { case 0 : ; default : ; } } " ,
tokenizeAndStringify ( " void foo () { switch(0) case 0 : default : ; } " ) ) ;
2018-04-08 08:00:12 +02:00
//ticket #8477
ASSERT_EQUALS ( " void foo ( ) { enum Anonymous0 : int { Six = 6 } ; return Six ; } " ,
tokenizeAndStringify ( " void foo () { enum : int { Six = 6 } ; return Six ; } " ) ) ;
2018-04-26 22:26:26 +02:00
// ticket #8281
tokenizeAndStringify ( " void lzma_decode(int i) { "
" bool state; "
" switch (i) "
" while (true) { "
" state=false; "
" case 1: "
" ; "
" } "
" } " ) ;
// ticket #8417
tokenizeAndStringify ( " void printOwnedAttributes(int mode) { "
" switch(mode) case 0: { break; } "
" } " ) ;
ASSERT_THROW ( tokenizeAndStringify ( " void printOwnedAttributes(int mode) { "
" switch(mode) case 0: { break; } case 1: ; "
" } " ) ,
InternalError ) ;
2009-12-06 23:09:56 +01:00
}
2010-01-20 21:19:06 +01:00
2014-11-20 14:20:09 +01:00
void simplifyPointerToStandardType ( ) {
2011-10-16 08:09:57 +02:00
// Pointer to standard type
ASSERT_EQUALS ( " char buf [ 100 ] ; readlink ( path , buf , 99 ) ; " ,
tokenizeAndStringify ( " char buf[100] ; readlink(path, &buf[0], 99); " ,
2021-04-06 21:21:53 +02:00
true , Settings : : Native , " test.c " ) ) ;
2011-10-16 08:09:57 +02:00
2017-10-16 17:39:50 +02:00
ASSERT_EQUALS ( " void foo ( char * c ) { if ( 1 == ( 1 & c [ 0 ] ) ) { } } " ,
tokenizeAndStringify ( " void foo(char *c) { if (1==(1 & c[0])) {} } " ,
2021-04-06 21:21:53 +02:00
true , Settings : : Native , " test.c " ) ) ;
2017-10-16 17:39:50 +02:00
2011-10-16 08:09:57 +02:00
// Simplification of unknown type - C only
ASSERT_EQUALS ( " foo data [ 100 ] ; something ( foo ) ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " foo data[100]; something(&foo[0]); " , true , Settings : : Native , " test.c " ) ) ;
2011-10-16 08:09:57 +02:00
// C++: No pointer simplification
ASSERT_EQUALS ( " foo data [ 100 ] ; something ( & foo [ 0 ] ) ; " ,
tokenizeAndStringify ( " foo data[100]; something(&foo[0]); " ) ) ;
}
2021-04-18 12:32:31 +02:00
void simplifyFunctionPointers1 ( ) {
2020-04-10 11:53:32 +02:00
ASSERT_EQUALS ( " void ( * f ) ( ) ; " , tokenizeAndStringify ( " void (*f)(); " ) ) ;
ASSERT_EQUALS ( " void * ( * f ) ( ) ; " , tokenizeAndStringify ( " void *(*f)(); " ) ) ;
ASSERT_EQUALS ( " unsigned int ( * f ) ( ) ; " , tokenizeAndStringify ( " unsigned int (*f)(); " ) ) ;
ASSERT_EQUALS ( " unsigned int * ( * f ) ( ) ; " , tokenizeAndStringify ( " unsigned int * (*f)(); " ) ) ;
2021-11-08 20:31:45 +01:00
ASSERT_EQUALS ( " void ( * f [ 2 ] ) ( ) ; " , tokenizeAndStringify ( " void (*f[2])(); " ) ) ;
TODO_ASSERT_EQUALS ( " void ( * f [ 2 ] ) ( ) ; " , " void ( * f ) ( ) [ 2 ] ; " , tokenizeAndStringify ( " typedef void func_t(void); func_t *f[2]; " ) ) ;
2010-01-20 21:19:06 +01:00
}
2010-01-31 09:33:57 +01:00
2021-04-18 12:32:31 +02:00
void simplifyFunctionPointers2 ( ) {
2011-03-19 21:21:26 +01:00
const char code [ ] = " typedef void (* PF)(); "
" void f1 ( ) { } "
" PF pf = &f1; "
" PF pfs[] = { &f1, &f1 }; " ;
2012-04-16 19:51:07 +02:00
const char expected [ ] = " void f1 ( ) { } "
2020-04-10 11:53:32 +02:00
" void ( * pf ) ( ) ; pf = & f1 ; "
2020-04-13 16:28:01 +02:00
" void ( * pfs [ ] ) ( ) = { & f1 , & f1 } ; " ;
2015-10-07 18:33:57 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2011-03-19 21:21:26 +01:00
}
2021-04-18 12:32:31 +02:00
void simplifyFunctionPointers3 ( ) {
2011-07-22 07:58:53 +02:00
// Related with ticket #2873
const char code [ ] = " void f() { \n "
" (void)(xy(*p)(0);) "
" \n } " ;
2015-10-07 18:33:57 +02:00
const char expected [ ] = " void f ( ) { \n "
" ( void ) ( xy ( * p ) ( 0 ) ; ) \n "
2011-07-22 07:58:53 +02:00
" } " ;
2015-10-07 18:33:57 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2011-07-22 07:58:53 +02:00
}
2021-04-18 12:32:31 +02:00
void simplifyFunctionPointers4 ( ) {
2014-04-02 17:33:04 +02:00
const char code [ ] = " struct S \n "
2011-11-10 21:32:37 +01:00
" { \n "
" typedef void (*FP)(); \n "
" virtual FP getFP(); \n "
2020-04-10 11:53:32 +02:00
" }; " ;
2016-07-18 10:52:38 +02:00
const char expected [ ] = " 1: struct S \n "
2011-11-10 21:32:37 +01:00
" 2: { \n "
2011-12-04 15:40:05 +01:00
" 3: \n "
2014-04-12 16:06:31 +02:00
" 4: virtual void * getFP ( ) ; \n "
2020-04-10 11:53:32 +02:00
" 5: } ; \n " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeDebugListing ( code ) ) ;
2011-11-09 21:02:41 +01:00
}
2021-04-18 12:32:31 +02:00
void simplifyFunctionPointers5 ( ) {
2011-12-27 11:56:40 +01:00
const char code [ ] = " ;void (*fp[])(int a) = {0,0,0}; " ;
2020-04-10 11:53:32 +02:00
const char expected [ ] = " 1: ; void ( * fp@1 [ ] ) ( ) = { 0 , 0 , 0 } ; \n " ; // TODO: Array dimension
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeDebugListing ( code ) ) ;
2011-12-27 11:56:40 +01:00
}
2021-04-18 12:32:31 +02:00
void simplifyFunctionPointers6 ( ) {
2020-04-10 11:53:32 +02:00
const char code1 [ ] = " void (*fp(void))(int) {} " ;
2021-03-25 08:25:43 +01:00
const char expected1 [ ] = " 1: void * fp ( void ) { } \n " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected1 , tokenizeDebugListing ( code1 ) ) ;
2014-04-12 16:06:31 +02:00
2020-04-10 11:53:32 +02:00
const char code2 [ ] = " std::string (*fp(void))(int); " ;
2021-03-25 08:25:43 +01:00
const char expected2 [ ] = " 1: std :: string * fp ( void ) ; \n " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected2 , tokenizeDebugListing ( code2 ) ) ;
2014-04-12 16:06:31 +02:00
}
2021-04-18 12:32:31 +02:00
void simplifyFunctionPointers7 ( ) {
2014-04-27 19:49:21 +02:00
const char code1 [ ] = " void (X::*y)(); " ;
2020-04-10 11:53:32 +02:00
const char expected1 [ ] = " 1: void ( * y@1 ) ( ) ; \n " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected1 , tokenizeDebugListing ( code1 ) ) ;
2014-04-27 19:49:21 +02:00
}
2021-04-18 12:32:31 +02:00
void simplifyFunctionPointers8 ( ) {
2016-02-29 08:02:02 +01:00
const char code1 [ ] = " int (*f)() throw(int); " ;
2020-04-10 11:53:32 +02:00
const char expected1 [ ] = " 1: int ( * f@1 ) ( ) ; \n " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected1 , tokenizeDebugListing ( code1 ) ) ;
2016-02-29 08:02:02 +01:00
}
2021-04-18 12:32:31 +02:00
void simplifyFunctionPointers9 ( ) { // function call with function pointer
2016-08-04 19:10:08 +02:00
const char code1 [ ] = " int f() { (*f)(); } " ;
const char expected1 [ ] = " 1: int f ( ) { ( * f ) ( ) ; } \n " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected1 , tokenizeDebugListing ( code1 ) ) ;
2016-08-04 19:10:08 +02:00
const char code2 [ ] = " int f() { return (*f)(); } " ;
const char expected2 [ ] = " 1: int f ( ) { return ( * f ) ( ) ; } \n " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected2 , tokenizeDebugListing ( code2 ) ) ;
2016-08-04 19:10:08 +02:00
const char code3 [ ] = " int f() { throw (*f)(); } " ;
const char expected3 [ ] = " 1: int f ( ) { throw ( * f ) ( ) ; } \n " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected3 , tokenizeDebugListing ( code3 ) ) ;
2010-01-31 09:33:57 +01:00
}
2010-02-03 20:01:56 +01:00
2014-11-20 14:20:09 +01:00
void removedeclspec ( ) {
2010-02-03 20:01:56 +01:00
ASSERT_EQUALS ( " a b " , tokenizeAndStringify ( " a __declspec ( dllexport ) b " ) ) ;
2015-04-11 11:02:30 +02:00
ASSERT_EQUALS ( " a b " , tokenizeAndStringify ( " a _declspec ( dllexport ) b " ) ) ;
2010-04-24 09:40:05 +02:00
ASSERT_EQUALS ( " int a ; " , tokenizeAndStringify ( " __declspec(thread) __declspec(align(32)) int a; " ) ) ;
ASSERT_EQUALS ( " int i ; " , tokenizeAndStringify ( " __declspec(allocate( \" mycode \" )) int i; " ) ) ;
ASSERT_EQUALS ( " struct IUnknown ; " , tokenizeAndStringify ( " struct __declspec(uuid( \" 00000000-0000-0000-c000-000000000046 \" )) IUnknown; " ) ) ;
2014-08-31 20:17:18 +02:00
ASSERT_EQUALS ( " __property int x [ ] ; " , tokenizeAndStringify ( " __declspec(property(get=GetX, put=PutX)) int x[]; " ) ) ;
2010-02-03 20:01:56 +01:00
}
2010-02-08 23:16:12 +01:00
2014-11-20 14:20:09 +01:00
void removeattribute ( ) {
2010-05-27 18:15:42 +02:00
ASSERT_EQUALS ( " short array [ 3 ] ; " , tokenizeAndStringify ( " short array[3] __attribute__ ((aligned)); " ) ) ;
ASSERT_EQUALS ( " int x [ 2 ] ; " , tokenizeAndStringify ( " int x[2] __attribute__ ((packed)); " ) ) ;
2011-04-24 03:04:02 +02:00
ASSERT_EQUALS ( " int vecint ; " , tokenizeAndStringify ( " int __attribute__((mode(SI))) __attribute__((vector_size (16))) vecint; " ) ) ;
2014-03-19 05:38:23 +01:00
// alternate spelling #5328
ASSERT_EQUALS ( " short array [ 3 ] ; " , tokenizeAndStringify ( " short array[3] __attribute ((aligned)); " ) ) ;
ASSERT_EQUALS ( " int x [ 2 ] ; " , tokenizeAndStringify ( " int x[2] __attribute ((packed)); " ) ) ;
ASSERT_EQUALS ( " int vecint ; " , tokenizeAndStringify ( " int __attribute((mode(SI))) __attribute((vector_size (16))) vecint; " ) ) ;
2016-05-04 13:51:34 +02:00
ASSERT_EQUALS ( " struct Payload_IR_config { uint8_t tap [ 16 ] ; } ; " , tokenizeAndStringify ( " struct __attribute__((packed, gcc_struct)) Payload_IR_config { uint8_t tap[16]; }; " ) ) ;
2010-05-27 18:15:42 +02:00
}
2021-06-26 14:23:39 +02:00
void functionAttributeBefore1 ( ) {
2014-04-20 20:40:55 +02:00
const char code [ ] = " void __attribute__((pure)) __attribute__((nothrow)) __attribute__((const)) func1(); \n "
" void __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__)) func2(); \n "
" void __attribute__((nothrow)) __attribute__((pure)) __attribute__((const)) func3(); \n "
2014-12-24 12:50:51 +01:00
" void __attribute__((__nothrow__)) __attribute__((__pure__)) __attribute__((__const__)) func4(); \n "
" void __attribute__((noreturn)) func5(); " ;
const char expected [ ] = " void func1 ( ) ; void func2 ( ) ; void func3 ( ) ; void func4 ( ) ; void func5 ( ) ; " ;
2014-04-20 20:40:55 +02:00
errout . str ( " " ) ;
// tokenize..
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2014-04-20 20:40:55 +02:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2014-04-20 20:40:55 +02:00
// Expected result..
2019-06-30 21:39:22 +02:00
ASSERT_EQUALS ( expected , tokenizer . tokens ( ) - > stringifyList ( nullptr , false ) ) ;
2014-04-20 20:40:55 +02:00
const Token * func1 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func1 " ) ;
const Token * func2 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func2 " ) ;
const Token * func3 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func3 " ) ;
const Token * func4 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func4 " ) ;
2014-12-24 12:50:51 +01:00
const Token * func5 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func5 " ) ;
2014-04-20 20:40:55 +02:00
ASSERT ( func1 & & func1 - > isAttributePure ( ) & & func1 - > isAttributeNothrow ( ) & & func1 - > isAttributeConst ( ) ) ;
ASSERT ( func2 & & func2 - > isAttributePure ( ) & & func2 - > isAttributeNothrow ( ) & & func2 - > isAttributeConst ( ) ) ;
ASSERT ( func3 & & func3 - > isAttributePure ( ) & & func3 - > isAttributeNothrow ( ) & & func3 - > isAttributeConst ( ) ) ;
ASSERT ( func4 & & func4 - > isAttributePure ( ) & & func4 - > isAttributeNothrow ( ) & & func4 - > isAttributeConst ( ) ) ;
2014-12-24 12:50:51 +01:00
ASSERT ( func5 & & func5 - > isAttributeNoreturn ( ) ) ;
2014-04-20 20:40:55 +02:00
}
2021-06-26 14:23:39 +02:00
void functionAttributeBefore2 ( ) {
const char code [ ] = " extern vas_f *VAS_Fail __attribute__((__noreturn__)); " ;
const char expected [ ] = " extern vas_f * VAS_Fail ; " ;
errout . str ( " " ) ;
// tokenize..
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2021-06-26 14:23:39 +02:00
ASSERT_EQUALS ( expected , tokenizer . tokens ( ) - > stringifyList ( nullptr , false ) ) ;
const Token * VAS_Fail = Token : : findsimplematch ( tokenizer . tokens ( ) , " VAS_Fail " ) ;
ASSERT ( VAS_Fail & & VAS_Fail - > isAttributeNoreturn ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void functionAttributeAfter ( ) {
2014-04-20 20:40:55 +02:00
const char code [ ] = " void func1() __attribute__((pure)) __attribute__((nothrow)) __attribute__((const)); \n "
" void func2() __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__)); \n "
" void func3() __attribute__((nothrow)) __attribute__((pure)) __attribute__((const)); \n "
2014-12-24 12:50:51 +01:00
" void func4() __attribute__((__nothrow__)) __attribute__((__pure__)) __attribute__((__const__)); "
" void func5() __attribute__((noreturn)); " ;
const char expected [ ] = " void func1 ( ) ; void func2 ( ) ; void func3 ( ) ; void func4 ( ) ; void func5 ( ) ; " ;
2014-04-20 20:40:55 +02:00
errout . str ( " " ) ;
// tokenize..
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2014-04-20 20:40:55 +02:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2014-04-20 20:40:55 +02:00
// Expected result..
2019-06-30 21:39:22 +02:00
ASSERT_EQUALS ( expected , tokenizer . tokens ( ) - > stringifyList ( nullptr , false ) ) ;
2014-04-20 20:40:55 +02:00
const Token * func1 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func1 " ) ;
const Token * func2 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func2 " ) ;
const Token * func3 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func3 " ) ;
const Token * func4 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func4 " ) ;
2014-12-24 12:50:51 +01:00
const Token * func5 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func5 " ) ;
2014-04-20 20:40:55 +02:00
ASSERT ( func1 & & func1 - > isAttributePure ( ) & & func1 - > isAttributeNothrow ( ) & & func1 - > isAttributeConst ( ) ) ;
ASSERT ( func2 & & func2 - > isAttributePure ( ) & & func2 - > isAttributeNothrow ( ) & & func2 - > isAttributeConst ( ) ) ;
ASSERT ( func3 & & func3 - > isAttributePure ( ) & & func3 - > isAttributeNothrow ( ) & & func3 - > isAttributeConst ( ) ) ;
ASSERT ( func4 & & func4 - > isAttributePure ( ) & & func4 - > isAttributeNothrow ( ) & & func4 - > isAttributeConst ( ) ) ;
2014-12-24 12:50:51 +01:00
ASSERT ( func5 & & func5 - > isAttributeNoreturn ( ) ) ;
2014-04-20 20:40:55 +02:00
}
2021-05-01 07:33:55 +02:00
void functionAttributeListBefore ( ) {
const char code [ ] = " void __attribute__((pure,nothrow,const)) func1(); \n "
" void __attribute__((__pure__,__nothrow__,__const__)) func2(); \n "
" void __attribute__((nothrow,pure,const)) func3(); \n "
" void __attribute__((__nothrow__,__pure__,__const__)) func4(); \n "
" void __attribute__((noreturn,format(printf,1,2))) func5(); \n "
" void __attribute__((__nothrow__)) __attribute__((__pure__,__const__)) func6(); \n "
" void __attribute__((__nothrow__,__pure__)) __attribute__((__const__)) func7(); \n "
" void __attribute__((noreturn)) __attribute__(()) __attribute__((nothrow,pure,const)) func8(); " ;
const char expected [ ] = " void func1 ( ) ; void func2 ( ) ; void func3 ( ) ; void func4 ( ) ; void func5 ( ) ; "
" void func6 ( ) ; void func7 ( ) ; void func8 ( ) ; " ;
errout . str ( " " ) ;
// tokenize..
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2021-05-01 07:33:55 +02:00
// Expected result..
ASSERT_EQUALS ( expected , tokenizer . tokens ( ) - > stringifyList ( nullptr , false ) ) ;
const Token * func1 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func1 " ) ;
const Token * func2 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func2 " ) ;
const Token * func3 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func3 " ) ;
const Token * func4 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func4 " ) ;
const Token * func5 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func5 " ) ;
const Token * func6 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func6 " ) ;
const Token * func7 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func7 " ) ;
const Token * func8 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func8 " ) ;
ASSERT ( func1 & & func1 - > isAttributePure ( ) & & func1 - > isAttributeNothrow ( ) & & func1 - > isAttributeConst ( ) ) ;
ASSERT ( func2 & & func2 - > isAttributePure ( ) & & func2 - > isAttributeNothrow ( ) & & func2 - > isAttributeConst ( ) ) ;
ASSERT ( func3 & & func3 - > isAttributePure ( ) & & func3 - > isAttributeNothrow ( ) & & func3 - > isAttributeConst ( ) ) ;
ASSERT ( func4 & & func4 - > isAttributePure ( ) & & func4 - > isAttributeNothrow ( ) & & func4 - > isAttributeConst ( ) ) ;
ASSERT ( func5 & & func5 - > isAttributeNoreturn ( ) ) ;
ASSERT ( func6 & & func6 - > isAttributePure ( ) & & func6 - > isAttributeNothrow ( ) & & func6 - > isAttributeConst ( ) ) ;
ASSERT ( func7 & & func7 - > isAttributePure ( ) & & func7 - > isAttributeNothrow ( ) & & func7 - > isAttributeConst ( ) ) ;
2021-05-01 07:35:03 +02:00
ASSERT ( func8 & & func8 - > isAttributeNoreturn ( ) & & func8 - > isAttributePure ( ) & & func8 - > isAttributeNothrow ( ) & & func8 - > isAttributeConst ( ) ) ;
2021-05-01 07:33:55 +02:00
}
void functionAttributeListAfter ( ) {
const char code [ ] = " void func1() __attribute__((pure,nothrow,const)); \n "
" void func2() __attribute__((__pure__,__nothrow__,__const__)); \n "
" void func3() __attribute__((nothrow,pure,const)); \n "
" void func4() __attribute__((__nothrow__,__pure__,__const__)); \n "
" void func5() __attribute__((noreturn,format(printf,1,2))); \n "
" void func6() __attribute__((__nothrow__)) __attribute__((__pure__,__const__)); \n "
" void func7() __attribute__((__nothrow__,__pure__)) __attribute__((__const__)); \n "
" void func8() __attribute__((noreturn)) __attribute__(()) __attribute__((nothrow,pure,const)); " ;
const char expected [ ] = " void func1 ( ) ; void func2 ( ) ; void func3 ( ) ; void func4 ( ) ; void func5 ( ) ; "
" void func6 ( ) ; void func7 ( ) ; void func8 ( ) ; " ;
errout . str ( " " ) ;
// tokenize..
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2021-05-01 07:33:55 +02:00
// Expected result..
ASSERT_EQUALS ( expected , tokenizer . tokens ( ) - > stringifyList ( nullptr , false ) ) ;
const Token * func1 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func1 " ) ;
const Token * func2 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func2 " ) ;
const Token * func3 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func3 " ) ;
const Token * func4 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func4 " ) ;
const Token * func5 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func5 " ) ;
const Token * func6 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func6 " ) ;
const Token * func7 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func7 " ) ;
const Token * func8 = Token : : findsimplematch ( tokenizer . tokens ( ) , " func8 " ) ;
ASSERT ( func1 & & func1 - > isAttributePure ( ) & & func1 - > isAttributeNothrow ( ) & & func1 - > isAttributeConst ( ) ) ;
ASSERT ( func2 & & func2 - > isAttributePure ( ) & & func2 - > isAttributeNothrow ( ) & & func2 - > isAttributeConst ( ) ) ;
ASSERT ( func3 & & func3 - > isAttributePure ( ) & & func3 - > isAttributeNothrow ( ) & & func3 - > isAttributeConst ( ) ) ;
ASSERT ( func4 & & func4 - > isAttributePure ( ) & & func4 - > isAttributeNothrow ( ) & & func4 - > isAttributeConst ( ) ) ;
ASSERT ( func5 & & func5 - > isAttributeNoreturn ( ) ) ;
ASSERT ( func6 & & func6 - > isAttributePure ( ) & & func6 - > isAttributeNothrow ( ) & & func6 - > isAttributeConst ( ) ) ;
ASSERT ( func7 & & func7 - > isAttributePure ( ) & & func7 - > isAttributeNothrow ( ) & & func7 - > isAttributeConst ( ) ) ;
2021-05-01 07:35:03 +02:00
ASSERT ( func8 & & func8 - > isAttributeNoreturn ( ) & & func8 - > isAttributePure ( ) & & func8 - > isAttributeNothrow ( ) & & func8 - > isAttributeConst ( ) ) ;
2021-05-01 07:33:55 +02:00
}
2020-11-29 16:07:56 +01:00
void splitTemplateRightAngleBrackets ( ) {
2020-11-29 12:56:13 +01:00
{
2020-12-02 20:21:32 +01:00
const char code [ ] = " ; z = x < 0 ? x >> y : x >> y; " ;
2020-11-29 12:56:13 +01:00
ASSERT_EQUALS ( " ; z = x < 0 ? x >> y : x >> y ; " , tokenizeAndStringify ( code ) ) ;
}
2020-12-02 20:21:32 +01:00
{
// ftp://ftp.de.debian.org/debian/pool/main/f/ffmpeg/ffmpeg_4.3.1.orig.tar.xz
// ffmpeg-4.3.1/libavcodec/mpeg4videodec.c:376
const char code [ ] = " void f ( ) { \n "
" int shift_y = ctx->sprite_shift[0]; \n "
" int shift_c = ctx->sprite_shift[1]; \n "
" if ( shift_c < 0 || shift_y < 0 || \n "
" FFABS ( sprite_offset [ 0 ] [ i ] ) >= INT_MAX >> shift_y || \n "
" FFABS ( sprite_offset [ 1 ] [ i ] ) >= INT_MAX >> shift_c || \n "
" FFABS ( sprite_delta [ 0 ] [ i ] ) >= INT_MAX >> shift_y || \n "
" FFABS ( sprite_delta [ 1 ] [ i ] ) >= INT_MAX >> shift_y ) ; \n "
" } " ;
ASSERT_EQUALS ( std : : string : : npos , tokenizeAndStringify ( code ) . find ( " > > " ) ) ;
}
2020-11-29 12:56:13 +01:00
}
2015-10-19 20:03:33 +02:00
void cpp03template1 ( ) {
{
const char * code = " template<typename> struct extent {}; " ;
ASSERT_EQUALS ( " template < typename > struct extent { } ; " , tokenizeAndStringify ( code ) ) ;
}
{
const char * code = " template<typename> struct extent; " ;
ASSERT_EQUALS ( " template < typename > struct extent ; " , tokenizeAndStringify ( code ) ) ;
}
{
const char * code = " template<typename, unsigned = 0> struct extent; " ;
ASSERT_EQUALS ( " template < typename , unsigned int = 0 > struct extent ; " , tokenizeAndStringify ( code ) ) ;
}
}
2014-11-20 14:20:09 +01:00
void cpp0xtemplate1 ( ) {
2010-02-08 23:16:12 +01:00
const char * code = " template <class T> \n "
" void fn2 (T t = []{return 1;}()) \n "
" {} \n "
" int main() \n "
" { \n "
" fn2<int>(); \n "
" } \n " ;
2018-11-23 11:36:09 +01:00
ASSERT_EQUALS ( " void fn2<int> ( int t = [ ] { return 1 ; } ( ) ) ; \n "
" \n "
" int main ( ) \n "
" { \n "
" fn2<int> ( ) ; \n "
2020-12-08 10:35:13 +01:00
" } \n "
" void fn2<int> ( int t = [ ] { return 1 ; } ( ) ) \n "
2018-11-23 11:36:09 +01:00
" { } " , tokenizeAndStringify ( code ) ) ;
2010-02-08 23:16:12 +01:00
}
2010-08-17 19:50:21 +02:00
2014-11-20 14:20:09 +01:00
void cpp0xtemplate2 ( ) {
2010-09-05 08:16:19 +02:00
// tokenize ">>" into "> >"
const char * code = " list<list<int>> ints; \n " ;
2012-03-20 19:00:16 +01:00
ASSERT_EQUALS ( " list < list < int > > ints ; " , tokenizeAndStringify ( code ) ) ;
2010-09-05 08:16:19 +02:00
}
2014-11-20 14:20:09 +01:00
void cpp0xtemplate3 ( ) {
2011-02-12 16:51:59 +01:00
// #2549
const char * code = " template<class T, T t = (T)0> \n "
" struct S \n "
" {}; \n "
" S<int> s; \n " ;
2019-06-01 10:52:29 +02:00
ASSERT_EQUALS ( " struct S<int,(int)0> ; \n "
" \n "
" \n "
2020-12-08 10:35:13 +01:00
" S<int,(int)0> s ; \n "
" struct S<int,(int)0> \n "
2019-06-01 10:52:29 +02:00
" { } ; " ,
tokenizeAndStringify ( code ) ) ;
2011-02-12 16:51:59 +01:00
}
2015-02-14 12:29:05 +01:00
void cpp0xtemplate4 ( ) { // #6181, #6354, #6414
2015-03-07 11:06:04 +01:00
tokenizeAndStringify ( " class A; "
" template <class T> class Disposer; "
" template <typename T, class D = Disposer<T>> class Shim {}; "
" class B : public Shim<A> {}; " ) ;
2015-02-14 12:29:05 +01:00
tokenizeAndStringify ( " template <class ELFT> class ELFObjectImage {}; "
" ObjectImage *createObjectImage() { "
" return new ELFObjectImage<ELFType<little>>(Obj); "
" } "
" void resolveX86_64Relocation() { "
" reinterpret_cast<int>(0); "
" } " ) ;
tokenizeAndStringify ( " template<typename value_type, typename function_type> "
" value_type Base(const value_type x, const value_type dx, function_type func, int type_deriv) { "
" return 0.0; "
" }; "
" namespace { "
" template<class DC> class C { "
" void Fun(int G, const double x); "
" }; "
" template<class DC> void C<DC>::Fun(int G, const double x) { "
" Base<double, CDFFunctor<DC>>(2, 2, f, 0); "
" }; "
" template<class DC> class C2 {}; "
" } " ) ;
2014-12-14 14:58:54 +01:00
}
2019-06-13 13:37:55 +02:00
void cpp0xtemplate5 ( ) { // #9154
{
const char * code = " struct s<x<u...>>; " ;
2019-09-04 08:07:30 +02:00
ASSERT_EQUALS ( " struct s < x < u ... > > ; " ,
2019-06-13 13:37:55 +02:00
tokenizeAndStringify ( code ) ) ;
}
{
const char * code = " template <class f> using c = e<i<q<f,r>,b...>>; " ;
2019-09-04 08:07:30 +02:00
ASSERT_EQUALS ( " template < class f > using c = e < i < q < f , r > , b ... > > ; " ,
2019-06-13 13:37:55 +02:00
tokenizeAndStringify ( code ) ) ;
}
{
const char * code = " struct s<x<u...>> { }; " ;
2019-09-04 08:07:30 +02:00
ASSERT_EQUALS ( " struct s < x < u ... > > { } ; " ,
2019-06-13 13:37:55 +02:00
tokenizeAndStringify ( code ) ) ;
}
{
const char * code = " struct q : s<x<u...>> { }; " ;
2019-09-04 08:07:30 +02:00
ASSERT_EQUALS ( " struct q : s < x < u ... > > { } ; " ,
2019-06-13 13:37:55 +02:00
tokenizeAndStringify ( code ) ) ;
}
{
const char * code = " struct q : private s<x<u...>> { }; " ;
2019-09-04 08:07:30 +02:00
ASSERT_EQUALS ( " struct q : private s < x < u ... > > { } ; " ,
2019-06-13 13:37:55 +02:00
tokenizeAndStringify ( code ) ) ;
}
}
2015-05-26 00:28:08 +02:00
void cpp14template ( ) { // Ticket #6708
tokenizeAndStringify ( " template <typename T> "
" decltype(auto) forward(T& t) { return 0; } " ) ;
}
2014-11-20 14:20:09 +01:00
void arraySize ( ) {
2015-10-08 11:35:51 +02:00
ASSERT_EQUALS ( " ; int a [ 3 ] = { 1 , 2 , 3 } ; " , tokenizeAndStringify ( " ;int a[]={1,2,3}; " ) ) ;
ASSERT_EQUALS ( " ; int a [ 3 ] = { 1 , 2 , 3 } ; " , tokenizeAndStringify ( " ;int a[]={1,2,3,}; " ) ) ;
ASSERT_EQUALS ( " ; foo a [ 3 ] = { { 1 , 2 } , { 3 , 4 } , { 5 , 6 } } ; " , tokenizeAndStringify ( " ;foo a[]={{1,2},{3,4},{5,6}}; " ) ) ;
2015-10-08 12:52:28 +02:00
ASSERT_EQUALS ( " ; int a [ 1 ] = { foo < bar1 , bar2 > ( 123 , 4 ) } ; " , tokenizeAndStringify ( " ;int a[]={foo<bar1,bar2>(123,4)}; " ) ) ;
2015-10-08 11:35:51 +02:00
ASSERT_EQUALS ( " ; int a [ 2 ] = { b > c ? 1 : 2 , 3 } ; " , tokenizeAndStringify ( " ;int a[]={ b>c?1:2,3}; " ) ) ;
2015-10-08 12:52:28 +02:00
ASSERT_EQUALS ( " int main ( ) { int a [ 2 ] = { b < c ? 1 : 2 , 3 } } " , tokenizeAndStringify ( " int main(){int a[]={b<c?1:2,3}} " ) ) ;
2015-10-08 11:35:51 +02:00
ASSERT_EQUALS ( " ; int a [ 3 ] = { ABC , 2 , 3 } ; " , tokenizeAndStringify ( " ;int a[]={ABC,2,3}; " ) ) ;
ASSERT_EQUALS ( " ; int a [ 3 ] = { [ 2 ] = 5 } ; " , tokenizeAndStringify ( " ;int a[]={ [2] = 5 }; " ) ) ;
ASSERT_EQUALS ( " ; int a [ 5 ] = { 1 , 2 , [ 2 ] = 5 , 3 , 4 } ; " , tokenizeAndStringify ( " ;int a[]={ 1, 2, [2] = 5, 3, 4 }; " ) ) ;
ASSERT_EQUALS ( " ; int a [ ] = { 1 , 2 , [ x ] = 5 , 3 , 4 } ; " , tokenizeAndStringify ( " ;int a[]={ 1, 2, [x] = 5, 3, 4 }; " ) ) ;
2010-02-21 09:47:41 +01:00
}
2014-11-20 14:20:09 +01:00
void labels ( ) {
2015-10-08 11:35:51 +02:00
ASSERT_EQUALS ( " void f ( ) { ab : ; a = 0 ; } " , tokenizeAndStringify ( " void f() { ab: a=0; } " ) ) ;
2011-10-08 21:13:53 +02:00
//ticket #3176
2015-10-08 11:35:51 +02:00
ASSERT_EQUALS ( " void f ( ) { ab : ; ( * func ) ( ) ; } " , tokenizeAndStringify ( " void f() { ab: (*func)(); } " ) ) ;
2011-10-08 21:13:53 +02:00
//with '*' operator
2015-10-08 11:35:51 +02:00
ASSERT_EQUALS ( " void f ( ) { ab : ; * b = 0 ; } " , tokenizeAndStringify ( " void f() { ab: *b=0; } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { ab : ; * * b = 0 ; } " , tokenizeAndStringify ( " void f() { ab: **b=0; } " ) ) ;
2011-10-08 21:13:53 +02:00
//with '&' operator
2015-10-08 11:35:51 +02:00
ASSERT_EQUALS ( " void f ( ) { ab : ; & b = 0 ; } " , tokenizeAndStringify ( " void f() { ab: &b=0; } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { ab : ; & ( b . x ) = 0 ; } " , tokenizeAndStringify ( " void f() { ab: &(b->x)=0; } " ) ) ;
2013-01-16 15:37:07 +01:00
//with '(' parentheses
2015-10-08 11:35:51 +02:00
ASSERT_EQUALS ( " void f ( ) { ab : ; * ( * b ) . x = 0 ; } " , tokenizeAndStringify ( " void f() { ab: *(* b)->x=0; } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { ab : ; ( * * b ) . x = 0 ; } " , tokenizeAndStringify ( " void f() { ab: (** b).x=0; } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { ab : ; & ( * b . x ) = 0 ; } " , tokenizeAndStringify ( " void f() { ab: &(*b.x)=0; } " ) ) ;
2013-01-16 15:37:07 +01:00
//with '{' parentheses
2015-10-08 11:35:51 +02:00
ASSERT_EQUALS ( " void f ( ) { ab : ; { b = 0 ; } } " , tokenizeAndStringify ( " void f() { ab: {b=0;} } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { ab : ; { * b = 0 ; } } " , tokenizeAndStringify ( " void f() { ab: { *b=0;} } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { ab : ; { & b = 0 ; } } " , tokenizeAndStringify ( " void f() { ab: { &b=0;} } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { ab : ; { & ( * b . x ) = 0 ; } } " , tokenizeAndStringify ( " void f() { ab: {&(*b.x)=0;} } " ) ) ;
2011-10-08 21:13:53 +02:00
//with unhandled MACRO() code
2020-03-12 13:28:09 +01:00
ASSERT_THROW ( tokenizeAndStringify ( " void f() { MACRO(ab: b=0;, foo)} " ) , InternalError ) ;
2015-10-08 11:35:51 +02:00
ASSERT_EQUALS ( " void f ( ) { MACRO ( bar , ab : { & ( * b . x ) = 0 ; } ) } " , tokenizeAndStringify ( " void f() { MACRO(bar, ab: {&(*b.x)=0;})} " ) ) ;
2010-02-21 09:47:41 +01:00
}
2010-04-14 19:04:16 +02:00
2014-11-20 14:20:09 +01:00
void simplifyInitVar ( ) {
2010-04-14 19:04:16 +02:00
{
const char code [ ] = " int i ; int p(0); " ;
ASSERT_EQUALS ( " int i ; int p ; p = 0 ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " int i; int *p(0); " ;
ASSERT_EQUALS ( " int i ; int * p ; p = 0 ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " int p(0); " ;
ASSERT_EQUALS ( " int p ; p = 0 ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " int *p(0); " ;
ASSERT_EQUALS ( " int * p ; p = 0 ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " int i ; int p(i); " ;
2010-08-27 22:58:21 +02:00
ASSERT_EQUALS ( " int i ; int p ; p = i ; " , tokenizeAndStringify ( code ) ) ;
2010-04-14 19:04:16 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " int i; int *p(&i); " ;
ASSERT_EQUALS ( " int i ; int * p ; p = & i ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " int i; void *p(&i); " ;
ASSERT_EQUALS ( " int i ; void * p ; p = & i ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " struct S { }; struct S s; struct S *p(&s); " ;
ASSERT_EQUALS ( " struct S { } ; struct S s ; struct S * p ; p = & s ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " struct S { }; S s; S *p(&s); " ;
ASSERT_EQUALS ( " struct S { } ; S s ; S * p ; p = & s ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " union S { int i; float f; }; union S s; union S *p(&s); " ;
ASSERT_EQUALS ( " union S { int i ; float f ; } ; union S s ; union S * p ; p = & s ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " union S { int i; float f; }; S s; S *p(&s); " ;
ASSERT_EQUALS ( " union S { int i ; float f ; } ; S s ; S * p ; p = & s ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " class C { }; class C c; class C *p(&c); " ;
ASSERT_EQUALS ( " class C { } ; class C c ; class C * p ; p = & c ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " class C { }; C c; C *p(&c); " ;
ASSERT_EQUALS ( " class C { } ; C c ; C * p ; p = & c ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " struct S { }; struct S s; struct S s1(s); " ;
ASSERT_EQUALS ( " struct S { } ; struct S s ; struct S s1 ( s ) ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " struct S { }; S s; S s1(s); " ;
ASSERT_EQUALS ( " struct S { } ; S s ; S s1 ( s ) ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " struct S { }; struct S s; struct S s1(&s); " ;
ASSERT_EQUALS ( " struct S { } ; struct S s ; struct S s1 ( & s ) ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " struct S { }; S s; S s1(&s); " ;
ASSERT_EQUALS ( " struct S { } ; S s ; S s1 ( & s ) ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-04-15 18:42:11 +02:00
{
const char code [ ] = " class S { int function(); }; " ;
ASSERT_EQUALS ( " class S { int function ( ) ; } ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-04-14 19:04:16 +02:00
{
const char code [ ] = " class S { int function(void); }; " ;
2021-03-25 08:25:43 +01:00
ASSERT_EQUALS ( " class S { int function ( void ) ; } ; " , tokenizeAndStringify ( code ) ) ;
2010-04-14 19:04:16 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " class S { int function(int); }; " ;
ASSERT_EQUALS ( " class S { int function ( int ) ; } ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " int function(void); " ;
2021-03-25 08:25:43 +01:00
ASSERT_EQUALS ( " int function ( void ) ; " , tokenizeAndStringify ( code ) ) ;
2010-04-14 19:04:16 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " int function(int); " ;
ASSERT_EQUALS ( " int function ( int ) ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " extern int function(void); " ;
2021-03-25 08:25:43 +01:00
ASSERT_EQUALS ( " extern int function ( void ) ; " , tokenizeAndStringify ( code ) ) ;
2010-04-14 19:04:16 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " int function1(void); int function2(void); " ;
2021-03-25 08:25:43 +01:00
ASSERT_EQUALS ( " int function1 ( void ) ; int function2 ( void ) ; " , tokenizeAndStringify ( code ) ) ;
2010-04-14 19:04:16 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-04-15 18:42:11 +02:00
{
const char code [ ] = " int function(A); " ;
// We can't tell if this a function prototype or a variable without knowing
// what A is. Since A is undefined, just leave it alone.
ASSERT_EQUALS ( " int function ( A ) ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " int i; int function(A); " ;
ASSERT_EQUALS ( " int i ; int function ( A ) ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " class A { } ; int foo(A); " ;
2010-08-27 22:58:21 +02:00
ASSERT_EQUALS ( " class A { } ; int foo ( A ) ; " , tokenizeAndStringify ( code ) ) ;
2010-04-15 18:42:11 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
const char code [ ] = " class A { } ; A a; int foo(a); " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " class A { } ; A a ; int foo ; foo = a ; " , tokenizeAndStringify ( code ) ) ;
2010-04-15 18:42:11 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2010-08-27 22:58:21 +02:00
}
{
const char code [ ] = " int x(f()); " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " int x ; x = f ( ) ; " , tokenizeAndStringify ( code ) ) ;
2010-04-15 18:42:11 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2012-09-15 11:55:08 +02:00
{
2020-04-11 17:36:11 +02:00
const char code [ ] = " { return doSomething(X), 0; } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " { return doSomething ( X ) , 0 ; } " , tokenizeAndStringify ( code ) ) ;
2015-08-02 09:11:51 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-04-14 19:04:16 +02:00
}
2010-08-15 11:54:28 +02:00
2014-11-20 14:20:09 +01:00
void simplifyInitVar2 ( ) {
2013-10-31 17:20:00 +01:00
// ticket #5131 - unsigned
const char code [ ] = " void f() { \n "
" unsigned int a(0),b(0); \n "
" } " ;
ASSERT_EQUALS ( " void f ( ) { \n "
" unsigned int a ; a = 0 ; unsigned int b ; b = 0 ; \n "
" } " , tokenizeAndStringify ( code ) ) ;
}
2014-11-20 14:20:09 +01:00
void simplifyInitVar3 ( ) {
2013-10-31 17:20:00 +01:00
const char code [ ] = " void f() { \n "
" int *a(0),b(0); \n "
" } " ;
ASSERT_EQUALS ( " void f ( ) { \n "
" int * a ; a = 0 ; int b ; b = 0 ; \n "
" } " , tokenizeAndStringify ( code ) ) ;
}
2014-11-20 14:20:09 +01:00
void bitfields1 ( ) {
2010-08-18 22:42:04 +02:00
const char code1 [ ] = " struct A { bool x : 1; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { bool x ; } ; " , tokenizeAndStringify ( code1 ) ) ;
2010-08-18 22:42:04 +02:00
const char code2 [ ] = " struct A { char x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { char x ; } ; " , tokenizeAndStringify ( code2 ) ) ;
2010-08-18 22:42:04 +02:00
const char code3 [ ] = " struct A { short x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { short x ; } ; " , tokenizeAndStringify ( code3 ) ) ;
2010-08-18 22:42:04 +02:00
const char code4 [ ] = " struct A { int x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { int x ; } ; " , tokenizeAndStringify ( code4 ) ) ;
2010-08-18 22:42:04 +02:00
const char code5 [ ] = " struct A { long x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { long x ; } ; " , tokenizeAndStringify ( code5 ) ) ;
2010-08-18 22:42:04 +02:00
2010-08-22 13:25:47 +02:00
const char code6 [ ] = " struct A { __int8 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { char x ; } ; " , tokenizeAndStringifyWindows ( code6 , true , Settings : : Win32A ) ) ;
2010-08-18 22:42:04 +02:00
2010-08-22 13:25:47 +02:00
const char code7 [ ] = " struct A { __int16 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { short x ; } ; " , tokenizeAndStringifyWindows ( code7 , true , Settings : : Win32A ) ) ;
2010-08-18 22:42:04 +02:00
2010-08-22 13:25:47 +02:00
const char code8 [ ] = " struct A { __int32 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { int x ; } ; " , tokenizeAndStringifyWindows ( code8 , true , Settings : : Win32A ) ) ;
2010-08-18 22:42:04 +02:00
2010-08-22 13:25:47 +02:00
const char code9 [ ] = " struct A { __int64 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { long long x ; } ; " , tokenizeAndStringifyWindows ( code9 , true , Settings : : Win32A ) ) ;
2010-08-18 22:42:04 +02:00
2010-08-22 13:25:47 +02:00
const char code10 [ ] = " struct A { unsigned char x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { unsigned char x ; } ; " , tokenizeAndStringify ( code10 ) ) ;
2010-08-16 18:51:25 +02:00
2010-08-22 13:25:47 +02:00
const char code11 [ ] = " struct A { unsigned short x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { unsigned short x ; } ; " , tokenizeAndStringify ( code11 ) ) ;
2010-08-18 22:42:04 +02:00
2010-08-22 13:25:47 +02:00
const char code12 [ ] = " struct A { unsigned int x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { unsigned int x ; } ; " , tokenizeAndStringify ( code12 ) ) ;
2010-08-18 22:42:04 +02:00
2010-08-22 13:25:47 +02:00
const char code13 [ ] = " struct A { unsigned long x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { unsigned long x ; } ; " , tokenizeAndStringify ( code13 ) ) ;
2010-08-22 09:41:22 +02:00
2010-08-22 13:25:47 +02:00
const char code14 [ ] = " struct A { unsigned __int8 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { unsigned char x ; } ; " , tokenizeAndStringifyWindows ( code14 , true , Settings : : Win32A ) ) ;
2010-08-22 09:41:22 +02:00
2010-08-22 13:25:47 +02:00
const char code15 [ ] = " struct A { unsigned __int16 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { unsigned short x ; } ; " , tokenizeAndStringifyWindows ( code15 , true , Settings : : Win32A ) ) ;
2010-08-22 09:41:22 +02:00
2010-08-22 13:25:47 +02:00
const char code16 [ ] = " struct A { unsigned __int32 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { unsigned int x ; } ; " , tokenizeAndStringifyWindows ( code16 , true , Settings : : Win32A ) ) ;
2010-08-22 13:25:47 +02:00
const char code17 [ ] = " struct A { unsigned __int64 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { unsigned long long x ; } ; " , tokenizeAndStringifyWindows ( code17 , true , Settings : : Win32A ) ) ;
2010-08-22 13:25:47 +02:00
const char code18 [ ] = " struct A { signed char x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { signed char x ; } ; " , tokenizeAndStringify ( code18 ) ) ;
2010-08-22 13:25:47 +02:00
const char code19 [ ] = " struct A { signed short x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { signed short x ; } ; " , tokenizeAndStringify ( code19 ) ) ;
2010-08-22 13:25:47 +02:00
const char code20 [ ] = " struct A { signed int x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { signed int x ; } ; " , tokenizeAndStringify ( code20 ) ) ;
2010-08-22 13:25:47 +02:00
const char code21 [ ] = " struct A { signed long x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { signed long x ; } ; " , tokenizeAndStringifyWindows ( code21 ) ) ;
2010-08-22 13:25:47 +02:00
const char code22 [ ] = " struct A { signed __int8 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { signed char x ; } ; " , tokenizeAndStringifyWindows ( code22 , true , Settings : : Win32A ) ) ;
2010-08-22 13:25:47 +02:00
const char code23 [ ] = " struct A { signed __int16 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { signed short x ; } ; " , tokenizeAndStringifyWindows ( code23 , true , Settings : : Win32A ) ) ;
2010-08-22 13:25:47 +02:00
const char code24 [ ] = " struct A { signed __int32 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { signed int x ; } ; " , tokenizeAndStringifyWindows ( code24 , true , Settings : : Win32A ) ) ;
2010-08-22 13:25:47 +02:00
const char code25 [ ] = " struct A { signed __int64 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { signed long long x ; } ; " , tokenizeAndStringifyWindows ( code25 , true , Settings : : Win32A ) ) ;
2010-08-18 22:42:04 +02:00
}
2014-11-20 14:20:09 +01:00
void bitfields2 ( ) {
2010-08-18 22:42:04 +02:00
const char code1 [ ] = " struct A { public: int x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { public: int x ; } ; " , tokenizeAndStringify ( code1 ) ) ;
2010-08-18 22:42:04 +02:00
const char code2 [ ] = " struct A { public: unsigned long x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { public: unsigned long x ; } ; " , tokenizeAndStringify ( code2 ) ) ;
2010-08-18 22:42:04 +02:00
const char code3 [ ] = " struct A { protected: int x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { protected: int x ; } ; " , tokenizeAndStringify ( code3 ) ) ;
2010-08-18 22:42:04 +02:00
const char code4 [ ] = " struct A { protected: unsigned long x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { protected: unsigned long x ; } ; " , tokenizeAndStringify ( code4 ) ) ;
2010-08-18 22:42:04 +02:00
const char code5 [ ] = " struct A { private: int x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { private: int x ; } ; " , tokenizeAndStringify ( code5 ) ) ;
2010-08-18 22:42:04 +02:00
const char code6 [ ] = " struct A { private: unsigned long x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { private: unsigned long x ; } ; " , tokenizeAndStringify ( code6 ) ) ;
2010-08-18 22:42:04 +02:00
}
2014-11-20 14:20:09 +01:00
void bitfields3 ( ) {
2010-08-18 22:42:04 +02:00
const char code1 [ ] = " struct A { const int x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { const int x ; } ; " , tokenizeAndStringify ( code1 ) ) ;
2010-08-18 22:42:04 +02:00
const char code2 [ ] = " struct A { const unsigned long x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { const unsigned long x ; } ; " , tokenizeAndStringify ( code2 ) ) ;
2010-08-18 22:42:04 +02:00
const char code3 [ ] = " struct A { public: const int x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { public: const int x ; } ; " , tokenizeAndStringify ( code3 ) ) ;
2010-08-18 22:42:04 +02:00
const char code4 [ ] = " struct A { public: const unsigned long x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { public: const unsigned long x ; } ; " , tokenizeAndStringify ( code4 ) ) ;
2010-08-18 22:42:04 +02:00
}
2014-11-20 14:20:09 +01:00
void bitfields4 ( ) { // ticket #1956
2010-08-21 16:34:41 +02:00
const char code1 [ ] = " struct A { CHAR x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { CHAR x ; } ; " , tokenizeAndStringify ( code1 ) ) ;
2010-08-21 16:34:41 +02:00
const char code2 [ ] = " struct A { UCHAR x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { UCHAR x ; } ; " , tokenizeAndStringify ( code2 ) ) ;
2010-08-21 16:34:41 +02:00
const char code3 [ ] = " struct A { BYTE x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { BYTE x ; } ; " , tokenizeAndStringify ( code3 ) ) ;
2010-08-21 16:34:41 +02:00
const char code4 [ ] = " struct A { WORD x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { WORD x ; } ; " , tokenizeAndStringify ( code4 ) ) ;
2010-08-21 16:34:41 +02:00
const char code5 [ ] = " struct A { DWORD x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { DWORD x ; } ; " , tokenizeAndStringify ( code5 ) ) ;
2010-08-21 16:34:41 +02:00
const char code6 [ ] = " struct A { LONG x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { LONG x ; } ; " , tokenizeAndStringify ( code6 ) ) ;
2010-08-21 16:34:41 +02:00
const char code7 [ ] = " struct A { UINT8 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { UINT8 x ; } ; " , tokenizeAndStringify ( code7 ) ) ;
2010-08-21 16:34:41 +02:00
const char code8 [ ] = " struct A { UINT16 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { UINT16 x ; } ; " , tokenizeAndStringify ( code8 ) ) ;
2010-08-21 16:34:41 +02:00
const char code9 [ ] = " struct A { UINT32 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { UINT32 x ; } ; " , tokenizeAndStringify ( code9 ) ) ;
2010-08-21 16:34:41 +02:00
const char code10 [ ] = " struct A { UINT64 x : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { UINT64 x ; } ; " , tokenizeAndStringify ( code10 ) ) ;
2010-08-21 16:34:41 +02:00
}
2014-11-20 14:20:09 +01:00
void bitfields5 ( ) { // ticket #1956
2010-08-22 09:41:22 +02:00
const char code1 [ ] = " struct RGB { unsigned int r : 3, g : 3, b : 2; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct RGB { unsigned int r ; unsigned int g ; unsigned int b ; } ; " , tokenizeAndStringify ( code1 ) ) ;
2010-08-22 13:25:47 +02:00
const char code2 [ ] = " struct A { int a : 3; int : 3; int c : 3; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { int a ; int c ; } ; " , tokenizeAndStringify ( code2 ) ) ;
2010-08-23 07:29:05 +02:00
const char code3 [ ] = " struct A { virtual void f() {} int f1 : 1; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { virtual void f ( ) { } int f1 ; } ; " , tokenizeAndStringify ( code3 ) ) ;
2011-02-21 00:22:49 +01:00
}
2014-11-20 14:20:09 +01:00
void bitfields6 ( ) { // ticket #2595
2011-02-21 00:22:49 +01:00
const char code1 [ ] = " struct A { bool b : true; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { bool b ; } ; " , tokenizeAndStringify ( code1 ) ) ;
2011-02-21 00:22:49 +01:00
const char code2 [ ] = " struct A { bool b : true, c : true; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { bool b ; bool c ; } ; " , tokenizeAndStringify ( code2 ) ) ;
2011-02-21 00:22:49 +01:00
const char code3 [ ] = " struct A { bool : true; }; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct A { } ; " , tokenizeAndStringify ( code3 ) ) ;
2010-08-22 09:41:22 +02:00
}
2014-11-20 14:20:09 +01:00
void bitfields7 ( ) { // ticket #1987
2011-03-19 21:00:43 +01:00
const char code [ ] = " typedef struct Descriptor { "
" unsigned element_size: 8* sizeof( unsigned ); "
" } Descriptor; " ;
const char expected [ ] = " struct Descriptor { "
" unsigned int element_size ; "
" } ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2011-03-19 21:00:43 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void bitfields8 ( ) {
2011-03-22 01:17:14 +01:00
const char code [ ] = " struct A; "
" class B : virtual public C "
" { "
" int f(); "
" }; " ;
const char expected [ ] = " struct A ; "
" class B : virtual public C "
" { "
" int f ( ) ; "
" } ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2011-03-22 01:17:14 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void bitfields9 ( ) { // ticket #2706
2011-04-05 04:18:12 +02:00
const char code [ ] = " void f() { \n "
" goto half; \n "
" half: \n "
" { \n "
" ; \n "
" } \n "
" }; " ;
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( code ) ;
2011-04-05 04:18:12 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void bitfields10 ( ) { // ticket #2737
2011-05-19 17:04:36 +02:00
const char code [ ] = " {} "
" MACRO "
" default: { } "
" ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " { } MACRO default : { } ; " , tokenizeAndStringify ( code ) ) ;
2011-05-19 17:04:36 +02:00
}
2014-11-20 14:20:09 +01:00
void bitfields12 ( ) { // ticket #3485 (segmentation fault)
2012-01-09 16:24:11 +01:00
const char code [ ] = " {a:1;}; \n " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " { } ; " , tokenizeAndStringify ( code ) ) ;
2012-01-09 16:24:11 +01:00
}
2014-11-20 14:20:09 +01:00
void bitfields13 ( ) { // ticket #3502 (segmentation fault)
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " x y ; " , tokenizeAndStringify ( " struct{x y:}; \n " ) ) ;
2012-01-23 07:39:31 +01:00
}
2014-11-20 14:20:09 +01:00
void bitfields14 ( ) { // #4561 - crash for 'signals:'
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " class x { protected: } ; " , tokenizeAndStringify ( " class x { signals: }; \n " ) ) ;
2013-02-07 17:03:08 +01:00
}
2016-10-04 15:57:43 +02:00
void bitfields15 ( ) { // #7747 - enum Foo {A,B}:4;
ASSERT_EQUALS ( " struct AB { \n "
" enum Foo { A , B } ; enum Foo Anonymous ; \n "
" } ; " ,
tokenizeAndStringify ( " struct AB { \n "
" enum Foo {A,B} : 4; \n "
" }; " ) ) ;
ASSERT_EQUALS ( " struct AB { \n "
" enum Foo { A , B } ; enum Foo foo ; \n "
" } ; " ,
tokenizeAndStringify ( " struct AB { \n "
" enum Foo {A,B} foo : 4; \n "
" }; " ) ) ;
}
2018-05-02 20:55:11 +02:00
void bitfields16 ( ) {
const char code [ ] = " struct A { unsigned int x : 1; }; " ;
errout . str ( " " ) ;
Tokenizer tokenizer ( & settings0 , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2018-05-02 20:55:11 +02:00
const Token * x = Token : : findsimplematch ( tokenizer . tokens ( ) , " x " ) ;
ASSERT_EQUALS ( 1 , x - > bits ( ) ) ;
}
2013-02-07 17:03:08 +01:00
2014-11-20 14:20:09 +01:00
void simplifyNamespaceStd ( ) {
2018-10-10 14:35:58 +02:00
const char * code , * expected ;
2018-10-10 14:28:53 +02:00
2018-10-10 14:35:58 +02:00
code = " map<foo, bar> m; " ; // namespace std is not used
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " map < foo , bar > m ; " , tokenizeAndStringify ( code ) ) ;
2012-07-15 11:05:19 +02:00
2018-10-10 14:35:58 +02:00
code = " using namespace std; \n "
" map<foo, bar> m; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " std :: map < foo , bar > m ; " , tokenizeAndStringify ( code ) ) ;
2012-07-15 11:05:19 +02:00
2018-10-10 14:35:58 +02:00
code = " using namespace std; \n "
" string s; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " std :: string s ; " , tokenizeAndStringify ( code ) ) ;
2012-07-15 11:05:19 +02:00
2018-10-10 14:35:58 +02:00
code = " using namespace std; \n "
" void foo() {swap(a, b); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { std :: swap ( a , b ) ; } " , tokenizeAndStringify ( code ) ) ;
2012-07-15 11:05:19 +02:00
2018-10-10 14:28:53 +02:00
code = " using namespace std; \n "
" void search() {} " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void search ( ) { } " , tokenizeAndStringify ( code ) ) ;
2018-10-10 14:28:53 +02:00
2018-10-10 17:35:53 +02:00
code = " using namespace std; \n "
" void search(); \n "
" void dostuff() { search(); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void search ( ) ; \n void dostuff ( ) { search ( ) ; } " , tokenizeAndStringify ( code ) ) ;
2018-10-10 17:35:53 +02:00
2018-10-10 14:35:58 +02:00
code = " using namespace std; \n "
" void foo() {map(a, b); } " ; // That's obviously not std::map<>
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { map ( a , b ) ; } " , tokenizeAndStringify ( code ) ) ;
2012-07-15 11:05:19 +02:00
2018-10-10 14:35:58 +02:00
code = " using namespace std; \n "
" string<wchar_t> s; " ; // That's obviously not std::string
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " string < wchar_t > s ; " , tokenizeAndStringify ( code ) ) ;
2012-07-15 11:05:19 +02:00
2018-10-10 14:35:58 +02:00
code = " using namespace std; \n "
" swap s; " ; // That's obviously not std::swap
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " swap s ; " , tokenizeAndStringify ( code ) ) ;
2012-07-15 11:05:19 +02:00
2018-10-10 14:35:58 +02:00
code = " using namespace std; \n "
" std::string s; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " std :: string s ; " , tokenizeAndStringify ( code ) ) ;
2012-07-15 11:05:19 +02:00
2018-10-10 14:35:58 +02:00
code = " using namespace std; \n "
" tr1::function <void(int)> f; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " tr1 :: function < void ( int ) > f ; " , tokenizeAndStringify ( code , true , Settings : : Native , " test.cpp " , false ) ) ;
ASSERT_EQUALS ( " std :: function < void ( int ) > f ; " , tokenizeAndStringify ( code , true , Settings : : Native , " test.cpp " , true ) ) ;
2012-07-15 11:05:19 +02:00
2018-10-10 14:35:58 +02:00
code = " std::tr1::function <void(int)> f; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " std :: tr1 :: function < void ( int ) > f ; " , tokenizeAndStringify ( code , true , Settings : : Native , " test.cpp " , false ) ) ;
ASSERT_EQUALS ( " std :: function < void ( int ) > f ; " , tokenizeAndStringify ( code , true , Settings : : Native , " test.cpp " , true ) ) ;
2013-07-11 07:13:47 +02:00
// #4042 (Do not add 'std ::' to variables)
2018-10-10 14:35:58 +02:00
code = " using namespace std; \n "
" const char * string = \" Hi \" ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " const char * string ; string = \" Hi \" ; " , tokenizeAndStringify ( code ) ) ;
2018-10-10 14:35:58 +02:00
code = " using namespace std; \n "
" string f(const char * string) { \n "
" cout << string << endl; \n "
" return string; \n "
" } " ;
expected = " std :: string f ( const char * string ) { \n "
" std :: cout << string << std :: endl ; \n "
" return string ; \n "
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2018-10-10 14:35:58 +02:00
code = " using namespace std; \n "
2020-04-11 17:36:11 +02:00
" void f() { \n "
" try { } \n "
" catch(std::exception &exception) { } \n "
" } " ;
expected = " void f ( ) { \n "
" try { } \n "
" catch ( std :: exception & exception ) { } \n "
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2014-05-09 21:57:34 +02:00
// #5773 (Don't prepend 'std ::' to function definitions)
2018-10-10 14:35:58 +02:00
code = " using namespace std; \n "
" class C { \n "
" void search() {} \n "
" void search() const {} \n "
" void search() THROW_MACRO {} \n "
" }; " ;
expected = " class C { \n "
" void search ( ) { } \n "
" void search ( ) const { } \n "
" void search ( ) { } \n "
" } ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
2017-07-29 11:56:09 +02:00
// Ticket #8091
ASSERT_EQUALS ( " enum Anonymous0 { string } ; " ,
tokenizeAndStringify ( " using namespace std; "
" enum { string }; " ) ) ;
ASSERT_EQUALS ( " enum Type { string } ; " ,
tokenizeAndStringify ( " using namespace std; "
" enum Type { string } ; " ) ) ;
ASSERT_EQUALS ( " enum class Type { string } ; " ,
tokenizeAndStringify ( " using namespace std; "
" enum class Type { string } ; " ) ) ;
ASSERT_EQUALS ( " enum struct Type { string } ; " ,
tokenizeAndStringify ( " using namespace std; "
" enum struct Type { string } ; " ) ) ;
ASSERT_EQUALS ( " enum struct Type : int { f = 0 , string } ; " ,
tokenizeAndStringify ( " using namespace std; "
" enum struct Type : int { f = 0 , string } ; " ) ) ;
ASSERT_EQUALS ( " enum Type { a , b } ; void foo ( enum Type , std :: string ) { } " ,
tokenizeAndStringify ( " using namespace std; "
" enum Type { a , b } ; void foo ( enum Type , string) {} " ) ) ;
ASSERT_EQUALS ( " struct T { } ; enum struct Type : int { f = 0 , string } ; " ,
tokenizeAndStringify ( " using namespace std; "
" struct T { typedef int type; } ; "
" enum struct Type : T :: type { f = 0 , string } ; " ) ) ;
// Handle garbage enum code "well"
ASSERT_EQUALS ( " enum E : int ; void foo ( ) { std :: string s ; } " ,
tokenizeAndStringify ( " using namespace std; enum E : int ; void foo ( ) { string s ; } " ) ) ;
2012-07-15 11:05:19 +02:00
}
2014-11-20 14:20:09 +01:00
void microsoftMemory ( ) {
2012-03-27 21:24:46 +02:00
const char code1a [ ] = " void foo() { int a[10], b[10]; CopyMemory(a, b, sizeof(a)); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memcpy ( a , b , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code1a , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code1b [ ] = " void foo() { int a[10], b[10]; RtlCopyMemory(a, b, sizeof(a)); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memcpy ( a , b , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code1b , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code1c [ ] = " void foo() { int a[10], b[10]; RtlCopyBytes(a, b, sizeof(a)); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memcpy ( a , b , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code1c , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code2a [ ] = " void foo() { int a[10]; FillMemory(a, sizeof(a), 255); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; memset ( a , 255 , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code2a , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code2b [ ] = " void foo() { int a[10]; RtlFillMemory(a, sizeof(a), 255); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; memset ( a , 255 , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code2b , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code2c [ ] = " void foo() { int a[10]; RtlFillBytes(a, sizeof(a), 255); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; memset ( a , 255 , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code2c , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code3a [ ] = " void foo() { int a[10], b[10]; MoveMemory(a, b, sizeof(a)); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memmove ( a , b , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code3a , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code3b [ ] = " void foo() { int a[10], b[10]; RtlMoveMemory(a, b, sizeof(a)); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memmove ( a , b , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code3b , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code4a [ ] = " void foo() { int a[10]; ZeroMemory(a, sizeof(a)); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; memset ( a , 0 , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code4a , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code4b [ ] = " void foo() { int a[10]; RtlZeroMemory(a, sizeof(a)); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; memset ( a , 0 , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code4b , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code4c [ ] = " void foo() { int a[10]; RtlZeroBytes(a, sizeof(a)); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; memset ( a , 0 , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code4c , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code4d [ ] = " void foo() { int a[10]; RtlSecureZeroMemory(a, sizeof(a)); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; memset ( a , 0 , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code4d , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code5 [ ] = " void foo() { int a[10], b[10]; RtlCompareMemory(a, b, sizeof(a)); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { int a [ 10 ] ; int b [ 10 ] ; memcmp ( a , b , sizeof ( a ) ) ; } " , tokenizeAndStringify ( code5 , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code6 [ ] = " void foo() { ZeroMemory(f(1, g(a, b)), h(i, j(0, 1))); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { memset ( f ( 1 , g ( a , b ) ) , 0 , h ( i , j ( 0 , 1 ) ) ) ; } " , tokenizeAndStringify ( code6 , true , Settings : : Win32A ) ) ;
2012-03-27 21:24:46 +02:00
const char code7 [ ] = " void foo() { FillMemory(f(1, g(a, b)), h(i, j(0, 1)), 255); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { memset ( f ( 1 , g ( a , b ) ) , 255 , h ( i , j ( 0 , 1 ) ) ) ; } " , tokenizeAndStringify ( code7 , true , Settings : : Win32A ) ) ;
2011-09-23 01:59:56 +02:00
}
2018-04-12 08:52:31 +02:00
void microsoftString ( ) {
const char code1a [ ] = " void foo() { _tprintf (_T( \" test \" ) _T( \" 1 \" )); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { printf ( \" test1 \" ) ; } " , tokenizeAndStringify ( code1a , true , Settings : : Win32A ) ) ;
2018-04-12 08:52:31 +02:00
const char code1b [ ] = " void foo() { _tprintf (_TEXT( \" test \" ) _TEXT( \" 2 \" )); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { printf ( \" test2 \" ) ; } " , tokenizeAndStringify ( code1b , true , Settings : : Win32A ) ) ;
2018-04-12 08:52:31 +02:00
const char code1c [ ] = " void foo() { _tprintf (TEXT( \" test \" ) TEXT( \" 3 \" )); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { printf ( \" test3 \" ) ; } " , tokenizeAndStringify ( code1c , true , Settings : : Win32A ) ) ;
2018-04-12 08:52:31 +02:00
const char code2a [ ] = " void foo() { _tprintf (_T( \" test \" ) _T( \" 1 \" )); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { wprintf ( L \" test1 \" ) ; } " , tokenizeAndStringify ( code2a , true , Settings : : Win32W ) ) ;
ASSERT_EQUALS ( " void foo ( ) { wprintf ( L \" test1 \" ) ; } " , tokenizeAndStringify ( code2a , true , Settings : : Win64 ) ) ;
2018-04-12 08:52:31 +02:00
const char code2b [ ] = " void foo() { _tprintf (_TEXT( \" test \" ) _TEXT( \" 2 \" )); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { wprintf ( L \" test2 \" ) ; } " , tokenizeAndStringify ( code2b , true , Settings : : Win32W ) ) ;
ASSERT_EQUALS ( " void foo ( ) { wprintf ( L \" test2 \" ) ; } " , tokenizeAndStringify ( code2b , true , Settings : : Win64 ) ) ;
2018-04-12 08:52:31 +02:00
const char code2c [ ] = " void foo() { _tprintf (TEXT( \" test \" ) TEXT( \" 3 \" )); } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void foo ( ) { wprintf ( L \" test3 \" ) ; } " , tokenizeAndStringify ( code2c , true , Settings : : Win32W ) ) ;
ASSERT_EQUALS ( " void foo ( ) { wprintf ( L \" test3 \" ) ; } " , tokenizeAndStringify ( code2c , true , Settings : : Win64 ) ) ;
2018-04-12 08:52:31 +02:00
}
2014-11-20 14:20:09 +01:00
void borland ( ) {
2010-09-01 18:10:12 +02:00
// __closure
2020-04-10 11:53:32 +02:00
ASSERT_EQUALS ( " int ( * a ) ( ) ; " , // TODO VarId
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " int (__closure *a)(); " , true , Settings : : Win32A ) ) ;
2010-09-01 18:10:12 +02:00
// __property
2010-09-07 18:37:43 +02:00
ASSERT_EQUALS ( " class Fred { ; __property ; } ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " class Fred { __property int x = { } }; " , true , Settings : : Win32A ) ) ;
2010-09-01 18:10:12 +02:00
}
2020-02-21 19:04:21 +01:00
void simplifyQtSignalsSlots1 ( ) {
2010-12-03 08:14:09 +01:00
const char code1 [ ] = " class Counter : public QObject "
" { "
" Q_OBJECT "
" public: "
" Counter() { m_value = 0; } "
" int value() const { return m_value; } "
" public slots: "
" void setValue(int value); "
" signals: "
" void valueChanged(int newValue); "
" private: "
" int m_value; "
2011-08-26 02:54:35 +02:00
" }; "
" void Counter::setValue(int value) "
" { "
" if (value != m_value) { "
" m_value = value; "
" emit valueChanged(value); "
" } "
" } " ;
2010-12-03 08:14:09 +01:00
2021-08-07 20:51:18 +02:00
const char result1 [ ] = " class Counter : public QObject "
" { "
" public: "
" Counter ( ) { m_value = 0 ; } "
" int value ( ) const { return m_value ; } "
" public: "
" void setValue ( int value ) ; "
" protected: "
" void valueChanged ( int newValue ) ; "
" private: "
" int m_value ; "
" } ; "
" void Counter :: setValue ( int value ) "
" { "
" if ( value != m_value ) { "
" m_value = value ; "
" valueChanged ( value ) ; "
" } "
" } " ;
2010-12-03 08:14:09 +01:00
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result1 , tokenizeAndStringify ( code1 ) ) ;
2010-12-03 08:14:09 +01:00
const char code2 [ ] = " class Counter : public QObject "
" { "
" Q_OBJECT "
" public: "
" Counter() { m_value = 0; } "
" int value() const { return m_value; } "
" public Q_SLOTS: "
" void setValue(int value); "
" Q_SIGNALS: "
" void valueChanged(int newValue); "
" private: "
" int m_value; "
2011-08-26 02:54:35 +02:00
" }; "
" void Counter::setValue(int value) "
" { "
" if (value != m_value) { "
" m_value = value; "
" emit valueChanged(value); "
" } "
" } " ;
2010-12-03 08:14:09 +01:00
2021-08-07 20:51:18 +02:00
const char result2 [ ] = " class Counter : public QObject "
" { "
" public: "
" Counter ( ) { m_value = 0 ; } "
" int value ( ) const { return m_value ; } "
" public: "
" void setValue ( int value ) ; "
" protected: "
" void valueChanged ( int newValue ) ; "
" private: "
" int m_value ; "
" } ; "
" void Counter :: setValue ( int value ) "
" { "
" if ( value != m_value ) { "
" m_value = value ; "
" valueChanged ( value ) ; "
" } "
" } " ;
2010-12-03 08:14:09 +01:00
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result2 , tokenizeAndStringify ( code2 ) ) ;
2011-09-16 22:59:43 +02:00
const char code3 [ ] = " class MyObject : public QObject { "
" MyObject() {} "
" ~MyObject() {} "
" public slots: "
" signals: "
" void test() {} "
" }; " ;
2021-08-07 20:51:18 +02:00
const char result3 [ ] = " class MyObject : public QObject { "
" MyObject ( ) { } "
" ~ MyObject ( ) { } "
" public: "
" protected: "
" void test ( ) { } "
" } ; " ;
2011-09-16 22:59:43 +02:00
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result3 , tokenizeAndStringify ( code3 ) ) ;
2011-09-16 22:59:43 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2016-08-20 22:43:27 +02:00
const char code4 [ ] = " class MyObject : public QObject { "
" Q_OBJECT "
" public slots: "
" }; " ;
const char result4 [ ] = " class MyObject : public QObject { "
" public: "
" } ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result4 , tokenizeAndStringify ( code4 ) ) ;
2010-12-02 17:41:49 +01:00
}
2020-02-21 19:04:21 +01:00
void simplifyQtSignalsSlots2 ( ) {
const char code1 [ ] = " class Foo::Bar: public QObject { private slots: }; " ;
const char result1 [ ] = " class Foo :: Bar : public QObject { private: } ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result1 , tokenizeAndStringify ( code1 ) ) ;
2020-02-21 19:04:21 +01:00
}
2014-11-20 14:20:09 +01:00
void simplifySQL ( ) {
2010-08-31 21:40:51 +02:00
// Oracle PRO*C extensions for inline SQL. Just replace the SQL with "asm()" to fix wrong error messages
// ticket: #1959
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " asm ( \" \" __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL SELECT A FROM B \" \" ) ; " , tokenizeAndStringify ( " __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL SELECT A FROM B; " ) ) ;
ASSERT_THROW ( tokenizeAndStringify ( " __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL " ) , InternalError ) ;
2017-11-03 21:04:12 +01:00
ASSERT_EQUALS ( " asm ( \" \" __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL EXECUTE BEGIN Proc1 ( A ) ; END ; END - __CPPCHECK_EMBEDDED_SQL_EXEC__ \" \" ) ; asm ( \" \" __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL COMMIT \" \" ) ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL EXECUTE BEGIN Proc1(A); END; END-__CPPCHECK_EMBEDDED_SQL_EXEC__; __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL COMMIT; " ) ) ;
2017-11-03 21:04:12 +01:00
ASSERT_EQUALS ( " asm ( \" \" __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL UPDATE A SET B = C \" \" ) ; asm ( \" \" __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL COMMIT \" \" ) ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL UPDATE A SET B = C; __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL COMMIT; " ) ) ;
2017-11-03 21:04:12 +01:00
ASSERT_EQUALS ( " asm ( \" \" __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL COMMIT \" \" ) ; asm ( \" \" __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL EXECUTE BEGIN Proc1 ( A ) ; END ; END - __CPPCHECK_EMBEDDED_SQL_EXEC__ \" \" ) ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL COMMIT; __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL EXECUTE BEGIN Proc1(A); END; END-__CPPCHECK_EMBEDDED_SQL_EXEC__; " ) ) ;
2017-11-03 21:04:12 +01:00
2021-04-06 21:21:53 +02:00
ASSERT_THROW ( tokenizeAndStringify ( " int f(){ __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL } int a; " ) , InternalError ) ;
ASSERT_THROW ( tokenizeAndStringify ( " __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL int f(){ " ) , InternalError ) ;
ASSERT_THROW ( tokenizeAndStringify ( " __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL END-__CPPCHECK_EMBEDDED_SQL_EXEC__ int a; " ) , InternalError ) ;
ASSERT_NO_THROW ( tokenizeAndStringify ( " __CPPCHECK_EMBEDDED_SQL_EXEC__ SQL UPDATE A SET B = :&b->b1, C = :c::c1; " ) ) ;
2010-08-31 21:40:51 +02:00
}
2010-09-09 17:43:09 +02:00
2014-11-20 14:20:09 +01:00
void simplifyCAlternativeTokens ( ) {
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void or ( void ) ; " , tokenizeAndStringify ( " void or(void); " , true , Settings : : Native , " test.c " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( a && b ) { ; } } " , tokenizeAndStringify ( " void f() { if (a and b); } " , true , Settings : : Native , " test.c " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( a && b ) { ; } } " , tokenizeAndStringify ( " void f() { if (a and b); } " , true , Settings : : Native , " test.cpp " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( a || b ) { ; } } " , tokenizeAndStringify ( " void f() { if (a or b); } " , true , Settings : : Native , " test.c " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( a || b ) { ; } } " , tokenizeAndStringify ( " void f() { if (a or b); } " , true , Settings : : Native , " test.cpp " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( a & b ) { ; } } " , tokenizeAndStringify ( " void f() { if (a bitand b); } " , true , Settings : : Native , " test.c " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( a & b ) { ; } } " , tokenizeAndStringify ( " void f() { if (a bitand b); } " , true , Settings : : Native , " test.cpp " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( a | b ) { ; } } " , tokenizeAndStringify ( " void f() { if (a bitor b); } " , true , Settings : : Native , " test.c " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( a | b ) { ; } } " , tokenizeAndStringify ( " void f() { if (a bitor b); } " , true , Settings : : Native , " test.cpp " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( a ^ b ) { ; } } " , tokenizeAndStringify ( " void f() { if (a xor b); } " , true , Settings : : Native , " test.c " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( a ^ b ) { ; } } " , tokenizeAndStringify ( " void f() { if (a xor b); } " , true , Settings : : Native , " test.cpp " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( ~ b ) { ; } } " , tokenizeAndStringify ( " void f() { if (compl b); } " , true , Settings : : Native , " test.c " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( ~ b ) { ; } } " , tokenizeAndStringify ( " void f() { if (compl b); } " , true , Settings : : Native , " test.cpp " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( ! b ) { ; } } " , tokenizeAndStringify ( " void f() { if (not b); } " , true , Settings : : Native , " test.c " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( ! b ) { ; } } " , tokenizeAndStringify ( " void f() { if (not b); } " , true , Settings : : Native , " test.cpp " ) ) ;
ASSERT_EQUALS ( " void f ( ) const { if ( ! b ) { ; } } " , tokenizeAndStringify ( " void f() const { if (not b); } " , true , Settings : : Native , " test.cpp " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( a != b ) { ; } } " , tokenizeAndStringify ( " void f() { if (a not_eq b); } " , true , Settings : : Native , " test.c " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( a != b ) { ; } } " , tokenizeAndStringify ( " void f() { if (a not_eq b); } " , true , Settings : : Native , " test.cpp " ) ) ;
2014-10-01 08:41:28 +02:00
// #6201
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void f ( ) { if ( ! c || ! memcmp ( a , b , s ) ) { ; } } " , tokenizeAndStringify ( " void f() { if (!c or !memcmp(a, b, s)); } " , true , Settings : : Native , " test.c " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( ! c || ! memcmp ( a , b , s ) ) { ; } } " , tokenizeAndStringify ( " void f() { if (!c or !memcmp(a, b, s)); } " , true , Settings : : Native , " test.cpp " ) ) ;
2016-05-24 13:33:21 +02:00
// #6029
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void f ( ) { if ( ! b ) { } } " , tokenizeAndStringify ( " void f() { if (not b){} } " , true , Settings : : Native , " test.c " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( ! b ) { } } " , tokenizeAndStringify ( " void f() { if (not b){} } " , true , Settings : : Native , " test.cpp " ) ) ;
2016-05-24 13:33:21 +02:00
// #6207
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void f ( ) { if ( not = x ) { } } " , tokenizeAndStringify ( " void f() { if (not=x){} } " , true , Settings : : Native , " test.c " ) ) ;
ASSERT_EQUALS ( " void f ( ) { if ( not = x ) { } } " , tokenizeAndStringify ( " void f() { if (not=x){} } " , true , Settings : : Native , " test.cpp " ) ) ;
2017-04-30 14:40:41 +02:00
// #8029
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void f ( struct S * s ) { x = s . and + 1 ; } " , tokenizeAndStringify ( " void f(struct S *s) { x = s->and + 1; } " , true , Settings : : Native , " test.c " ) ) ;
2018-09-09 16:40:56 +02:00
// #8745
ASSERT_EQUALS ( " void f ( ) { if ( x ) { or = 0 ; } } " , tokenizeAndStringify ( " void f() { if (x) or = 0; } " ) ) ;
2019-11-03 12:53:30 +01:00
// #9324
ASSERT_EQUALS ( " void f ( const char * str ) { while ( * str == '!' || * str == '[' ) { } } " ,
tokenizeAndStringify ( " void f(const char *str) { while (*str=='!' or *str=='['){} } " ) ) ;
2020-09-28 16:35:50 +02:00
// #9920
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " result = ch != s . end ( ) && * ch == ':' ; " , tokenizeAndStringify ( " result = ch != s.end() and *ch == ':'; " , true , Settings : : Native , " test.c " ) ) ;
2021-01-12 21:26:32 +01:00
// #8975
ASSERT_EQUALS ( " void foo ( ) { \n "
" char * or ; \n "
" while ( ( * or != 0 ) && ( * or != '|' ) ) { or ++ ; } \n "
" } " ,
tokenizeAndStringify (
" void foo() { \n "
" char *or; \n "
" while ((*or != 0) && (*or != '|')) or++; \n "
2021-04-06 21:21:53 +02:00
" } " , true , Settings : : Native , " test.c " ) ) ;
2021-02-13 20:32:49 +01:00
// #10013
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " void f ( ) { x = ! 123 ; } " , tokenizeAndStringify ( " void f() { x = not 123; } " , true , Settings : : Native , " test.cpp " ) ) ;
2020-05-30 11:23:22 +02:00
}
2014-11-20 14:20:09 +01:00
void simplifyRoundCurlyParentheses ( ) {
2012-10-13 13:24:41 +02:00
ASSERT_EQUALS ( " ; x = 123 ; " , tokenizeAndStringify ( " ;x=({123;}); " ) ) ;
ASSERT_EQUALS ( " ; x = y ; " , tokenizeAndStringify ( " ;x=({y;}); " ) ) ;
2012-09-22 18:41:33 +02:00
}
2014-11-20 14:20:09 +01:00
void simplifyOperatorName1 ( ) {
2011-01-27 18:44:20 +01:00
// make sure C code doesn't get changed
2011-02-28 20:29:34 +01:00
const char code [ ] = " void operator () {} "
" int main() "
" { "
" operator(); "
" } " ;
2011-01-27 18:44:20 +01:00
2021-08-07 20:51:18 +02:00
const char result [ ] = " void operator ( ) { } "
" int main ( ) "
" { "
" operator ( ) ; "
" } " ;
2011-01-27 18:44:20 +01:00
2021-08-07 20:51:18 +02:00
ASSERT_EQUALS ( result , tokenizeAndStringify ( code , /*expand=*/ true , /*platform=*/ Settings : : Native , " test.c " ) ) ;
2011-02-28 20:29:34 +01:00
}
2011-01-27 18:44:20 +01:00
2014-11-20 14:20:09 +01:00
void simplifyOperatorName2 ( ) {
2011-02-28 20:29:34 +01:00
const char code [ ] = " class Fred "
" { "
" Fred(const Fred & f) { operator = (f); } "
" operator = (); "
" } " ;
2011-01-27 18:44:20 +01:00
2021-08-07 20:51:18 +02:00
const char result [ ] = " class Fred "
" { "
" Fred ( const Fred & f ) { operator= ( f ) ; } "
" operator= ( ) ; "
" } " ;
2011-01-27 18:44:20 +01:00
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result , tokenizeAndStringify ( code ) ) ;
2011-02-28 20:29:34 +01:00
}
2014-11-20 14:20:09 +01:00
void simplifyOperatorName3 ( ) {
2011-02-28 20:29:34 +01:00
// #2615
const char code [ ] = " void f() { "
" static_cast<ScToken*>(xResult.operator->())->GetMatrix(); "
" } " ;
const char result [ ] = " void f ( ) { static_cast < ScToken * > ( xResult . operator. ( ) ) . GetMatrix ( ) ; } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result , tokenizeAndStringify ( code ) ) ;
2011-02-28 20:29:34 +01:00
}
2014-11-20 14:20:09 +01:00
void simplifyOperatorName4 ( ) {
2011-02-28 20:29:34 +01:00
const char code [ ] = " void operator==() { } " ;
const char result [ ] = " void operator== ( ) { } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result , tokenizeAndStringify ( code ) ) ;
2011-01-27 18:44:20 +01:00
}
2011-01-30 08:34:58 +01:00
2014-11-20 14:20:09 +01:00
void simplifyOperatorName5 ( ) {
2011-03-29 02:02:06 +02:00
const char code1 [ ] = " std::istream & operator >> (std::istream & s, Fred &f); " ;
const char result1 [ ] = " std :: istream & operator>> ( std :: istream & s , Fred & f ) ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result1 , tokenizeAndStringify ( code1 ) ) ;
2011-03-29 02:02:06 +02:00
const char code2 [ ] = " std::ostream & operator << (std::ostream & s, const Fred &f); " ;
const char result2 [ ] = " std :: ostream & operator<< ( std :: ostream & s , const Fred & f ) ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result2 , tokenizeAndStringify ( code2 ) ) ;
2011-03-29 02:02:06 +02:00
}
2014-11-20 14:20:09 +01:00
void simplifyOperatorName6 ( ) { // ticket #3195
2011-10-12 15:10:34 +02:00
const char code1 [ ] = " value_type * operator ++ (int); " ;
const char result1 [ ] = " value_type * operator++ ( int ) ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result1 , tokenizeAndStringify ( code1 ) ) ;
2011-10-12 15:10:34 +02:00
const char code2 [ ] = " value_type * operator -- (int); " ;
const char result2 [ ] = " value_type * operator-- ( int ) ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result2 , tokenizeAndStringify ( code2 ) ) ;
2011-10-12 15:10:34 +02:00
}
2014-11-20 14:20:09 +01:00
void simplifyOperatorName7 ( ) { // ticket #4619
2013-03-01 13:06:51 +01:00
const char code1 [ ] = " value_type * operator += (int); " ;
const char result1 [ ] = " value_type * operator+= ( int ) ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result1 , tokenizeAndStringify ( code1 ) ) ;
2013-03-01 13:06:51 +01:00
}
2014-11-20 14:20:09 +01:00
void simplifyOperatorName8 ( ) { // ticket #5706
2014-04-26 18:30:09 +02:00
const char code1 [ ] = " value_type * operator += (int) noexcept ; " ;
2017-08-16 11:31:19 +02:00
const char result1 [ ] = " value_type * operator+= ( int ) noexcept ( true ) ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result1 , tokenizeAndStringify ( code1 ) ) ;
2014-04-26 18:30:09 +02:00
const char code2 [ ] = " value_type * operator += (int) noexcept ( true ) ; " ;
const char result2 [ ] = " value_type * operator+= ( int ) noexcept ( true ) ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result2 , tokenizeAndStringify ( code2 ) ) ;
2014-04-26 18:30:09 +02:00
const char code3 [ ] = " value_type * operator += (int) throw ( ) ; " ;
const char result3 [ ] = " value_type * operator+= ( int ) throw ( ) ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result3 , tokenizeAndStringify ( code3 ) ) ;
2014-04-26 18:30:09 +02:00
const char code4 [ ] = " value_type * operator += (int) const noexcept ; " ;
const char result4 [ ] = " value_type * operator+= ( int ) const noexcept ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result4 , tokenizeAndStringify ( code4 ) ) ;
2014-04-26 18:30:09 +02:00
const char code5 [ ] = " value_type * operator += (int) const noexcept ( true ) ; " ;
const char result5 [ ] = " value_type * operator+= ( int ) const noexcept ( true ) ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result5 , tokenizeAndStringify ( code5 ) ) ;
2014-04-26 18:30:09 +02:00
const char code6 [ ] = " value_type * operator += (int) const throw ( ) ; " ;
const char result6 [ ] = " value_type * operator+= ( int ) const throw ( ) ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result6 , tokenizeAndStringify ( code6 ) ) ;
2017-08-16 11:31:19 +02:00
const char code7 [ ] = " value_type * operator += (int) const noexcept ( false ) ; " ;
const char result7 [ ] = " value_type * operator+= ( int ) const noexcept ( false ) ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( result7 , tokenizeAndStringify ( code7 ) ) ;
2017-08-16 11:31:19 +02:00
2014-04-26 18:30:09 +02:00
}
2014-11-20 14:20:09 +01:00
void simplifyOperatorName9 ( ) { // Ticket #5709
2014-05-03 21:35:04 +02:00
const char code [ ] = " struct R { R operator, ( R b ) ; } ; " ;
ASSERT_EQUALS ( code , tokenizeAndStringify ( code ) ) ;
}
2021-11-18 20:25:21 +01:00
void simplifyOperatorName31 ( ) { // #6342
const char code [ ] = " template <typename T> \n "
" struct B { \n "
" typedef T A[3]; \n "
" operator A& () { return x_; } \n "
" A x_; \n "
" }; " ;
ASSERT_EQUALS ( " template < typename T > \n struct B { \n \n operatorT ( & ( ) ) [ 3 ] { return x_ ; } \n T x_ [ 3 ] ; \n } ; " , tokenizeAndStringify ( code ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2018-09-09 21:11:45 +02:00
void simplifyOperatorName10 ( ) { // #8746
2019-03-08 19:26:49 +01:00
const char code1 [ ] = " using a::operator=; " ;
ASSERT_EQUALS ( " using a :: operator= ; " , tokenizeAndStringify ( code1 ) ) ;
2020-04-11 17:36:11 +02:00
const char code2 [ ] = " { return &Fred::operator!=; } " ;
ASSERT_EQUALS ( " { return & Fred :: operator!= ; } " , tokenizeAndStringify ( code2 ) ) ;
2018-09-09 21:11:45 +02:00
}
2018-12-13 06:34:10 +01:00
void simplifyOperatorName11 ( ) { // #8889
const char code [ ] = " auto operator = (const Fred & other) -> Fred & ; " ;
ASSERT_EQUALS ( " auto operator= ( const Fred & other ) . Fred & ; " , tokenizeAndStringify ( code ) ) ;
const char code1 [ ] = " auto operator = (const Fred & other) -> Fred & { } " ;
ASSERT_EQUALS ( " auto operator= ( const Fred & other ) . Fred & { } " , tokenizeAndStringify ( code1 ) ) ;
const char code2 [ ] = " template <typename T> void g(S<&T::operator+ >) {} " ;
ASSERT_EQUALS ( " template < typename T > void g ( S < & T :: operator+ > ) { } " , tokenizeAndStringify ( code2 ) ) ;
const char code3 [ ] = " template <typename T> void g(S<&T::operator int>) {} " ;
ASSERT_EQUALS ( " template < typename T > void g ( S < & T :: operatorint > ) { } " , tokenizeAndStringify ( code3 ) ) ;
const char code4 [ ] = " template <typename T> void g(S<&T::template operator- <double> >) {} " ;
2020-11-28 21:55:28 +01:00
ASSERT_EQUALS ( " template < typename T > void g ( S < & T :: operator- < double > > ) { } " , tokenizeAndStringify ( code4 ) ) ;
2018-12-13 06:34:10 +01:00
}
2019-04-29 15:17:37 +02:00
void simplifyOperatorName12 ( ) { // #9110
const char code [ ] = " namespace a { "
" template <typename b> void operator+(b); "
" } "
" using a::operator+; " ;
ASSERT_EQUALS ( " namespace a { "
" template < typename b > void operator+ ( b ) ; "
" } "
" using a :: operator+ ; " ,
tokenizeAndStringify ( code ) ) ;
}
2019-05-09 09:52:18 +02:00
void simplifyOperatorName13 ( ) { // user defined literal
2019-06-05 10:15:22 +02:00
const char code [ ] = " unsigned long operator \" \" _numch(const char *ch, unsigned long size); " ;
ASSERT_EQUALS ( " unsigned long operator \" \" _numch ( const char * ch , unsigned long size ) ; " ,
2019-05-09 09:52:18 +02:00
tokenizeAndStringify ( code ) ) ;
}
2019-06-05 10:15:22 +02:00
void simplifyOperatorName14 ( ) { // std::complex operator "" if
{
const char code [ ] = " constexpr std::complex<float> operator \" \" if(long double __num); " ;
2021-07-22 07:22:26 +02:00
ASSERT_EQUALS ( " constexpr std :: complex < float > operator \" \" if ( long double __num ) ; " ,
2019-06-05 10:15:22 +02:00
tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " constexpr std::complex<float> operator \" \" if(long double __num) { } " ;
2021-07-22 07:22:26 +02:00
ASSERT_EQUALS ( " constexpr std :: complex < float > operator \" \" if ( long double __num ) { } " ,
2019-06-05 10:15:22 +02:00
tokenizeAndStringify ( code ) ) ;
}
}
2019-11-14 09:26:21 +01:00
void simplifyOperatorName15 ( ) { // ticket #9468 syntaxError
const char code [ ] = " template <typename> struct a; "
" template <typename> struct b { "
" typedef char c; "
" operator c(); "
" }; "
" template <> struct a<char> : b<char> { using b::operator char; }; " ;
ASSERT_EQUALS ( " struct a<char> ; template < typename > struct a ; "
" struct b<char> ; "
" struct a<char> : b<char> { using b :: operatorchar ; } ; struct b<char> { "
" operatorchar ( ) ; "
" } ; " ,
tokenizeAndStringify ( code ) ) ;
}
2019-11-15 07:03:57 +01:00
void simplifyOperatorName16 ( ) { // ticket #9472
{
const char code [ ] = " class I : public A { iterator& operator++() override; }; " ;
ASSERT_EQUALS ( " class I : public A { iterator & operator++ ( ) override ; } ; " ,
tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " class I : public A { iterator& operator++() override { } }; " ;
ASSERT_EQUALS ( " class I : public A { iterator & operator++ ( ) override { } } ; " ,
tokenizeAndStringify ( code ) ) ;
}
}
void simplifyOperatorName17 ( ) {
{
const char code [ ] = " template <class a> void b(a c, a d) { c.operator>() == d; } " ;
ASSERT_EQUALS ( " template < class a > void b ( a c , a d ) { c . operator> ( ) == d ; } " ,
tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " template <class a> void b(a c, a d) { c.operator>() == (d + 1); } " ;
ASSERT_EQUALS ( " template < class a > void b ( a c , a d ) { c . operator> ( ) == ( d + 1 ) ; } " ,
tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " template <class a> void b(a c, a d) { c.operator<() == d; } " ;
ASSERT_EQUALS ( " template < class a > void b ( a c , a d ) { c . operator< ( ) == d ; } " ,
tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " template <class a> void b(a c, a d) { c.operator>() == (d + 1); } " ;
ASSERT_EQUALS ( " template < class a > void b ( a c , a d ) { c . operator> ( ) == ( d + 1 ) ; } " ,
tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " template <class a> void b(a c, a d) { c.operator++() == d; } " ;
ASSERT_EQUALS ( " template < class a > void b ( a c , a d ) { c . operator++ ( ) == d ; } " ,
tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " template <class a> void b(a c, a d) { c.operator++() == (d + 1); } " ;
ASSERT_EQUALS ( " template < class a > void b ( a c , a d ) { c . operator++ ( ) == ( d + 1 ) ; } " ,
tokenizeAndStringify ( code ) ) ;
}
}
2019-11-16 08:03:13 +01:00
void simplifyOperatorName18 ( ) { // global namespace
{
const char code [ ] = " struct Fred { operator std::string() const { return std::string( \" Fred \" ); } }; " ;
ASSERT_EQUALS ( " struct Fred { operatorstd::string ( ) const { return std :: string ( \" Fred \" ) ; } } ; " ,
tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " struct Fred { operator ::std::string() const { return ::std::string( \" Fred \" ); } }; " ;
ASSERT_EQUALS ( " struct Fred { operator::std::string ( ) const { return :: std :: string ( \" Fred \" ) ; } } ; " ,
tokenizeAndStringify ( code ) ) ;
}
}
void simplifyOperatorName19 ( ) {
const char code [ ] = " struct v {}; "
" enum E { e }; "
" struct s { "
" operator struct v() { return v(); }; "
" operator enum E() { return e; } "
" }; "
" void f() { "
" (void)&s::operator struct v; "
" (void)&s::operator enum E; "
" } " ;
ASSERT_EQUALS ( " struct v { } ; "
" enum E { e } ; "
" struct s { "
" operatorstructv ( ) { return v ( ) ; } ; "
" operatorenumE ( ) { return e ; } "
" } ; "
" void f ( ) { "
" ( void ) & s :: operatorstructv ; "
" ( void ) & s :: operatorenumE ; "
" } " ,
tokenizeAndStringify ( code ) ) ;
}
void simplifyOperatorName20 ( ) {
const char code [ ] = " void operator \" \" _a(const char *); "
" namespace N { "
" using ::operator \" \" _a; "
" void operator \" \" _b(const char *); "
" } " ;
ASSERT_EQUALS ( " void operator \" \" _a ( const char * ) ; "
" namespace N { "
" using :: operator \" \" _a ; "
" void operator \" \" _b ( const char * ) ; "
" } " ,
tokenizeAndStringify ( code ) ) ;
}
void simplifyOperatorName21 ( ) {
const char code [ ] = " template<char...> void operator \" \" _h() {} "
" template<> void operator \" \" _h<'a', 'b', 'c'>() {} "
" template void operator \" \" _h<'a', 'b', 'c', 'd'>(); " ;
ASSERT_EQUALS ( " void operator \" \" _h<'a','b','c'> ( ) ; "
" void operator \" \" _h<'a','b','c','d'> ( ) ; "
" void operator \" \" _h<'a','b','c'> ( ) { } "
" void operator \" \" _h<'a','b','c','d'> ( ) { } " ,
tokenizeAndStringify ( code ) ) ;
}
void simplifyOperatorName22 ( ) {
const char code [ ] = " static RSLRelOp convertOperator(const Software::ComparisonOperator& op) { "
" if (op == &Software::operator==) return RSLEqual; "
" return RSLNotEqual; "
" } " ;
ASSERT_EQUALS ( " static RSLRelOp convertOperator ( const Software :: ComparisonOperator & op ) { "
" if ( op == & Software :: operator== ) { return RSLEqual ; } "
" return RSLNotEqual ; "
" } " ,
tokenizeAndStringify ( code ) ) ;
}
2019-11-18 06:38:53 +01:00
void simplifyOperatorName23 ( ) {
{
const char code [ ] = " double *vtkMatrix3x3::operator[](const unsigned int i) { "
" VTK_LEGACY_BODY(vtkMatrix3x3::operator[], \" VTK 7.0 \" ); "
" return &(this->Element[i][0]); "
" } " ;
ASSERT_EQUALS ( " double * vtkMatrix3x3 :: operator[] ( const unsigned int i ) { "
" VTK_LEGACY_BODY ( vtkMatrix3x3 :: operator[] , \" VTK 7.0 \" ) ; "
" return & ( this . Element [ i ] [ 0 ] ) ; "
" } " ,
tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " double *vtkMatrix3x3::operator,(const unsigned int i) { "
" VTK_LEGACY_BODY(vtkMatrix3x3::operator,, \" VTK 7.0 \" ); "
" return &(this->Element[i][0]); "
" } " ;
ASSERT_EQUALS ( " double * vtkMatrix3x3 :: operator, ( const unsigned int i ) { "
" VTK_LEGACY_BODY ( vtkMatrix3x3 :: operator, , \" VTK 7.0 \" ) ; "
" return & ( this . Element [ i ] [ 0 ] ) ; "
" } " ,
tokenizeAndStringify ( code ) ) ;
}
}
2019-11-20 22:13:32 +01:00
void simplifyOperatorName24 ( ) {
{
const char code [ ] = " void foo() { int i = a.operator++() ? a.operator--() : 0; } " ;
ASSERT_EQUALS ( " void foo ( ) { int i ; i = a . operator++ ( ) ? a . operator-- ( ) : 0 ; } " ,
tokenizeAndStringify ( code ) ) ;
}
{
const char code [ ] = " void foo() { int i = a.operator++(0) ? a.operator--(0) : 0; } " ;
ASSERT_EQUALS ( " void foo ( ) { int i ; i = a . operator++ ( 0 ) ? a . operator-- ( 0 ) : 0 ; } " ,
tokenizeAndStringify ( code ) ) ;
}
}
2019-11-23 17:42:24 +01:00
void simplifyOperatorName25 ( ) {
const char code [ ] = " bool negative(const Number &num) { return num.operator std::string()[0] == '-'; } " ;
ASSERT_EQUALS ( " bool negative ( const Number & num ) { return num . operatorstd::string ( ) [ 0 ] == '-' ; } " ,
tokenizeAndStringify ( code ) ) ;
}
2020-05-04 21:33:30 +02:00
void simplifyOperatorName26 ( ) {
const char code [ ] = " void foo() { "
" x = y.operator *().z[123]; "
" } " ;
ASSERT_EQUALS ( " void foo ( ) { x = y . operator* ( ) . z [ 123 ] ; } " ,
tokenizeAndStringify ( code ) ) ;
}
2020-06-25 22:06:34 +02:00
void simplifyOperatorName27 ( ) {
const char code [ ] = " int operator \" \" i (const char *, int); \n "
" x = \" abc \" i; " ;
ASSERT_EQUALS ( " int operator \" \" i ( const char * , int ) ; \n "
" x = operator \" \" i ( \" abc \" , 3 ) ; " ,
tokenizeAndStringify ( code ) ) ;
}
2021-01-14 20:56:11 +01:00
void simplifyOperatorName28 ( ) {
const char code [ ] = " template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; \n "
" int main() { } " ;
ASSERT_EQUALS ( " template < class ... Ts > struct overloaded : Ts ... { using Ts :: operator ( ) ... ; } ; \n "
" int main ( ) { } " ,
tokenizeAndStringify ( code ) ) ;
}
2021-04-22 19:15:22 +02:00
void simplifyOperatorName29 ( ) {
Settings settings ;
settings . standards . cpp = Standards : : CPP20 ;
ASSERT_EQUALS ( " auto operator<=> ( ) ; " , tokenizeAndStringify ( " auto operator<=>(); " , settings ) ) ;
}
2020-09-06 21:02:06 +02:00
void simplifyOverloadedOperators1 ( ) {
const char code [ ] = " struct S { void operator()(int); }; \n "
" \n "
" void foo(S x) { \n "
" x(123); \n "
" } " ;
ASSERT_EQUALS ( " struct S { void operator() ( int ) ; } ; \n "
" \n "
" void foo ( S x ) { \n "
" x . operator() ( 123 ) ; \n "
" } " ,
tokenizeAndStringify ( code ) ) ;
}
2020-09-07 20:07:02 +02:00
void simplifyOverloadedOperators2 ( ) { // #9879 - (*this)(123);
const char code [ ] = " struct S { \n "
" void operator()(int); \n "
" void foo() { (*this)(123); } \n "
" }; \n " ;
ASSERT_EQUALS ( " struct S { \n "
" void operator() ( int ) ; \n "
" void foo ( ) { ( * this ) . operator() ( 123 ) ; } \n "
" } ; " ,
tokenizeAndStringify ( code ) ) ;
}
2020-09-07 21:32:29 +02:00
void simplifyOverloadedOperators3 ( ) { // #9881
const char code [ ] = " struct Func { double operator()(double x) const; }; \n "
" void foo(double, double); \n "
" void test() { \n "
" Func max; \n "
" double y = 0; \n "
" foo(0, max(y)); \n "
" } " ;
ASSERT_EQUALS ( " struct Func { double operator() ( double x ) const ; } ; \n "
" void foo ( double , double ) ; \n "
" void test ( ) { \n "
" Func max ; \n "
" double y ; y = 0 ; \n "
" foo ( 0 , max . operator() ( y ) ) ; \n "
" } " ,
tokenizeAndStringify ( code ) ) ;
}
2014-11-20 14:20:09 +01:00
void simplifyNullArray ( ) {
2012-08-26 10:03:05 +02:00
ASSERT_EQUALS ( " * ( foo . bar [ 5 ] ) = x ; " , tokenizeAndStringify ( " 0[foo.bar[5]] = x; " ) ) ;
}
2014-11-20 14:20:09 +01:00
void removeMacrosInGlobalScope ( ) {
2011-01-30 08:34:58 +01:00
// remove some unhandled macros in the global scope.
ASSERT_EQUALS ( " void f ( ) { } " , tokenizeAndStringify ( " void f() NOTHROW { } " ) ) ;
2011-03-30 19:49:55 +02:00
ASSERT_EQUALS ( " struct Foo { } ; " , tokenizeAndStringify ( " struct __declspec(dllexport) Foo {}; " ) ) ;
2020-06-07 13:49:04 +02:00
ASSERT_EQUALS ( " namespace { int a ; } " , tokenizeAndStringify ( " ABA() namespace { int a ; } " ) ) ;
2012-06-12 18:45:31 +02:00
// #3750
2019-09-13 13:05:26 +02:00
ASSERT_THROW ( tokenizeAndStringify ( " ; AB(foo*) foo::foo() { } " ) , InternalError ) ;
2012-06-13 19:21:20 +02:00
2018-11-13 16:49:02 +01:00
// #4834 - syntax error
ASSERT_THROW ( tokenizeAndStringify ( " A(B) foo() {} " ) , InternalError ) ;
2013-06-16 15:41:13 +02:00
2012-06-13 19:21:20 +02:00
// #3855
ASSERT_EQUALS ( " ; class foo { } " ,
tokenizeAndStringify ( " ; AB class foo { } " ) ) ;
ASSERT_EQUALS ( " ; CONST struct ABC abc ; " ,
tokenizeAndStringify ( " ; CONST struct ABC abc ; " ) ) ;
2019-09-13 13:05:26 +02:00
2020-05-17 19:12:16 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " class A { \n "
" UNKNOWN_MACRO(A) \n " // <- this macro is ignored
" private: \n "
" int x; \n "
" }; " ) ) ;
2019-09-13 13:05:26 +02:00
ASSERT_THROW ( tokenizeAndStringify ( " MACRO(test) void test() { } " ) , InternalError ) ; // #7931
2019-09-15 21:07:20 +02:00
ASSERT_THROW ( tokenizeAndStringify ( " BEGIN_MESSAGE_MAP(CSetProgsAdvDlg, CResizableStandAloneDialog) \n "
" ON_BN_CLICKED(IDC_ADDTOOL, OnBnClickedAddtool) \n "
" END_MESSAGE_MAP() \n "
" \n "
" BOOL CSetProgsAdvDlg::OnInitDialog() {} " ) ,
InternalError ) ;
2011-01-30 08:34:58 +01:00
}
2011-03-26 12:20:23 +01:00
2014-11-20 14:20:09 +01:00
void removeMacroInVarDecl ( ) { // #4304
2012-11-29 08:44:12 +01:00
// only remove macros with parentheses (those hurt most)
ASSERT_EQUALS ( " void f ( ) { PROGMEM int x ; } " , tokenizeAndStringify ( " void f() { PROGMEM int x ; } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { int x ; } " , tokenizeAndStringify ( " void f() { SECTION( \" .data.ro \" ) int x ; } " ) ) ;
// various variable declarations
ASSERT_EQUALS ( " void f ( ) { CONST int x ; } " , tokenizeAndStringify ( " void f() { SECTION( \" .data.ro \" ) CONST int x ; } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { char a [ 4 ] ; } " , tokenizeAndStringify ( " void f() { SECTION( \" .data.ro \" ) char a[4]; } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { const char a [ 4 ] ; } " , tokenizeAndStringify ( " void f() { SECTION( \" .data.ro \" ) const char a[4]; } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { struct ABC abc ; } " , tokenizeAndStringify ( " void f() { SECTION( \" .data.ro \" ) struct ABC abc; } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { CONST struct ABC abc ; } " , tokenizeAndStringify ( " void f() { SECTION( \" .data.ro \" ) CONST struct ABC abc; } " ) ) ;
}
2019-11-02 19:34:19 +01:00
void addSemicolonAfterUnknownMacro ( ) {
// #6975
ASSERT_EQUALS ( " void f ( ) { MACRO ( ) ; try { } } " , tokenizeAndStringify ( " void f() { MACRO() try {} } " ) ) ;
// #9376
ASSERT_EQUALS ( " MACRO ( ) ; using namespace foo ; " , tokenizeAndStringify ( " MACRO() using namespace foo; " ) ) ;
}
2014-11-20 14:20:09 +01:00
void multipleAssignment ( ) {
2011-03-26 12:20:23 +01:00
ASSERT_EQUALS ( " a = b = 0 ; " , tokenizeAndStringify ( " a=b=0; " ) ) ;
}
2011-06-11 21:51:12 +02:00
2014-11-20 14:20:09 +01:00
void platformWin ( ) {
2012-11-11 16:16:17 +01:00
const char code [ ] = " BOOL f; "
2011-09-18 19:06:54 +02:00
" BOOLEAN g; "
" BYTE h; "
" CHAR i; "
" DWORD j; "
" FLOAT k; "
" INT l; "
" INT32 m; "
" INT64 n; "
" LONG o; "
" SHORT p; "
" UCHAR q; "
" UINT r; "
" ULONG s; "
" USHORT t; "
" WORD u; "
2011-09-20 05:14:58 +02:00
" VOID *v; "
" LPBOOL w; "
" PBOOL x; "
" LPBYTE y; "
" PBOOLEAN z; "
" PBYTE A; "
" LPCSTR B; "
" PCSTR C; "
" LPCVOID D; "
" LPDWORD E; "
" LPINT F; "
" PINT G; "
" LPLONG H; "
" PLONG I; "
" LPSTR J; "
" PSTR K; "
" PCHAR L; "
" LPVOID M; "
2011-09-21 02:17:02 +02:00
" PVOID N; "
2012-01-18 12:57:41 +01:00
" BOOL _bool; "
" HFILE hfile; "
" LONG32 long32; "
" LCID lcid; "
" LCTYPE lctype; "
" LGRPID lgrpid; "
" LONG64 long64; "
" PUCHAR puchar; "
" LPCOLORREF lpcolorref; "
" PDWORD pdword; "
" PULONG pulong; "
" SERVICE_STATUS_HANDLE service_status_hanlde; "
" SC_LOCK sc_lock; "
" SC_HANDLE sc_handle; "
" HACCEL haccel; "
" HCONV hconv; "
" HCONVLIST hconvlist; "
" HDDEDATA hddedata; "
" HDESK hdesk; "
" HDROP hdrop; "
" HDWP hdwp; "
" HENHMETAFILE henhmetafile; "
" HHOOK hhook; "
" HKL hkl; "
" HMONITOR hmonitor; "
" HSZ hsz; "
" HWINSTA hwinsta; "
" PWCHAR pwchar; "
" PUSHORT pushort; "
" LANGID langid; "
" DWORD64 dword64; "
" ULONG64 ulong64; "
2012-11-11 15:40:06 +01:00
" LPWSTR lpcwstr; "
2018-05-15 09:43:28 +02:00
" LPCWSTR lpcwstr; "
2018-05-16 09:16:12 +02:00
" LPHANDLE lpHandle; "
" PCWSTR pcwStr; "
" PDWORDLONG pdWordLong; "
" PDWORD_PTR pdWordPtr; "
" PDWORD32 pdWord32; "
" PDWORD64 pdWord64; "
2018-05-16 16:26:40 +02:00
" LONGLONG ll; "
" USN usn; "
" PULONG64 puLong64; "
" PULONG32 puLong32; "
2018-05-15 09:43:28 +02:00
" PFLOAT ptrToFloat; " ;
2011-09-18 16:31:31 +02:00
2012-11-11 16:16:17 +01:00
const char expected [ ] = " int f ; "
2011-09-18 19:06:54 +02:00
" unsigned char g ; "
" unsigned char h ; "
" char i ; "
" unsigned long j ; "
" float k ; "
" int l ; "
" int m ; "
" long long n ; "
" long o ; "
" short p ; "
" unsigned char q ; "
" unsigned int r ; "
" unsigned long s ; "
" unsigned short t ; "
" unsigned short u ; "
2011-09-20 05:14:58 +02:00
" void * v ; "
" int * w ; "
" int * x ; "
" unsigned char * y ; "
" unsigned char * z ; "
" unsigned char * A ; "
" const char * B ; "
" const char * C ; "
" const void * D ; "
" unsigned long * E ; "
" int * F ; "
" int * G ; "
" long * H ; "
" long * I ; "
" char * J ; "
" char * K ; "
" char * L ; "
" void * M ; "
2011-09-21 02:17:02 +02:00
" void * N ; "
2012-01-18 12:57:41 +01:00
" int _bool ; "
" int hfile ; "
" int long32 ; "
" unsigned long lcid ; "
" unsigned long lctype ; "
" unsigned long lgrpid ; "
" long long long64 ; "
" unsigned char * puchar ; "
" unsigned long * lpcolorref ; "
" unsigned long * pdword ; "
" unsigned long * pulong ; "
" void * service_status_hanlde ; "
" void * sc_lock ; "
" void * sc_handle ; "
" void * haccel ; "
" void * hconv ; "
" void * hconvlist ; "
" void * hddedata ; "
" void * hdesk ; "
" void * hdrop ; "
" void * hdwp ; "
" void * henhmetafile ; "
" void * hhook ; "
" void * hkl ; "
" void * hmonitor ; "
" void * hsz ; "
" void * hwinsta ; "
2012-11-11 15:40:06 +01:00
" wchar_t * pwchar ; "
2012-01-18 12:57:41 +01:00
" unsigned short * pushort ; "
" unsigned short langid ; "
2013-08-25 08:29:24 +02:00
" unsigned long long dword64 ; "
" unsigned long long ulong64 ; "
2012-11-11 15:40:06 +01:00
" wchar_t * lpcwstr ; "
2018-05-15 09:43:28 +02:00
" const wchar_t * lpcwstr ; "
2018-05-16 09:16:12 +02:00
" void * lpHandle ; "
" const wchar_t * pcwStr ; "
" long * pdWordLong ; "
" long * pdWordPtr ; "
" unsigned int * pdWord32 ; "
" unsigned long * pdWord64 ; "
2018-05-16 16:26:40 +02:00
" long long ll ; "
" long long usn ; "
" unsigned long long * puLong64 ; "
" unsigned int * puLong32 ; "
2018-05-15 09:43:28 +02:00
" float * ptrToFloat ; " ;
2011-09-18 16:31:31 +02:00
2012-11-11 16:16:17 +01:00
// These types should be defined the same on all Windows platforms
2021-04-06 21:21:53 +02:00
const std : : string win32A = tokenizeAndStringifyWindows ( code , true , Settings : : Win32A ) ;
2012-11-11 16:16:17 +01:00
ASSERT_EQUALS ( expected , win32A ) ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( win32A , tokenizeAndStringifyWindows ( code , true , Settings : : Win32W ) ) ;
ASSERT_EQUALS ( win32A , tokenizeAndStringifyWindows ( code , true , Settings : : Win64 ) ) ;
2011-09-24 20:51:03 +02:00
}
2014-11-20 14:20:09 +01:00
void platformWin32A ( ) {
2011-09-24 22:02:56 +02:00
const char code [ ] = " wchar_t wc; "
" TCHAR c; "
2011-09-24 20:51:03 +02:00
" PTSTR ptstr; "
" LPTSTR lptstr; "
" PCTSTR pctstr; "
" LPCTSTR lpctstr; "
" void foo() { "
2011-09-27 04:08:24 +02:00
" TCHAR tc = _T( \' c \' ); "
2011-09-24 20:51:03 +02:00
" TCHAR src[10] = _T( \" 123456789 \" ); "
" TCHAR dst[10]; "
" _tcscpy(dst, src); "
" dst[0] = 0; "
2011-09-24 22:02:56 +02:00
" _tcscat(dst, src); "
2011-09-27 13:29:36 +02:00
" LPTSTR d = _tcsdup(str); "
2017-05-18 21:52:31 +02:00
" _tprintf(_T( \" Hello world! \" )); "
" _stprintf(dst, _T( \" Hello! \" )); "
" _sntprintf(dst, sizeof(dst) / sizeof(TCHAR), _T( \" Hello world! \" )); "
2011-09-25 16:02:27 +02:00
" _tscanf(_T( \" %s \" ), dst); "
" _stscanf(dst, _T( \" %s \" ), dst); "
2012-01-18 12:57:41 +01:00
" } "
" TBYTE tbyte; " ;
2012-11-11 15:16:08 +01:00
const char expected [ ] = " wchar_t wc ; "
2011-09-24 22:02:56 +02:00
" char c ; "
2011-09-24 20:51:03 +02:00
" char * ptstr ; "
" char * lptstr ; "
" const char * pctstr ; "
" const char * lpctstr ; "
" void foo ( ) { "
2011-09-27 04:08:24 +02:00
" char tc ; tc = \' c \' ; "
2011-09-24 20:51:03 +02:00
" char src [ 10 ] = \" 123456789 \" ; "
" char dst [ 10 ] ; "
" strcpy ( dst , src ) ; "
" dst [ 0 ] = 0 ; "
2011-09-24 22:02:56 +02:00
" strcat ( dst , src ) ; "
2011-09-27 13:29:36 +02:00
" char * d ; d = strdup ( str ) ; "
2017-05-18 21:52:31 +02:00
" printf ( \" Hello world! \" ) ; "
" sprintf ( dst , \" Hello! \" ) ; "
" _snprintf ( dst , sizeof ( dst ) / sizeof ( char ) , \" Hello world! \" ) ; "
2011-09-25 16:02:27 +02:00
" scanf ( \" %s \" , dst ) ; "
" sscanf ( dst , \" %s \" , dst ) ; "
2012-01-18 12:57:41 +01:00
" } "
2014-10-19 07:34:40 +02:00
" unsigned char tbyte ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringifyWindows ( code , true , Settings : : Win32A ) ) ;
2011-09-24 20:51:03 +02:00
}
2014-11-20 14:20:09 +01:00
void platformWin32W ( ) {
2011-09-24 22:02:56 +02:00
const char code [ ] = " wchar_t wc; "
" TCHAR c; "
" PTSTR ptstr; "
" LPTSTR lptstr; "
" PCTSTR pctstr; "
" LPCTSTR lpctstr; "
2012-01-18 12:57:41 +01:00
" TBYTE tbyte; "
2011-09-24 22:02:56 +02:00
" void foo() { "
2011-09-27 04:08:24 +02:00
" TCHAR tc = _T( \' c \' ); "
2011-09-24 22:02:56 +02:00
" TCHAR src[10] = _T( \" 123456789 \" ); "
" TCHAR dst[10]; "
" _tcscpy(dst, src); "
" dst[0] = 0; "
" _tcscat(dst, src); "
2011-09-27 13:29:36 +02:00
" LPTSTR d = _tcsdup(str); "
2017-05-18 21:52:31 +02:00
" _tprintf(_T( \" Hello world! \" )); "
" _stprintf(dst, _T( \" Hello! \" )); "
" _sntprintf(dst, sizeof(dst) / sizeof(TCHAR), _T( \" Hello world! \" )); "
2011-09-25 16:02:27 +02:00
" _tscanf(_T( \" %s \" ), dst); "
" _stscanf(dst, _T( \" %s \" ), dst); "
2011-09-24 22:02:56 +02:00
" } " ;
2012-11-11 15:16:08 +01:00
const char expected [ ] = " wchar_t wc ; "
" wchar_t c ; "
2012-11-11 15:40:06 +01:00
" wchar_t * ptstr ; "
" wchar_t * lptstr ; "
" const wchar_t * pctstr ; "
" const wchar_t * lpctstr ; "
2014-10-19 07:34:40 +02:00
" unsigned wchar_t tbyte ; "
2011-09-24 22:02:56 +02:00
" void foo ( ) { "
2013-09-06 05:36:33 +02:00
" wchar_t tc ; tc = L \' c \' ; "
" wchar_t src [ 10 ] = L \" 123456789 \" ; "
2012-11-11 15:16:08 +01:00
" wchar_t dst [ 10 ] ; "
2011-09-24 22:02:56 +02:00
" wcscpy ( dst , src ) ; "
" dst [ 0 ] = 0 ; "
" wcscat ( dst , src ) ; "
2012-11-11 15:40:06 +01:00
" wchar_t * d ; d = wcsdup ( str ) ; "
2017-05-18 21:52:31 +02:00
" wprintf ( L \" Hello world! \" ) ; "
" swprintf ( dst , L \" Hello! \" ) ; "
" _snwprintf ( dst , sizeof ( dst ) / sizeof ( wchar_t ) , L \" Hello world! \" ) ; "
2013-09-06 05:36:33 +02:00
" wscanf ( L \" %s \" , dst ) ; "
" swscanf ( dst , L \" %s \" , dst ) ; "
2011-09-24 22:02:56 +02:00
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringifyWindows ( code , true , Settings : : Win32W ) ) ;
2011-09-18 01:40:52 +02:00
}
2012-09-03 18:51:15 +02:00
2014-11-20 14:20:09 +01:00
void platformWin32AStringCat ( ) { //#5150
2013-09-06 05:36:33 +02:00
const char code [ ] = " TCHAR text[] = _T( \" 123 \" ) _T( \" 456 \" ) _T( \" 789 \" ); " ;
const char expected [ ] = " char text [ 10 ] = \" 123456789 \" ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringifyWindows ( code , true , Settings : : Win32A ) ) ;
2013-09-06 05:36:33 +02:00
}
2014-11-20 14:20:09 +01:00
void platformWin32WStringCat ( ) { //#5150
2013-09-06 05:36:33 +02:00
const char code [ ] = " TCHAR text[] = _T( \" 123 \" ) _T( \" 456 \" ) _T( \" 789 \" ); " ;
const char expected [ ] = " wchar_t text [ 10 ] = L \" 123456789 \" ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected , tokenizeAndStringifyWindows ( code , true , Settings : : Win32W ) ) ;
2014-10-19 07:34:40 +02:00
}
2014-11-20 14:20:09 +01:00
void platformWinWithNamespace ( ) {
2014-10-19 07:34:40 +02:00
const char code1 [ ] = " UINT32 a; ::UINT32 b; foo::UINT32 c; " ;
const char expected1 [ ] = " unsigned int a ; unsigned int b ; foo :: UINT32 c ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected1 , tokenizeAndStringifyWindows ( code1 , true , Settings : : Win32A ) ) ;
2014-10-19 07:34:40 +02:00
const char code2 [ ] = " LPCVOID a; ::LPCVOID b; foo::LPCVOID c; " ;
const char expected2 [ ] = " const void * a ; const void * b ; foo :: LPCVOID c ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected2 , tokenizeAndStringifyWindows ( code2 , true , Settings : : Win32A ) ) ;
2013-09-06 05:36:33 +02:00
}
2014-11-20 14:20:09 +01:00
void isZeroNumber ( ) const {
2013-10-01 20:30:59 +02:00
ASSERT_EQUALS ( true , Tokenizer : : isZeroNumber ( " 0.0 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isZeroNumber ( " +0.0 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isZeroNumber ( " -0.0 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isZeroNumber ( " +0L " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isZeroNumber ( " +0 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isZeroNumber ( " -0 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isZeroNumber ( " -0E+0 " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isZeroNumber ( " 1.0 " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isZeroNumber ( " +1.0 " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isZeroNumber ( " -1 " ) ) ;
2013-10-03 20:52:07 +02:00
ASSERT_EQUALS ( false , Tokenizer : : isZeroNumber ( " " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isZeroNumber ( " garbage " ) ) ;
2014-02-20 16:56:49 +01:00
ASSERT_EQUALS ( false , Tokenizer : : isZeroNumber ( " E2 " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isZeroNumber ( " 2e " ) ) ;
2013-10-01 20:30:59 +02:00
}
2014-11-20 14:20:09 +01:00
void isOneNumber ( ) const {
2013-10-01 20:30:59 +02:00
ASSERT_EQUALS ( true , Tokenizer : : isOneNumber ( " 1.0 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isOneNumber ( " +1.0 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isOneNumber ( " 1.0e+0 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isOneNumber ( " +1L " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isOneNumber ( " +1 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isOneNumber ( " 1 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isOneNumber ( " +1E+0 " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isOneNumber ( " 0.0 " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isOneNumber ( " +0.0 " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isOneNumber ( " -0 " ) ) ;
2013-10-03 20:52:07 +02:00
ASSERT_EQUALS ( false , Tokenizer : : isOneNumber ( " " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isOneNumber ( " garbage " ) ) ;
2013-10-01 20:30:59 +02:00
}
2014-11-20 14:20:09 +01:00
void isTwoNumber ( ) const {
2013-10-03 15:41:12 +02:00
ASSERT_EQUALS ( true , Tokenizer : : isTwoNumber ( " 2.0 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isTwoNumber ( " +2.0 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isTwoNumber ( " 2.0e+0 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isTwoNumber ( " +2L " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isTwoNumber ( " +2 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isTwoNumber ( " 2 " ) ) ;
ASSERT_EQUALS ( true , Tokenizer : : isTwoNumber ( " +2E+0 " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isTwoNumber ( " 0.0 " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isTwoNumber ( " +0.0 " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isTwoNumber ( " -0 " ) ) ;
2013-10-03 20:52:07 +02:00
ASSERT_EQUALS ( false , Tokenizer : : isTwoNumber ( " " ) ) ;
ASSERT_EQUALS ( false , Tokenizer : : isTwoNumber ( " garbage " ) ) ;
2013-10-03 15:41:12 +02:00
}
2014-11-20 14:20:09 +01:00
void simplifyStaticConst ( ) {
2014-07-02 08:59:04 +02:00
const char code1 [ ] = " class foo { public: bool const static c ; } " ;
const char expected1 [ ] = " class foo { public: static const bool c ; } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected1 , tokenizeAndStringify ( code1 ) ) ;
2014-07-02 08:59:04 +02:00
const char code2 [ ] =
" int long long f() \n "
" { \n "
" static const long long signed int i1; \n "
" static const long long int signed i2; \n "
" static const signed long long int i3; \n "
" static const signed int long long i4; \n "
" static const int signed long long i5; \n "
" static const int long long signed i6; \n "
" long long static const signed int i7; \n "
" long long static const int signed i8; \n "
" signed static const long long int i9; \n "
" signed static const int long long i10; \n "
" int static const signed long long i11; \n "
" int static const long long signed i12; \n "
" long long signed int static const i13; \n "
" long long int signed static const i14; \n "
" signed long long int static const i15; \n "
" signed int long long static const i16; \n "
" int signed long long static const i17; \n "
" int long long signed static const i18; \n "
" return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12 \n "
" + i13 + i14 + i15 + i16 + i17 + i18; \n "
" } " ;
const char expected2 [ ] =
" long long f ( ) \n "
" { \n "
" static const signed long long i1 ; \n "
" static const signed long long i2 ; \n "
" static const signed long long i3 ; \n "
" static const signed long long i4 ; \n "
" static const signed long long i5 ; \n "
" static const signed long long i6 ; \n "
2015-08-27 14:34:00 +02:00
" static const signed long long i7 ; \n "
" static const signed long long i8 ; \n "
" static const signed long long i9 ; \n "
" static const signed long long i10 ; \n "
" static const signed long long i11 ; \n "
" static const signed long long i12 ; \n "
2014-07-02 08:59:04 +02:00
" static const signed long long i13 ; \n "
" static const signed long long i14 ; \n "
" static const signed long long i15 ; \n "
" static const signed long long i16 ; \n "
" static const signed long long i17 ; \n "
" static const signed long long i18 ; \n "
" return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12 \n "
" + i13 + i14 + i15 + i16 + i17 + i18 ; \n "
" } " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected2 , tokenizeAndStringify ( code2 ) ) ;
2015-08-29 10:57:52 +02:00
const char code3 [ ] = " const unsigned long extern int i; " ;
const char expected3 [ ] = " extern const unsigned long i ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected3 , tokenizeAndStringify ( code3 ) ) ;
2014-07-02 08:59:04 +02:00
}
2014-04-13 12:47:54 +02:00
2018-02-16 22:25:51 +01:00
void simplifyCPPAttribute ( ) {
2015-05-10 12:35:47 +02:00
ASSERT_EQUALS ( " int f ( ) ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " [[deprecated]] int f(); " , true , Settings : : Native , " test.cpp " , true ) ) ;
2015-05-10 12:35:47 +02:00
ASSERT_EQUALS ( " [ [ deprecated ] ] int f ( ) ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " [[deprecated]] int f(); " , true , Settings : : Native , " test.cpp " , false ) ) ;
2015-05-10 12:35:47 +02:00
ASSERT_EQUALS ( " [ [ deprecated ] ] int f ( ) ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " [[deprecated]] int f(); " , true , Settings : : Native , " test.c " , true ) ) ;
2018-02-16 22:25:51 +01:00
ASSERT_EQUALS ( " template < class T > int f ( ) { } " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " template <class T> [[noreturn]] int f(){} " , true , Settings : : Native , " test.cpp " , true ) ) ;
2018-02-16 22:25:51 +01:00
ASSERT_EQUALS ( " int f ( int i ) ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " [[maybe_unused]] int f([[maybe_unused]] int i); " , true , Settings : : Native , " test.cpp " , true ) ) ;
2018-02-16 22:25:51 +01:00
ASSERT_EQUALS ( " [ [ maybe_unused ] ] int f ( [ [ maybe_unused ] ] int i ) ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " [[maybe_unused]] int f([[maybe_unused]] int i); " , true , Settings : : Native , " test.cpp " , false ) ) ;
2018-02-16 22:25:51 +01:00
2019-12-06 05:17:19 +01:00
ASSERT_EQUALS ( " struct a ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " struct [[]] a; " , true , Settings : : Native , " test.cpp " , true ) ) ;
2019-12-06 05:17:19 +01:00
ASSERT_EQUALS ( " struct a ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " struct [[,]] a; " , true , Settings : : Native , " test.cpp " , true ) ) ;
2019-12-06 05:17:19 +01:00
ASSERT_EQUALS ( " struct a ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " struct [[deprecated,]] a; " , true , Settings : : Native , " test.cpp " , true ) ) ;
2019-12-06 05:17:19 +01:00
ASSERT_EQUALS ( " struct a ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " struct [[,,]] a; " , true , Settings : : Native , " test.cpp " , true ) ) ;
2019-12-06 05:17:19 +01:00
ASSERT_EQUALS ( " struct a ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " struct [[deprecated,,]] a; " , true , Settings : : Native , " test.cpp " , true ) ) ;
2019-12-06 05:17:19 +01:00
ASSERT_EQUALS ( " struct a ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " struct [[deprecated,maybe_unused,]] a; " , true , Settings : : Native , " test.cpp " , true ) ) ;
2019-12-06 05:17:19 +01:00
ASSERT_EQUALS ( " struct a ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " struct [[,,,]] a; " , true , Settings : : Native , " test.cpp " , true ) ) ;
2021-03-20 10:38:47 +01:00
ASSERT_EQUALS ( " struct a ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " struct alignas(int) a; " , true , Settings : : Native , " test.cpp " , true ) ) ;
2021-03-20 10:38:47 +01:00
ASSERT_EQUALS ( " struct a ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " struct alignas ( alignof ( float ) ) a; " , true , Settings : : Native , " test.cpp " , true ) ) ;
2021-03-20 10:38:47 +01:00
ASSERT_EQUALS ( " char a [ 256 ] ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " alignas(256) char a[256]; " , true , Settings : : Native , " test.cpp " , true ) ) ;
2021-03-20 10:38:47 +01:00
ASSERT_EQUALS ( " struct a ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " struct alignas(float) [[deprecated(reason)]] a; " , true , Settings : : Native , " test.cpp " , true ) ) ;
2021-03-20 10:38:47 +01:00
ASSERT_EQUALS ( " struct a ; " ,
2021-04-06 21:21:53 +02:00
tokenizeAndStringify ( " struct [[deprecated,maybe_unused]] alignas(double) [[trivial_abi]] a; " , true , Settings : : Native , " test.cpp " , true ) ) ;
2015-05-10 12:35:47 +02:00
}
2015-11-06 18:39:03 +01:00
void simplifyCaseRange ( ) {
2017-09-16 02:13:48 +02:00
ASSERT_EQUALS ( " void f ( ) { switch ( x ) { case 1 : case 2 : case 3 : case 4 : ; } } " , tokenizeAndStringify ( " void f() { switch(x) { case 1 ... 4: } } " ) ) ;
2019-09-04 08:07:30 +02:00
ASSERT_EQUALS ( " void f ( ) { switch ( x ) { case 4 ... 1 : ; } } " , tokenizeAndStringify ( " void f() { switch(x) { case 4 ... 1: } } " ) ) ;
2017-09-16 02:13:48 +02:00
tokenizeAndStringify ( " void f() { switch(x) { case 1 ... 1000000: } } " ) ; // Do not run out of memory
2015-11-06 18:46:43 +01:00
2021-05-08 11:24:07 +02:00
ASSERT_EQUALS ( " void f ( ) { switch ( x ) { case 'a' : case 98 : case 'c' : ; } } " , tokenizeAndStringify ( " void f() { switch(x) { case 'a' ... 'c': } } " ) ) ;
2019-09-04 08:07:30 +02:00
ASSERT_EQUALS ( " void f ( ) { switch ( x ) { case 'c' ... 'a' : ; } } " , tokenizeAndStringify ( " void f() { switch(x) { case 'c' ... 'a': } } " ) ) ;
2019-07-15 09:29:47 +02:00
2021-05-08 11:24:07 +02:00
ASSERT_EQUALS ( " void f ( ) { switch ( x ) { case '[' : case 92 : case ']' : ; } } " , tokenizeAndStringify ( " void f() { switch(x) { case '[' ... ']': } } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { switch ( x ) { case '&' : case 39 : case '(' : ; } } " , tokenizeAndStringify ( " void f() { switch(x) { case '&' ... '(': } } " ) ) ;
ASSERT_EQUALS ( " void f ( ) { switch ( x ) { case ' \\ x61' : case 98 : case ' \\ x63' : ; } } " , tokenizeAndStringify ( " void f() { switch(x) { case ' \\ x61' ... ' \\ x63': } } " ) ) ;
2015-11-06 18:39:03 +01:00
}
2020-06-07 13:49:04 +02:00
void simplifyEmptyNamespaces ( ) {
2020-11-22 16:43:36 +01:00
ASSERT_EQUALS ( " ; " , tokenizeAndStringify ( " namespace { } " ) ) ;
ASSERT_EQUALS ( " ; " , tokenizeAndStringify ( " namespace foo { } " ) ) ;
ASSERT_EQUALS ( " ; " , tokenizeAndStringify ( " namespace foo { namespace { } } " ) ) ;
ASSERT_EQUALS ( " ; " , tokenizeAndStringify ( " namespace { namespace { } } " ) ) ; // Ticket #9512
ASSERT_EQUALS ( " ; " , tokenizeAndStringify ( " namespace foo { namespace bar { } } " ) ) ;
2020-06-07 13:49:04 +02:00
}
2015-10-12 18:14:56 +02:00
void prepareTernaryOpForAST ( ) {
ASSERT_EQUALS ( " a ? b : c ; " , tokenizeAndStringify ( " a ? b : c; " ) ) ;
ASSERT_EQUALS ( " a ? ( b , c ) : d ; " , tokenizeAndStringify ( " a ? b , c : d; " ) ) ;
ASSERT_EQUALS ( " a ? ( b , c ) : d ; " , tokenizeAndStringify ( " a ? (b , c) : d; " ) ) ;
ASSERT_EQUALS ( " a ? ( 1 ? ( a , b ) : 3 ) : d ; " , tokenizeAndStringify ( " a ? 1 ? a, b : 3 : d; " ) ) ;
2016-05-22 11:33:21 +02:00
ASSERT_EQUALS ( " a ? ( std :: map < int , int > ( ) ) : 0 ; " , tokenizeAndStringify ( " typedef std::map<int,int> mymap; a ? mymap() : 0; " ) ) ;
2018-09-23 10:27:38 +02:00
ASSERT_EQUALS ( " a ? ( b < c ) : d > e " , tokenizeAndStringify ( " a ? b < c : d > e " ) ) ;
2015-10-12 18:14:56 +02:00
}
2020-05-19 18:27:44 +02:00
enum class AstStyle {
2020-05-19 18:15:05 +02:00
Simple ,
Z3
} ;
std : : string testAst ( const char code [ ] , AstStyle style = AstStyle : : Simple ) {
2012-12-15 20:21:09 +01:00
// tokenize given code..
2015-10-07 18:33:57 +02:00
Tokenizer tokenList ( & settings0 , nullptr ) ;
2012-12-15 20:21:09 +01:00
std : : istringstream istr ( code ) ;
2014-05-24 11:28:43 +02:00
if ( ! tokenList . list . createTokens ( istr , " test.cpp " ) )
2012-12-15 20:21:09 +01:00
return " ERROR " ;
2019-03-10 10:38:50 +01:00
tokenList . combineStringAndCharLiterals ( ) ;
2014-05-24 11:28:43 +02:00
tokenList . combineOperators ( ) ;
2021-04-22 19:15:22 +02:00
tokenList . simplifySpaceshipOperator ( ) ;
2014-05-24 11:28:43 +02:00
tokenList . createLinks ( ) ;
tokenList . createLinks2 ( ) ;
2019-11-01 09:05:45 +01:00
tokenList . list . front ( ) - > assignIndexes ( ) ;
2013-11-02 19:18:58 +01:00
2019-03-09 19:09:15 +01:00
// set varid..
for ( Token * tok = tokenList . list . front ( ) ; tok ; tok = tok - > next ( ) ) {
if ( tok - > str ( ) = = " var " )
tok - > varId ( 1 ) ;
}
2012-12-15 20:21:09 +01:00
// Create AST..
2015-10-12 18:14:56 +02:00
tokenList . prepareTernaryOpForAST ( ) ;
2014-05-24 11:28:43 +02:00
tokenList . list . createAst ( ) ;
2012-12-15 20:21:09 +01:00
2017-06-04 12:16:49 +02:00
tokenList . list . validateAst ( ) ;
2014-05-19 10:38:54 +02:00
// Basic AST validation
2014-05-24 11:28:43 +02:00
for ( const Token * tok = tokenList . list . front ( ) ; tok ; tok = tok - > next ( ) ) {
2014-05-19 21:54:59 +02:00
if ( tok - > astOperand2 ( ) & & ! tok - > astOperand1 ( ) & & tok - > str ( ) ! = " ; " & & tok - > str ( ) ! = " : " )
2014-05-19 10:38:54 +02:00
return " Op2 but no Op1 for token: " + tok - > str ( ) ;
}
2014-01-27 06:18:42 +01:00
// Return stringified AST
2020-05-19 18:15:05 +02:00
if ( style = = AstStyle : : Z3 )
2020-05-18 19:31:13 +02:00
return tokenList . list . front ( ) - > astTop ( ) - > astStringZ3 ( ) ;
2014-04-25 06:06:54 +02:00
2014-01-27 06:18:42 +01:00
std : : string ret ;
std : : set < const Token * > astTop ;
2014-05-24 11:28:43 +02:00
for ( const Token * tok = tokenList . list . front ( ) ; tok ; tok = tok - > next ( ) ) {
2014-01-27 06:18:42 +01:00
if ( tok - > astOperand1 ( ) & & astTop . find ( tok - > astTop ( ) ) = = astTop . end ( ) ) {
astTop . insert ( tok - > astTop ( ) ) ;
if ( ! ret . empty ( ) )
ret = ret + " " ;
ret + = tok - > astTop ( ) - > astString ( ) ;
}
2013-11-02 18:37:35 +01:00
}
2014-01-27 06:18:42 +01:00
return ret ;
2012-12-15 20:21:09 +01:00
}
2015-10-07 18:33:57 +02:00
void astexpr ( ) { // simple expressions with arithmetical ops
2012-12-16 11:48:19 +01:00
ASSERT_EQUALS ( " 12+3+ " , testAst ( " 1+2+3 " ) ) ;
2012-12-15 20:21:09 +01:00
ASSERT_EQUALS ( " 12*3+ " , testAst ( " 1*2+3 " ) ) ;
ASSERT_EQUALS ( " 123*+ " , testAst ( " 1+2*3 " ) ) ;
ASSERT_EQUALS ( " 12*34*+ " , testAst ( " 1*2+3*4 " ) ) ;
2012-12-16 11:48:19 +01:00
ASSERT_EQUALS ( " 12*34*5*+ " , testAst ( " 1*2+3*4*5 " ) ) ;
2014-05-04 18:36:04 +02:00
ASSERT_EQUALS ( " 0(r.& " , testAst ( " (&((typeof(x))0).r); " ) ) ;
ASSERT_EQUALS ( " 0(r.& " , testAst ( " &((typeof(x))0).r; " ) ) ;
2021-04-24 11:47:51 +02:00
ASSERT_EQUALS ( " 0f1(|| " , testAst ( " ; 0 || f(1); " ) ) ;
2012-12-16 11:56:23 +01:00
// Various tests of precedence
ASSERT_EQUALS ( " ab::c+ " , testAst ( " a::b+c " ) ) ;
ASSERT_EQUALS ( " abc+= " , testAst ( " a=b+c " ) ) ;
ASSERT_EQUALS ( " abc=, " , testAst ( " a,b=c " ) ) ;
2013-11-11 16:39:34 +01:00
ASSERT_EQUALS ( " a-1+ " , testAst ( " -a+1 " ) ) ;
ASSERT_EQUALS ( " ab++-c- " , testAst ( " a-b++-c " ) ) ;
2021-04-22 19:15:22 +02:00
ASSERT_EQUALS ( " ab<=> " , testAst ( " a<=>b " ) ) ;
2012-12-16 11:56:23 +01:00
2015-02-18 19:56:13 +01:00
// sizeof
ASSERT_EQUALS ( " ab.sizeof " , testAst ( " sizeof a.b " ) ) ;
2014-04-21 13:05:34 +02:00
// assignment operators
ASSERT_EQUALS ( " ab>>= " , testAst ( " a>>=b; " ) ) ;
ASSERT_EQUALS ( " ab<<= " , testAst ( " a<<=b; " ) ) ;
ASSERT_EQUALS ( " ab+= " , testAst ( " a+=b; " ) ) ;
ASSERT_EQUALS ( " ab-= " , testAst ( " a-=b; " ) ) ;
ASSERT_EQUALS ( " ab*= " , testAst ( " a*=b; " ) ) ;
ASSERT_EQUALS ( " ab/= " , testAst ( " a/=b; " ) ) ;
ASSERT_EQUALS ( " ab%= " , testAst ( " a%=b; " ) ) ;
ASSERT_EQUALS ( " ab&= " , testAst ( " a&=b; " ) ) ;
ASSERT_EQUALS ( " ab|= " , testAst ( " a|=b; " ) ) ;
ASSERT_EQUALS ( " ab^= " , testAst ( " a^=b; " ) ) ;
2014-05-19 21:54:59 +02:00
ASSERT_EQUALS ( " ab*c*.(+return " , testAst ( " return a + ((*b).*c)(); " ) ) ;
2014-05-03 12:08:42 +02:00
// assignments are executed from right to left
ASSERT_EQUALS ( " abc== " , testAst ( " a=b=c; " ) ) ;
2015-10-12 18:14:56 +02:00
// ternary operator
2015-07-24 13:02:00 +02:00
ASSERT_EQUALS ( " ab0=c1=:? " , testAst ( " a?b=0:c=1; " ) ) ;
2015-10-12 18:14:56 +02:00
ASSERT_EQUALS ( " fabc,d:?=e, " , testAst ( " f = a ? b, c : d, e; " ) ) ;
ASSERT_EQUALS ( " fabc,de,:?= " , testAst ( " f = (a ? (b, c) : (d, e)); " ) ) ;
ASSERT_EQUALS ( " fabc,de,:?= " , testAst ( " f = (a ? b, c : (d, e)); " ) ) ;
ASSERT_EQUALS ( " ab35,4:?foo(:?return " , testAst ( " return (a ? b ? (3,5) : 4 : foo()); " ) ) ;
2015-10-17 17:03:24 +02:00
ASSERT_EQUALS ( " check(result_type00,{invalid:?return " , testAst ( " return check() ? result_type {0, 0} : invalid; " ) ) ;
2020-06-14 14:46:16 +02:00
ASSERT_EQUALS ( " x01:?return " , testAst ( " return x ? 0 : 1; " ) ) ;
ASSERT_EQUALS ( " x00throw:?return " , testAst ( " return x ? 0 : throw 0; " ) ) ; // #9768
2020-06-14 18:45:19 +02:00
ASSERT_EQUALS ( " val0<1throwval:?return " , testAst ( " return val < 0 ? throw 1 : val; " ) ) ; // #8526
ASSERT_EQUALS ( " ix0<00throw:?= " , testAst ( " int i = x < 0 ? 0 : throw 0; " ) ) ;
2015-07-24 13:02:00 +02:00
2013-11-04 11:26:16 +01:00
ASSERT_EQUALS ( " a \" \" = " , testAst ( " a= \" \" " ) ) ;
ASSERT_EQUALS ( " a \' \' = " , testAst ( " a= \' \' " ) ) ;
2013-11-20 05:57:56 +01:00
ASSERT_EQUALS ( " 'X''a'> " , testAst ( " ('X' > 'a') " ) ) ;
2019-10-16 11:41:33 +02:00
ASSERT_EQUALS ( " L'X'L'a'> " , testAst ( " (L'X' > L'a') " ) ) ;
ASSERT_EQUALS ( " u'X'u'a'> " , testAst ( " (u'X' > u'a') " ) ) ;
ASSERT_EQUALS ( " U'X'U'a'> " , testAst ( " (U'X' > U'a') " ) ) ;
ASSERT_EQUALS ( " u8'X'u8'a'> " , testAst ( " (u8'X' > u8'a') " ) ) ;
2014-01-08 21:49:42 +01:00
2014-05-11 13:39:28 +02:00
ASSERT_EQUALS ( " a0>bc/d:? " , testAst ( " (a>0) ? (b/(c)) : d; " ) ) ;
2014-01-08 21:49:42 +01:00
ASSERT_EQUALS ( " abc/+d+ " , testAst ( " a + (b/(c)) + d; " ) ) ;
2020-10-04 11:27:31 +02:00
ASSERT_EQUALS ( " x1024x/0:? " , testAst ( " void f() { x ? 1024 / x : 0; } " ) ) ;
2014-01-15 17:32:14 +01:00
2014-01-18 13:18:11 +01:00
ASSERT_EQUALS ( " absizeofd(ef.+(= " , testAst ( " a = b(sizeof(c d) + e.f) " ) ) ;
2014-05-17 12:09:32 +02:00
ASSERT_EQUALS ( " a*b*** " , testAst ( " *a * **b; " ) ) ; // Correctly distinguish between unary and binary operator*
2015-07-27 13:13:30 +02:00
// strings
ASSERT_EQUALS ( " f \" A \" 1,( " , testAst ( " f( \" A \" B, 1); " ) ) ;
ASSERT_EQUALS ( " fA1,( " , testAst ( " f(A \" B \" , 1); " ) ) ;
2017-05-24 20:18:31 +02:00
// C++ : type()
ASSERT_EQUALS ( " fint(0,( " , testAst ( " f(int(),0); " ) ) ;
ASSERT_EQUALS ( " f(0,( " , testAst ( " f(int *(),0); " ) ) ; // typedef int* X; f(X(),0);
2017-05-24 20:24:56 +02:00
ASSERT_EQUALS ( " f((0,( " , testAst ( " f((intp)int *(),0); " ) ) ;
2017-08-26 23:25:45 +02:00
ASSERT_EQUALS ( " zx1(&y2(&|= " , testAst ( " z = (x & (unsigned)1) | (y & (unsigned)2); " ) ) ; // not type()
2017-05-24 20:18:31 +02:00
2014-01-15 17:32:14 +01:00
// for
ASSERT_EQUALS ( " for;;( " , testAst ( " for(;;) " ) ) ;
ASSERT_EQUALS ( " fora0=a8<a++;;( " , testAst ( " for(a=0;a<8;a++) " ) ) ;
2014-05-19 10:38:54 +02:00
ASSERT_EQUALS ( " fori1=current0=,iNUM<=i++;;( " , testAst ( " for(i = (1), current = 0; i <= (NUM); ++i) " ) ) ;
2014-01-23 06:13:24 +01:00
ASSERT_EQUALS ( " foreachxy,(( " , testAst ( " for(each(x,y)){} " ) ) ; // it's not well-defined what this ast should be
2020-04-19 17:00:08 +02:00
ASSERT_EQUALS ( " forvar1(;;( " , testAst ( " for(int var(1);;) " ) ) ;
2014-01-23 06:13:24 +01:00
ASSERT_EQUALS ( " forab:( " , testAst ( " for (int a : b); " ) ) ;
2020-04-19 17:00:08 +02:00
ASSERT_EQUALS ( " forvarb:( " , testAst ( " for (int *var : b); " ) ) ;
ASSERT_EQUALS ( " forvard:( " , testAst ( " for (a<b> var : d); " ) ) ;
ASSERT_EQUALS ( " forvare:( " , testAst ( " for (a::b<c> var : e); " ) ) ;
2014-03-31 17:16:13 +02:00
ASSERT_EQUALS ( " forx*0=yz;;( " , testAst ( " for(*x=0;y;z) " ) ) ;
2017-04-17 21:11:53 +02:00
ASSERT_EQUALS ( " forx0=y(8<z;;( " , testAst ( " for (x=0;(int)y<8;z); " ) ) ;
2020-02-27 09:58:41 +01:00
ASSERT_EQUALS ( " forab,c:( " , testAst ( " for (auto [a,b]: c); " ) ) ;
2020-06-09 20:57:00 +02:00
ASSERT_EQUALS ( " fora*++;;( " , testAst ( " for (++(*a);;); " ) ) ;
2020-08-16 21:10:55 +02:00
ASSERT_EQUALS ( " foryz:( " , testAst ( " for (decltype(x) *y : z); " ) ) ;
2020-09-26 19:22:24 +02:00
ASSERT_EQUALS ( " for(tmpNULL!=tmptmpnext.=;;( tmpa= " , testAst ( " for ( ({ tmp = a; }) ; tmp != NULL; tmp = tmp->next ) {} " ) ) ;
2021-04-24 11:47:51 +02:00
ASSERT_EQUALS ( " forx0=x;;( " , testAst ( " for (int x=0; x;); " ) ) ;
// for with initializer (c++20)
ASSERT_EQUALS ( " forab=ca:;( " , testAst ( " for(a=b;int c:a) " ) ) ;
2014-01-27 06:18:42 +01:00
// problems with multiple expressions
ASSERT_EQUALS ( " ax( whilex( " , testAst ( " a(x) while (x) " ) ) ;
ASSERT_EQUALS ( " ifx( i0= whilei( " , testAst ( " if (x) { ({ int i = 0; while(i); }) }; " ) ) ;
ASSERT_EQUALS ( " ifx( BUG_ON{!( i0= whilei( " , testAst ( " if (x) { BUG_ON(!({int i=0; while(i);})); } " ) ) ;
2014-05-24 11:28:43 +02:00
ASSERT_EQUALS ( " v0= while{0!=( v0= while{0!=( v0= " , testAst ( " ({ v = 0; }); while (({ v = 0; }) != 0); while (({ v = 0; }) != 0); " ) ) ;
2014-05-19 21:54:59 +02:00
ASSERT_EQUALS ( " abc.1:?1+bd.1:?+= " , testAst ( " a =(b.c ? : 1) + 1 + (b.d ? : 1); " ) ) ;
2014-06-04 18:08:51 +02:00
2019-09-04 08:07:30 +02:00
ASSERT_EQUALS ( " catch...( " , testAst ( " try {} catch (...) {} " ) ) ;
2014-06-04 18:08:51 +02:00
2020-10-04 11:27:31 +02:00
ASSERT_EQUALS ( " " , testAst ( " void Foo(Bar&); " ) ) ;
ASSERT_EQUALS ( " " , testAst ( " void Foo(Bar&&); " ) ) ;
2019-10-04 12:30:11 +02:00
2020-10-04 11:27:31 +02:00
ASSERT_EQUALS ( " Barb& " , testAst ( " void Foo(Bar& b); " ) ) ;
ASSERT_EQUALS ( " Barb&& " , testAst ( " void Foo(Bar&& b); " ) ) ;
2019-10-04 12:30:11 +02:00
2014-06-04 18:08:51 +02:00
ASSERT_EQUALS ( " DerivedDerived::( " , testAst ( " Derived::~Derived() {} " ) ) ;
2014-06-26 09:03:02 +02:00
ASSERT_EQUALS ( " ifCA_FarReadfilenew(,sizeofobjtype(,(!( " , testAst ( " if (!CA_FarRead(file, (void far *)new, sizeof(objtype))) " ) ) ; // #5910 - don't hang if C code is parsed as C++
2018-10-22 11:37:08 +02:00
2019-04-12 17:35:06 +02:00
// C++17: if (expr1; expr2)
ASSERT_EQUALS ( " ifx3=y;( " , testAst ( " if (int x=3; y) " ) ) ;
2019-04-29 11:50:19 +02:00
2020-02-21 21:11:32 +01:00
2014-06-04 18:08:51 +02:00
}
2017-06-04 12:16:49 +02:00
void astexpr2 ( ) { // limit for large expressions
// #7724 - wrong AST causes hang
// Ideally a proper AST is created for this code.
const char code [ ] = " const char * a(int type) { \n "
" return ( \n "
" (type == 1) ? \" \" \n "
" : (type == 2) ? \" \" \n "
" : (type == 3) ? \" \" \n "
" : (type == 4) ? \" \" \n "
" : (type == 5) ? \" \" \n "
" : (type == 6) ? \" \" \n "
" : (type == 7) ? \" \" \n "
" : (type == 8) ? \" \" \n "
" : (type == 9) ? \" \" \n "
" : (type == 10) ? \" \" \n "
" : (type == 11) ? \" \" \n "
" : (type == 12) ? \" \" \n "
" : (type == 13) ? \" \" \n "
" : (type == 14) ? \" \" \n "
" : (type == 15) ? \" \" \n "
" : (type == 16) ? \" \" \n "
" : (type == 17) ? \" \" \n "
" : (type == 18) ? \" \" \n "
" : (type == 19) ? \" \" \n "
" : (type == 20) ? \" \" \n "
" : (type == 21) ? \" \" \n "
" : (type == 22) ? \" \" \n "
" : (type == 23) ? \" \" \n "
" : (type == 24) ? \" \" \n "
" : (type == 25) ? \" \" \n "
" : (type == 26) ? \" \" \n "
" : (type == 27) ? \" \" \n "
" : (type == 28) ? \" \" \n "
" : (type == 29) ? \" \" \n "
" : (type == 30) ? \" \" \n "
" : (type == 31) ? \" \" \n "
" : (type == 32) ? \" \" \n "
" : (type == 33) ? \" \" \n "
" : (type == 34) ? \" \" \n "
" : (type == 35) ? \" \" \n "
" : (type == 36) ? \" \" \n "
" : (type == 37) ? \" \" \n "
" : (type == 38) ? \" \" \n "
" : (type == 39) ? \" \" \n "
" : (type == 40) ? \" \" \n "
" : (type == 41) ? \" \" \n "
" : (type == 42) ? \" \" \n "
" : (type == 43) ? \" \" \n "
" : (type == 44) ? \" \" \n "
" : (type == 45) ? \" \" \n "
" : (type == 46) ? \" \" \n "
" : (type == 47) ? \" \" \n "
" : (type == 48) ? \" \" \n "
" : (type == 49) ? \" \" \n "
" : (type == 50) ? \" \" \n "
" : (type == 51) ? \" \" \n "
" : \" \" ); \n "
" } \n " ;
// Ensure that the AST is validated for the simplified token list
2020-03-07 21:46:38 +01:00
TODO_ASSERT_THROW ( tokenizeAndStringify ( code ) , InternalError ) ; // this should not crash/hang
2017-06-04 12:16:49 +02:00
}
2015-10-07 18:33:57 +02:00
void astnewdelete ( ) {
2014-06-04 18:08:51 +02:00
ASSERT_EQUALS ( " aintnew= " , testAst ( " a = new int; " ) ) ;
2014-09-29 10:26:15 +02:00
ASSERT_EQUALS ( " aint4[new= " , testAst ( " a = new int[4]; " ) ) ;
2014-10-10 10:37:54 +02:00
ASSERT_EQUALS ( " aFoobar(new= " , testAst ( " a = new Foo(bar); " ) ) ;
ASSERT_EQUALS ( " aFoobar(new= " , testAst ( " a = new Foo(bar); " ) ) ;
ASSERT_EQUALS ( " aFoo(new= " , testAst ( " a = new Foo<bar>(); " ) ) ;
2014-10-12 09:24:43 +02:00
ASSERT_EQUALS ( " aXnew( " , testAst ( " a (new (X)); " ) ) ;
2014-10-12 10:20:03 +02:00
ASSERT_EQUALS ( " aXnew5,( " , testAst ( " a (new (X), 5); " ) ) ;
2014-06-04 18:08:51 +02:00
ASSERT_EQUALS ( " adelete " , testAst ( " delete a; " ) ) ;
ASSERT_EQUALS ( " adelete " , testAst ( " delete (a); " ) ) ;
ASSERT_EQUALS ( " adelete " , testAst ( " delete[] a; " ) ) ;
ASSERT_EQUALS ( " ab.3c-(delete " , testAst ( " delete[] a.b(3 - c); " ) ) ;
2014-10-12 12:13:01 +02:00
ASSERT_EQUALS ( " aA1(new(bB2(new(, " , testAst ( " a(new A(1)), b(new B(2)) " ) ) ;
2015-10-20 23:55:29 +02:00
ASSERT_EQUALS ( " Fred10[new " , testAst ( " ;new Fred[10]; " ) ) ;
2020-10-04 11:27:31 +02:00
ASSERT_EQUALS ( " adelete " , testAst ( " void f() { delete a; } " ) ) ;
2014-10-10 12:47:01 +02:00
2020-11-23 22:03:50 +01:00
// placement new
ASSERT_EQUALS ( " X12,3,(new ab,c, " , testAst ( " new (a,b,c) X(1,2,3); " ) ) ;
ASSERT_EQUALS ( " a::new= " , testAst ( " a = new (b) ::X; " ) ) ;
ASSERT_EQUALS ( " cCnew= abc:? " , testAst ( " c = new(a ? b : c) C; " ) ) ;
2014-10-13 19:12:20 +02:00
// invalid code (libreoffice), don't hang
// #define SlideSorterViewShell
// SfxViewFrame* pFrame;
// new SlideSorterViewShell(pFrame,rViewShellBase,pParentWindow,pFrameViewArgument);
ASSERT_EQUALS ( " fxnewy,z,( " , testAst ( " f(new (x,y,z)); " ) ) ;
2014-10-10 12:47:01 +02:00
// clang testsuite..
ASSERT_EQUALS ( " const0(new " , testAst ( " new const auto (0); " ) ) ;
2014-10-11 11:27:13 +02:00
ASSERT_EQUALS ( " autonew " , testAst ( " new (auto) (0.0); " ) ) ;
2014-10-12 11:12:25 +02:00
ASSERT_EQUALS ( " int3[4[5[new " , testAst ( " new (int S::*[3][4][5]) (); " ) ) ;
2014-10-11 11:27:13 +02:00
ASSERT_EQUALS ( " pSnew= " , testAst ( " p=new (x)(S)(1,2); " ) ) ;
ASSERT_EQUALS ( " inti[new( " , testAst ( " (void)new (int[i]); " ) ) ;
2014-10-11 13:20:48 +02:00
ASSERT_EQUALS ( " intp* pnew malloc4( " , testAst ( " int*p; new (p) (malloc(4)); " ) ) ;
ASSERT_EQUALS ( " intnew " , testAst ( " new (&w.x)(int*)(0); " ) ) ;
ASSERT_EQUALS ( " &new " , testAst ( " new (&w.x)(0); " ) ) ; // <- the "(int*)" has been simplified
2014-10-12 12:57:01 +02:00
// gcc testsuite..
ASSERT_EQUALS ( " char10[new( " , testAst ( " (void)new(char*)[10]; " ) ) ;
2012-12-15 20:21:09 +01:00
}
2015-10-07 18:33:57 +02:00
void astpar ( ) { // parentheses
2012-12-15 20:21:09 +01:00
ASSERT_EQUALS ( " 12+3* " , testAst ( " (1+2)*3 " ) ) ;
ASSERT_EQUALS ( " 123+* " , testAst ( " 1*(2+3) " ) ) ;
ASSERT_EQUALS ( " 123+*4* " , testAst ( " 1*(2+3)*4 " ) ) ;
2013-11-04 11:26:16 +01:00
ASSERT_EQUALS ( " ifab.c&d==( " , testAst ( " if((a.b&c)==d){} " ) ) ;
2013-11-11 16:39:34 +01:00
2013-11-27 06:17:00 +01:00
ASSERT_EQUALS ( " pf.pf.12,(&& " , testAst ( " ((p.f) && (p.f)(1,2)) " ) ) ;
2021-08-07 20:51:18 +02:00
ASSERT_EQUALS ( " forresdirGetFirst.file&_T(,(=;;( " , testAst ( " for ((res = dir.GetFirst(&file, _T( " " )));;) {} " ) ) ;
2020-07-19 11:10:38 +02:00
2014-04-15 15:46:26 +02:00
// problems with: if (x[y]==z)
ASSERT_EQUALS ( " ifa(0[1==( " , testAst ( " if(a()[0]==1){} " ) ) ;
ASSERT_EQUALS ( " ifbuff0[&(*1==( " , testAst ( " if (*((DWORD*)&buff[0])==1){} " ) ) ;
2014-04-26 13:16:34 +02:00
ASSERT_EQUALS ( " ifp*0[1==( " , testAst ( " if((*p)[0]==1) " ) ) ;
2014-05-08 06:48:53 +02:00
ASSERT_EQUALS ( " ifab.cd.[e==( " , testAst ( " if(a.b[c.d]==e){} " ) ) ;
2014-04-26 13:16:34 +02:00
2014-05-19 10:38:54 +02:00
ASSERT_EQUALS ( " iftpnote.i1-[note.0==tpnote.i1-[type.4>||( " , testAst ( " if ((tp.note[i - 1].note == 0) || (tp.note[i - 1].type > 4)) {} " ) ) ;
ASSERT_EQUALS ( " ab.i[j1+[ " , testAst ( " a.b[i][j+1] " ) ) ;
2014-05-17 12:09:32 +02:00
2014-04-26 13:16:34 +02:00
// problems with: x=expr
2020-05-19 18:27:44 +02:00
ASSERT_EQUALS ( " (= x (( (. ([ a i) f))) " ,
testAst ( " x = ((a[i]).f)(); " , AstStyle : : Z3 ) ) ;
2014-04-29 06:09:26 +02:00
ASSERT_EQUALS ( " abc.de.++[= " , testAst ( " a = b.c[++(d.e)]; " ) ) ;
2014-04-26 13:32:08 +02:00
ASSERT_EQUALS ( " abc(1+= " , testAst ( " a = b(c**)+1; " ) ) ;
2014-04-27 18:03:50 +02:00
ASSERT_EQUALS ( " abc.= " , testAst ( " a = (b).c; " ) ) ;
2014-04-15 15:46:26 +02:00
2013-11-11 16:39:34 +01:00
// casts
ASSERT_EQUALS ( " a1(2(+= " , testAst ( " a=(t)1+(t)2; " ) ) ;
ASSERT_EQUALS ( " a1(2+= " , testAst ( " a=(t)1+2; " ) ) ;
2013-12-25 21:19:28 +01:00
ASSERT_EQUALS ( " a1(2+= " , testAst ( " a=(t*)1+2; " ) ) ;
ASSERT_EQUALS ( " a1(2+= " , testAst ( " a=(t&)1+2; " ) ) ;
2020-02-25 21:05:36 +01:00
ASSERT_EQUALS ( " a1(2+= " , testAst ( " a=(t&&)1+2; " ) ) ;
2013-12-25 21:19:28 +01:00
ASSERT_EQUALS ( " ab::r&c(= " , testAst ( " a::b& r = (a::b&)c; " ) ) ; // #5261
2014-05-11 13:39:28 +02:00
ASSERT_EQUALS ( " ab10:?= " , testAst ( " a=(b)?1:0; " ) ) ;
2018-10-18 20:17:23 +02:00
ASSERT_EQUALS ( " ac5[new(= " , testAst ( " a = (b*)(new c[5]); " ) ) ; // #8786
ASSERT_EQUALS ( " a(4+ " , testAst ( " (int)(a) + 4; " ) ) ;
2017-04-10 23:05:41 +02:00
2019-10-06 09:43:46 +02:00
// (cast){data}[index]
ASSERT_EQUALS ( " a&{(0[1[5[0= " , testAst ( " (int (**)[i]){&a}[0][1][5] = 0; " ) ) ;
ASSERT_EQUALS ( " ab12,{(0[,( " , testAst ( " a(b, (int []){1,2}[0]); " ) ) ;
2017-04-10 23:05:41 +02:00
ASSERT_EQUALS ( " n0= " , testAst ( " TrivialDefCtor{[2][2]}[1][1].n = 0; " ) ) ;
2017-04-10 23:29:15 +02:00
ASSERT_EQUALS ( " aT12,3,{1[= " , testAst ( " a = T{1, 2, 3}[1]; " ) ) ;
2013-11-25 20:58:40 +01:00
2020-02-16 13:58:43 +01:00
// Type{data}()
ASSERT_EQUALS ( " ab{(= " , testAst ( " a=b{}(); " ) ) ;
ASSERT_EQUALS ( " abc{((= " , testAst ( " a=b(c{}()); " ) ) ;
2020-10-04 11:27:31 +02:00
ASSERT_EQUALS ( " xNULL!=0(x(:? " , testAst ( " void f() { {} ((x != NULL) ? (void)0 : x()); } " ) ) ;
2020-02-16 13:58:43 +01:00
2013-11-25 20:58:40 +01:00
// ({..})
2014-01-27 06:18:42 +01:00
ASSERT_EQUALS ( " a{+d+ bc+ " , testAst ( " a+({b+c;})+d " ) ) ;
ASSERT_EQUALS ( " a{d*+ bc+ " , testAst ( " a+({b+c;})*d " ) ) ;
2019-11-23 21:36:36 +01:00
ASSERT_EQUALS ( " xa{((= bc( yd{((= ef( " ,
2014-02-05 06:05:48 +01:00
testAst ( " x=(int)(a({b(c);})); " // don't hang
" y=(int)(d({e(f);})); " ) ) ;
2019-11-19 11:38:03 +01:00
ASSERT_EQUALS ( " A{{,( x0= Bx1={x2={,( " , // TODO: This is not perfect!!
2019-10-27 12:00:08 +01:00
testAst ( " A({},{x=0;}); " // don't hang
2019-11-01 09:05:45 +01:00
" B({x=1},{x=2}); " ) ) ;
2017-04-21 21:02:46 +02:00
ASSERT_EQUALS ( " xMACROtype.T=value.1=,{({= " ,
2016-11-27 11:40:42 +01:00
testAst ( " x = { MACRO( { .type=T, .value=1 } ) } " ) ) ; // don't hang: MACRO({..})
2017-03-19 07:26:11 +01:00
ASSERT_EQUALS ( " fori10=i{;;( i-- " , testAst ( " for (i=10;i;({i--;}) ) {} " ) ) ;
2020-12-26 18:33:29 +01:00
ASSERT_EQUALS ( " c{1{,{2.3f{,( " ,
testAst ( " c({{}, {1}}, {2.3f}); " ) ) ;
2014-06-04 18:08:51 +02:00
// function pointer
TODO_ASSERT_EQUALS ( " todo " , " va_argapvoid((,(*0= " , testAst ( " *va_arg(ap, void(**) ()) = 0; " ) ) ;
2014-07-31 23:14:44 +02:00
2020-12-02 07:38:21 +01:00
// struct/array initialization
2014-07-31 23:14:44 +02:00
ASSERT_EQUALS ( " name_bytes[bits~unusedBits>>unusedBits<<{= " , testAst ( " const uint8_t name_bytes[] = { (~bits >> unusedBits) << unusedBits }; " ) ) ;
2017-04-21 21:02:46 +02:00
ASSERT_EQUALS ( " abuf.0{={= " , testAst ( " a = { .buf = { 0 } }; " ) ) ;
ASSERT_EQUALS ( " ab2[a.0=b.0=,{a.0=b.0=,{,{= " , testAst ( " struct AB ab[2] = { { .a=0, .b=0 }, { .a=0, .b=0 } }; " ) ) ;
2014-07-31 23:14:44 +02:00
ASSERT_EQUALS ( " tset{= " , testAst ( " struct cgroup_taskset tset = {}; " ) ) ;
2015-07-21 11:40:42 +02:00
ASSERT_EQUALS ( " s1a&,{2b&,{,{= " , testAst ( " s = { {1, &a}, {2, &b} }; " ) ) ;
2017-04-10 07:25:18 +02:00
ASSERT_EQUALS ( " s0[L.2[x={= " , testAst ( " s = { [0].L[2] = x}; " ) ) ;
2017-04-22 11:23:11 +02:00
ASSERT_EQUALS ( " ac.0={(= " , testAst ( " a = (b){.c=0,}; " ) ) ; // <- useless comma
2017-04-26 22:35:04 +02:00
ASSERT_EQUALS ( " xB[1y.z.1={(&=,{={= " , testAst ( " x = { [B] = {1, .y = &(struct s) { .z=1 } } }; " ) ) ;
2018-03-27 13:44:28 +02:00
ASSERT_EQUALS ( " xab,c,{= " , testAst ( " x={a,b,(c)}; " ) ) ;
2019-05-04 19:05:03 +02:00
ASSERT_EQUALS ( " x0fSa.1=b.2=,c. \" \" =,{(||= " , testAst ( " x = 0 || f(S{.a = 1, .b = 2, .c = \" \" }); " ) ) ;
2020-04-20 08:59:35 +02:00
ASSERT_EQUALS ( " x0fSa.1{=b.2{,c. \" \" =,{(||= " , testAst ( " x = 0 || f(S{.a = { 1 }, .b { 2 }, .c = \" \" }); " ) ) ;
2020-05-22 09:35:55 +02:00
ASSERT_EQUALS ( " a0{,( \" \" abc12:?, " , testAst ( " a(0, {{ \" \" , (abc) ? 1 : 2}}); " ) ) ;
ASSERT_EQUALS ( " a0{,( \' \' abc12:?, " , testAst ( " a(0, {{ \' \' , (abc) ? 1 : 2}}); " ) ) ;
2020-12-02 07:38:21 +01:00
ASSERT_EQUALS ( " x12,{34,{,{56,{78,{,{,{= " , testAst ( " x = { { {1,2}, {3,4} }, { {5,6}, {7,8} } }; " ) ) ;
2021-12-19 12:36:48 +01:00
ASSERT_EQUALS ( " Sa.stdmove::s(=b.1=,{( " , testAst ( " S({.a = std::move(s), .b = 1}) " ) ) ;
2014-09-29 10:59:58 +02:00
2017-04-09 22:06:13 +02:00
// struct initialization hang
2020-10-04 11:27:31 +02:00
ASSERT_EQUALS ( " sbar.1{,{(={= forfieldfield++;;( " ,
2017-04-09 22:06:13 +02:00
testAst ( " struct S s = {.bar = (struct foo) { 1, { } } }; \n "
" void f(struct cmd *) { for (; field; field++) {} } " ) ) ;
2015-10-17 17:03:24 +02:00
// template parentheses: <>
2021-05-03 20:22:08 +02:00
ASSERT_EQUALS ( " ab::c(de::(<=return " , testAst ( " return a::b(c) <= d<double>::e(); " ) ) ; // #6195
2015-10-17 17:03:24 +02:00
// C++ initializer
ASSERT_EQUALS ( " Class{ " , testAst ( " Class{}; " ) ) ;
ASSERT_EQUALS ( " Class12,{ " , testAst ( " Class{1,2}; " ) ) ;
2015-10-18 13:43:39 +02:00
ASSERT_EQUALS ( " Class12,{ " , testAst ( " Class<X>{1,2}; " ) ) ;
2015-10-17 17:03:24 +02:00
ASSERT_EQUALS ( " abc{d:?= " , testAst ( " a=b?c{}:d; " ) ) ;
ASSERT_EQUALS ( " abc12,{d:?= " , testAst ( " a=b?c{1,2}:d; " ) ) ;
2015-10-18 13:43:39 +02:00
ASSERT_EQUALS ( " abc{d:?= " , testAst ( " a=b?c<X>{}:d; " ) ) ;
ASSERT_EQUALS ( " abc12,{d:?= " , testAst ( " a=b?c<X>{1,2}:d; " ) ) ;
2015-10-18 16:58:15 +02:00
ASSERT_EQUALS ( " a::12,{ " , testAst ( " ::a{1,2}; " ) ) ; // operator precedence
2015-11-06 17:34:26 +01:00
ASSERT_EQUALS ( " Abc({newreturn " , testAst ( " return new A {b(c)}; " ) ) ;
2017-06-09 22:35:46 +02:00
ASSERT_EQUALS ( " a{{return " , testAst ( " return{{a}}; " ) ) ;
ASSERT_EQUALS ( " a{b{,{return " , testAst ( " return{{a},{b}}; " ) ) ;
2021-06-24 08:22:03 +02:00
ASSERT_EQUALS ( " stdvector::{{,{return " , testAst ( " return std::vector<std::vector<int> >{{},{}}; " ) ) ;
ASSERT_EQUALS ( " stdvector::{2{,{return " , testAst ( " return std::vector<std::vector<int> >{{}, {2}}; " ) ) ;
ASSERT_EQUALS ( " forbstdvector::{{,{:( " , testAst ( " for (auto b : std::vector<std::vector<int> >{{},{}}); " ) ) ;
ASSERT_EQUALS ( " forbstdvector::{2{,{:( " , testAst ( " for (auto b : std::vector<std::vector<int> >{{}, {2}}); " ) ) ;
2020-09-27 20:41:09 +02:00
ASSERT_EQUALS ( " abR{{,P(,(( " , testAst ( " a(b(R{},{},P())); " ) ) ;
2020-12-26 18:33:29 +01:00
ASSERT_EQUALS ( " f1{2{,3{,{x,( " , testAst ( " f({{1},{2},{3}},x); " ) ) ;
2021-04-25 10:38:33 +02:00
ASSERT_EQUALS ( " a1{ b2{ " , testAst ( " auto a{1}; auto b{2}; " ) ) ;
2021-06-24 08:22:03 +02:00
ASSERT_EQUALS ( " var1ab::23,{,4ab::56,{,{,{{ " , testAst ( " auto var{{1,a::b{2,3}}, {4,a::b{5,6}}}; " ) ) ;
2021-05-04 19:02:29 +02:00
ASSERT_EQUALS ( " var{{,{,{{ " , testAst ( " auto var{ {{},{}}, {} }; " ) ) ;
2021-06-24 08:25:13 +02:00
ASSERT_EQUALS ( " fX{,{( abcfalse==CD:? " , testAst ( " f({X, {Y, abc == false ? C : D}}); " ) ) ;
2021-05-03 21:40:49 +02:00
// Initialization with decltype(expr) instead of a type
ASSERT_EQUALS ( " decltypex(( " , testAst ( " decltype(x)(); " ) ) ;
ASSERT_EQUALS ( " decltypex({ " , testAst ( " decltype(x){}; " ) ) ;
ASSERT_EQUALS ( " decltypexy+(yx+( " , testAst ( " decltype(x+y)(y+x); " ) ) ;
ASSERT_EQUALS ( " decltypexy+(yx+{ " , testAst ( " decltype(x+y){y+x}; " ) ) ;
2021-06-30 21:40:45 +02:00
// #10334: Do not hang!
tokenizeAndStringify ( " void foo(const std::vector<std::string>& locations = { \" \" }) { \n "
" for (int i = 0; i <= 123; ++i) \n "
" x->emplace_back(y); \n "
" } " ) ;
2012-12-15 20:21:09 +01:00
}
2015-10-07 18:33:57 +02:00
void astbrackets ( ) { // []
2013-11-04 11:26:16 +01:00
ASSERT_EQUALS ( " a23+[4+ " , testAst ( " a[2+3]+4 " ) ) ;
2013-11-13 17:52:56 +01:00
ASSERT_EQUALS ( " a1[0[ " , testAst ( " a[1][0] " ) ) ;
2013-11-25 20:58:40 +01:00
ASSERT_EQUALS ( " ab0[= " , testAst ( " a=(b)[0]; " ) ) ;
2014-04-29 06:09:26 +02:00
ASSERT_EQUALS ( " abc.0[= " , testAst ( " a=b.c[0]; " ) ) ;
2013-11-25 20:58:40 +01:00
ASSERT_EQUALS ( " ab0[1[= " , testAst ( " a=b[0][1]; " ) ) ;
2012-12-15 20:21:09 +01:00
}
2019-05-12 17:24:42 +02:00
void astvardecl ( ) {
// Variable declaration
2020-11-01 11:41:41 +01:00
ASSERT_EQUALS ( " a1[ \" \" = " , testAst ( " char a[1]= \" \" ; " ) ) ;
2019-05-12 17:24:42 +02:00
ASSERT_EQUALS ( " charp*(3[char5[3[new= " , testAst ( " char (*p)[3] = new char[5][3]; " ) ) ;
ASSERT_EQUALS ( " varp= " , testAst ( " const int *var = p; " ) ) ;
// #9127
const char code1 [ ] = " using uno::Ref; \n "
" Ref<X> r; \n "
2020-10-04 11:27:31 +02:00
" int var(0); " ;
ASSERT_EQUALS ( " unoRef:: var0( " , testAst ( code1 ) ) ;
2020-06-22 08:34:08 +02:00
ASSERT_EQUALS ( " vary= " , testAst ( " std::string var = y; " ) ) ;
2020-11-16 20:11:26 +01:00
// create ast for decltype
ASSERT_EQUALS ( " decltypex( var1= " , testAst ( " decltype(x) var = 1; " ) ) ;
2021-05-07 13:19:28 +02:00
ASSERT_EQUALS ( " a1bdecltypet((>2,( " , testAst ( " a(1 > b(decltype(t)), 2); " ) ) ; // #10271
ASSERT_EQUALS ( " decltypex({01:? " , testAst ( " decltype(x){} ? 0 : 1; " ) ) ;
2019-05-12 17:24:42 +02:00
}
2015-10-07 18:33:57 +02:00
void astunaryop ( ) { // unary operators
2012-12-16 08:41:04 +01:00
ASSERT_EQUALS ( " 1a--+ " , testAst ( " 1 + --a " ) ) ;
ASSERT_EQUALS ( " 1a--+ " , testAst ( " 1 + a-- " ) ) ;
ASSERT_EQUALS ( " ab+! " , testAst ( " !(a+b) " ) ) ;
2014-04-27 16:02:24 +02:00
ASSERT_EQUALS ( " ab.++ " , testAst ( " ++a.b; " ) ) ;
ASSERT_EQUALS ( " ab.++ " , testAst ( " a.b++; " ) ) ;
ASSERT_EQUALS ( " ab::++ " , testAst ( " a::b++; " ) ) ;
ASSERT_EQUALS ( " c5[--* " , testAst ( " *c[5]--; " ) ) ;
2018-03-10 22:30:21 +01:00
ASSERT_EQUALS ( " xreturn " , testAst ( " return x; " ) ) ;
ASSERT_EQUALS ( " x(throw " , testAst ( " ;throw x(); " ) ) ;
2014-05-19 10:38:54 +02:00
ASSERT_EQUALS ( " a*bc:?return " , testAst ( " return *a ? b : c; " ) ) ;
2018-09-27 19:26:08 +02:00
ASSERT_EQUALS ( " xy*--= " , testAst ( " x = -- * y; " ) ) ;
2020-11-15 10:37:29 +01:00
ASSERT_EQUALS ( " x(throw " , testAst ( " ;throw (foo) x; " ) ) ; // #9955
2013-12-27 14:40:59 +01:00
2014-02-25 06:36:10 +01:00
// Unary :: operator
2014-05-17 12:09:32 +02:00
ASSERT_EQUALS ( " abcd::12,(e/:?= " , testAst ( " a = b ? c : ::d(1,2) / e; " ) ) ;
2014-02-25 06:36:10 +01:00
2013-12-27 14:40:59 +01:00
// how is "--" handled here:
2014-05-11 13:39:28 +02:00
ASSERT_EQUALS ( " ab4<<c--+1:? " , testAst ( " a ? (b << 4) + --c : 1 " ) ) ;
ASSERT_EQUALS ( " ab4<<c--+1:? " , testAst ( " a ? (b << 4) + c-- : 1 " ) ) ;
2014-06-26 17:31:57 +02:00
ASSERT_EQUALS ( " ai[i= i-- " , testAst ( " a[i]=i; --i; " ) ) ;
2012-12-16 08:41:04 +01:00
}
2015-10-07 18:33:57 +02:00
void astfunction ( ) { // function calls
2013-11-04 11:26:16 +01:00
ASSERT_EQUALS ( " 1f(+2+ " , testAst ( " 1+f()+2 " ) ) ;
ASSERT_EQUALS ( " 1f2(+3+ " , testAst ( " 1+f(2)+3 " ) ) ;
ASSERT_EQUALS ( " 1f23,(+4+ " , testAst ( " 1+f(2,3)+4 " ) ) ;
ASSERT_EQUALS ( " 1f2a&,(+ " , testAst ( " 1+f(2,&a) " ) ) ;
2020-10-04 11:27:31 +02:00
ASSERT_EQUALS ( " argv[ " , testAst ( " int f(char argv[]); " ) ) ;
ASSERT_EQUALS ( " " , testAst ( " extern unsigned f(const char *); " ) ) ;
ASSERT_EQUALS ( " charformat*..., " , testAst ( " extern void f(const char *format, ...); " ) ) ;
ASSERT_EQUALS ( " int((void, " , testAst ( " extern int for_each_commit_graft(int (*)(int*), void *); " ) ) ;
2014-06-05 17:36:29 +02:00
ASSERT_EQUALS ( " for;;( " , testAst ( " for (;;) {} " ) ) ;
2013-12-25 22:08:53 +01:00
ASSERT_EQUALS ( " xsizeofvoid(= " , testAst ( " x=sizeof(void*) " ) ) ;
2019-11-03 11:02:59 +01:00
ASSERT_EQUALS ( " abc{d{,{(= " , testAst ( " a = b({ c{}, d{} }); " ) ) ;
2019-11-01 09:05:45 +01:00
ASSERT_EQUALS ( " abc;( " , testAst ( " a(b;c) " ) ) ;
2019-11-23 21:36:36 +01:00
ASSERT_EQUALS ( " x{( forbc;;( " , testAst ( " x({ for(a;b;c){} }); " ) ) ;
2021-08-28 22:11:30 +02:00
ASSERT_EQUALS ( " PT.( " , testAst ( " P->~T(); " ) ) ; // <- The "T" token::function() will be a destructor
2012-12-16 08:41:04 +01:00
}
2015-10-07 18:33:57 +02:00
void asttemplate ( ) { // uninstantiated templates will have <,>,etc..
2014-01-09 17:14:16 +01:00
ASSERT_EQUALS ( " a(3== " , testAst ( " a<int>()==3 " ) ) ;
2014-01-27 06:18:42 +01:00
ASSERT_EQUALS ( " ab(== f( " , testAst ( " a == b<c>(); f(); " ) ) ;
2014-10-10 08:18:24 +02:00
ASSERT_EQUALS ( " static_casta(i[ " , testAst ( " ; static_cast<char*>(a)[i]; " ) ) ; // #6203
2016-01-03 09:38:03 +01:00
ASSERT_EQUALS ( " reinterpret_castreinterpret_castptr(123&( " ,
testAst ( " ;reinterpret_cast<void*>(reinterpret_cast<unsigned>(ptr) & 123); " ) ) ; // #7253
2017-05-23 18:55:17 +02:00
ASSERT_EQUALS ( " bcd.(= " , testAst ( " ;a<int> && b = c->d(); " ) ) ;
2014-02-17 17:37:39 +01:00
2014-05-17 12:09:32 +02:00
// This two unit tests were added to avoid a crash. The actual correct AST result for non-executable code has not been determined so far.
2021-05-03 20:22:08 +02:00
ASSERT_NO_THROW ( testAst ( " class C : public ::a::b<bool> { }; " ) ) ;
2020-10-04 11:27:31 +02:00
ASSERT_EQUALS ( " AB: abc+= " , testAst ( " struct A : public B<C*> { void f() { a=b+c; } }; " ) ) ;
2018-12-12 19:00:14 +01:00
ASSERT_EQUALS ( " xfts(= " , testAst ( " ; auto x = f(ts...); " ) ) ;
2012-12-15 20:21:09 +01:00
}
2014-04-13 12:47:54 +02:00
2015-10-07 18:33:57 +02:00
void astcast ( ) {
2014-05-24 11:28:43 +02:00
ASSERT_EQUALS ( " ac&(= " , testAst ( " a = (long)&c; " ) ) ;
ASSERT_EQUALS ( " ac*(= " , testAst ( " a = (Foo*)*c; " ) ) ;
ASSERT_EQUALS ( " ac-(= " , testAst ( " a = (long)-c; " ) ) ;
2015-10-17 18:25:27 +02:00
ASSERT_EQUALS ( " ac~(= " , testAst ( " a = (b)~c; " ) ) ;
2014-05-24 11:28:43 +02:00
ASSERT_EQUALS ( " ac(= " , testAst ( " a = (some<strange, type>)c; " ) ) ;
2014-05-24 20:21:08 +02:00
ASSERT_EQUALS ( " afoveon_avgimage((foveon_avgimage((+= " , testAst ( " a = foveon_avg(((short(*)[4]) image)) + foveon_avg(((short(*)[4]) image)); " ) ) ;
2014-09-12 06:43:52 +02:00
ASSERT_EQUALS ( " c(40<<return " , testAst ( " return (long long)c << 40; " ) ) ;
2014-05-24 19:04:47 +02:00
ASSERT_EQUALS ( " ab-(= " , testAst ( " a = ((int)-b) " ) ) ; // Multiple subsequent unary operators (cast and -)
2014-10-16 15:57:05 +02:00
ASSERT_EQUALS ( " xdouble123(i*(= " , testAst ( " x = (int)(double(123)*i); " ) ) ;
2016-01-25 10:29:24 +01:00
ASSERT_EQUALS ( " ac(= " , testAst ( " a = (::b)c; " ) ) ;
2017-04-21 17:44:11 +02:00
ASSERT_EQUALS ( " abcd,({(= " , testAst ( " a = (s){b(c, d)}; " ) ) ;
ASSERT_EQUALS ( " xatoistr({(= " , testAst ( " x = (struct X){atoi(str)}; " ) ) ;
2017-04-21 21:02:46 +02:00
ASSERT_EQUALS ( " xa.0=b.0=,c.0=,{(= " , testAst ( " x = (struct abc) { .a=0, .b=0, .c=0 }; " ) ) ;
2015-10-17 18:25:27 +02:00
2018-11-14 21:05:03 +01:00
ASSERT_EQUALS ( " yz.(return " , testAst ( " return (x)(y).z; " ) ) ;
2020-02-21 17:15:33 +01:00
ASSERT_EQUALS ( " fon!(restoring01:?,( " , testAst ( " f((long) !on, restoring ? 0 : 1); " ) ) ;
2015-10-17 18:25:27 +02:00
// not cast
ASSERT_EQUALS ( " AB|| " , testAst ( " (A)||(B) " ) ) ;
2017-09-08 22:52:16 +02:00
ASSERT_EQUALS ( " abc[1&= " , testAst ( " a = (b[c]) & 1; " ) ) ;
2018-09-04 18:10:31 +02:00
ASSERT_EQUALS ( " abc::(= " , testAst ( " a = (b::c)(); " ) ) ;
2019-05-11 15:50:30 +02:00
ASSERT_EQUALS ( " pcharnew(= " , testAst ( " p = (void *)(new char); " ) ) ;
2014-05-24 11:28:43 +02:00
}
2015-10-07 18:33:57 +02:00
void astlambda ( ) {
2015-06-17 19:32:44 +02:00
// a lambda expression '[x](y){}' is compiled as:
// [
// `-(
// `-{
2020-09-05 07:56:01 +02:00
ASSERT_EQUALS ( " x{(a&[( ai= " , testAst ( " x([&a](int i){a=i;}); " ) ) ;
2015-06-17 19:32:44 +02:00
ASSERT_EQUALS ( " {([(return 0return " , testAst ( " return [](){ return 0; }(); " ) ) ;
2020-05-22 11:29:10 +02:00
2021-05-02 21:34:28 +02:00
// noexcept (which if simplified to always have a condition by the time AST is created)
ASSERT_EQUALS ( " x{([( ai= " , testAst ( " x([](int i) noexcept(true) { a=i; }); " ) ) ;
ASSERT_EQUALS ( " x{([( ai= " , testAst ( " x([](int i) mutable noexcept(true) { a=i; }); " ) ) ;
ASSERT_EQUALS ( " x{([( ai= " , testAst ( " x([](int i) const noexcept(true) { a=i; }); " ) ) ;
// both mutable and constexpr (which is simplified to 'const' by the time AST is created)
ASSERT_EQUALS ( " x{([( ai= " , testAst ( " x([](int i) const mutable { a=i; }); " ) ) ;
ASSERT_EQUALS ( " x{([( ai= " , testAst ( " x([](int i) mutable const { a=i; }); " ) ) ;
ASSERT_EQUALS ( " x{([( ai= " , testAst ( " x([](int i) const mutable noexcept(true) { a=i; }); " ) ) ;
ASSERT_EQUALS ( " x{([( ai= " , testAst ( " x([](int i) mutable const noexcept(true) { a=i; }); " ) ) ;
2020-05-22 11:29:10 +02:00
// ->
2015-06-17 19:32:44 +02:00
ASSERT_EQUALS ( " {([(return 0return " , testAst ( " return []() -> int { return 0; }(); " ) ) ;
2020-09-05 07:56:01 +02:00
ASSERT_EQUALS ( " {(something[(return 0return " , testAst ( " return [something]() -> int { return 0; }(); " ) ) ;
2015-06-17 19:32:44 +02:00
ASSERT_EQUALS ( " {([cd,(return 0return " , testAst ( " return [](int a, int b) -> int { return 0; }(c, d); " ) ) ;
2019-12-16 12:17:01 +01:00
ASSERT_EQUALS ( " {([return " , testAst ( " return []() -> decltype(0) {}; " ) ) ;
2020-09-05 07:56:01 +02:00
ASSERT_EQUALS ( " x{(&[= " , testAst ( " x = [&]()->std::string const & {}; " ) ) ;
2018-10-22 17:25:01 +02:00
ASSERT_EQUALS ( " f{([= " , testAst ( " f = []() -> foo* {}; " ) ) ;
2020-11-28 06:53:46 +01:00
ASSERT_EQUALS ( " f{([= " , testAst ( " f = []() -> foo&& {}; " ) ) ;
2018-10-31 12:36:08 +01:00
ASSERT_EQUALS ( " f{([= " , testAst ( " f = [](void) mutable -> foo* {}; " ) ) ;
ASSERT_EQUALS ( " f{([= " , testAst ( " f = []() mutable {}; " ) ) ;
2015-06-17 19:32:44 +02:00
ASSERT_EQUALS ( " x{([= 0return " , testAst ( " x = [](){return 0; }; " ) ) ;
2017-04-09 17:49:55 +02:00
2020-09-05 07:56:01 +02:00
ASSERT_EQUALS ( " ab{&[(= cd= " , testAst ( " a = b([&]{c=d;}); " ) ) ;
2018-11-10 21:32:06 +01:00
// 8628
ASSERT_EQUALS ( " f{([( switchx( 1case y++ " , testAst ( " f([](){switch(x){case 1:{++y;}}}); " ) ) ;
2019-10-22 18:39:44 +02:00
2020-09-05 07:56:01 +02:00
ASSERT_EQUALS ( " {(=[{return ab= " ,
2019-10-22 18:39:44 +02:00
testAst ( " return { \n "
" [=]() { \n "
" a = b; \n "
" } \n "
" }; \n " ) ) ;
2020-09-05 07:56:01 +02:00
ASSERT_EQUALS ( " {=[{return ab= " ,
2019-12-10 21:21:07 +01:00
testAst ( " return { \n "
" [=] { \n "
" a = b; \n "
" } \n "
" }; \n " ) ) ;
2020-09-05 07:56:01 +02:00
ASSERT_EQUALS ( " {(=[{return ab= " ,
2019-10-26 19:19:20 +02:00
testAst ( " return { \n "
" [=]() -> int { \n "
" a=b; \n "
" } \n "
" } " ) ) ;
2020-09-05 07:56:01 +02:00
ASSERT_EQUALS ( " {(=[{return ab= " ,
2019-12-10 21:21:07 +01:00
testAst ( " return { \n "
" [=]() mutable -> int { \n "
" a=b; \n "
" } \n "
" } " ) ) ;
2019-10-30 17:58:19 +01:00
2019-10-30 16:05:34 +01:00
// daca@home hang
2020-09-05 07:56:01 +02:00
ASSERT_EQUALS ( " a{(&[= 0return b{(=[= fori0=i10!=i++;;( " ,
2019-10-30 16:05:34 +01:00
testAst ( " a = [&]() -> std::pair<int, int> { return 0; }; \n "
" b = [=]() { for (i = 0; i != 10; ++i); }; " ) ) ;
2020-04-03 10:04:10 +02:00
// #9662
ASSERT_EQUALS ( " b{[{ stdunique_ptr::0nullptrnullptr:?{ " , testAst ( " auto b{[] { std::unique_ptr<void *>{0 ? nullptr : nullptr}; }}; " ) ) ;
2020-10-04 11:27:31 +02:00
ASSERT_EQUALS ( " b{[= " , testAst ( " void a() { [b = [] { ; }] {}; } " ) ) ;
2020-04-03 10:04:10 +02:00
2021-04-16 15:18:02 +02:00
// Lambda capture expression (C++14)
ASSERT_EQUALS ( " a{b1=[= c2= " , testAst ( " a = [b=1]{c=2;}; " ) ) ;
2021-05-02 21:34:28 +02:00
// #9729
ASSERT_NO_THROW ( tokenizeAndStringify ( " void foo() { bar([]() noexcept { if (0) {} }); } " ) ) ;
2021-05-04 20:15:44 +02:00
// #10079 - createInnerAST bug..
ASSERT_EQUALS ( " x{([= yz= switchy( " ,
testAst ( " x = []() -> std::vector<uint8_t> { \n "
" const auto y = z; \n "
" switch (y) {} \n "
" }; " ) ) ;
2014-05-25 19:48:31 +02:00
}
2017-06-08 15:32:35 +02:00
void astcase ( ) {
ASSERT_EQUALS ( " 0case " , testAst ( " case 0: " ) ) ;
ASSERT_EQUALS ( " 12+case " , testAst ( " case 1+2: " ) ) ;
ASSERT_EQUALS ( " xyz:?case " , testAst ( " case (x?y:z): " ) ) ;
2020-06-14 14:46:16 +02:00
ASSERT_EQUALS ( " switchx( 1case y++ 2case " , testAst ( " switch(x){case 1:{++y;break;case 2:break;}} " ) ) ;
2017-06-08 15:32:35 +02:00
}
2019-12-06 04:19:46 +01:00
void astrefqualifier ( ) {
ASSERT_EQUALS ( " b(int. " , testAst ( " class a { auto b() -> int&; }; " ) ) ;
ASSERT_EQUALS ( " b(int. " , testAst ( " class a { auto b() -> int&&; }; " ) ) ;
ASSERT_EQUALS ( " b( " , testAst ( " class a { void b() &&; }; " ) ) ;
ASSERT_EQUALS ( " b( " , testAst ( " class a { void b() &; }; " ) ) ;
ASSERT_EQUALS ( " b( " , testAst ( " class a { void b() && {} }; " ) ) ;
ASSERT_EQUALS ( " b( " , testAst ( " class a { void b() & {} }; " ) ) ;
}
2020-05-18 19:31:13 +02:00
//Verify that returning a newly constructed object generates the correct AST even when the class name is scoped
//Addresses https://trac.cppcheck.net/ticket/9700
void astnewscoped ( ) {
2020-05-19 18:15:05 +02:00
ASSERT_EQUALS ( " (return (new A)) " , testAst ( " return new A; " , AstStyle : : Z3 ) ) ;
ASSERT_EQUALS ( " (return (new (( A))) " , testAst ( " return new A(); " , AstStyle : : Z3 ) ) ;
ASSERT_EQUALS ( " (return (new (( A true))) " , testAst ( " return new A(true); " , AstStyle : : Z3 ) ) ;
ASSERT_EQUALS ( " (return (new (:: A B))) " , testAst ( " return new A::B; " , AstStyle : : Z3 ) ) ;
ASSERT_EQUALS ( " (return (new (( (:: A B)))) " , testAst ( " return new A::B(); " , AstStyle : : Z3 ) ) ;
ASSERT_EQUALS ( " (return (new (( (:: A B) true))) " , testAst ( " return new A::B(true); " , AstStyle : : Z3 ) ) ;
ASSERT_EQUALS ( " (return (new (:: (:: A B) C))) " , testAst ( " return new A::B::C; " , AstStyle : : Z3 ) ) ;
ASSERT_EQUALS ( " (return (new (( (:: (:: A B) C)))) " , testAst ( " return new A::B::C(); " , AstStyle : : Z3 ) ) ;
ASSERT_EQUALS ( " (return (new (( (:: (:: A B) C) true))) " , testAst ( " return new A::B::C(true); " , AstStyle : : Z3 ) ) ;
ASSERT_EQUALS ( " (return (new (:: (:: (:: A B) C) D))) " , testAst ( " return new A::B::C::D; " , AstStyle : : Z3 ) ) ;
ASSERT_EQUALS ( " (return (new (( (:: (:: (:: A B) C) D)))) " , testAst ( " return new A::B::C::D(); " , AstStyle : : Z3 ) ) ;
ASSERT_EQUALS ( " (return (new (( (:: (:: (:: A B) C) D) true))) " , testAst ( " return new A::B::C::D(true); " , AstStyle : : Z3 ) ) ;
2020-05-18 19:31:13 +02:00
}
2014-11-20 14:20:09 +01:00
void compileLimits ( ) {
2014-04-13 12:47:54 +02:00
const char raw_code [ ] = " #define PTR1 (* (* (* (* (* (* (* (* (* (* \n "
" #define PTR2 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 \n "
" #define PTR3 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 \n "
" #define PTR4 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 \n "
" #define PTR5 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 \n "
" #define PTR6 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 \n "
" \n "
" #define RBR1 ) ) ) ) ) ) ) ) ) ) \n "
" #define RBR2 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 \n "
" #define RBR3 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 \n "
" #define RBR4 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 \n "
" #define RBR5 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 \n "
" #define RBR6 RBR5 RBR5 RBR5 RBR5 RBR5 RBR5 RBR5 RBR5 RBR5 RBR5 \n "
" \n "
" int PTR4 q4_var RBR4 = 0; \n " ;
// Preprocess file..
2015-10-07 18:33:57 +02:00
Preprocessor preprocessor ( settings0 ) ;
2014-04-13 12:47:54 +02:00
std : : list < std : : string > configurations ;
2016-11-30 10:39:14 +01:00
std : : string filedata ;
2014-04-13 12:47:54 +02:00
std : : istringstream fin ( raw_code ) ;
2016-01-03 16:18:17 +01:00
preprocessor . preprocess ( fin , filedata , configurations , emptyString , settings0 . includePaths ) ;
2015-03-15 12:36:40 +01:00
const std : : string code = preprocessor . getcode ( filedata , emptyString , emptyString ) ;
2014-04-13 12:47:54 +02:00
tokenizeAndStringify ( code . c_str ( ) ) ; // just survive...
}
2021-11-29 07:34:39 +01:00
# define isStartOfExecutableScope(offset, code) isStartOfExecutableScope_(offset, code, __FILE__, __LINE__)
bool isStartOfExecutableScope_ ( int offset , const char code [ ] , const char * file , int line ) {
2015-10-07 18:33:57 +02:00
Tokenizer tokenizer ( & settings0 , this ) ;
2014-04-26 18:31:56 +02:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT_LOC ( tokenizer . tokenize ( istr , " test.cpp " ) , file , line ) ;
2014-04-26 18:31:56 +02:00
return Tokenizer : : startOfExecutableScope ( tokenizer . tokens ( ) - > tokAt ( offset ) ) ! = nullptr ;
}
2014-11-20 14:20:09 +01:00
void startOfExecutableScope ( ) {
2014-04-26 18:31:56 +02:00
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() const { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() volatile { } " ) ) ;
2016-01-03 12:22:07 +01:00
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() override { } " ) ) ;
2014-04-26 18:31:56 +02:00
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() noexcept { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() NOEXCEPT { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() CONST NOEXCEPT { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() const noexcept { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() noexcept(true) { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() const noexcept(true) { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() throw() { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() THROW() { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() CONST THROW() { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() const throw() { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() throw(int) { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 3 , " void foo() const throw(int) { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 2 , " foo() : a(1) { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 2 , " foo() : a(1), b(2) { } " ) ) ;
2014-10-15 21:33:07 +02:00
ASSERT ( isStartOfExecutableScope ( 2 , " foo() : a{1} { } " ) ) ;
ASSERT ( isStartOfExecutableScope ( 2 , " foo() : a{1}, b{2} { } " ) ) ;
2014-04-26 18:31:56 +02:00
}
2015-01-17 07:42:49 +01:00
void removeMacroInClassDef ( ) { // #6058
ASSERT_EQUALS ( " class Fred { } ; " , tokenizeAndStringify ( " class DLLEXPORT Fred { } ; " ) ) ;
ASSERT_EQUALS ( " class Fred : Base { } ; " , tokenizeAndStringify ( " class Fred FINAL : Base { } ; " ) ) ;
2015-09-01 07:10:12 +02:00
// Regression for C code:
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( " struct Fred { } ; " , tokenizeAndStringify ( " struct DLLEXPORT Fred { } ; " , true , Settings : : Native , " test.c " ) ) ;
2015-01-17 07:42:49 +01:00
}
2015-02-22 13:38:06 +01:00
void sizeofAddParentheses ( ) {
ASSERT_EQUALS ( " sizeof ( sizeof ( 1 ) ) ; " , tokenizeAndStringify ( " sizeof sizeof 1; " ) ) ;
ASSERT_EQUALS ( " sizeof ( a . b ) + 3 ; " , tokenizeAndStringify ( " sizeof a.b+3; " ) ) ;
ASSERT_EQUALS ( " sizeof ( a [ 2 ] . b ) + 3 ; " , tokenizeAndStringify ( " sizeof a[2].b+3; " ) ) ;
ASSERT_EQUALS ( " f ( 0 , sizeof ( ptr . bar ) ) ; " , tokenizeAndStringify ( " f(0, sizeof ptr->bar ); " ) ) ;
2018-11-30 13:53:58 +01:00
ASSERT_EQUALS ( " sizeof ( a ) > sizeof ( & main ) ; " , tokenizeAndStringify ( " sizeof a > sizeof &main; " ) ) ;
2015-02-22 13:38:06 +01:00
}
2016-07-26 12:15:55 +02:00
2020-02-22 11:57:09 +01:00
void reportUnknownMacros ( ) {
const char code1 [ ] = " MY_UNKNOWN_IMP1(IInStream) \n "
" STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) { if (ptr); } " ;
ASSERT_THROW ( tokenizeAndStringify ( code1 ) , InternalError ) ;
const char code2 [ ] = " void foo() { dostuff(x 0); } " ;
ASSERT_THROW ( tokenizeAndStringify ( code2 ) , InternalError ) ;
2020-02-28 21:51:49 +01:00
const char code3 [ ] = " f( \" 1 \" __stringify(48) \" 1 \" ); " ;
ASSERT_THROW ( tokenizeAndStringify ( code3 ) , InternalError ) ;
2020-03-10 20:22:29 +01:00
const char code4 [ ] = " struct Foo { \n "
" virtual MACRO(int) f1() {} \n "
" virtual MACRO(int) f2() {} \n "
" }; " ;
ASSERT_THROW ( tokenizeAndStringify ( code4 ) , InternalError ) ;
2020-03-12 13:28:09 +01:00
const char code5 [ ] = " void foo() { \n "
" EVALUATE(123, int x=a; int y=b+c;); \n "
" } " ;
ASSERT_THROW ( tokenizeAndStringify ( code5 ) , InternalError ) ;
2020-04-04 10:32:56 +02:00
const char code6 [ ] = " void foo() { dostuff(a, .x=0); } " ;
ASSERT_THROW ( tokenizeAndStringify ( code6 ) , InternalError ) ;
2020-10-24 22:11:21 +02:00
const char code7 [ ] = " void foo() { dostuff(ZEND_NUM_ARGS() TSRMLS_CC, x, y); } " ; // #9476
ASSERT_THROW ( tokenizeAndStringify ( code7 ) , InternalError ) ;
2020-10-27 09:08:13 +01:00
const char code8 [ ] = " void foo() { a = [](int x, decltype(vec) y){}; } " ;
ASSERT_NO_THROW ( tokenizeAndStringify ( code8 ) ) ;
2020-02-19 21:11:54 +01:00
}
2019-10-30 19:36:19 +01:00
void findGarbageCode ( ) { // Test Tokenizer::findGarbageCode()
2020-04-11 17:36:11 +02:00
// C++ try/catch in global scope
2021-05-02 09:05:12 +02:00
ASSERT_THROW_EQUALS ( tokenizeAndStringify ( " try { } " ) , InternalError , " syntax error: keyword 'try' is not allowed in global scope " ) ;
ASSERT_NO_THROW ( tokenizeAndStringify ( " void f() try { } catch (int) { } " ) ) ;
2020-04-11 17:36:11 +02:00
2016-07-26 12:15:55 +02:00
// before if|for|while|switch
2020-04-21 17:27:51 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " void f() { do switch (a) {} while (1); } " ) ) ;
2016-07-26 12:15:55 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " void f() { label: switch (a) {} } " ) ) ;
2020-04-21 17:27:51 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " void f() { UNKNOWN_MACRO if (a) {} } " ) ) ;
2018-10-28 17:17:53 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " void f() { []() -> int * {}; } " ) ) ;
ASSERT_NO_THROW ( tokenizeAndStringify ( " void f() { const char* var = \" 1 \" \" 2 \" ; } " ) ) ;
2019-10-30 19:36:19 +01:00
ASSERT_THROW ( tokenizeAndStringify ( " void f() { MACRO(switch); } " ) , InternalError ) ;
ASSERT_THROW ( tokenizeAndStringify ( " void f() { MACRO(x,switch); } " ) , InternalError ) ;
ASSERT_THROW ( tokenizeAndStringify ( " void foo() { for_chain( if (!done) done = 1); } " ) , InternalError ) ;
ASSERT_THROW ( tokenizeAndStringify ( " void foo() { for_chain( a, b, if (!done) done = 1); } " ) , InternalError ) ;
2016-07-26 12:15:55 +02:00
2020-07-18 06:02:12 +02:00
ASSERT_THROW_EQUALS ( tokenizeAndStringify ( " void f() { if (retval==){} } " ) , InternalError , " syntax error: ==) " ) ;
2019-11-23 18:50:31 +01:00
2016-07-26 14:35:11 +02:00
// after (expr)
2016-07-26 12:15:55 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " void f() { switch (a) int b; } " ) ) ;
2019-07-17 15:21:03 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " S s = { .x=2, .y[0]=3 }; " ) ) ;
2019-08-20 13:56:38 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " S s = { .ab.a=2, .ab.b=3 }; " ) ) ;
2019-12-12 13:51:14 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " extern \" C \" typedef void FUNC(); " ) ) ;
2020-01-25 10:14:16 +01:00
// Ticket #9572
ASSERT_NO_THROW ( tokenizeAndStringify ( " struct poc { "
" struct { int d; } port[1]; "
" }; "
" struct poc p = { .port[0] = {.d = 3} }; " ) ) ;
2020-04-11 11:05:27 +02:00
// op op
ASSERT_THROW_EQUALS ( tokenizeAndStringify ( " void f() { dostuff (x==>y); } " ) , InternalError , " syntax error: == > " ) ;
2020-04-20 08:59:35 +02:00
// Ticket #9664
ASSERT_NO_THROW ( tokenizeAndStringify ( " S s = { .x { 2 }, .y[0] { 3 } }; " ) ) ;
2020-07-18 06:02:12 +02:00
ASSERT_THROW_EQUALS ( tokenizeAndStringify ( " void f() { assert(a==()); } " ) , InternalError , " syntax error: ==() " ) ;
ASSERT_THROW_EQUALS ( tokenizeAndStringify ( " void f() { assert(a+()); } " ) , InternalError , " syntax error: +() " ) ;
2020-09-08 17:12:54 +02:00
// #9445 - typeof is not a keyword in C
2021-04-06 21:21:53 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " void foo() { char *typeof, *value; } " , false , Settings : : Native , " test.c " ) ) ;
2016-07-26 12:15:55 +02:00
}
2017-04-07 19:19:10 +02:00
2018-10-28 17:16:31 +01:00
void checkEnableIf ( ) {
ASSERT_NO_THROW ( tokenizeAndStringify (
2018-10-28 17:37:19 +01:00
" template< \n "
" typename U, \n "
" typename std::enable_if< \n "
" std::is_convertible<U, T>{}>::type* = nullptr> \n "
2020-04-21 17:27:51 +02:00
" void foo(U x); \n " ) ) ;
2018-10-28 17:16:31 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify (
2018-10-28 17:37:19 +01:00
" template<class t> \n "
" T f(const T a, const T b) { \n "
" return a < b ? b : a; \n "
2020-04-21 17:27:51 +02:00
" } \n " ) ) ;
2018-10-28 17:16:31 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify (
2018-10-28 17:37:19 +01:00
" template<class T> \n "
" struct A { \n "
" T f(const T a, const T b) { \n "
" return a < b ? b : a; \n "
" } \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2018-10-28 17:16:31 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify (
2018-10-28 17:37:19 +01:00
" const int a = 1; \n "
" const int b = 2; \n "
" template<class T> \n "
" struct A { \n "
" int x = a < b ? b : a; "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2018-10-28 17:16:31 +01:00
2021-08-28 09:28:56 +02:00
// #10139
ASSERT_NO_THROW ( tokenizeAndStringify ( " template<typename F> \n "
" void foo(std::enable_if_t<value<F>>* = 0) {} \n " ) ) ;
2022-01-12 22:04:28 +01:00
// #10001
ASSERT_NO_THROW ( tokenizeAndStringify ( " struct a { \n "
" int c; \n "
" template <class b> void d(b e) const { c < e ? c : e; } \n "
" }; \n " ) ) ;
ASSERT_NO_THROW ( tokenizeAndStringify ( " struct a { \n "
" int c; \n "
" template <class b> void d(b e) const { c > e ? c : e; } \n "
" }; \n " ) ) ;
2018-10-28 17:16:31 +01:00
}
2019-05-19 10:05:34 +02:00
void checkTemplates ( ) {
2019-05-24 10:44:08 +02:00
// #9109
ASSERT_NO_THROW ( tokenizeAndStringify (
" namespace { \n "
" template <typename> struct a; \n "
" template <typename> struct b {}; \n "
" } \n "
" namespace { \n "
" template <typename> struct c; \n "
" template <typename d> struct e { \n "
" using f = a< b<typename c<d>::g> >; \n "
" bool h = f::h; \n "
" }; \n "
" template <typename i> using j = typename e<i>::g; \n "
2020-04-21 17:27:51 +02:00
" } \n " ) ) ;
2019-05-24 10:44:08 +02:00
2019-05-19 10:05:34 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify (
" template <typename = void> struct a { \n "
" void c(); \n "
" }; \n "
" void f() { \n "
" a<> b; \n "
" b.a<>::c(); \n "
2020-04-21 17:27:51 +02:00
" } \n " ) ) ;
2019-05-21 08:47:10 +02:00
// #9138
ASSERT_NO_THROW ( tokenizeAndStringify (
" template <typename> struct a; \n "
" template <bool> using c = int; \n "
" template <bool b> c<b> d; \n "
" template <> struct a<int> { \n "
2019-05-21 10:43:33 +02:00
" template <typename e> constexpr auto g() { d<0 || e::f>; return 0; } \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2019-05-27 06:54:21 +02:00
// #9144
ASSERT_NO_THROW ( tokenizeAndStringify (
" namespace a { \n "
" template <typename b, bool = __is_empty(b) && __is_final(b)> struct c; \n "
" } \n "
" namespace boost { \n "
" using a::c; \n "
" } \n "
" namespace d = boost; \n "
" using d::c; \n "
" template <typename...> struct e {}; \n "
2020-04-21 17:27:51 +02:00
" static_assert(sizeof(e<>) == sizeof(e<c<int>, c<int>, int>), \" \" ); \n " ) ) ;
2019-06-02 10:23:27 +02:00
// #9146
ASSERT_NO_THROW ( tokenizeAndStringify (
" template <int> struct a; \n "
" template <class, class b> using c = typename a<int{b::d}>::e; \n "
" template <class> struct f; \n "
2020-04-21 17:27:51 +02:00
" template <class b> using g = typename f<c<int, b>>::e; \n " ) ) ;
2019-06-02 10:23:27 +02:00
// #9153
ASSERT_NO_THROW ( tokenizeAndStringify (
" namespace { \n "
" template <class> struct a; \n "
" } \n "
" namespace { \n "
" namespace b { \n "
" template <int c> struct B { using B<c / 2>::d; }; \n "
" } \n "
" template <class, class> using e = typename b::B<int{}>; \n "
" namespace b { \n "
" template <class> struct f; \n "
" } \n "
" template <class c> using g = b::f<e<int, c>>; \n "
2020-04-21 17:27:51 +02:00
" } \n " ) ) ;
2019-06-02 10:23:27 +02:00
// #9154
ASSERT_NO_THROW ( tokenizeAndStringify (
" template <bool> using a = int; \n "
" template <class b> using aa = a<b::c>; \n "
" template <class...> struct A; \n "
" template <class> struct d; \n "
" template <class... f> using e = typename d<f...>::g; \n "
" template <class> struct h; \n "
" template <class, class... b> using i = typename h<b...>::g; \n "
" template <class f, template <class> class j> using k = typename f::g; \n "
" template <class... b> using l = a<k<A<b...>, aa>::c>; \n "
" template <int> struct m; \n "
" template <class, class n> using o = typename m<int{n::c}>::g; \n "
" template <class> struct p; \n "
" template <class, class n> using q = typename p<o<A<>, n>>::g; \n "
" template <class f, class r, class... b> using c = e<i<q<f, r>, b...>>; \n "
" template <class, class> struct s; \n "
" template <template <class> class t, class... w, template <class> class x, \n "
" class... u> \n "
2020-04-21 17:27:51 +02:00
" struct s<t<w...>, x<u...>>; \n " ) ) ;
2019-06-09 08:10:57 +02:00
// #9156
ASSERT_NO_THROW ( tokenizeAndStringify (
" template <typename> struct a; \n "
" template <bool> struct b; \n "
" template <class k, class> using d = typename b<k::c>::e; \n "
" template <class> struct f; \n "
" template <template <class> class, class... g> using i = typename f<g...>::e; \n "
" template <template <class> class h, class... g> using ab = d<i<h, g...>, int>; \n "
" template <template <class> class h, class... g> struct j { \n "
" template <class... ag> using ah = typename ab<h, ag..., g...>::e; \n "
" }; \n "
" template <class> struct F; \n "
2020-04-21 17:27:51 +02:00
" int main() { using T = void (*)(a<j<F, char[]>>); } \n " ) ) ;
2019-09-09 21:35:49 +02:00
2021-08-14 22:50:58 +02:00
// #9245
ASSERT_NO_THROW ( tokenizeAndStringify ( " struct a { \n "
" typedef int b; \n "
" operator b(); \n "
" }; \n "
" template <int> using c = a; \n "
" template <int d> c<d> e; \n "
" auto f = ((e<4> | 0)); \n " ) ) ;
2019-09-09 21:35:49 +02:00
// #9340
ASSERT_NO_THROW ( tokenizeAndStringify (
" struct a { \n "
" template <class... b> void c(b... p1) { \n "
" using d = a; \n "
" d e = {(p1)...}; \n "
" } \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2020-05-23 21:11:08 +02:00
2021-08-15 07:43:02 +02:00
// #9444
ASSERT_NO_THROW ( tokenizeAndStringify ( " template <int> struct a; \n "
" template <long b> using c = a<b>; \n "
" template <long b> c<b> d; \n "
" template <typename> struct e { \n "
" template <typename... f> void g() const { d<e<f &&...>::h>; } \n "
" }; \n " ) ) ;
2020-09-07 10:54:32 +02:00
// #9858
ASSERT_NO_THROW ( tokenizeAndStringify (
" struct a { \n "
" struct b {}; \n "
" }; \n "
" void c(a::b, a::b); \n "
" void g(a::b f) { c(f, {a::b{}}); } \n "
" template <class> void h() { \n "
" int e; \n "
" for (int d = 0; d < e; d++) \n "
" ; \n "
" } \n " ) ) ;
2021-08-14 22:50:58 +02:00
// #10015
ASSERT_NO_THROW ( tokenizeAndStringify (
" void func() { \n "
" if (std::is_same_v<int, int> || 1) \n "
" ; \n "
" } \n " ) ) ;
2021-06-24 08:25:13 +02:00
// #10309
ASSERT_NO_THROW ( tokenizeAndStringify (
" using a = void *; \n "
" void b() { \n "
" std::unique_ptr<a, void (*)(a *)>(new a(0), [](a *c) { \n "
" if (c) \n "
" ; \n "
" }); \n "
" } \n " ) ) ;
2020-05-23 21:11:08 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " a<b?0:1>()==3; " ) ) ;
2021-07-09 07:22:24 +02:00
// #10336
ASSERT_NO_THROW ( tokenizeAndStringify ( " struct a { \n "
" template <class b> a(b); \n "
" }; \n "
" struct c; \n "
" void fn1(int, a); \n "
" void f() { fn1(0, {a{0}}); } \n "
" template <class> std::vector<c> g() { \n "
" int d; \n "
" for (size_t e = 0; e < d; e++) \n "
" ; \n "
" } \n " ) ) ;
2021-08-14 21:16:27 +02:00
2021-12-04 17:03:02 +01:00
// #9523
ASSERT_NO_THROW ( tokenizeAndStringify (
" template <int> struct a; \n "
" template <typename, typename> struct b; \n "
" template <typename c> struct b<c, typename a<c{} && 0>::d> { \n "
" void e() { \n "
" if (0) {} \n "
" } \n "
" }; \n " ) ) ;
2021-08-14 21:16:27 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify (
" template <std::size_t First, std::size_t... Indices, typename Functor> \n "
" constexpr void constexpr_for_fold_impl([[maybe_unused]] Functor&& f, std::index_sequence<Indices...>) noexcept { \n "
" (std::forward<Functor>(f).template operator() < First + Indices > (), ...); \n "
" } \n " ) ) ;
2021-12-04 12:56:25 +01:00
// #9301
ASSERT_NO_THROW ( tokenizeAndStringify ( " template <typename> constexpr char x[] = \" \" ; \n "
" template <> constexpr char x<int>[] = \" \" ; \n " ) ) ;
2021-12-16 22:32:44 +01:00
// #10951
ASSERT_NO_THROW ( tokenizeAndStringify ( " struct a { \n "
" template <class> static void b() {} \n "
" ~a(); \n "
" }; \n "
" void d() { a::b<int>(); } \n " ) ) ;
2019-05-19 10:05:34 +02:00
}
2019-06-10 08:22:48 +02:00
void checkNamespaces ( ) {
2020-04-21 17:27:51 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " namespace x { namespace y { namespace z {}}} " ) ) ;
2019-06-10 08:22:48 +02:00
}
2019-07-05 12:26:01 +02:00
void checkLambdas ( ) {
2020-04-21 17:27:51 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " auto f(int& i) { return [=, &i] {}; } " ) ) ;
ASSERT_NO_THROW ( tokenizeAndStringify ( " auto f(int& i) { return [&, i] {}; } " ) ) ;
ASSERT_NO_THROW ( tokenizeAndStringify ( " auto f(int& i) { return [&, i = std::move(i)] {}; } " ) ) ;
ASSERT_NO_THROW ( tokenizeAndStringify ( " auto f(int& i) { return [=, i = std::move(i)] {}; } " ) ) ;
2019-07-06 10:46:17 +02:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " struct c { \n "
" void d() { \n "
" int a; \n "
" auto b = [this, a] {}; \n "
" } \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2019-12-10 21:21:07 +01:00
// #9525
ASSERT_NO_THROW ( tokenizeAndStringify ( " struct a { \n "
" template <class b> a(b) {} \n "
" }; \n "
" auto c() -> a { \n "
" return {[] { \n "
" if (0) {} \n "
" }}; \n "
2020-04-21 17:27:51 +02:00
" } \n " ) ) ;
2019-12-10 21:21:07 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " struct a { \n "
" template <class b> a(b) {} \n "
" }; \n "
" auto c() -> a { \n "
" return {[]() -> int { \n "
" if (0) {} \n "
" return 0; \n "
" }}; \n "
2020-04-21 17:27:51 +02:00
" } \n " ) ) ;
2019-12-10 21:21:07 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " struct a { \n "
" template <class b> a(b) {} \n "
" }; \n "
" auto c() -> a { \n "
" return {[]() mutable -> int { \n "
" if (0) {} \n "
" return 0; \n "
" }}; \n "
2020-04-21 17:27:51 +02:00
" } \n " ) ) ;
2019-12-16 12:17:01 +01:00
// #0535
ASSERT_NO_THROW ( tokenizeAndStringify ( " template <typename, typename> struct a; \n "
" template <typename, typename b> void c() { \n "
" ([]() -> decltype(0) { \n "
" if (a<b, decltype(0)>::d) {} \n "
" }); \n "
2020-04-21 17:27:51 +02:00
" } \n " ) ) ;
2020-01-04 10:45:24 +01:00
// #9563
ASSERT_NO_THROW ( tokenizeAndStringify ( " template <typename> struct a; \n "
" template <typename b, typename... c> struct a<b(c...)> { \n "
" template <typename d> a(d); \n "
" }; \n "
" void e( \n "
2020-04-21 17:27:51 +02:00
" int, a<void()> f = [] {}); \n " ) ) ;
2020-04-03 10:04:10 +02:00
2020-04-04 10:55:31 +02:00
// #9644
ASSERT_NO_THROW ( tokenizeAndStringify ( " void a() { \n "
" char b[]{}; \n "
" auto c = [](int d) { \n "
" for (char e = 0; d;) {} \n "
" }; \n "
2020-04-21 17:27:51 +02:00
" } \n " ) ) ;
2020-04-03 10:04:10 +02:00
// #9537
ASSERT_NO_THROW ( tokenizeAndStringify ( " struct a { \n "
" template <typename b> a(b) {} \n "
" }; \n "
" a c{[] { \n "
" if (0) {} \n "
2020-04-21 17:27:51 +02:00
" }}; \n " ) ) ;
2020-06-07 08:58:12 +02:00
// #9185
ASSERT_NO_THROW ( tokenizeAndStringify ( " void a() { \n "
" [b = [] { ; }] {}; \n "
" } \n " ) ) ;
2019-07-05 12:26:01 +02:00
}
2019-12-01 14:53:03 +01:00
void checkIfCppCast ( ) {
ASSERT_NO_THROW ( tokenizeAndStringify ( " struct a { \n "
" int b(); \n "
" }; \n "
" struct c { \n "
" bool d() const; \n "
" a e; \n "
" }; \n "
" bool c::d() const { \n "
" int f = 0; \n "
" if (!const_cast<a *>(&e)->b()) {} \n "
" return f; \n "
2020-04-21 17:27:51 +02:00
" } \n " ) ) ;
2019-12-01 14:53:03 +01:00
}
2019-07-05 12:26:01 +02:00
2019-12-06 04:19:46 +01:00
void checkRefQualifiers ( ) {
2019-12-07 21:06:45 +01:00
// #9511
2019-12-06 04:19:46 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " class a { \n "
" void b() && { \n "
" if (this) {} \n "
" } \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2019-12-06 04:19:46 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " class a { \n "
" void b() & { \n "
" if (this) {} \n "
" } \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2019-12-06 04:19:46 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " class a { \n "
" auto b() && -> void { \n "
" if (this) {} \n "
" } \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2019-12-06 04:19:46 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " class a { \n "
" auto b() & -> void { \n "
" if (this) {} \n "
" } \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2019-12-06 04:19:46 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " class a { \n "
" auto b(int& x) -> int& { \n "
" if (this) {} \n "
" return x; \n "
" } \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2019-12-06 04:19:46 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " class a { \n "
" auto b(int& x) -> int&& { \n "
" if (this) {} \n "
" return x; \n "
" } \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2019-12-06 04:19:46 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " class a { \n "
" auto b(int& x) && -> int& { \n "
" if (this) {} \n "
" return x; \n "
" } \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2019-12-07 21:06:45 +01:00
// #9524
ASSERT_NO_THROW ( tokenizeAndStringify ( " auto f() -> int* { \n "
" if (0) {} \n "
" return 0; \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2019-12-07 21:06:45 +01:00
ASSERT_NO_THROW ( tokenizeAndStringify ( " auto f() -> int** { \n "
" if (0) {} \n "
" return 0; \n "
2020-04-21 17:27:51 +02:00
" }; \n " ) ) ;
2019-12-06 04:19:46 +01:00
}
2019-12-07 21:16:25 +01:00
void checkConditionBlock ( ) {
ASSERT_NO_THROW ( tokenizeAndStringify ( " void a() { \n "
" for (auto b : std::vector<std::vector<int>>{{}, {}}) {} \n "
2020-04-21 17:27:51 +02:00
" } \n " ) ) ;
2019-12-07 21:16:25 +01:00
}
2021-09-25 11:55:49 +02:00
void checkUnknownCircularVar ( )
{
ASSERT_NO_THROW ( tokenizeAndStringify ( " void execute() { \n "
" const auto &bias = GEMM_CTX_ARG_STORAGE(bias); \n "
" auto &c = GEMM_CTX_ARG_STORAGE(c); \n "
" } \n " ) ) ;
}
2019-03-22 01:56:09 +01:00
void noCrash1 ( ) {
ASSERT_NO_THROW ( tokenizeAndStringify (
" struct A { \n "
2021-08-07 20:51:18 +02:00
" A( const std::string &name = " " ); \n "
2019-03-22 01:56:09 +01:00
" }; \n "
2020-04-21 17:27:51 +02:00
" A::A( const std::string &name ) { return; } \n " ) ) ;
2019-03-22 01:56:09 +01:00
}
2019-06-10 08:24:09 +02:00
// #9007
void noCrash2 ( ) {
ASSERT_NO_THROW ( tokenizeAndStringify (
" class a { \n "
" public: \n "
" enum b {}; \n "
" }; \n "
" struct c; \n "
" template <class> class d { \n "
" d(const int &, a::b, double, double); \n "
" d(const d &); \n "
" }; \n "
" template <> d<int>::d(const int &, a::b, double, double); \n "
" template <> d<int>::d(const d &) {} \n "
2020-04-21 17:27:51 +02:00
" template <> d<c>::d(const d &) {} \n " ) ) ;
2019-06-10 08:24:09 +02:00
}
2020-09-14 18:44:50 +02:00
void noCrash3 ( ) {
ASSERT_NO_THROW ( tokenizeAndStringify ( " void a(X<int> x, typename Y1::Y2<int, A::B::C, 2> y, Z z = []{}); " ) ) ;
}
2022-01-01 00:14:36 +01:00
void noCrash4 ( )
{
ASSERT_NO_THROW ( tokenizeAndStringify ( " static int foo() { \n "
" zval ref ; \n "
" p = &(ref).value; \n "
" return result ; \n "
" } \n " ) ) ;
}
2017-04-07 19:19:10 +02:00
void checkConfig ( const char code [ ] ) {
errout . str ( " " ) ;
Settings s ;
s . checkConfiguration = true ;
// tokenize..
Tokenizer tokenizer ( & s , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2017-04-07 19:19:10 +02:00
}
void checkConfiguration ( ) {
2020-03-12 13:28:09 +01:00
ASSERT_THROW ( checkConfig ( " void f() { DEBUG(x();y()); } " ) , InternalError ) ;
//ASSERT_EQUALS("[test.cpp:1]: (information) Ensure that 'DEBUG' is defined either using -I, --include or -D.\n", errout.str());
2017-04-07 19:19:10 +02:00
}
2019-01-31 16:53:51 +01:00
void unknownType ( ) { // #8952
// Clear the error log
errout . str ( " " ) ;
Settings settings ;
settings . debugwarnings = true ;
char code [ ] = " class A { \n "
" public: \n "
" enum Type { Null }; \n "
" }; \n "
" using V = A; \n "
" V::Type value; " ;
// Tokenize..
Tokenizer tokenizer ( & settings , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2019-01-31 16:53:51 +01:00
tokenizer . printUnknownTypes ( ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2019-07-16 20:32:46 +02:00
void unknownMacroBeforeReturn ( ) {
ASSERT_THROW ( tokenizeAndStringify ( " int f() { X return 0; } " ) , InternalError ) ;
}
2020-02-16 16:46:30 +01:00
void cppcast ( ) {
const char code [ ] = " a = const_cast<int>(x); \n "
" a = dynamic_cast<int>(x); \n "
" a = reinterpret_cast<int>(x); \n "
" a = static_cast<int>(x); \n " ;
Settings settings ;
Tokenizer tokenizer ( & settings , this ) ;
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT ( tokenizer . tokenize ( istr , " test.cpp " ) ) ;
2020-02-16 16:46:30 +01:00
for ( const Token * tok = tokenizer . tokens ( ) ; tok ; tok = tok - > next ( ) ) {
ASSERT_EQUALS ( tok - > str ( ) = = " ( " , tok - > isCast ( ) ) ;
}
}
2020-11-11 09:50:51 +01:00
2020-11-22 16:43:36 +01:00
std : : string checkHeaders ( const char code [ ] , bool checkHeadersFlag ) {
2020-11-11 09:50:51 +01:00
// Clear the error buffer..
errout . str ( " " ) ;
Settings settings ;
2020-11-22 16:43:36 +01:00
settings . checkHeaders = checkHeadersFlag ;
2020-11-11 09:50:51 +01:00
// Raw tokens..
std : : vector < std : : string > files ( 1 , " test.cpp " ) ;
std : : istringstream istr ( code ) ;
const simplecpp : : TokenList tokens1 ( istr , files , files [ 0 ] ) ;
// Preprocess..
simplecpp : : TokenList tokens2 ( files ) ;
std : : map < std : : string , simplecpp : : TokenList * > filedata ;
simplecpp : : preprocess ( tokens2 , tokens1 , files , filedata , simplecpp : : DUI ( ) ) ;
Preprocessor preprocessor ( settings0 , nullptr ) ;
preprocessor . setDirectives ( tokens1 ) ;
// Tokenizer..
2020-11-11 15:28:32 +01:00
Tokenizer tokenizer ( & settings , this ) ;
2020-11-11 09:50:51 +01:00
tokenizer . createTokens ( std : : move ( tokens2 ) ) ;
tokenizer . simplifyTokens1 ( " " ) ;
return tokenizer . tokens ( ) - > stringifyList ( ) ;
}
void checkHeader1 ( ) {
// #9977
const char code [ ] = " # 1 \" test.h \" \n "
" struct A { \n "
" int a = 1; \n "
" void f() { g(1); } \n "
" template <typename T> void g(T x) { a = 2; } \n " // <- template is used and should be kept
" }; " ;
ASSERT_EQUALS ( " \n \n ##file 1 \n "
" 1: struct A { \n "
" 2: int a ; a = 1 ; \n "
" 3: void f ( ) { g<int> ( 1 ) ; } \n "
" 4: void g<int> ( int x ) ; \n "
2020-12-08 10:35:13 +01:00
" 5: } ; \n "
" 4: void A :: g<int> ( int x ) { a = 2 ; } \n " ,
2020-11-11 09:50:51 +01:00
checkHeaders ( code , true ) ) ;
2020-11-22 16:43:36 +01:00
ASSERT_EQUALS ( " \n \n ##file 1 \n \n "
" 1: \n "
" | \n "
2020-11-11 15:28:32 +01:00
" 4: \n "
2020-11-22 16:43:36 +01:00
" 5: ; \n " ,
2020-11-11 09:50:51 +01:00
checkHeaders ( code , false ) ) ;
}
2020-11-28 21:55:28 +01:00
void removeExtraTemplateKeywords ( ) {
const char code1 [ ] = " typename GridView::template Codim<0>::Iterator iterator; " ;
const char expected1 [ ] = " GridView :: Codim < 0 > :: Iterator iterator ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected1 , tokenizeAndStringify ( code1 ) ) ;
2020-11-28 21:55:28 +01:00
const char code2 [ ] = " typename GridView::template Codim<0>::Iterator it = gv.template begin<0>(); " ;
const char expected2 [ ] = " GridView :: Codim < 0 > :: Iterator it ; it = gv . begin < 0 > ( ) ; " ;
2021-04-06 21:21:53 +02:00
ASSERT_EQUALS ( expected2 , tokenizeAndStringify ( code2 ) ) ;
2020-11-28 21:55:28 +01:00
}
2021-04-15 20:26:53 +02:00
2021-04-26 11:43:49 +02:00
void removeAlignas1 ( ) {
2021-04-15 20:26:53 +02:00
const char code [ ] = " alignas(float) unsigned char c[sizeof(float)]; " ;
const char expected [ ] = " unsigned char c [ sizeof ( float ) ] ; " ;
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
}
2021-04-18 19:42:22 +02:00
2021-04-26 11:43:49 +02:00
void removeAlignas2 ( ) { // Do not remove alignas and alignof in the same way
const char code [ ] = " static_assert( alignof( VertexC ) == 4 ); " ;
const char expected [ ] = " static_assert ( alignof ( VertexC ) == 4 ) ; " ;
ASSERT_EQUALS ( expected , tokenizeAndStringify ( code ) ) ;
}
2021-04-18 19:42:22 +02:00
void simplifyCoroutines ( ) {
Settings settings ;
settings . standards . cpp = Standards : : CPP20 ;
const char code1 [ ] = " generator<int> f() { co_yield start++; } " ;
const char expected1 [ ] = " generator < int > f ( ) { co_yield ( start ++ ) ; } " ;
ASSERT_EQUALS ( expected1 , tokenizeAndStringify ( code1 , settings ) ) ;
const char code2 [ ] = " task<> f() { co_await foo(); } " ;
const char expected2 [ ] = " task < > f ( ) { co_await ( foo ( ) ) ; } " ;
ASSERT_EQUALS ( expected2 , tokenizeAndStringify ( code2 , settings ) ) ;
const char code3 [ ] = " generator<int> f() { co_return 7; } " ;
const char expected3 [ ] = " generator < int > f ( ) { co_return ( 7 ) ; } " ;
ASSERT_EQUALS ( expected3 , tokenizeAndStringify ( code3 , settings ) ) ;
}
2021-04-22 19:15:22 +02:00
void simplifySpaceshipOperator ( ) {
Settings settings ;
settings . standards . cpp = Standards : : CPP20 ;
ASSERT_EQUALS ( " ; x <=> y ; " , tokenizeAndStringify ( " ;x<=>y; " , settings ) ) ;
}
2021-04-25 14:37:27 +02:00
void simplifyIfSwitchForInit1 ( ) {
Settings settings ;
settings . standards . cpp = Standards : : CPP17 ;
const char code [ ] = " void f() { if (a;b) {} } " ;
ASSERT_EQUALS ( " void f ( ) { { a ; if ( b ) { } } } " , tokenizeAndStringify ( code , settings ) ) ;
}
void simplifyIfSwitchForInit2 ( ) {
Settings settings ;
settings . standards . cpp = Standards : : CPP20 ;
const char code [ ] = " void f() { if (a;b) {} else {} } " ;
ASSERT_EQUALS ( " void f ( ) { { a ; if ( b ) { } else { } } } " , tokenizeAndStringify ( code , settings ) ) ;
}
void simplifyIfSwitchForInit3 ( ) {
Settings settings ;
settings . standards . cpp = Standards : : CPP20 ;
const char code [ ] = " void f() { switch (a;b) {} } " ;
ASSERT_EQUALS ( " void f ( ) { { a ; switch ( b ) { } } } " , tokenizeAndStringify ( code , settings ) ) ;
}
void simplifyIfSwitchForInit4 ( ) {
Settings settings ;
settings . standards . cpp = Standards : : CPP20 ;
const char code [ ] = " void f() { for (a;b:c) {} } " ;
ASSERT_EQUALS ( " void f ( ) { { a ; for ( b : c ) { } } } " , tokenizeAndStringify ( code , settings ) ) ;
}
2021-12-15 19:34:18 +01:00
void simplifyIfSwitchForInit5 ( ) {
Settings settings ;
settings . standards . cpp = Standards : : CPP20 ;
const char code [ ] = " void f() { if ([] { ; }) {} } " ;
ASSERT_EQUALS ( " void f ( ) { if ( [ ] { ; } ) { } } " , tokenizeAndStringify ( code , settings ) ) ;
}
2008-12-18 22:28:57 +01:00
} ;
2009-01-05 16:49:57 +01:00
REGISTER_TEST ( TestTokenizer )