Commit 7bc66113 authored by Oliver Kellogg's avatar Oliver Kellogg
Browse files

Merge origin/release/21.04 @ 7d3eb053 to master.

parents e01b8ac4 7d3eb053
......@@ -285,40 +285,49 @@ ParsedFilePointer Driver::translationUnit(const QString& fileName) const
class Driver::ParseHelper
{
public:
ParseHelper(const QString& fileName, bool force, Driver* driver, bool reportMessages = true, QString includedFrom = QString()) : m_wasReset(false), m_fileName(fileName), m_previousFileName(driver->m_currentFileName), m_previousLexer(driver->lexer), m_previousParsedFile(driver->m_currentParsedFile), m_previousCachedLexedFile(driver->m_currentLexerCache), m_force(force), m_driver(driver), m_lex(m_driver)
ParseHelper(const QString& fileName, bool force, Driver* driver, bool reportMessages = true, QString includedFrom = QString())
: m_wasReset(false), m_fileName(fileName), m_previousFileName(driver->m_currentFileName), m_previousLexer(driver->lexer),
m_previousParsedFile(driver->m_currentParsedFile), m_previousCachedLexedFile(driver->m_currentLexerCache), m_force(force),
m_reportMessages(reportMessages), m_includedFrom(includedFrom), m_driver(driver), m_lex(m_driver) {}
/**
* This function must be called after constructing the ParseHelper.
*/
void init()
{
QFileInfo fileInfo(fileName);
m_driver->m_currentParsedFile = new ParsedFile(fileName, fileInfo.lastModified());
if (!includedFrom.isEmpty())
m_driver->m_currentParsedFile->setIncludedFrom(includedFrom);
QFileInfo fileInfo(m_fileName);
m_driver->m_currentParsedFile = new ParsedFile(m_fileName, fileInfo.lastModified());
if (!m_includedFrom.isEmpty())
m_driver->m_currentParsedFile->setIncludedFrom(m_includedFrom);
#ifdef CACHELEXER
m_driver->m_currentLexerCache = new CachedLexedFile(fileName, &m_driver->m_lexerCache);
m_driver->m_currentLexerCache = new CachedLexedFile(m_fileName, &m_driver->m_lexerCache);
#endif
m_absoluteFilePath = fileInfo.absoluteFilePath();
QMap<QString, ParsedFilePointer>::Iterator it = m_driver->m_parsedUnits.find(m_absoluteFilePath);
if (force && it != m_driver->m_parsedUnits.end()) {
if (m_force && it != m_driver->m_parsedUnits.end()) {
m_driver->takeTranslationUnit(m_absoluteFilePath);
} else if (it != m_driver->m_parsedUnits.end() && *it != (ParsedFilePointer)0) {
// file already processed
return ;
}
CachedLexedFilePointer lexedFileP = m_driver->m_lexerCache.lexedFile(HashedString(fileName));
CachedLexedFilePointer lexedFileP = m_driver->m_lexerCache.lexedFile(HashedString(m_fileName));
m_driver->m_dependences.remove(fileName);
m_driver->m_problems.remove(fileName);
m_driver->m_dependences.remove(m_fileName);
m_driver->m_problems.remove(m_fileName);
driver->m_currentFileName = fileName;
m_driver->m_currentFileName = m_fileName;
m_driver->lexer = &m_lex;
m_driver->setupLexer(&m_lex);
m_lex.setReportMessages(reportMessages);
m_lex.setReportMessages(m_reportMessages);
DBG_DRV << "lexing file " << fileName << endl;
m_lex.setSource(m_driver->sourceProvider() ->contents(fileName));
DBG_DRV << "lexing file " << m_fileName << endl;
m_fileContent = m_driver->sourceProvider()->contents(m_fileName);
m_lex.setSource(m_fileContent);
if (m_previousCachedLexedFile)
m_previousCachedLexedFile->merge(*m_driver->m_currentLexerCache);
else
......@@ -385,8 +394,11 @@ private:
ParsedFilePointer m_previousParsedFile;
CachedLexedFilePointer m_previousCachedLexedFile;
bool m_force;
bool m_reportMessages;
QString m_includedFrom;
Driver* m_driver;
Lexer m_lex;
QString m_fileContent;
};
......@@ -441,7 +453,7 @@ void Driver::addDependence(const QString & fileName, const Dependence & dep)
CachedLexedFilePointer lexedFileP = m_lexerCache.lexedFile(HashedString(file));
if (lexedFileP) {
CachedLexedFile& lexedFile(*lexedFileP);
m_currentLexerCache->merge(lexedFile); //The ParseHelper will will copy the include-files into the result later
m_currentLexerCache->merge(lexedFile); //The ParseHelper will copy the include-files into the result later
for (MacroSet::Macros::const_iterator it = lexedFile.definedMacros().macros().begin(); it != lexedFile.definedMacros().macros().end(); ++it) {
addMacro((*it));
}
......@@ -450,6 +462,7 @@ void Driver::addDependence(const QString & fileName, const Dependence & dep)
}
ParseHelper h(file, true, this, false, m_currentMasterFileName);
h.init();
/*if (m_parsedUnits.find(file) != m_parsedUnits.end())
return;*/
......@@ -553,6 +566,7 @@ bool Driver::parseFile(const QString& fileName, bool onlyPreProcess, bool force
m_includePaths = getCustomIncludePath(fileName);
ParseHelper p(fileName, force, this);
p.init();
if (!onlyPreProcess) {
p.parse();
}
......
This diff is collapsed.
......@@ -252,21 +252,8 @@ public:
return m_currentColumn;
}
inline const CHARTYPE* offset(int offset) const
{
Q_ASSERT(offset >= 0);
Q_ASSERT(offset <= m_source.length());
return m_source.unicode() + offset;
}
inline int getOffset(const QChar* p) const
{
const QChar* src = m_source.unicode();
Q_ASSERT(p >= src);
int result = int(p - src);
Q_ASSERT(result <= m_source.length());
return result;
}
const CHARTYPE* offset(int offset) const;
int getOffset(const QChar* p) const;
private:
void setEndPtr(const QChar* c)
......@@ -289,7 +276,7 @@ private:
void nextChar(int n);
void skip(int l, int r);
void readIdentifier();
void readWhiteSpaces(bool skipNewLine=true, bool skipOnlyOnce=false);
bool readWhiteSpaces(bool skipNewLine=true, bool skipOnlyOnce=false);
void readLineComment();
void readMultiLineComment();
void readCharLiteral();
......@@ -335,6 +322,7 @@ private:
int m_size;
int m_index;
QString m_source;
const QChar* m_src;
const QChar* m_ptr;
const QChar* m_endPtr;
QChar m_currentChar;
......@@ -364,546 +352,4 @@ private:
void operator = (const Lexer& source);
};
inline Token::Token(const QString & text)
: m_type(-1),
m_position(0),
m_length(0),
m_startLine(0),
m_startColumn(0),
m_endLine(0),
m_endColumn(0),
m_text(text)
{
}
inline Token::Token(int type, int position, int length, const QString& text)
: m_type(type),
m_position(position),
m_length(length),
m_startLine(0),
m_startColumn(0),
m_endLine(0),
m_endColumn(0),
m_text(text)
{
DBG_LEXER << type << position << length << text.mid(position, length);
}
inline Token::Token(const Token& source)
: m_type(source.m_type),
m_position(source.m_position),
m_length(source.m_length),
m_startLine(source.m_startLine),
m_startColumn(source.m_startColumn),
m_endLine(source.m_endLine),
m_endColumn(source.m_endColumn),
m_text(source.m_text)
{
}
inline Token& Token::operator = (const Token& source)
{
m_type = source.m_type;
m_position = source.m_position;
m_length = source.m_length;
m_startLine = source.m_startLine;
m_startColumn = source.m_startColumn;
m_endLine = source.m_endLine;
m_endColumn = source.m_endColumn;
// m_text = source.m_text;
return (*this);
}
inline Token::operator int () const
{
return m_type;
}
inline bool Token::operator == (const Token& token) const
{
return m_type == token.m_type &&
m_position == token.m_position &&
m_length == token.m_length &&
m_startLine == token.m_startLine &&
m_startColumn == token.m_startColumn &&
m_endLine == token.m_endLine &&
m_endColumn == token.m_endColumn &&
m_text == token.m_text;
}
inline bool Token::isNull() const
{
return m_type == Token_eof || m_length == 0;
}
inline int Token::type() const
{
return m_type;
}
inline void Token::setType(int type)
{
m_type = type;
}
inline int Token::position() const
{
return m_position;
}
inline QString Token::text() const
{
return m_text.mid(m_position, m_length);
}
inline void Token::setStartPosition(int line, int column)
{
m_startLine = line;
m_startColumn = column;
}
inline void Token::setEndPosition(int line, int column)
{
m_endLine = line;
m_endColumn = column;
}
inline void Token::getStartPosition(int* line, int* column) const
{
if (line) *line = m_startLine;
if (column) *column = m_startColumn;
}
inline void Token::getEndPosition(int* line, int* column) const
{
if (line) *line = m_endLine;
if (column) *column = m_endColumn;
}
inline void Token::setPosition(int position)
{
m_position = position;
}
inline unsigned int Token::length() const
{
return m_length;
}
inline void Token::setLength(unsigned int length)
{
m_length = length;
}
inline bool Lexer::recordComments() const
{
return m_recordComments;
}
inline void Lexer::setRecordComments(bool record)
{
m_recordComments = record;
}
inline bool Lexer::recordWhiteSpaces() const
{
return m_recordWhiteSpaces;
}
inline void Lexer::setRecordWhiteSpaces(bool record)
{
m_recordWhiteSpaces = record;
}
inline QString Lexer::source() const
{
return m_source;
}
inline int Lexer::index() const
{
return m_index;
}
inline void Lexer::setIndex(int index)
{
m_index = index;
}
inline const Token& Lexer::nextToken()
{
if (m_index < m_size)
return *m_tokens[ m_index++ ];
return *m_tokens[ m_index ];
}
inline const Token& Lexer::tokenAt(int n) const
{
return *m_tokens[ qMin(n, m_size-1) ];
}
inline const Token& Lexer::lookAhead(int n) const
{
Token &t = *m_tokens[ qMin(m_index + n, m_size-1) ];
DBG_LEXER << t;
return t;
}
inline int Lexer::tokenPosition(const Token& token) const
{
return token.position();
}
inline void Lexer::nextChar()
{
if (m_ptr >= m_endPtr) {
m_currentChar = QChar();
return;
}
if (*m_ptr == QLatin1Char('\n')) {
++m_currentLine;
m_currentColumn = 0;
m_startLine = true;
} else {
++m_currentColumn;
}
++m_ptr;
if (m_ptr < m_endPtr)
m_currentChar = *m_ptr;
else
m_currentChar = QChar();
}
inline void Lexer::nextChar(int n)
{
if (m_ptr + n >= m_endPtr) {
m_ptr = m_endPtr;
m_currentChar = QChar();
return;
}
m_currentColumn += n;
m_ptr += n;
if (m_ptr < m_endPtr)
m_currentChar = *m_ptr;
else
m_currentChar = QChar();
}
inline void Lexer::readIdentifier()
{
while (currentChar().isLetterOrNumber() || currentChar() == QLatin1Char('_'))
nextChar();
}
inline void Lexer::readWhiteSpaces(bool skipNewLine, bool skipOnlyOnce)
{
while (!currentChar().isNull()) {
QChar ch = currentChar();
if (ch == QLatin1Char('\n') && !skipNewLine) {
break;
} else if (ch.isSpace()) {
nextChar();
} else if (m_inPreproc && currentChar() == QLatin1Char('\\')) {
nextChar();
readWhiteSpaces(true, true);
} else {
break;
}
if (skipOnlyOnce && ch == QLatin1Char('\n')) {
skipNewLine = false;
}
}
}
//little hack for better performance
inline bool isTodo(const QString& txt, int position)
{
if (txt.length() < position + 4) return false;
return (txt[ position ] == QLatin1Char('t') || txt[ position ] == QLatin1Char('T'))
&& (txt[ position+1 ] == QLatin1Char('o') || txt[ position+1 ] == QLatin1Char('O'))
&& (txt[ position+2 ] == QLatin1Char('d') || txt[ position+2 ] == QLatin1Char('D'))
&& (txt[ position+3 ] == QLatin1Char('o') || txt[ position+3 ] == QLatin1Char('O'));
}
inline bool isFixme(const QString& txt, int position)
{
if (txt.length() < position + 5) return false;
return (txt[ position ] == QLatin1Char('f') || txt[ position ] == QLatin1Char('F'))
&& (txt[ position+1 ] == QLatin1Char('i') || txt[ position+1 ] == QLatin1Char('I'))
&& (txt[ position+2 ] == QLatin1Char('x') || txt[ position+2 ] == QLatin1Char('X'))
&& (txt[ position+3 ] == QLatin1Char('m') || txt[ position+3 ] == QLatin1Char('M'))
&& (txt[ position+4 ] == QLatin1Char('e') || txt[ position+4 ] == QLatin1Char('E'));
}
inline void Lexer::readLineComment()
{
while (!currentChar().isNull() && currentChar() != QLatin1Char('\n')) {
if (m_reportMessages && isTodo(m_source, currentPosition())) {
nextChar(4);
QString msg;
int line = m_currentLine;
int col = m_currentColumn;
while (!currentChar().isNull()) {
if (currentChar() == QLatin1Char('*') && peekChar() == QLatin1Char('/'))
break;
else if (currentChar() == QLatin1Char('\n'))
break;
msg += currentChar();
nextChar();
}
m_driver->addProblem(m_driver->currentFileName(), Problem(msg, line, col, Problem::Level_Todo));
} else if (m_reportMessages && isFixme(m_source, currentPosition())) {
nextChar(5);
QString msg;
int line = m_currentLine;
int col = m_currentColumn;
while (!currentChar().isNull()) {
if (currentChar() == QLatin1Char('*') && peekChar() == QLatin1Char('/'))
break;
else if (currentChar() == QLatin1Char('\n'))
break;
msg += currentChar();
nextChar();
}
m_driver->addProblem(m_driver->currentFileName(), Problem(msg, line, col, Problem::Level_Fixme));
} else
nextChar();
}
}
inline void Lexer::readMultiLineComment()
{
while (!currentChar().isNull()) {
if (currentChar() == QLatin1Char('*') && peekChar() == QLatin1Char('/')) {
nextChar(2);
return;
} else if (m_reportMessages && isTodo(m_source, currentPosition())) {
nextChar(4);
QString msg;
int line = m_currentLine;
int col = m_currentColumn;
while (!currentChar().isNull()) {
if (currentChar() == QLatin1Char('*') && peekChar() == QLatin1Char('/'))
break;
else if (currentChar() == QLatin1Char('\n'))
break;
msg += currentChar();
nextChar();
}
m_driver->addProblem(m_driver->currentFileName(), Problem(msg, line, col, Problem::Level_Todo));
} else if (m_reportMessages && isFixme(m_source, currentPosition())) {
nextChar(5);
QString msg;
int line = m_currentLine;
int col = m_currentColumn;
while (!currentChar().isNull()) {
if (currentChar() == QLatin1Char('*') && peekChar() == QLatin1Char('/'))
break;
else if (currentChar() == QLatin1Char('\n'))
break;
msg += currentChar();
nextChar();
}
m_driver->addProblem(m_driver->currentFileName(), Problem(msg, line, col, Problem::Level_Fixme));
} else
nextChar();
}
}
inline void Lexer::readCharLiteral()
{
if (currentChar() == QLatin1Char('\''))
nextChar(); // skip '
else if (currentChar() == QLatin1Char('L') && peekChar() == QLatin1Char('\''))
nextChar(2); // slip L'
else
return;
while (!currentChar().isNull()) {
int len = getOffset(m_endPtr) - currentPosition();
if (len>=2 && (currentChar() == QLatin1Char('\\') && peekChar() == QLatin1Char('\''))) {
nextChar(2);
} else if (len>=2 && (currentChar() == QLatin1Char('\\') && peekChar() == QLatin1Char('\\'))) {
nextChar(2);
} else if (currentChar() == QLatin1Char('\'')) {
nextChar();
break;
} else {
nextChar();
}
}
}
inline void Lexer::readStringLiteral()
{
if (currentChar() != QLatin1Char('"'))
return;
nextChar(); // skip "
while (!currentChar().isNull()) {
int len = getOffset(m_endPtr) - currentPosition();
if (len>=2 && currentChar() == QLatin1Char('\\') && peekChar() == QLatin1Char('"')) {
nextChar(2);
} else if (len>=2 && currentChar() == QLatin1Char('\\') && peekChar() == QLatin1Char('\\')) {
nextChar(2);
} else if (currentChar() == QLatin1Char('"')) {
nextChar();
break;
} else {
nextChar();
}
}
}
inline void Lexer::readNumberLiteral()
{
while (currentChar().isLetterOrNumber() || currentChar() == QLatin1Char('.'))
nextChar();
}
inline int Lexer::findOperator3() const
{
int n = getOffset(m_endPtr) - currentPosition();
if (n >= 3) {
char ch = currentChar().toLatin1();
char ch1 = peekChar().toLatin1();
char ch2 = peekChar(2).toLatin1();
if (ch == '<' && ch1 == '<' && ch2 == '=') return Token_assign;
else if (ch == '>' && ch1 == '>' && ch2 == '=') return Token_assign;
else if (ch == '-' && ch1 == '>' && ch2 == '*') return Token_ptrmem;
else if (ch == '.' && ch1 == '.' && ch2 == '.') return Token_ellipsis;
}
return -1;
}
inline int Lexer::findOperator2() const
{
int n = getOffset(m_endPtr) - currentPosition();
if (n>=2) {
char ch = currentChar().toLatin1(), ch1 = peekChar().toLatin1();
if (ch == ':' && ch1 == ':') return Token_scope;
else if (ch == '.' && ch1 == '*') return Token_ptrmem;
else if (ch == '+' && ch1 == '=') return Token_assign;
else if (ch == '-' && ch1 == '=') return Token_assign;
else if (ch == '*' && ch1 == '=') return Token_assign;
else if (ch == '/' && ch1 == '=') return Token_assign;
else if (ch == '%' && ch1 == '=') return Token_assign;
else if (ch == '^' && ch1 == '=') return Token_assign;
else if (ch == '&' && ch1 == '=') return Token_assign;
else if (ch == '|' && ch1 == '=') return Token_assign;
else if (ch == '<' && ch1 == '<') return Token_shift;
//else if(ch == '>' && ch1 == '>') return Token_shift;
else if (ch == '=' && ch1 == '=') return Token_eq;
else if (ch == '!' && ch1 == '=') return Token_eq;
else if (ch == '<' && ch1 == '=') return Token_leq;
else if (ch == '>' && ch1 == '=') return Token_geq;
else if (ch == '&' && ch1 == '&') return Token_and;
else if (ch == '|' && ch1 == '|') return Token_or;
else if (ch == '+' && ch1 == '+') return Token_incr;
else if (ch == '-' && ch1 == '-') return Token_decr;
else if (ch == '-' && ch1 == '>') return Token_arrow;
else if (ch == '#' && ch1 == '#') return Token_concat;
}
return -1;
}