aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/cplusplus/pp-engine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/cplusplus/pp-engine.cpp')
-rw-r--r--src/libs/cplusplus/pp-engine.cpp103
1 files changed, 66 insertions, 37 deletions
diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp
index c6aabbe608e..fec9dd28067 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 &poundToken)
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 &poundToken)
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 &poundToken)
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