summaryrefslogtreecommitdiff
path: root/src/plugins/cpptools/cpppreprocessor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/cpptools/cpppreprocessor.cpp')
-rw-r--r--src/plugins/cpptools/cpppreprocessor.cpp127
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 &macro)
{
- if (! m_currentDoc)
+ if (!m_currentDoc)
return;
m_currentDoc->appendMacro(macro);
}
-static inline const Macro revision(const CppModelManagerInterface::WorkingCopy &s, const Macro &macro)
+static inline const Macro revision(const CppModelManagerInterface::WorkingCopy &s,
+ const Macro &macro)
{
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 &macro)
{
- 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 &macro)
{
- 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 &macro,
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 &macroName)
@@ -320,7 +317,7 @@ void CppPreprocessor::markAsIncludeGuard(const QByteArray &macroName)
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;
}