diff options
author | Nikolai Kosjar <nikolai.kosjar@digia.com> | 2014-05-09 10:04:13 -0400 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@digia.com> | 2014-05-23 14:34:01 +0200 |
commit | c6358e5d380c18f3ebff148a095ddf3a9d6b266c (patch) | |
tree | 84fc2fa9919e2d57720ae3944e2d3a94b6c28c68 | |
parent | bb7da966b801a2884cd7cf47f640bf7ac7d775df (diff) |
C++: Add utf16 indices to Macro and Document::MacroUse
In most cases we need to work with the utf16 indices. Only in
cppfindreferences the byte interface is still needed since there we read
in files and work on a QByteArray to save memory.
Change-Id: I6ef6a93fc1875a8c9a305c075d51a9ca034c41bb
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
24 files changed, 346 insertions, 216 deletions
diff --git a/src/libs/3rdparty/cplusplus/Lexer.cpp b/src/libs/3rdparty/cplusplus/Lexer.cpp index 8357b9e554..2da7d3a41c 100644 --- a/src/libs/3rdparty/cplusplus/Lexer.cpp +++ b/src/libs/3rdparty/cplusplus/Lexer.cpp @@ -36,6 +36,21 @@ using namespace CPlusPlus; \sa Token */ +/*! + \fn static void Lexer::yyinp_utf8(const char *¤tSourceChar, unsigned char &yychar, unsigned &utf16charCounter) + + Process a single unicode code point in an UTF-8 encoded source. + + \a currentSourceChar points to the UTF-8 encoded source. + \a yychar must be the byte pointed to by \a currentSourceChar. + + Points \a currentSourceChar to the byte of the next code point + and modifies \a yychar to the value pointed by the updated + \a currentSourceChar. \a utf16charCounter will be incremented by + the number of UTF-16 code units that were needed for that code + point. +*/ + Lexer::Lexer(TranslationUnit *unit) : _translationUnit(unit), _control(unit->control()), diff --git a/src/libs/3rdparty/cplusplus/Lexer.h b/src/libs/3rdparty/cplusplus/Lexer.h index 8d63d2ba1d..78396a0e60 100644 --- a/src/libs/3rdparty/cplusplus/Lexer.h +++ b/src/libs/3rdparty/cplusplus/Lexer.h @@ -61,6 +61,28 @@ public: LanguageFeatures languageFeatures() const { return _languageFeatures; } void setLanguageFeatures(LanguageFeatures features) { _languageFeatures = features; } +public: + static void yyinp_utf8(const char *¤tSourceChar, unsigned char &yychar, + unsigned &utf16charCounter) + { + ++utf16charCounter; + + // Process multi-byte UTF-8 code point (non-latin1) + if (CPLUSPLUS_UNLIKELY(isByteOfMultiByteCodePoint(yychar))) { + unsigned trailingBytesCurrentCodePoint = 1; + for (unsigned char c = yychar << 2; isByteOfMultiByteCodePoint(c); c <<= 1) + ++trailingBytesCurrentCodePoint; + // Code points >= 0x00010000 are represented by two UTF-16 code units + if (trailingBytesCurrentCodePoint >= 3) + ++utf16charCounter; + yychar = *(currentSourceChar += trailingBytesCurrentCodePoint + 1); + + // Process single-byte UTF-8 code point (latin1) + } else { + yychar = *++currentSourceChar; + } + } + private: void pushLineStartOffset(); void scan_helper(Token *tok); @@ -83,23 +105,7 @@ private: void yyinp() { - ++_currentCharUtf16; - - // Process multi-byte UTF-8 code point (non-latin1) - if (CPLUSPLUS_UNLIKELY(isByteOfMultiByteCodePoint(_yychar))) { - unsigned trailingBytesCurrentCodePoint = 1; - for (unsigned char c = _yychar << 2; isByteOfMultiByteCodePoint(c); c <<= 1) - ++trailingBytesCurrentCodePoint; - // Code points >= 0x00010000 are represented by two UTF16 code units - if (trailingBytesCurrentCodePoint >= 3) - ++_currentCharUtf16; - _yychar = *(_currentChar += trailingBytesCurrentCodePoint + 1); - - // Process single-byte UTF-8 code point (latin1) - } else { - _yychar = *++_currentChar; - } - + yyinp_utf8(_currentChar, _yychar, _currentCharUtf16); if (CPLUSPLUS_UNLIKELY(_yychar == '\n')) pushLineStartOffset(); } diff --git a/src/libs/3rdparty/cplusplus/TranslationUnit.cpp b/src/libs/3rdparty/cplusplus/TranslationUnit.cpp index fe309ed82f..9bc8edecfd 100644 --- a/src/libs/3rdparty/cplusplus/TranslationUnit.cpp +++ b/src/libs/3rdparty/cplusplus/TranslationUnit.cpp @@ -264,7 +264,7 @@ void TranslationUnit::tokenize() currentExpanded = true; const std::pair<unsigned, unsigned> &p = lineColumn[lineColumnIdx]; if (p.first) - _expandedLineColumn.insert(std::make_pair(tk.bytesBegin(), p)); + _expandedLineColumn.insert(std::make_pair(tk.utf16charsBegin(), p)); else currentGenerated = true; diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 61d82d945e..4fa078d6ee 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -365,25 +365,31 @@ void Document::appendMacro(const Macro ¯o) _definedMacros.append(macro); } -void Document::addMacroUse(const Macro ¯o, unsigned offset, unsigned length, +void Document::addMacroUse(const Macro ¯o, + unsigned bytesOffset, unsigned bytesLength, + unsigned utf16charsOffset, unsigned utf16charLength, unsigned beginLine, const QVector<MacroArgumentReference> &actuals) { - MacroUse use(macro, offset, offset + length, beginLine); + MacroUse use(macro, + bytesOffset, bytesOffset + bytesLength, + utf16charsOffset, utf16charsOffset + utf16charLength, + beginLine); foreach (const MacroArgumentReference &actual, actuals) { - const Block arg(actual.position(), actual.position() + actual.length()); - + const Block arg(0, 0, actual.utf16charsOffset(), + actual.utf16charsOffset() + actual.utf16charsLength()); use.addArgument(arg); } _macroUses.append(use); } -void Document::addUndefinedMacroUse(const QByteArray &name, unsigned offset) +void Document::addUndefinedMacroUse(const QByteArray &name, + unsigned bytesOffset, unsigned utf16charsOffset) { QByteArray copy(name.data(), name.size()); - UndefinedMacroUse use(copy, offset); + UndefinedMacroUse use(copy, bytesOffset, utf16charsOffset); _undefinedMacroUses.append(use); } @@ -548,19 +554,23 @@ const Macro *Document::findMacroDefinitionAt(unsigned line) const return 0; } -const Document::MacroUse *Document::findMacroUseAt(unsigned offset) const +const Document::MacroUse *Document::findMacroUseAt(unsigned utf16charsOffset) const { foreach (const Document::MacroUse &use, _macroUses) { - if (use.contains(offset) && (offset < use.begin() + use.macro().name().length())) + if (use.containsUtf16charOffset(utf16charsOffset) + && (utf16charsOffset < use.utf16charsBegin() + use.macro().nameToQString().size())) { return &use; + } } return 0; } -const Document::UndefinedMacroUse *Document::findUndefinedMacroUseAt(unsigned offset) const +const Document::UndefinedMacroUse *Document::findUndefinedMacroUseAt(unsigned utf16charsOffset) const { foreach (const Document::UndefinedMacroUse &use, _undefinedMacroUses) { - if (use.contains(offset) && (offset < use.begin() + use.name().length())) + if (use.containsUtf16charOffset(utf16charsOffset) + && (utf16charsOffset < use.utf16charsBegin() + + QString::fromUtf8(use.name(), use.name().size()).length())) return &use; } return 0; @@ -581,21 +591,21 @@ void Document::setUtf8Source(const QByteArray &source) _translationUnit->setSource(_source.constBegin(), _source.size()); } -void Document::startSkippingBlocks(unsigned start) +void Document::startSkippingBlocks(unsigned utf16charsOffset) { - _skippedBlocks.append(Block(start, 0)); + _skippedBlocks.append(Block(0, 0, utf16charsOffset, 0)); } -void Document::stopSkippingBlocks(unsigned stop) +void Document::stopSkippingBlocks(unsigned utf16charsOffset) { if (_skippedBlocks.isEmpty()) return; - unsigned start = _skippedBlocks.back().begin(); - if (start > stop) + unsigned start = _skippedBlocks.back().utf16charsBegin(); + if (start > utf16charsOffset) _skippedBlocks.removeLast(); // Ignore this block, it's invalid. else - _skippedBlocks.back() = Block(start, stop); + _skippedBlocks.back() = Block(0, 0, start, utf16charsOffset); } bool Document::isTokenized() const diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h index 7d0c2aa902..527f2ed82b 100644 --- a/src/libs/cplusplus/CppDocument.h +++ b/src/libs/cplusplus/CppDocument.h @@ -77,10 +77,12 @@ public: QString fileName() const; void appendMacro(const Macro ¯o); - void addMacroUse(const Macro ¯o, unsigned offset, unsigned length, - unsigned beginLine, - const QVector<MacroArgumentReference> &range); - void addUndefinedMacroUse(const QByteArray &name, unsigned offset); + void addMacroUse(const Macro ¯o, + unsigned bytesOffset, unsigned bytesLength, + unsigned utf16charsOffset, unsigned utf16charLength, + unsigned beginLine, const QVector<MacroArgumentReference> &range); + void addUndefinedMacroUse(const QByteArray &name, + unsigned bytesOffset, unsigned utf16charsOffset); Control *control() const; TranslationUnit *translationUnit() const; @@ -108,8 +110,8 @@ public: void setFingerprint(const QByteArray &fingerprint) { m_fingerprint = fingerprint; } - void startSkippingBlocks(unsigned offset); - void stopSkippingBlocks(unsigned offset); + void startSkippingBlocks(unsigned utf16charsOffset); + void stopSkippingBlocks(unsigned utf16charsOffset); enum ParseMode { // ### keep in sync with CPlusPlus::TranslationUnit ParseTranlationUnit, @@ -207,22 +209,34 @@ public: class Block { - unsigned _begin; - unsigned _end; + unsigned _bytesBegin; + unsigned _bytesEnd; + unsigned _utf16charsBegin; + unsigned _utf16charsEnd; public: - inline Block(unsigned begin = 0, unsigned end = 0) - : _begin(begin), _end(end) - { } + inline Block(unsigned bytesBegin = 0, unsigned bytesEnd = 0, + unsigned utf16charsBegin = 0, unsigned utf16charsEnd = 0) + : _bytesBegin(bytesBegin), + _bytesEnd(bytesEnd), + _utf16charsBegin(utf16charsBegin), + _utf16charsEnd(utf16charsEnd) + {} + + inline unsigned bytesBegin() const + { return _bytesBegin; } + + inline unsigned bytesEnd() const + { return _bytesEnd; } - inline unsigned begin() const - { return _begin; } + inline unsigned utf16charsBegin() const + { return _utf16charsBegin; } - inline unsigned end() const - { return _end; } + inline unsigned utf16charsEnd() const + { return _utf16charsEnd; } - bool contains(unsigned pos) const - { return pos >= _begin && pos < _end; } + bool containsUtf16charOffset(unsigned utf16charOffset) const + { return utf16charOffset >= _utf16charsBegin && utf16charOffset < _utf16charsEnd; } }; class Include { @@ -259,8 +273,11 @@ public: unsigned _beginLine; public: - inline MacroUse(const Macro ¯o, unsigned begin, unsigned end, unsigned beginLine) - : Block(begin, end), + inline MacroUse(const Macro ¯o, + unsigned bytesBegin, unsigned bytesEnd, + unsigned utf16charsBegin, unsigned utf16charsEnd, + unsigned beginLine) + : Block(bytesBegin, bytesEnd, utf16charsBegin, utf16charsEnd), _macro(macro), _beginLine(beginLine) { } @@ -293,8 +310,12 @@ public: public: inline UndefinedMacroUse( const QByteArray &name, - unsigned begin) - : Block(begin, begin + name.length()), + unsigned bytesBegin, + unsigned utf16charsBegin) + : Block(bytesBegin, + bytesBegin + name.length(), + utf16charsBegin, + utf16charsBegin + QString::fromUtf8(name, name.size()).size()), _name(name) { } @@ -328,8 +349,8 @@ public: { return _includeGuardMacroName; } const Macro *findMacroDefinitionAt(unsigned line) const; - const MacroUse *findMacroUseAt(unsigned offset) const; - const UndefinedMacroUse *findUndefinedMacroUseAt(unsigned offset) const; + const MacroUse *findMacroUseAt(unsigned utf16charsOffset) const; + const UndefinedMacroUse *findUndefinedMacroUseAt(unsigned utf16charsOffset) const; void keepSourceAndAST(); void releaseSourceAndAST(); diff --git a/src/libs/cplusplus/FastPreprocessor.cpp b/src/libs/cplusplus/FastPreprocessor.cpp index 5c52764cf5..c49695fc8c 100644 --- a/src/libs/cplusplus/FastPreprocessor.cpp +++ b/src/libs/cplusplus/FastPreprocessor.cpp @@ -108,37 +108,45 @@ static const Macro revision(const Snapshot &s, const Macro &m) return m; } -void FastPreprocessor::passedMacroDefinitionCheck(unsigned offset, unsigned line, const Macro ¯o) +void FastPreprocessor::passedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset, + unsigned line, const Macro ¯o) { Q_ASSERT(_currentDoc); _currentDoc->addMacroUse(revision(_snapshot, macro), - offset, macro.name().length(), line, - QVector<MacroArgumentReference>()); + bytesOffset, macro.name().size(), + utf16charsOffset, macro.nameToQString().size(), + line, QVector<MacroArgumentReference>()); } -void FastPreprocessor::failedMacroDefinitionCheck(unsigned offset, const ByteArrayRef &name) +void FastPreprocessor::failedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset, + const ByteArrayRef &name) { Q_ASSERT(_currentDoc); - _currentDoc->addUndefinedMacroUse(QByteArray(name.start(), name.size()), offset); + _currentDoc->addUndefinedMacroUse(QByteArray(name.start(), name.size()), + bytesOffset, utf16charsOffset); } -void FastPreprocessor::notifyMacroReference(unsigned offset, unsigned line, const Macro ¯o) +void FastPreprocessor::notifyMacroReference(unsigned bytesOffset, unsigned utf16charsOffset, + unsigned line, const Macro ¯o) { Q_ASSERT(_currentDoc); _currentDoc->addMacroUse(revision(_snapshot, macro), - offset, macro.name().length(), line, - QVector<MacroArgumentReference>()); + bytesOffset, macro.name().size(), + utf16charsOffset, macro.nameToQString().size(), + line, QVector<MacroArgumentReference>()); } -void FastPreprocessor::startExpandingMacro(unsigned offset, unsigned line, - const Macro ¯o, - const QVector<MacroArgumentReference> &actuals) +void FastPreprocessor::startExpandingMacro(unsigned bytesOffset, unsigned utf16charsOffset, + unsigned line, const Macro ¯o, + const QVector<MacroArgumentReference> &actuals) { Q_ASSERT(_currentDoc); _currentDoc->addMacroUse(revision(_snapshot, macro), - offset, macro.name().length(), line, actuals); + bytesOffset, macro.name().size(), + utf16charsOffset, macro.nameToQString().size(), + line, actuals); } diff --git a/src/libs/cplusplus/FastPreprocessor.h b/src/libs/cplusplus/FastPreprocessor.h index eabc4d03de..df19c4dcdf 100644 --- a/src/libs/cplusplus/FastPreprocessor.h +++ b/src/libs/cplusplus/FastPreprocessor.h @@ -61,13 +61,14 @@ public: virtual void macroAdded(const Macro &); - virtual void passedMacroDefinitionCheck(unsigned, unsigned, const Macro &); - virtual void failedMacroDefinitionCheck(unsigned, const ByteArrayRef &); + virtual void passedMacroDefinitionCheck(unsigned, unsigned, unsigned, const Macro &); + virtual void failedMacroDefinitionCheck(unsigned, unsigned, const ByteArrayRef &); - virtual void notifyMacroReference(unsigned, unsigned, const Macro &); + virtual void notifyMacroReference(unsigned, unsigned, unsigned, const Macro &); virtual void startExpandingMacro(unsigned, unsigned, + unsigned, const Macro &, const QVector<MacroArgumentReference> &); virtual void stopExpandingMacro(unsigned, const Macro &) {} diff --git a/src/libs/cplusplus/Macro.cpp b/src/libs/cplusplus/Macro.cpp index b957e32156..c6b91b8b3a 100644 --- a/src/libs/cplusplus/Macro.cpp +++ b/src/libs/cplusplus/Macro.cpp @@ -55,7 +55,8 @@ Macro::Macro() _hashcode(0), _fileRevision(0), _line(0), - _offset(0), + _bytesOffset(0), + _utf16charsOffset(0), _length(0), _state(0) { } diff --git a/src/libs/cplusplus/Macro.h b/src/libs/cplusplus/Macro.h index 0258345cfe..01bb3dce9f 100644 --- a/src/libs/cplusplus/Macro.h +++ b/src/libs/cplusplus/Macro.h @@ -71,6 +71,9 @@ public: QByteArray name() const { return _name; } + QString nameToQString() const + { return QString::fromUtf8(_name, _name.size()); } + void setName(const QByteArray &name) { _name = name; } @@ -107,11 +110,17 @@ public: void setLine(unsigned line) { _line = line; } - unsigned offset() const - { return _offset; } + unsigned bytesOffset() const + { return _bytesOffset; } + + void setBytesOffset(unsigned bytesOffset) + { _bytesOffset = bytesOffset; } + + unsigned utf16CharOffset() const + { return _utf16charsOffset; } - void setOffset(unsigned offset) - { _offset = offset; } + void setUtf16charOffset(unsigned utf16charOffset) + { _utf16charsOffset = utf16charOffset; } unsigned length() const { return _length; } @@ -161,7 +170,8 @@ private: unsigned _hashcode; unsigned _fileRevision; unsigned _line; - unsigned _offset; + unsigned _bytesOffset; + unsigned _utf16charsOffset; unsigned _length; union diff --git a/src/libs/cplusplus/PPToken.cpp b/src/libs/cplusplus/PPToken.cpp index fdfaacd2bd..793dedb9b8 100644 --- a/src/libs/cplusplus/PPToken.cpp +++ b/src/libs/cplusplus/PPToken.cpp @@ -58,5 +58,6 @@ void Internal::PPToken::squeezeSource() m_src = m_src.mid(byteOffset, f.bytes); m_src.squeeze(); byteOffset = 0; + utf16charOffset = 0; } } diff --git a/src/libs/cplusplus/PreprocessorClient.h b/src/libs/cplusplus/PreprocessorClient.h index 4802289dfa..a990a39357 100644 --- a/src/libs/cplusplus/PreprocessorClient.h +++ b/src/libs/cplusplus/PreprocessorClient.h @@ -46,19 +46,19 @@ class Macro; class CPLUSPLUS_EXPORT MacroArgumentReference { - unsigned _position; - unsigned _length; + unsigned _utf16charsOffset; + unsigned _utf16charsLength; public: - explicit MacroArgumentReference(unsigned position = 0, unsigned length = 0) - : _position(position), _length(length) + explicit MacroArgumentReference(unsigned utf16charsOffset = 0, unsigned utf16charsLength = 0) + : _utf16charsOffset(utf16charsOffset), _utf16charsLength(utf16charsLength) { } - unsigned position() const - { return _position; } + unsigned utf16charsOffset() const + { return _utf16charsOffset; } - unsigned length() const - { return _length; } + unsigned utf16charsLength() const + { return _utf16charsLength; } }; class CPLUSPLUS_EXPORT Client @@ -79,24 +79,26 @@ public: virtual void macroAdded(const Macro ¯o) = 0; - virtual void passedMacroDefinitionCheck(unsigned offset, unsigned line, const Macro ¯o) = 0; - virtual void failedMacroDefinitionCheck(unsigned offset, const ByteArrayRef &name) = 0; + virtual void passedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset, + unsigned line, const Macro ¯o) = 0; + virtual void failedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset, + const ByteArrayRef &name) = 0; - virtual void notifyMacroReference(unsigned offset, unsigned line, const Macro ¯o) = 0; + virtual void notifyMacroReference(unsigned bytesOffset, unsigned utf16charsOffset, + unsigned line, const Macro ¯o) = 0; - virtual void startExpandingMacro(unsigned offset, - unsigned line, - const Macro ¯o, + virtual void startExpandingMacro(unsigned bytesOffset, unsigned utf16charsOffset, + unsigned line, const Macro ¯o, const QVector<MacroArgumentReference> &actuals = QVector<MacroArgumentReference>()) = 0; - virtual void stopExpandingMacro(unsigned offset, const Macro ¯o) = 0; + virtual void stopExpandingMacro(unsigned bytesOffset, const Macro ¯o) = 0; // TODO: ?! /// Mark the given macro name as the include guard for the current file. virtual void markAsIncludeGuard(const QByteArray ¯oName) = 0; - /// Start skipping from the given offset. - virtual void startSkippingBlocks(unsigned offset) = 0; - virtual void stopSkippingBlocks(unsigned offset) = 0; + /// Start skipping from the given utf16charsOffset. + virtual void startSkippingBlocks(unsigned utf16charsOffset) = 0; + virtual void stopSkippingBlocks(unsigned utf16charsOffset) = 0; virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType mode) = 0; diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index c6aabbe608..fec9dd2806 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -277,7 +277,8 @@ inline bool isContinuationToken(const PPToken &tk) } Macro *macroDefinition(const ByteArrayRef &name, - unsigned offset, + unsigned bytesOffset, + unsigned utf16charsOffset, unsigned line, Environment *env, Client *client) @@ -285,9 +286,9 @@ Macro *macroDefinition(const ByteArrayRef &name, Macro *m = env->resolve(name); if (client) { if (m) - client->passedMacroDefinitionCheck(offset, line, *m); + client->passedMacroDefinitionCheck(bytesOffset, utf16charsOffset, line, *m); else - client->failedMacroDefinitionCheck(offset, name); + client->failedMacroDefinitionCheck(bytesOffset, utf16charsOffset, name); } return m; } @@ -304,6 +305,7 @@ public: { // WARN: `last' must be a valid iterator. trivial.byteOffset = last->byteOffset; + trivial.utf16charOffset = last->utf16charOffset; } inline operator bool() const @@ -422,6 +424,7 @@ protected: if ((*_lex)->is(T_IDENTIFIER)) { _value.set_long(macroDefinition(tokenSpell(), (*_lex)->byteOffset, + (*_lex)->utf16charOffset, (*_lex)->lineno, env, client) != 0); ++(*_lex); @@ -430,6 +433,7 @@ protected: if ((*_lex)->is(T_IDENTIFIER)) { _value.set_long(macroDefinition(tokenSpell(), (*_lex)->byteOffset, + (*_lex)->utf16charOffset, (*_lex)->lineno, env, client) != 0); @@ -610,7 +614,8 @@ Preprocessor::State::State() , m_markExpandedTokens(true) , m_noLines(false) , m_inCondition(false) - , m_offsetRef(0) + , m_bytesOffsetRef(0) + , m_utf16charsOffsetRef(0) , m_result(0) , m_lineRef(1) , m_currentExpansion(0) @@ -830,7 +835,9 @@ void Preprocessor::handleDefined(PPToken *tk) QByteArray result(1, '0'); const ByteArrayRef macroName = idToken.asByteArrayRef(); - if (macroDefinition(macroName, idToken.byteOffset + m_state.m_offsetRef, + if (macroDefinition(macroName, + idToken.byteOffset + m_state.m_bytesOffsetRef, + idToken.utf16charOffset + m_state.m_utf16charsOffsetRef, idToken.lineno, m_env, m_client)) { result[0] = '1'; } @@ -984,7 +991,8 @@ bool Preprocessor::handleIdentifier(PPToken *tk) if (!expandFunctionlikeMacros() // Still expand if this originally started with an object-like macro. && m_state.m_expansionStatus != Expanding) { - m_client->notifyMacroReference(m_state.m_offsetRef + idTk.byteOffset, + m_client->notifyMacroReference(m_state.m_bytesOffsetRef + idTk.byteOffset, + m_state.m_utf16charsOffsetRef + idTk.utf16charOffset, idTk.lineno, *macro); return false; @@ -1044,13 +1052,14 @@ bool Preprocessor::handleIdentifier(PPToken *tk) } else { argRefs.push_back(MacroArgumentReference( - m_state.m_offsetRef + argTks.first().bytesBegin(), - argTks.last().bytesBegin() + argTks.last().bytes() - - argTks.first().bytesBegin())); + m_state.m_utf16charsOffsetRef + argTks.first().utf16charsBegin(), + argTks.last().utf16charsBegin() + argTks.last().utf16chars() + - argTks.first().utf16charsBegin())); } } - m_client->startExpandingMacro(m_state.m_offsetRef + idTk.byteOffset, + m_client->startExpandingMacro(m_state.m_bytesOffsetRef + idTk.byteOffset, + m_state.m_utf16charsOffsetRef + idTk.utf16charOffset, idTk.lineno, *macro, argRefs); @@ -1062,7 +1071,9 @@ bool Preprocessor::handleIdentifier(PPToken *tk) return false; } } else if (m_client && !idTk.generated()) { - m_client->startExpandingMacro(m_state.m_offsetRef + idTk.byteOffset, idTk.lineno, *macro); + m_client->startExpandingMacro(m_state.m_bytesOffsetRef + idTk.byteOffset, + m_state.m_utf16charsOffsetRef + idTk.utf16charOffset, + idTk.lineno, *macro); } if (body.isEmpty()) { @@ -1379,7 +1390,8 @@ void Preprocessor::preprocess(const QString &fileName, const QByteArray &source, QByteArray *result, QByteArray *includeGuardMacroName, bool noLines, bool markGeneratedTokens, bool inCondition, - unsigned offsetRef, unsigned lineRef) + unsigned bytesOffsetRef, unsigned utf16charOffsetRef, + unsigned lineRef) { if (source.isEmpty()) return; @@ -1397,7 +1409,8 @@ void Preprocessor::preprocess(const QString &fileName, const QByteArray &source, m_state.m_noLines = noLines; m_state.m_markExpandedTokens = markGeneratedTokens; m_state.m_inCondition = inCondition; - m_state.m_offsetRef = offsetRef; + m_state.m_bytesOffsetRef = bytesOffsetRef; + m_state.m_utf16charsOffsetRef = utf16charOffsetRef; m_state.m_lineRef = lineRef; ScopedSwap<QString> savedFileName(m_env->currentFile, fileName); @@ -1638,7 +1651,8 @@ void Preprocessor::handleDefineDirective(PPToken *tk) macro.setLine(tk->lineno); QByteArray macroName = tk->asByteArrayRef().toByteArray(); macro.setName(macroName); - macro.setOffset(tk->byteOffset); + macro.setBytesOffset(tk->byteOffset); + macro.setUtf16charOffset(tk->utf16charOffset); PPToken idToken(*tk); @@ -1682,7 +1696,8 @@ void Preprocessor::handleDefineDirective(PPToken *tk) } QVector<PPToken> bodyTokens; - unsigned previousOffset = 0; + unsigned previousBytesOffset = 0; + unsigned previousUtf16charsOffset = 0; unsigned previousLine = 0; Macro *macroReference = 0; while (isContinuationToken(*tk)) { @@ -1699,17 +1714,21 @@ void Preprocessor::handleDefineDirective(PPToken *tk) macroReference = m_env->resolve(tk->asByteArrayRef()); if (macroReference) { if (!macroReference->isFunctionLike()) { - m_client->notifyMacroReference(tk->byteOffset, tk->lineno, *macroReference); + m_client->notifyMacroReference(tk->byteOffset, tk->utf16charOffset, + tk->lineno, *macroReference); macroReference = 0; } } } else if (macroReference) { - if (tk->is(T_LPAREN)) - m_client->notifyMacroReference(previousOffset, previousLine, *macroReference); + if (tk->is(T_LPAREN)) { + m_client->notifyMacroReference(previousBytesOffset, previousUtf16charsOffset, + previousLine, *macroReference); + } macroReference = 0; } - previousOffset = tk->byteOffset; + previousBytesOffset = tk->byteOffset; + previousUtf16charsOffset = tk->utf16charOffset; previousLine = tk->lineno; // Discard comments in macro definitions (keep comments flag doesn't apply here). @@ -1768,20 +1787,21 @@ void Preprocessor::handleDefineDirective(PPToken *tk) QByteArray Preprocessor::expand(PPToken *tk, PPToken *lastConditionToken) { unsigned line = tk->lineno; - unsigned begin = tk->bytesBegin(); + unsigned bytesBegin = tk->bytesBegin(); PPToken lastTk; while (isContinuationToken(*tk)) { lastTk = *tk; lex(tk); } // Gather the exact spelling of the content in the source. - QByteArray condition(m_state.m_source.mid(begin, lastTk.bytesBegin() + lastTk.bytes() - - begin)); + QByteArray condition(m_state.m_source.mid(bytesBegin, lastTk.bytesBegin() + lastTk.bytes() + - bytesBegin)); // qDebug("*** Condition before: [%s]", condition.constData()); QByteArray result; result.reserve(256); - preprocess(m_state.m_currentFileName, condition, &result, 0, true, false, true, begin, line); + preprocess(m_state.m_currentFileName, condition, &result, 0, true, false, true, + bytesBegin, tk->utf16charsBegin(), line); result.squeeze(); // qDebug("*** Condition after: [%s]", result.constData()); @@ -1855,7 +1875,7 @@ void Preprocessor::handleElifDirective(PPToken *tk, const PPToken £Token) m_state.m_trueTest[m_state.m_ifLevel] = !startSkipping; m_state.m_skipping[m_state.m_ifLevel] = startSkipping; if (m_client && !startSkipping) - m_client->stopSkippingBlocks(poundToken.byteOffset - 1); + m_client->stopSkippingBlocks(poundToken.utf16charOffset - 1); } } } @@ -1874,7 +1894,7 @@ void Preprocessor::handleElseDirective(PPToken *tk, const PPToken £Token) m_state.m_skipping[m_state.m_ifLevel] = startSkipping; if (m_client && wasSkipping && !startSkipping) - m_client->stopSkippingBlocks(poundToken.byteOffset - 1); + m_client->stopSkippingBlocks(poundToken.utf16charOffset - 1); else if (m_client && !wasSkipping && startSkipping) startSkippingBlocks(poundToken); } @@ -1900,7 +1920,7 @@ void Preprocessor::handleEndIfDirective(PPToken *tk, const PPToken £Token) m_state.m_trueTest[m_state.m_ifLevel] = false; --m_state.m_ifLevel; if (m_client && wasSkipping && !m_state.m_skipping[m_state.m_ifLevel]) - m_client->stopSkippingBlocks(poundToken.byteOffset - 1); + m_client->stopSkippingBlocks(poundToken.utf16charOffset - 1); if (m_state.m_ifLevel == 0) m_state.updateIncludeGuardState(State::IncludeGuardStateHint_Endif); @@ -1918,7 +1938,8 @@ void Preprocessor::handleIfDefDirective(bool checkUndefined, PPToken *tk) bool value = false; const ByteArrayRef macroName = tk->asByteArrayRef(); - if (Macro *macro = macroDefinition(macroName, tk->byteOffset, tk->lineno, m_env, m_client)) { + if (Macro *macro = macroDefinition(macroName, tk->byteOffset, tk->utf16charOffset, + tk->lineno, m_env, m_client)) { value = true; // the macro is a feature constraint(e.g. QT_NO_XXX) @@ -1957,17 +1978,21 @@ void Preprocessor::handleUndefDirective(PPToken *tk) lex(tk); // consume "undef" token if (tk->is(T_IDENTIFIER)) { const ByteArrayRef macroName = tk->asByteArrayRef(); - const unsigned offset = tk->byteOffset + m_state.m_offsetRef; + const unsigned bytesOffset = tk->byteOffset + m_state.m_bytesOffsetRef; + const unsigned utf16charsOffset = tk->utf16charOffset + m_state.m_utf16charsOffsetRef; // Track macro use if previously defined if (m_client) { - if (const Macro *existingMacro = m_env->resolve(macroName)) - m_client->notifyMacroReference(offset, tk->lineno, *existingMacro); + if (const Macro *existingMacro = m_env->resolve(macroName)) { + m_client->notifyMacroReference(bytesOffset, utf16charsOffset, + tk->lineno, *existingMacro); + } } synchronizeOutputLines(*tk); Macro *macro = m_env->remove(macroName); if (m_client && macro) { - macro->setOffset(offset); + macro->setBytesOffset(bytesOffset); + macro->setUtf16charOffset(utf16charsOffset); m_client->macroAdded(*macro); } lex(tk); // consume macro name @@ -2035,14 +2060,18 @@ void Preprocessor::startSkippingBlocks(const Preprocessor::PPToken &tk) const if (!m_client) return; - int iter = tk.bytesEnd(); - const QByteArray &txt = tk.source(); - for (; iter < txt.size(); ++iter) { - if (txt.at(iter) == '\n') { - m_client->startSkippingBlocks(iter + 1); + unsigned utf16charIter = tk.utf16charsEnd(); + const char *source = tk.source().constData() + tk.bytesEnd(); + const char *sourceEnd = tk.source().constEnd(); + unsigned char yychar = *source; + + do { + if (yychar == '\n') { + m_client->startSkippingBlocks(utf16charIter + 1); return; } - } + Lexer::yyinp_utf8(source, yychar, utf16charIter); + } while (source < sourceEnd); } bool Preprocessor::atStartOfOutputLine() const diff --git a/src/libs/cplusplus/pp-engine.h b/src/libs/cplusplus/pp-engine.h index 8ff8712cab..bb920c4aee 100644 --- a/src/libs/cplusplus/pp-engine.h +++ b/src/libs/cplusplus/pp-engine.h @@ -95,7 +95,8 @@ private: void preprocess(const QString &filename, const QByteArray &source, QByteArray *result, QByteArray *includeGuardMacroName, bool noLines, bool markGeneratedTokens, bool inCondition, - unsigned offsetRef = 0, unsigned lineRef = 1); + unsigned bytesOffsetRef = 0, unsigned utf16charOffsetRef = 0, + unsigned lineRef = 1); enum { MAX_LEVEL = 512 }; @@ -128,7 +129,8 @@ private: bool m_noLines; bool m_inCondition; - unsigned m_offsetRef; + unsigned m_bytesOffsetRef; + unsigned m_utf16charsOffsetRef; QByteArray *m_result; unsigned m_lineRef; diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 62cf921069..991f3d86e2 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -717,7 +717,7 @@ const Macro *CPPEditorWidget::findCanonicalMacro(const QTextCursor &cursor, Docu if (const Macro *macro = doc->findMacroDefinitionAt(line)) { QTextCursor macroCursor = cursor; - const QByteArray name = identifierUnderCursor(¯oCursor).toLatin1(); + const QByteArray name = identifierUnderCursor(¯oCursor).toUtf8(); if (macro->name() == name) return macro; } else if (const Document::MacroUse *use = doc->findMacroUseAt(cursor.position())) { @@ -836,9 +836,9 @@ void CPPEditorWidget::markSymbols(const QTextCursor &tc, const SemanticInfo &inf //Macro definition if (macro->fileName() == info.doc->fileName()) { QTextCursor cursor(document()); - cursor.setPosition(macro->offset()); + cursor.setPosition(macro->utf16CharOffset()); cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, - macro->name().length()); + macro->nameToQString().size()); QTextEdit::ExtraSelection sel; sel.format = occurrencesFormat; @@ -850,14 +850,14 @@ void CPPEditorWidget::markSymbols(const QTextCursor &tc, const SemanticInfo &inf foreach (const Document::MacroUse &use, info.doc->macroUses()) { const Macro &useMacro = use.macro(); if (useMacro.line() != macro->line() - || useMacro.offset() != macro->offset() + || useMacro.utf16CharOffset() != macro->utf16CharOffset() || useMacro.length() != macro->length() || useMacro.fileName() != macro->fileName()) continue; QTextCursor cursor(document()); - cursor.setPosition(use.begin()); - cursor.setPosition(use.end(), QTextCursor::KeepAnchor); + cursor.setPosition(use.utf16charsBegin()); + cursor.setPosition(use.utf16charsEnd(), QTextCursor::KeepAnchor); QTextEdit::ExtraSelection sel; sel.format = occurrencesFormat; diff --git a/src/plugins/cppeditor/cppelementevaluator.cpp b/src/plugins/cppeditor/cppelementevaluator.cpp index 0da38d6958..bb68e2078e 100644 --- a/src/plugins/cppeditor/cppelementevaluator.cpp +++ b/src/plugins/cppeditor/cppelementevaluator.cpp @@ -142,9 +142,9 @@ bool CppElementEvaluator::matchIncludeFile(const CPlusPlus::Document::Ptr &docum bool CppElementEvaluator::matchMacroInUse(const CPlusPlus::Document::Ptr &document, unsigned pos) { foreach (const Document::MacroUse &use, document->macroUses()) { - if (use.contains(pos)) { - const unsigned begin = use.begin(); - if (pos < begin + use.macro().name().length()) { + if (use.containsUtf16charOffset(pos)) { + const unsigned begin = use.utf16charsBegin(); + if (pos < begin + use.macro().nameToQString().size()) { m_element = QSharedPointer<CppElement>(new CppMacro(use.macro())); return true; } @@ -270,7 +270,7 @@ CppInclude::CppInclude(const Document::Include &includeFile) : CppMacro::CppMacro(const Macro ¯o) { helpCategory = TextEditor::HelpItem::Macro; - const QString macroName = QLatin1String(macro.name()); + const QString macroName = QString::fromUtf8(macro.name(), macro.name().size()); helpIdCandidates = QStringList(macroName); helpMark = macroName; link = CPPEditorWidget::Link(macro.fileName(), macro.line()); diff --git a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp index ae3e911849..3fb2639ef2 100644 --- a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp +++ b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp @@ -591,7 +591,7 @@ BaseTextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor & const Macro *macro = doc->findMacroDefinitionAt(line); if (macro) { QTextCursor macroCursor = cursor; - const QByteArray name = CPPEditorWidget::identifierUnderCursor(¯oCursor).toLatin1(); + const QByteArray name = CPPEditorWidget::identifierUnderCursor(¯oCursor).toUtf8(); if (macro->name() == name) return link; //already on definition! } else if (const Document::MacroUse *use = doc->findMacroUseAt(endOfToken - 1)) { @@ -602,8 +602,8 @@ BaseTextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor & const Macro ¯o = use->macro(); link.targetFileName = macro.fileName(); link.targetLine = macro.line(); - link.linkTextStart = use->begin(); - link.linkTextEnd = use->end(); + link.linkTextStart = use->utf16charsBegin(); + link.linkTextEnd = use->utf16charsEnd(); } return link; } @@ -722,7 +722,7 @@ BaseTextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor & // Handle macro uses QTextCursor macroCursor = cursor; - const QByteArray name = CPPEditorWidget::identifierUnderCursor(¯oCursor).toLatin1(); + const QByteArray name = CPPEditorWidget::identifierUnderCursor(¯oCursor).toUtf8(); link = findMacroLink(name, documentFromSemanticInfo); if (link.hasValidTarget()) { link.linkTextStart = macroCursor.selectionStart(); diff --git a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp index 2aef1c21cf..680944b677 100644 --- a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp +++ b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp @@ -660,8 +660,9 @@ void Dumper::dumpDocuments(const QList<CPlusPlus::Document::Ptr> &documents, boo const QString type = use.isFunctionLike() ? QLatin1String("function-like") : QLatin1String("object-like"); m_out << i4 << "at line " << use.beginLine() << ", " - << QString::fromUtf8(use.macro().name()) << ", begin=" << use.begin() - << ", end=" << use.end() << ", " << type << ", args=" + << use.macro().nameToQString().size() + << ", begin=" << use.utf16charsBegin() << ", end=" << use.utf16charsEnd() + << ", " << type << ", args=" << use.arguments().size() << "\n"; } } diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp index 77a25b1d5c..29ddb68223 100644 --- a/src/plugins/cpptools/cppcompletionassist.cpp +++ b/src/plugins/cpptools/cppcompletionassist.cpp @@ -1751,7 +1751,7 @@ void CppCompletionAssistProcessor::addMacros_helper(const CPlusPlus::Snapshot &s addMacros_helper(snapshot, i.resolvedFileName(), processed, definedMacros); foreach (const Macro ¯o, doc->definedMacros()) { - const QString macroName = QString::fromUtf8(macro.name().constData(), macro.name().length()); + const QString macroName = macro.nameToQString(); if (!macro.isHidden()) definedMacros->insert(macroName); else diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 6f353cb520..63b3b6a587 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -572,10 +572,10 @@ restart_search: } if (macro.name() == useMacro.name()) { - unsigned lineStart; - const QByteArray &lineSource = matchingLine(use.begin(), source, &lineStart); - usages.append(Usage(fileName, QString::fromUtf8(lineSource), use.beginLine(), - use.begin() - lineStart, useMacro.name().length())); + unsigned column; + const QString &lineSource = matchingLine(use.bytesBegin(), source, &column); + usages.append(Usage(fileName, lineSource, use.beginLine(), column, + useMacro.nameToQString().size())); } } } @@ -585,19 +585,26 @@ restart_search: return usages; } - static QByteArray matchingLine(unsigned position, const QByteArray &source, - unsigned *lineStart = 0) + static QString matchingLine(unsigned bytesOffsetOfUseStart, const QByteArray &utf8Source, + unsigned *columnOfUseStart = 0) { - int lineBegin = source.lastIndexOf('\n', position) + 1; - int lineEnd = source.indexOf('\n', position); + int lineBegin = utf8Source.lastIndexOf('\n', bytesOffsetOfUseStart) + 1; + int lineEnd = utf8Source.indexOf('\n', bytesOffsetOfUseStart); if (lineEnd == -1) - lineEnd = source.length(); - - if (lineStart) - *lineStart = lineBegin; + lineEnd = utf8Source.length(); + + if (columnOfUseStart) { + *columnOfUseStart = 0; + const char *startOfUse = utf8Source.constData() + bytesOffsetOfUseStart; + QTC_ASSERT(startOfUse < utf8Source.constData() + lineEnd, return QString()); + const char *currentSourceByte = utf8Source.constData() + lineBegin; + unsigned char yychar = *currentSourceByte; + while (currentSourceByte != startOfUse) + Lexer::yyinp_utf8(currentSourceByte, yychar, *columnOfUseStart); + } - const QByteArray matchingLine = source.mid(lineBegin, lineEnd - lineBegin); - return matchingLine; + const QByteArray matchingLine = utf8Source.mid(lineBegin, lineEnd - lineBegin); + return QString::fromUtf8(matchingLine, matchingLine.size()); } }; @@ -638,7 +645,7 @@ void CppFindReferences::findMacroUses(const Macro ¯o, const QString &replace Core::SearchResult *search = Core::SearchResultWindow::instance()->startNewSearch( tr("C++ Macro Usages:"), QString(), - QString::fromUtf8(macro.name()), + macro.nameToQString(), replace ? Core::SearchResultWindow::SearchAndReplace : Core::SearchResultWindow::SearchOnly, Core::SearchResultWindow::PreserveCaseDisabled, @@ -661,11 +668,11 @@ void CppFindReferences::findMacroUses(const Macro ¯o, const QString &replace // add the macro definition itself { const QByteArray &source = getSource(macro.fileName(), workingCopy); - unsigned lineStart; - const QByteArray line = FindMacroUsesInFile::matchingLine(macro.offset(), source, - &lineStart); - search->addResult(macro.fileName(), macro.line(), QString::fromUtf8(line), - macro.offset() - lineStart, macro.name().length()); + unsigned column; + const QString line = FindMacroUsesInFile::matchingLine(macro.bytesOffset(), source, + &column); + search->addResult(macro.fileName(), macro.line(), line, column, + macro.nameToQString().length()); } QFuture<Usage> result; @@ -679,7 +686,7 @@ void CppFindReferences::findMacroUses(const Macro ¯o, const QString &replace void CppFindReferences::renameMacroUses(const Macro ¯o, const QString &replacement) { - const QString textToReplace = replacement.isEmpty() ? QString::fromUtf8(macro.name()) : replacement; + const QString textToReplace = replacement.isEmpty() ? macro.nameToQString() : replacement; findMacroUses(macro, textToReplace, true); } diff --git a/src/plugins/cpptools/cpphighlightingsupportinternal.cpp b/src/plugins/cpptools/cpphighlightingsupportinternal.cpp index 0fe3351d94..29bf316082 100644 --- a/src/plugins/cpptools/cpphighlightingsupportinternal.cpp +++ b/src/plugins/cpptools/cpphighlightingsupportinternal.cpp @@ -59,15 +59,15 @@ QFuture<TextEditor::HighlightingResult> CppHighlightingSupportInternal::highligh // Get macro definitions foreach (const CPlusPlus::Macro& macro, doc->definedMacros()) { int line, column; - editor()->convertPosition(macro.offset(), &line, &column); + editor()->convertPosition(macro.utf16CharOffset(), &line, &column); ++column; //Highlighting starts at (column-1) --> compensate here - Result use(line, column, macro.name().size(), MacroUse); + Result use(line, column, macro.nameToQString().size(), MacroUse); macroUses.append(use); } // Get macro uses foreach (const Document::MacroUse ¯o, doc->macroUses()) { - const QString name = QString::fromUtf8(macro.macro().name()); + const QString name = macro.macro().nameToQString(); //Filter out QtKeywords if (isQtKeyword(QStringRef(&name))) @@ -86,7 +86,7 @@ QFuture<TextEditor::HighlightingResult> CppHighlightingSupportInternal::highligh continue; int line, column; - editor()->convertPosition(macro.begin(), &line, &column); + editor()->convertPosition(macro.utf16charsBegin(), &line, &column); ++column; //Highlighting starts at (column-1) --> compensate here Result use(line, column, name.size(), MacroUse); macroUses.append(use); diff --git a/src/plugins/cpptools/cpppreprocessor.cpp b/src/plugins/cpptools/cpppreprocessor.cpp index c6dfc5012b..4e809989ad 100644 --- a/src/plugins/cpptools/cpppreprocessor.cpp +++ b/src/plugins/cpptools/cpppreprocessor.cpp @@ -291,41 +291,51 @@ static inline const Macro revision(const CppModelManagerInterface::WorkingCopy & return newMacro; } -void CppPreprocessor::passedMacroDefinitionCheck(unsigned offset, unsigned line, const Macro ¯o) +void CppPreprocessor::passedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset, + unsigned line, const Macro ¯o) { if (!m_currentDoc) return; - m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line, - QVector<MacroArgumentReference>()); + m_currentDoc->addMacroUse(revision(m_workingCopy, macro), + bytesOffset, macro.name().length(), + utf16charsOffset, macro.nameToQString().size(), + line, QVector<MacroArgumentReference>()); } -void CppPreprocessor::failedMacroDefinitionCheck(unsigned offset, const ByteArrayRef &name) +void CppPreprocessor::failedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charOffset, + const ByteArrayRef &name) { if (!m_currentDoc) return; - m_currentDoc->addUndefinedMacroUse(QByteArray(name.start(), name.size()), offset); + m_currentDoc->addUndefinedMacroUse(QByteArray(name.start(), name.size()), + bytesOffset, utf16charOffset); } -void CppPreprocessor::notifyMacroReference(unsigned offset, unsigned line, const Macro ¯o) +void CppPreprocessor::notifyMacroReference(unsigned bytesOffset, unsigned utf16charOffset, + unsigned line, const Macro ¯o) { if (!m_currentDoc) return; - m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line, - QVector<MacroArgumentReference>()); + m_currentDoc->addMacroUse(revision(m_workingCopy, macro), + bytesOffset, macro.name().length(), + utf16charOffset, macro.nameToQString().size(), + line, QVector<MacroArgumentReference>()); } -void CppPreprocessor::startExpandingMacro(unsigned offset, unsigned line, - const Macro ¯o, +void CppPreprocessor::startExpandingMacro(unsigned bytesOffset, unsigned utf16charOffset, + unsigned line, const Macro ¯o, const QVector<MacroArgumentReference> &actuals) { if (!m_currentDoc) return; - m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line, - actuals); + m_currentDoc->addMacroUse(revision(m_workingCopy, macro), + bytesOffset, macro.name().length(), + utf16charOffset, macro.nameToQString().size(), + line, actuals); } void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &) @@ -366,16 +376,16 @@ void CppPreprocessor::mergeEnvironment(Document::Ptr doc) m_env.addMacros(doc->definedMacros()); } -void CppPreprocessor::startSkippingBlocks(unsigned offset) +void CppPreprocessor::startSkippingBlocks(unsigned utf16charsOffset) { if (m_currentDoc) - m_currentDoc->startSkippingBlocks(offset); + m_currentDoc->startSkippingBlocks(utf16charsOffset); } -void CppPreprocessor::stopSkippingBlocks(unsigned offset) +void CppPreprocessor::stopSkippingBlocks(unsigned utf16charsOffset) { if (m_currentDoc) - m_currentDoc->stopSkippingBlocks(offset); + m_currentDoc->stopSkippingBlocks(utf16charsOffset); } void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType type) diff --git a/src/plugins/cpptools/cpppreprocessor.h b/src/plugins/cpptools/cpppreprocessor.h index f8b076be8a..a250074f94 100644 --- a/src/plugins/cpptools/cpppreprocessor.h +++ b/src/plugins/cpptools/cpppreprocessor.h @@ -64,19 +64,21 @@ protected: void mergeEnvironment(CPlusPlus::Document::Ptr doc); virtual void macroAdded(const CPlusPlus::Macro ¯o); - virtual void passedMacroDefinitionCheck(unsigned offset, unsigned line, - const CPlusPlus::Macro ¯o); - virtual void failedMacroDefinitionCheck(unsigned offset, const CPlusPlus::ByteArrayRef &name); - virtual void notifyMacroReference(unsigned offset, unsigned line, - const CPlusPlus::Macro ¯o); - virtual void startExpandingMacro(unsigned offset, + virtual void passedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset, + unsigned line, const CPlusPlus::Macro ¯o); + virtual void failedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charOffset, + const CPlusPlus::ByteArrayRef &name); + virtual void notifyMacroReference(unsigned bytesOffset, unsigned utf16charOffset, + unsigned line, const CPlusPlus::Macro ¯o); + virtual void startExpandingMacro(unsigned bytesOffset, + unsigned utf16charOffset, unsigned line, const CPlusPlus::Macro ¯o, const QVector<CPlusPlus::MacroArgumentReference> &actuals); - virtual void stopExpandingMacro(unsigned offset, const CPlusPlus::Macro ¯o); + virtual void stopExpandingMacro(unsigned bytesOffset, const CPlusPlus::Macro ¯o); virtual void markAsIncludeGuard(const QByteArray ¯oName); - virtual void startSkippingBlocks(unsigned offset); - virtual void stopSkippingBlocks(unsigned offset); + virtual void startSkippingBlocks(unsigned utf16charsOffset); + virtual void stopSkippingBlocks(unsigned utf16charsOffset); virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType type); private: diff --git a/src/plugins/cpptools/cpptoolseditorsupport.cpp b/src/plugins/cpptools/cpptoolseditorsupport.cpp index 1f18b1db31..3866f774f5 100644 --- a/src/plugins/cpptools/cpptoolseditorsupport.cpp +++ b/src/plugins/cpptools/cpptoolseditorsupport.cpp @@ -333,7 +333,7 @@ void CppEditorSupport::onDocumentUpdated(Document::Ptr doc) QList<BlockRange> ifdefedOutBlocks; ifdefedOutBlocks.reserve(skippedBlocks.size()); foreach (const Document::Block &block, skippedBlocks) - ifdefedOutBlocks.append(BlockRange(block.begin(), block.end())); + ifdefedOutBlocks.append(BlockRange(block.utf16charsBegin(), block.utf16charsEnd())); setIfdefedOutBlocks(ifdefedOutBlocks); } diff --git a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp index 720bd1ea11..a7d4287dac 100644 --- a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp +++ b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp @@ -116,7 +116,8 @@ public: m_definedMacrosLine.append(macro.line()); } - virtual void passedMacroDefinitionCheck(unsigned /*offset*/, + virtual void passedMacroDefinitionCheck(unsigned /*bytesOffset*/, + unsigned /*utf16charsOffset*/, unsigned line, const Macro ¯o) { @@ -124,36 +125,39 @@ public: } virtual void failedMacroDefinitionCheck(unsigned /*offset*/, + unsigned /*utf16charsOffset*/, const ByteArrayRef &name) { m_unresolvedDefines.insert(name.toByteArray()); } - virtual void notifyMacroReference(unsigned offset, unsigned line, const Macro ¯o) + virtual void notifyMacroReference(unsigned bytesOffset, unsigned /*utf16charsOffset*/, + unsigned line, const Macro ¯o) { m_macroUsesLine[macro.name()].append(line); - m_expandedMacrosOffset.append(offset); + m_expandedMacrosOffset.append(bytesOffset); } - virtual void startExpandingMacro(unsigned offset, + virtual void startExpandingMacro(unsigned bytesOffset, + unsigned /*utf16charsOffset*/, unsigned line, const Macro ¯o, const QVector<MacroArgumentReference> &actuals = QVector<MacroArgumentReference>()) { m_expandedMacros.append(macro.name()); - m_expandedMacrosOffset.append(offset); + m_expandedMacrosOffset.append(bytesOffset); m_macroUsesLine[macro.name()].append(line); m_macroArgsCount.append(actuals.size()); } virtual void stopExpandingMacro(unsigned /*offset*/, const Macro &/*macro*/) {} - virtual void startSkippingBlocks(unsigned offset) - { m_skippedBlocks.append(Block(offset)); } + virtual void startSkippingBlocks(unsigned utf16charsOffset) + { m_skippedBlocks.append(Block(utf16charsOffset)); } - virtual void stopSkippingBlocks(unsigned offset) - { m_skippedBlocks.last().end = offset; } + virtual void stopSkippingBlocks(unsigned utf16charsOffset) + { m_skippedBlocks.last().end = utf16charsOffset; } virtual void sourceNeeded(unsigned line, const QString &includedFileName, IncludeType mode) { @@ -1762,22 +1766,22 @@ void tst_Preprocessor::undef() QCOMPARE(env.macroCount(), 4U); Macro *macro = env.macroAt(0); QCOMPARE(macro->name(), QByteArray("FOO")); - QCOMPARE(macro->offset(), 8U); + QCOMPARE(macro->bytesOffset(), 8U); QCOMPARE(macro->line(), 1U); QVERIFY(!macro->isHidden()); macro = env.macroAt(1); QCOMPARE(macro->name(), QByteArray("FOO2")); - QCOMPARE(macro->offset(), 20U); + QCOMPARE(macro->bytesOffset(), 20U); QCOMPARE(macro->line(), 2U); QVERIFY(!macro->isHidden()); macro = env.macroAt(2); QCOMPARE(macro->name(), QByteArray("FOO")); - QCOMPARE(macro->offset(), 32U); + QCOMPARE(macro->bytesOffset(), 32U); QCOMPARE(macro->line(), 3U); QVERIFY(macro->isHidden()); macro = env.macroAt(3); QCOMPARE(macro->name(), QByteArray("BAR")); - QCOMPARE(macro->offset(), 43U); + QCOMPARE(macro->bytesOffset(), 43U); QCOMPARE(macro->line(), 4U); QVERIFY(macro->isHidden()); QList<QByteArray> macros = client.definedMacros(); |