forked from qt-creator/qt-creator
		
	Clang: Fix local references for operator arguments
Workaround for wrong cursor annotated by Clang. Use clang_getCursor in case of the variable used as operator argument to get the proper cursor. Task-number: QTCREATORBUG-20966 Change-Id: Idb195bffc2296f3fae27595cf9c43c9e6b2c5cd0 Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
		@@ -43,8 +43,15 @@ namespace {
 | 
			
		||||
class ReferencedCursor
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    static ReferencedCursor find(const Cursor &cursor)
 | 
			
		||||
    static ReferencedCursor find(const Cursor &cursor, const CXToken &token)
 | 
			
		||||
    {
 | 
			
		||||
        if (cursor.spelling().startsWith("operator")
 | 
			
		||||
                && clang_getTokenKind(token) == CXToken_Identifier) {
 | 
			
		||||
            // We are actually inside operator, use clang_getCursor to return a proper cursor instead.
 | 
			
		||||
            return find(clang_getCursor(cursor.cxTranslationUnit(),
 | 
			
		||||
                                        clang_getTokenLocation(cursor.cxTranslationUnit(), token)),
 | 
			
		||||
                        token);
 | 
			
		||||
        }
 | 
			
		||||
        // Query the referenced cursor directly instead of first testing with cursor.isReference().
 | 
			
		||||
        // cursor.isReference() reports false for e.g. CXCursor_DeclRefExpr or CXCursor_CallExpr
 | 
			
		||||
        // although it returns a valid cursor.
 | 
			
		||||
@@ -194,7 +201,7 @@ bool ReferencesCollector::checkToken(unsigned index, const Utf8String &identifie
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    { // For debugging only
 | 
			
		||||
//        const SourceRange range = clang_getTokenExtent(m_cxTranslationUnit, token);
 | 
			
		||||
//        const SourceRange range{m_cxTranslationUnit, clang_getTokenExtent(m_cxTranslationUnit, token)};
 | 
			
		||||
//        const uint line = range.start().line();
 | 
			
		||||
//        const ClangString spellingCs = clang_getTokenSpelling(m_cxTranslationUnit, token);
 | 
			
		||||
//        const Utf8String spelling = spellingCs;
 | 
			
		||||
@@ -202,7 +209,7 @@ bool ReferencesCollector::checkToken(unsigned index, const Utf8String &identifie
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const Cursor currentCursor(m_cxCursors[static_cast<int>(index)]);
 | 
			
		||||
    const ReferencedCursor candidate = ReferencedCursor::find(currentCursor);
 | 
			
		||||
    const ReferencedCursor candidate = ReferencedCursor::find(currentCursor, token);
 | 
			
		||||
 | 
			
		||||
    return candidate.usr() == usr;
 | 
			
		||||
}
 | 
			
		||||
@@ -217,7 +224,7 @@ ReferencesResult ReferencesCollector::collect(uint line, uint column, bool local
 | 
			
		||||
 | 
			
		||||
    const Cursor cursorFromUser = m_cxCursors[static_cast<int>(index)];
 | 
			
		||||
 | 
			
		||||
    const ReferencedCursor refCursor = ReferencedCursor::find(cursorFromUser);
 | 
			
		||||
    const ReferencedCursor refCursor = ReferencedCursor::find(cursorFromUser, m_cxTokens[index]);
 | 
			
		||||
    const Utf8String usr = refCursor.usr();
 | 
			
		||||
    if (usr.isEmpty())
 | 
			
		||||
        return result;
 | 
			
		||||
 
 | 
			
		||||
@@ -463,6 +463,54 @@ TEST_F(ReferencesCollector, ArgumentToFunctionLikeMacro)
 | 
			
		||||
    ASSERT_THAT(actual, expected);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(ReferencesCollector, OverloadedBraceOperatorArgument)
 | 
			
		||||
{
 | 
			
		||||
    const ReferencesResult expected {
 | 
			
		||||
        true,
 | 
			
		||||
        {createSourceRange(171, 7, 1),
 | 
			
		||||
         createSourceRange(172, 7, 1),
 | 
			
		||||
         createSourceRange(172, 12, 1),
 | 
			
		||||
         createSourceRange(173, 7, 1),
 | 
			
		||||
         createSourceRange(173, 10, 1)},
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const ReferencesResult actual = getReferences(172, 7);
 | 
			
		||||
 | 
			
		||||
    ASSERT_THAT(actual, expected);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(ReferencesCollector, OverloadedParenOperatorSecondArgument)
 | 
			
		||||
{
 | 
			
		||||
    const ReferencesResult expected {
 | 
			
		||||
        true,
 | 
			
		||||
        {createSourceRange(171, 7, 1),
 | 
			
		||||
         createSourceRange(172, 7, 1),
 | 
			
		||||
         createSourceRange(172, 12, 1),
 | 
			
		||||
         createSourceRange(173, 7, 1),
 | 
			
		||||
         createSourceRange(173, 10, 1)},
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const ReferencesResult actual = getReferences(173, 10);
 | 
			
		||||
 | 
			
		||||
    ASSERT_THAT(actual, expected);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(ReferencesCollector, OverloadedOperatorsArgumentsFromOutside)
 | 
			
		||||
{
 | 
			
		||||
    const ReferencesResult expected {
 | 
			
		||||
        true,
 | 
			
		||||
        {createSourceRange(171, 7, 1),
 | 
			
		||||
         createSourceRange(172, 7, 1),
 | 
			
		||||
         createSourceRange(172, 12, 1),
 | 
			
		||||
         createSourceRange(173, 7, 1),
 | 
			
		||||
         createSourceRange(173, 10, 1)},
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const ReferencesResult actual = getReferences(171, 7);
 | 
			
		||||
 | 
			
		||||
    ASSERT_THAT(actual, expected);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::unique_ptr<const Data> ReferencesCollector::data;
 | 
			
		||||
 | 
			
		||||
void ReferencesCollector::SetUpTestCase()
 | 
			
		||||
 
 | 
			
		||||
@@ -157,3 +157,18 @@ int functionLikeMacro(int foo)
 | 
			
		||||
{
 | 
			
		||||
    return BAR(foo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
class Container
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    T &operator[](int); T &operator()(int, int);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int testOperator() {
 | 
			
		||||
  Container<int> vec;
 | 
			
		||||
 | 
			
		||||
  int n = 10;
 | 
			
		||||
  vec[n] = n * 100;
 | 
			
		||||
  vec(n, n) = 100;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user