diff options
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/clangbackend/ipcsource/clangtype.cpp | 2 | ||||
-rw-r--r-- | src/tools/clangbackend/ipcsource/clangtype.h | 2 | ||||
-rw-r--r-- | src/tools/clangbackend/ipcsource/cursor.cpp | 61 | ||||
-rw-r--r-- | src/tools/clangbackend/ipcsource/cursor.h | 8 | ||||
-rw-r--r-- | src/tools/clangbackend/ipcsource/highlightingmark.cpp | 96 | ||||
-rw-r--r-- | src/tools/clangbackend/ipcsource/highlightingmark.h | 13 | ||||
-rw-r--r-- | src/tools/clangbackend/ipcsource/highlightingmarks.cpp | 25 | ||||
-rw-r--r-- | src/tools/clangbackend/ipcsource/highlightingmarks.h | 3 | ||||
-rw-r--r-- | src/tools/clangbackend/ipcsource/highlightingmarksiterator.h | 19 |
9 files changed, 193 insertions, 36 deletions
diff --git a/src/tools/clangbackend/ipcsource/clangtype.cpp b/src/tools/clangbackend/ipcsource/clangtype.cpp index 54fe1aba2d..13ab8c9c6c 100644 --- a/src/tools/clangbackend/ipcsource/clangtype.cpp +++ b/src/tools/clangbackend/ipcsource/clangtype.cpp @@ -69,7 +69,7 @@ bool Type::isReferencingConstant() const return (isPointer() || isLValueReference()) && pointeeType().isConstant(); } -bool Type::isOutputParameter() const +bool Type::isOutputArgument() const { return (isPointer() || isLValueReference()) && !pointeeType().isConstant(); } diff --git a/src/tools/clangbackend/ipcsource/clangtype.h b/src/tools/clangbackend/ipcsource/clangtype.h index e9a19e92db..6a51245ce6 100644 --- a/src/tools/clangbackend/ipcsource/clangtype.h +++ b/src/tools/clangbackend/ipcsource/clangtype.h @@ -49,7 +49,7 @@ public: bool isConstantPointer() const; bool isLValueReference() const; bool isReferencingConstant() const; - bool isOutputParameter() const; + bool isOutputArgument() const; Utf8String utf8Spelling() const; ClangString spelling() const; diff --git a/src/tools/clangbackend/ipcsource/cursor.cpp b/src/tools/clangbackend/ipcsource/cursor.cpp index f88ef02bcd..56dfd9e610 100644 --- a/src/tools/clangbackend/ipcsource/cursor.cpp +++ b/src/tools/clangbackend/ipcsource/cursor.cpp @@ -213,16 +213,32 @@ SourceLocation Cursor::sourceLocation() const return clang_getCursorLocation(cxCursor); } +CXSourceLocation Cursor::cxSourceLocation() const +{ + return clang_getCursorLocation(cxCursor); +} + SourceRange Cursor::sourceRange() const { return clang_getCursorExtent(cxCursor); } +CXSourceRange Cursor::cxSourceRange() const +{ + return clang_getCursorExtent(cxCursor); +} + SourceRange Cursor::commentRange() const { return clang_Cursor_getCommentRange(cxCursor); } +bool Cursor::hasSameSourceLocationAs(const Cursor &other) const +{ + return clang_equalLocations(clang_getCursorLocation(cxCursor), + clang_getCursorLocation(other.cxCursor)); +} + Cursor Cursor::definition() const { return clang_getCursorDefinition(cxCursor); @@ -279,32 +295,42 @@ Cursor Cursor::argument(int index) const { return clang_Cursor_getArgument(cxCursor, index); } + namespace { -void collectOutputArguments(const Cursor &callExpression, - std::vector<Cursor> &outputArguments) + +bool isNotUnexposedLValueReference(const Cursor &argument, const Type &argumentType) +{ + return !(argument.isUnexposed() && argumentType.isLValueReference()); +} + +} + +void Cursor::collectOutputArgumentRangesTo(std::vector<CXSourceRange> &outputArgumentRanges) const { - auto callExpressionType = callExpression.referenced().type(); - auto argumentCount = callExpression.argumentCount(); - outputArguments.reserve(argumentCount); + const Type callExpressionType = referenced().type(); + const int argumentCount = this->argumentCount(); + const std::size_t maxSize = std::size_t(std::max(0, argumentCount)) + + outputArgumentRanges.size(); + outputArgumentRanges.reserve(maxSize); for (int argumentIndex = 0; argumentIndex < argumentCount; ++argumentIndex) { - auto argument = callExpression.argument(argumentIndex); - auto argumentType = callExpressionType.argument(argumentIndex); + const Cursor argument = this->argument(argumentIndex); + const Type argumentType = callExpressionType.argument(argumentIndex); - if (!argument.isUnexposed() && argumentType.isOutputParameter()) - outputArguments.push_back(callExpression.argument(argumentIndex)); + if (isNotUnexposedLValueReference(argument, argumentType) + && argumentType.isOutputArgument()) { + outputArgumentRanges.push_back(argument.cxSourceRange()); + } } } -} -std::vector<Cursor> Cursor::outputArguments() const +std::vector<CXSourceRange> Cursor::outputArgumentRanges() const { - std::vector<Cursor> outputArguments; + std::vector<CXSourceRange> outputArgumentRanges; - if (kind() == CXCursor_CallExpr) - collectOutputArguments(*this, outputArguments); + collectOutputArgumentRangesTo(outputArgumentRanges); - return outputArguments; + return outputArgumentRanges; } CXCursorKind Cursor::kind() const @@ -317,6 +343,11 @@ bool operator==(const Cursor &first, const Cursor &second) return clang_equalCursors(first.cxCursor, second.cxCursor); } +bool operator!=(const Cursor &first, const Cursor &second) +{ + return !(first == second); +} + void PrintTo(CXCursorKind cursorKind, ::std::ostream *os) { ClangString cursorKindSpelling(clang_getCursorKindSpelling(cursorKind)); diff --git a/src/tools/clangbackend/ipcsource/cursor.h b/src/tools/clangbackend/ipcsource/cursor.h index 6711ab98d5..8f294c7e26 100644 --- a/src/tools/clangbackend/ipcsource/cursor.h +++ b/src/tools/clangbackend/ipcsource/cursor.h @@ -78,8 +78,11 @@ public: Type nonPointerTupe() const; SourceLocation sourceLocation() const; + CXSourceLocation cxSourceLocation() const; SourceRange sourceRange() const; + CXSourceRange cxSourceRange() const; SourceRange commentRange() const; + bool hasSameSourceLocationAs(const Cursor &other) const; Cursor definition() const; Cursor canonical() const; @@ -90,7 +93,9 @@ public: Cursor functionBaseDeclaration() const; Cursor functionBase() const; Cursor argument(int index) const; - std::vector<Cursor> outputArguments() const; + void collectOutputArgumentRangesTo( + std::vector<CXSourceRange> &outputArgumentRanges) const; + std::vector<CXSourceRange> outputArgumentRanges() const; CXCursorKind kind() const; @@ -114,6 +119,7 @@ void Cursor::visit(VisitorCallback visitorCallback) const } bool operator==(const Cursor &first, const Cursor &second); +bool operator!=(const Cursor &first, const Cursor &second); void PrintTo(CXCursorKind cursorKind, ::std::ostream *os); void PrintTo(const Cursor &cursor, ::std::ostream* os); diff --git a/src/tools/clangbackend/ipcsource/highlightingmark.cpp b/src/tools/clangbackend/ipcsource/highlightingmark.cpp index 18ceca9157..d4744f7853 100644 --- a/src/tools/clangbackend/ipcsource/highlightingmark.cpp +++ b/src/tools/clangbackend/ipcsource/highlightingmark.cpp @@ -30,6 +30,7 @@ #include "highlightingmark.h" #include "sourcelocation.h" #include "sourcerange.h" +#include "sourcerangecontainer.h" #include <cstring> #include <ostream> @@ -39,16 +40,19 @@ namespace ClangBackEnd { HighlightingMark::HighlightingMark(const CXCursor &cxCursor, - CXToken *cxToken, - CXTranslationUnit cxTranslationUnit) + CXToken *cxToken, + CXTranslationUnit cxTranslationUnit, + std::vector<CXSourceRange> ¤tOutputArgumentRanges) + : currentOutputArgumentRanges(¤tOutputArgumentRanges), + originalCursor(cxCursor) { const SourceRange sourceRange = clang_getTokenExtent(cxTranslationUnit, *cxToken); const auto start = sourceRange.start(); const auto end = sourceRange.end(); - originalCursor = cxCursor; line = start.line(); column = start.column(); + offset = start.offset(); length = end.offset() - start.offset(); collectKinds(cxToken, originalCursor); } @@ -159,6 +163,17 @@ void HighlightingMark::variableKind(const Cursor &cursor) types.mainHighlightingType = HighlightingType::LocalVariable; else types.mainHighlightingType = HighlightingType::GlobalVariable; + + if (isOutputArgument()) + types.mixinHighlightingTypes.push_back(HighlightingType::OutputArgument); +} + +void HighlightingMark::fieldKind(const Cursor &) +{ + types.mainHighlightingType = HighlightingType::Field; + + if (isOutputArgument()) + types.mixinHighlightingTypes.push_back(HighlightingType::OutputArgument); } bool HighlightingMark::isVirtualMethodDeclarationOrDefinition(const Cursor &cursor) const @@ -185,6 +200,68 @@ void HighlightingMark::addExtraTypeIfFirstPass(HighlightingType type, types.mixinHighlightingTypes.push_back(type); } +bool HighlightingMark::isArgumentInCurrentOutputArgumentLocations() const +{ + auto originalSourceLocation = originalCursor.cxSourceLocation(); + + const auto isNotSameOutputArgument = [&] (const CXSourceRange ¤tSourceRange) { + return !(originalSourceLocation.int_data >= currentSourceRange.begin_int_data + && originalSourceLocation.int_data <= currentSourceRange.end_int_data); + }; + + auto partitionPoint = std::partition(currentOutputArgumentRanges->begin(), + currentOutputArgumentRanges->end(), + isNotSameOutputArgument); + + bool isOutputArgument = partitionPoint != currentOutputArgumentRanges->end(); + + if (isOutputArgument) + currentOutputArgumentRanges->erase(partitionPoint, currentOutputArgumentRanges->end()); + + return isOutputArgument; +} + +bool HighlightingMark::isOutputArgument() const +{ + if (currentOutputArgumentRanges->empty()) + return false; + + return isArgumentInCurrentOutputArgumentLocations(); +} + +void HighlightingMark::collectOutputArguments(const Cursor &cursor) +{ + cursor.collectOutputArgumentRangesTo(*currentOutputArgumentRanges); + filterOutPreviousOutputArguments(); +} + +namespace { + +uint getStart(CXSourceRange cxSourceRange) +{ + CXSourceLocation startSourceLocation = clang_getRangeStart(cxSourceRange); + + uint startOffset; + + clang_getFileLocation(startSourceLocation, nullptr, nullptr, nullptr, &startOffset); + + return startOffset; +} +} + +void HighlightingMark::filterOutPreviousOutputArguments() +{ + auto isAfterLocation = [this] (CXSourceRange outputRange) { + return getStart(outputRange) > offset; + }; + + auto precedingBegin = std::partition(currentOutputArgumentRanges->begin(), + currentOutputArgumentRanges->end(), + isAfterLocation); + + currentOutputArgumentRanges->erase(precedingBegin, currentOutputArgumentRanges->end()); +} + void HighlightingMark::functionKind(const Cursor &cursor, Recursion recursion) { if (isRealDynamicCall(cursor) || isVirtualMethodDeclarationOrDefinition(cursor)) @@ -204,12 +281,13 @@ void HighlightingMark::identifierKind(const Cursor &cursor, Recursion recursion) case CXCursor_CallExpr: case CXCursor_CXXMethod: functionKind(cursor, recursion); break; case CXCursor_NonTypeTemplateParameter: - case CXCursor_ParmDecl: types.mainHighlightingType = HighlightingType::LocalVariable; break; + case CXCursor_CompoundStmt: types.mainHighlightingType = HighlightingType::LocalVariable; break; + case CXCursor_ParmDecl: case CXCursor_VarDecl: variableKind(cursor); break; case CXCursor_DeclRefExpr: identifierKind(cursor.referenced(), Recursion::RecursivePass); break; case CXCursor_MemberRefExpr: memberReferenceKind(cursor); break; case CXCursor_FieldDecl: - case CXCursor_MemberRef: + case CXCursor_MemberRef: fieldKind(cursor); break; case CXCursor_ObjCIvarDecl: case CXCursor_ObjCPropertyDecl: case CXCursor_ObjCClassMethodDecl: @@ -282,15 +360,17 @@ HighlightingType operatorKind(const Cursor &cursor) return HighlightingType::Invalid; } -HighlightingType punctationKind(const Cursor &cursor) +} + +HighlightingType HighlightingMark::punctuationKind(const Cursor &cursor) { switch (cursor.kind()) { case CXCursor_DeclRefExpr: return operatorKind(cursor); + case CXCursor_CallExpr: collectOutputArguments(cursor); default: return HighlightingType::Invalid; } } -} void HighlightingMark::collectKinds(CXToken *cxToken, const Cursor &cursor) { auto cxTokenKind = clang_getTokenKind(*cxToken); @@ -299,7 +379,7 @@ void HighlightingMark::collectKinds(CXToken *cxToken, const Cursor &cursor) switch (cxTokenKind) { case CXToken_Keyword: types.mainHighlightingType = HighlightingType::Keyword; break; - case CXToken_Punctuation: types.mainHighlightingType = punctationKind(cursor); break; + case CXToken_Punctuation: types.mainHighlightingType = punctuationKind(cursor); break; case CXToken_Identifier: identifierKind(cursor, Recursion::FirstPass); break; case CXToken_Comment: types.mainHighlightingType = HighlightingType::Comment; break; case CXToken_Literal: types.mainHighlightingType = literalKind(cursor); break; diff --git a/src/tools/clangbackend/ipcsource/highlightingmark.h b/src/tools/clangbackend/ipcsource/highlightingmark.h index 7f2009810b..1740852730 100644 --- a/src/tools/clangbackend/ipcsource/highlightingmark.h +++ b/src/tools/clangbackend/ipcsource/highlightingmark.h @@ -45,7 +45,10 @@ class HighlightingMark }; public: - HighlightingMark(const CXCursor &cxCursor, CXToken *cxToken, CXTranslationUnit cxTranslationUnit); + HighlightingMark(const CXCursor &cxCursor, + CXToken *cxToken, + CXTranslationUnit cxTranslationUnit, + std::vector<CXSourceRange> ¤tOutputArgumentRanges); HighlightingMark(uint line, uint column, uint length, HighlightingTypes types); HighlightingMark(uint line, uint column, uint length, HighlightingType type); @@ -61,18 +64,26 @@ private: void identifierKind(const Cursor &cursor, Recursion recursion); void referencedTypeKind(const Cursor &cursor); void variableKind(const Cursor &cursor); + void fieldKind(const Cursor &cursor); bool isVirtualMethodDeclarationOrDefinition(const Cursor &cursor) const; void functionKind(const Cursor &cursor, Recursion recursion); void memberReferenceKind(const Cursor &cursor); + HighlightingType punctuationKind(const Cursor &cursor); void collectKinds(CXToken *cxToken, const Cursor &cursor); bool isRealDynamicCall(const Cursor &cursor) const; void addExtraTypeIfFirstPass(HighlightingType type, Recursion recursion); + bool isOutputArgument() const; + void collectOutputArguments(const Cursor &cursor); + void filterOutPreviousOutputArguments(); + bool isArgumentInCurrentOutputArgumentLocations() const; private: + std::vector<CXSourceRange> *currentOutputArgumentRanges = nullptr; Cursor originalCursor; uint line; uint column; uint length; + uint offset = 0; HighlightingTypes types; }; diff --git a/src/tools/clangbackend/ipcsource/highlightingmarks.cpp b/src/tools/clangbackend/ipcsource/highlightingmarks.cpp index 10cb2b5e82..725e6eb316 100644 --- a/src/tools/clangbackend/ipcsource/highlightingmarks.cpp +++ b/src/tools/clangbackend/ipcsource/highlightingmarks.cpp @@ -47,12 +47,18 @@ HighlightingMarks::~HighlightingMarks() HighlightingMarks::const_iterator HighlightingMarks::begin() const { - return const_iterator(cxCursor.cbegin(), cxToken, cxTranslationUnit); + return const_iterator(cxCursor.cbegin(), + cxToken, + cxTranslationUnit, + currentOutputArgumentRanges); } HighlightingMarks::const_iterator HighlightingMarks::end() const { - return const_iterator(cxCursor.cend(), cxToken + cxTokenCount, cxTranslationUnit); + return const_iterator(cxCursor.cend(), + cxToken + cxTokenCount, + cxTranslationUnit, + currentOutputArgumentRanges); } QVector<HighlightingMarkContainer> HighlightingMarks::toHighlightingMarksContainers() const @@ -67,11 +73,19 @@ QVector<HighlightingMarkContainer> HighlightingMarks::toHighlightingMarksContain && !highlightMark.hasMainType(HighlightingType::Comment); }; - std::copy_if(begin(), end(), std::back_inserter(containers), isValidHighlightMark); + for (const HighlightingMark &highlightMark : *this) { + if (isValidHighlightMark(highlightMark)) + containers.push_back(highlightMark); + } return containers; } +bool HighlightingMarks::currentOutputArgumentRangesAreEmpty() const +{ + return currentOutputArgumentRanges.empty(); +} + bool HighlightingMarks::isEmpty() const { return cxTokenCount == 0; @@ -89,7 +103,10 @@ uint HighlightingMarks::size() const HighlightingMark HighlightingMarks::operator[](size_t index) const { - return HighlightingMark(cxCursor[index], cxToken + index, cxTranslationUnit); + return HighlightingMark(cxCursor[index], + cxToken + index, + cxTranslationUnit, + currentOutputArgumentRanges); } } // namespace ClangBackEnd diff --git a/src/tools/clangbackend/ipcsource/highlightingmarks.h b/src/tools/clangbackend/ipcsource/highlightingmarks.h index 2d77bb86c5..6904bb3184 100644 --- a/src/tools/clangbackend/ipcsource/highlightingmarks.h +++ b/src/tools/clangbackend/ipcsource/highlightingmarks.h @@ -58,7 +58,10 @@ public: QVector<HighlightingMarkContainer> toHighlightingMarksContainers() const; + bool currentOutputArgumentRangesAreEmpty() const; + private: + mutable std::vector<CXSourceRange> currentOutputArgumentRanges; CXTranslationUnit cxTranslationUnit = nullptr; CXToken *const cxToken = nullptr; const uint cxTokenCount = 0; diff --git a/src/tools/clangbackend/ipcsource/highlightingmarksiterator.h b/src/tools/clangbackend/ipcsource/highlightingmarksiterator.h index 9cbfcabaad..daeada47a7 100644 --- a/src/tools/clangbackend/ipcsource/highlightingmarksiterator.h +++ b/src/tools/clangbackend/ipcsource/highlightingmarksiterator.h @@ -43,11 +43,13 @@ class HighlightingMarksIterator : public std::iterator<std::forward_iterator_tag { public: HighlightingMarksIterator(std::vector<CXCursor>::const_iterator cxCursorIterator, - CXToken *cxToken, - CXTranslationUnit cxTranslationUnit) + CXToken *cxToken, + CXTranslationUnit cxTranslationUnit, + std::vector<CXSourceRange> ¤tOutputArgumentRanges) : cxCursorIterator(cxCursorIterator), cxToken(cxToken), - cxTranslationUnit(cxTranslationUnit) + cxTranslationUnit(cxTranslationUnit), + currentOutputArgumentRanges(currentOutputArgumentRanges) {} HighlightingMarksIterator& operator++() @@ -60,7 +62,10 @@ public: HighlightingMarksIterator operator++(int) { - return HighlightingMarksIterator(cxCursorIterator++, cxToken++, cxTranslationUnit); + return HighlightingMarksIterator(cxCursorIterator++, + cxToken++, + cxTranslationUnit, + currentOutputArgumentRanges); } bool operator==(HighlightingMarksIterator other) const @@ -75,13 +80,17 @@ public: HighlightingMark operator*() { - return HighlightingMark(*cxCursorIterator, cxToken, cxTranslationUnit); + return HighlightingMark(*cxCursorIterator, + cxToken, + cxTranslationUnit, + currentOutputArgumentRanges); } private: std::vector<CXCursor>::const_iterator cxCursorIterator; CXToken *cxToken; CXTranslationUnit cxTranslationUnit; + std::vector<CXSourceRange> ¤tOutputArgumentRanges; }; } // namespace ClangBackEnd |