forked from qt-creator/qt-creator
ClangCodeModel: Fix access type categorization for functions
... with clangd. The code is starting to look rather hacky and might need to be rewritten completely at some point. Let's see how far we get with it. Change-Id: I506dd410831970b9f9291b005129b4d70f397de0 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -477,7 +477,9 @@ static QList<AstNode> getAstPath(const AstNode &root, const Position &pos)
|
|||||||
static Usage::Type getUsageType(const QList<AstNode> &path)
|
static Usage::Type getUsageType(const QList<AstNode> &path)
|
||||||
{
|
{
|
||||||
bool potentialWrite = false;
|
bool potentialWrite = false;
|
||||||
|
bool isFunction = false;
|
||||||
const bool symbolIsDataType = path.last().role() == "type" && path.last().kind() == "Record";
|
const bool symbolIsDataType = path.last().role() == "type" && path.last().kind() == "Record";
|
||||||
|
const auto isPotentialWrite = [&] { return potentialWrite && !isFunction; };
|
||||||
for (auto pathIt = path.rbegin(); pathIt != path.rend(); ++pathIt) {
|
for (auto pathIt = path.rbegin(); pathIt != path.rend(); ++pathIt) {
|
||||||
if (pathIt->arcanaContains("non_odr_use_unevaluated"))
|
if (pathIt->arcanaContains("non_odr_use_unevaluated"))
|
||||||
return Usage::Type::Other;
|
return Usage::Type::Other;
|
||||||
@@ -487,11 +489,24 @@ static Usage::Type getUsageType(const QList<AstNode> &path)
|
|||||||
return Usage::Type::Other;
|
return Usage::Type::Other;
|
||||||
if (pathIt->kind() == "Switch" || pathIt->kind() == "If")
|
if (pathIt->kind() == "Switch" || pathIt->kind() == "If")
|
||||||
return Usage::Type::Read;
|
return Usage::Type::Read;
|
||||||
if (pathIt->kind() == "Call" || pathIt->kind() == "CXXMemberCall")
|
if (pathIt->kind() == "Call")
|
||||||
return potentialWrite ? Usage::Type::WritableRef : Usage::Type::Read;
|
return isFunction ? Usage::Type::Other
|
||||||
|
: potentialWrite ? Usage::Type::WritableRef : Usage::Type::Read;
|
||||||
|
if (pathIt->kind() == "CXXMemberCall") {
|
||||||
|
const auto children = pathIt->children();
|
||||||
|
if (children && children->size() == 1
|
||||||
|
&& children->first() == path.last()
|
||||||
|
&& children->first().arcanaContains("bound member function")) {
|
||||||
|
return Usage::Type::Other;
|
||||||
|
}
|
||||||
|
return isPotentialWrite() ? Usage::Type::WritableRef : Usage::Type::Read;
|
||||||
|
}
|
||||||
if ((pathIt->kind() == "DeclRef" || pathIt->kind() == "Member")
|
if ((pathIt->kind() == "DeclRef" || pathIt->kind() == "Member")
|
||||||
&& pathIt->arcanaContains("lvalue")) {
|
&& pathIt->arcanaContains("lvalue")) {
|
||||||
potentialWrite = true;
|
if (pathIt->arcanaContains(" Function "))
|
||||||
|
isFunction = true;
|
||||||
|
else
|
||||||
|
potentialWrite = true;
|
||||||
}
|
}
|
||||||
if (pathIt->role() == "declaration") {
|
if (pathIt->role() == "declaration") {
|
||||||
if (symbolIsDataType)
|
if (symbolIsDataType)
|
||||||
@@ -501,6 +516,8 @@ static Usage::Type getUsageType(const QList<AstNode> &path)
|
|||||||
return Usage::Type::Initialization;
|
return Usage::Type::Initialization;
|
||||||
if (pathIt->childContainsRange(0, path.last().range()))
|
if (pathIt->childContainsRange(0, path.last().range()))
|
||||||
return Usage::Type::Initialization;
|
return Usage::Type::Initialization;
|
||||||
|
if (isFunction)
|
||||||
|
return Usage::Type::Read;
|
||||||
if (!pathIt->hasConstType())
|
if (!pathIt->hasConstType())
|
||||||
return Usage::Type::WritableRef;
|
return Usage::Type::WritableRef;
|
||||||
return Usage::Type::Read;
|
return Usage::Type::Read;
|
||||||
@@ -528,7 +545,7 @@ static Usage::Type getUsageType(const QList<AstNode> &path)
|
|||||||
const int lhsIndex = isBinaryOp ? 0 : 1;
|
const int lhsIndex = isBinaryOp ? 0 : 1;
|
||||||
if (pathIt->childContainsRange(lhsIndex, path.last().range()))
|
if (pathIt->childContainsRange(lhsIndex, path.last().range()))
|
||||||
return Usage::Type::Write;
|
return Usage::Type::Write;
|
||||||
return potentialWrite ? Usage::Type::WritableRef : Usage::Type::Read;
|
return isPotentialWrite() ? Usage::Type::WritableRef : Usage::Type::Read;
|
||||||
}
|
}
|
||||||
return Usage::Type::Read;
|
return Usage::Type::Read;
|
||||||
}
|
}
|
||||||
|
@@ -284,6 +284,11 @@ void ClangdTestFindReferences::test_data()
|
|||||||
QTest::newRow("array variable") << "main.cpp" << 1134 << ItemList{
|
QTest::newRow("array variable") << "main.cpp" << 1134 << ItemList{
|
||||||
makeItem(57, 8, Usage::Type::Declaration), makeItem(58, 4, Usage::Type::Write),
|
makeItem(57, 8, Usage::Type::Declaration), makeItem(58, 4, Usage::Type::Write),
|
||||||
makeItem(59, 15, Usage::Type::Read)};
|
makeItem(59, 15, Usage::Type::Read)};
|
||||||
|
QTest::newRow("free function") << "defs.h" << 510 << ItemList{
|
||||||
|
makeItem(24, 5, Usage::Type::Declaration), makeItem(19, 4, Usage::Type::Other),
|
||||||
|
makeItem(25, 4, Usage::Type::Other), makeItem(60, 26, Usage::Type::Read)};
|
||||||
|
QTest::newRow("member function") << "defs.h" << 192 << ItemList{
|
||||||
|
makeItem(9, 12, Usage::Type::Declaration), makeItem(40, 8, Usage::Type::Other)};
|
||||||
}
|
}
|
||||||
|
|
||||||
// The main point here is to test our access type categorization.
|
// The main point here is to test our access type categorization.
|
||||||
|
@@ -57,4 +57,5 @@ int main()
|
|||||||
int array[3];
|
int array[3];
|
||||||
array[S::value] = S::value;
|
array[S::value] = S::value;
|
||||||
S::value = array[S::value];
|
S::value = array[S::value];
|
||||||
|
const auto funcPtr = &func1;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user