forked from qt-creator/qt-creator
Added support for override/final and enum classes
Change-Id: I6dfe9dd606781046ff5a1ed61315741d2f332cb8 Reviewed-by: Christian Kamm <christian.d.kamm@nokia.com>
This commit is contained in:
committed by
Christian Kamm
parent
656ecfbf59
commit
95c5ab2746
4
src/libs/3rdparty/cplusplus/AST.cpp
vendored
4
src/libs/3rdparty/cplusplus/AST.cpp
vendored
@@ -523,6 +523,8 @@ unsigned ClassSpecifierAST::firstToken() const
|
|||||||
if (name)
|
if (name)
|
||||||
if (unsigned candidate = name->firstToken())
|
if (unsigned candidate = name->firstToken())
|
||||||
return candidate;
|
return candidate;
|
||||||
|
if (final_token)
|
||||||
|
return final_token;
|
||||||
if (colon_token)
|
if (colon_token)
|
||||||
return colon_token;
|
return colon_token;
|
||||||
if (base_clause_list)
|
if (base_clause_list)
|
||||||
@@ -557,6 +559,8 @@ unsigned ClassSpecifierAST::lastToken() const
|
|||||||
return candidate;
|
return candidate;
|
||||||
if (colon_token)
|
if (colon_token)
|
||||||
return colon_token + 1;
|
return colon_token + 1;
|
||||||
|
if (final_token)
|
||||||
|
return final_token + 1;
|
||||||
if (name)
|
if (name)
|
||||||
if (unsigned candidate = name->lastToken())
|
if (unsigned candidate = name->lastToken())
|
||||||
return candidate;
|
return candidate;
|
||||||
|
|||||||
2
src/libs/3rdparty/cplusplus/AST.h
vendored
2
src/libs/3rdparty/cplusplus/AST.h
vendored
@@ -1168,6 +1168,7 @@ public:
|
|||||||
unsigned classkey_token;
|
unsigned classkey_token;
|
||||||
SpecifierListAST *attribute_list;
|
SpecifierListAST *attribute_list;
|
||||||
NameAST *name;
|
NameAST *name;
|
||||||
|
unsigned final_token;
|
||||||
unsigned colon_token;
|
unsigned colon_token;
|
||||||
BaseSpecifierListAST *base_clause_list;
|
BaseSpecifierListAST *base_clause_list;
|
||||||
unsigned dot_dot_dot_token;
|
unsigned dot_dot_dot_token;
|
||||||
@@ -1183,6 +1184,7 @@ public:
|
|||||||
: classkey_token(0)
|
: classkey_token(0)
|
||||||
, attribute_list(0)
|
, attribute_list(0)
|
||||||
, name(0)
|
, name(0)
|
||||||
|
, final_token(0)
|
||||||
, colon_token(0)
|
, colon_token(0)
|
||||||
, base_clause_list(0)
|
, base_clause_list(0)
|
||||||
, dot_dot_dot_token(0)
|
, dot_dot_dot_token(0)
|
||||||
|
|||||||
1
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
1
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
@@ -362,6 +362,7 @@ ClassSpecifierAST *ClassSpecifierAST::clone(MemoryPool *pool) const
|
|||||||
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
|
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
|
||||||
if (name)
|
if (name)
|
||||||
ast->name = name->clone(pool);
|
ast->name = name->clone(pool);
|
||||||
|
ast->final_token = final_token;
|
||||||
ast->colon_token = colon_token;
|
ast->colon_token = colon_token;
|
||||||
for (BaseSpecifierListAST *iter = base_clause_list, **ast_iter = &ast->base_clause_list;
|
for (BaseSpecifierListAST *iter = base_clause_list, **ast_iter = &ast->base_clause_list;
|
||||||
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
|
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
|
||||||
|
|||||||
2
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
2
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
@@ -593,6 +593,8 @@ bool ASTMatcher::match(ClassSpecifierAST *node, ClassSpecifierAST *pattern)
|
|||||||
else if (! AST::match(node->name, pattern->name, this))
|
else if (! AST::match(node->name, pattern->name, this))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
pattern->final_token = node->final_token;
|
||||||
|
|
||||||
pattern->colon_token = node->colon_token;
|
pattern->colon_token = node->colon_token;
|
||||||
|
|
||||||
if (! pattern->base_clause_list)
|
if (! pattern->base_clause_list)
|
||||||
|
|||||||
16
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
16
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
@@ -2660,6 +2660,20 @@ bool Bind::visit(TemplateIdAST *ast)
|
|||||||
bool Bind::visit(SimpleSpecifierAST *ast)
|
bool Bind::visit(SimpleSpecifierAST *ast)
|
||||||
{
|
{
|
||||||
switch (tokenKind(ast->specifier_token)) {
|
switch (tokenKind(ast->specifier_token)) {
|
||||||
|
case T_IDENTIFIER: {
|
||||||
|
const Identifier *id = tokenAt(ast->specifier_token).identifier;
|
||||||
|
if (id->isEqualTo(control()->cpp11Override())) {
|
||||||
|
if (_type.isOverride())
|
||||||
|
translationUnit()->error(ast->specifier_token, "duplicate `override'");
|
||||||
|
_type.setOverride(true);
|
||||||
|
}
|
||||||
|
else if (id->isEqualTo(control()->cpp11Final())) {
|
||||||
|
if (_type.isFinal())
|
||||||
|
translationUnit()->error(ast->specifier_token, "duplicate `final'");
|
||||||
|
_type.setFinal(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case T_CONST:
|
case T_CONST:
|
||||||
if (_type.isConst())
|
if (_type.isConst())
|
||||||
translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
|
translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
|
||||||
@@ -3106,6 +3120,8 @@ bool Bind::visit(FunctionDeclaratorAST *ast)
|
|||||||
// propagate the cv-qualifiers
|
// propagate the cv-qualifiers
|
||||||
fun->setConst(type.isConst());
|
fun->setConst(type.isConst());
|
||||||
fun->setVolatile(type.isVolatile());
|
fun->setVolatile(type.isVolatile());
|
||||||
|
fun->setOverride(type.isOverride());
|
||||||
|
fun->setFinal(type.isFinal());
|
||||||
|
|
||||||
this->exceptionSpecification(ast->exception_specification, type);
|
this->exceptionSpecification(ast->exception_specification, type);
|
||||||
if (ast->as_cpp_initializer != 0) {
|
if (ast->as_cpp_initializer != 0) {
|
||||||
|
|||||||
11
src/libs/3rdparty/cplusplus/Control.cpp
vendored
11
src/libs/3rdparty/cplusplus/Control.cpp
vendored
@@ -507,6 +507,8 @@ public:
|
|||||||
const Identifier *objcRetainId;
|
const Identifier *objcRetainId;
|
||||||
const Identifier *objcCopyId;
|
const Identifier *objcCopyId;
|
||||||
const Identifier *objcNonatomicId;
|
const Identifier *objcNonatomicId;
|
||||||
|
const Identifier *cpp11Override;
|
||||||
|
const Identifier *cpp11Final;
|
||||||
TopLevelDeclarationProcessor *processor;
|
TopLevelDeclarationProcessor *processor;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -525,6 +527,9 @@ Control::Control()
|
|||||||
d->objcRetainId = identifier("retain");
|
d->objcRetainId = identifier("retain");
|
||||||
d->objcCopyId = identifier("copy");
|
d->objcCopyId = identifier("copy");
|
||||||
d->objcNonatomicId = identifier("nonatomic");
|
d->objcNonatomicId = identifier("nonatomic");
|
||||||
|
|
||||||
|
d->cpp11Override = identifier("override");
|
||||||
|
d->cpp11Final = identifier("final");
|
||||||
}
|
}
|
||||||
|
|
||||||
Control::~Control()
|
Control::~Control()
|
||||||
@@ -764,6 +769,12 @@ const Identifier *Control::objcCopyId() const
|
|||||||
const Identifier *Control::objcNonatomicId() const
|
const Identifier *Control::objcNonatomicId() const
|
||||||
{ return d->objcNonatomicId; }
|
{ return d->objcNonatomicId; }
|
||||||
|
|
||||||
|
const Identifier *Control::cpp11Override() const
|
||||||
|
{ return d->cpp11Override; }
|
||||||
|
|
||||||
|
const Identifier *Control::cpp11Final() const
|
||||||
|
{ return d->cpp11Final; }
|
||||||
|
|
||||||
Symbol **Control::firstSymbol() const
|
Symbol **Control::firstSymbol() const
|
||||||
{
|
{
|
||||||
if (d->symbols.empty())
|
if (d->symbols.empty())
|
||||||
|
|||||||
3
src/libs/3rdparty/cplusplus/Control.h
vendored
3
src/libs/3rdparty/cplusplus/Control.h
vendored
@@ -178,6 +178,9 @@ public:
|
|||||||
const Identifier *objcRetainId() const;
|
const Identifier *objcRetainId() const;
|
||||||
const Identifier *objcCopyId() const;
|
const Identifier *objcCopyId() const;
|
||||||
const Identifier *objcNonatomicId() const;
|
const Identifier *objcNonatomicId() const;
|
||||||
|
// C++11 context keywords
|
||||||
|
const Identifier *cpp11Override() const;
|
||||||
|
const Identifier *cpp11Final() const;
|
||||||
|
|
||||||
const OperatorNameId *findOperatorNameId(OperatorNameId::Kind operatorId) const;
|
const OperatorNameId *findOperatorNameId(OperatorNameId::Kind operatorId) const;
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ FullySpecifiedType FullySpecifiedType::qualifiedType() const
|
|||||||
|
|
||||||
ty.setInline(false);
|
ty.setInline(false);
|
||||||
ty.setVirtual(false);
|
ty.setVirtual(false);
|
||||||
|
ty.setOverride(false);
|
||||||
|
ty.setFinal(false);
|
||||||
ty.setExplicit(false);
|
ty.setExplicit(false);
|
||||||
|
|
||||||
ty.setDeprecated(false);
|
ty.setDeprecated(false);
|
||||||
@@ -140,6 +142,18 @@ bool FullySpecifiedType::isVirtual() const
|
|||||||
void FullySpecifiedType::setVirtual(bool isVirtual)
|
void FullySpecifiedType::setVirtual(bool isVirtual)
|
||||||
{ f._isVirtual = isVirtual; }
|
{ f._isVirtual = isVirtual; }
|
||||||
|
|
||||||
|
bool FullySpecifiedType::isOverride() const
|
||||||
|
{ return f._isOverride; }
|
||||||
|
|
||||||
|
void FullySpecifiedType::setOverride(bool isOverride)
|
||||||
|
{ f._isOverride = isOverride; }
|
||||||
|
|
||||||
|
bool FullySpecifiedType::isFinal() const
|
||||||
|
{ return f._isFinal; }
|
||||||
|
|
||||||
|
void FullySpecifiedType::setFinal(bool isFinal)
|
||||||
|
{ f._isFinal = isFinal; }
|
||||||
|
|
||||||
bool FullySpecifiedType::isExplicit() const
|
bool FullySpecifiedType::isExplicit() const
|
||||||
{ return f._isExplicit; }
|
{ return f._isExplicit; }
|
||||||
|
|
||||||
@@ -226,6 +240,8 @@ void FullySpecifiedType::copySpecifiers(const FullySpecifiedType &type)
|
|||||||
// function specifiers
|
// function specifiers
|
||||||
f._isInline = type.f._isInline;
|
f._isInline = type.f._isInline;
|
||||||
f._isVirtual = type.f._isVirtual;
|
f._isVirtual = type.f._isVirtual;
|
||||||
|
f._isOverride = type.f._isOverride;
|
||||||
|
f._isFinal = type.f._isFinal;
|
||||||
f._isExplicit = type.f._isExplicit;
|
f._isExplicit = type.f._isExplicit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,4 +251,4 @@ bool FullySpecifiedType::match(const FullySpecifiedType &otherTy, TypeMatcher *m
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
return type()->matchType(otherTy.type(), matcher);
|
return type()->matchType(otherTy.type(), matcher);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,12 @@ public:
|
|||||||
bool isVirtual() const;
|
bool isVirtual() const;
|
||||||
void setVirtual(bool isVirtual);
|
void setVirtual(bool isVirtual);
|
||||||
|
|
||||||
|
bool isOverride() const;
|
||||||
|
void setOverride(bool isOverride);
|
||||||
|
|
||||||
|
bool isFinal() const;
|
||||||
|
void setFinal(bool isFinal);
|
||||||
|
|
||||||
bool isExplicit() const;
|
bool isExplicit() const;
|
||||||
void setExplicit(bool isExplicit);
|
void setExplicit(bool isExplicit);
|
||||||
|
|
||||||
@@ -132,6 +138,8 @@ private:
|
|||||||
// function specifiers
|
// function specifiers
|
||||||
unsigned _isInline: 1;
|
unsigned _isInline: 1;
|
||||||
unsigned _isVirtual: 1;
|
unsigned _isVirtual: 1;
|
||||||
|
unsigned _isOverride: 1;
|
||||||
|
unsigned _isFinal: 1;
|
||||||
unsigned _isExplicit: 1;
|
unsigned _isExplicit: 1;
|
||||||
|
|
||||||
// speficiers from attributes
|
// speficiers from attributes
|
||||||
|
|||||||
74
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
74
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -1178,6 +1178,40 @@ bool Parser::parseCvQualifiers(SpecifierListAST *&node)
|
|||||||
return start != cursor();
|
return start != cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Handles override and final from C++ 2011, they are pseudo keywords and has special meaning only in function declaration
|
||||||
|
*/
|
||||||
|
bool Parser::parseOverrideFinalQualifiers(SpecifierListAST *&node)
|
||||||
|
{
|
||||||
|
DEBUG_THIS_RULE();
|
||||||
|
|
||||||
|
if (!_cxx0xEnabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned start = cursor();
|
||||||
|
|
||||||
|
SpecifierListAST **ast = &node;
|
||||||
|
while (*ast)
|
||||||
|
ast = &(*ast)->next;
|
||||||
|
|
||||||
|
while (LA() == T_IDENTIFIER) {
|
||||||
|
const Identifier &id = *(_translationUnit->tokenAt(cursor()).identifier);
|
||||||
|
|
||||||
|
if (id.equalTo(_control->cpp11Override())
|
||||||
|
|| id.equalTo(_control->cpp11Final())) {
|
||||||
|
SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST;
|
||||||
|
spec->specifier_token = consumeToken();
|
||||||
|
*ast = new (_pool) SpecifierListAST(spec);
|
||||||
|
ast = &(*ast)->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (start != cursor());
|
||||||
|
}
|
||||||
|
|
||||||
bool Parser::parsePtrOperator(PtrOperatorListAST *&node)
|
bool Parser::parsePtrOperator(PtrOperatorListAST *&node)
|
||||||
{
|
{
|
||||||
DEBUG_THIS_RULE();
|
DEBUG_THIS_RULE();
|
||||||
@@ -1442,6 +1476,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specif
|
|||||||
ast->rparen_token = consumeToken();
|
ast->rparen_token = consumeToken();
|
||||||
// ### parse attributes
|
// ### parse attributes
|
||||||
parseCvQualifiers(ast->cv_qualifier_list);
|
parseCvQualifiers(ast->cv_qualifier_list);
|
||||||
|
parseOverrideFinalQualifiers(ast->cv_qualifier_list);
|
||||||
// ### parse ref-qualifiers
|
// ### parse ref-qualifiers
|
||||||
parseExceptionSpecification(ast->exception_specification);
|
parseExceptionSpecification(ast->exception_specification);
|
||||||
|
|
||||||
@@ -1572,11 +1607,26 @@ bool Parser::parseAbstractDeclarator(DeclaratorAST *&node, SpecifierListAST *dec
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads enumeration type declaration, examples:
|
||||||
|
* @code
|
||||||
|
enum {
|
||||||
|
debug = 1
|
||||||
|
};
|
||||||
|
enum class Format {
|
||||||
|
FormatPNG,
|
||||||
|
FormatJPEG
|
||||||
|
};
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
bool Parser::parseEnumSpecifier(SpecifierListAST *&node)
|
bool Parser::parseEnumSpecifier(SpecifierListAST *&node)
|
||||||
{
|
{
|
||||||
DEBUG_THIS_RULE();
|
DEBUG_THIS_RULE();
|
||||||
if (LA() == T_ENUM) {
|
if (LA() == T_ENUM) {
|
||||||
unsigned enum_token = consumeToken();
|
unsigned enum_token = consumeToken();
|
||||||
|
if (_cxx0xEnabled && LA() == T_CLASS)
|
||||||
|
consumeToken();
|
||||||
|
|
||||||
NameAST *name = 0;
|
NameAST *name = 0;
|
||||||
parseName(name);
|
parseName(name);
|
||||||
if (LA() == T_LBRACE) {
|
if (LA() == T_LBRACE) {
|
||||||
@@ -1874,9 +1924,12 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (LA(1) == T_IDENTIFIER && LA(2) == T_IDENTIFIER) {
|
if (LA(1) == T_IDENTIFIER && LA(2) == T_IDENTIFIER) {
|
||||||
warning(cursor(), "skip identifier `%s'",
|
const Identifier *id = tok(2).identifier;
|
||||||
tok().spell());
|
if (!id->equalTo(_control->cpp11Final())) {
|
||||||
consumeToken();
|
warning(cursor(), "skip identifier `%s'",
|
||||||
|
tok().spell());
|
||||||
|
consumeToken();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NameAST *name = 0;
|
NameAST *name = 0;
|
||||||
@@ -1889,6 +1942,13 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
|
|||||||
|
|
||||||
unsigned colon_token = 0;
|
unsigned colon_token = 0;
|
||||||
unsigned dot_dot_dot_token = 0;
|
unsigned dot_dot_dot_token = 0;
|
||||||
|
unsigned final_token = 0;
|
||||||
|
|
||||||
|
if (LA() == T_IDENTIFIER) {
|
||||||
|
const Identifier *id = tok().identifier;
|
||||||
|
if (id->equalTo(_control->cpp11Final()))
|
||||||
|
final_token = consumeToken();
|
||||||
|
}
|
||||||
|
|
||||||
if (LA() == T_COLON || LA() == T_LBRACE) {
|
if (LA() == T_COLON || LA() == T_LBRACE) {
|
||||||
BaseSpecifierListAST *base_clause_list = 0;
|
BaseSpecifierListAST *base_clause_list = 0;
|
||||||
@@ -1919,6 +1979,7 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
|
|||||||
ClassSpecifierAST *ast = new (_pool) ClassSpecifierAST;
|
ClassSpecifierAST *ast = new (_pool) ClassSpecifierAST;
|
||||||
ast->classkey_token = classkey_token;
|
ast->classkey_token = classkey_token;
|
||||||
ast->attribute_list = attributes;
|
ast->attribute_list = attributes;
|
||||||
|
ast->final_token = final_token;
|
||||||
ast->name = name;
|
ast->name = name;
|
||||||
ast->colon_token = colon_token;
|
ast->colon_token = colon_token;
|
||||||
ast->base_clause_list = base_clause_list;
|
ast->base_clause_list = base_clause_list;
|
||||||
@@ -3772,8 +3833,11 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
|
|||||||
} else if (! has_type_specifier && lookAtClassKey()) {
|
} else if (! has_type_specifier && lookAtClassKey()) {
|
||||||
unsigned startOfTypeSpecifier = cursor();
|
unsigned startOfTypeSpecifier = cursor();
|
||||||
if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr) ||
|
if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr) ||
|
||||||
(LA() == T_COLON || LA() == T_LBRACE || (LA(0) == T_IDENTIFIER && LA(1) == T_IDENTIFIER &&
|
(LA() == T_COLON || LA() == T_LBRACE
|
||||||
(LA(2) == T_COLON || LA(2) == T_LBRACE)))) {
|
|| (LA(0) == T_IDENTIFIER && LA(1) == T_IDENTIFIER // MACRO Name followed by : or {
|
||||||
|
&& (LA(2) == T_COLON || LA(2) == T_LBRACE))
|
||||||
|
|| (LA(0) == T_IDENTIFIER && LA(1) == T_IDENTIFIER && LA(2) == T_IDENTIFIER && // MACRO Name final followed by : or {
|
||||||
|
(LA(3) == T_COLON || LA(3) == T_LBRACE)))) {
|
||||||
rewind(startOfTypeSpecifier);
|
rewind(startOfTypeSpecifier);
|
||||||
if (! parseClassSpecifier(*decl_specifier_seq_ptr)) {
|
if (! parseClassSpecifier(*decl_specifier_seq_ptr)) {
|
||||||
error(startOfTypeSpecifier,
|
error(startOfTypeSpecifier,
|
||||||
|
|||||||
1
src/libs/3rdparty/cplusplus/Parser.h
vendored
1
src/libs/3rdparty/cplusplus/Parser.h
vendored
@@ -82,6 +82,7 @@ public:
|
|||||||
bool parseConstantExpression(ExpressionAST *&node);
|
bool parseConstantExpression(ExpressionAST *&node);
|
||||||
bool parseCtorInitializer(CtorInitializerAST *&node);
|
bool parseCtorInitializer(CtorInitializerAST *&node);
|
||||||
bool parseCvQualifiers(SpecifierListAST *&node);
|
bool parseCvQualifiers(SpecifierListAST *&node);
|
||||||
|
bool parseOverrideFinalQualifiers(SpecifierListAST *&node);
|
||||||
bool parseDeclaratorOrAbstractDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list);
|
bool parseDeclaratorOrAbstractDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list);
|
||||||
bool parseDeclaration(DeclarationAST *&node);
|
bool parseDeclaration(DeclarationAST *&node);
|
||||||
bool parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *declaringClass = 0);
|
bool parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *declaringClass = 0);
|
||||||
|
|||||||
12
src/libs/3rdparty/cplusplus/Symbols.cpp
vendored
12
src/libs/3rdparty/cplusplus/Symbols.cpp
vendored
@@ -358,6 +358,18 @@ bool Function::isVirtual() const
|
|||||||
void Function::setVirtual(bool isVirtual)
|
void Function::setVirtual(bool isVirtual)
|
||||||
{ f._isVirtual = isVirtual; }
|
{ f._isVirtual = isVirtual; }
|
||||||
|
|
||||||
|
bool Function::isOverride() const
|
||||||
|
{ return f._isOverride; }
|
||||||
|
|
||||||
|
void Function::setOverride(bool isOverride)
|
||||||
|
{ f._isOverride = isOverride; }
|
||||||
|
|
||||||
|
bool Function::isFinal() const
|
||||||
|
{ return f._isFinal; }
|
||||||
|
|
||||||
|
void Function::setFinal(bool isFinal)
|
||||||
|
{ f._isFinal = isFinal; }
|
||||||
|
|
||||||
bool Function::isVariadic() const
|
bool Function::isVariadic() const
|
||||||
{ return f._isVariadic; }
|
{ return f._isVariadic; }
|
||||||
|
|
||||||
|
|||||||
8
src/libs/3rdparty/cplusplus/Symbols.h
vendored
8
src/libs/3rdparty/cplusplus/Symbols.h
vendored
@@ -323,6 +323,12 @@ public:
|
|||||||
bool isVirtual() const;
|
bool isVirtual() const;
|
||||||
void setVirtual(bool isVirtual);
|
void setVirtual(bool isVirtual);
|
||||||
|
|
||||||
|
bool isOverride() const;
|
||||||
|
void setOverride(bool isOverride);
|
||||||
|
|
||||||
|
bool isFinal() const;
|
||||||
|
void setFinal(bool isFinal);
|
||||||
|
|
||||||
bool isVariadic() const;
|
bool isVariadic() const;
|
||||||
void setVariadic(bool isVariadic);
|
void setVariadic(bool isVariadic);
|
||||||
|
|
||||||
@@ -371,6 +377,8 @@ private:
|
|||||||
FullySpecifiedType _returnType;
|
FullySpecifiedType _returnType;
|
||||||
struct Flags {
|
struct Flags {
|
||||||
unsigned _isVirtual: 1;
|
unsigned _isVirtual: 1;
|
||||||
|
unsigned _isOverride: 1;
|
||||||
|
unsigned _isFinal: 1;
|
||||||
unsigned _isVariadic: 1;
|
unsigned _isVariadic: 1;
|
||||||
unsigned _isPureVirtual: 1;
|
unsigned _isPureVirtual: 1;
|
||||||
unsigned _isConst: 1;
|
unsigned _isConst: 1;
|
||||||
|
|||||||
@@ -134,6 +134,8 @@ private:
|
|||||||
fun->setConst(funTy->isConst());
|
fun->setConst(funTy->isConst());
|
||||||
fun->setVolatile(funTy->isVolatile());
|
fun->setVolatile(funTy->isVolatile());
|
||||||
fun->setVirtual(funTy->isVirtual());
|
fun->setVirtual(funTy->isVirtual());
|
||||||
|
fun->setOverride(funTy->isOverride());
|
||||||
|
fun->setFinal(funTy->isFinal());
|
||||||
fun->setAmbiguous(funTy->isAmbiguous());
|
fun->setAmbiguous(funTy->isAmbiguous());
|
||||||
fun->setVariadic(funTy->isVariadic());
|
fun->setVariadic(funTy->isVariadic());
|
||||||
|
|
||||||
|
|||||||
@@ -1775,6 +1775,8 @@ void CPPEditorWidget::setFontSettings(const TextEditor::FontSettings &fs)
|
|||||||
fs.toTextCharFormat(TextEditor::C_PREPROCESSOR);
|
fs.toTextCharFormat(TextEditor::C_PREPROCESSOR);
|
||||||
m_semanticHighlightFormatMap[SemanticInfo::FunctionUse] =
|
m_semanticHighlightFormatMap[SemanticInfo::FunctionUse] =
|
||||||
fs.toTextCharFormat(TextEditor::C_FUNCTION);
|
fs.toTextCharFormat(TextEditor::C_FUNCTION);
|
||||||
|
m_semanticHighlightFormatMap[SemanticInfo::PseudoKeywordUse] =
|
||||||
|
fs.toTextCharFormat(TextEditor::C_KEYWORD);
|
||||||
m_keywordFormat = fs.toTextCharFormat(TextEditor::C_KEYWORD);
|
m_keywordFormat = fs.toTextCharFormat(TextEditor::C_KEYWORD);
|
||||||
|
|
||||||
// only set the background, we do not want to modify foreground properties set by the syntax highlighter or the link
|
// only set the background, we do not want to modify foreground properties set by the syntax highlighter or the link
|
||||||
|
|||||||
@@ -506,6 +506,14 @@ bool CheckSymbols::visit(SimpleDeclarationAST *ast)
|
|||||||
decl->enclosingScope()),
|
decl->enclosingScope()),
|
||||||
nameAST, funTy->argumentCount())) {
|
nameAST, funTy->argumentCount())) {
|
||||||
declrIdNameAST = nameAST;
|
declrIdNameAST = nameAST;
|
||||||
|
|
||||||
|
// Add a diagnostic message if non-virtual function has override/final marker
|
||||||
|
if ((_usages.back().kind != SemanticInfo::VirtualMethodUse)) {
|
||||||
|
if (funTy->isOverride())
|
||||||
|
warning(declrIdNameAST, "Only virtual methods can be marked `override'");
|
||||||
|
else if (funTy->isFinal())
|
||||||
|
warning(declrIdNameAST, "Only virtual methods can be marked `final'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -952,6 +960,37 @@ bool CheckSymbols::visit(LabeledStatementAST *ast)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Highlights "override" and "final" pseudokeywords like true keywords
|
||||||
|
*/
|
||||||
|
bool CheckSymbols::visit(SimpleSpecifierAST *ast)
|
||||||
|
{
|
||||||
|
if (ast->specifier_token)
|
||||||
|
{
|
||||||
|
const Token &tk = tokenAt(ast->specifier_token);
|
||||||
|
if (tk.is(T_IDENTIFIER))
|
||||||
|
{
|
||||||
|
const Identifier &id = *(tk.identifier);
|
||||||
|
if (id.equalTo(_doc->control()->cpp11Override())
|
||||||
|
|| id.equalTo(_doc->control()->cpp11Final()))
|
||||||
|
{
|
||||||
|
addUse(ast->specifier_token, SemanticInfo::PseudoKeywordUse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckSymbols::visit(ClassSpecifierAST *ast)
|
||||||
|
{
|
||||||
|
if (ast->final_token)
|
||||||
|
addUse(ast->final_token, SemanticInfo::PseudoKeywordUse);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CheckSymbols::visit(FunctionDefinitionAST *ast)
|
bool CheckSymbols::visit(FunctionDefinitionAST *ast)
|
||||||
{
|
{
|
||||||
AST *thisFunction = _astStack.takeLast();
|
AST *thisFunction = _astStack.takeLast();
|
||||||
|
|||||||
@@ -151,6 +151,8 @@ protected:
|
|||||||
|
|
||||||
virtual bool visit(GotoStatementAST *ast);
|
virtual bool visit(GotoStatementAST *ast);
|
||||||
virtual bool visit(LabeledStatementAST *ast);
|
virtual bool visit(LabeledStatementAST *ast);
|
||||||
|
virtual bool visit(SimpleSpecifierAST *ast);
|
||||||
|
virtual bool visit(ClassSpecifierAST *ast);
|
||||||
|
|
||||||
virtual bool visit(MemInitializerAST *ast);
|
virtual bool visit(MemInitializerAST *ast);
|
||||||
virtual bool visit(EnumeratorAST *ast);
|
virtual bool visit(EnumeratorAST *ast);
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ public:
|
|||||||
VirtualMethodUse,
|
VirtualMethodUse,
|
||||||
LabelUse,
|
LabelUse,
|
||||||
MacroUse,
|
MacroUse,
|
||||||
FunctionUse
|
FunctionUse,
|
||||||
|
PseudoKeywordUse
|
||||||
};
|
};
|
||||||
typedef TextEditor::SemanticHighlighter::Result Use;
|
typedef TextEditor::SemanticHighlighter::Result Use;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user