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:
Volodymyr Zibarov
2020-05-14 23:07:05 +03:00
parent be97943372
commit 9ee693ee22
43 changed files with 1198 additions and 58 deletions

View File

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