From 98483659784e1130693cf0981bb12cb7f6c700ce Mon Sep 17 00:00:00 2001 From: Szymon Tomasz Stefanek Date: Sun, 28 Jan 2018 03:52:55 +0100 Subject: [PATCH 1/4] CXX: Improve parsing of brackets: avoid confusing certain function declarations with variable initializations --- parsers/cxx/cxx_parser_block.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/parsers/cxx/cxx_parser_block.c b/parsers/cxx/cxx_parser_block.c index b6df123c6b..8cf55987db 100644 --- a/parsers/cxx/cxx_parser_block.c +++ b/parsers/cxx/cxx_parser_block.c @@ -60,14 +60,28 @@ bool cxxParserParseBlockHandleOpeningBracket(void) // Class::Class() : member { arg1, arg2, ... } { (4) cxxTokenTypeIs(g_cxx.pToken->pPrev,CXXTokenTypeIdentifier) && ( + // case 1 (!g_cxx.pToken->pPrev->pPrev) || - (cxxTokenTypeIsOneOf( + // case 4 + cxxTokenTypeIsOneOf( g_cxx.pToken->pPrev->pPrev, - CXXTokenTypeIdentifier | CXXTokenTypeStar | CXXTokenTypeAnd | - CXXTokenTypeGreaterThanSign | CXXTokenTypeKeyword | - // FIXME: This check could be made stricter? CXXTokenTypeSingleColon | CXXTokenTypeComma - )) + ) || + // cases 1,2,3 but not 4 + ( + // more parts of typename or maybe the "new" keyword before the identifier + cxxTokenTypeIsOneOf( + g_cxx.pToken->pPrev->pPrev, + CXXTokenTypeIdentifier | CXXTokenTypeStar | CXXTokenTypeAnd | + CXXTokenTypeGreaterThanSign | CXXTokenTypeKeyword + ) && + // but no parenthesis (discard things like bool test() Q_DECL_NO_THROW { ... }) + (!(pAux = cxxTokenChainPreviousTokenOfType( + g_cxx.pToken->pPrev->pPrev, + CXXTokenTypeParenthesisChain + )) + ) + ) ) && // "override" is handled as identifier since it's a keyword only after function signatures (strcmp(vStringValue(g_cxx.pToken->pPrev->pszWord),"override") != 0) From 9884559fd65c63f78cd42d176c47bc4901842241 Mon Sep 17 00:00:00 2001 From: Szymon Tomasz Stefanek Date: Sun, 28 Jan 2018 03:53:09 +0100 Subject: [PATCH 2/4] CXX: Improve parsing of brackets: add unit tests --- Units/parser-cxx.r/brackets.cpp.d/expected.tags | 9 +++++++++ Units/parser-cxx.r/brackets.cpp.d/input.cpp | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/Units/parser-cxx.r/brackets.cpp.d/expected.tags b/Units/parser-cxx.r/brackets.cpp.d/expected.tags index ab48e75ff2..b1e978591b 100644 --- a/Units/parser-cxx.r/brackets.cpp.d/expected.tags +++ b/Units/parser-cxx.r/brackets.cpp.d/expected.tags @@ -1,3 +1,4 @@ +EMPTY_MACRO input.cpp /^#define EMPTY_MACRO$/;" macro file: n01 input.cpp /^namespace n01 {$/;" namespace file: g01 input.cpp /^ std::string g01 { "" };$/;" variable namespace:n01 typeref:typename:std::string f01 input.cpp /^ auto f01(std::string p01) -> std::string {$/;" function namespace:n01 typeref:typename:std::string signature:(std::string p01) @@ -14,3 +15,11 @@ C01 input.cpp /^ C01()$/;" function class:n01::C01 file: signature:() l03 input.cpp /^ std::string l03 { "" };$/;" local function:n01::C01::C01 typeref:typename:std::string file: l04 input.cpp /^ std::string l04 { "" };$/;" local function:n01::C01::C01 typeref:typename:std::string file: l05 input.cpp /^ C01 l05{ "" };$/;" local function:n01::C01::C01 typeref:typename:C01 file: +f02 input.cpp /^ std::string f02() const EMPTY_MACRO { }$/;" function class:n01::C01 typeref:typename:std::string file: signature:() const +m04 input.cpp /^ int m04 { 0 };$/;" member class:n01::C01 typeref:typename:int file: +f03 input.cpp /^ std::string f03() const EMPTY_MACRO { }$/;" function class:n01::C01 typeref:typename:std::string file: signature:() const +f04 input.cpp /^ std::string f04() const EMPTY_MACRO { }$/;" function class:n01::C01 typeref:typename:std::string file: signature:() const +m05 input.cpp /^ int m05 { 0 };$/;" member class:n01::C01 typeref:typename:int file: +f05 input.cpp /^ std::string f05() const EMPTY_MACRO { }$/;" function class:n01::C01 typeref:typename:std::string file: signature:() const +f06 input.cpp /^ std::string f06() const { }$/;" function class:n01::C01 typeref:typename:std::string file: signature:() const +f07 input.cpp /^ std::string f07() { }$/;" function class:n01::C01 typeref:typename:std::string file: signature:() diff --git a/Units/parser-cxx.r/brackets.cpp.d/input.cpp b/Units/parser-cxx.r/brackets.cpp.d/input.cpp index dfae794639..da485af348 100644 --- a/Units/parser-cxx.r/brackets.cpp.d/input.cpp +++ b/Units/parser-cxx.r/brackets.cpp.d/input.cpp @@ -3,6 +3,8 @@ #include #include +#define EMPTY_MACRO + namespace n01 { std::string g01 { "" }; @@ -45,6 +47,17 @@ namespace n01 { std::string l04 { "" }; C01 l05{ "" }; } + + std::string f02() const EMPTY_MACRO { } + int m04 { 0 }; + + std::string f03() const EMPTY_MACRO { } + std::string f04() const EMPTY_MACRO { } + int m05 { 0 }; + + std::string f05() const EMPTY_MACRO { } + std::string f06() const { } + std::string f07() { } }; } From 6024c5c509aa5766da74ffd6c531f1aa8fcd0e1d Mon Sep 17 00:00:00 2001 From: Szymon Tomasz Stefanek Date: Sun, 28 Jan 2018 04:34:24 +0100 Subject: [PATCH 3/4] CXX: Do not attempt to extract multiple variable declarations after the first one when templates are present on the right hand side of the assignment: commas are likely to mess it up, it's very hard to get it right and the gain is close to zero. --- parsers/cxx/cxx_parser_variable.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/parsers/cxx/cxx_parser_variable.c b/parsers/cxx/cxx_parser_variable.c index 8ecd39be0d..7c161347e1 100644 --- a/parsers/cxx/cxx_parser_variable.c +++ b/parsers/cxx/cxx_parser_variable.c @@ -710,15 +710,24 @@ bool cxxParserExtractVariableDeclarations(CXXTokenChain * pChain,unsigned int uF CXXTokenTypeComma | CXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket )) { + // look for it, but also check for "<" signs: these usually indicate an uncondensed + // template. We give up on them as they are too complicated in this context. + // It's rather unlikely to have multiple declarations with templates after the first one t = cxxTokenChainNextTokenOfType( t, - CXXTokenTypeComma | CXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket + CXXTokenTypeComma | CXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket | + CXXTokenTypeSmallerThanSign ); if(!t) { CXX_DEBUG_LEAVE_TEXT("Didn't find a comma, semicolon or {"); return bGotVariable; } + if(cxxTokenTypeIs(t,CXXTokenTypeSmallerThanSign)) + { + CXX_DEBUG_LEAVE_TEXT("Found '<': probably a template on the right side of declaration"); + return bGotVariable; + } } if(cxxTokenTypeIsOneOf(t,CXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket)) From 322b7e8f673f744f3e675dfc54c4c0df861c44e7 Mon Sep 17 00:00:00 2001 From: Szymon Tomasz Stefanek Date: Sun, 28 Jan 2018 04:39:22 +0100 Subject: [PATCH 4/4] CXX: Add unit test for templates on the right side of a variable declaration --- Units/parser-cxx.r/variable-declarations.cpp.d/expected.tags | 1 + Units/parser-cxx.r/variable-declarations.cpp.d/input.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Units/parser-cxx.r/variable-declarations.cpp.d/expected.tags b/Units/parser-cxx.r/variable-declarations.cpp.d/expected.tags index f39e4f2e89..db83474937 100644 --- a/Units/parser-cxx.r/variable-declarations.cpp.d/expected.tags +++ b/Units/parser-cxx.r/variable-declarations.cpp.d/expected.tags @@ -29,6 +29,7 @@ l28 input.cpp /^ int l28 {};$/;" l function:main typeref:typename:int file: l29 input.cpp /^ bool l29 { false };$/;" l function:main typeref:typename:bool file: l30 input.cpp /^ std::string * l30{ new std::string("test") };$/;" l function:main typeref:typename:std::string * file: l31 input.cpp /^ std::string * l31(new std::string("test"));$/;" l function:main typeref:typename:std::string * file: +l32 input.cpp /^ auto l32 = new std::basic_string, std::allocator >;$/;" l function:main typeref:typename:auto file: m01 input.cpp /^ unsigned int m01;$/;" m struct:Struct1 typeref:typename:unsigned int file: m02 input.cpp /^ std::string m02;$/;" m struct:Struct1 typeref:typename:std::string file: m03 input.cpp /^ std::string ** m03, m04;$/;" m struct:Struct1 typeref:typename:std::string ** file: diff --git a/Units/parser-cxx.r/variable-declarations.cpp.d/input.cpp b/Units/parser-cxx.r/variable-declarations.cpp.d/input.cpp index 05f10a9c01..229c532d5c 100644 --- a/Units/parser-cxx.r/variable-declarations.cpp.d/input.cpp +++ b/Units/parser-cxx.r/variable-declarations.cpp.d/input.cpp @@ -66,6 +66,8 @@ int main(int argc,char ** argv) std::string * l30{ new std::string("test") }; std::string * l31(new std::string("test")); + auto l32 = new std::basic_string, std::allocator >; + return 0; }