From 641863c2647c21abb36aedc40ac93e6cc478f920 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Tue, 30 Jun 2015 23:15:09 +0200 Subject: [PATCH 1/4] c++: Fix handling of the `final` contextual keyword `final` is not a normal keyword, as it only have a special meaning in some specific context. So, use a special case instead of a keyword not to break identifiers of that name. --- tagmanager/ctags/c.c | 19 ++++++++++--------- tests/ctags/Makefile.am | 1 + tests/ctags/cxx11-final.cpp | 23 +++++++++++++++++++++++ tests/ctags/cxx11-final.cpp.tags | 9 +++++++++ 4 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 tests/ctags/cxx11-final.cpp create mode 100644 tests/ctags/cxx11-final.cpp.tags diff --git a/tagmanager/ctags/c.c b/tagmanager/ctags/c.c index 4f35860b..739f47de 100644 --- a/tagmanager/ctags/c.c +++ b/tagmanager/ctags/c.c @@ -425,7 +425,7 @@ static const keywordDesc KeywordTable [] = { { "extends", KEYWORD_EXTENDS, { 0, 0, 0, 1, 1, 0, 0 } }, { "extern", KEYWORD_EXTERN, { 1, 1, 1, 0, 1, 1, 0 } }, { "extern", KEYWORD_NAMESPACE, { 0, 0, 0, 0, 0, 0, 1 } }, /* parse block */ - { "final", KEYWORD_FINAL, { 0, 1, 0, 1, 0, 0, 1 } }, + { "final", KEYWORD_FINAL, { 0, 0, 0, 1, 0, 0, 1 } }, { "finally", KEYWORD_FINALLY, { 0, 0, 0, 0, 0, 1, 1 } }, { "float", KEYWORD_FLOAT, { 1, 1, 1, 1, 0, 1, 1 } }, { "for", KEYWORD_FOR, { 1, 1, 1, 1, 0, 1, 1 } }, @@ -2969,7 +2969,15 @@ static void tagCheck (statementInfo *const st) tokenInfo *name_token = (tokenInfo *)prev; boolean free_name_token = FALSE; - if (isType (name_token, TOKEN_NAME)) + /* C++ 11 allows class final { ... } */ + if (isLanguage (Lang_cpp) && isType (prev, TOKEN_NAME) && + strcmp("final", vStringValue(prev->name)) == 0 && + isType(prev2, TOKEN_NAME)) + { + name_token = (tokenInfo *)prev2; + copyToken (st->blockName, name_token); + } + else if (isType (name_token, TOKEN_NAME)) { if (!isLanguage (Lang_vala)) copyToken (st->blockName, name_token); @@ -2994,13 +3002,6 @@ static void tagCheck (statementInfo *const st) } } } - /* C++ 11 allows class final { ... } */ - else if (isLanguage (Lang_cpp) && isType (prev, TOKEN_KEYWORD) && - prev->keyword == KEYWORD_FINAL && isType(prev2, TOKEN_NAME)) - { - name_token = (tokenInfo *)prev2; - copyToken (st->blockName, name_token); - } else if (isLanguage (Lang_csharp)) makeTag (prev, st, FALSE, TAG_PROPERTY); else diff --git a/tests/ctags/Makefile.am b/tests/ctags/Makefile.am index 865f8509..6a0a97d8 100644 --- a/tests/ctags/Makefile.am +++ b/tests/ctags/Makefile.am @@ -132,6 +132,7 @@ test_sources = \ cython_sample.pyx \ cython_sample2.pyx \ cxx11enum.cpp \ + cxx11-final.cpp \ db-trig.sql \ debian_432872.f90 \ directives.c \ diff --git a/tests/ctags/cxx11-final.cpp b/tests/ctags/cxx11-final.cpp new file mode 100644 index 00000000..fa7894f6 --- /dev/null +++ b/tests/ctags/cxx11-final.cpp @@ -0,0 +1,23 @@ +class Base +{ +public: + virtual void foo() = 0; +}; + +class Derived final : public Base +{ + virtual void foo(); + virtual void final(); +}; + +void Base::foo() +{ +} + +void Derived::foo() +{ +} + +void Derived::final() +{ +} diff --git a/tests/ctags/cxx11-final.cpp.tags b/tests/ctags/cxx11-final.cpp.tags new file mode 100644 index 00000000..e82e4f1b --- /dev/null +++ b/tests/ctags/cxx11-final.cpp.tags @@ -0,0 +1,9 @@ +# format=tagmanager +BaseÌ1Ö0 +DerivedÌ1Ö0 +finalÌ16Í()ÎDerivedÖ0Ïvoid +finalÌ1024Í()ÎDerivedÖ0Ïvirtual void +fooÌ16Í()ÎBaseÖ0Ïvoid +fooÌ16Í()ÎDerivedÖ0Ïvoid +fooÌ1024Í()ÎBaseÖ0Ïvirtual void +fooÌ1024Í()ÎDerivedÖ0Ïvirtual void From 95a0d4db7e2188a62cf7770496ee2a51591f1962 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Tue, 30 Jun 2015 14:40:55 +0200 Subject: [PATCH 2/4] c++: Properly parse C++11 override and final members As `override` and `final` aren't real keywords, handle them manually not to break identifiers of those names. --- tagmanager/ctags/c.c | 8 +++++++- tests/ctags/Makefile.am | 1 + tests/ctags/cxx11-final.cpp | 2 +- tests/ctags/cxx11-override.cpp | 23 +++++++++++++++++++++++ tests/ctags/cxx11-override.cpp.tags | 9 +++++++++ 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 tests/ctags/cxx11-override.cpp create mode 100644 tests/ctags/cxx11-override.cpp.tags diff --git a/tagmanager/ctags/c.c b/tagmanager/ctags/c.c index 739f47de..28b4d357 100644 --- a/tagmanager/ctags/c.c +++ b/tagmanager/ctags/c.c @@ -2262,7 +2262,13 @@ static boolean skipPostArgumentStuff (statementInfo *const st, break; default: - if (isType (token, TOKEN_NONE)) + /* "override" and "final" are only keywords in the declaration of a virtual + * member function, so need to be handled specially, not as keywords */ + if (isLanguage(Lang_cpp) && isType (token, TOKEN_NAME) && + (strcmp ("override", vStringValue (token->name)) == 0 || + strcmp ("final", vStringValue (token->name)) == 0)) + ; + else if (isType (token, TOKEN_NONE)) ; else if (info->isKnrParamList && info->parameterCount > 0) ++elementCount; diff --git a/tests/ctags/Makefile.am b/tests/ctags/Makefile.am index 6a0a97d8..d3d08ba2 100644 --- a/tests/ctags/Makefile.am +++ b/tests/ctags/Makefile.am @@ -133,6 +133,7 @@ test_sources = \ cython_sample2.pyx \ cxx11enum.cpp \ cxx11-final.cpp \ + cxx11-override.cpp \ db-trig.sql \ debian_432872.f90 \ directives.c \ diff --git a/tests/ctags/cxx11-final.cpp b/tests/ctags/cxx11-final.cpp index fa7894f6..099d1385 100644 --- a/tests/ctags/cxx11-final.cpp +++ b/tests/ctags/cxx11-final.cpp @@ -6,7 +6,7 @@ public: class Derived final : public Base { - virtual void foo(); + virtual void foo() final; virtual void final(); }; diff --git a/tests/ctags/cxx11-override.cpp b/tests/ctags/cxx11-override.cpp new file mode 100644 index 00000000..069bb488 --- /dev/null +++ b/tests/ctags/cxx11-override.cpp @@ -0,0 +1,23 @@ +class Base +{ +public: + virtual void foo() = 0; +}; + +class Derived : public Base +{ + virtual void foo() override; + virtual void override(); +}; + +void Base::foo() +{ +} + +void Derived::foo() +{ +} + +void Derived::override() +{ +} diff --git a/tests/ctags/cxx11-override.cpp.tags b/tests/ctags/cxx11-override.cpp.tags new file mode 100644 index 00000000..1bdac7f6 --- /dev/null +++ b/tests/ctags/cxx11-override.cpp.tags @@ -0,0 +1,9 @@ +# format=tagmanager +BaseÌ1Ö0 +DerivedÌ1Ö0 +fooÌ16Í()ÎBaseÖ0Ïvoid +fooÌ16Í()ÎDerivedÖ0Ïvoid +fooÌ1024Í()ÎBaseÖ0Ïvirtual void +fooÌ1024Í()ÎDerivedÖ0Ïvirtual void +overrideÌ16Í()ÎDerivedÖ0Ïvoid +overrideÌ1024Í()ÎDerivedÖ0Ïvirtual void From f60b31385e4da74d3b926c8e0c8f97c00a508d7b Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 1 Jul 2015 03:21:04 +0200 Subject: [PATCH 3/4] c++: Handle C++11 noexcept --- tagmanager/ctags/c.c | 4 +++- tests/ctags/Makefile.am | 1 + tests/ctags/cxx11-noexcept.cpp | 7 +++++++ tests/ctags/cxx11-noexcept.cpp.tags | 5 +++++ 4 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tests/ctags/cxx11-noexcept.cpp create mode 100644 tests/ctags/cxx11-noexcept.cpp.tags diff --git a/tagmanager/ctags/c.c b/tagmanager/ctags/c.c index 28b4d357..6955628c 100644 --- a/tagmanager/ctags/c.c +++ b/tagmanager/ctags/c.c @@ -76,7 +76,7 @@ typedef enum eKeywordId KEYWORD_LOCAL, KEYWORD_LONG, KEYWORD_M_BAD_STATE, KEYWORD_M_BAD_TRANS, KEYWORD_M_STATE, KEYWORD_M_TRANS, KEYWORD_MODULE, KEYWORD_MUTABLE, - KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NEWCOV, KEYWORD_NATIVE, + KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NEWCOV, KEYWORD_NATIVE, KEYWORD_NOEXCEPT, KEYWORD_OPERATOR, KEYWORD_OUT, KEYWORD_OUTPUT, KEYWORD_OVERLOAD, KEYWORD_OVERRIDE, KEYWORD_PACKED, KEYWORD_PORT, KEYWORD_PACKAGE, KEYWORD_PRIVATE, KEYWORD_PROGRAM, KEYWORD_PROTECTED, KEYWORD_PUBLIC, @@ -457,6 +457,7 @@ static const keywordDesc KeywordTable [] = { { "native", KEYWORD_NATIVE, { 0, 0, 0, 1, 0, 0, 0 } }, { "new", KEYWORD_NEW, { 0, 1, 1, 1, 0, 1, 1 } }, { "newcov", KEYWORD_NEWCOV, { 0, 0, 0, 0, 1, 0, 0 } }, + { "noexcept", KEYWORD_NOEXCEPT, { 0, 1, 0, 0, 0, 0, 0 } }, { "operator", KEYWORD_OPERATOR, { 0, 1, 1, 0, 0, 0, 0 } }, { "out", KEYWORD_OUT, { 0, 0, 0, 0, 0, 1, 1 } }, { "output", KEYWORD_OUTPUT, { 0, 0, 0, 0, 1, 0, 0 } }, @@ -2242,6 +2243,7 @@ static boolean skipPostArgumentStuff (statementInfo *const st, case KEYWORD_ATTRIBUTE: skipParens (); break; case KEYWORD_THROW: skipParens (); break; case KEYWORD_CONST: break; + case KEYWORD_NOEXCEPT: break; case KEYWORD_TRY: break; case KEYWORD_VOLATILE: break; diff --git a/tests/ctags/Makefile.am b/tests/ctags/Makefile.am index d3d08ba2..5b6adf0e 100644 --- a/tests/ctags/Makefile.am +++ b/tests/ctags/Makefile.am @@ -133,6 +133,7 @@ test_sources = \ cython_sample2.pyx \ cxx11enum.cpp \ cxx11-final.cpp \ + cxx11-noexcept.cpp \ cxx11-override.cpp \ db-trig.sql \ debian_432872.f90 \ diff --git a/tests/ctags/cxx11-noexcept.cpp b/tests/ctags/cxx11-noexcept.cpp new file mode 100644 index 00000000..a807beb6 --- /dev/null +++ b/tests/ctags/cxx11-noexcept.cpp @@ -0,0 +1,7 @@ +class Base +{ +public: + virtual void foo() noexcept = 0; + virtual void bar() const noexcept = 0; + int baz() noexcept { return 42; } +}; diff --git a/tests/ctags/cxx11-noexcept.cpp.tags b/tests/ctags/cxx11-noexcept.cpp.tags new file mode 100644 index 00000000..1b32b9e8 --- /dev/null +++ b/tests/ctags/cxx11-noexcept.cpp.tags @@ -0,0 +1,5 @@ +# format=tagmanager +BaseÌ1Ö0 +barÌ1024Í()ÎBaseÖ0Ïvirtual void +bazÌ16Í()ÎBaseÖ0Ïint +fooÌ1024Í()ÎBaseÖ0Ïvirtual void From 4476ed9c4b238072f52cefd7baf93f725048cde1 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 1 Jul 2015 03:30:29 +0200 Subject: [PATCH 4/4] c++: Add a small test combining various C++14 things --- tests/ctags/Makefile.am | 1 + tests/ctags/cxx14-combined.cpp | 8 ++++++++ tests/ctags/cxx14-combined.cpp.tags | 6 ++++++ 3 files changed, 15 insertions(+) create mode 100644 tests/ctags/cxx14-combined.cpp create mode 100644 tests/ctags/cxx14-combined.cpp.tags diff --git a/tests/ctags/Makefile.am b/tests/ctags/Makefile.am index 5b6adf0e..18c09339 100644 --- a/tests/ctags/Makefile.am +++ b/tests/ctags/Makefile.am @@ -135,6 +135,7 @@ test_sources = \ cxx11-final.cpp \ cxx11-noexcept.cpp \ cxx11-override.cpp \ + cxx14-combined.cpp \ db-trig.sql \ debian_432872.f90 \ directives.c \ diff --git a/tests/ctags/cxx14-combined.cpp b/tests/ctags/cxx14-combined.cpp new file mode 100644 index 00000000..df1a8536 --- /dev/null +++ b/tests/ctags/cxx14-combined.cpp @@ -0,0 +1,8 @@ +struct Base { + virtual void baz() const throw() = 0; +}; + +struct Foo final : public Base { + static constexpr auto bar() noexcept { return 1; } + virtual void baz() const throw() final override; +}; diff --git a/tests/ctags/cxx14-combined.cpp.tags b/tests/ctags/cxx14-combined.cpp.tags new file mode 100644 index 00000000..9852e857 --- /dev/null +++ b/tests/ctags/cxx14-combined.cpp.tags @@ -0,0 +1,6 @@ +# format=tagmanager +BaseÌ2048Ö0 +FooÌ2048Ö0 +barÌ16Í()ÎFooÖ0Ïconstexpr +bazÌ1024Í()ÎBaseÖ0Ïvirtual void +bazÌ1024Í()ÎFooÖ0Ïvirtual void