Clang: Add semantic C++ operator-token styling

We used to style overloaded operators in the same way
as C++'s built-in operators. There was no way to tell
if a + token would call a operator+() function or not.

Now, if an operator is overloaded (redefined),
we give it the "Overloaded Operator"-mixin so users
can style it differently.

Note: Calls to overloaded 'new' and 'delete' are not
highlighted by "Overloaded Operator". This is because
clang today always maps these to CXCursor_CXXNewExpr
and CXCursor_CXXDeleteExpr with cursor.spelling == ""
(empty string). So there is no (?) quick way for us
to tell if a new/delete-token was overloaded or not.

After follow-ups, follow symbol will work for operator
overload usages in current translation unit.
Commit is appended by Ivan Donchevskii.

Task-number: QTCREATORBUG-19659
Change-Id: I157855d482a61ad2059642a1ee982089fcb7d312
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
Hugo Holgersson
2016-11-05 15:29:10 +01:00
parent bb6eae5c3b
commit 142ae0cdf9
15 changed files with 519 additions and 75 deletions

View File

@@ -216,16 +216,16 @@ void FullTokenInfo::memberReferenceKind(const Cursor &cursor)
}
}
void FullTokenInfo::keywordKind(const Cursor &cursor)
void FullTokenInfo::keywordKind()
{
TokenInfo::keywordKind(cursor);
TokenInfo::keywordKind();
CXCursorKind cursorKind = cursor.kind();
CXCursorKind cursorKind = m_originalCursor.kind();
bool anonymous = false;
if (clang_Cursor_isAnonymous(cursor.cx())) {
if (clang_Cursor_isAnonymous(m_originalCursor.cx())) {
anonymous = true;
} else {
const Utf8String type = fullyQualifiedType(cursor);
const Utf8String type = fullyQualifiedType(m_originalCursor);
if (type.endsWith(Utf8StringLiteral(")"))
&& static_cast<const QByteArray &>(type).indexOf("(anonymous") >= 0) {
anonymous = true;
@@ -242,11 +242,33 @@ void FullTokenInfo::keywordKind(const Cursor &cursor)
m_types.mixinHighlightingTypes.push_back(HighlightingType::Namespace);
m_extraInfo.declaration = m_extraInfo.definition = true;
m_extraInfo.token = Utf8StringLiteral("anonymous");
updateTypeSpelling(cursor);
m_extraInfo.cursorRange = cursor.sourceRange();
updateTypeSpelling(m_originalCursor);
m_extraInfo.cursorRange = m_originalCursor.sourceRange();
}
}
void FullTokenInfo::overloadedOperatorKind()
{
TokenInfo::overloadedOperatorKind();
if (m_types.mixinHighlightingTypes.front() != HighlightingType::OverloadedOperator)
return;
// Overloaded operator
m_extraInfo.identifier = true;
if (!m_originalCursor.isDeclaration())
return;
// Overloaded operator declaration
m_extraInfo.declaration = true;
m_extraInfo.definition = m_originalCursor.isDefinition();
updateTypeSpelling(m_originalCursor, true);
m_extraInfo.cursorRange = m_originalCursor.sourceRange();
m_extraInfo.accessSpecifier = m_originalCursor.accessSpecifier();
m_extraInfo.storageClass = m_originalCursor.storageClass();
}
void FullTokenInfo::evaluate()
{
m_extraInfo.token = ClangString(clang_getTokenSpelling(m_cxTranslationUnit, *m_cxToken));