Commit cb362b79 authored by Kai Stierand's avatar Kai Stierand Committed by Milian Wolff
Browse files

plugins/clang: fix code generator for operators that contain '<'

parent 2aa50fdd
......@@ -261,3 +261,46 @@ void TestClangUtils::testRangeForIncludePathSpec()
QCOMPARE(ClangUtils::rangeForIncludePathSpec("#include \"foo\\\".h\""), KTextEditor::Range(0, 10, 0, 17));
QCOMPARE(ClangUtils::rangeForIncludePathSpec("#include \"foo<>.h\""), KTextEditor::Range(0, 10, 0, 17));
}
void TestClangUtils::testGetCursorSignature()
{
QFETCH(QByteArray, code);
QFETCH(QString, expectedSignature);
QString fileName;
auto unit = parse(code, &fileName);
CXCursor functionCursor = clang_getNullCursor();
const auto startCursor = clang_getTranslationUnitCursor(unit.get());
ClangUtils::visitChildren(startCursor, [&](CXCursor cursor, CXCursor){
switch (clang_getCursorKind(cursor))
{
case CXCursor_FunctionDecl:
case CXCursor_CXXMethod:
case CXCursor_FunctionTemplate:
functionCursor = cursor;
return CXChildVisit_Break;
default:
return CXChildVisit_Recurse;
}
});
QVERIFY2(! clang_Cursor_isNull(functionCursor), "function not found");
auto scope = ClangUtils::getScope(functionCursor, startCursor);
auto signature = ClangUtils::getCursorSignature(functionCursor, scope, {});
QCOMPARE(signature, expectedSignature);
}
void TestClangUtils::testGetCursorSignature_data()
{
QTest::addColumn<QByteArray>("code");
QTest::addColumn<QString>("expectedSignature");
QTest::newRow("global-less")
<< QByteArray("class klass {}; bool operator < (const klass&, const klass&);")
<< "bool operator<(const klass&, const klass&)";
QTest::newRow("member-less")
<< QByteArray("class klass { bool operator < (const klass&); };")
<< "bool klass::operator<(const klass&)";
QTest::newRow("template-member-less")
<< QByteArray("class klass { template<typename T> bool operator < (const T&); };")
<< "bool klass::operator<(const T&)";
}
......@@ -24,6 +24,8 @@ private Q_SLOTS:
void testGetRawContents();
void testGetRawContents_data();
void testRangeForIncludePathSpec();
void testGetCursorSignature();
void testGetCursorSignature_data();
};
#endif // TESTCLANGUTILS_H
......@@ -232,7 +232,7 @@ QString ClangUtils::getCursorSignature(CXCursor cursor, const QString& scope, co
}
QString functionName = ClangString(clang_getCursorSpelling(cursor)).toString();
if (functionName.contains(QLatin1Char('<'))) {
if (functionName.contains(QLatin1Char('<')) && ! functionName.startsWith(QStringLiteral("operator<"))) {
stream << functionName.leftRef(functionName.indexOf(QLatin1Char('<')));
} else {
stream << functionName;
......@@ -361,6 +361,15 @@ bool ClangUtils::isExplicitlyDefaultedOrDeleted(CXCursor cursor)
return false;
}
void ClangUtils::visitChildren(CXCursor parent, std::function<CXChildVisitResult(CXCursor, CXCursor)> visitor)
{
static constexpr CXCursorVisitor cVisitor = [](CXCursor cursor, CXCursor parent, CXClientData client_data)
{
return (*static_cast<std::function<CXChildVisitResult(CXCursor, CXCursor)>*>(client_data))(cursor, parent);
};
clang_visitChildren(parent, cVisitor, &visitor);
}
KDevelop::ClassFunctionFlags ClangUtils::specialAttributes(CXCursor cursor)
{
// check for our injected attributes to detect Qt signals and slots
......
......@@ -16,6 +16,8 @@
#include <language/duchain/classfunctiondeclaration.h>
#include <functional>
namespace ClangUtils
{
/**
......@@ -84,7 +86,7 @@ namespace ClangUtils
* @param scope The scope of the cursor (e.g. "SomeNS::SomeClass")
* @return A QString of the function's signature
*/
QString getCursorSignature(CXCursor cursor, const QString& scope, const QVector<QString>& defaultArgs = QVector<QString>());
KDEVCLANGPRIVATE_EXPORT QString getCursorSignature(CXCursor cursor, const QString& scope, const QVector<QString>& defaultArgs = QVector<QString>());
/**
* Given a cursor representing the template argument list, return a
......@@ -125,6 +127,12 @@ namespace ClangUtils
*/
bool isExplicitlyDefaultedOrDeleted(CXCursor cursor);
/**
* @brief run clang_visitChildren using given visitor function
*/
KDEVCLANGPRIVATE_EXPORT void visitChildren(CXCursor parent, std::function<CXChildVisitResult(CXCursor cursor, CXCursor parent)> visitor);
/**
* Extract the range of the path-spec inside the include-directive in line @p line
*
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment