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.
This commit is contained in:
Colomban Wendling 2015-06-30 23:15:09 +02:00
parent db30fdc6ec
commit 641863c264
4 changed files with 43 additions and 9 deletions

View File

@ -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 <name> 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 <name> 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

View File

@ -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 \

View File

@ -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()
{
}

View File

@ -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