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:
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);
|
||||
|
||||
Reference in New Issue
Block a user