diff options
Diffstat (limited to 'src/plugins/cpptools/cpppreprocessor.cpp')
-rw-r--r-- | src/plugins/cpptools/cpppreprocessor.cpp | 127 |
1 files changed, 68 insertions, 59 deletions
diff --git a/src/plugins/cpptools/cpppreprocessor.cpp b/src/plugins/cpptools/cpppreprocessor.cpp index 57a3fb4a72..48cb7fc77c 100644 --- a/src/plugins/cpptools/cpppreprocessor.cpp +++ b/src/plugins/cpptools/cpppreprocessor.cpp @@ -1,7 +1,9 @@ -#include "cppmodelmanager.h" #include "cpppreprocessor.h" +#include "cppmodelmanager.h" + #include <utils/hostosinfo.h> +#include <utils/textfileformat.h> #include <QCoreApplication> @@ -21,7 +23,8 @@ using namespace CPlusPlus; using namespace CppTools; using namespace CppTools::Internal; -CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager, bool dumpFileNameWhileParsing) +CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager, + bool dumpFileNameWhileParsing) : m_snapshot(modelManager->snapshot()), m_modelManager(modelManager), m_dumpFileNameWhileParsing(dumpFileNameWhileParsing), @@ -68,10 +71,8 @@ void CppPreprocessor::setIncludePaths(const QStringList &includePaths) void CppPreprocessor::setFrameworkPaths(const QStringList &frameworkPaths) { m_frameworkPaths.clear(); - - foreach (const QString &frameworkPath, frameworkPaths) { + foreach (const QString &frameworkPath, frameworkPaths) addFrameworkPath(frameworkPath); - } } // Add the given framework path, and expand private frameworks. @@ -86,7 +87,7 @@ void CppPreprocessor::addFrameworkPath(const QString &frameworkPath) // The algorithm below is a bit too eager, but that's because we're not getting // in the frameworks we're linking against. If we would have that, then we could // add only those private frameworks. - QString cleanFrameworkPath = cleanPath(frameworkPath); + const QString cleanFrameworkPath = cleanPath(frameworkPath); if (!m_frameworkPaths.contains(cleanFrameworkPath)) m_frameworkPaths.append(cleanFrameworkPath); @@ -95,7 +96,8 @@ void CppPreprocessor::addFrameworkPath(const QString &frameworkPath) foreach (const QFileInfo &framework, frameworkDir.entryInfoList(filter)) { if (!framework.isDir()) continue; - const QFileInfo privateFrameworks(framework.absoluteFilePath(), QLatin1String("Frameworks")); + const QFileInfo privateFrameworks(framework.absoluteFilePath(), + QLatin1String("Frameworks")); if (privateFrameworks.exists() && privateFrameworks.isDir()) addFrameworkPath(privateFrameworks.absoluteFilePath()); } @@ -119,7 +121,6 @@ public: _doc(doc), _mode(Document::FastCheck) { - if (workingCopy.contains(_doc->fileName())) _mode = Document::FullCheck; } @@ -154,14 +155,14 @@ void CppPreprocessor::resetEnvironment() } void CppPreprocessor::getFileContents(const QString &absoluteFilePath, - QString *contents, + QByteArray *contents, unsigned *revision) const { if (absoluteFilePath.isEmpty()) return; if (m_workingCopy.contains(absoluteFilePath)) { - QPair<QString, unsigned> entry = m_workingCopy.get(absoluteFilePath); + const QPair<QByteArray, unsigned> entry = m_workingCopy.get(absoluteFilePath); if (contents) *contents = entry.first; if (revision) @@ -169,17 +170,11 @@ void CppPreprocessor::getFileContents(const QString &absoluteFilePath, return; } - QFile file(absoluteFilePath); - if (file.open(QFile::ReadOnly | QFile::Text)) { - QTextCodec *defaultCodec = Core::EditorManager::instance()->defaultTextCodec(); - QTextStream stream(&file); - stream.setCodec(defaultCodec); - if (contents) - *contents = stream.readAll(); - if (revision) - *revision = 0; - file.close(); - } + QString errStr; + if (contents) + Utils::TextFileFormat::readFileUTF8(absoluteFilePath, contents, &errStr); + if (revision) + *revision = 0; } bool CppPreprocessor::checkFile(const QString &absoluteFilePath) const @@ -187,7 +182,7 @@ bool CppPreprocessor::checkFile(const QString &absoluteFilePath) const if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) return true; - QFileInfo fileInfo(absoluteFilePath); + const QFileInfo fileInfo(absoluteFilePath); return fileInfo.isFile() && fileInfo.isReadable(); } @@ -218,48 +213,51 @@ QString CppPreprocessor::cleanPath(const QString &path) QString CppPreprocessor::resolveFile_helper(const QString &fileName, IncludeType type) { - QFileInfo fileInfo(fileName); + const QFileInfo fileInfo(fileName); if (fileName == Preprocessor::configurationFileName || fileInfo.isAbsolute()) return fileName; if (type == IncludeLocal && m_currentDoc) { - QFileInfo currentFileInfo(m_currentDoc->fileName()); - QString path = cleanPath(currentFileInfo.absolutePath()) + fileName; + const QFileInfo currentFileInfo(m_currentDoc->fileName()); + const QString path = cleanPath(currentFileInfo.absolutePath()) + fileName; if (checkFile(path)) return path; + // Fall through! "16.2 Source file inclusion" from the standard states to continue + // searching as if this would be a global include. } foreach (const QString &includePath, m_includePaths) { - QString path = includePath + fileName; + const QString path = includePath + fileName; if (m_workingCopy.contains(path) || checkFile(path)) return path; } - int index = fileName.indexOf(QLatin1Char('/')); + const int index = fileName.indexOf(QLatin1Char('/')); if (index != -1) { - QString frameworkName = fileName.left(index); - QString name = frameworkName + QLatin1String(".framework/Headers/") + fileName.mid(index + 1); + const QString frameworkName = fileName.left(index); + const QString name = frameworkName + QLatin1String(".framework/Headers/") + + fileName.mid(index + 1); foreach (const QString &frameworkPath, m_frameworkPaths) { - QString path = frameworkPath + name; + const QString path = frameworkPath + name; if (checkFile(path)) return path; } } - //qDebug() << "**** file" << fileName << "not found!"; return QString(); } void CppPreprocessor::macroAdded(const Macro ¯o) { - if (! m_currentDoc) + if (!m_currentDoc) return; m_currentDoc->appendMacro(macro); } -static inline const Macro revision(const CppModelManagerInterface::WorkingCopy &s, const Macro ¯o) +static inline const Macro revision(const CppModelManagerInterface::WorkingCopy &s, + const Macro ¯o) { Macro newMacro(macro); newMacro.setFileRevision(s.get(macro.fileName()).second); @@ -268,7 +266,7 @@ static inline const Macro revision(const CppModelManagerInterface::WorkingCopy & void CppPreprocessor::passedMacroDefinitionCheck(unsigned offset, unsigned line, const Macro ¯o) { - if (! m_currentDoc) + if (!m_currentDoc) return; m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line, @@ -277,7 +275,7 @@ void CppPreprocessor::passedMacroDefinitionCheck(unsigned offset, unsigned line, void CppPreprocessor::failedMacroDefinitionCheck(unsigned offset, const ByteArrayRef &name) { - if (! m_currentDoc) + if (!m_currentDoc) return; m_currentDoc->addUndefinedMacroUse(QByteArray(name.start(), name.size()), offset); @@ -285,7 +283,7 @@ void CppPreprocessor::failedMacroDefinitionCheck(unsigned offset, const ByteArra void CppPreprocessor::notifyMacroReference(unsigned offset, unsigned line, const Macro ¯o) { - if (! m_currentDoc) + if (!m_currentDoc) return; m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line, @@ -296,18 +294,17 @@ void CppPreprocessor::startExpandingMacro(unsigned offset, unsigned line, const Macro ¯o, const QVector<MacroArgumentReference> &actuals) { - if (! m_currentDoc) + if (!m_currentDoc) return; - m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line, actuals); + m_currentDoc->addMacroUse(revision(m_workingCopy, macro), offset, macro.name().length(), line, + actuals); } void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &) { - if (! m_currentDoc) + if (!m_currentDoc) return; - - //qDebug() << "stop expanding:" << macro.name; } void CppPreprocessor::markAsIncludeGuard(const QByteArray ¯oName) @@ -320,7 +317,7 @@ void CppPreprocessor::markAsIncludeGuard(const QByteArray ¯oName) void CppPreprocessor::mergeEnvironment(Document::Ptr doc) { - if (! doc) + if (!doc) return; const QString fn = doc->fileName(); @@ -330,8 +327,8 @@ void CppPreprocessor::mergeEnvironment(Document::Ptr doc) m_processed.insert(fn); - foreach (const Document::Include &incl, doc->includes()) { - QString includedFile = incl.resolvedFileName(); + foreach (const Document::Include &incl, doc->resolvedIncludes()) { + const QString includedFile = incl.resolvedFileName(); if (Document::Ptr includedDoc = m_snapshot.document(includedFile)) mergeEnvironment(includedDoc); @@ -344,18 +341,28 @@ void CppPreprocessor::mergeEnvironment(Document::Ptr doc) void CppPreprocessor::startSkippingBlocks(unsigned offset) { - //qDebug() << "start skipping blocks:" << offset; if (m_currentDoc) m_currentDoc->startSkippingBlocks(offset); } void CppPreprocessor::stopSkippingBlocks(unsigned offset) { - //qDebug() << "stop skipping blocks:" << offset; if (m_currentDoc) m_currentDoc->stopSkippingBlocks(offset); } +// This is a temporary fix to handle non-ascii characters. This can be removed when the lexer can +// handle multi-byte characters. +static QByteArray convertToLatin1(const QByteArray &contents) +{ + const char *p = contents.constData(); + while (char ch = *p++) + if (ch & 0x80) + return QString::fromUtf8(contents).toLatin1(); + + return contents; +} + void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType type) { if (fileName.isEmpty()) @@ -363,7 +370,7 @@ void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, Inclu QString absoluteFileName = resolveFile(fileName, type); absoluteFileName = QDir::cleanPath(absoluteFileName); - if (m_currentDoc && !absoluteFileName.isEmpty()) + if (m_currentDoc) m_currentDoc->addIncludeFile(Document::Include(fileName, absoluteFileName, line, type)); if (m_included.contains(absoluteFileName)) return; // we've already seen this file. @@ -371,10 +378,11 @@ void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, Inclu m_included.insert(absoluteFileName); unsigned editorRevision = 0; - QString contents; + QByteArray contents; getFileContents(absoluteFileName, &contents, &editorRevision); + contents = convertToLatin1(contents); if (m_currentDoc) { - if (contents.isEmpty() && ! QFileInfo(absoluteFileName).isAbsolute()) { + if (contents.isEmpty() && !QFileInfo(absoluteFileName).isAbsolute()) { QString msg = QCoreApplication::translate( "CppPreprocessor", "%1: No such file or directory").arg(fileName); @@ -384,17 +392,14 @@ void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, Inclu msg); m_currentDoc->addDiagnosticMessage(d); - - //qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line; - return; } } if (m_dumpFileNameWhileParsing) { qDebug() << "Parsing file:" << absoluteFileName -// << "contents:" << contents.size() - ; + << "contents:" << contents.size() + ; } Document::Ptr doc = m_snapshot.document(absoluteFileName); @@ -407,15 +412,19 @@ void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, Inclu doc->setRevision(m_revision); doc->setEditorRevision(editorRevision); - QFileInfo info(absoluteFileName); + const QFileInfo info(absoluteFileName); if (info.exists()) doc->setLastModified(info.lastModified()); - Document::Ptr previousDoc = switchDocument(doc); + const Document::Ptr previousDoc = switchDocument(doc); const QByteArray preprocessedCode = m_preprocess.run(absoluteFileName, contents); - -// { QByteArray b(preprocessedCode); b.replace("\n", "<<<\n"); qDebug("Preprocessed code for \"%s\": [[%s]]", fileName.toUtf8().constData(), b.constData()); } +// { +// QByteArray b(preprocessedCode); +// b.replace("\n", "<<<\n"); +// qDebug("Preprocessed code for \"%s\": [[%s]]", fileName.toUtf8().constData(), +// b.constData()); +// } doc->setUtf8Source(preprocessedCode); doc->keepSourceAndAST(); @@ -432,7 +441,7 @@ void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, Inclu Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc) { - Document::Ptr previousDoc = m_currentDoc; + const Document::Ptr previousDoc = m_currentDoc; m_currentDoc = doc; return previousDoc; } |