diff --git a/Makefile b/Makefile index b008aa403..c5fcd3995 100644 --- a/Makefile +++ b/Makefile @@ -226,6 +226,7 @@ TESTOBJ = test/options.o \ test/testboost.o \ test/testbufferoverrun.o \ test/testcharvar.o \ + test/testclangastdump.o \ test/testclass.o \ test/testcmdlineparser.o \ test/testcondition.o \ @@ -591,6 +592,9 @@ test/testbufferoverrun.o: test/testbufferoverrun.cpp externals/tinyxml/tinyxml2. test/testcharvar.o: test/testcharvar.cpp lib/check.h lib/checkother.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testcharvar.o test/testcharvar.cpp +test/testclangastdump.o: test/testclangastdump.cpp lib/clangastdump.h lib/config.h lib/errorlogger.h lib/suppressions.h test/testsuite.h + $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testclangastdump.o test/testclangastdump.cpp + test/testclass.o: test/testclass.cpp externals/tinyxml/tinyxml2.h lib/check.h lib/checkclass.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testclass.o test/testclass.cpp diff --git a/lib/clangastdump.cpp b/lib/clangastdump.cpp index a29a21602..bf875daf5 100644 --- a/lib/clangastdump.cpp +++ b/lib/clangastdump.cpp @@ -376,6 +376,7 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList) Token *eq = addtoken(tokenList, "="); eq->astOperand1(vartok2); eq->astOperand2(children.back()->createTokens(tokenList)); + addtoken(tokenList, ";"); } return nullptr; } diff --git a/test/testclangastdump.cpp b/test/testclangastdump.cpp new file mode 100644 index 000000000..fde62d0bc --- /dev/null +++ b/test/testclangastdump.cpp @@ -0,0 +1,81 @@ +// Cppcheck - A tool for static C/C++ code analysis +// Copyright (C) 2007-2019 Cppcheck team. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "clangastdump.h" +#include "settings.h" +#include "tokenize.h" +#include "testsuite.h" + + +class TestClangAstDump: public TestFixture { +public: + TestClangAstDump() + :TestFixture("TestClangAstDump") { + } + + +private: + void run() OVERRIDE { + TEST_CASE(funcdecl1); + TEST_CASE(funcdecl2); + TEST_CASE(vardecl1); + } + + std::string parse(const char clang[]) { + Settings settings; + Tokenizer tokenizer(&settings, this); + std::istringstream istr(clang); + clangastdump::parseClangAstDump(&tokenizer, istr); + return tokenizer.tokens()->stringifyList(true, false, false, true, false); + } + + + void funcdecl1() { + const char clang[] = "`-FunctionDecl 0x3122c30 <1.c:1:1, col:22> col:6 foo 'void (int, int)'\n" + " |-ParmVarDecl 0x3122ae0 col:14 x 'int'\n" + " `-ParmVarDecl 0x3122b58 col:21 y 'int'"; + ASSERT_EQUALS("void foo ( int x@1 , int y@2 ) ;", parse(clang)); + } + + void funcdecl2() { + const char clang[] = "`-FunctionDecl 0x24b2c38 <1.c:1:1, line:4:1> line:1:5 foo 'int (int, int)'\n" + " |-ParmVarDecl 0x24b2ae0 col:13 used x 'int'\n" + " |-ParmVarDecl 0x24b2b58 col:20 used y 'int'\n" + " `-CompoundStmt 0x24b2de8 \n" + " `-ReturnStmt 0x24b2dd0 \n" + " `-BinaryOperator 0x24b2da8 'int' '/'\n" + " |-ImplicitCastExpr 0x24b2d78 'int' \n" + " | `-DeclRefExpr 0x24b2d28 'int' lvalue ParmVar 0x24b2ae0 'x' 'int'\n" + " `-ImplicitCastExpr 0x24b2d90 'int' \n" + " `-DeclRefExpr 0x24b2d50 'int' lvalue ParmVar 0x24b2b58 'y' 'int'"; + ASSERT_EQUALS("int foo ( int x@1 , int y@2 ) {\n\n" + "return x@1 / y@2 ; }", parse(clang)); + } + + void vardecl1() { + const char clang[] = "|-VarDecl 0x32b8aa0 <1.c:1:1, col:9> col:5 used a 'int' cinit\n" + "| `-IntegerLiteral 0x32b8b40 'int' 1\n" + "`-VarDecl 0x32b8b78 col:5 b 'int' cinit\n" + " `-ImplicitCastExpr 0x32b8c00 'int' \n" + " `-DeclRefExpr 0x32b8bd8 'int' lvalue Var 0x32b8aa0 'a' 'int'"; + + ASSERT_EQUALS("int a@1 ; a@1 = 1 ;\n" + "int b@2 ; b@2 = a@1 ;", + parse(clang)); + } +}; + +REGISTER_TEST(TestClangAstDump)