forked from qt-creator/qt-creator
C++: Fix preprocessor line offsets
In TranslationUnit, the "normal" lines are based on utf16char offsets, but the preprocessor lines were based on byte/latin1 offsets. The preprocessor lines are now based on utf16char offsets, too. Task-number: QTCREATORBUG-7356 Change-Id: I3c41d1dcee8e9e487210f36da806b0229d3f4cd0 Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
14
src/libs/3rdparty/cplusplus/TranslationUnit.cpp
vendored
14
src/libs/3rdparty/cplusplus/TranslationUnit.cpp
vendored
@@ -164,7 +164,7 @@ void TranslationUnit::tokenize()
|
|||||||
|
|
||||||
_Lrecognize:
|
_Lrecognize:
|
||||||
if (tk.is(T_POUND) && tk.newline()) {
|
if (tk.is(T_POUND) && tk.newline()) {
|
||||||
unsigned offset = tk.byteOffset;
|
const unsigned utf16CharOffset = tk.utf16charOffset;
|
||||||
lex(&tk);
|
lex(&tk);
|
||||||
|
|
||||||
if (! tk.newline() && tk.is(T_IDENTIFIER) && tk.identifier == expansionId) {
|
if (! tk.newline() && tk.is(T_IDENTIFIER) && tk.identifier == expansionId) {
|
||||||
@@ -237,7 +237,7 @@ void TranslationUnit::tokenize()
|
|||||||
if (! tk.newline() && tk.is(T_STRING_LITERAL)) {
|
if (! tk.newline() && tk.is(T_STRING_LITERAL)) {
|
||||||
const StringLiteral *fileName =
|
const StringLiteral *fileName =
|
||||||
control()->stringLiteral(tk.string->chars(), tk.string->size());
|
control()->stringLiteral(tk.string->chars(), tk.string->size());
|
||||||
pushPreprocessorLine(offset, line, fileName);
|
pushPreprocessorLine(utf16CharOffset, line, fileName);
|
||||||
lex(&tk);
|
lex(&tk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,10 +343,10 @@ bool TranslationUnit::parse(ParseMode mode)
|
|||||||
void TranslationUnit::pushLineOffset(unsigned offset)
|
void TranslationUnit::pushLineOffset(unsigned offset)
|
||||||
{ _lineOffsets.push_back(offset); }
|
{ _lineOffsets.push_back(offset); }
|
||||||
|
|
||||||
void TranslationUnit::pushPreprocessorLine(unsigned offset,
|
void TranslationUnit::pushPreprocessorLine(unsigned utf16charOffset,
|
||||||
unsigned line,
|
unsigned line,
|
||||||
const StringLiteral *fileName)
|
const StringLiteral *fileName)
|
||||||
{ _ppLines.push_back(PPLine(offset, line, fileName)); }
|
{ _ppLines.push_back(PPLine(utf16charOffset, line, fileName)); }
|
||||||
|
|
||||||
unsigned TranslationUnit::findLineNumber(unsigned utf16charOffset) const
|
unsigned TranslationUnit::findLineNumber(unsigned utf16charOffset) const
|
||||||
{
|
{
|
||||||
@@ -359,10 +359,10 @@ unsigned TranslationUnit::findLineNumber(unsigned utf16charOffset) const
|
|||||||
return it - _lineOffsets.begin();
|
return it - _lineOffsets.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
TranslationUnit::PPLine TranslationUnit::findPreprocessorLine(unsigned offset) const
|
TranslationUnit::PPLine TranslationUnit::findPreprocessorLine(unsigned utf16charOffset) const
|
||||||
{
|
{
|
||||||
std::vector<PPLine>::const_iterator it =
|
std::vector<PPLine>::const_iterator it =
|
||||||
std::lower_bound(_ppLines.begin(), _ppLines.end(), PPLine(offset));
|
std::lower_bound(_ppLines.begin(), _ppLines.end(), PPLine(utf16charOffset));
|
||||||
|
|
||||||
if (it != _ppLines.begin())
|
if (it != _ppLines.begin())
|
||||||
--it;
|
--it;
|
||||||
@@ -419,7 +419,7 @@ void TranslationUnit::getPosition(unsigned utf16charOffset,
|
|||||||
|
|
||||||
// Adjust the line in regards to the preprocessing markers.
|
// Adjust the line in regards to the preprocessing markers.
|
||||||
const PPLine ppLine = findPreprocessorLine(utf16charOffset);
|
const PPLine ppLine = findPreprocessorLine(utf16charOffset);
|
||||||
lineNumber -= findLineNumber(ppLine.offset) + 1;
|
lineNumber -= findLineNumber(ppLine.utf16charOffset) + 1;
|
||||||
lineNumber += ppLine.line;
|
lineNumber += ppLine.line;
|
||||||
|
|
||||||
file = ppLine.fileName;
|
file = ppLine.fileName;
|
||||||
|
|||||||
16
src/libs/3rdparty/cplusplus/TranslationUnit.h
vendored
16
src/libs/3rdparty/cplusplus/TranslationUnit.h
vendored
@@ -138,7 +138,7 @@ public:
|
|||||||
const StringLiteral **fileName = 0) const;
|
const StringLiteral **fileName = 0) const;
|
||||||
|
|
||||||
void pushLineOffset(unsigned offset);
|
void pushLineOffset(unsigned offset);
|
||||||
void pushPreprocessorLine(unsigned offset,
|
void pushPreprocessorLine(unsigned utf16charOffset,
|
||||||
unsigned line,
|
unsigned line,
|
||||||
const StringLiteral *fileName);
|
const StringLiteral *fileName);
|
||||||
|
|
||||||
@@ -151,30 +151,30 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
struct PPLine {
|
struct PPLine {
|
||||||
unsigned offset;
|
unsigned utf16charOffset;
|
||||||
unsigned line;
|
unsigned line;
|
||||||
const StringLiteral *fileName;
|
const StringLiteral *fileName;
|
||||||
|
|
||||||
PPLine(unsigned offset = 0,
|
PPLine(unsigned utf16charOffset = 0,
|
||||||
unsigned line = 0,
|
unsigned line = 0,
|
||||||
const StringLiteral *fileName = 0)
|
const StringLiteral *fileName = 0)
|
||||||
: offset(offset), line(line), fileName(fileName)
|
: utf16charOffset(utf16charOffset), line(line), fileName(fileName)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool operator == (const PPLine &other) const
|
bool operator == (const PPLine &other) const
|
||||||
{ return offset == other.offset; }
|
{ return utf16charOffset == other.utf16charOffset; }
|
||||||
|
|
||||||
bool operator != (const PPLine &other) const
|
bool operator != (const PPLine &other) const
|
||||||
{ return offset != other.offset; }
|
{ return utf16charOffset != other.utf16charOffset; }
|
||||||
|
|
||||||
bool operator < (const PPLine &other) const
|
bool operator < (const PPLine &other) const
|
||||||
{ return offset < other.offset; }
|
{ return utf16charOffset < other.utf16charOffset; }
|
||||||
};
|
};
|
||||||
|
|
||||||
void releaseTokensAndComments();
|
void releaseTokensAndComments();
|
||||||
unsigned findLineNumber(unsigned utf16charOffset) const;
|
unsigned findLineNumber(unsigned utf16charOffset) const;
|
||||||
unsigned findColumnNumber(unsigned utf16CharOffset, unsigned lineNumber) const;
|
unsigned findColumnNumber(unsigned utf16CharOffset, unsigned lineNumber) const;
|
||||||
PPLine findPreprocessorLine(unsigned offset) const;
|
PPLine findPreprocessorLine(unsigned utf16charOffset) const;
|
||||||
void showErrorLine(unsigned index, unsigned column, FILE *out);
|
void showErrorLine(unsigned index, unsigned column, FILE *out);
|
||||||
|
|
||||||
static const Token nullToken;
|
static const Token nullToken;
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ public:
|
|||||||
// Preprocess source
|
// Preprocess source
|
||||||
Environment env;
|
Environment env;
|
||||||
Preprocessor preprocess(0, &env);
|
Preprocessor preprocess(0, &env);
|
||||||
|
preprocess.setKeepComments(true);
|
||||||
const QByteArray preprocessedSource = preprocess.run(filePath, source);
|
const QByteArray preprocessedSource = preprocess.run(filePath, source);
|
||||||
|
|
||||||
document->setUtf8Source(preprocessedSource);
|
document->setUtf8Source(preprocessedSource);
|
||||||
@@ -1687,6 +1688,26 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
<< Use(9, 1, 5, Highlighting::TypeUse)
|
<< Use(9, 1, 5, Highlighting::TypeUse)
|
||||||
<< Use(9, 1, 5, Highlighting::TypeUse)
|
<< Use(9, 1, 5, Highlighting::TypeUse)
|
||||||
<< Use(9, 9, 5, Highlighting::TypeUse));
|
<< Use(9, 9, 5, Highlighting::TypeUse));
|
||||||
|
|
||||||
|
#define UC_U10302_4TIMES UC_U10302 UC_U10302 UC_U10302 UC_U10302
|
||||||
|
#define UC_U10302_12TIMES UC_U10302_4TIMES UC_U10302_4TIMES UC_U10302_4TIMES
|
||||||
|
QTest::newRow("unicodeComments1")
|
||||||
|
<< _("#define NULL 0\n"
|
||||||
|
"\n"
|
||||||
|
"// " UC_U10302_12TIMES "\n"
|
||||||
|
"// " UC_U10302_12TIMES "\n"
|
||||||
|
"\n"
|
||||||
|
"class Foo {\n"
|
||||||
|
"double f(bool b = NULL);\n"
|
||||||
|
"Foo *x;\n"
|
||||||
|
"};\n")
|
||||||
|
<< (UseList()
|
||||||
|
<< Use(6, 7, 3, CppHighlightingSupport::TypeUse)
|
||||||
|
<< Use(7, 8, 1, CppHighlightingSupport::FunctionUse)
|
||||||
|
<< Use(8, 1, 3, CppHighlightingSupport::TypeUse)
|
||||||
|
<< Use(8, 6, 1, CppHighlightingSupport::FieldUse));
|
||||||
|
#undef UC_U10302_12TIMES
|
||||||
|
#undef UC_U10302_4TIMES
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_CheckSymbols::test_checksymbols_macroUses()
|
void tst_CheckSymbols::test_checksymbols_macroUses()
|
||||||
|
|||||||
Reference in New Issue
Block a user