2014-09-24 13:23:44 +02:00
|
|
|
/*
|
|
|
|
* Cppcheck - A tool for static C/C++ code analysis
|
2022-02-05 11:45:17 +01:00
|
|
|
* Copyright (C) 2007-2022 Cppcheck team.
|
2014-09-24 13:23:44 +02: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
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2022-01-27 19:03:20 +01:00
|
|
|
#include "mathlib.h"
|
2017-05-27 04:33:47 +02:00
|
|
|
#include "platform.h"
|
|
|
|
#include "settings.h"
|
|
|
|
#include "standards.h"
|
2014-09-24 13:23:44 +02:00
|
|
|
#include "testsuite.h"
|
|
|
|
#include "token.h"
|
2017-05-27 04:33:47 +02:00
|
|
|
#include "tokenize.h"
|
|
|
|
|
2022-09-16 07:15:49 +02:00
|
|
|
#include <sstream> // IWYU pragma: keep
|
2017-05-27 04:33:47 +02:00
|
|
|
#include <string>
|
|
|
|
|
|
|
|
struct InternalError;
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
|
|
|
|
class TestVarID : public TestFixture {
|
|
|
|
public:
|
2021-08-07 20:51:18 +02:00
|
|
|
TestVarID() : TestFixture("TestVarID") {}
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
private:
|
2022-02-10 23:02:24 +01:00
|
|
|
void run() override {
|
2014-09-24 13:23:44 +02:00
|
|
|
TEST_CASE(varid1);
|
|
|
|
TEST_CASE(varid2);
|
|
|
|
TEST_CASE(varid3);
|
|
|
|
TEST_CASE(varid4);
|
|
|
|
TEST_CASE(varid5);
|
|
|
|
TEST_CASE(varid6);
|
|
|
|
TEST_CASE(varid7);
|
|
|
|
TEST_CASE(varidReturn1);
|
|
|
|
TEST_CASE(varidReturn2);
|
|
|
|
TEST_CASE(varid8);
|
|
|
|
TEST_CASE(varid9);
|
|
|
|
TEST_CASE(varid10);
|
|
|
|
TEST_CASE(varid11);
|
|
|
|
TEST_CASE(varid12);
|
|
|
|
TEST_CASE(varid13);
|
|
|
|
TEST_CASE(varid14);
|
|
|
|
TEST_CASE(varid15);
|
|
|
|
TEST_CASE(varid16);
|
|
|
|
TEST_CASE(varid17); // ticket #1810
|
|
|
|
TEST_CASE(varid18);
|
|
|
|
TEST_CASE(varid19);
|
|
|
|
TEST_CASE(varid20);
|
|
|
|
TEST_CASE(varid24);
|
|
|
|
TEST_CASE(varid25);
|
|
|
|
TEST_CASE(varid26); // ticket #1967 (list of function pointers)
|
|
|
|
TEST_CASE(varid27); // Ticket #2280 (same name for namespace and variable)
|
|
|
|
TEST_CASE(varid28); // ticket #2630
|
|
|
|
TEST_CASE(varid29); // ticket #1974
|
|
|
|
TEST_CASE(varid30); // ticket #2614
|
|
|
|
TEST_CASE(varid34); // ticket #2825
|
2015-11-19 16:27:16 +01:00
|
|
|
TEST_CASE(varid35); // function declaration inside function body
|
2014-09-24 13:23:44 +02:00
|
|
|
TEST_CASE(varid36); // ticket #2980 (segmentation fault)
|
|
|
|
TEST_CASE(varid37); // ticket #3092 (varid for 'Bar bar(*this);')
|
|
|
|
TEST_CASE(varid38); // ticket #3272 (varid for 'FOO class C;')
|
|
|
|
TEST_CASE(varid39); // ticket #3279 (varid for 'FOO::BAR const')
|
|
|
|
TEST_CASE(varid40); // ticket #3279
|
|
|
|
TEST_CASE(varid41); // ticket #3340 (varid for union type)
|
|
|
|
TEST_CASE(varid42); // ticket #3316 (varid for array)
|
|
|
|
TEST_CASE(varid43);
|
|
|
|
TEST_CASE(varid44);
|
|
|
|
TEST_CASE(varid45); // #3466
|
|
|
|
TEST_CASE(varid46); // struct varname
|
|
|
|
TEST_CASE(varid47); // function parameters
|
|
|
|
TEST_CASE(varid48); // #3785 - return (a*b)
|
|
|
|
TEST_CASE(varid49); // #3799 - void f(std::vector<int>)
|
|
|
|
TEST_CASE(varid50); // #3760 - explicit
|
|
|
|
TEST_CASE(varid51); // don't set varid for template function
|
|
|
|
TEST_CASE(varid52); // Set varid for nested templates
|
|
|
|
TEST_CASE(varid53); // #4172 - Template instantiation: T<&functionName> list[4];
|
|
|
|
TEST_CASE(varid54); // hang
|
|
|
|
TEST_CASE(varid55); // #5868: Function::addArgument with varid 0 for argument named the same as a typedef
|
2015-02-26 16:31:42 +01:00
|
|
|
TEST_CASE(varid56); // function with a throw()
|
2015-04-08 20:30:41 +02:00
|
|
|
TEST_CASE(varid57); // #6636: new scope by {}
|
2015-04-09 19:58:12 +02:00
|
|
|
TEST_CASE(varid58); // #6638: for loop in for condition
|
2015-11-10 17:03:27 +01:00
|
|
|
TEST_CASE(varid59); // #6696
|
2016-01-06 17:47:59 +01:00
|
|
|
TEST_CASE(varid60); // #7267 cast '(unsigned x)10'
|
2017-11-05 22:25:46 +01:00
|
|
|
TEST_CASE(varid61); // #4988 inline function
|
2019-03-24 07:06:15 +01:00
|
|
|
TEST_CASE(varid62);
|
2019-05-12 09:10:37 +02:00
|
|
|
TEST_CASE(varid63);
|
2020-09-29 10:53:20 +02:00
|
|
|
TEST_CASE(varid64); // #9928 - extern const char (*x[256])
|
2022-03-31 21:08:04 +02:00
|
|
|
TEST_CASE(varid65); // #10936
|
2020-04-18 12:08:53 +02:00
|
|
|
TEST_CASE(varid_for_1);
|
|
|
|
TEST_CASE(varid_for_2);
|
2014-09-24 13:23:44 +02:00
|
|
|
TEST_CASE(varid_cpp_keywords_in_c_code);
|
|
|
|
TEST_CASE(varid_cpp_keywords_in_c_code2); // #5373: varid=0 for argument called "delete"
|
|
|
|
TEST_CASE(varidFunctionCall1);
|
|
|
|
TEST_CASE(varidFunctionCall2);
|
|
|
|
TEST_CASE(varidFunctionCall3);
|
|
|
|
TEST_CASE(varidFunctionCall4); // ticket #3280
|
2016-12-18 20:16:38 +01:00
|
|
|
TEST_CASE(varidFunctionCall5);
|
2014-09-24 13:23:44 +02:00
|
|
|
TEST_CASE(varidStl);
|
2017-11-05 17:59:34 +01:00
|
|
|
TEST_CASE(varidStl2);
|
2014-10-10 16:46:31 +02:00
|
|
|
TEST_CASE(varid_newauto); // not declaration: new const auto(0);
|
2014-09-24 13:23:44 +02:00
|
|
|
TEST_CASE(varid_delete);
|
|
|
|
TEST_CASE(varid_functions);
|
|
|
|
TEST_CASE(varid_sizeof);
|
|
|
|
TEST_CASE(varid_reference_to_containers);
|
|
|
|
TEST_CASE(varid_in_class1);
|
|
|
|
TEST_CASE(varid_in_class2);
|
|
|
|
TEST_CASE(varid_in_class3); // #3092 - shadow variable in member function
|
|
|
|
TEST_CASE(varid_in_class4); // #3271 - public: class C;
|
|
|
|
TEST_CASE(varid_in_class5); // #3584 - std::vector<::FOO::B> b;
|
|
|
|
TEST_CASE(varid_in_class6); // #3755
|
|
|
|
TEST_CASE(varid_in_class7); // set variable id for struct members
|
2020-05-17 19:12:16 +02:00
|
|
|
TEST_CASE(varid_in_class8); // unknown macro in class
|
2014-09-24 13:23:44 +02:00
|
|
|
TEST_CASE(varid_in_class9); // #4291 - id for variables accessed through 'this'
|
|
|
|
TEST_CASE(varid_in_class10);
|
|
|
|
TEST_CASE(varid_in_class11); // #4277 - anonymous union
|
|
|
|
TEST_CASE(varid_in_class12); // #4637 - method
|
|
|
|
TEST_CASE(varid_in_class13); // #4637 - method
|
|
|
|
TEST_CASE(varid_in_class14);
|
|
|
|
TEST_CASE(varid_in_class15); // #5533 - functions
|
|
|
|
TEST_CASE(varid_in_class16);
|
|
|
|
TEST_CASE(varid_in_class17); // #6056 - no varid for member functions
|
2015-11-13 10:07:57 +01:00
|
|
|
TEST_CASE(varid_in_class18); // #7127
|
2015-11-18 21:13:58 +01:00
|
|
|
TEST_CASE(varid_in_class19);
|
2016-01-10 22:10:49 +01:00
|
|
|
TEST_CASE(varid_in_class20); // #7267
|
2017-11-10 21:03:15 +01:00
|
|
|
TEST_CASE(varid_in_class21); // #7788
|
2022-03-16 15:29:34 +01:00
|
|
|
TEST_CASE(varid_in_class22); // #10872
|
2022-09-21 17:35:10 +02:00
|
|
|
TEST_CASE(varid_in_class23); // #11293
|
2023-01-09 16:11:26 +01:00
|
|
|
TEST_CASE(varid_in_class24);
|
2017-11-08 22:52:27 +01:00
|
|
|
TEST_CASE(varid_namespace_1); // #7272
|
|
|
|
TEST_CASE(varid_namespace_2); // #7000
|
2018-12-02 09:28:05 +01:00
|
|
|
TEST_CASE(varid_namespace_3); // #8627
|
2020-12-08 17:25:50 +01:00
|
|
|
TEST_CASE(varid_namespace_4);
|
|
|
|
TEST_CASE(varid_namespace_5);
|
2014-09-24 13:23:44 +02:00
|
|
|
TEST_CASE(varid_initList);
|
2015-04-06 19:47:21 +02:00
|
|
|
TEST_CASE(varid_initListWithBaseTemplate);
|
2016-01-09 12:18:36 +01:00
|
|
|
TEST_CASE(varid_initListWithScope);
|
2014-09-24 13:23:44 +02:00
|
|
|
TEST_CASE(varid_operator);
|
|
|
|
TEST_CASE(varid_throw);
|
|
|
|
TEST_CASE(varid_unknown_macro); // #2638 - unknown macro is not type
|
|
|
|
TEST_CASE(varid_using); // ticket #3648
|
|
|
|
TEST_CASE(varid_catch);
|
|
|
|
TEST_CASE(varid_functionPrototypeTemplate);
|
|
|
|
TEST_CASE(varid_templatePtr); // #4319
|
|
|
|
TEST_CASE(varid_templateNamespaceFuncPtr); // #4172
|
|
|
|
TEST_CASE(varid_templateArray);
|
2016-01-31 11:07:30 +01:00
|
|
|
TEST_CASE(varid_templateParameter); // #7046 set varid for "X": std::array<int,X> Y;
|
2022-05-22 09:20:32 +02:00
|
|
|
TEST_CASE(varid_templateParameterFunctionPointer); // #11050
|
2016-08-02 15:04:07 +02:00
|
|
|
TEST_CASE(varid_templateUsing); // #5781 #7273
|
2022-08-19 18:26:00 +02:00
|
|
|
TEST_CASE(varid_templateSpecializationFinal);
|
2018-11-11 07:50:25 +01:00
|
|
|
TEST_CASE(varid_not_template_in_condition); // #7988
|
2014-10-11 18:35:06 +02:00
|
|
|
TEST_CASE(varid_cppcast); // #6190
|
2014-09-24 13:23:44 +02:00
|
|
|
TEST_CASE(varid_variadicFunc);
|
|
|
|
TEST_CASE(varid_typename); // #4644
|
|
|
|
TEST_CASE(varid_rvalueref);
|
|
|
|
TEST_CASE(varid_arrayFuncPar); // #5294
|
|
|
|
TEST_CASE(varid_sizeofPassed); // #5295
|
|
|
|
TEST_CASE(varid_classInFunction); // #5293
|
|
|
|
TEST_CASE(varid_pointerToArray); // #2645
|
|
|
|
TEST_CASE(varid_cpp11initialization); // #4344
|
|
|
|
TEST_CASE(varid_inheritedMembers); // #4101
|
2015-01-02 12:32:23 +01:00
|
|
|
TEST_CASE(varid_header); // #6386
|
2015-10-26 19:03:23 +01:00
|
|
|
TEST_CASE(varid_rangeBasedFor);
|
2016-05-22 21:18:52 +02:00
|
|
|
TEST_CASE(varid_structinit); // #6406
|
2016-07-18 15:27:08 +02:00
|
|
|
TEST_CASE(varid_arrayinit); // #7579
|
2018-10-07 20:40:59 +02:00
|
|
|
TEST_CASE(varid_lambda_arg);
|
2019-02-03 08:57:04 +01:00
|
|
|
TEST_CASE(varid_lambda_mutable);
|
2019-04-18 20:22:39 +02:00
|
|
|
TEST_CASE(varid_trailing_return1); // #8889
|
|
|
|
TEST_CASE(varid_trailing_return2); // #9066
|
2022-12-12 22:58:48 +01:00
|
|
|
TEST_CASE(varid_trailing_return3); // #11423
|
2019-10-06 12:45:42 +02:00
|
|
|
TEST_CASE(varid_parameter_pack); // #9383
|
2020-02-27 07:18:07 +01:00
|
|
|
TEST_CASE(varid_for_auto_cpp17);
|
2020-04-25 14:42:31 +02:00
|
|
|
TEST_CASE(varid_not); // #9689 'not x'
|
2021-04-26 07:38:03 +02:00
|
|
|
TEST_CASE(varid_declInIfCondition);
|
2022-06-11 08:11:16 +02:00
|
|
|
TEST_CASE(varid_globalScope);
|
2020-02-27 07:18:07 +01:00
|
|
|
|
2014-09-24 13:23:44 +02:00
|
|
|
TEST_CASE(varidclass1);
|
|
|
|
TEST_CASE(varidclass2);
|
|
|
|
TEST_CASE(varidclass3);
|
|
|
|
TEST_CASE(varidclass4);
|
|
|
|
TEST_CASE(varidclass5);
|
|
|
|
TEST_CASE(varidclass6);
|
|
|
|
TEST_CASE(varidclass7);
|
|
|
|
TEST_CASE(varidclass8);
|
|
|
|
TEST_CASE(varidclass9);
|
|
|
|
TEST_CASE(varidclass10); // variable declaration below usage
|
|
|
|
TEST_CASE(varidclass11); // variable declaration below usage
|
|
|
|
TEST_CASE(varidclass12);
|
|
|
|
TEST_CASE(varidclass13);
|
|
|
|
TEST_CASE(varidclass14);
|
|
|
|
TEST_CASE(varidclass15); // initializer list
|
|
|
|
TEST_CASE(varidclass16); // #4577
|
|
|
|
TEST_CASE(varidclass17); // #6073
|
2015-07-14 18:09:07 +02:00
|
|
|
TEST_CASE(varidclass18);
|
2016-01-23 08:28:04 +01:00
|
|
|
TEST_CASE(varidclass19); // initializer list
|
2020-04-15 20:56:21 +02:00
|
|
|
TEST_CASE(varidclass20); // #7578: int (*p)[2]
|
2014-09-24 13:23:44 +02:00
|
|
|
TEST_CASE(varid_classnameshaddowsvariablename); // #3990
|
2021-03-29 12:16:02 +02:00
|
|
|
TEST_CASE(varid_classnametemplate); // #10221
|
2014-09-24 13:23:44 +02:00
|
|
|
|
Fix #9647: Set correct enum value (#2856)
* Tokenize: Set varId for variables in enum
Set varIds in enum values. It was previously disabled in 5119ae84b879fad
to avoid issues with enums named the same as global variables. Take care
to only set varids to variables used to set the value of an enumerator,
not the enumerator itself. This is somewhat complicated by the fact that
at the time this happens, astOperand1(), astOperand2(), astParent() etc
are not set. The current implementation is not perfect, for example in
the code below, y will not have a varid set, but x and z will. This is
deemed sufficient for now.
int x, y, z;
enum E { a = f(x, y, z); };
* Fix #9647: Value of enums with variables as init values
C++ allows enum values to be set using constexprs, which cppcheck did
not handle before. To solve this, add a new pass to valueflow to update
enum values after global consts have been processed. In order to do so,
I moved all settings of enum values to valueflow. After setting the enum
values, we need another call to valueFlowNumber() to actually set users
of the enums.
There is still room for improvements, since each pass of
valueFlowGlobalConstVar() and valueFlowEnumValue() only sets variables
that are possible to set directly, and not if setting the value of a
variable allows us to set the value of another. For example
constexpr int a = 5;
constexpr int b = a + 5;
enum E { X = a };
constexpr E e = X;
Here both b and e will not have their values set, even though cppcheck
should be possible to figure out their values. That's for another PR
though.
This was tested by running test-my-pr.py with 500 packages. The only
difference was one error message in fairy-stockfish_11.1, where cppcheck
now printed the correct size of an array instead of 2147483648 which I
assume is some kind of default value. In that package, using a constexpr
when setting enum values is common, but as mentioned, there was no
change in the number of warnings.
2020-10-22 07:45:04 +02:00
|
|
|
TEST_CASE(varidenum1);
|
|
|
|
TEST_CASE(varidenum2);
|
|
|
|
TEST_CASE(varidenum3);
|
|
|
|
TEST_CASE(varidenum4);
|
|
|
|
TEST_CASE(varidenum5);
|
2022-04-27 12:43:21 +02:00
|
|
|
TEST_CASE(varidenum6); // #9180
|
2022-04-30 08:20:00 +02:00
|
|
|
TEST_CASE(varidenum7); // #8991
|
Fix #9647: Set correct enum value (#2856)
* Tokenize: Set varId for variables in enum
Set varIds in enum values. It was previously disabled in 5119ae84b879fad
to avoid issues with enums named the same as global variables. Take care
to only set varids to variables used to set the value of an enumerator,
not the enumerator itself. This is somewhat complicated by the fact that
at the time this happens, astOperand1(), astOperand2(), astParent() etc
are not set. The current implementation is not perfect, for example in
the code below, y will not have a varid set, but x and z will. This is
deemed sufficient for now.
int x, y, z;
enum E { a = f(x, y, z); };
* Fix #9647: Value of enums with variables as init values
C++ allows enum values to be set using constexprs, which cppcheck did
not handle before. To solve this, add a new pass to valueflow to update
enum values after global consts have been processed. In order to do so,
I moved all settings of enum values to valueflow. After setting the enum
values, we need another call to valueFlowNumber() to actually set users
of the enums.
There is still room for improvements, since each pass of
valueFlowGlobalConstVar() and valueFlowEnumValue() only sets variables
that are possible to set directly, and not if setting the value of a
variable allows us to set the value of another. For example
constexpr int a = 5;
constexpr int b = a + 5;
enum E { X = a };
constexpr E e = X;
Here both b and e will not have their values set, even though cppcheck
should be possible to figure out their values. That's for another PR
though.
This was tested by running test-my-pr.py with 500 packages. The only
difference was one error message in fairy-stockfish_11.1, where cppcheck
now printed the correct size of an array instead of 2147483648 which I
assume is some kind of default value. In that package, using a constexpr
when setting enum values is common, but as mentioned, there was no
change in the number of warnings.
2020-10-22 07:45:04 +02:00
|
|
|
|
2014-09-24 13:23:44 +02:00
|
|
|
TEST_CASE(varidnamespace1);
|
2017-11-09 15:58:08 +01:00
|
|
|
TEST_CASE(varidnamespace2);
|
2017-11-09 22:08:58 +01:00
|
|
|
TEST_CASE(usingNamespace1);
|
|
|
|
TEST_CASE(usingNamespace2);
|
2017-11-09 23:15:16 +01:00
|
|
|
TEST_CASE(usingNamespace3);
|
2018-11-14 19:11:35 +01:00
|
|
|
|
|
|
|
TEST_CASE(setVarIdStructMembers1);
|
2020-01-29 17:40:22 +01:00
|
|
|
|
|
|
|
TEST_CASE(decltype1);
|
2020-11-16 20:11:26 +01:00
|
|
|
TEST_CASE(decltype2);
|
2020-08-23 17:17:33 +02:00
|
|
|
|
2020-08-20 18:21:29 +02:00
|
|
|
TEST_CASE(exprid1);
|
2021-04-26 18:04:27 +02:00
|
|
|
|
|
|
|
TEST_CASE(structuredBindings);
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2021-11-29 07:34:39 +01:00
|
|
|
#define tokenize(...) tokenize_(__FILE__, __LINE__, __VA_ARGS__)
|
|
|
|
std::string tokenize_(const char* file, int line, const char code[], const char filename[] = "test.cpp") {
|
2014-09-24 13:23:44 +02:00
|
|
|
errout.str("");
|
|
|
|
|
2016-07-19 11:59:37 +02:00
|
|
|
Settings settings;
|
|
|
|
settings.platform(Settings::Unix64);
|
2014-09-24 13:23:44 +02:00
|
|
|
settings.standards.c = Standards::C89;
|
2021-04-26 18:04:27 +02:00
|
|
|
settings.standards.cpp = Standards::CPPLatest;
|
2020-11-22 16:43:36 +01:00
|
|
|
settings.checkUnusedTemplates = true;
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
Tokenizer tokenizer(&settings, this);
|
|
|
|
std::istringstream istr(code);
|
2021-11-29 07:34:39 +01:00
|
|
|
ASSERT_LOC((tokenizer.tokenize)(istr, filename), file, line);
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
// result..
|
2020-08-20 18:21:29 +02:00
|
|
|
Token::stringifyOptions options = Token::stringifyOptions::forDebugVarId();
|
|
|
|
options.files = false;
|
|
|
|
return tokenizer.tokens()->stringifyList(options);
|
|
|
|
}
|
|
|
|
|
2021-11-29 07:34:39 +01:00
|
|
|
#define tokenizeExpr(...) tokenizeExpr_(__FILE__, __LINE__, __VA_ARGS__)
|
|
|
|
std::string tokenizeExpr_(const char* file, int line, const char code[], const char filename[] = "test.cpp") {
|
2020-08-20 18:21:29 +02:00
|
|
|
errout.str("");
|
|
|
|
|
|
|
|
Settings settings;
|
|
|
|
settings.platform(Settings::Unix64);
|
|
|
|
settings.standards.c = Standards::C89;
|
2021-04-26 18:04:27 +02:00
|
|
|
settings.standards.cpp = Standards::CPPLatest;
|
2020-11-22 16:43:36 +01:00
|
|
|
settings.checkUnusedTemplates = true;
|
2020-08-20 18:21:29 +02:00
|
|
|
|
|
|
|
Tokenizer tokenizer(&settings, this);
|
|
|
|
std::istringstream istr(code);
|
2021-11-29 07:34:39 +01:00
|
|
|
ASSERT_LOC((tokenizer.tokenize)(istr, filename), file, line);
|
2020-08-20 18:21:29 +02:00
|
|
|
|
|
|
|
// result..
|
|
|
|
Token::stringifyOptions options = Token::stringifyOptions::forDebugExprId();
|
|
|
|
options.files = false;
|
|
|
|
return tokenizer.tokens()->stringifyList(options);
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2021-11-29 07:34:39 +01:00
|
|
|
#define compareVaridsForVariable(...) compareVaridsForVariable_(__FILE__, __LINE__, __VA_ARGS__)
|
|
|
|
std::string compareVaridsForVariable_(const char* file, int line, const char code[], const char varname[], const char filename[] = "test.cpp") {
|
2019-03-24 07:06:15 +01:00
|
|
|
errout.str("");
|
|
|
|
|
|
|
|
Settings settings;
|
|
|
|
settings.platform(Settings::Unix64);
|
|
|
|
settings.standards.c = Standards::C89;
|
|
|
|
settings.standards.cpp = Standards::CPP11;
|
2020-11-22 16:43:36 +01:00
|
|
|
settings.checkUnusedTemplates = true;
|
2019-03-24 07:06:15 +01:00
|
|
|
|
|
|
|
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-03-24 07:06:15 +01:00
|
|
|
|
|
|
|
unsigned int varid = ~0U;
|
|
|
|
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
|
|
|
|
if (tok->str() == varname) {
|
|
|
|
if (varid == ~0U)
|
|
|
|
varid = tok->varId();
|
|
|
|
else if (varid != tok->varId())
|
|
|
|
return std::string("Variable ") + varname + " has different varids:\n" + tokenizer.tokens()->stringifyList(true,true,true,true,false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "same varid";
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid1() {
|
2014-09-24 13:23:44 +02:00
|
|
|
{
|
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"static int i = 1;\n"
|
|
|
|
"void f()\n"
|
|
|
|
"{\n"
|
|
|
|
" int i = 2;\n"
|
|
|
|
" for (int i = 0; i < 10; ++i)\n"
|
|
|
|
" i = 3;\n"
|
|
|
|
" i = 4;\n"
|
|
|
|
"}\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: static int i@1 = 1 ;\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: void f ( )\n"
|
|
|
|
"3: {\n"
|
|
|
|
"4: int i@2 ; i@2 = 2 ;\n"
|
|
|
|
"5: for ( int i@3 = 0 ; i@3 < 10 ; ++ i@3 ) {\n"
|
|
|
|
"6: i@3 = 3 ; }\n"
|
|
|
|
"7: i@2 = 4 ;\n"
|
|
|
|
"8: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"static int i = 1;\n"
|
|
|
|
"void f()\n"
|
|
|
|
"{\n"
|
|
|
|
" int i = 2;\n"
|
|
|
|
" for (int i = 0; i < 10; ++i)\n"
|
|
|
|
" {\n"
|
|
|
|
" i = 3;\n"
|
|
|
|
" }\n"
|
|
|
|
" i = 4;\n"
|
|
|
|
"}\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: static int i@1 = 1 ;\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: void f ( )\n"
|
|
|
|
"3: {\n"
|
|
|
|
"4: int i@2 ; i@2 = 2 ;\n"
|
|
|
|
"5: for ( int i@3 = 0 ; i@3 < 10 ; ++ i@3 )\n"
|
|
|
|
"6: {\n"
|
|
|
|
"7: i@3 = 3 ;\n"
|
|
|
|
"8: }\n"
|
|
|
|
"9: i@2 = 4 ;\n"
|
|
|
|
"10: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid2() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void f()\n"
|
|
|
|
"{\n"
|
|
|
|
" struct ABC abc;\n"
|
|
|
|
" abc.a = 3;\n"
|
|
|
|
" i = abc.a;\n"
|
|
|
|
"}\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: struct ABC abc@1 ;\n"
|
|
|
|
"4: abc@1 . a@2 = 3 ;\n"
|
|
|
|
"5: i = abc@1 . a@2 ;\n"
|
|
|
|
"6: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid3() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"static char str[4];\n"
|
|
|
|
"void f()\n"
|
|
|
|
"{\n"
|
|
|
|
" char str[10];\n"
|
|
|
|
" str[0] = 0;\n"
|
|
|
|
"}\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: static char str@1 [ 4 ] ;\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: void f ( )\n"
|
|
|
|
"3: {\n"
|
|
|
|
"4: char str@2 [ 10 ] ;\n"
|
|
|
|
"5: str@2 [ 0 ] = 0 ;\n"
|
|
|
|
"6: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid4() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void f(const unsigned int a[])\n"
|
|
|
|
"{\n"
|
|
|
|
" int i = *(a+10);\n"
|
|
|
|
"}\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( const unsigned int a@1 [ ] )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: int i@2 ; i@2 = * ( a@1 + 10 ) ;\n"
|
|
|
|
"4: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid5() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void f()\n"
|
|
|
|
"{\n"
|
|
|
|
" int a,b;\n"
|
|
|
|
"}\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: int a@1 ; int b@2 ;\n"
|
|
|
|
"4: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid6() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"int f(int a, int b)\n"
|
|
|
|
"{\n"
|
|
|
|
" return a+b;\n"
|
|
|
|
"}\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: int f ( int a@1 , int b@2 )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: return a@1 + b@2 ;\n"
|
|
|
|
"4: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid7() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void func() {\n"
|
|
|
|
" char a[256] = \"test\";\n"
|
|
|
|
" {\n"
|
|
|
|
" char b[256] = \"test\";\n"
|
|
|
|
" }\n"
|
|
|
|
"}\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void func ( ) {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: char a@1 [ 256 ] = \"test\" ;\n"
|
|
|
|
"3: {\n"
|
|
|
|
"4: char b@2 [ 256 ] = \"test\" ;\n"
|
|
|
|
"5: }\n"
|
|
|
|
"6: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidReturn1() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"int f()\n"
|
|
|
|
"{\n"
|
|
|
|
" int a;\n"
|
|
|
|
" return a;\n"
|
|
|
|
"}\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: int f ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: int a@1 ;\n"
|
|
|
|
"4: return a@1 ;\n"
|
|
|
|
"5: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidReturn2() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void foo()\n"
|
|
|
|
"{\n"
|
|
|
|
" unsigned long mask = (1UL << size_) - 1;\n"
|
|
|
|
" return (abits_val_ & mask);\n"
|
|
|
|
"}\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void foo ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
2016-07-18 10:42:03 +02:00
|
|
|
"3: unsigned long mask@1 ; mask@1 = ( 1UL << size_ ) - 1 ;\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"4: return ( abits_val_ & mask@1 ) ;\n"
|
|
|
|
"5: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid8() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void func()\n"
|
|
|
|
"{\n"
|
|
|
|
" std::string str(\"test\");\n"
|
|
|
|
" str.clear();\n"
|
|
|
|
"}");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void func ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: std :: string str@1 ( \"test\" ) ;\n"
|
|
|
|
"4: str@1 . clear ( ) ;\n"
|
|
|
|
"5: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid9() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"typedef int INT32;\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid10() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void foo()\n"
|
|
|
|
"{\n"
|
|
|
|
" int abc;\n"
|
|
|
|
" struct abc abc1;\n"
|
|
|
|
"}", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void foo ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: int abc@1 ;\n"
|
|
|
|
"4: struct abc abc1@2 ;\n"
|
|
|
|
"5: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid11() {
|
2021-02-20 12:58:42 +01:00
|
|
|
const std::string actual = tokenize("class Foo;");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Foo ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid12() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"static void a()\n"
|
|
|
|
"{\n"
|
|
|
|
" class Foo *foo;\n"
|
|
|
|
"}");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: static void a ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: class Foo * foo@1 ;\n"
|
|
|
|
"4: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid13() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void f()\n"
|
|
|
|
"{\n"
|
|
|
|
" int a; int b;\n"
|
|
|
|
" a = a;\n"
|
|
|
|
"}\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: int a@1 ; int b@2 ;\n"
|
|
|
|
"4: a@1 = a@1 ;\n"
|
|
|
|
"5: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid14() {
|
2014-09-24 13:23:44 +02:00
|
|
|
// Overloaded operator*
|
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void foo()\n"
|
|
|
|
"{\n"
|
|
|
|
"A a;\n"
|
|
|
|
"B b;\n"
|
|
|
|
"b * a;\n"
|
|
|
|
"}", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void foo ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: A a@1 ;\n"
|
|
|
|
"4: B b@2 ;\n"
|
|
|
|
"5: b@2 * a@1 ;\n"
|
|
|
|
"6: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid15() {
|
2014-09-24 13:23:44 +02:00
|
|
|
{
|
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"struct S {\n"
|
|
|
|
" struct T {\n"
|
|
|
|
" } t;\n"
|
|
|
|
"} s;", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: struct S {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: struct T {\n"
|
|
|
|
"3: } ; struct T t@1 ;\n"
|
|
|
|
"4: } ; struct S s@2 ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"struct S {\n"
|
|
|
|
" struct T {\n"
|
|
|
|
" } t;\n"
|
|
|
|
"};", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: struct S {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: struct T {\n"
|
|
|
|
"3: } ; struct T t@1 ;\n"
|
|
|
|
"4: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid16() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="void foo()\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"{\n"
|
|
|
|
" int x = 1;\n"
|
|
|
|
" y = (z * x);\n"
|
|
|
|
"}\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void foo ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: int x@1 ; x@1 = 1 ;\n"
|
|
|
|
"4: y = z * x@1 ;\n"
|
|
|
|
"5: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid17() { // ticket #1810
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="char foo()\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"{\n"
|
|
|
|
" char c('c');\n"
|
|
|
|
" return c;\n"
|
|
|
|
"}\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: char foo ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: char c@1 ( 'c' ) ;\n"
|
|
|
|
"4: return c@1 ;\n"
|
|
|
|
"5: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid18() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="char foo(char c)\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"{\n"
|
|
|
|
" bar::c = c;\n"
|
|
|
|
"}\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: char foo ( char c@1 )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: bar :: c = c@1 ;\n"
|
|
|
|
"4: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid19() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="void foo()\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"{\n"
|
|
|
|
" std::pair<std::vector<double>, int> x;\n"
|
|
|
|
"}\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void foo ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: std :: pair < std :: vector < double > , int > x@1 ;\n"
|
|
|
|
"4: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid20() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="void foo()\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"{\n"
|
|
|
|
" pair<vector<int>, vector<double> > x;\n"
|
|
|
|
"}\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void foo ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: pair < vector < int > , vector < double > > x@1 ;\n"
|
|
|
|
"4: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid24() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="class foo()\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"{\n"
|
|
|
|
"public:\n"
|
|
|
|
" ;\n"
|
|
|
|
"private:\n"
|
|
|
|
" static int i;\n"
|
|
|
|
"};\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class foo ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: public:\n"
|
|
|
|
"4: ;\n"
|
|
|
|
"5: private:\n"
|
|
|
|
"6: static int i@1 ;\n"
|
|
|
|
"7: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid25() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="class foo()\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"{\n"
|
|
|
|
"public:\n"
|
|
|
|
" ;\n"
|
|
|
|
"private:\n"
|
|
|
|
" mutable int i;\n"
|
|
|
|
"};\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class foo ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: public:\n"
|
|
|
|
"4: ;\n"
|
|
|
|
"5: private:\n"
|
|
|
|
"6: mutable int i@1 ;\n"
|
|
|
|
"7: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid26() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="list<int (*)()> functions;\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: list < int ( * ) ( ) > functions@1 ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid27() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="int fooled_ya;\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"fooled_ya::iterator iter;\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: int fooled_ya@1 ;\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: fooled_ya :: iterator iter@2 ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid28() { // ticket #2630 (segmentation fault)
|
2015-10-18 15:47:37 +02:00
|
|
|
ASSERT_THROW(tokenize("template <typedef A>\n"), InternalError);
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid29() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="class A {\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
" B<C<1>,1> b;\n"
|
|
|
|
"};\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class A {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: B < C < 1 > , 1 > b@1 ;\n"
|
|
|
|
"3: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid30() { // ticket #2614
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code1[] = "void f(EventPtr *eventP, ActionPtr **actionsP)\n"
|
|
|
|
"{\n"
|
|
|
|
" EventPtr event = *eventP;\n"
|
|
|
|
" *actionsP = &event->actions;\n"
|
|
|
|
"}\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected1[] = "1: void f ( EventPtr * eventP@1 , ActionPtr * * actionsP@2 )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: EventPtr event@3 ; event@3 = * eventP@1 ;\n"
|
|
|
|
"4: * actionsP@2 = & event@3 . actions@4 ;\n"
|
|
|
|
"5: }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected1, tokenize(code1, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
const char code2[] = "void f(int b, int c) {\n"
|
|
|
|
" x(a*b*c,10);\n"
|
|
|
|
"}\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected2[] = "1: void f ( int b@1 , int c@2 ) {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: x ( a * b@1 * c@2 , 10 ) ;\n"
|
|
|
|
"3: }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected2, tokenize(code2, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
const char code3[] = "class Nullpointer : public ExecutionPath\n"
|
|
|
|
" {\n"
|
|
|
|
" Nullpointer(Check *c, const unsigned int id, const std::string &name)\n"
|
|
|
|
" : ExecutionPath(c, id)\n"
|
|
|
|
" {\n"
|
|
|
|
" }\n"
|
#11134 Fix broken AST with (designated) initializers (#4550)
* Make control flow a bit easier, and more similar to previous code
Made similar to around line 790
* In a cpp11init, always parse only the corresponding } (#11134)
- _always_, because in some cases this was omitted (around line 790) or too strict (around line 860)
- _only_, and not following tokens which happen to be } as well (around line 1030)
* Fix unit tests: AST was incorrect, now is fixed
auto var{ {{},{}}, {} };
Old AST:
```
{
|-var
`-{
`-,
|-,
| |-{
| `-{
`-{
```
New AST:
```
{
|-var
`-,
|-{
| `-,
| | |-{
| | `-{
`-{
```
Compare the same example, but with `X{}` instead of just `{}`:
`auto var{ a{b{},c{}}, d{} };`
```
{
|-var
`-,
|-{
| |-a
| `-,
| | |-{
| | | `-b
| | `-{
| | | `-c
`-{
`-d
```
This structure is similar to that of the new AST, not the old AST
* Fix unit tests: another AST was incorrect, now is fixed
Code: `auto var{{1,a::b{2,3}}, {4,a::b{5,6}}};`
Old AST:
```
{
|-var
`-{
`-,
|-,
| |-1 'signed int'
| `-{
| | |-::
| | | |-a
| | | `-b
| | `-,
| | | |-2 'signed int'
| | | `-3 'signed int'
`-{
`-,
|-4 'signed int'
`-{
|-::
| |-a
| `-b
`-,
|-5 'signed int'
`-6 'signed int'
```
New AST:
```
{
|-var
`-,
|-{
| `-,
| | |-1 'signed int'
| | `-{
| | | |-::
| | | | |-a
| | | | `-b
| | | `-,
| | | | |-2 'signed int'
| | | | `-3 'signed int'
`-{
`-,
|-4 'signed int'
`-{
|-::
| |-a
| `-b
`-,
|-5 'signed int'
`-6 'signed int'
```
* Fix unit tests: missing ; after class, resulting in incorrectly being marked as cpp11init
Because of the missing `;` after the class declaration, it was marked as a cpp11init block.
Which it isn't, and which now throws an exception
* Fix cpp11init to let unit tests pass again
The following unit tests failed on the newly introduced throws, because the code for these tests incorrectly marked some tokens as cpp11init:
TestVarID::varid_cpp11initialization
TestTokenizer::checkRefQualifiers
* Fix typo
* Improve check for void trailing return type
Observation: the only function body _not_ containing a semicolon, is a void function: something like
auto make_zero(ini& i) -> void {
while(--i > 0) {}
}
Non-void function? Then it must return a value, and thus contain a semicolon, which is checked for a few lines later.
* Fix cpp11init with templated trailing return type
In the following example, vector was marked as cpp11init due to the mismatch of `%any% {`
auto f() -> std::vector<int> { return {}; }
I made the assumption that whenever "%any% {" matches, endtok must be set too.
If this assumtion doesn't hold (so "%any% {" matches, but endtok == nullptr), then the for-loop would search all the way to the end of stream. Which I guess was not the intention.
* Remove comments
Co-authored-by: Gerbo Engels <gerbo.engels@ortec-finance.com>
2022-10-19 07:25:15 +02:00
|
|
|
"};\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected3[] = "1: class Nullpointer : public ExecutionPath\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
2016-07-18 10:42:03 +02:00
|
|
|
"3: Nullpointer ( Check * c@1 , const unsigned int id@2 , const std :: string & name@3 )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"4: : ExecutionPath ( c@1 , id@2 )\n"
|
|
|
|
"5: {\n"
|
|
|
|
"6: }\n"
|
#11134 Fix broken AST with (designated) initializers (#4550)
* Make control flow a bit easier, and more similar to previous code
Made similar to around line 790
* In a cpp11init, always parse only the corresponding } (#11134)
- _always_, because in some cases this was omitted (around line 790) or too strict (around line 860)
- _only_, and not following tokens which happen to be } as well (around line 1030)
* Fix unit tests: AST was incorrect, now is fixed
auto var{ {{},{}}, {} };
Old AST:
```
{
|-var
`-{
`-,
|-,
| |-{
| `-{
`-{
```
New AST:
```
{
|-var
`-,
|-{
| `-,
| | |-{
| | `-{
`-{
```
Compare the same example, but with `X{}` instead of just `{}`:
`auto var{ a{b{},c{}}, d{} };`
```
{
|-var
`-,
|-{
| |-a
| `-,
| | |-{
| | | `-b
| | `-{
| | | `-c
`-{
`-d
```
This structure is similar to that of the new AST, not the old AST
* Fix unit tests: another AST was incorrect, now is fixed
Code: `auto var{{1,a::b{2,3}}, {4,a::b{5,6}}};`
Old AST:
```
{
|-var
`-{
`-,
|-,
| |-1 'signed int'
| `-{
| | |-::
| | | |-a
| | | `-b
| | `-,
| | | |-2 'signed int'
| | | `-3 'signed int'
`-{
`-,
|-4 'signed int'
`-{
|-::
| |-a
| `-b
`-,
|-5 'signed int'
`-6 'signed int'
```
New AST:
```
{
|-var
`-,
|-{
| `-,
| | |-1 'signed int'
| | `-{
| | | |-::
| | | | |-a
| | | | `-b
| | | `-,
| | | | |-2 'signed int'
| | | | `-3 'signed int'
`-{
`-,
|-4 'signed int'
`-{
|-::
| |-a
| `-b
`-,
|-5 'signed int'
`-6 'signed int'
```
* Fix unit tests: missing ; after class, resulting in incorrectly being marked as cpp11init
Because of the missing `;` after the class declaration, it was marked as a cpp11init block.
Which it isn't, and which now throws an exception
* Fix cpp11init to let unit tests pass again
The following unit tests failed on the newly introduced throws, because the code for these tests incorrectly marked some tokens as cpp11init:
TestVarID::varid_cpp11initialization
TestTokenizer::checkRefQualifiers
* Fix typo
* Improve check for void trailing return type
Observation: the only function body _not_ containing a semicolon, is a void function: something like
auto make_zero(ini& i) -> void {
while(--i > 0) {}
}
Non-void function? Then it must return a value, and thus contain a semicolon, which is checked for a few lines later.
* Fix cpp11init with templated trailing return type
In the following example, vector was marked as cpp11init due to the mismatch of `%any% {`
auto f() -> std::vector<int> { return {}; }
I made the assumption that whenever "%any% {" matches, endtok must be set too.
If this assumtion doesn't hold (so "%any% {" matches, but endtok == nullptr), then the for-loop would search all the way to the end of stream. Which I guess was not the intention.
* Remove comments
Co-authored-by: Gerbo Engels <gerbo.engels@ortec-finance.com>
2022-10-19 07:25:15 +02:00
|
|
|
"7: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
ASSERT_EQUALS(expected3, tokenize(code3));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid34() { // ticket #2825
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="class Fred : public B1, public B2\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"{\n"
|
|
|
|
"public:\n"
|
|
|
|
" Fred() { a = 0; }\n"
|
|
|
|
"private:\n"
|
|
|
|
" int a;\n"
|
|
|
|
"};\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Fred : public B1 , public B2\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: public:\n"
|
|
|
|
"4: Fred ( ) { a@1 = 0 ; }\n"
|
|
|
|
"5: private:\n"
|
|
|
|
"6: int a@1 ;\n"
|
|
|
|
"7: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
ASSERT_EQUALS("", errout.str());
|
|
|
|
}
|
|
|
|
|
2015-11-19 16:27:16 +01:00
|
|
|
void varid35() { // function declaration inside function body
|
|
|
|
// #2937
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="int foo() {\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
" int f(x);\n"
|
|
|
|
" return f;\n"
|
|
|
|
"}\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: int foo ( ) {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: int f@1 ( x ) ;\n"
|
|
|
|
"3: return f@1 ;\n"
|
|
|
|
"4: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
2015-11-19 16:27:16 +01:00
|
|
|
|
|
|
|
// #4627
|
|
|
|
const char code2[] = "void f() {\n"
|
|
|
|
" int *p;\n"
|
|
|
|
" void bar(int *p);\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected2[] = "1: void f ( ) {\n"
|
2015-11-19 16:27:16 +01:00
|
|
|
"2: int * p@1 ;\n"
|
|
|
|
"3: void bar ( int * p ) ;\n"
|
|
|
|
"4: }\n";
|
|
|
|
ASSERT_EQUALS(expected2, tokenize(code2));
|
2016-10-03 10:02:18 +02:00
|
|
|
|
|
|
|
// #7740
|
|
|
|
const char code3[] = "Float f(float scale) {\n"
|
|
|
|
" return Float(val * scale);\n"
|
|
|
|
"}\n";
|
|
|
|
const char expected3[] = "1: Float f ( float scale@1 ) {\n"
|
|
|
|
"2: return Float ( val * scale@1 ) ;\n"
|
|
|
|
"3: }\n";
|
|
|
|
ASSERT_EQUALS(expected3, tokenize(code3));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid36() { // ticket #2980 (segmentation fault)
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="#elif A\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"A,a<b<x0\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
tokenize(code);
|
|
|
|
ASSERT_EQUALS("", errout.str());
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid37() {
|
2014-09-24 13:23:44 +02:00
|
|
|
{
|
|
|
|
const char code[] = "void blah() {"
|
|
|
|
" Bar bar(*x);"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void blah ( ) { Bar bar@1 ( * x ) ; }\n",
|
2014-09-24 13:23:44 +02:00
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
{
|
|
|
|
const char code[] = "void blah() {"
|
|
|
|
" Bar bar(&x);"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void blah ( ) { Bar bar@1 ( & x ) ; }\n",
|
2014-09-24 13:23:44 +02:00
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid38() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "FOO class C;\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: FOO class C ;\n",
|
2014-09-24 13:23:44 +02:00
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid39() {
|
2014-09-24 13:23:44 +02:00
|
|
|
// const..
|
|
|
|
{
|
|
|
|
const char code[] = "void f(FOO::BAR const);\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void f ( const FOO :: BAR ) ;\n",
|
2014-09-24 13:23:44 +02:00
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
{
|
|
|
|
const char code[] = "static int const SZ = 22;\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: static const int SZ@1 = 22 ;\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid40() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="extern \"C\" int (*a())();";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: int * a ( ) ;\n",
|
2014-09-24 13:23:44 +02:00
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid41() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code1[] = "union evt; void f(const evt & event);";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: union evt ; void f ( const evt & event@1 ) ;\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code1, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
const char code2[] = "struct evt; void f(const evt & event);";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: struct evt ; void f ( const evt & event@1 ) ;\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code2, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid42() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="namespace fruit { struct banana {}; };\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"class Fred {\n"
|
|
|
|
"public:\n"
|
|
|
|
" struct fruit::banana Bananas[25];\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: namespace fruit { struct banana { } ; } ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: class Fred {\n"
|
|
|
|
"3: public:\n"
|
|
|
|
"4: struct fruit :: banana Bananas@1 [ 25 ] ;\n"
|
|
|
|
"5: } ;\n",
|
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid43() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="int main(int flag) { if(a & flag) { return 1; } }";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: int main ( int flag@1 ) { if ( a & flag@1 ) { return 1 ; } }\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid44() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="class A:public B,public C,public D {};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A : public B , public C , public D { } ;\n",
|
2014-09-24 13:23:44 +02:00
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid45() { // #3466
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="void foo() { B b(this); A a(this, b); }";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void foo ( ) { B b@1 ( this ) ; A a@2 ( this , b@1 ) ; }\n",
|
2014-09-24 13:23:44 +02:00
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid46() { // #3756
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="void foo() { int t; x = (struct t *)malloc(); f(t); }";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void foo ( ) { int t@1 ; x = ( struct t * ) malloc ( ) ; f ( t@1 ) ; }\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid47() { // function parameters
|
2014-09-24 13:23:44 +02:00
|
|
|
// #3768
|
|
|
|
{
|
|
|
|
const char code[] ="void f(std::string &string, std::string &len) {}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void f ( std :: string & string@1 , std :: string & len@2 ) { }\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code, "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// #4729
|
|
|
|
{
|
|
|
|
const char code[] = "int x;\n"
|
|
|
|
"void a(int x);\n"
|
|
|
|
"void b() { x = 0; }\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: int x@1 ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: void a ( int x@2 ) ;\n"
|
|
|
|
"3: void b ( ) { x@1 = 0 ; }\n",
|
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid48() { // #3785 - return (a*b)
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="int X::f(int b) const { return(a*b); }";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: int X :: f ( int b@1 ) const { return ( a * b@1 ) ; }\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid49() { // #3799 - void f(std::vector<int>)
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="void f(std::vector<int>)";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void f ( std :: vector < int > )\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code, "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid50() { // #3760 - explicit
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="class A { explicit A(const A&); };";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A { explicit A ( const A & ) ; } ;\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code, "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid51() { // don't set varid on template function
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="T t; t.x<0>();";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: T t@1 ; t@1 . x < 0 > ( ) ;\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code, "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid52() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="A<B<C>::D> e;\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"B< C<> > b[10];\n"
|
|
|
|
"B<C<>> c[10];";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: A < B < C > :: D > e@1 ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: B < C < > > b@2 [ 10 ] ;\n"
|
|
|
|
"3: B < C < > > c@3 [ 10 ] ;\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code, "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid53() { // #4172 - Template instantiation: T<&functionName> list[4];
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: A < & f > list@1 [ 4 ] ;\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize("A<&f> list[4];", "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid54() { // hang
|
2014-09-24 13:23:44 +02:00
|
|
|
// Original source code: libgc
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize("STATIC ptr_t GC_approx_sp(void) { word sp; sp = (word)&sp; return((ptr_t)sp); }");
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid55() { // Ticket #5868
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "typedef struct foo {} foo; "
|
2021-08-07 20:51:18 +02:00
|
|
|
"void bar1(struct foo foo) {} "
|
|
|
|
"void baz1(foo foo) {} "
|
|
|
|
"void bar2(struct foo& foo) {} "
|
|
|
|
"void baz2(foo& foo) {} "
|
|
|
|
"void bar3(struct foo* foo) {} "
|
|
|
|
"void baz3(foo* foo) {}";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: "
|
|
|
|
"struct foo { } ; "
|
2014-09-24 13:23:44 +02:00
|
|
|
"void bar1 ( struct foo foo@1 ) { } "
|
|
|
|
"void baz1 ( struct foo foo@2 ) { } "
|
|
|
|
"void bar2 ( struct foo & foo@3 ) { } "
|
|
|
|
"void baz2 ( struct foo & foo@4 ) { } "
|
|
|
|
"void bar3 ( struct foo * foo@5 ) { } "
|
|
|
|
"void baz3 ( struct foo * foo@6 ) { }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code, "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2015-02-26 16:31:42 +01:00
|
|
|
void varid56() { // Ticket #6548 - function with a throw()
|
2015-02-27 18:29:34 +01:00
|
|
|
const char code1[] = "void fred(int x) throw() {}"
|
|
|
|
"void wilma() { x++; }";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected1[] = "1: "
|
2015-02-27 18:29:34 +01:00
|
|
|
"void fred ( int x@1 ) throw ( ) { } "
|
|
|
|
"void wilma ( ) { x ++ ; }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected1, tokenize(code1, "test.cpp"));
|
2015-02-27 18:29:34 +01:00
|
|
|
|
|
|
|
const char code2[] = "void fred(int x) const throw(EXCEPT) {}"
|
|
|
|
"void wilma() { x++; }";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected2[] = "1: "
|
2015-02-27 18:29:34 +01:00
|
|
|
"void fred ( int x@1 ) const throw ( EXCEPT ) { } "
|
|
|
|
"void wilma ( ) { x ++ ; }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected2, tokenize(code2, "test.cpp"));
|
2015-02-28 11:09:39 +01:00
|
|
|
|
|
|
|
const char code3[] = "void fred(int x) throw() ABCD {}"
|
|
|
|
"void wilma() { x++; }";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected3[] = "1: "
|
2015-02-28 11:09:39 +01:00
|
|
|
"void fred ( int x@1 ) throw ( ) { } "
|
|
|
|
"void wilma ( ) { x ++ ; }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected3, tokenize(code3, "test.cpp"));
|
2015-11-06 18:00:59 +01:00
|
|
|
|
|
|
|
const char code4[] = "void fred(int x) noexcept() {}"
|
|
|
|
"void wilma() { x++; }";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected4[] = "1: "
|
2015-11-06 18:00:59 +01:00
|
|
|
"void fred ( int x@1 ) noexcept ( ) { } "
|
|
|
|
"void wilma ( ) { x ++ ; }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected4, tokenize(code4, "test.cpp"));
|
2015-11-06 18:00:59 +01:00
|
|
|
|
|
|
|
const char code5[] = "void fred(int x) noexcept {}"
|
|
|
|
"void wilma() { x++; }";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected5[] = "1: "
|
2017-08-16 11:31:19 +02:00
|
|
|
"void fred ( int x@1 ) noexcept ( true ) { } "
|
2015-11-06 18:00:59 +01:00
|
|
|
"void wilma ( ) { x ++ ; }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected5, tokenize(code5, "test.cpp"));
|
2017-08-16 11:31:19 +02:00
|
|
|
|
|
|
|
const char code6[] = "void fred(int x) noexcept ( false ) {}"
|
|
|
|
"void wilma() { x++; }";
|
|
|
|
const char expected6[] = "1: "
|
|
|
|
"void fred ( int x@1 ) noexcept ( false ) { } "
|
|
|
|
"void wilma ( ) { x ++ ; }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected6, tokenize(code6, "test.cpp"));
|
2015-02-26 16:31:42 +01:00
|
|
|
}
|
|
|
|
|
2015-04-08 20:30:41 +02:00
|
|
|
void varid57() { // #6636: new scope by {}
|
|
|
|
const char code1[] = "void SmoothPath() {\n"
|
|
|
|
" {\n" // new scope
|
|
|
|
" float dfx = (p2p0.x > 0.0f)?\n"
|
|
|
|
" ((n0->xmax() * SQUARE_SIZE) - p0.x):\n"
|
|
|
|
" ((n0->xmin() * SQUARE_SIZE) - p0.x);\n"
|
|
|
|
" float tx = dfx / dx;\n"
|
|
|
|
" if (hEdge) {\n"
|
|
|
|
" }\n"
|
|
|
|
" if (vEdge) {\n"
|
|
|
|
" pi.z = tx;\n"
|
|
|
|
" }\n"
|
|
|
|
" }\n"
|
|
|
|
"}\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected1[] = "1: void SmoothPath ( ) {\n"
|
2015-04-08 20:30:41 +02:00
|
|
|
"2:\n"
|
|
|
|
"3: float dfx@1 ; dfx@1 = ( p2p0 . x > 0.0f ) ?\n"
|
|
|
|
"4: ( ( n0 . xmax ( ) * SQUARE_SIZE ) - p0 . x ) :\n"
|
|
|
|
"5: ( ( n0 . xmin ( ) * SQUARE_SIZE ) - p0 . x ) ;\n"
|
|
|
|
"6: float tx@2 ; tx@2 = dfx@1 / dx ;\n"
|
|
|
|
"7: if ( hEdge ) {\n"
|
|
|
|
"8: }\n"
|
|
|
|
"9: if ( vEdge ) {\n"
|
|
|
|
"10: pi . z = tx@2 ;\n"
|
|
|
|
"11: }\n"
|
|
|
|
"12:\n"
|
|
|
|
"13: }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected1, tokenize(code1, "test.cpp"));
|
2015-04-08 20:30:41 +02:00
|
|
|
}
|
|
|
|
|
2015-04-09 19:58:12 +02:00
|
|
|
void varid58() { // #6638: for loop in for condition
|
|
|
|
const char code1[] = "void f() {\n"
|
|
|
|
" for (int i;\n"
|
|
|
|
" ({for(int i;i;++i){i++;}i++;}),i;\n"
|
|
|
|
" ({for(int i;i;++i){i++;}i++;}),i++) {\n"
|
|
|
|
" i++;\n"
|
|
|
|
" }\n"
|
|
|
|
"}\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected1[] = "1: void f ( ) {\n"
|
2015-04-09 19:58:12 +02:00
|
|
|
"2: for ( int i@1 ;\n"
|
2017-03-08 11:41:18 +01:00
|
|
|
"3: ( { for ( int i@2 ; i@2 ; ++ i@2 ) { i@2 ++ ; } i@1 ++ ; } ) , i@1 ;\n"
|
|
|
|
"4: ( { for ( int i@3 ; i@3 ; ++ i@3 ) { i@3 ++ ; } i@1 ++ ; } ) , i@1 ++ ) {\n"
|
2015-04-09 19:58:12 +02:00
|
|
|
"5: i@1 ++ ;\n"
|
|
|
|
"6: }\n"
|
|
|
|
"7: }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected1, tokenize(code1, "test.cpp"));
|
2015-04-09 19:58:12 +02:00
|
|
|
}
|
|
|
|
|
2015-11-10 17:03:27 +01:00
|
|
|
void varid59() { // #6696
|
|
|
|
const char code[] = "class DLLSYM B;\n"
|
|
|
|
"struct B {\n"
|
|
|
|
" ~B() {}\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class DLLSYM B@1 ;\n" // In this line, we cannot really do better...
|
2015-11-10 17:03:27 +01:00
|
|
|
"2: struct B {\n"
|
|
|
|
"3: ~ B@1 ( ) { }\n" // ...but here we could
|
|
|
|
"4: } ;\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char wanted[] = "1: class DLLSYM B@1 ;\n"
|
2015-11-10 17:03:27 +01:00
|
|
|
"2: struct B {\n"
|
|
|
|
"3: ~ B ( ) { }\n"
|
2020-04-21 17:27:51 +02:00
|
|
|
"4: } ;\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
TODO_ASSERT_EQUALS(wanted, expected, tokenize(code, "test.cpp"));
|
2015-11-10 17:03:27 +01:00
|
|
|
}
|
|
|
|
|
2016-01-06 17:47:59 +01:00
|
|
|
void varid60() { // #7267 - cast
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: a = ( x y ) 10 ;\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize("a=(x y)10;"));
|
2016-01-06 17:47:59 +01:00
|
|
|
}
|
|
|
|
|
2017-11-05 22:25:46 +01:00
|
|
|
void varid61() {
|
|
|
|
const char code[] = "void foo(int b) {\n"
|
|
|
|
" void bar(int a, int b) {}\n"
|
|
|
|
"}";
|
|
|
|
const char expected[] = "1: void foo ( int b@1 ) {\n"
|
|
|
|
"2: void bar ( int a@2 , int b@3 ) { }\n"
|
|
|
|
"3: }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
2017-11-05 22:25:46 +01:00
|
|
|
}
|
|
|
|
|
2019-03-24 07:06:15 +01:00
|
|
|
void varid62() {
|
|
|
|
const char code[] = "void bar(int,int);\n"
|
|
|
|
"void f() {\n"
|
|
|
|
" for (size_t c = 0; c < 42; ++c) {\n"
|
|
|
|
" int x;\n"
|
|
|
|
" bar(r, r * x);\n"
|
|
|
|
" }\n"
|
|
|
|
"}";
|
|
|
|
// Ensure that there is only one variable id for "x"
|
|
|
|
ASSERT_EQUALS("same varid", compareVaridsForVariable(code, "x"));
|
|
|
|
}
|
|
|
|
|
2019-05-12 09:10:37 +02:00
|
|
|
void varid63() {
|
|
|
|
const char code[] = "void f(boost::optional<int> const& x) {}";
|
2022-04-08 08:22:39 +02:00
|
|
|
const char expected[] = "1: void f ( const boost :: optional < int > & x@1 ) { }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
2019-05-12 09:10:37 +02:00
|
|
|
}
|
|
|
|
|
2020-09-29 10:53:20 +02:00
|
|
|
void varid64() {
|
|
|
|
const char code[] = "extern const char (*x[256]);";
|
|
|
|
const char expected[] = "1: extern const char ( * x@1 [ 256 ] ) ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2022-03-31 21:08:04 +02:00
|
|
|
void varid65() { // #10936
|
|
|
|
{
|
|
|
|
const char code[] = "extern int (*p);";
|
|
|
|
const char expected[] = "1: extern int ( * p@1 ) ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
{
|
|
|
|
const char code[] = "extern int (i);";
|
|
|
|
const char expected[] = "1: extern int ( i@1 ) ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
{
|
|
|
|
const char code[] = "int (*p);";
|
|
|
|
const char expected[] = "1: int ( * p@1 ) ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
{
|
|
|
|
const char code[] = "int (i);";
|
|
|
|
const char expected[] = "1: int ( i@1 ) ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-18 12:08:53 +02:00
|
|
|
void varid_for_1() {
|
|
|
|
const char code[] = "void foo(int a, int b) {\n"
|
|
|
|
" for (int a=1,b=2;;) {}\n"
|
|
|
|
"}";
|
|
|
|
const char expected[] = "1: void foo ( int a@1 , int b@2 ) {\n"
|
|
|
|
"2: for ( int a@3 = 1 , b@4 = 2 ; ; ) { }\n"
|
|
|
|
"3: }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
2020-04-18 12:08:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void varid_for_2() {
|
|
|
|
const char code[] = "void foo(int a, int b) {\n"
|
|
|
|
" for (int a=f(x,y,z),b=2;;) {}\n"
|
|
|
|
"}";
|
|
|
|
const char expected[] = "1: void foo ( int a@1 , int b@2 ) {\n"
|
|
|
|
"2: for ( int a@3 = f ( x , y , z ) , b@4 = 2 ; ; ) { }\n"
|
|
|
|
"3: }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
2020-04-18 12:08:53 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_cpp_keywords_in_c_code() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "void f() {\n"
|
|
|
|
" delete d;\n"
|
|
|
|
" throw t;\n"
|
|
|
|
"}";
|
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( ) {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: delete d@1 ;\n"
|
|
|
|
"3: throw t@2 ;\n"
|
|
|
|
"4: }\n";
|
|
|
|
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_cpp_keywords_in_c_code2() { // #5373
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, "
|
|
|
|
"unsigned long bits, int wake, int delete, struct extent_state **cached_state, "
|
|
|
|
"gfp_t mask) {\n"
|
|
|
|
" struct extent_state *state;\n"
|
|
|
|
"}"
|
|
|
|
"int clear_extent_dirty() {\n"
|
|
|
|
" return clear_extent_bit(tree, start, end, EXTENT_DIRTY | EXTENT_DELALLOC | "
|
|
|
|
" EXTENT_DO_ACCOUNTING, 0, 0, NULL, mask);\n"
|
|
|
|
"}";
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code, "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidFunctionCall1() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="void f() {\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
" int x;\n"
|
|
|
|
" x = a(y*x,10);\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( ) {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: int x@1 ;\n"
|
|
|
|
"3: x@1 = a ( y * x@1 , 10 ) ;\n"
|
|
|
|
"4: }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidFunctionCall2() {
|
2014-09-24 13:23:44 +02:00
|
|
|
// #2491
|
|
|
|
const char code[] ="void f(int b) {\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
" x(a*b,10);\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
const std::string expected1("1: void f ( int b@1 ) {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: x ( a * b");
|
|
|
|
const std::string expected2(" , 10 ) ;\n"
|
|
|
|
"3: }\n");
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected1+"@1"+expected2, tokenize(code, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidFunctionCall3() {
|
2014-09-24 13:23:44 +02:00
|
|
|
// Ticket #2339
|
|
|
|
const char code[] ="void f() {\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
" int a = 0;\n"
|
|
|
|
" int b = c - (foo::bar * a);\n"
|
|
|
|
"}";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( ) {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: int a@1 ; a@1 = 0 ;\n"
|
|
|
|
"3: int b@2 ; b@2 = c - ( foo :: bar * a@1 ) ;\n"
|
|
|
|
"4: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidFunctionCall4() {
|
2014-09-24 13:23:44 +02:00
|
|
|
// Ticket #3280
|
|
|
|
const char code1[] = "void f() { int x; fun(a,b*x); }";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void f ( ) { int x@1 ; fun ( a , b * x@1 ) ; }\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code1, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code2[] = "void f(int a) { int x; fun(a,b*x); }";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void f ( int a@1 ) { int x@2 ; fun ( a@1 , b * x@2 ) ; }\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code2, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2016-12-18 20:16:38 +01:00
|
|
|
void varidFunctionCall5() {
|
|
|
|
const char code[] = "void foo() { (f(x[2]))(x[2]); }";
|
|
|
|
ASSERT_EQUALS("1: void foo ( ) { f ( x [ 2 ] ) ( x [ 2 ] ) ; }\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code, "test.c"));
|
2016-12-18 20:16:38 +01:00
|
|
|
}
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidStl() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"list<int> ints;\n"
|
|
|
|
"list<int>::iterator it;\n"
|
|
|
|
"std::vector<std::string> dirs;\n"
|
|
|
|
"std::map<int, int> coords;\n"
|
|
|
|
"std::tr1::unordered_map<int, int> xy;\n"
|
|
|
|
"std::list<boost::wave::token_id> tokens;\n"
|
|
|
|
"static std::vector<CvsProcess*> ex1;\n"
|
|
|
|
"extern std::vector<CvsProcess*> ex2;\n"
|
|
|
|
"std::map<int, 1> m;");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: list < int > ints@1 ;\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: list < int > :: iterator it@2 ;\n"
|
|
|
|
"3: std :: vector < std :: string > dirs@3 ;\n"
|
|
|
|
"4: std :: map < int , int > coords@4 ;\n"
|
2021-04-26 18:04:27 +02:00
|
|
|
"5: std :: tr1 :: unordered_map < int , int > xy@5 ;\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"6: std :: list < boost :: wave :: token_id > tokens@6 ;\n"
|
|
|
|
"7: static std :: vector < CvsProcess * > ex1@7 ;\n"
|
|
|
|
"8: extern std :: vector < CvsProcess * > ex2@8 ;\n"
|
|
|
|
"9: std :: map < int , 1 > m@9 ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2017-11-05 17:59:34 +01:00
|
|
|
void varidStl2() {
|
|
|
|
const std::string actual = tokenize("std::bitset<static_cast<int>(2)> x;");
|
|
|
|
|
|
|
|
const char expected[] = "1: std :: bitset < static_cast < int > ( 2 ) > x@1 ;\n";
|
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_newauto() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void f ( ) { const new auto ( 0 ) ; }\n",
|
2014-10-10 16:46:31 +02:00
|
|
|
tokenize("void f(){new const auto(0);}"));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_delete() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void f()\n"
|
|
|
|
"{\n"
|
|
|
|
" int *a;\n"
|
|
|
|
" delete a;\n"
|
|
|
|
"}");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: int * a@1 ;\n"
|
|
|
|
"4: delete a@1 ;\n"
|
|
|
|
"5: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_functions() {
|
2014-09-24 13:23:44 +02:00
|
|
|
{
|
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void f();\n"
|
|
|
|
"void f(){}\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( ) ;\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: void f ( ) { }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"A f(3);\n"
|
|
|
|
"A f2(true);\n"
|
|
|
|
"A g();\n"
|
|
|
|
"A e(int c);\n", "test.c");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: A f@1 ( 3 ) ;\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: A f2@2 ( true ) ;\n"
|
|
|
|
"3: A g ( ) ;\n"
|
|
|
|
"4: A e ( int c@3 ) ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void f1(int &p)\n"
|
|
|
|
"{\n"
|
|
|
|
" p = 0;\n"
|
|
|
|
"}\n"
|
|
|
|
"void f2(std::string &str)\n"
|
|
|
|
"{\n"
|
|
|
|
" str.clear();\n"
|
|
|
|
"}\n"
|
|
|
|
"void f3(const std::string &s)\n"
|
|
|
|
"{\n"
|
|
|
|
" s.size();\n"
|
|
|
|
"}");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f1 ( int & p@1 )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: p@1 = 0 ;\n"
|
|
|
|
"4: }\n"
|
|
|
|
"5: void f2 ( std :: string & str@2 )\n"
|
|
|
|
"6: {\n"
|
|
|
|
"7: str@2 . clear ( ) ;\n"
|
|
|
|
"8: }\n"
|
|
|
|
"9: void f3 ( const std :: string & s@3 )\n"
|
|
|
|
"10: {\n"
|
|
|
|
"11: s@3 . size ( ) ;\n"
|
|
|
|
"12: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2020-05-20 18:52:46 +02:00
|
|
|
const std::string actual = tokenize("void f(struct foobar);", "test.c");
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( struct foobar ) ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
2014-10-14 20:37:32 +02:00
|
|
|
|
|
|
|
{
|
2020-05-20 18:52:46 +02:00
|
|
|
const std::string actual = tokenize("bool f(X x, int=3);", "test.cpp");
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: bool f ( X x@1 , int = 3 ) ;\n";
|
2014-10-14 20:37:32 +02:00
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_sizeof() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "x = sizeof(a*b);";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: x = sizeof ( a * b ) ;\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_reference_to_containers() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"void f()\n"
|
|
|
|
"{\n"
|
|
|
|
" std::vector<int> b;\n"
|
|
|
|
" std::vector<int> &a = b;\n"
|
|
|
|
" std::vector<int> *c = &b;\n"
|
|
|
|
"}");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: std :: vector < int > b@1 ;\n"
|
|
|
|
"4: std :: vector < int > & a@2 = b@1 ;\n"
|
|
|
|
"5: std :: vector < int > * c@3 ; c@3 = & b@1 ;\n"
|
|
|
|
"6: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class1() {
|
2014-09-24 13:23:44 +02:00
|
|
|
{
|
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"class Foo\n"
|
|
|
|
"{\n"
|
|
|
|
"public:\n"
|
|
|
|
" std::string name1;\n"
|
|
|
|
" std::string name2;\n"
|
|
|
|
"};");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Foo\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: public:\n"
|
|
|
|
"4: std :: string name1@1 ;\n"
|
|
|
|
"5: std :: string name2@2 ;\n"
|
|
|
|
"6: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"class foo\n"
|
|
|
|
"{\n"
|
|
|
|
"public:\n"
|
|
|
|
" void do_something(const int x, const int y);\n"
|
|
|
|
" void bar();\n"
|
|
|
|
"};\n"
|
|
|
|
"\n"
|
|
|
|
"void foo::bar()\n"
|
|
|
|
"{\n"
|
|
|
|
" POINT pOutput = { 0 , 0 };\n"
|
|
|
|
" int x = pOutput.x;\n"
|
|
|
|
" int y = pOutput.y;\n"
|
|
|
|
"}");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class foo\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: public:\n"
|
|
|
|
"4: void do_something ( const int x@1 , const int y@2 ) ;\n"
|
|
|
|
"5: void bar ( ) ;\n"
|
|
|
|
"6: } ;\n"
|
|
|
|
"7:\n"
|
|
|
|
"8: void foo :: bar ( )\n"
|
|
|
|
"9: {\n"
|
|
|
|
"10: POINT pOutput@3 ; pOutput@3 = { 0 , 0 } ;\n"
|
|
|
|
"11: int x@4 ; x@4 = pOutput@3 . x@5 ;\n"
|
|
|
|
"12: int y@6 ; y@6 = pOutput@3 . y@7 ;\n"
|
|
|
|
"13: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class2() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"struct Foo {\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};\n"
|
|
|
|
"\n"
|
|
|
|
"struct Bar {\n"
|
|
|
|
" Foo foo;\n"
|
|
|
|
" int x;\n"
|
|
|
|
" void f();\n"
|
|
|
|
"};\n"
|
|
|
|
"\n"
|
|
|
|
"void Bar::f()\n"
|
|
|
|
"{\n"
|
|
|
|
" foo.x = x;\n"
|
|
|
|
"}");
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: struct Foo {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: int x@1 ;\n"
|
|
|
|
"3: } ;\n"
|
|
|
|
"4:\n"
|
|
|
|
"5: struct Bar {\n"
|
|
|
|
"6: Foo foo@2 ;\n"
|
|
|
|
"7: int x@3 ;\n"
|
|
|
|
"8: void f ( ) ;\n"
|
|
|
|
"9: } ;\n"
|
|
|
|
"10:\n"
|
|
|
|
"11: void Bar :: f ( )\n"
|
|
|
|
"12: {\n"
|
2017-03-25 15:59:35 +01:00
|
|
|
"13: foo@2 . x@4 = x@3 ;\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"14: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class3() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "class Foo {\n"
|
|
|
|
" void blah() {\n"
|
|
|
|
" Bar x(*this);\n" // <- ..
|
|
|
|
" }\n"
|
|
|
|
" int x;\n" // <- .. don't assign same varid
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Foo {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: void blah ( ) {\n"
|
|
|
|
"3: Bar x@1 ( * this ) ;\n"
|
|
|
|
"4: }\n"
|
|
|
|
"5: int x@2 ;\n"
|
|
|
|
"6: } ;\n", tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class4() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "class Foo {\n"
|
|
|
|
"public: class C;\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Foo {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: public: class C ;\n"
|
|
|
|
"3: } ;\n",
|
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class5() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "struct Foo {\n"
|
|
|
|
" std::vector<::X> v;\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: struct Foo {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: std :: vector < :: X > v@1 ;\n"
|
|
|
|
"3: }\n",
|
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class6() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "class A {\n"
|
|
|
|
" void f(const char *str) const {\n"
|
|
|
|
" std::stringstream sst;\n"
|
|
|
|
" sst.str();\n"
|
|
|
|
" }\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: void f ( const char * str@1 ) const {\n"
|
|
|
|
"3: std :: stringstream sst@2 ;\n"
|
|
|
|
"4: sst@2 . str ( ) ;\n"
|
|
|
|
"5: }\n"
|
|
|
|
"6: } ;\n",
|
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class7() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "class A {\n"
|
|
|
|
" void f() {\n"
|
|
|
|
" abc.a = 0;\n"
|
|
|
|
" }\n"
|
|
|
|
" struct ABC abc;\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: void f ( ) {\n"
|
|
|
|
"3: abc@1 . a@2 = 0 ;\n"
|
|
|
|
"4: }\n"
|
|
|
|
"5: struct ABC abc@1 ;\n"
|
|
|
|
"6: } ;\n",
|
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
|
2020-05-17 19:12:16 +02:00
|
|
|
void varid_in_class8() { // #3776 - unknown macro
|
|
|
|
const char code[] = "class A {\n"
|
|
|
|
" UNKNOWN_MACRO(A)\n"
|
|
|
|
"private:\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};";
|
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
|
|
|
"2: UNKNOWN_MACRO ( A )\n"
|
|
|
|
"3: private:\n"
|
|
|
|
"4: int x@1 ;\n"
|
|
|
|
"5: } ;\n",
|
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class9() { // #4291 - id for variables accessed through 'this'
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code1[] = "class A {\n"
|
|
|
|
" int var;\n"
|
|
|
|
"public:\n"
|
|
|
|
" void setVar();\n"
|
|
|
|
"};\n"
|
|
|
|
"void A::setVar() {\n"
|
|
|
|
" this->var = var;\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: int var@1 ;\n"
|
|
|
|
"3: public:\n"
|
|
|
|
"4: void setVar ( ) ;\n"
|
|
|
|
"5: } ;\n"
|
|
|
|
"6: void A :: setVar ( ) {\n"
|
|
|
|
"7: this . var@1 = var@1 ;\n"
|
|
|
|
"8: }\n",
|
|
|
|
tokenize(code1));
|
|
|
|
|
|
|
|
const char code2[] = "class Foo : public FooBase {\n"
|
|
|
|
" void Clone(FooBase& g);\n"
|
|
|
|
" short m_bar;\n"
|
|
|
|
"};\n"
|
|
|
|
"void Foo::Clone(FooBase& g) {\n"
|
|
|
|
" g->m_bar = m_bar;\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Foo : public FooBase {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: void Clone ( FooBase & g@1 ) ;\n"
|
|
|
|
"3: short m_bar@2 ;\n"
|
|
|
|
"4: } ;\n"
|
|
|
|
"5: void Foo :: Clone ( FooBase & g@3 ) {\n"
|
|
|
|
"6: g@3 . m_bar@4 = m_bar@2 ;\n"
|
|
|
|
"7: }\n",
|
|
|
|
tokenize(code2)); // #4311
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class10() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "class Foo : public FooBase {\n"
|
|
|
|
" void Clone(FooBase& g);\n"
|
|
|
|
" short m_bar;\n"
|
|
|
|
"};\n"
|
|
|
|
"void Foo::Clone(FooBase& g) {\n"
|
|
|
|
" ((FooBase)g)->m_bar = m_bar;\n"
|
|
|
|
"}";
|
2018-11-14 19:11:35 +01:00
|
|
|
ASSERT_EQUALS("1: class Foo : public FooBase {\n"
|
|
|
|
"2: void Clone ( FooBase & g@1 ) ;\n"
|
|
|
|
"3: short m_bar@2 ;\n"
|
|
|
|
"4: } ;\n"
|
|
|
|
"5: void Foo :: Clone ( FooBase & g@3 ) {\n"
|
|
|
|
"6: ( ( FooBase ) g@3 ) . m_bar@4 = m_bar@2 ;\n"
|
|
|
|
"7: }\n",
|
|
|
|
tokenize(code));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class11() { // #4277 - anonymous union
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code1[] = "class Foo {\n"
|
|
|
|
" union { float a; int b; };\n"
|
|
|
|
" void f() { a=0; }\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Foo {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: union { float a@1 ; int b@2 ; } ;\n"
|
|
|
|
"3: void f ( ) { a@1 = 0 ; }\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code1));
|
|
|
|
|
|
|
|
const char code2[] = "class Foo {\n"
|
|
|
|
" void f() { a=0; }\n"
|
|
|
|
" union { float a; int b; };\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Foo {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: void f ( ) { a@1 = 0 ; }\n"
|
|
|
|
"3: union { float a@1 ; int b@2 ; } ;\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code2));
|
2015-08-30 15:41:32 +02:00
|
|
|
|
|
|
|
const char code3[] = "void f() {\n"
|
|
|
|
" union {\n"
|
|
|
|
" struct {\n"
|
|
|
|
" char a, b, c, d;\n"
|
|
|
|
" };\n"
|
|
|
|
" int abcd;\n"
|
|
|
|
" };\n"
|
|
|
|
" g(abcd);\n"
|
|
|
|
" h(a, b, c, d);\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void f ( ) {\n"
|
2015-08-30 15:41:32 +02:00
|
|
|
"2: union {\n"
|
|
|
|
"3: struct {\n"
|
|
|
|
"4: char a@1 ; char b@2 ; char c@3 ; char d@4 ;\n"
|
|
|
|
"5: } ;\n"
|
|
|
|
"6: int abcd@5 ;\n"
|
|
|
|
"7: } ;\n"
|
|
|
|
"8: g ( abcd@5 ) ;\n"
|
|
|
|
"9: h ( a@1 , b@2 , c@3 , d@4 ) ;\n"
|
|
|
|
"10: }\n",
|
|
|
|
tokenize(code3));
|
2016-05-11 20:43:23 +02:00
|
|
|
|
|
|
|
// #7444
|
|
|
|
const char code4[] = "class Foo {\n"
|
|
|
|
" void f(float a) { this->a = a; }\n"
|
|
|
|
" union { float a; int b; };\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Foo {\n"
|
2016-05-11 20:43:23 +02:00
|
|
|
"2: void f ( float a@1 ) { this . a@2 = a@1 ; }\n"
|
|
|
|
"3: union { float a@2 ; int b@3 ; } ;\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code4));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class12() { // #4637 - method
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "class Foo {\n"
|
|
|
|
"private:\n"
|
|
|
|
" void f(void);\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Foo {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: private:\n"
|
2022-03-31 21:24:20 +02:00
|
|
|
"3: void f ( ) ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class13() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code1[] = "struct a { char typename; };";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: struct a { char typename@1 ; } ;\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code1, "test.c"));
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: struct a { char typename ; } ;\n", // not valid C++ code
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code1, "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
const char code2[] = "struct a { char typename[2]; };";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: struct a { char typename@1 [ 2 ] ; } ;\n",
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code2, "test.c"));
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: struct a { char typename [ 2 ] ; } ;\n", // not valid C++ code
|
2020-05-20 18:52:46 +02:00
|
|
|
tokenize(code2, "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class14() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "class Tokenizer { TokenList list; };\n"
|
|
|
|
"\n"
|
|
|
|
"void Tokenizer::f() {\n"
|
|
|
|
" std::list<int> x;\n" // <- not member variable
|
|
|
|
" list.do_something();\n" // <- member variable
|
|
|
|
" Tokenizer::list.do_something();\n" // <- redundant scope info
|
|
|
|
"}\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Tokenizer { TokenList list@1 ; } ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2:\n"
|
|
|
|
"3: void Tokenizer :: f ( ) {\n"
|
|
|
|
"4: std :: list < int > x@2 ;\n"
|
|
|
|
"5: list@1 . do_something ( ) ;\n"
|
|
|
|
"6: Tokenizer :: list@1 . do_something ( ) ;\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"7: }\n", tokenize(code, "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class15() { // #5533 - functions
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "class Fred {\n"
|
|
|
|
" void x(int a) const;\n"
|
|
|
|
" void y() { a=0; }\n" // <- unknown variable
|
|
|
|
"}\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Fred {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: void x ( int a@1 ) const ;\n"
|
|
|
|
"3: void y ( ) { a = 0 ; }\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"4: }\n", tokenize(code, "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class16() { // Set varId for inline member functions
|
2015-11-09 21:43:40 +01:00
|
|
|
{
|
|
|
|
const char code[] = "class Fred {\n"
|
|
|
|
" int x;\n"
|
|
|
|
" void foo(int x) { this->x = x; }\n"
|
|
|
|
"};\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Fred {\n"
|
2015-11-09 21:43:40 +01:00
|
|
|
"2: int x@1 ;\n"
|
|
|
|
"3: void foo ( int x@2 ) { this . x@1 = x@2 ; }\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"4: } ;\n", tokenize(code, "test.cpp"));
|
2015-11-09 21:43:40 +01:00
|
|
|
}
|
|
|
|
{
|
|
|
|
const char code[] = "class Fred {\n"
|
|
|
|
" void foo(int x) { this->x = x; }\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Fred {\n"
|
2015-11-09 21:43:40 +01:00
|
|
|
"2: void foo ( int x@1 ) { this . x@2 = x@1 ; }\n"
|
|
|
|
"3: int x@2 ;\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"4: } ;\n", tokenize(code, "test.cpp"));
|
2015-11-09 21:43:40 +01:00
|
|
|
}
|
|
|
|
{
|
|
|
|
const char code[] = "class Fred {\n"
|
|
|
|
" void foo(int x) { (*this).x = x; }\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Fred {\n"
|
2015-11-09 21:43:40 +01:00
|
|
|
"2: void foo ( int x@1 ) { ( * this ) . x@2 = x@1 ; }\n"
|
|
|
|
"3: int x@2 ;\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"4: } ;\n", tokenize(code, "test.cpp"));
|
2015-11-09 21:43:40 +01:00
|
|
|
}
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_in_class17() { // #6056 - Set no varid for member functions
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code1[] = "class Fred {\n"
|
|
|
|
" int method_with_internal(X&);\n"
|
|
|
|
" int method_with_internal(X*);\n"
|
|
|
|
" int method_with_internal(int&);\n"
|
|
|
|
" int method_with_internal(A* b, X&);\n"
|
|
|
|
" int method_with_internal(X&, A* b);\n"
|
|
|
|
" int method_with_internal(const B &, int);\n"
|
|
|
|
" void Set(BAR);\n"
|
|
|
|
" FOO Set(BAR);\n"
|
|
|
|
" int method_with_class(B<B> b);\n"
|
|
|
|
" bool function(std::map<int, int, MYless> & m);\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Fred {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: int method_with_internal ( X & ) ;\n"
|
|
|
|
"3: int method_with_internal ( X * ) ;\n"
|
|
|
|
"4: int method_with_internal ( int & ) ;\n"
|
|
|
|
"5: int method_with_internal ( A * b@1 , X & ) ;\n"
|
|
|
|
"6: int method_with_internal ( X & , A * b@2 ) ;\n"
|
|
|
|
"7: int method_with_internal ( const B & , int ) ;\n"
|
|
|
|
"8: void Set ( BAR ) ;\n"
|
|
|
|
"9: FOO Set ( BAR ) ;\n"
|
|
|
|
"10: int method_with_class ( B < B > b@3 ) ;\n"
|
|
|
|
"11: bool function ( std :: map < int , int , MYless > & m@4 ) ;\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"12: } ;\n", tokenize(code1, "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
const char code2[] = "int i;\n"
|
|
|
|
"SomeType someVar1(i, i);\n"
|
|
|
|
"SomeType someVar2(j, j);\n"
|
|
|
|
"SomeType someVar3(j, 1);\n"
|
|
|
|
"SomeType someVar4(new bar);";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: int i@1 ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: SomeType someVar1@2 ( i@1 , i@1 ) ;\n"
|
|
|
|
"3: SomeType someVar2 ( j , j ) ;\n" // This one could be a function
|
|
|
|
"4: SomeType someVar3@3 ( j , 1 ) ;\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"5: SomeType someVar4@4 ( new bar ) ;\n", tokenize(code2, "test.cpp"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2015-11-13 10:07:57 +01:00
|
|
|
void varid_in_class18() {
|
|
|
|
const char code[] = "class A {\n"
|
|
|
|
" class B;\n"
|
|
|
|
"};\n"
|
|
|
|
"class A::B {\n"
|
|
|
|
" B();\n"
|
|
|
|
" int* i;\n"
|
|
|
|
"};\n"
|
|
|
|
"A::B::B() :\n"
|
|
|
|
" i(0)\n"
|
|
|
|
"{}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2015-11-13 10:07:57 +01:00
|
|
|
"2: class B ;\n"
|
|
|
|
"3: } ;\n"
|
|
|
|
"4: class A :: B {\n"
|
|
|
|
"5: B ( ) ;\n"
|
|
|
|
"6: int * i@1 ;\n"
|
|
|
|
"7: } ;\n"
|
|
|
|
"8: A :: B :: B ( ) :\n"
|
|
|
|
"9: i@1 ( 0 )\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"10: { }\n", tokenize(code, "test.cpp"));
|
2015-11-13 10:07:57 +01:00
|
|
|
}
|
|
|
|
|
2015-11-18 21:13:58 +01:00
|
|
|
void varid_in_class19() {
|
|
|
|
const char code[] = "class Fred {\n"
|
|
|
|
" char *str1;\n"
|
|
|
|
" ~Fred();\n"
|
|
|
|
"};\n"
|
|
|
|
"Fred::~Fred() {\n"
|
|
|
|
" free(str1);\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Fred {\n"
|
2015-11-18 21:13:58 +01:00
|
|
|
"2: char * str1@1 ;\n"
|
|
|
|
"3: ~ Fred ( ) ;\n"
|
|
|
|
"4: } ;\n"
|
|
|
|
"5: Fred :: ~ Fred ( ) {\n"
|
|
|
|
"6: free ( str1@1 ) ;\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"7: }\n", tokenize(code, "test.cpp"));
|
2015-11-18 21:13:58 +01:00
|
|
|
}
|
|
|
|
|
2016-01-10 22:10:49 +01:00
|
|
|
void varid_in_class20() {
|
|
|
|
const char code[] = "template<class C> class cacheEntry {\n"
|
|
|
|
"protected:\n"
|
|
|
|
" int m_key;\n"
|
|
|
|
"public:\n"
|
|
|
|
" cacheEntry();\n"
|
|
|
|
"};\n"
|
|
|
|
"\n"
|
|
|
|
"template<class C> cacheEntry<C>::cacheEntry() : m_key() {}";
|
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: template < class C > class cacheEntry {\n"
|
2016-01-10 22:10:49 +01:00
|
|
|
"2: protected:\n"
|
|
|
|
"3: int m_key@1 ;\n"
|
|
|
|
"4: public:\n"
|
|
|
|
"5: cacheEntry ( ) ;\n"
|
|
|
|
"6: } ;\n"
|
|
|
|
"7:\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"8: template < class C > cacheEntry < C > :: cacheEntry ( ) : m_key@1 ( ) { }\n", tokenize(code, "test.cpp"));
|
2016-01-10 22:10:49 +01:00
|
|
|
}
|
|
|
|
|
2017-11-10 21:03:15 +01:00
|
|
|
void varid_in_class21() {
|
|
|
|
const char code[] = "template <typename t1,typename t2>\n"
|
|
|
|
"class A::B {\n"
|
|
|
|
" B();\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};\n"
|
|
|
|
"\n"
|
|
|
|
"template <typename t1,typename t2>\n"
|
|
|
|
"A::B<t1,t2>::B() : x(9) {}";
|
|
|
|
|
|
|
|
const char expected[] = "1: template < typename t1 , typename t2 >\n"
|
|
|
|
"2: class A :: B {\n"
|
|
|
|
"3: B ( ) ;\n"
|
|
|
|
"4: int x@1 ;\n"
|
|
|
|
"5: } ;\n"
|
|
|
|
"6:\n"
|
|
|
|
"7: template < typename t1 , typename t2 >\n"
|
|
|
|
"8: A :: B < t1 , t2 > :: B ( ) : x@1 ( 9 ) { }\n";
|
|
|
|
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code, "test.cpp"));
|
2017-11-10 21:03:15 +01:00
|
|
|
}
|
|
|
|
|
2022-03-16 15:29:34 +01:00
|
|
|
void varid_in_class22() {
|
|
|
|
const char code[] = "struct data {};\n"
|
|
|
|
" struct S {\n"
|
|
|
|
" std::vector<data> std;\n"
|
|
|
|
" void f();\n"
|
|
|
|
"};\n"
|
|
|
|
"void S::f() {\n"
|
|
|
|
" std::vector<data>::const_iterator end = std.end();\n"
|
|
|
|
" for (std::vector<data>::const_iterator i = std.begin(); i != end; ++i) {}\n"
|
|
|
|
"}\n";
|
|
|
|
|
|
|
|
const char expected[] = "1: struct data { } ;\n"
|
|
|
|
"2: struct S {\n"
|
|
|
|
"3: std :: vector < data > std@1 ;\n"
|
|
|
|
"4: void f ( ) ;\n"
|
|
|
|
"5: } ;\n"
|
|
|
|
"6: void S :: f ( ) {\n"
|
|
|
|
"7: std :: vector < data > :: const_iterator end@2 ; end@2 = std@1 . end ( ) ;\n"
|
|
|
|
"8: for ( std :: vector < data > :: const_iterator i@3 = std@1 . begin ( ) ; i@3 != end@2 ; ++ i@3 ) { }\n"
|
|
|
|
"9: }\n";
|
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code, "test.cpp"));
|
|
|
|
}
|
|
|
|
|
2022-09-21 17:35:10 +02:00
|
|
|
void varid_in_class23() { // #11293
|
|
|
|
const char code[] = "struct A {\n"
|
|
|
|
" struct S {\n"
|
|
|
|
" bool b;\n"
|
|
|
|
" };\n"
|
|
|
|
"};\n"
|
|
|
|
"struct B : A::S {\n"
|
|
|
|
" void f() { b = false; }\n"
|
|
|
|
"};\n";
|
|
|
|
|
|
|
|
const char expected[] = "1: struct A {\n"
|
|
|
|
"2: struct S {\n"
|
|
|
|
"3: bool b@1 ;\n"
|
|
|
|
"4: } ;\n"
|
|
|
|
"5: } ;\n"
|
|
|
|
"6: struct B : A :: S {\n"
|
|
|
|
"7: void f ( ) { b@1 = false ; }\n"
|
|
|
|
"8: } ;\n";
|
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code, "test.cpp"));
|
|
|
|
}
|
|
|
|
|
2023-01-09 16:11:26 +01:00
|
|
|
void varid_in_class24() {
|
|
|
|
const char code[] = "class A {\n"
|
|
|
|
" Q_OBJECT\n"
|
|
|
|
"public:\n"
|
|
|
|
" using QPtr = QPointer<A>;\n"
|
|
|
|
"};\n";
|
|
|
|
|
|
|
|
const char expected[] = "1: class A {\n"
|
|
|
|
"2: Q_OBJECT\n"
|
|
|
|
"3: public:\n"
|
|
|
|
"4:\n"
|
|
|
|
"5: } ;\n";
|
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code, "test.cpp"));
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:52:27 +01:00
|
|
|
void varid_namespace_1() { // #7272
|
2016-01-19 14:32:27 +01:00
|
|
|
const char code[] = "namespace Blah {\n"
|
|
|
|
" struct foo { int x;};\n"
|
|
|
|
" struct bar {\n"
|
|
|
|
" int x;\n"
|
|
|
|
" union { char y; };\n"
|
|
|
|
" };\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: namespace Blah {\n"
|
2016-01-19 14:32:27 +01:00
|
|
|
"2: struct foo { int x@1 ; } ;\n"
|
|
|
|
"3: struct bar {\n"
|
|
|
|
"4: int x@2 ;\n"
|
|
|
|
"5: union { char y@3 ; } ;\n"
|
|
|
|
"6: } ;\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"7: }\n", tokenize(code, "test.cpp"));
|
2016-01-19 14:32:27 +01:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:52:27 +01:00
|
|
|
void varid_namespace_2() { // #7000
|
|
|
|
const char code[] = "namespace Ui {\n"
|
|
|
|
" class C { int X; };\n" // X@1
|
|
|
|
"}\n"
|
|
|
|
"\n"
|
|
|
|
"class C {\n"
|
|
|
|
" void dostuff();\n"
|
|
|
|
" int X;\n" // X@2
|
|
|
|
"};\n"
|
|
|
|
"\n"
|
|
|
|
"void C::dostuff() {\n"
|
|
|
|
" X = 0;\n" // X@2
|
|
|
|
"}";
|
|
|
|
|
2020-05-20 18:52:46 +02:00
|
|
|
const std::string actual = tokenize(code, "test.cpp");
|
2017-11-08 22:52:27 +01:00
|
|
|
|
|
|
|
ASSERT(actual.find("X@2 = 0") != std::string::npos);
|
|
|
|
}
|
|
|
|
|
2022-03-02 07:46:47 +01:00
|
|
|
static std::string getLine(const std::string &code, int lineNumber) {
|
2018-12-02 09:28:05 +01:00
|
|
|
std::string nr = MathLib::toString(lineNumber);
|
|
|
|
const std::string::size_type pos1 = code.find('\n' + nr + ": ");
|
|
|
|
if (pos1 == std::string::npos)
|
|
|
|
return "";
|
|
|
|
const std::string::size_type pos2 = code.find('\n', pos1+1);
|
|
|
|
if (pos2 == std::string::npos)
|
|
|
|
return "";
|
|
|
|
return code.substr(pos1+1, pos2-pos1-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void varid_namespace_3() { // #8627
|
|
|
|
const char code[] = "namespace foo {\n"
|
|
|
|
"struct Bar {\n"
|
|
|
|
" explicit Bar(int type);\n"
|
|
|
|
" void f();\n"
|
|
|
|
" int type;\n" // <- Same varid here ...
|
|
|
|
"};\n"
|
|
|
|
"\n"
|
|
|
|
"Bar::Bar(int type) : type(type) {}\n"
|
|
|
|
"\n"
|
|
|
|
"void Bar::f() {\n"
|
|
|
|
" type = 0;\n" // <- ... and here
|
|
|
|
"}\n"
|
|
|
|
"}";
|
|
|
|
|
2020-05-20 18:52:46 +02:00
|
|
|
const std::string actual = tokenize(code, "test.cpp");
|
2018-12-02 09:28:05 +01:00
|
|
|
|
|
|
|
ASSERT_EQUALS("5: int type@2 ;", getLine(actual,5));
|
|
|
|
ASSERT_EQUALS("11: type@2 = 0 ;", getLine(actual,11));
|
|
|
|
}
|
|
|
|
|
2020-12-08 17:25:50 +01:00
|
|
|
void varid_namespace_4() {
|
|
|
|
const char code[] = "namespace X {\n"
|
|
|
|
" struct foo { int x;};\n"
|
|
|
|
" struct bar: public foo {\n"
|
|
|
|
" void dostuff();\n"
|
|
|
|
" };\n"
|
|
|
|
" void bar::dostuff() { int x2 = x * 2; }\n"
|
|
|
|
"}";
|
|
|
|
ASSERT_EQUALS("1: namespace X {\n"
|
|
|
|
"2: struct foo { int x@1 ; } ;\n"
|
|
|
|
"3: struct bar : public foo {\n"
|
|
|
|
"4: void dostuff ( ) ;\n"
|
|
|
|
"5: } ;\n"
|
|
|
|
"6: void bar :: dostuff ( ) { int x2@2 ; x2@2 = x@1 * 2 ; }\n"
|
|
|
|
"7: }\n", tokenize(code, "test.cpp"));
|
|
|
|
}
|
|
|
|
|
|
|
|
void varid_namespace_5() {
|
|
|
|
const char code[] = "namespace X {\n"
|
|
|
|
" struct foo { int x;};\n"
|
|
|
|
" namespace Y {\n"
|
|
|
|
" struct bar: public foo {\n"
|
|
|
|
" void dostuff();\n"
|
|
|
|
" };\n"
|
|
|
|
" void bar::dostuff() { int x2 = x * 2; }\n"
|
|
|
|
" }\n"
|
|
|
|
"}";
|
|
|
|
ASSERT_EQUALS("1: namespace X {\n"
|
|
|
|
"2: struct foo { int x@1 ; } ;\n"
|
|
|
|
"3: namespace Y {\n"
|
|
|
|
"4: struct bar : public foo {\n"
|
|
|
|
"5: void dostuff ( ) ;\n"
|
|
|
|
"6: } ;\n"
|
|
|
|
"7: void bar :: dostuff ( ) { int x2@2 ; x2@2 = x@1 * 2 ; }\n"
|
|
|
|
"8: }\n"
|
|
|
|
"9: }\n", tokenize(code, "test.cpp"));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_initList() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code1[] = "class A {\n"
|
|
|
|
" A() : x(0) {}\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: A ( ) : x@1 ( 0 ) { }\n"
|
|
|
|
"3: int x@1 ;\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code1));
|
|
|
|
|
|
|
|
const char code2[] = "class A {\n"
|
|
|
|
" A(int x) : x(x) {}\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: A ( int x@1 ) : x@2 ( x@1 ) { }\n"
|
|
|
|
"3: int x@2 ;\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code2));
|
|
|
|
|
|
|
|
const char code3[] = "class A {\n"
|
|
|
|
" A(int x);\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};\n"
|
|
|
|
"A::A(int x) : x(x) {}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: A ( int x@1 ) ;\n"
|
|
|
|
"3: int x@2 ;\n"
|
|
|
|
"4: } ;\n"
|
|
|
|
"5: A :: A ( int x@3 ) : x@2 ( x@3 ) { }\n",
|
|
|
|
tokenize(code3));
|
|
|
|
|
|
|
|
const char code4[] = "struct A {\n"
|
|
|
|
" int x;\n"
|
|
|
|
" A(int x) : x(x) {}\n"
|
|
|
|
"};\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: struct A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: int x@1 ;\n"
|
|
|
|
"3: A ( int x@2 ) : x@1 ( x@2 ) { }\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code4));
|
2015-01-02 20:03:06 +01:00
|
|
|
|
|
|
|
const char code5[] = "class A {\n"
|
|
|
|
" A(int x) noexcept : x(x) {}\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2017-08-16 11:31:19 +02:00
|
|
|
"2: A ( int x@1 ) noexcept ( true ) : x@2 ( x@1 ) { }\n"
|
2015-01-02 20:03:06 +01:00
|
|
|
"3: int x@2 ;\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code5));
|
|
|
|
|
|
|
|
const char code6[] = "class A {\n"
|
|
|
|
" A(int x) noexcept(true) : x(x) {}\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2015-01-02 20:03:06 +01:00
|
|
|
"2: A ( int x@1 ) noexcept ( true ) : x@2 ( x@1 ) { }\n"
|
|
|
|
"3: int x@2 ;\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code6));
|
2015-02-22 11:57:46 +01:00
|
|
|
|
2017-08-16 11:31:19 +02:00
|
|
|
const char code7[] = "class A {\n"
|
|
|
|
" A(int x) noexcept(false) : x(x) {}\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};";
|
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
|
|
|
"2: A ( int x@1 ) noexcept ( false ) : x@2 ( x@1 ) { }\n"
|
|
|
|
"3: int x@2 ;\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code7));
|
|
|
|
|
|
|
|
const char code8[] = "class Foo : public Bar {\n"
|
2015-11-09 23:00:14 +01:00
|
|
|
" explicit Foo(int i) : Bar(mi = i) { }\n"
|
|
|
|
" int mi;\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Foo : public Bar {\n"
|
2015-11-09 23:00:14 +01:00
|
|
|
"2: explicit Foo ( int i@1 ) : Bar ( mi@2 = i@1 ) { }\n"
|
|
|
|
"3: int mi@2 ;\n"
|
|
|
|
"4: } ;\n",
|
2017-08-16 11:31:19 +02:00
|
|
|
tokenize(code8));
|
2015-11-09 23:00:14 +01:00
|
|
|
|
2015-02-22 11:57:46 +01:00
|
|
|
// #6520
|
2017-08-16 11:31:19 +02:00
|
|
|
const char code9[] = "class A {\n"
|
2015-02-22 11:57:46 +01:00
|
|
|
" A(int x) : y(a?0:1), x(x) {}\n"
|
|
|
|
" int x, y;\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2015-02-22 11:57:46 +01:00
|
|
|
"2: A ( int x@1 ) : y@3 ( a ? 0 : 1 ) , x@2 ( x@1 ) { }\n"
|
|
|
|
"3: int x@2 ; int y@3 ;\n"
|
|
|
|
"4: } ;\n",
|
2017-08-16 11:31:19 +02:00
|
|
|
tokenize(code9));
|
2015-11-11 11:01:32 +01:00
|
|
|
|
|
|
|
// #7123
|
2017-08-16 11:31:19 +02:00
|
|
|
const char code10[] = "class A {\n"
|
2017-08-16 18:56:02 +02:00
|
|
|
" double *work;\n"
|
|
|
|
" A(const Matrix &m) throw (e);\n"
|
|
|
|
"};\n"
|
|
|
|
"A::A(const Matrix &m) throw (e) : work(0)\n"
|
|
|
|
"{}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2015-11-11 11:01:32 +01:00
|
|
|
"2: double * work@1 ;\n"
|
|
|
|
"3: A ( const Matrix & m@2 ) throw ( e ) ;\n"
|
|
|
|
"4: } ;\n"
|
|
|
|
"5: A :: A ( const Matrix & m@3 ) throw ( e ) : work@1 ( 0 )\n"
|
|
|
|
"6: { }\n",
|
2017-08-16 11:31:19 +02:00
|
|
|
tokenize(code10));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2015-04-06 19:47:21 +02:00
|
|
|
void varid_initListWithBaseTemplate() {
|
|
|
|
const char code1[] = "class A : B<C,D> {\n"
|
|
|
|
" A() : B<C,D>(), x(0) {}\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A : B < C , D > {\n"
|
2015-04-06 19:47:21 +02:00
|
|
|
"2: A ( ) : B < C , D > ( ) , x@1 ( 0 ) { }\n"
|
|
|
|
"3: int x@1 ;\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code1));
|
|
|
|
|
|
|
|
const char code2[] = "class A : B<C,D> {\n"
|
|
|
|
" A(int x) : x(x) {}\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A : B < C , D > {\n"
|
2015-04-06 19:47:21 +02:00
|
|
|
"2: A ( int x@1 ) : x@2 ( x@1 ) { }\n"
|
|
|
|
"3: int x@2 ;\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code2));
|
|
|
|
|
|
|
|
const char code3[] = "class A : B<C,D> {\n"
|
|
|
|
" A(int x);\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};\n"
|
|
|
|
"A::A(int x) : x(x) {}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A : B < C , D > {\n"
|
2015-04-06 19:47:21 +02:00
|
|
|
"2: A ( int x@1 ) ;\n"
|
|
|
|
"3: int x@2 ;\n"
|
|
|
|
"4: } ;\n"
|
|
|
|
"5: A :: A ( int x@3 ) : x@2 ( x@3 ) { }\n",
|
|
|
|
tokenize(code3));
|
|
|
|
|
|
|
|
const char code4[] = "struct A : B<C,D> {\n"
|
|
|
|
" int x;\n"
|
|
|
|
" A(int x) : x(x) {}\n"
|
|
|
|
"};\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: struct A : B < C , D > {\n"
|
2015-04-06 19:47:21 +02:00
|
|
|
"2: int x@1 ;\n"
|
|
|
|
"3: A ( int x@2 ) : x@1 ( x@2 ) { }\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code4));
|
2015-11-10 16:14:53 +01:00
|
|
|
|
|
|
|
const char code5[] = "class BCLass : public Ticket<void> {\n"
|
|
|
|
" BCLass();\n"
|
|
|
|
" PClass* member;\n"
|
|
|
|
"};\n"
|
|
|
|
"BCLass::BCLass() : Ticket<void>() {\n"
|
|
|
|
" member = 0;\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class BCLass : public Ticket < void > {\n"
|
2015-11-10 16:14:53 +01:00
|
|
|
"2: BCLass ( ) ;\n"
|
|
|
|
"3: PClass * member@1 ;\n"
|
|
|
|
"4: } ;\n"
|
|
|
|
"5: BCLass :: BCLass ( ) : Ticket < void > ( ) {\n"
|
|
|
|
"6: member@1 = 0 ;\n"
|
|
|
|
"7: }\n",
|
|
|
|
tokenize(code5));
|
2015-04-06 19:47:21 +02:00
|
|
|
}
|
|
|
|
|
2016-01-09 12:18:36 +01:00
|
|
|
void varid_initListWithScope() {
|
|
|
|
const char code1[] = "class A : public B::C {\n"
|
|
|
|
" A() : B::C(), x(0) {}\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A : public B :: C {\n"
|
2016-01-09 12:18:36 +01:00
|
|
|
"2: A ( ) : B :: C ( ) , x@1 ( 0 ) { }\n"
|
|
|
|
"3: int x@1 ;\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize(code1));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_operator() {
|
2014-09-24 13:23:44 +02:00
|
|
|
{
|
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"class Foo\n"
|
|
|
|
"{\n"
|
|
|
|
"public:\n"
|
|
|
|
" void operator=(const Foo &);\n"
|
|
|
|
"};");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Foo\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: public:\n"
|
|
|
|
"4: void operator= ( const Foo & ) ;\n"
|
|
|
|
"5: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"struct Foo {\n"
|
|
|
|
" void * operator new [](int);\n"
|
|
|
|
"};");
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: struct Foo {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: void * operatornew[] ( int ) ;\n"
|
|
|
|
"3: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_throw() { // ticket #1723
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"UserDefinedException* pe = new UserDefinedException();\n"
|
|
|
|
"throw pe;");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: UserDefinedException * pe@1 ; pe@1 = new UserDefinedException ( ) ;\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: throw pe@1 ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_unknown_macro() {
|
2014-09-24 13:23:44 +02:00
|
|
|
// #2638 - unknown macro
|
|
|
|
const char code[] = "void f() {\n"
|
|
|
|
" int a[10];\n"
|
|
|
|
" AAA\n"
|
|
|
|
" a[0] = 0;\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( ) {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: int a@1 [ 10 ] ;\n"
|
|
|
|
"3: AAA\n"
|
|
|
|
"4: a@1 [ 0 ] = 0 ;\n"
|
|
|
|
"5: }\n";
|
2020-05-20 18:52:46 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code, "test.c"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_using() {
|
2014-09-24 13:23:44 +02:00
|
|
|
// #3648
|
|
|
|
const char code[] = "using std::size_t;";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: using unsigned long ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_catch() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "void f() {\n"
|
|
|
|
" try { dostuff(); }\n"
|
|
|
|
" catch (exception &e) { }\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: void f ( ) {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: try { dostuff ( ) ; }\n"
|
|
|
|
"3: catch ( exception & e@1 ) { }\n"
|
|
|
|
"4: }\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_functionPrototypeTemplate() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: function < void ( ) > fptr@1 ;\n", tokenize("function<void(void)> fptr;"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_templatePtr() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: std :: map < int , FooTemplate < int > * > dummy_member@1 [ 1 ] ;\n", tokenize("std::map<int, FooTemplate<int>*> dummy_member[1];"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_templateNamespaceFuncPtr() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: KeyListT < float , & NIFFile :: getFloat > mKeyList@1 [ 4 ] ;\n", tokenize("KeyListT<float, &NIFFile::getFloat> mKeyList[4];"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_templateArray() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: VertexArrayIterator < float [ 2 ] > attrPos@1 ; attrPos@1 = m_AttributePos . GetIterator < float [ 2 ] > ( ) ;\n",
|
2014-09-24 13:23:44 +02:00
|
|
|
tokenize("VertexArrayIterator<float[2]> attrPos = m_AttributePos.GetIterator<float[2]>();"));
|
|
|
|
}
|
|
|
|
|
2022-04-25 22:23:06 +02:00
|
|
|
void varid_templateParameter() {
|
|
|
|
{
|
|
|
|
const char code[] = "const int X = 0;\n" // #7046 set varid for "X": std::array<int,X> Y;
|
|
|
|
"std::array<int,X> Y;\n";
|
2016-01-31 11:07:30 +01:00
|
|
|
|
2022-04-25 22:23:06 +02:00
|
|
|
ASSERT_EQUALS("1: const int X@1 = 0 ;\n"
|
|
|
|
"2: std :: array < int , X@1 > Y@2 ;\n",
|
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
{
|
|
|
|
const char code[] = "std::optional<N::Foo<A>> Foo;\n"; // #11003
|
|
|
|
|
|
|
|
ASSERT_EQUALS("1: std :: optional < N :: Foo < A > > Foo@1 ;\n",
|
|
|
|
tokenize(code));
|
2022-05-22 09:20:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void varid_templateParameterFunctionPointer() {
|
|
|
|
{
|
|
|
|
const char code[] = "template <class, void (*F)()>\n"
|
|
|
|
"struct a;\n";
|
|
|
|
|
|
|
|
ASSERT_EQUALS("1: template < class , void ( * F ) ( ) >\n"
|
|
|
|
"2: struct a ;\n",
|
|
|
|
tokenize(code));
|
2022-04-25 22:23:06 +02:00
|
|
|
}
|
2016-01-31 11:07:30 +01:00
|
|
|
}
|
|
|
|
|
2016-08-02 15:04:07 +02:00
|
|
|
void varid_templateUsing() { // #5781 #7273
|
2017-12-29 22:47:07 +01:00
|
|
|
const char code[] = "template<class T> using X = Y<T,4>;\n"
|
2016-08-02 15:04:07 +02:00
|
|
|
"X<int> x;";
|
2019-06-01 10:52:29 +02:00
|
|
|
ASSERT_EQUALS("2: Y < int , 4 > x@1 ;\n",
|
2019-01-31 23:57:37 +01:00
|
|
|
tokenize(code));
|
2016-08-02 15:04:07 +02:00
|
|
|
}
|
|
|
|
|
2022-08-19 18:26:00 +02:00
|
|
|
void varid_templateSpecializationFinal() {
|
|
|
|
const char code[] = "template <typename T>\n"
|
|
|
|
"struct S;\n"
|
|
|
|
"template <>\n"
|
|
|
|
"struct S<void> final {};\n";
|
|
|
|
ASSERT_EQUALS("4: struct S<void> ;\n"
|
|
|
|
"1: template < typename T >\n"
|
|
|
|
"2: struct S ;\n"
|
|
|
|
"3:\n"
|
|
|
|
"4: struct S<void> { } ;\n",
|
|
|
|
tokenize(code));
|
|
|
|
}
|
|
|
|
|
2018-11-11 07:50:25 +01:00
|
|
|
void varid_not_template_in_condition() {
|
|
|
|
const char code1[] = "void f() { if (x<a||x>b); }";
|
|
|
|
ASSERT_EQUALS("1: void f ( ) { if ( x < a || x > b ) { ; } }\n", tokenize(code1));
|
|
|
|
|
|
|
|
const char code2[] = "void f() { if (1+x<a||x>b); }";
|
|
|
|
ASSERT_EQUALS("1: void f ( ) { if ( 1 + x < a || x > b ) { ; } }\n", tokenize(code2));
|
|
|
|
|
|
|
|
const char code3[] = "void f() { if (x<a||x>b+1); }";
|
|
|
|
ASSERT_EQUALS("1: void f ( ) { if ( x < a || x > b + 1 ) { ; } }\n", tokenize(code3));
|
|
|
|
|
|
|
|
const char code4[] = "void f() { if ((x==13) && (x<a||x>b)); }";
|
|
|
|
ASSERT_EQUALS("1: void f ( ) { if ( ( x == 13 ) && ( x < a || x > b ) ) { ; } }\n", tokenize(code4));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_cppcast() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: const_cast < int * > ( code ) [ 0 ] = 0 ;\n",
|
2014-10-11 18:35:06 +02:00
|
|
|
tokenize("const_cast<int *>(code)[0] = 0;"));
|
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: dynamic_cast < int * > ( code ) [ 0 ] = 0 ;\n",
|
2014-10-11 18:35:06 +02:00
|
|
|
tokenize("dynamic_cast<int *>(code)[0] = 0;"));
|
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: reinterpret_cast < int * > ( code ) [ 0 ] = 0 ;\n",
|
2014-10-11 18:35:06 +02:00
|
|
|
tokenize("reinterpret_cast<int *>(code)[0] = 0;"));
|
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: static_cast < int * > ( code ) [ 0 ] = 0 ;\n",
|
2014-10-11 18:35:06 +02:00
|
|
|
tokenize("static_cast<int *>(code)[0] = 0;"));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_variadicFunc() {
|
2019-09-04 08:07:30 +02:00
|
|
|
ASSERT_EQUALS("1: int foo ( ... ) ;\n", tokenize("int foo(...);"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_typename() {
|
2017-12-29 22:47:07 +01:00
|
|
|
ASSERT_EQUALS("1: template < int d , class A , class B > struct S { } ;\n", tokenize("template<int d, class A, class B> struct S {};"));
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2017-12-29 22:47:07 +01:00
|
|
|
ASSERT_EQUALS("1: template < int d , typename A , typename B > struct S { } ;\n", tokenize("template<int d, typename A, typename B> struct S {};"));
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2019-02-09 08:34:59 +01:00
|
|
|
ASSERT_EQUALS("1: A a@1 ;\n", tokenize("typename A a;"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_rvalueref() {
|
2019-10-04 12:30:11 +02:00
|
|
|
ASSERT_EQUALS("1: int && a@1 ;\n", tokenize("int&& a;"));
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2019-10-04 12:30:11 +02:00
|
|
|
ASSERT_EQUALS("1: void foo ( int && a@1 ) { }\n", tokenize("void foo(int&& a) {}"));
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class C {\n"
|
2019-10-04 12:30:11 +02:00
|
|
|
"2: C ( int && a@1 ) ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"3: } ;\n",
|
|
|
|
tokenize("class C {\n"
|
|
|
|
" C(int&& a);\n"
|
|
|
|
"};"));
|
|
|
|
|
2019-10-04 12:30:11 +02:00
|
|
|
ASSERT_EQUALS("1: void foo ( int && ) ;\n", tokenize("void foo(int&&);"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_arrayFuncPar() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void check ( const char fname@1 [ ] = 0 ) { }\n", tokenize("void check( const char fname[] = 0) { }"));
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_sizeofPassed() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void which_test ( ) {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: const char * argv@1 [ 2 ] = { \"./test_runner\" , \"TestClass\" } ;\n"
|
2015-02-22 13:38:06 +01:00
|
|
|
"3: options args@2 ( sizeof ( argv@1 ) / sizeof ( argv@1 [ 0 ] ) , argv@1 ) ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"4: args@2 . which_test ( ) ;\n"
|
|
|
|
"5: }\n",
|
|
|
|
tokenize("void which_test() {\n"
|
|
|
|
" const char* argv[] = { \"./test_runner\", \"TestClass\" };\n"
|
|
|
|
" options args(sizeof argv / sizeof argv[0], argv);\n"
|
|
|
|
" args.which_test();\n"
|
|
|
|
"}"));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_classInFunction() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void AddSuppression ( ) {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: class QErrorLogger {\n"
|
|
|
|
"3: void reportErr ( ErrorLogger :: ErrorMessage & msg@1 ) {\n"
|
|
|
|
"4: }\n"
|
|
|
|
"5: } ;\n"
|
|
|
|
"6: }\n",
|
|
|
|
tokenize("void AddSuppression() {\n"
|
|
|
|
" class QErrorLogger {\n"
|
|
|
|
" void reportErr(ErrorLogger::ErrorMessage &msg) {\n"
|
|
|
|
" }\n"
|
2021-02-20 12:58:42 +01:00
|
|
|
" };\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"}"));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_pointerToArray() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: int ( * a1@1 ) [ 10 ] ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: void f1 ( ) {\n"
|
2015-08-25 21:19:19 +02:00
|
|
|
"3: int ( * a2@2 ) [ 10 ] ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"4: int ( & a3@3 ) [ 10 ] ;\n"
|
|
|
|
"5: }\n"
|
|
|
|
"6: struct A {\n"
|
|
|
|
"7: int ( & a4@4 ) [ 10 ] ;\n"
|
|
|
|
"8: int f2 ( int i@5 ) { return a4@4 [ i@5 ] ; }\n"
|
|
|
|
"9: int f3 ( int ( & a5@6 ) [ 10 ] , int i@7 ) { return a5@6 [ i@7 ] ; }\n"
|
|
|
|
"10: } ;\n"
|
|
|
|
"11: int f4 ( int ( & a6@8 ) [ 10 ] , int i@9 ) { return a6@8 [ i@9 ] ; }\n",
|
|
|
|
tokenize("int (*a1)[10];\n" // pointer to array of 10 ints
|
|
|
|
"void f1() {\n"
|
|
|
|
" int(*a2)[10];\n"
|
|
|
|
" int(&a3)[10];\n"
|
|
|
|
"}\n"
|
|
|
|
"struct A {\n"
|
|
|
|
" int(&a4)[10];\n"
|
|
|
|
" int f2(int i) { return a4[i]; }\n"
|
|
|
|
" int f3(int(&a5)[10], int i) { return a5[i]; }\n"
|
|
|
|
"};\n"
|
|
|
|
"int f4(int(&a6)[10], int i) { return a6[i]; }"));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_cpp11initialization() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: int i@1 { 1 } ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: std :: vector < int > vec@2 { 1 , 2 , 3 } ;\n"
|
|
|
|
"3: namespace n { int z@3 ; } ;\n"
|
2014-10-16 20:46:44 +02:00
|
|
|
"4: int & j@4 { i@1 } ;\n"
|
|
|
|
"5: int k@5 { 1 } ; int l@6 { 2 } ;\n",
|
2014-09-24 13:23:44 +02:00
|
|
|
tokenize("int i{1};\n"
|
|
|
|
"std::vector<int> vec{1, 2, 3};\n"
|
|
|
|
"namespace n { int z; };\n"
|
2014-10-16 20:46:44 +02:00
|
|
|
"int& j{i};\n"
|
|
|
|
"int k{1}, l{2};"));
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
// #6030
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: struct S3 : public S1 , public S2 { } ;\n",
|
2014-09-24 13:23:44 +02:00
|
|
|
tokenize("struct S3 : public S1, public S2 { };"));
|
|
|
|
|
|
|
|
// #6058
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class Scope { } ;\n",
|
2014-09-24 13:23:44 +02:00
|
|
|
tokenize("class CPPCHECKLIB Scope { };"));
|
|
|
|
|
2015-04-06 19:47:21 +02:00
|
|
|
// #6073 #6253
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A : public B , public C :: D , public E < F > :: G < H > {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: int i@1 ;\n"
|
2015-04-06 19:47:21 +02:00
|
|
|
"3: A ( int i@2 ) : B { i@2 } , C :: D { i@2 } , E < F > :: G < H > { i@2 } , i@1 { i@2 } {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"4: int j@3 { i@2 } ;\n"
|
|
|
|
"5: }\n"
|
|
|
|
"6: } ;\n",
|
2015-04-06 19:47:21 +02:00
|
|
|
tokenize("class A: public B, public C::D, public E<F>::G<H> {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
" int i;\n"
|
2015-04-06 19:47:21 +02:00
|
|
|
" A(int i): B{i}, C::D{i}, E<F>::G<H>{i} ,i{i} {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
" int j{i};\n"
|
|
|
|
" }\n"
|
|
|
|
"};"));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_inheritedMembers() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: int a@1 ;\n"
|
|
|
|
"3: } ;\n"
|
|
|
|
"4: class B : public A {\n"
|
|
|
|
"5: void f ( ) ;\n"
|
|
|
|
"6: } ;\n"
|
|
|
|
"7: void B :: f ( ) {\n"
|
|
|
|
"8: a@1 = 0 ;\n"
|
|
|
|
"9: }\n",
|
|
|
|
tokenize("class A {\n"
|
|
|
|
" int a;\n"
|
|
|
|
"};\n"
|
|
|
|
"class B : public A {\n"
|
|
|
|
" void f();\n"
|
|
|
|
"};\n"
|
|
|
|
"void B::f() {\n"
|
|
|
|
" a = 0;\n"
|
|
|
|
"}"));
|
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: int a@1 ;\n"
|
|
|
|
"3: } ;\n"
|
|
|
|
"4: class B : A {\n"
|
|
|
|
"5: void f ( ) ;\n"
|
|
|
|
"6: } ;\n"
|
|
|
|
"7: void B :: f ( ) {\n"
|
|
|
|
"8: a@1 = 0 ;\n"
|
|
|
|
"9: }\n",
|
|
|
|
tokenize("class A {\n"
|
|
|
|
" int a;\n"
|
|
|
|
"};\n"
|
|
|
|
"class B : A {\n"
|
|
|
|
" void f();\n"
|
|
|
|
"};\n"
|
|
|
|
"void B::f() {\n"
|
|
|
|
" a = 0;\n"
|
|
|
|
"}"));
|
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: int a@1 ;\n"
|
|
|
|
"3: } ;\n"
|
|
|
|
"4: class B : protected B , public A {\n"
|
|
|
|
"5: void f ( ) ;\n"
|
|
|
|
"6: } ;\n"
|
|
|
|
"7: void B :: f ( ) {\n"
|
|
|
|
"8: a@1 = 0 ;\n"
|
|
|
|
"9: }\n",
|
|
|
|
tokenize("class A {\n"
|
|
|
|
" int a;\n"
|
|
|
|
"};\n"
|
|
|
|
"class B : protected B, public A {\n"
|
|
|
|
" void f();\n"
|
|
|
|
"};\n"
|
|
|
|
"void B::f() {\n"
|
|
|
|
" a = 0;\n"
|
|
|
|
"}"));
|
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: int a@1 ;\n"
|
|
|
|
"3: } ;\n"
|
|
|
|
"4: class B : public A {\n"
|
|
|
|
"5: void f ( ) {\n"
|
|
|
|
"6: a@1 = 0 ;\n"
|
|
|
|
"7: }\n"
|
|
|
|
"8: } ;\n",
|
|
|
|
tokenize("class A {\n"
|
|
|
|
" int a;\n"
|
|
|
|
"};\n"
|
|
|
|
"class B : public A {\n"
|
|
|
|
" void f() {\n"
|
|
|
|
" a = 0;\n"
|
|
|
|
" }\n"
|
|
|
|
"};"));
|
|
|
|
}
|
|
|
|
|
2015-01-02 12:32:23 +01:00
|
|
|
void varid_header() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: class A ;\n"
|
2015-01-02 12:32:23 +01:00
|
|
|
"2: struct B {\n"
|
|
|
|
"3: void setData ( const A & a@1 ) ;\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize("class A;\n"
|
|
|
|
"struct B {\n"
|
|
|
|
" void setData(const A & a);\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"}; ", "test.h"));
|
2015-01-02 12:32:23 +01:00
|
|
|
}
|
|
|
|
|
2015-10-26 19:03:23 +01:00
|
|
|
void varid_rangeBasedFor() {
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void reset ( Foo array@1 ) {\n"
|
2015-10-26 19:03:23 +01:00
|
|
|
"2: for ( auto & e@2 : array@1 ) {\n"
|
|
|
|
"3: foo ( e@2 ) ; }\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize("void reset(Foo array) {\n"
|
|
|
|
" for (auto& e : array)\n"
|
|
|
|
" foo(e);\n"
|
|
|
|
"};"));
|
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void reset ( Foo array@1 ) {\n"
|
2015-10-26 19:03:23 +01:00
|
|
|
"2: for ( auto e@2 : array@1 ) {\n"
|
|
|
|
"3: foo ( e@2 ) ; }\n"
|
|
|
|
"4: } ;\n",
|
|
|
|
tokenize("void reset(Foo array) {\n"
|
|
|
|
" for (auto e : array)\n"
|
|
|
|
" foo(e);\n"
|
|
|
|
"};"));
|
2015-10-26 21:24:53 +01:00
|
|
|
|
|
|
|
// Labels are no variables
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void foo ( ) {\n"
|
2015-10-26 21:24:53 +01:00
|
|
|
"2: switch ( event . key . keysym . sym ) {\n"
|
|
|
|
"3: case SDLK_LEFT : ;\n"
|
|
|
|
"4: break ;\n"
|
|
|
|
"5: case SDLK_RIGHT : ;\n"
|
|
|
|
"6: delta = 1 ;\n"
|
|
|
|
"7: break ;\n"
|
|
|
|
"8: }\n"
|
|
|
|
"9: }\n",
|
|
|
|
tokenize("void foo() {\n"
|
|
|
|
" switch (event.key.keysym.sym) {\n"
|
|
|
|
" case SDLK_LEFT:\n"
|
|
|
|
" break;\n"
|
|
|
|
" case SDLK_RIGHT:\n"
|
|
|
|
" delta = 1;\n"
|
|
|
|
" break;\n"
|
|
|
|
" }\n"
|
2020-05-20 18:52:46 +02:00
|
|
|
"}", "test.c"));
|
2015-10-26 19:03:23 +01:00
|
|
|
}
|
|
|
|
|
2016-05-22 21:18:52 +02:00
|
|
|
void varid_structinit() { // #6406
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void foo ( ) {\n"
|
2016-05-22 21:18:52 +02:00
|
|
|
"2: struct ABC abc@1 ; abc@1 = { . a@2 = 0 , . b@3 = 1 } ;\n"
|
|
|
|
"3: }\n",
|
|
|
|
tokenize("void foo() {\n"
|
|
|
|
" struct ABC abc = {.a=0,.b=1};\n"
|
|
|
|
"}"));
|
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
ASSERT_EQUALS("1: void foo ( ) {\n"
|
2016-05-22 21:18:52 +02:00
|
|
|
"2: struct ABC abc@1 ; abc@1 = { . a@2 = abc@1 . a@2 , . b@3 = abc@1 . b@3 } ;\n"
|
|
|
|
"3: }\n",
|
|
|
|
tokenize("void foo() {\n"
|
|
|
|
" struct ABC abc = {.a=abc.a,.b=abc.b};\n"
|
|
|
|
"}"));
|
2020-04-20 08:59:35 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS("1: void foo ( ) {\n"
|
|
|
|
"2: struct ABC abc@1 ; abc@1 = { . a@2 { abc@1 . a@2 } , . b@3 = { abc@1 . b@3 } } ;\n"
|
|
|
|
"3: }\n",
|
|
|
|
tokenize("void foo() {\n"
|
|
|
|
" struct ABC abc = {.a { abc.a },.b= { abc.b } };\n"
|
|
|
|
"}"));
|
2016-05-22 21:18:52 +02:00
|
|
|
}
|
|
|
|
|
2016-07-18 15:27:08 +02:00
|
|
|
void varid_arrayinit() { // #7579 - no variable declaration in rhs
|
|
|
|
ASSERT_EQUALS("1: void foo ( int * a@1 ) { int b@2 [ 1 ] = { x * a@1 [ 0 ] } ; }\n", tokenize("void foo(int*a) { int b[] = { x*a[0] }; }"));
|
|
|
|
}
|
|
|
|
|
2018-10-07 20:40:59 +02:00
|
|
|
void varid_lambda_arg() {
|
|
|
|
// #8664
|
2022-03-08 20:10:51 +01:00
|
|
|
{
|
|
|
|
const char code[] = "static void func(int ec) {\n"
|
|
|
|
" func2([](const std::error_code& ec) { return ec; });\n"
|
|
|
|
"}";
|
|
|
|
const char exp[] = "1: static void func ( int ec@1 ) {\n"
|
|
|
|
"2: func2 ( [ ] ( const std :: error_code & ec@2 ) { return ec@2 ; } ) ;\n"
|
|
|
|
"3: }\n";
|
|
|
|
ASSERT_EQUALS(exp, tokenize(code));
|
|
|
|
}
|
|
|
|
{
|
|
|
|
const char code[] = "static void func(int ec) {\n"
|
|
|
|
" func2([](int x, const std::error_code& ec) { return x + ec; });\n"
|
|
|
|
"}";
|
|
|
|
const char exp[] = "1: static void func ( int ec@1 ) {\n"
|
|
|
|
"2: func2 ( [ ] ( int x@2 , const std :: error_code & ec@3 ) { return x@2 + ec@3 ; } ) ;\n"
|
|
|
|
"3: }\n";
|
|
|
|
ASSERT_EQUALS(exp, tokenize(code));
|
|
|
|
}
|
|
|
|
// #9384
|
|
|
|
{
|
|
|
|
const char code[] = "auto g = [](const std::string& s) -> std::string { return {}; };\n";
|
|
|
|
const char exp[] = "1: auto g@1 ; g@1 = [ ] ( const std :: string & s@2 ) . std :: string { return { } ; } ;\n";
|
|
|
|
ASSERT_EQUALS(exp, tokenize(code));
|
|
|
|
}
|
|
|
|
{
|
|
|
|
const char code[] = "auto g = [](std::function<void()> p) {};\n";
|
|
|
|
const char exp[] = "1: auto g@1 ; g@1 = [ ] ( std :: function < void ( ) > p@2 ) { } ;\n";
|
2022-03-12 06:17:37 +01:00
|
|
|
ASSERT_EQUALS(exp, tokenize(code));
|
2022-03-08 20:10:51 +01:00
|
|
|
}
|
2022-04-01 19:50:40 +02:00
|
|
|
// # 10849
|
|
|
|
{
|
|
|
|
const char code[] = "class T {};\n"
|
|
|
|
"auto g = [](const T* t) -> int {\n"
|
|
|
|
" const T* u{}, *v{};\n"
|
|
|
|
" return 0;\n"
|
|
|
|
"};\n";
|
|
|
|
const char exp[] = "1: class T { } ;\n"
|
|
|
|
"2: auto g@1 ; g@1 = [ ] ( const T * t@2 ) . int {\n"
|
|
|
|
"3: const T * u@3 { } ; const T * v@4 { } ;\n"
|
|
|
|
"4: return 0 ;\n"
|
|
|
|
"5: } ;\n";
|
|
|
|
ASSERT_EQUALS(exp, tokenize(code));
|
|
|
|
}
|
2022-09-26 18:21:21 +02:00
|
|
|
// # 11332
|
|
|
|
{
|
|
|
|
const char code[] = "auto a() {\n"
|
|
|
|
" return [](int, int b) {};\n"
|
|
|
|
"}\n";
|
|
|
|
const char exp[] = "1: auto a ( ) {\n"
|
|
|
|
"2: return [ ] ( int , int b@1 ) { } ;\n"
|
|
|
|
"3: }\n";
|
|
|
|
ASSERT_EQUALS(exp, tokenize(code));
|
|
|
|
}
|
2018-10-07 20:40:59 +02:00
|
|
|
}
|
|
|
|
|
2019-02-03 08:57:04 +01:00
|
|
|
void varid_lambda_mutable() {
|
|
|
|
// #8957
|
2022-03-08 20:10:51 +01:00
|
|
|
{
|
|
|
|
const char code[] = "static void func() {\n"
|
|
|
|
" auto x = []() mutable {};\n"
|
|
|
|
" dostuff(x);\n"
|
|
|
|
"}";
|
|
|
|
const char exp[] = "1: static void func ( ) {\n"
|
|
|
|
"2: auto x@1 ; x@1 = [ ] ( ) mutable { } ;\n"
|
|
|
|
"3: dostuff ( x@1 ) ;\n"
|
|
|
|
"4: }\n";
|
|
|
|
ASSERT_EQUALS(exp, tokenize(code));
|
|
|
|
}
|
|
|
|
// #9384
|
|
|
|
{
|
|
|
|
const char code[] = "auto g = [](int i) mutable {};\n";
|
|
|
|
const char exp[] = "1: auto g@1 ; g@1 = [ ] ( int i@2 ) mutable { } ;\n";
|
|
|
|
ASSERT_EQUALS(exp, tokenize(code));
|
|
|
|
}
|
2019-02-03 08:57:04 +01:00
|
|
|
}
|
|
|
|
|
2019-04-18 20:22:39 +02:00
|
|
|
void varid_trailing_return1() { // #8889
|
|
|
|
const char code1[] = "struct Fred {\n"
|
|
|
|
" auto foo(const Fred & other) -> Fred &;\n"
|
|
|
|
" auto bar(const Fred & other) -> Fred & {\n"
|
|
|
|
" return *this;\n"
|
|
|
|
" }\n"
|
|
|
|
"};\n"
|
|
|
|
"auto Fred::foo(const Fred & other) -> Fred & {\n"
|
|
|
|
" return *this;\n"
|
|
|
|
"}";
|
|
|
|
const char exp1[] = "1: struct Fred {\n"
|
|
|
|
"2: auto foo ( const Fred & other@1 ) . Fred & ;\n"
|
|
|
|
"3: auto bar ( const Fred & other@2 ) . Fred & {\n"
|
|
|
|
"4: return * this ;\n"
|
|
|
|
"5: }\n"
|
|
|
|
"6: } ;\n"
|
|
|
|
"7: auto Fred :: foo ( const Fred & other@3 ) . Fred & {\n"
|
|
|
|
"8: return * this ;\n"
|
|
|
|
"9: }\n";
|
|
|
|
ASSERT_EQUALS(exp1, tokenize(code1));
|
|
|
|
}
|
|
|
|
|
|
|
|
void varid_trailing_return2() { // #9066
|
|
|
|
const char code1[] = "auto func(int arg) -> bar::quux {}";
|
|
|
|
const char exp1[] = "1: auto func ( int arg@1 ) . bar :: quux { }\n";
|
|
|
|
ASSERT_EQUALS(exp1, tokenize(code1));
|
|
|
|
}
|
|
|
|
|
2022-12-12 22:58:48 +01:00
|
|
|
void varid_trailing_return3() { // #11423
|
|
|
|
const char code[] = "void f(int a, int b) {\n"
|
|
|
|
" auto g = [](int& a, const int b) -> void {};\n"
|
|
|
|
" auto h = [&a, &b]() { std::swap(a, b); };\n"
|
|
|
|
"}\n";
|
|
|
|
const char exp[] = "1: void f ( int a@1 , int b@2 ) {\n"
|
|
|
|
"2: auto g@3 ; g@3 = [ ] ( int & a@4 , const int b@5 ) . void { } ;\n"
|
|
|
|
"3: auto h@6 ; h@6 = [ & a@1 , & b@2 ] ( ) { std :: swap ( a@1 , b@2 ) ; } ;\n"
|
|
|
|
"4: }\n";
|
|
|
|
ASSERT_EQUALS(exp, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2019-10-06 12:45:42 +02:00
|
|
|
void varid_parameter_pack() { // #9383
|
|
|
|
const char code1[] = "template <typename... Rest>\n"
|
|
|
|
"void func(Rest... parameters) {\n"
|
|
|
|
" foo(parameters...);\n"
|
|
|
|
"}\n";
|
|
|
|
const char exp1[] = "1: template < typename ... Rest >\n"
|
|
|
|
"2: void func ( Rest ... parameters@1 ) {\n"
|
|
|
|
"3: foo ( parameters@1 ... ) ;\n"
|
|
|
|
"4: }\n";
|
|
|
|
ASSERT_EQUALS(exp1, tokenize(code1));
|
|
|
|
}
|
|
|
|
|
2020-02-27 07:18:07 +01:00
|
|
|
void varid_for_auto_cpp17() {
|
|
|
|
const char code[] = "void f() {\n"
|
|
|
|
" for (auto [x,y,z]: xyz) {\n"
|
|
|
|
" x+y+z;\n"
|
|
|
|
" }\n"
|
|
|
|
" x+y+z;\n"
|
|
|
|
"}";
|
|
|
|
const char exp1[] = "1: void f ( ) {\n"
|
|
|
|
"2: for ( auto [ x@1 , y@2 , z@3 ] : xyz ) {\n"
|
|
|
|
"3: x@1 + y@2 + z@3 ;\n"
|
|
|
|
"4: }\n"
|
|
|
|
"5: x + y + z ;\n"
|
|
|
|
"6: }\n";
|
|
|
|
ASSERT_EQUALS(exp1, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2020-04-25 14:42:31 +02:00
|
|
|
void varid_not() { // #9689 'not x'
|
|
|
|
const char code1[] = "void foo(int x) const {\n"
|
|
|
|
" if (not x) {}\n"
|
|
|
|
"}";
|
|
|
|
const char exp1[] = "1: void foo ( int x@1 ) const {\n"
|
2020-05-25 16:02:34 +02:00
|
|
|
"2: if ( ! x@1 ) { }\n"
|
2020-04-25 14:42:31 +02:00
|
|
|
"3: }\n";
|
|
|
|
ASSERT_EQUALS(exp1, tokenize(code1));
|
|
|
|
}
|
|
|
|
|
2021-04-26 07:38:03 +02:00
|
|
|
void varid_declInIfCondition() {
|
|
|
|
// if
|
|
|
|
ASSERT_EQUALS("1: void f ( int x@1 ) {\n"
|
|
|
|
"2: if ( int x@2 = 0 ) { x@2 ; }\n"
|
|
|
|
"3: x@1 ;\n"
|
|
|
|
"4: }\n",
|
|
|
|
tokenize("void f(int x) {\n"
|
|
|
|
" if (int x = 0) { x; }\n"
|
|
|
|
" x;\n"
|
|
|
|
"}"));
|
|
|
|
// if, else
|
|
|
|
ASSERT_EQUALS("1: void f ( int x@1 ) {\n"
|
|
|
|
"2: if ( int x@2 = 0 ) { x@2 ; }\n"
|
|
|
|
"3: else { x@2 ; }\n"
|
|
|
|
"4: x@1 ;\n"
|
|
|
|
"5: }\n",
|
|
|
|
tokenize("void f(int x) {\n"
|
|
|
|
" if (int x = 0) { x; }\n"
|
|
|
|
" else { x; }\n"
|
|
|
|
" x;\n"
|
|
|
|
"}"));
|
|
|
|
// if, else if
|
|
|
|
ASSERT_EQUALS("1: void f ( int x@1 ) {\n"
|
|
|
|
"2: if ( int x@2 = 0 ) { x@2 ; }\n"
|
|
|
|
"3: else { if ( void * x@3 = & x@3 ) { x@3 ; } }\n"
|
|
|
|
"4: x@1 ;\n"
|
|
|
|
"5: }\n",
|
|
|
|
tokenize("void f(int x) {\n"
|
|
|
|
" if (int x = 0) x;\n"
|
|
|
|
" else if (void* x = &x) x;\n"
|
|
|
|
" x;\n"
|
|
|
|
"}"));
|
|
|
|
// if, else if, else
|
|
|
|
ASSERT_EQUALS("1: void f ( int x@1 ) {\n"
|
|
|
|
"2: if ( int x@2 = 0 ) { x@2 ; }\n"
|
|
|
|
"3: else { if ( void * x@3 = & x@3 ) { x@3 ; }\n"
|
|
|
|
"4: else { x@3 ; } }\n"
|
|
|
|
"5: x@1 ;\n"
|
|
|
|
"6: }\n",
|
|
|
|
tokenize("void f(int x) {\n"
|
|
|
|
" if (int x = 0) x;\n"
|
|
|
|
" else if (void* x = &x) x;\n"
|
|
|
|
" else x;\n"
|
|
|
|
" x;\n"
|
|
|
|
"}"));
|
|
|
|
}
|
|
|
|
|
2022-06-11 08:11:16 +02:00
|
|
|
void varid_globalScope() {
|
|
|
|
const char code1[] = "int a[5];\n"
|
|
|
|
"namespace Z { struct B { int a[5]; } b; }\n"
|
|
|
|
"void f() {\n"
|
|
|
|
" int a[5];\n"
|
|
|
|
" memset(a, 123, 5);\n"
|
|
|
|
" memset(::a, 123, 5);\n"
|
|
|
|
" memset(Z::b.a, 123, 5);\n"
|
|
|
|
" memset(::Z::b.a, 123, 5);\n"
|
|
|
|
"}";
|
|
|
|
|
|
|
|
const char exp1[] = "1: int a@1 [ 5 ] ;\n"
|
|
|
|
"2: namespace Z { struct B { int a@2 [ 5 ] ; } ; struct B b@3 ; }\n"
|
|
|
|
"3: void f ( ) {\n"
|
|
|
|
"4: int a@4 [ 5 ] ;\n"
|
|
|
|
"5: memset ( a@4 , 123 , 5 ) ;\n"
|
|
|
|
"6: memset ( :: a@1 , 123 , 5 ) ;\n"
|
|
|
|
"7: memset ( Z :: b@3 . a , 123 , 5 ) ;\n"
|
|
|
|
"8: memset ( :: Z :: b@3 . a , 123 , 5 ) ;\n"
|
|
|
|
"9: }\n";
|
|
|
|
ASSERT_EQUALS(exp1, tokenize(code1));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass1() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"class Fred\n"
|
|
|
|
"{\n"
|
|
|
|
"private:\n"
|
|
|
|
" int i;\n"
|
|
|
|
"\n"
|
|
|
|
" void foo1();\n"
|
|
|
|
" void foo2()\n"
|
|
|
|
" {\n"
|
|
|
|
" ++i;\n"
|
|
|
|
" }\n"
|
|
|
|
"}\n"
|
|
|
|
"\n"
|
|
|
|
"Fred::foo1()\n"
|
|
|
|
"{\n"
|
|
|
|
" i = 0;\n"
|
|
|
|
"}");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Fred\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: private:\n"
|
|
|
|
"4: int i@1 ;\n"
|
|
|
|
"5:\n"
|
|
|
|
"6: void foo1 ( ) ;\n"
|
|
|
|
"7: void foo2 ( )\n"
|
|
|
|
"8: {\n"
|
|
|
|
"9: ++ i@1 ;\n"
|
|
|
|
"10: }\n"
|
|
|
|
"11: }\n"
|
|
|
|
"12:\n"
|
|
|
|
"13: Fred :: foo1 ( )\n"
|
|
|
|
"14: {\n"
|
|
|
|
"15: i@1 = 0 ;\n"
|
|
|
|
"16: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass2() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"class Fred\n"
|
|
|
|
"{ void f(); };\n"
|
|
|
|
"\n"
|
|
|
|
"void A::foo1()\n"
|
|
|
|
"{\n"
|
|
|
|
" int i = 0;\n"
|
|
|
|
"}\n"
|
|
|
|
"\n"
|
|
|
|
"void Fred::f()\n"
|
|
|
|
"{\n"
|
|
|
|
" i = 0;\n"
|
|
|
|
"}");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Fred\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: { void f ( ) ; } ;\n"
|
|
|
|
"3:\n"
|
|
|
|
"4: void A :: foo1 ( )\n"
|
|
|
|
"5: {\n"
|
|
|
|
"6: int i@1 ; i@1 = 0 ;\n"
|
|
|
|
"7: }\n"
|
|
|
|
"8:\n"
|
|
|
|
"9: void Fred :: f ( )\n"
|
|
|
|
"10: {\n"
|
|
|
|
"11: i = 0 ;\n"
|
|
|
|
"12: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass3() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"class Fred\n"
|
|
|
|
"{ int i; void f(); };\n"
|
|
|
|
"\n"
|
|
|
|
"void Fred::f()\n"
|
|
|
|
"{\n"
|
|
|
|
" i = 0;\n"
|
|
|
|
"}\n"
|
|
|
|
"\n"
|
|
|
|
"void A::f()\n"
|
|
|
|
"{\n"
|
|
|
|
" i = 0;\n"
|
|
|
|
"}");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Fred\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: { int i@1 ; void f ( ) ; } ;\n"
|
|
|
|
"3:\n"
|
|
|
|
"4: void Fred :: f ( )\n"
|
|
|
|
"5: {\n"
|
|
|
|
"6: i@1 = 0 ;\n"
|
|
|
|
"7: }\n"
|
|
|
|
"8:\n"
|
|
|
|
"9: void A :: f ( )\n"
|
|
|
|
"10: {\n"
|
|
|
|
"11: i = 0 ;\n"
|
|
|
|
"12: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass4() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"class Fred\n"
|
|
|
|
"{ int i; void f(); };\n"
|
|
|
|
"\n"
|
|
|
|
"void Fred::f()\n"
|
|
|
|
"{\n"
|
|
|
|
" if (i) { }\n"
|
|
|
|
" i = 0;\n"
|
|
|
|
"}");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Fred\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: { int i@1 ; void f ( ) ; } ;\n"
|
|
|
|
"3:\n"
|
|
|
|
"4: void Fred :: f ( )\n"
|
|
|
|
"5: {\n"
|
|
|
|
"6: if ( i@1 ) { }\n"
|
|
|
|
"7: i@1 = 0 ;\n"
|
|
|
|
"8: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass5() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"class A { };\n"
|
|
|
|
"class B\n"
|
|
|
|
"{\n"
|
|
|
|
" A *a;\n"
|
|
|
|
" B() : a(new A)\n"
|
|
|
|
" { }\n"
|
|
|
|
"};");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class A { } ;\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: class B\n"
|
|
|
|
"3: {\n"
|
|
|
|
"4: A * a@1 ;\n"
|
|
|
|
"5: B ( ) : a@1 ( new A )\n"
|
|
|
|
"6: { }\n"
|
|
|
|
"7: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass6() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"class A\n"
|
|
|
|
"{\n"
|
|
|
|
" public:\n"
|
|
|
|
" static char buf[20];\n"
|
|
|
|
"};\n"
|
|
|
|
"char A::buf[20];\n"
|
|
|
|
"int main()\n"
|
|
|
|
"{\n"
|
|
|
|
" char buf[2];\n"
|
|
|
|
" A::buf[10] = 0;\n"
|
|
|
|
"}");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class A\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: public:\n"
|
|
|
|
"4: static char buf@1 [ 20 ] ;\n"
|
|
|
|
"5: } ;\n"
|
|
|
|
"6: char A :: buf@1 [ 20 ] ;\n"
|
|
|
|
"7: int main ( )\n"
|
|
|
|
"8: {\n"
|
|
|
|
"9: char buf@2 [ 2 ] ;\n"
|
|
|
|
"10: A :: buf@1 [ 10 ] = 0 ;\n"
|
|
|
|
"11: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2015-03-15 12:36:40 +01:00
|
|
|
ASSERT_EQUALS(expected, actual);
|
2014-09-24 13:23:44 +02:00
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass7() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const std::string actual = tokenize(
|
2021-08-07 20:51:18 +02:00
|
|
|
"int main()\n"
|
|
|
|
"{\n"
|
|
|
|
" char buf[2];\n"
|
|
|
|
" A::buf[10] = 0;\n"
|
|
|
|
"}");
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: int main ( )\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: {\n"
|
|
|
|
"3: char buf@1 [ 2 ] ;\n"
|
|
|
|
"4: A :: buf [ 10 ] = 0 ;\n"
|
|
|
|
"5: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass8() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="class Fred {\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"public:\n"
|
|
|
|
" void foo(int d) {\n"
|
|
|
|
" int i = bar(x * d);\n"
|
|
|
|
" }\n"
|
|
|
|
" int x;\n"
|
|
|
|
"}\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Fred {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: public:\n"
|
|
|
|
"3: void foo ( int d@1 ) {\n"
|
|
|
|
"4: int i@2 ; i@2 = bar ( x@3 * d@1 ) ;\n"
|
|
|
|
"5: }\n"
|
|
|
|
"6: int x@3 ;\n"
|
|
|
|
"7: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass9() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="typedef char Str[10];"
|
2021-08-07 20:51:18 +02:00
|
|
|
"class A {\n"
|
|
|
|
"public:\n"
|
|
|
|
" void f(Str &cl);\n"
|
|
|
|
" void g(Str cl);\n"
|
|
|
|
"}\n"
|
|
|
|
"void Fred::f(Str &cl) {\n"
|
|
|
|
" sizeof(cl);\n"
|
|
|
|
"}";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class A {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: public:\n"
|
|
|
|
"3: void f ( char ( & cl@1 ) [ 10 ] ) ;\n"
|
|
|
|
"4: void g ( char cl@2 [ 10 ] ) ;\n"
|
|
|
|
"5: }\n"
|
|
|
|
"6: void Fred :: f ( char ( & cl@3 ) [ 10 ] ) {\n"
|
|
|
|
"7: sizeof ( cl@3 ) ;\n"
|
|
|
|
"8: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass10() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="class A {\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
" void f() {\n"
|
|
|
|
" a = 3;\n"
|
|
|
|
" }\n"
|
|
|
|
" int a;\n"
|
|
|
|
"};\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class A {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: void f ( ) {\n"
|
|
|
|
"3: a@1 = 3 ;\n"
|
|
|
|
"4: }\n"
|
|
|
|
"5: int a@1 ;\n"
|
|
|
|
"6: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass11() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="class Fred {\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
" int a;\n"
|
|
|
|
" void f();\n"
|
|
|
|
"};\n"
|
|
|
|
"class Wilma {\n"
|
|
|
|
" int a;\n"
|
|
|
|
" void f();\n"
|
|
|
|
"};\n"
|
|
|
|
"void Fred::f() { a = 0; }\n"
|
|
|
|
"void Wilma::f() { a = 0; }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Fred {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: int a@1 ;\n"
|
|
|
|
"3: void f ( ) ;\n"
|
|
|
|
"4: } ;\n"
|
|
|
|
"5: class Wilma {\n"
|
|
|
|
"6: int a@2 ;\n"
|
|
|
|
"7: void f ( ) ;\n"
|
|
|
|
"8: } ;\n"
|
|
|
|
"9: void Fred :: f ( ) { a@1 = 0 ; }\n"
|
|
|
|
"10: void Wilma :: f ( ) { a@2 = 0 ; }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass12() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="class Fred {\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
" int a;\n"
|
|
|
|
" void f() { Fred::a = 0; }\n"
|
|
|
|
"};\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Fred {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: int a@1 ;\n"
|
|
|
|
"3: void f ( ) { Fred :: a@1 = 0 ; }\n"
|
|
|
|
"4: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass13() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] ="class Fred {\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
" int a;\n"
|
|
|
|
" void f() { Foo::Fred::a = 0; }\n"
|
|
|
|
"};\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Fred {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: int a@1 ;\n"
|
|
|
|
"3: void f ( ) { Foo :: Fred :: a = 0 ; }\n"
|
|
|
|
"4: } ;\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass14() {
|
2014-09-24 13:23:44 +02:00
|
|
|
// don't give friend classes varid
|
|
|
|
{
|
|
|
|
const char code[] ="class A {\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"friend class B;\n"
|
|
|
|
"}";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class A {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: friend class B ;\n"
|
|
|
|
"3: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const char code[] ="class A {\n"
|
2021-08-07 20:51:18 +02:00
|
|
|
"private: friend class B;\n"
|
|
|
|
"}";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class A {\n"
|
2015-03-15 12:36:40 +01:00
|
|
|
"2: private: friend class B ;\n"
|
|
|
|
"3: }\n";
|
2014-09-24 13:23:44 +02:00
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass15() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "class A {\n"
|
|
|
|
" int a;\n"
|
|
|
|
" int b;\n"
|
|
|
|
" A();\n"
|
|
|
|
"};\n"
|
|
|
|
"A::A() : a(0) { b = 1; }";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: int a@1 ;\n"
|
|
|
|
"3: int b@2 ;\n"
|
|
|
|
"4: A ( ) ;\n"
|
|
|
|
"5: } ;\n"
|
|
|
|
"6: A :: A ( ) : a@1 ( 0 ) { b@2 = 1 ; }\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass16() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "struct A;\n"
|
|
|
|
"typedef bool (A::* FuncPtr)();\n"
|
|
|
|
"struct A {\n"
|
|
|
|
" FuncPtr pFun;\n"
|
|
|
|
" void setPFun(int mode);\n"
|
|
|
|
" bool funcNorm();\n"
|
|
|
|
"};\n"
|
|
|
|
"void A::setPFun(int mode) {\n"
|
|
|
|
" pFun = &A::funcNorm;\n"
|
|
|
|
"}";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: struct A ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2:\n"
|
|
|
|
"3: struct A {\n"
|
2020-04-10 11:53:32 +02:00
|
|
|
"4: bool ( * pFun@1 ) ( ) ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"5: void setPFun ( int mode@2 ) ;\n"
|
|
|
|
"6: bool funcNorm ( ) ;\n"
|
|
|
|
"7: } ;\n"
|
|
|
|
"8: void A :: setPFun ( int mode@3 ) {\n"
|
|
|
|
"9: pFun@1 = & A :: funcNorm ;\n"
|
|
|
|
"10: }\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidclass17() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "class A: public B, public C::D {\n"
|
|
|
|
" int i;\n"
|
|
|
|
" A(int i): B(i), C::D(i), i(i) {\n"
|
|
|
|
" int j(i);\n"
|
|
|
|
" }\n"
|
|
|
|
"};";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class A : public B , public C :: D {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: int i@1 ;\n"
|
|
|
|
"3: A ( int i@2 ) : B ( i@2 ) , C :: D ( i@2 ) , i@1 ( i@2 ) {\n"
|
|
|
|
"4: int j@3 ; j@3 = i@2 ;\n"
|
|
|
|
"5: }\n"
|
|
|
|
"6: } ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2015-07-14 18:09:07 +02:00
|
|
|
void varidclass18() {
|
|
|
|
const char code[] = "class A {\n"
|
|
|
|
" int a;\n"
|
|
|
|
" int b;\n"
|
|
|
|
" A();\n"
|
|
|
|
"};\n"
|
|
|
|
"A::A() : a{0} { b = 1; }";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class A {\n"
|
2015-07-14 18:09:07 +02:00
|
|
|
"2: int a@1 ;\n"
|
|
|
|
"3: int b@2 ;\n"
|
|
|
|
"4: A ( ) ;\n"
|
|
|
|
"5: } ;\n"
|
|
|
|
"6: A :: A ( ) : a@1 { 0 } { b@2 = 1 ; }\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2016-01-23 08:28:04 +01:00
|
|
|
void varidclass19() {
|
|
|
|
const char code[] = "class A : public ::B {\n"
|
|
|
|
" int a;\n"
|
|
|
|
" A();\n"
|
|
|
|
"};\n"
|
|
|
|
"A::A() : ::B(), a(0) {}";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class A : public :: B {\n"
|
2016-01-23 08:28:04 +01:00
|
|
|
"2: int a@1 ;\n"
|
|
|
|
"3: A ( ) ;\n"
|
|
|
|
"4: } ;\n"
|
|
|
|
"5: A :: A ( ) : :: B ( ) , a@1 ( 0 ) { }\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2020-04-15 20:56:21 +02:00
|
|
|
void varidclass20() { // #7578: int (*p)[2]
|
|
|
|
const char code[] = "struct S {\n"
|
|
|
|
" int (*p)[2];\n"
|
|
|
|
" S();\n"
|
|
|
|
"};\n"
|
|
|
|
"S::S() { p[0] = 0; }";
|
|
|
|
const char expected[] = "1: struct S {\n"
|
|
|
|
"2: int ( * p@1 ) [ 2 ] ;\n"
|
|
|
|
"3: S ( ) ;\n"
|
|
|
|
"4: } ;\n"
|
|
|
|
"5: S :: S ( ) { p@1 [ 0 ] = 0 ; }\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
Fix #9647: Set correct enum value (#2856)
* Tokenize: Set varId for variables in enum
Set varIds in enum values. It was previously disabled in 5119ae84b879fad
to avoid issues with enums named the same as global variables. Take care
to only set varids to variables used to set the value of an enumerator,
not the enumerator itself. This is somewhat complicated by the fact that
at the time this happens, astOperand1(), astOperand2(), astParent() etc
are not set. The current implementation is not perfect, for example in
the code below, y will not have a varid set, but x and z will. This is
deemed sufficient for now.
int x, y, z;
enum E { a = f(x, y, z); };
* Fix #9647: Value of enums with variables as init values
C++ allows enum values to be set using constexprs, which cppcheck did
not handle before. To solve this, add a new pass to valueflow to update
enum values after global consts have been processed. In order to do so,
I moved all settings of enum values to valueflow. After setting the enum
values, we need another call to valueFlowNumber() to actually set users
of the enums.
There is still room for improvements, since each pass of
valueFlowGlobalConstVar() and valueFlowEnumValue() only sets variables
that are possible to set directly, and not if setting the value of a
variable allows us to set the value of another. For example
constexpr int a = 5;
constexpr int b = a + 5;
enum E { X = a };
constexpr E e = X;
Here both b and e will not have their values set, even though cppcheck
should be possible to figure out their values. That's for another PR
though.
This was tested by running test-my-pr.py with 500 packages. The only
difference was one error message in fairy-stockfish_11.1, where cppcheck
now printed the correct size of an array instead of 2147483648 which I
assume is some kind of default value. In that package, using a constexpr
when setting enum values is common, but as mentioned, there was no
change in the number of warnings.
2020-10-22 07:45:04 +02:00
|
|
|
void varidenum1() {
|
|
|
|
const char code[] = "const int eStart = 6;\n"
|
|
|
|
"enum myEnum {\n"
|
|
|
|
" A = eStart;\n"
|
|
|
|
"};\n";
|
|
|
|
const char expected[] = "1: const int eStart@1 = 6 ;\n"
|
|
|
|
"2: enum myEnum {\n"
|
|
|
|
"3: A = eStart@1 ;\n"
|
|
|
|
"4: } ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
|
|
|
void varidenum2() {
|
|
|
|
const char code[] = "const int eStart = 6;\n"
|
|
|
|
"enum myEnum {\n"
|
|
|
|
" A = f(eStart);\n"
|
|
|
|
"};\n";
|
|
|
|
const char expected[] = "1: const int eStart@1 = 6 ;\n"
|
|
|
|
"2: enum myEnum {\n"
|
|
|
|
"3: A = f ( eStart@1 ) ;\n"
|
|
|
|
"4: } ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
|
|
|
void varidenum3() {
|
|
|
|
const char code[] = "const int eStart = 6;\n"
|
|
|
|
"enum myEnum {\n"
|
|
|
|
" A = f(eStart, x);\n"
|
|
|
|
"};\n";
|
|
|
|
const char expected[] = "1: const int eStart@1 = 6 ;\n"
|
|
|
|
"2: enum myEnum {\n"
|
|
|
|
"3: A = f ( eStart@1 , x ) ;\n"
|
|
|
|
"4: } ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
|
|
|
void varidenum4() {
|
|
|
|
const char code[] = "const int eStart = 6;\n"
|
|
|
|
"enum myEnum {\n"
|
|
|
|
" A = f(x, eStart);\n"
|
|
|
|
"};\n";
|
|
|
|
const char expected[] = "1: const int eStart@1 = 6 ;\n"
|
|
|
|
"2: enum myEnum {\n"
|
|
|
|
"3: A = f ( x , eStart@1 ) ;\n"
|
|
|
|
"4: } ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
|
|
|
void varidenum5() {
|
|
|
|
const char code[] = "const int eStart = 6;\n"
|
|
|
|
"enum myEnum {\n"
|
|
|
|
" A = f(x, eStart, y);\n"
|
|
|
|
"};\n";
|
|
|
|
const char expected[] = "1: const int eStart@1 = 6 ;\n"
|
|
|
|
"2: enum myEnum {\n"
|
|
|
|
"3: A = f ( x , eStart@1 , y ) ;\n"
|
|
|
|
"4: } ;\n";
|
|
|
|
const char current[] = "1: const int eStart@1 = 6 ;\n"
|
|
|
|
"2: enum myEnum {\n"
|
|
|
|
"3: A = f ( x , eStart , y ) ;\n"
|
|
|
|
"4: } ;\n";
|
|
|
|
TODO_ASSERT_EQUALS(expected, current, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2022-04-27 12:43:21 +02:00
|
|
|
void varidenum6() { // #9180
|
|
|
|
const char code[] = "const int IDL1 = 13;\n"
|
|
|
|
"enum class E { IDL1 = 16, };\n";
|
|
|
|
const char expected[] = "1: const int IDL1@1 = 13 ;\n"
|
|
|
|
"2: enum class E { IDL1 = 16 , } ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2022-04-30 08:20:00 +02:00
|
|
|
void varidenum7() { // #8991
|
|
|
|
const char code[] = "namespace N1 { const int c = 42; }\n"
|
|
|
|
"namespace N2 { const int c = 24; }\n"
|
|
|
|
"struct S {\n"
|
|
|
|
" enum { v1 = N1::c, v2 = N2::c };\n"
|
|
|
|
"};\n";
|
|
|
|
const char expected[] = "1: namespace N1 { const int c@1 = 42 ; }\n"
|
|
|
|
"2: namespace N2 { const int c@2 = 24 ; }\n"
|
|
|
|
"3: struct S {\n"
|
|
|
|
"4: enum Anonymous0 { v1 = N1 :: c@1 , v2 = N2 :: c@2 } ;\n"
|
|
|
|
"5: } ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varid_classnameshaddowsvariablename() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "class Data;\n"
|
|
|
|
"void strange_declarated(const Data& Data);\n"
|
|
|
|
"void handleData(const Data& data) {\n"
|
|
|
|
" strange_declarated(data);\n"
|
|
|
|
"}\n";
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: class Data ;\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: void strange_declarated ( const Data & Data@1 ) ;\n"
|
|
|
|
"3: void handleData ( const Data & data@2 ) {\n"
|
|
|
|
"4: strange_declarated ( data@2 ) ;\n"
|
|
|
|
"5: }\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-03-29 12:16:02 +02:00
|
|
|
void varid_classnametemplate() {
|
|
|
|
const char code[] = "template <typename T>\n"
|
|
|
|
"struct BBB {\n"
|
|
|
|
" struct inner;\n"
|
|
|
|
"};\n"
|
|
|
|
"\n"
|
|
|
|
"template <typename T>\n"
|
|
|
|
"struct BBB<T>::inner {\n"
|
|
|
|
" inner(int x);\n"
|
|
|
|
" int x;\n"
|
|
|
|
"};\n"
|
|
|
|
"\n"
|
|
|
|
"template <typename T>\n"
|
|
|
|
"BBB<T>::inner::inner(int x): x(x) {}\n";
|
|
|
|
const char expected[] = "1: template < typename T >\n"
|
|
|
|
"2: struct BBB {\n"
|
|
|
|
"3: struct inner ;\n"
|
|
|
|
"4: } ;\n"
|
|
|
|
"5:\n"
|
|
|
|
"6: template < typename T >\n"
|
|
|
|
"7: struct BBB < T > :: inner {\n"
|
|
|
|
"8: inner ( int x@1 ) ;\n"
|
|
|
|
"9: int x@2 ;\n"
|
|
|
|
"10: } ;\n"
|
|
|
|
"11:\n"
|
|
|
|
"12: template < typename T >\n"
|
|
|
|
"13: BBB < T > :: inner :: inner ( int x@3 ) : x@2 ( x@3 ) { }\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
void varidnamespace1() {
|
2014-09-24 13:23:44 +02:00
|
|
|
const char code[] = "namespace A {\n"
|
|
|
|
" char buf[20];\n"
|
|
|
|
"}\n"
|
|
|
|
"int main() {\n"
|
|
|
|
" return foo(A::buf);\n"
|
|
|
|
"}";
|
|
|
|
|
2016-07-18 10:42:03 +02:00
|
|
|
const char expected[] = "1: namespace A {\n"
|
2014-09-24 13:23:44 +02:00
|
|
|
"2: char buf@1 [ 20 ] ;\n"
|
|
|
|
"3: }\n"
|
|
|
|
"4: int main ( ) {\n"
|
|
|
|
"5: return foo ( A :: buf@1 ) ;\n"
|
|
|
|
"6: }\n";
|
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
2017-11-09 15:58:08 +01:00
|
|
|
|
|
|
|
void varidnamespace2() {
|
|
|
|
const char code[] = "namespace A {\n"
|
|
|
|
" namespace B {\n"
|
|
|
|
" char buf[20];\n"
|
|
|
|
" }\n"
|
|
|
|
"}\n"
|
|
|
|
"int main() {\n"
|
|
|
|
" return foo(A::B::buf);\n"
|
|
|
|
"}";
|
|
|
|
|
|
|
|
const char expected[] = "1: namespace A {\n"
|
|
|
|
"2: namespace B {\n"
|
|
|
|
"3: char buf@1 [ 20 ] ;\n"
|
|
|
|
"4: }\n"
|
|
|
|
"5: }\n"
|
|
|
|
"6: int main ( ) {\n"
|
|
|
|
"7: return foo ( A :: B :: buf@1 ) ;\n"
|
|
|
|
"8: }\n";
|
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
2017-11-09 22:08:58 +01:00
|
|
|
|
|
|
|
void usingNamespace1() {
|
|
|
|
const char code[] = "namespace NS {\n"
|
|
|
|
" class A { int x; void dostuff(); };\n"
|
|
|
|
"}\n"
|
|
|
|
"using namespace NS;\n"
|
|
|
|
"void A::dostuff() { x = 0; }\n";
|
|
|
|
const char expected[] = "1: namespace NS {\n"
|
|
|
|
"2: class A { int x@1 ; void dostuff ( ) ; } ;\n"
|
|
|
|
"3: }\n"
|
|
|
|
"4: using namespace NS ;\n"
|
|
|
|
"5: void A :: dostuff ( ) { x@1 = 0 ; }\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
|
|
|
void usingNamespace2() {
|
|
|
|
const char code[] = "class A { int x; void dostuff(); };\n"
|
|
|
|
"using namespace NS;\n"
|
|
|
|
"void A::dostuff() { x = 0; }\n";
|
|
|
|
const char expected[] = "1: class A { int x@1 ; void dostuff ( ) ; } ;\n"
|
|
|
|
"2: using namespace NS ;\n"
|
|
|
|
"3: void A :: dostuff ( ) { x@1 = 0 ; }\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
2017-11-09 23:15:16 +01:00
|
|
|
|
|
|
|
void usingNamespace3() {
|
|
|
|
const char code[] = "namespace A {\n"
|
|
|
|
" namespace B {\n"
|
|
|
|
" class C {\n"
|
|
|
|
" double m;\n"
|
|
|
|
" C();\n"
|
|
|
|
" };\n"
|
|
|
|
" }\n"
|
|
|
|
"}\n"
|
|
|
|
"using namespace A::B;\n"
|
|
|
|
"C::C() : m(42) {}";
|
|
|
|
|
|
|
|
const char expected[] = "1: namespace A {\n"
|
|
|
|
"2: namespace B {\n"
|
|
|
|
"3: class C {\n"
|
|
|
|
"4: double m@1 ;\n"
|
|
|
|
"5: C ( ) ;\n"
|
|
|
|
"6: } ;\n"
|
|
|
|
"7: }\n"
|
|
|
|
"8: }\n"
|
|
|
|
"9: using namespace A :: B ;\n"
|
|
|
|
"10: C :: C ( ) : m@1 ( 42 ) { }\n";
|
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
2018-11-14 19:11:35 +01:00
|
|
|
|
|
|
|
void setVarIdStructMembers1() {
|
|
|
|
const char code[] = "void f(Foo foo)\n"
|
|
|
|
"{\n"
|
|
|
|
" foo.size = 0;\n"
|
|
|
|
" return ((uint8_t)(foo).size);\n"
|
|
|
|
"}";
|
|
|
|
const char expected[] = "1: void f ( Foo foo@1 )\n"
|
|
|
|
"2: {\n"
|
|
|
|
"3: foo@1 . size@2 = 0 ;\n"
|
|
|
|
"4: return ( ( uint8_t ) ( foo@1 ) . size@2 ) ;\n"
|
|
|
|
"5: }\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
2020-01-29 17:40:22 +01:00
|
|
|
|
|
|
|
void decltype1() {
|
|
|
|
const char code[] = "void foo(int x, decltype(A::b) *p);";
|
|
|
|
const char expected[] = "1: void foo ( int x@1 , decltype ( A :: b ) * p@2 ) ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
2020-08-20 18:21:29 +02:00
|
|
|
|
2020-11-16 20:11:26 +01:00
|
|
|
void decltype2() {
|
|
|
|
const char code[] = "int x; decltype(x) y;";
|
|
|
|
const char expected[] = "1: int x@1 ; decltype ( x@1 ) y@2 ;\n";
|
|
|
|
ASSERT_EQUALS(expected, tokenize(code));
|
|
|
|
}
|
|
|
|
|
2020-08-20 18:21:29 +02:00
|
|
|
void exprid1() {
|
|
|
|
const std::string actual = tokenizeExpr(
|
2021-08-07 20:51:18 +02:00
|
|
|
"struct A {\n"
|
|
|
|
" int x, y;\n"
|
|
|
|
"};\n"
|
|
|
|
"int f(A a, A b) {\n"
|
|
|
|
" int x = a.x + b.x;\n"
|
|
|
|
" int y = b.x + a.x;\n"
|
|
|
|
" return x + y + a.y + b.y;\n"
|
|
|
|
"}\n");
|
2020-08-20 18:21:29 +02:00
|
|
|
|
|
|
|
const char expected[] = "1: struct A {\n"
|
|
|
|
"2: int x ; int y ;\n"
|
|
|
|
"3: } ;\n"
|
|
|
|
"4: int f ( A a , A b ) {\n"
|
2021-10-06 08:39:58 +02:00
|
|
|
"5: int x@5 ; x@5 =@9 a@3 .@10 x@6 +@11 b@4 .@12 x@7 ;\n"
|
|
|
|
"6: int y@8 ; y@8 =@13 b@4 .@12 x@7 +@11 a@3 .@10 x@6 ;\n"
|
|
|
|
"7: return x@5 +@17 y@8 +@18 a@3 .@19 y@9 +@20 b@4 .@21 y@10 ;\n"
|
2020-08-20 18:21:29 +02:00
|
|
|
"8: }\n";
|
|
|
|
|
|
|
|
ASSERT_EQUALS(expected, actual);
|
|
|
|
}
|
2021-04-26 18:04:27 +02:00
|
|
|
|
|
|
|
void structuredBindings() {
|
|
|
|
const char code[] = "int foo() { auto [x,y] = xy(); return x+y; }";
|
|
|
|
ASSERT_EQUALS("1: int foo ( ) { auto [ x@1 , y@2 ] = xy ( ) ; return x@1 + y@2 ; }\n",
|
|
|
|
tokenize(code));
|
|
|
|
}
|
2014-09-24 13:23:44 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
REGISTER_TEST(TestVarID)
|