From ef67b47e61a1a5f6258e7034ddb520a57b0a477e Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 20 Jan 2016 12:19:13 +0300 Subject: [PATCH 1/3] Prevent C++ static_assert from stopping parsing Manual cherry-pick of https://github.com/geany/geany/commit/fa0f92def2bf584ed1f6ae836e509f38324f8b6c --- c.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/c.c b/c.c index c40cc42..6bc8b76 100644 --- a/c.c +++ b/c.c @@ -83,7 +83,7 @@ typedef enum eKeywordId { KEYWORD_PROGRAM, KEYWORD_PROTECTED, KEYWORD_PUBLIC, KEYWORD_REGISTER, KEYWORD_RETURN, KEYWORD_SHADOW, KEYWORD_STATE, - KEYWORD_SHORT, KEYWORD_SIGNED, KEYWORD_STATIC, KEYWORD_STRING, + KEYWORD_SHORT, KEYWORD_SIGNED, KEYWORD_STATIC, KEYWORD_STATIC_ASSERT, KEYWORD_STRING, KEYWORD_STRUCT, KEYWORD_SWITCH, KEYWORD_SYNCHRONIZED, KEYWORD_TASK, KEYWORD_TEMPLATE, KEYWORD_THIS, KEYWORD_THROW, KEYWORD_THROWS, KEYWORD_TRANSIENT, KEYWORD_TRANS, KEYWORD_TRANSITION, @@ -437,6 +437,7 @@ static const keywordDesc KeywordTable [] = { { "signed", KEYWORD_SIGNED, { 1, 1, 0, 0, 0 } }, { "state", KEYWORD_STATE, { 0, 0, 0, 0, 1 } }, { "static", KEYWORD_STATIC, { 1, 1, 1, 1, 1 } }, + { "static_assert", KEYWORD_STATIC_ASSERT, { 0, 1, 0, 0, 0} }, { "string", KEYWORD_STRING, { 0, 0, 1, 0, 1 } }, { "struct", KEYWORD_STRUCT, { 1, 1, 1, 0, 0 } }, { "switch", KEYWORD_SWITCH, { 1, 1, 1, 1, 0 } }, @@ -1764,6 +1765,7 @@ static void processToken (tokenInfo *const token, statementInfo *const st) case KEYWORD_RETURN: skipStatement (st); break; case KEYWORD_SHORT: st->declaration = DECL_BASE; break; case KEYWORD_SIGNED: st->declaration = DECL_BASE; break; + case KEYWORD_STATIC_ASSERT: skipParens(); break; case KEYWORD_STRING: st->declaration = DECL_BASE; break; case KEYWORD_STRUCT: st->declaration = DECL_STRUCT; break; case KEYWORD_TASK: st->declaration = DECL_TASK; break; From 3a843374f200b80b7e155059cd4e73171597880d Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 20 Jan 2016 12:21:26 +0300 Subject: [PATCH 2/3] c++: Handle C++11 noexcept Manual cherry-pick of https://github.com/geany/geany/commit/f60b31385e4da74d3b926c8e0c8f97c00a508d7b --- c.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/c.c b/c.c index 6bc8b76..0dd84d7 100644 --- a/c.c +++ b/c.c @@ -77,7 +77,7 @@ typedef enum eKeywordId { KEYWORD_LOCAL, KEYWORD_LONG, KEYWORD_M_BAD_STATE, KEYWORD_M_BAD_TRANS, KEYWORD_M_STATE, KEYWORD_M_TRANS, KEYWORD_MUTABLE, - KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NEWCOV, KEYWORD_NATIVE, + KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NEWCOV, KEYWORD_NATIVE, KEYWORD_NOEXCEPT, KEYWORD_OPERATOR, KEYWORD_OUTPUT, KEYWORD_OVERLOAD, KEYWORD_OVERRIDE, KEYWORD_PACKED, KEYWORD_PORT, KEYWORD_PACKAGE, KEYWORD_PRIVATE, KEYWORD_PROGRAM, KEYWORD_PROTECTED, KEYWORD_PUBLIC, @@ -419,6 +419,7 @@ static const keywordDesc KeywordTable [] = { { "native", KEYWORD_NATIVE, { 0, 0, 0, 1, 0 } }, { "new", KEYWORD_NEW, { 0, 1, 1, 1, 0 } }, { "newcov", KEYWORD_NEWCOV, { 0, 0, 0, 0, 1 } }, + { "noexcept", KEYWORD_NOEXCEPT, { 0, 1, 0, 0, 0 } }, { "operator", KEYWORD_OPERATOR, { 0, 1, 1, 0, 0 } }, { "output", KEYWORD_OUTPUT, { 0, 0, 0, 0, 1 } }, { "overload", KEYWORD_OVERLOAD, { 0, 1, 0, 0, 0 } }, @@ -1967,6 +1968,7 @@ static boolean skipPostArgumentStuff ( case KEYWORD_NAMESPACE: case KEYWORD_NEW: case KEYWORD_NEWCOV: + case KEYWORD_NOEXCEPT: case KEYWORD_OPERATOR: case KEYWORD_OVERLOAD: case KEYWORD_PRIVATE: From ce27db2946ae2ebc2766138af451d7d981201134 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 20 Jan 2016 12:25:18 +0300 Subject: [PATCH 3/3] c++: Properly parse C++11 override and final members Manual cherry-pick of - https://github.com/geany/geany/commit/95a0d4db7e2188a62cf7770496ee2a51591f1962 - https://github.com/geany/geany/commit/641863c2647c21abb36aedc40ac93e6cc478f920 --- c.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/c.c b/c.c index 0dd84d7..6e8b5aa 100644 --- a/c.c +++ b/c.c @@ -1986,7 +1986,13 @@ static boolean skipPostArgumentStuff ( 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; @@ -2839,8 +2845,20 @@ static void tagCheck (statementInfo *const st) st->declaration == DECL_NAMESPACE || st->declaration == DECL_PROGRAM) { - if (isType (prev, TOKEN_NAME)) + tokenInfo *name_token = (tokenInfo *)prev; + + /* 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)) + { copyToken (st->blockName, prev); + } else { /* For an anonymous struct or union we use a unique ID