forked from qt-creator/qt-creator
C++: fix built-in code model to work with shared_ptr on MSVC 2017
These changes target Find Usages feature to work with shared_ptr. Improve libs/3rdparty/cplusplus and plugins/cplusplus: parse __declspec() attribute, call to variadic function template without specified template arguments, if constexpr, c++11 attributes [[value]], function templates with default parameters, resolve order for function vs template with default parameter, template operator->() with default arguments, template specialization with numeric values, find best partial specialization, fix partial specialization for non-first specialized argument Fixes: QTCREATORBUG-7866 Fixes: QTCREATORBUG-20781 Fixes: QTCREATORBUG-22857 Fixes: QTCREATORBUG-17825 Change-Id: I31a080f7729edfb2ee9650f1aff48daeba5a673b Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: Nikolai Kosjar <pinaceae.pinus@gmail.com>
This commit is contained in:
44
src/libs/3rdparty/cplusplus/AST.cpp
vendored
44
src/libs/3rdparty/cplusplus/AST.cpp
vendored
@@ -73,6 +73,16 @@ int GnuAttributeSpecifierAST::firstToken() const
|
||||
return attribute_token;
|
||||
}
|
||||
|
||||
int MsvcDeclspecSpecifierAST::firstToken() const
|
||||
{
|
||||
return attribute_token;
|
||||
}
|
||||
|
||||
int StdAttributeSpecifierAST::firstToken() const
|
||||
{
|
||||
return first_lbracket_token;
|
||||
}
|
||||
|
||||
int BaseSpecifierAST::firstToken() const
|
||||
{
|
||||
if (virtual_token && access_specifier_token)
|
||||
@@ -1524,6 +1534,8 @@ int IfStatementAST::firstToken() const
|
||||
{
|
||||
if (if_token)
|
||||
return if_token;
|
||||
if (constexpr_token)
|
||||
return constexpr_token;
|
||||
if (lparen_token)
|
||||
return lparen_token;
|
||||
if (condition)
|
||||
@@ -1560,6 +1572,8 @@ int IfStatementAST::lastToken() const
|
||||
return candidate;
|
||||
if (lparen_token)
|
||||
return lparen_token + 1;
|
||||
if (constexpr_token)
|
||||
return constexpr_token + 1;
|
||||
if (if_token)
|
||||
return if_token + 1;
|
||||
return 1;
|
||||
@@ -4214,6 +4228,36 @@ int GnuAttributeSpecifierAST::lastToken() const
|
||||
return 1;
|
||||
}
|
||||
|
||||
int MsvcDeclspecSpecifierAST::lastToken() const
|
||||
{
|
||||
if (rparen_token)
|
||||
return rparen_token + 1;
|
||||
if (attribute_list)
|
||||
if (int candidate = attribute_list->lastToken())
|
||||
return candidate;
|
||||
if (lparen_token)
|
||||
return lparen_token + 1;
|
||||
if (attribute_token)
|
||||
return attribute_token + 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int StdAttributeSpecifierAST::lastToken() const
|
||||
{
|
||||
if (second_rbracket_token)
|
||||
return second_rbracket_token + 1;
|
||||
if (first_rbracket_token)
|
||||
return first_rbracket_token + 1;
|
||||
if (attribute_list)
|
||||
if (int candidate = attribute_list->lastToken())
|
||||
return candidate;
|
||||
if (second_lbracket_token)
|
||||
return second_lbracket_token + 1;
|
||||
if (first_lbracket_token)
|
||||
return first_lbracket_token + 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** \generated */
|
||||
int PointerLiteralAST::firstToken() const
|
||||
{
|
||||
|
||||
46
src/libs/3rdparty/cplusplus/AST.h
vendored
46
src/libs/3rdparty/cplusplus/AST.h
vendored
@@ -195,6 +195,7 @@ public:
|
||||
virtual LinkageSpecificationAST *asLinkageSpecification() { return nullptr; }
|
||||
virtual MemInitializerAST *asMemInitializer() { return nullptr; }
|
||||
virtual MemberAccessAST *asMemberAccess() { return nullptr; }
|
||||
virtual MsvcDeclspecSpecifierAST *asMsvcDeclspecSpecifier() { return nullptr; }
|
||||
virtual NameAST *asName() { return nullptr; }
|
||||
virtual NamedTypeSpecifierAST *asNamedTypeSpecifier() { return nullptr; }
|
||||
virtual NamespaceAST *asNamespace() { return nullptr; }
|
||||
@@ -265,6 +266,7 @@ public:
|
||||
virtual SpecifierAST *asSpecifier() { return nullptr; }
|
||||
virtual StatementAST *asStatement() { return nullptr; }
|
||||
virtual StaticAssertDeclarationAST *asStaticAssertDeclaration() { return nullptr; }
|
||||
virtual StdAttributeSpecifierAST *asStdAttributeSpecifier() { return nullptr; }
|
||||
virtual StringLiteralAST *asStringLiteral() { return nullptr; }
|
||||
virtual SwitchStatementAST *asSwitchStatement() { return nullptr; }
|
||||
virtual TemplateDeclarationAST *asTemplateDeclaration() { return nullptr; }
|
||||
@@ -475,6 +477,49 @@ protected:
|
||||
virtual bool match0(AST *, ASTMatcher *);
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT MsvcDeclspecSpecifierAST: public AttributeSpecifierAST
|
||||
{
|
||||
public:
|
||||
int attribute_token = 0;
|
||||
int lparen_token = 0;
|
||||
GnuAttributeListAST *attribute_list = nullptr;
|
||||
int rparen_token = 0;
|
||||
|
||||
public:
|
||||
virtual MsvcDeclspecSpecifierAST *asMsvcDeclspecSpecifier() { return this; }
|
||||
|
||||
virtual int firstToken() const;
|
||||
virtual int lastToken() const;
|
||||
|
||||
virtual MsvcDeclspecSpecifierAST *clone(MemoryPool *pool) const;
|
||||
|
||||
protected:
|
||||
virtual void accept0(ASTVisitor *visitor);
|
||||
virtual bool match0(AST *, ASTMatcher *);
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT StdAttributeSpecifierAST: public AttributeSpecifierAST
|
||||
{
|
||||
public:
|
||||
int first_lbracket_token = 0;
|
||||
int second_lbracket_token = 0;
|
||||
GnuAttributeListAST *attribute_list = nullptr;
|
||||
int first_rbracket_token = 0;
|
||||
int second_rbracket_token = 0;
|
||||
|
||||
public:
|
||||
virtual StdAttributeSpecifierAST *asStdAttributeSpecifier() { return this; }
|
||||
|
||||
virtual int firstToken() const;
|
||||
virtual int lastToken() const;
|
||||
|
||||
virtual StdAttributeSpecifierAST *clone(MemoryPool *pool) const;
|
||||
|
||||
protected:
|
||||
virtual void accept0(ASTVisitor *visitor);
|
||||
virtual bool match0(AST *, ASTMatcher *);
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT GnuAttributeAST: public AST
|
||||
{
|
||||
public:
|
||||
@@ -1610,6 +1655,7 @@ class CPLUSPLUS_EXPORT IfStatementAST: public StatementAST
|
||||
{
|
||||
public:
|
||||
int if_token = 0;
|
||||
int constexpr_token = 0;
|
||||
int lparen_token = 0;
|
||||
ExpressionAST *condition = nullptr;
|
||||
int rparen_token = 0;
|
||||
|
||||
26
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
26
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
@@ -81,6 +81,31 @@ GnuAttributeSpecifierAST *GnuAttributeSpecifierAST::clone(MemoryPool *pool) cons
|
||||
return ast;
|
||||
}
|
||||
|
||||
MsvcDeclspecSpecifierAST *MsvcDeclspecSpecifierAST::clone(MemoryPool *pool) const
|
||||
{
|
||||
MsvcDeclspecSpecifierAST *ast = new (pool) MsvcDeclspecSpecifierAST;
|
||||
ast->attribute_token = attribute_token;
|
||||
ast->lparen_token = lparen_token;
|
||||
for (GnuAttributeListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
|
||||
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
|
||||
*ast_iter = new (pool) GnuAttributeListAST((iter->value) ? iter->value->clone(pool) : nullptr);
|
||||
ast->rparen_token = rparen_token;
|
||||
return ast;
|
||||
}
|
||||
|
||||
StdAttributeSpecifierAST *StdAttributeSpecifierAST::clone(MemoryPool *pool) const
|
||||
{
|
||||
StdAttributeSpecifierAST *ast = new (pool) StdAttributeSpecifierAST;
|
||||
ast->first_lbracket_token = first_lbracket_token;
|
||||
ast->second_lbracket_token = second_lbracket_token;
|
||||
for (GnuAttributeListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
|
||||
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
|
||||
*ast_iter = new (pool) GnuAttributeListAST((iter->value) ? iter->value->clone(pool) : nullptr);
|
||||
ast->first_rbracket_token = first_rbracket_token;
|
||||
ast->second_rbracket_token = second_rbracket_token;
|
||||
return ast;
|
||||
}
|
||||
|
||||
GnuAttributeAST *GnuAttributeAST::clone(MemoryPool *pool) const
|
||||
{
|
||||
GnuAttributeAST *ast = new (pool) GnuAttributeAST;
|
||||
@@ -730,6 +755,7 @@ IfStatementAST *IfStatementAST::clone(MemoryPool *pool) const
|
||||
{
|
||||
IfStatementAST *ast = new (pool) IfStatementAST;
|
||||
ast->if_token = if_token;
|
||||
ast->constexpr_token = constexpr_token;
|
||||
ast->lparen_token = lparen_token;
|
||||
if (condition)
|
||||
ast->condition = condition->clone(pool);
|
||||
|
||||
16
src/libs/3rdparty/cplusplus/ASTMatch0.cpp
vendored
16
src/libs/3rdparty/cplusplus/ASTMatch0.cpp
vendored
@@ -72,6 +72,22 @@ bool GnuAttributeSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MsvcDeclspecSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||
{
|
||||
if (MsvcDeclspecSpecifierAST *_other = pattern->asMsvcDeclspecSpecifier())
|
||||
return matcher->match(this, _other);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StdAttributeSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||
{
|
||||
if (StdAttributeSpecifierAST *_other = pattern->asStdAttributeSpecifier())
|
||||
return matcher->match(this, _other);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GnuAttributeAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||
{
|
||||
if (GnuAttributeAST *_other = pattern->asGnuAttribute())
|
||||
|
||||
42
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
42
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
@@ -117,6 +117,46 @@ bool ASTMatcher::match(GnuAttributeSpecifierAST *node, GnuAttributeSpecifierAST
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTMatcher::match(MsvcDeclspecSpecifierAST *node, MsvcDeclspecSpecifierAST *pattern)
|
||||
{
|
||||
(void) node;
|
||||
(void) pattern;
|
||||
|
||||
pattern->attribute_token = node->attribute_token;
|
||||
|
||||
pattern->lparen_token = node->lparen_token;
|
||||
|
||||
if (! pattern->attribute_list)
|
||||
pattern->attribute_list = node->attribute_list;
|
||||
else if (! AST::match(node->attribute_list, pattern->attribute_list, this))
|
||||
return false;
|
||||
|
||||
pattern->rparen_token = node->rparen_token;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTMatcher::match(StdAttributeSpecifierAST *node, StdAttributeSpecifierAST *pattern)
|
||||
{
|
||||
(void) node;
|
||||
(void) pattern;
|
||||
|
||||
pattern->first_lbracket_token = node->first_lbracket_token;
|
||||
|
||||
pattern->second_lbracket_token = node->second_lbracket_token;
|
||||
|
||||
if (! pattern->attribute_list)
|
||||
pattern->attribute_list = node->attribute_list;
|
||||
else if (! AST::match(node->attribute_list, pattern->attribute_list, this))
|
||||
return false;
|
||||
|
||||
pattern->first_rbracket_token = node->first_rbracket_token;
|
||||
|
||||
pattern->second_rbracket_token = node->second_rbracket_token;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTMatcher::match(GnuAttributeAST *node, GnuAttributeAST *pattern)
|
||||
{
|
||||
(void) node;
|
||||
@@ -1246,6 +1286,8 @@ bool ASTMatcher::match(IfStatementAST *node, IfStatementAST *pattern)
|
||||
|
||||
pattern->if_token = node->if_token;
|
||||
|
||||
pattern->constexpr_token = node->constexpr_token;
|
||||
|
||||
pattern->lparen_token = node->lparen_token;
|
||||
|
||||
if (! pattern->condition)
|
||||
|
||||
2
src/libs/3rdparty/cplusplus/ASTMatcher.h
vendored
2
src/libs/3rdparty/cplusplus/ASTMatcher.h
vendored
@@ -96,6 +96,7 @@ public:
|
||||
virtual bool match(LinkageSpecificationAST *node, LinkageSpecificationAST *pattern);
|
||||
virtual bool match(MemInitializerAST *node, MemInitializerAST *pattern);
|
||||
virtual bool match(MemberAccessAST *node, MemberAccessAST *pattern);
|
||||
virtual bool match(MsvcDeclspecSpecifierAST *node, MsvcDeclspecSpecifierAST *pattern);
|
||||
virtual bool match(NamedTypeSpecifierAST *node, NamedTypeSpecifierAST *pattern);
|
||||
virtual bool match(NamespaceAST *node, NamespaceAST *pattern);
|
||||
virtual bool match(NamespaceAliasDefinitionAST *node, NamespaceAliasDefinitionAST *pattern);
|
||||
@@ -160,6 +161,7 @@ public:
|
||||
virtual bool match(SimpleSpecifierAST *node, SimpleSpecifierAST *pattern);
|
||||
virtual bool match(SizeofExpressionAST *node, SizeofExpressionAST *pattern);
|
||||
virtual bool match(StaticAssertDeclarationAST *node, StaticAssertDeclarationAST *pattern);
|
||||
virtual bool match(StdAttributeSpecifierAST *node, StdAttributeSpecifierAST *pattern);
|
||||
virtual bool match(StringLiteralAST *node, StringLiteralAST *pattern);
|
||||
virtual bool match(SwitchStatementAST *node, SwitchStatementAST *pattern);
|
||||
virtual bool match(TemplateDeclarationAST *node, TemplateDeclarationAST *pattern);
|
||||
|
||||
14
src/libs/3rdparty/cplusplus/ASTPatternBuilder.h
vendored
14
src/libs/3rdparty/cplusplus/ASTPatternBuilder.h
vendored
@@ -76,6 +76,20 @@ public:
|
||||
return ast;
|
||||
}
|
||||
|
||||
MsvcDeclspecSpecifierAST *MsvcDeclspecSpecifier(GnuAttributeListAST *attribute_list = nullptr)
|
||||
{
|
||||
MsvcDeclspecSpecifierAST *ast = new (&pool) MsvcDeclspecSpecifierAST;
|
||||
ast->attribute_list = attribute_list;
|
||||
return ast;
|
||||
}
|
||||
|
||||
StdAttributeSpecifierAST *StdAttributeSpecifier(GnuAttributeListAST *attribute_list = nullptr)
|
||||
{
|
||||
StdAttributeSpecifierAST *ast = new (&pool) StdAttributeSpecifierAST;
|
||||
ast->attribute_list = attribute_list;
|
||||
return ast;
|
||||
}
|
||||
|
||||
GnuAttributeAST *GnuAttribute(ExpressionListAST *expression_list = nullptr)
|
||||
{
|
||||
GnuAttributeAST *ast = new (&pool) GnuAttributeAST;
|
||||
|
||||
16
src/libs/3rdparty/cplusplus/ASTVisit.cpp
vendored
16
src/libs/3rdparty/cplusplus/ASTVisit.cpp
vendored
@@ -70,6 +70,22 @@ void GnuAttributeSpecifierAST::accept0(ASTVisitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void MsvcDeclspecSpecifierAST::accept0(ASTVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(attribute_list, visitor);
|
||||
}
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void StdAttributeSpecifierAST::accept0(ASTVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(attribute_list, visitor);
|
||||
}
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void GnuAttributeAST::accept0(ASTVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
|
||||
4
src/libs/3rdparty/cplusplus/ASTVisitor.h
vendored
4
src/libs/3rdparty/cplusplus/ASTVisitor.h
vendored
@@ -138,6 +138,7 @@ public:
|
||||
virtual bool visit(LinkageSpecificationAST *) { return true; }
|
||||
virtual bool visit(MemInitializerAST *) { return true; }
|
||||
virtual bool visit(MemberAccessAST *) { return true; }
|
||||
virtual bool visit(MsvcDeclspecSpecifierAST *) { return true; }
|
||||
virtual bool visit(NamedTypeSpecifierAST *) { return true; }
|
||||
virtual bool visit(NamespaceAST *) { return true; }
|
||||
virtual bool visit(NamespaceAliasDefinitionAST *) { return true; }
|
||||
@@ -202,6 +203,7 @@ public:
|
||||
virtual bool visit(SimpleSpecifierAST *) { return true; }
|
||||
virtual bool visit(SizeofExpressionAST *) { return true; }
|
||||
virtual bool visit(StaticAssertDeclarationAST *) { return true; }
|
||||
virtual bool visit(StdAttributeSpecifierAST *) { return true; }
|
||||
virtual bool visit(StringLiteralAST *) { return true; }
|
||||
virtual bool visit(SwitchStatementAST *) { return true; }
|
||||
virtual bool visit(TemplateDeclarationAST *) { return true; }
|
||||
@@ -289,6 +291,7 @@ public:
|
||||
virtual void endVisit(LinkageSpecificationAST *) {}
|
||||
virtual void endVisit(MemInitializerAST *) {}
|
||||
virtual void endVisit(MemberAccessAST *) {}
|
||||
virtual void endVisit(MsvcDeclspecSpecifierAST *) {}
|
||||
virtual void endVisit(NamedTypeSpecifierAST *) {}
|
||||
virtual void endVisit(NamespaceAST *) {}
|
||||
virtual void endVisit(NamespaceAliasDefinitionAST *) {}
|
||||
@@ -353,6 +356,7 @@ public:
|
||||
virtual void endVisit(SimpleSpecifierAST *) {}
|
||||
virtual void endVisit(SizeofExpressionAST *) {}
|
||||
virtual void endVisit(StaticAssertDeclarationAST *) {}
|
||||
virtual void endVisit(StdAttributeSpecifierAST *) {}
|
||||
virtual void endVisit(StringLiteralAST *) {}
|
||||
virtual void endVisit(SwitchStatementAST *) {}
|
||||
virtual void endVisit(TemplateDeclarationAST *) {}
|
||||
|
||||
2
src/libs/3rdparty/cplusplus/ASTfwd.h
vendored
2
src/libs/3rdparty/cplusplus/ASTfwd.h
vendored
@@ -102,6 +102,7 @@ class LinkageBodyAST;
|
||||
class LinkageSpecificationAST;
|
||||
class MemInitializerAST;
|
||||
class MemberAccessAST;
|
||||
class MsvcDeclspecSpecifierAST;
|
||||
class NameAST;
|
||||
class NamedTypeSpecifierAST;
|
||||
class NamespaceAST;
|
||||
@@ -172,6 +173,7 @@ class SizeofExpressionAST;
|
||||
class SpecifierAST;
|
||||
class StatementAST;
|
||||
class StaticAssertDeclarationAST;
|
||||
class StdAttributeSpecifierAST;
|
||||
class StringLiteralAST;
|
||||
class SwitchStatementAST;
|
||||
class TemplateDeclarationAST;
|
||||
|
||||
50
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
50
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
@@ -918,6 +918,19 @@ void Bind::parameterDeclarationClause(ParameterDeclarationClauseAST *ast, int lp
|
||||
|
||||
for (ParameterDeclarationListAST *it = ast->parameter_declaration_list; it; it = it->next) {
|
||||
this->declaration(it->value);
|
||||
|
||||
// Check for '...' in last parameter declarator for variadic template
|
||||
// (i.e. template<class ... T> void foo(T ... args);)
|
||||
// those last dots are part of parameter declarator, not the parameter declaration clause
|
||||
if (! it->next
|
||||
&& it->value->declarator != nullptr
|
||||
&& it->value->declarator->core_declarator != nullptr){
|
||||
DeclaratorIdAST* declId = it->value->declarator->core_declarator->asDeclaratorId();
|
||||
if (declId && declId->dot_dot_dot_token != 0){
|
||||
fun->setVariadic(true);
|
||||
fun->setVariadicTemplate(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ast->dot_dot_dot_token)
|
||||
@@ -2767,10 +2780,27 @@ bool Bind::visit(DestructorNameAST *ast)
|
||||
bool Bind::visit(TemplateIdAST *ast)
|
||||
{
|
||||
// collect the template parameters
|
||||
std::vector<FullySpecifiedType> templateArguments;
|
||||
std::vector<TemplateArgument> templateArguments;
|
||||
for (ExpressionListAST *it = ast->template_argument_list; it; it = it->next) {
|
||||
ExpressionTy value = this->expression(it->value);
|
||||
templateArguments.push_back(value);
|
||||
if (value.isValid()) {
|
||||
templateArguments.emplace_back(value);
|
||||
} else {
|
||||
// special case for numeric values
|
||||
if (it->value->asNumericLiteral()) {
|
||||
templateArguments
|
||||
.emplace_back(value,
|
||||
tokenAt(it->value->asNumericLiteral()->literal_token).number);
|
||||
} else if (it->value->asBoolLiteral()) {
|
||||
templateArguments
|
||||
.emplace_back(value, tokenAt(it->value->asBoolLiteral()->literal_token).number);
|
||||
} else {
|
||||
// fall back to non-valid type in templateArguments
|
||||
// for ast->template_argument_list and templateArguments sizes match
|
||||
// TODO support other literals/expressions as default arguments
|
||||
templateArguments.emplace_back(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Identifier *id = identifier(ast->identifier_token);
|
||||
@@ -3014,6 +3044,22 @@ bool Bind::visit(GnuAttributeSpecifierAST *ast)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Bind::visit(MsvcDeclspecSpecifierAST *ast)
|
||||
{
|
||||
for (GnuAttributeListAST *it = ast->attribute_list; it; it = it->next) {
|
||||
this->attribute(it->value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Bind::visit(StdAttributeSpecifierAST *ast)
|
||||
{
|
||||
for (GnuAttributeListAST *it = ast->attribute_list; it; it = it->next) {
|
||||
this->attribute(it->value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Bind::visit(TypeofSpecifierAST *ast)
|
||||
{
|
||||
ExpressionTy expression = this->expression(ast->expression);
|
||||
|
||||
2
src/libs/3rdparty/cplusplus/Bind.h
vendored
2
src/libs/3rdparty/cplusplus/Bind.h
vendored
@@ -253,6 +253,8 @@ protected:
|
||||
virtual bool visit(SimpleSpecifierAST *ast);
|
||||
virtual bool visit(AlignmentSpecifierAST *ast);
|
||||
virtual bool visit(GnuAttributeSpecifierAST *ast);
|
||||
virtual bool visit(MsvcDeclspecSpecifierAST *ast);
|
||||
virtual bool visit(StdAttributeSpecifierAST *ast);
|
||||
virtual bool visit(TypeofSpecifierAST *ast);
|
||||
virtual bool visit(DecltypeSpecifierAST *ast);
|
||||
virtual bool visit(ClassSpecifierAST *ast);
|
||||
|
||||
2
src/libs/3rdparty/cplusplus/Control.cpp
vendored
2
src/libs/3rdparty/cplusplus/Control.cpp
vendored
@@ -629,7 +629,7 @@ const NumericLiteral *Control::numericLiteral(const char *chars)
|
||||
|
||||
const TemplateNameId *Control::templateNameId(const Identifier *id,
|
||||
bool isSpecialization,
|
||||
const FullySpecifiedType *const args,
|
||||
const TemplateArgument *const args,
|
||||
int argv)
|
||||
{
|
||||
return d->findOrInsertTemplateNameId(id, isSpecialization, args, args + argv);
|
||||
|
||||
2
src/libs/3rdparty/cplusplus/Control.h
vendored
2
src/libs/3rdparty/cplusplus/Control.h
vendored
@@ -54,7 +54,7 @@ public:
|
||||
/// Returns the canonical template name id.
|
||||
const TemplateNameId *templateNameId(const Identifier *id,
|
||||
bool isSpecialization,
|
||||
const FullySpecifiedType *const args = nullptr,
|
||||
const TemplateArgument *const args = nullptr,
|
||||
int argc = 0);
|
||||
|
||||
/// Returns the canonical destructor name id.
|
||||
|
||||
30
src/libs/3rdparty/cplusplus/Keywords.cpp
vendored
30
src/libs/3rdparty/cplusplus/Keywords.cpp
vendored
@@ -1079,6 +1079,23 @@ static inline int classify9(const char *s, LanguageFeatures features)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s[1] == 'd') {
|
||||
if (s[2] == 'e') {
|
||||
if (s[3] == 'c') {
|
||||
if (s[4] == 'l') {
|
||||
if (s[5] == 's') {
|
||||
if (s[6] == 'p') {
|
||||
if (s[7] == 'e') {
|
||||
if (s[8] == 'c') {
|
||||
return T__DECLSPEC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (features.cxx11Enabled && s[0] == 'c') {
|
||||
if (s[1] == 'o') {
|
||||
@@ -1178,11 +1195,20 @@ static inline int classify10(const char *s, LanguageFeatures features)
|
||||
{
|
||||
if (s[0] == '_') {
|
||||
if (s[1] == '_') {
|
||||
if (features.cxxEnabled && s[2] == 'd') {
|
||||
if (s[2] == 'd') {
|
||||
if (s[3] == 'e') {
|
||||
if (s[4] == 'c') {
|
||||
if (s[5] == 'l') {
|
||||
if (s[6] == 't') {
|
||||
if (s[6] == 's') {
|
||||
if (s[7] == 'p') {
|
||||
if (s[8] == 'e') {
|
||||
if (s[9] == 'c') {
|
||||
return T___DECLSPEC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (features.cxxEnabled && s[6] == 't') {
|
||||
if (s[7] == 'y') {
|
||||
if (s[8] == 'p') {
|
||||
if (s[9] == 'e') {
|
||||
|
||||
2
src/libs/3rdparty/cplusplus/Keywords.kwgen
vendored
2
src/libs/3rdparty/cplusplus/Keywords.kwgen
vendored
@@ -37,6 +37,8 @@ __asm__
|
||||
__attribute
|
||||
__attribute__
|
||||
__alignof__
|
||||
_declspec
|
||||
__declspec
|
||||
__const
|
||||
__const__
|
||||
__inline
|
||||
|
||||
11
src/libs/3rdparty/cplusplus/Lexer.cpp
vendored
11
src/libs/3rdparty/cplusplus/Lexer.cpp
vendored
@@ -1052,10 +1052,17 @@ void Lexer::scanIdentifier(Token *tok, unsigned extraProcessedChars)
|
||||
yyinp();
|
||||
}
|
||||
int yylen = _currentChar - yytext;
|
||||
if (f._scanKeywords)
|
||||
if (f._scanKeywords) {
|
||||
tok->f.kind = classify(yytext, yylen, _languageFeatures);
|
||||
else
|
||||
|
||||
if (tok->f.kind == T_FALSE || tok->f.kind == T_TRUE) {
|
||||
if (control()) {
|
||||
tok->number = control()->numericLiteral(yytext, yylen);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tok->f.kind = T_IDENTIFIER;
|
||||
}
|
||||
|
||||
if (tok->f.kind == T_IDENTIFIER) {
|
||||
tok->f.kind = classifyOperator(yytext, yylen);
|
||||
|
||||
4
src/libs/3rdparty/cplusplus/Matcher.cpp
vendored
4
src/libs/3rdparty/cplusplus/Matcher.cpp
vendored
@@ -324,8 +324,8 @@ bool Matcher::match(const TemplateNameId *name, const TemplateNameId *otherName)
|
||||
if (name->templateArgumentCount() != otherName->templateArgumentCount())
|
||||
return false;
|
||||
for (unsigned i = 0, ei = name->templateArgumentCount(); i != ei; ++i) {
|
||||
const FullySpecifiedType &l = name->templateArgumentAt(i);
|
||||
const FullySpecifiedType &r = otherName->templateArgumentAt(i);
|
||||
const TemplateArgument &l = name->templateArgumentAt(i);
|
||||
const TemplateArgument &r = otherName->templateArgumentAt(i);
|
||||
if (! l.match(r, this))
|
||||
return false;
|
||||
}
|
||||
|
||||
9
src/libs/3rdparty/cplusplus/Names.cpp
vendored
9
src/libs/3rdparty/cplusplus/Names.cpp
vendored
@@ -93,10 +93,17 @@ bool TemplateNameId::match0(const Name *otherName, Matcher *matcher) const
|
||||
const Identifier *TemplateNameId::identifier() const
|
||||
{ return _identifier; }
|
||||
|
||||
bool TemplateArgument::match(const TemplateArgument &otherTy, Matcher *matcher) const
|
||||
{
|
||||
if (_numericLiteral != otherTy._numericLiteral)
|
||||
return false;
|
||||
return type().match(otherTy.type(), matcher);
|
||||
}
|
||||
|
||||
int TemplateNameId::templateArgumentCount() const
|
||||
{ return int(_templateArguments.size()); }
|
||||
|
||||
const FullySpecifiedType &TemplateNameId::templateArgumentAt(int index) const
|
||||
const TemplateArgument &TemplateNameId::templateArgumentAt(int index) const
|
||||
{ return _templateArguments[index]; }
|
||||
|
||||
bool TemplateNameId::Compare::operator()(const TemplateNameId *name,
|
||||
|
||||
51
src/libs/3rdparty/cplusplus/Names.h
vendored
51
src/libs/3rdparty/cplusplus/Names.h
vendored
@@ -73,6 +73,51 @@ private:
|
||||
const Name *_name;
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT TemplateArgument
|
||||
{
|
||||
public:
|
||||
TemplateArgument()
|
||||
: _expressionTy(nullptr)
|
||||
, _numericLiteral(nullptr)
|
||||
{}
|
||||
|
||||
TemplateArgument(const FullySpecifiedType &type, const NumericLiteral *numericLiteral = nullptr)
|
||||
: _expressionTy(type)
|
||||
, _numericLiteral(numericLiteral)
|
||||
{}
|
||||
|
||||
bool hasType() const { return _expressionTy.isValid(); }
|
||||
|
||||
bool hasNumericLiteral() const { return _numericLiteral != nullptr; }
|
||||
|
||||
const FullySpecifiedType &type() const { return _expressionTy; }
|
||||
FullySpecifiedType &type() { return _expressionTy; }
|
||||
|
||||
const NumericLiteral *numericLiteral() const { return _numericLiteral; }
|
||||
|
||||
bool operator==(const TemplateArgument &other) const
|
||||
{
|
||||
return _expressionTy == other._expressionTy && _numericLiteral == other._numericLiteral;
|
||||
}
|
||||
bool operator!=(const TemplateArgument &other) const
|
||||
{
|
||||
return _expressionTy != other._expressionTy || _numericLiteral != other._numericLiteral;
|
||||
}
|
||||
bool operator<(const TemplateArgument &other) const
|
||||
{
|
||||
if (_expressionTy == other._expressionTy) {
|
||||
return _numericLiteral < other._numericLiteral;
|
||||
}
|
||||
return _expressionTy < other._expressionTy;
|
||||
}
|
||||
|
||||
bool match(const TemplateArgument &otherTy, Matcher *matcher = nullptr) const;
|
||||
|
||||
private:
|
||||
FullySpecifiedType _expressionTy;
|
||||
const NumericLiteral *_numericLiteral = nullptr;
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT TemplateNameId: public Name
|
||||
{
|
||||
public:
|
||||
@@ -89,12 +134,12 @@ public:
|
||||
|
||||
// ### find a better name
|
||||
int templateArgumentCount() const;
|
||||
const FullySpecifiedType &templateArgumentAt(int index) const;
|
||||
const TemplateArgument &templateArgumentAt(int index) const;
|
||||
|
||||
virtual const TemplateNameId *asTemplateNameId() const
|
||||
{ return this; }
|
||||
|
||||
typedef std::vector<FullySpecifiedType>::const_iterator TemplateArgumentIterator;
|
||||
typedef std::vector<TemplateArgument>::const_iterator TemplateArgumentIterator;
|
||||
|
||||
TemplateArgumentIterator firstTemplateArgument() const { return _templateArguments.begin(); }
|
||||
TemplateArgumentIterator lastTemplateArgument() const { return _templateArguments.end(); }
|
||||
@@ -111,7 +156,7 @@ protected:
|
||||
|
||||
private:
|
||||
const Identifier *_identifier;
|
||||
std::vector<FullySpecifiedType> _templateArguments;
|
||||
std::vector<TemplateArgument> _templateArguments;
|
||||
// now TemplateNameId can be a specialization or an instantiation
|
||||
bool _isSpecialization;
|
||||
};
|
||||
|
||||
79
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
79
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -770,6 +770,18 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
|
||||
else if (LA() == T_AT_PROPERTY)
|
||||
return parseObjCPropertyDeclaration(node, attributes);
|
||||
rewind(start);
|
||||
} else if (LA() == T___DECLSPEC) {
|
||||
const int start = cursor();
|
||||
SpecifierListAST *attributes = nullptr, **attr = &attributes;
|
||||
while (parseMsvcDeclspecSpecifier(*attr))
|
||||
attr = &(*attr)->next;
|
||||
rewind(start);
|
||||
} else if (lookAtStdAttribute()) {
|
||||
const int start = cursor();
|
||||
SpecifierListAST *attributes = nullptr, **attr = &attributes;
|
||||
while (parseStdAttributeSpecifier(*attr))
|
||||
attr = &(*attr)->next;
|
||||
rewind(start);
|
||||
}
|
||||
|
||||
if (LA() == T_EXTERN && LA(2) == T_TEMPLATE)
|
||||
@@ -3761,6 +3773,11 @@ bool Parser::parseIfStatement(StatementAST *&node)
|
||||
if (LA() == T_IF) {
|
||||
IfStatementAST *ast = new (_pool) IfStatementAST;
|
||||
ast->if_token = consumeToken();
|
||||
if (LA() == T_CONSTEXPR) {
|
||||
// "if constexpr" added in cxx17, but we don't check cxx version here
|
||||
// because msvc 2019 compiler uses "if constexpr" in headers despite cxx version set for the project
|
||||
ast->constexpr_token = consumeToken();
|
||||
}
|
||||
match(T_LPAREN, &ast->lparen_token);
|
||||
parseCondition(ast->condition);
|
||||
match(T_RPAREN, &ast->rparen_token);
|
||||
@@ -3961,6 +3978,8 @@ bool Parser::lookAtBuiltinTypeSpecifier() const
|
||||
// [gcc] extensions
|
||||
case T___TYPEOF__:
|
||||
case T___ATTRIBUTE__:
|
||||
// [msvc] extensions
|
||||
case T___DECLSPEC:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -4020,8 +4039,22 @@ bool Parser::parseAttributeSpecifier(SpecifierListAST *&attribute_list)
|
||||
attr_ptr = &(*attr_ptr)->next;
|
||||
}
|
||||
return true;
|
||||
case T___DECLSPEC:
|
||||
while (LA() == T___DECLSPEC) {
|
||||
parseMsvcDeclspecSpecifier(*attr_ptr);
|
||||
attr_ptr = &(*attr_ptr)->next;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
{
|
||||
bool foundAttributes = false;
|
||||
while (lookAtStdAttribute()) {
|
||||
parseStdAttributeSpecifier(*attr_ptr);
|
||||
attr_ptr = &(*attr_ptr)->next;
|
||||
foundAttributes = true;
|
||||
}
|
||||
return foundAttributes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4078,11 +4111,46 @@ bool Parser::parseGnuAttributeList(GnuAttributeListAST *&node)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::parseMsvcDeclspecSpecifier(SpecifierListAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() != T___DECLSPEC)
|
||||
return false;
|
||||
|
||||
MsvcDeclspecSpecifierAST *ast = new (_pool) MsvcDeclspecSpecifierAST;
|
||||
ast->attribute_token = consumeToken();
|
||||
match(T_LPAREN, &ast->lparen_token);
|
||||
parseGnuAttributeList(ast->attribute_list);
|
||||
match(T_RPAREN, &ast->rparen_token);
|
||||
node = new (_pool) SpecifierListAST(ast);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::parseStdAttributeSpecifier(SpecifierListAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (!lookAtStdAttribute())
|
||||
return false;
|
||||
|
||||
StdAttributeSpecifierAST *ast = new (_pool) StdAttributeSpecifierAST;
|
||||
match(T_LBRACKET, &ast->first_lbracket_token);
|
||||
match(T_LBRACKET, &ast->second_lbracket_token);
|
||||
parseGnuAttributeList(ast->attribute_list);
|
||||
match(T_RBRACKET, &ast->first_rbracket_token);
|
||||
match(T_RBRACKET, &ast->second_rbracket_token);
|
||||
node = new (_pool) SpecifierListAST(ast);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::parseBuiltinTypeSpecifier(SpecifierListAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() == T___ATTRIBUTE__) {
|
||||
return parseGnuAttributeSpecifier(node);
|
||||
} else if (LA() == T___DECLSPEC) {
|
||||
return parseMsvcDeclspecSpecifier(node);
|
||||
} else if (lookAtStdAttribute()) {
|
||||
return parseStdAttributeSpecifier(node);
|
||||
} else if (LA() == T___TYPEOF__) {
|
||||
TypeofSpecifierAST *ast = new (_pool) TypeofSpecifierAST;
|
||||
ast->typeof_token = consumeToken();
|
||||
@@ -5748,6 +5816,11 @@ bool Parser::parseNoExceptOperatorExpression(ExpressionAST *&node)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Parser::lookAtStdAttribute() const
|
||||
{
|
||||
return _languageFeatures.cxx11Enabled && LA() == T_LBRACKET && LA(2) == T_LBRACKET;
|
||||
}
|
||||
|
||||
bool Parser::lookAtObjCSelector() const
|
||||
{
|
||||
switch (LA()) {
|
||||
@@ -6797,6 +6870,8 @@ bool Parser::parseLambdaDeclarator(LambdaDeclaratorAST *&node)
|
||||
SpecifierListAST **attr = &ast->attributes;
|
||||
while (parseGnuAttributeSpecifier(*attr))
|
||||
attr = &(*attr)->next;
|
||||
while (parseStdAttributeSpecifier(*attr))
|
||||
attr = &(*attr)->next;
|
||||
|
||||
if (LA() == T_MUTABLE)
|
||||
ast->mutable_token = consumeToken();
|
||||
@@ -6821,6 +6896,8 @@ bool Parser::parseTrailingReturnType(TrailingReturnTypeAST *&node)
|
||||
SpecifierListAST **attr = &ast->attributes;
|
||||
while (parseGnuAttributeSpecifier(*attr))
|
||||
attr = &(*attr)->next;
|
||||
while (parseStdAttributeSpecifier(*attr))
|
||||
attr = &(*attr)->next;
|
||||
|
||||
parseTrailingTypeSpecifierSeq(ast->type_specifier_list);
|
||||
parseAbstractDeclarator(ast->declarator, ast->type_specifier_list);
|
||||
|
||||
5
src/libs/3rdparty/cplusplus/Parser.h
vendored
5
src/libs/3rdparty/cplusplus/Parser.h
vendored
@@ -170,6 +170,9 @@ public:
|
||||
bool parseGnuAttributeSpecifier(SpecifierListAST *&node);
|
||||
bool parseGnuAttributeList(GnuAttributeListAST *&node);
|
||||
|
||||
bool parseMsvcDeclspecSpecifier(SpecifierListAST *&node);
|
||||
bool parseStdAttributeSpecifier(SpecifierListAST *&node);
|
||||
|
||||
bool parseDeclSpecifierSeq(SpecifierListAST *&node,
|
||||
bool noStorageSpecifiers = false,
|
||||
bool onlySimpleTypeSpecifiers = false);
|
||||
@@ -247,6 +250,8 @@ public:
|
||||
bool peekAtObjCContextKeyword(int kind);
|
||||
bool parseObjCContextKeyword(int kind, int &in_token);
|
||||
|
||||
bool lookAtStdAttribute() const;
|
||||
|
||||
bool lookAtObjCSelector() const;
|
||||
|
||||
// c99
|
||||
|
||||
11
src/libs/3rdparty/cplusplus/Symbols.cpp
vendored
11
src/libs/3rdparty/cplusplus/Symbols.cpp
vendored
@@ -191,7 +191,7 @@ Declaration::Declaration(Clone *clone, Subst *subst, Declaration *original)
|
||||
if (const TemplateNameId * templateNameId =
|
||||
namedType->name()->asTemplateNameId()) {
|
||||
if (templateNameId->templateArgumentCount()) {
|
||||
newType = clone->type(templateNameId->templateArgumentAt(0), nullptr);
|
||||
newType = clone->type(templateNameId->templateArgumentAt(0).type(), nullptr);
|
||||
newType = FullySpecifiedType(clone->control()->pointerType(newType));
|
||||
}
|
||||
}
|
||||
@@ -469,6 +469,12 @@ bool Function::isVariadic() const
|
||||
void Function::setVariadic(bool isVariadic)
|
||||
{ f._isVariadic = isVariadic; }
|
||||
|
||||
bool Function::isVariadicTemplate() const
|
||||
{ return f._isVariadicTemplate; }
|
||||
|
||||
void Function::setVariadicTemplate(bool isVariadicTemplate)
|
||||
{ f._isVariadicTemplate = isVariadicTemplate; }
|
||||
|
||||
bool Function::isConst() const
|
||||
{ return f._isConst; }
|
||||
|
||||
@@ -523,6 +529,9 @@ bool Function::maybeValidPrototype(int actualArgumentCount) const
|
||||
break;
|
||||
}
|
||||
|
||||
if (isVariadicTemplate())
|
||||
--minNumberArguments;
|
||||
|
||||
if (actualArgumentCount < minNumberArguments) {
|
||||
// not enough arguments.
|
||||
return false;
|
||||
|
||||
4
src/libs/3rdparty/cplusplus/Symbols.h
vendored
4
src/libs/3rdparty/cplusplus/Symbols.h
vendored
@@ -346,6 +346,9 @@ public:
|
||||
bool isVariadic() const;
|
||||
void setVariadic(bool isVariadic);
|
||||
|
||||
bool isVariadicTemplate() const;
|
||||
void setVariadicTemplate(bool isVariadicTemplate);
|
||||
|
||||
bool isConst() const;
|
||||
void setConst(bool isConst);
|
||||
|
||||
@@ -397,6 +400,7 @@ private:
|
||||
unsigned _isOverride: 1;
|
||||
unsigned _isFinal: 1;
|
||||
unsigned _isVariadic: 1;
|
||||
unsigned _isVariadicTemplate: 1;
|
||||
unsigned _isPureVirtual: 1;
|
||||
unsigned _isConst: 1;
|
||||
unsigned _isVolatile: 1;
|
||||
|
||||
4
src/libs/3rdparty/cplusplus/Templates.cpp
vendored
4
src/libs/3rdparty/cplusplus/Templates.cpp
vendored
@@ -439,9 +439,9 @@ void CloneName::visit(const AnonymousNameId *name)
|
||||
|
||||
void CloneName::visit(const TemplateNameId *name)
|
||||
{
|
||||
std::vector<FullySpecifiedType> args(name->templateArgumentCount());
|
||||
std::vector<TemplateArgument> args(name->templateArgumentCount());
|
||||
for (int i = 0; i < int(args.size()); ++i)
|
||||
args[i] = _clone->type(name->templateArgumentAt(i), _subst);
|
||||
args[i].type() = _clone->type(name->templateArgumentAt(i).type(), _subst);
|
||||
if (args.empty())
|
||||
_name = _control->templateNameId(_clone->identifier(name->identifier()), name->isSpecialization());
|
||||
else
|
||||
|
||||
3
src/libs/3rdparty/cplusplus/Token.cpp
vendored
3
src/libs/3rdparty/cplusplus/Token.cpp
vendored
@@ -177,6 +177,9 @@ const char *token_names[] = {
|
||||
("__thread"),
|
||||
("__typeof__"),
|
||||
|
||||
// msvc
|
||||
("__declspec"),
|
||||
|
||||
// objc @keywords
|
||||
("@catch"),
|
||||
("@class"),
|
||||
|
||||
3
src/libs/3rdparty/cplusplus/Token.h
vendored
3
src/libs/3rdparty/cplusplus/Token.h
vendored
@@ -186,6 +186,8 @@ enum Kind {
|
||||
T___THREAD,
|
||||
T___TYPEOF__,
|
||||
|
||||
T___DECLSPEC,
|
||||
|
||||
// obj c++ @ keywords
|
||||
T_FIRST_OBJC_AT_KEYWORD,
|
||||
|
||||
@@ -298,6 +300,7 @@ enum Kind {
|
||||
T_FOREACH = T_Q_FOREACH,
|
||||
T_SIGNALS = T_Q_SIGNALS,
|
||||
T_Q_OVERRIDE = T_Q_PROPERTY,
|
||||
T__DECLSPEC = T___DECLSPEC,
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT Token
|
||||
|
||||
Reference in New Issue
Block a user