From 9ee693ee229d28bd618e8dd44bc6b12750d43a29 Mon Sep 17 00:00:00 2001 From: Volodymyr Zibarov Date: Thu, 14 May 2020 23:07:05 +0300 Subject: 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 Reviewed-by: Nikolai Kosjar --- src/libs/3rdparty/cplusplus/Bind.cpp | 50 ++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'src/libs/3rdparty/cplusplus/Bind.cpp') diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index 486efffc3d..53a14f6def 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -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 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 templateArguments; + std::vector 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); -- cgit v1.2.1