summaryrefslogtreecommitdiff
path: root/src/plugins/cpptools
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/cpptools')
-rw-r--r--src/plugins/cpptools/cppclassesfilter.cpp1
-rw-r--r--src/plugins/cpptools/cppcodecompletion.cpp8
-rw-r--r--src/plugins/cpptools/cppmodelmanager.cpp562
-rw-r--r--src/plugins/cpptools/cppmodelmanager.h33
-rw-r--r--src/plugins/cpptools/cppmodelmanagerinterface.h32
-rw-r--r--src/plugins/cpptools/cpptools.pro2
-rw-r--r--src/plugins/cpptools/rpp/pp-cctype.h74
-rw-r--r--src/plugins/cpptools/rpp/pp-client.h79
-rw-r--r--src/plugins/cpptools/rpp/pp-engine.cpp1124
-rw-r--r--src/plugins/cpptools/rpp/pp-engine.h231
-rw-r--r--src/plugins/cpptools/rpp/pp-environment.cpp231
-rw-r--r--src/plugins/cpptools/rpp/pp-environment.h109
-rw-r--r--src/plugins/cpptools/rpp/pp-internal.h78
-rw-r--r--src/plugins/cpptools/rpp/pp-macro-expander.cpp361
-rw-r--r--src/plugins/cpptools/rpp/pp-macro-expander.h103
-rw-r--r--src/plugins/cpptools/rpp/pp-macro.h95
-rw-r--r--src/plugins/cpptools/rpp/pp-scanner.h380
-rw-r--r--src/plugins/cpptools/rpp/pp.h69
-rw-r--r--src/plugins/cpptools/rpp/rpp.pri18
-rw-r--r--src/plugins/cpptools/searchsymbols.cpp79
-rw-r--r--src/plugins/cpptools/searchsymbols.h16
21 files changed, 435 insertions, 3250 deletions
diff --git a/src/plugins/cpptools/cppclassesfilter.cpp b/src/plugins/cpptools/cppclassesfilter.cpp
index 3d8da9a738..6aa6734fca 100644
--- a/src/plugins/cpptools/cppclassesfilter.cpp
+++ b/src/plugins/cpptools/cppclassesfilter.cpp
@@ -42,6 +42,7 @@ CppClassesFilter::CppClassesFilter(CppModelManager *manager, Core::EditorManager
setIncludedByDefault(false);
search.setSymbolsToSearchFor(SearchSymbols::Classes);
+ search.setSeparateScope(true);
}
CppClassesFilter::~CppClassesFilter()
diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp
index 7568d2c887..d24f5a5f81 100644
--- a/src/plugins/cpptools/cppcodecompletion.cpp
+++ b/src/plugins/cpptools/cppcodecompletion.cpp
@@ -699,7 +699,9 @@ void CppCodeCompletion::addMacros(const LookupContext &context)
continue;
processed.insert(fn);
if (Document::Ptr doc = context.document(fn)) {
- macroNames += doc->macroNames();
+ foreach (const Macro macro, doc->definedMacros()) {
+ macroNames.insert(macro.name);
+ }
todo += doc->includedFiles();
}
}
@@ -1025,6 +1027,10 @@ bool CppCodeCompletion::partiallyComplete(const QList<TextEditor::CompletionItem
void CppCodeCompletion::cleanup()
{
m_completions.clear();
+
+ // Set empty map in order to avoid referencing old versions of the documents
+ // until the next completion
+ typeOfExpression.setDocuments(QMap<QString, Document::Ptr>());
}
int CppCodeCompletion::findStartOfName(const TextEditor::ITextEditor *editor)
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index b3f9fb604c..a165614a59 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -31,8 +31,7 @@
**
***************************************************************************/
-#define _SCL_SECURE_NO_WARNINGS 1
-#include "pp.h"
+#include <cplusplus/pp.h>
#include "cppmodelmanager.h"
#include "cpphoverhandler.h"
@@ -66,14 +65,14 @@
#include <Token.h>
#include <QPlainTextEdit>
+#include <QMutexLocker>
#include <QTime>
#include <QDebug>
+using namespace CppTools;
+using namespace CppTools::Internal;
using namespace CPlusPlus;
-namespace CppTools {
-namespace Internal {
-
static const char pp_configuration_file[] = "<configuration>";
static const char pp_configuration[] =
@@ -105,299 +104,322 @@ static const char pp_configuration[] =
"#define __declspec(a)\n"
"#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method\n";
-class CppPreprocessor: public rpp::Client
+namespace CppTools {
+namespace Internal {
+
+class CppPreprocessor: public CPlusPlus::Client
{
public:
- CppPreprocessor(QPointer<CppModelManager> modelManager)
- : m_modelManager(modelManager),
- m_documents(modelManager->documents()),
- m_proc(this, env)
- { }
+ CppPreprocessor(QPointer<CppModelManager> modelManager);
+
+ void setWorkingCopy(const QMap<QString, QByteArray> &workingCopy);
+ void setIncludePaths(const QStringList &includePaths);
+ void setFrameworkPaths(const QStringList &frameworkPaths);
+ void setProjectFiles(const QStringList &files);
+ void run(QString &fileName);
+ void operator()(QString &fileName);
+
+protected:
+ CPlusPlus::Document::Ptr switchDocument(CPlusPlus::Document::Ptr doc);
+
+ bool includeFile(const QString &absoluteFilePath, QByteArray *result);
+ QByteArray tryIncludeFile(QString &fileName, IncludeType type);
+
+ void mergeEnvironment(CPlusPlus::Document::Ptr doc);
+ void mergeEnvironment(CPlusPlus::Document::Ptr doc, QSet<QString> *processed);
+
+ virtual void macroAdded(const Macro &macro);
+ virtual void startExpandingMacro(unsigned offset,
+ const Macro &macro,
+ const QByteArray &originalText);
+ virtual void stopExpandingMacro(unsigned offset, const Macro &macro);
+ virtual void startSkippingBlocks(unsigned offset);
+ virtual void stopSkippingBlocks(unsigned offset);
+ virtual void sourceNeeded(QString &fileName, IncludeType type);
+
+private:
+ QPointer<CppModelManager> m_modelManager;
+ CppModelManager::DocumentTable m_documents;
+ Environment env;
+ pp m_proc;
+ QStringList m_includePaths;
+ QStringList m_systemIncludePaths;
+ QMap<QString, QByteArray> m_workingCopy;
+ QStringList m_projectFiles;
+ QStringList m_frameworkPaths;
+ QSet<QString> m_included;
+ CPlusPlus::Document::Ptr m_currentDoc;
+};
- void setWorkingCopy(const QMap<QString, QByteArray> &workingCopy)
- { m_workingCopy = workingCopy; }
+} // namespace Internal
+} // namespace CppTools
- void setIncludePaths(const QStringList &includePaths)
- { m_includePaths = includePaths; }
+CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager)
+ : m_modelManager(modelManager),
+ m_documents(modelManager->documents()),
+ m_proc(this, env)
+{ }
- void setFrameworkPaths(const QStringList &frameworkPaths)
- { m_frameworkPaths = frameworkPaths; }
+void CppPreprocessor::setWorkingCopy(const QMap<QString, QByteArray> &workingCopy)
+{ m_workingCopy = workingCopy; }
- void addIncludePath(const QString &path)
- { m_includePaths.append(path); }
+void CppPreprocessor::setIncludePaths(const QStringList &includePaths)
+{ m_includePaths = includePaths; }
- void setProjectFiles(const QStringList &files)
- { m_projectFiles = files; }
+void CppPreprocessor::setFrameworkPaths(const QStringList &frameworkPaths)
+{ m_frameworkPaths = frameworkPaths; }
- void run(QString &fileName)
- { sourceNeeded(fileName, IncludeGlobal); }
+void CppPreprocessor::setProjectFiles(const QStringList &files)
+{ m_projectFiles = files; }
- void operator()(QString &fileName)
- { run(fileName); }
+void CppPreprocessor::run(QString &fileName)
+{ sourceNeeded(fileName, IncludeGlobal); }
-protected:
- bool includeFile(const QString &absoluteFilePath, QByteArray *result)
- {
- if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) {
- return true;
- }
+void CppPreprocessor::operator()(QString &fileName)
+{ run(fileName); }
- if (m_workingCopy.contains(absoluteFilePath)) {
- m_included.insert(absoluteFilePath);
- *result = m_workingCopy.value(absoluteFilePath);
- return true;
- }
+bool CppPreprocessor::includeFile(const QString &absoluteFilePath, QByteArray *result)
+{
+ if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) {
+ return true;
+ }
- QFileInfo fileInfo(absoluteFilePath);
- if (! fileInfo.isFile())
- return false;
-
- QFile file(absoluteFilePath);
- if (file.open(QFile::ReadOnly)) {
- m_included.insert(absoluteFilePath);
- QTextStream stream(&file);
- const QString contents = stream.readAll();
- *result = contents.toUtf8();
- file.close();
- return true;
- }
+ if (m_workingCopy.contains(absoluteFilePath)) {
+ m_included.insert(absoluteFilePath);
+ *result = m_workingCopy.value(absoluteFilePath);
+ return true;
+ }
+ QFileInfo fileInfo(absoluteFilePath);
+ if (! fileInfo.isFile())
return false;
+
+ QFile file(absoluteFilePath);
+ if (file.open(QFile::ReadOnly)) {
+ m_included.insert(absoluteFilePath);
+ QTextStream stream(&file);
+ const QString contents = stream.readAll();
+ *result = contents.toUtf8();
+ file.close();
+ return true;
}
- QByteArray tryIncludeFile(QString &fileName, IncludeType type)
- {
- QFileInfo fileInfo(fileName);
- if (fileName == QLatin1String(pp_configuration_file) || fileInfo.isAbsolute()) {
- QByteArray contents;
- includeFile(fileName, &contents);
+ return false;
+}
+
+QByteArray CppPreprocessor::tryIncludeFile(QString &fileName, IncludeType type)
+{
+ QFileInfo fileInfo(fileName);
+ if (fileName == QLatin1String(pp_configuration_file) || fileInfo.isAbsolute()) {
+ QByteArray contents;
+ includeFile(fileName, &contents);
+ return contents;
+ }
+
+ if (type == IncludeLocal && m_currentDoc) {
+ QFileInfo currentFileInfo(m_currentDoc->fileName());
+ QString path = currentFileInfo.absolutePath();
+ path += QLatin1Char('/');
+ path += fileName;
+ path = QDir::cleanPath(path);
+ QByteArray contents;
+ if (includeFile(path, &contents)) {
+ fileName = path;
return contents;
}
+ }
- if (type == IncludeLocal && m_currentDoc) {
- QFileInfo currentFileInfo(m_currentDoc->fileName());
- QString path = currentFileInfo.absolutePath();
- path += QLatin1Char('/');
- path += fileName;
- path = QDir::cleanPath(path);
- QByteArray contents;
- if (includeFile(path, &contents)) {
- fileName = path;
- return contents;
- }
+ foreach (const QString &includePath, m_includePaths) {
+ QString path = includePath;
+ path += QLatin1Char('/');
+ path += fileName;
+ path = QDir::cleanPath(path);
+ QByteArray contents;
+ if (includeFile(path, &contents)) {
+ fileName = path;
+ return contents;
}
+ }
- foreach (const QString &includePath, m_includePaths) {
- QString path = includePath;
- path += QLatin1Char('/');
- path += fileName;
- path = QDir::cleanPath(path);
- QByteArray contents;
- if (includeFile(path, &contents)) {
- fileName = path;
- return contents;
- }
+ // look in the system include paths
+ foreach (const QString &includePath, m_systemIncludePaths) {
+ QString path = includePath;
+ path += QLatin1Char('/');
+ path += fileName;
+ path = QDir::cleanPath(path);
+ QByteArray contents;
+ if (includeFile(path, &contents)) {
+ fileName = path;
+ return contents;
}
+ }
- // look in the system include paths
- foreach (const QString &includePath, m_systemIncludePaths) {
- QString path = includePath;
+ int index = fileName.indexOf(QLatin1Char('/'));
+ if (index != -1) {
+ QString frameworkName = fileName.left(index);
+ QString name = fileName.mid(index + 1);
+
+ foreach (const QString &frameworkPath, m_frameworkPaths) {
+ QString path = frameworkPath;
path += QLatin1Char('/');
- path += fileName;
- path = QDir::cleanPath(path);
+ path += frameworkName;
+ path += QLatin1String(".framework/Headers/");
+ path += name;
QByteArray contents;
if (includeFile(path, &contents)) {
fileName = path;
return contents;
}
}
+ }
- int index = fileName.indexOf(QLatin1Char('/'));
- if (index != -1) {
- QString frameworkName = fileName.left(index);
- QString name = fileName.mid(index + 1);
-
- foreach (const QString &frameworkPath, m_frameworkPaths) {
- QString path = frameworkPath;
- path += QLatin1Char('/');
- path += frameworkName;
- path += QLatin1String(".framework/Headers/");
- path += name;
- QByteArray contents;
- if (includeFile(path, &contents)) {
- fileName = path;
- return contents;
- }
- }
- }
-
- QString path = fileName;
- if (path.at(0) != QLatin1Char('/'))
- path.prepend(QLatin1Char('/'));
+ QString path = fileName;
+ if (path.at(0) != QLatin1Char('/'))
+ path.prepend(QLatin1Char('/'));
- foreach (const QString &projectFile, m_projectFiles) {
- if (projectFile.endsWith(path)) {
- fileName = projectFile;
- QByteArray contents;
- includeFile(fileName, &contents);
- return contents;
- }
+ foreach (const QString &projectFile, m_projectFiles) {
+ if (projectFile.endsWith(path)) {
+ fileName = projectFile;
+ QByteArray contents;
+ includeFile(fileName, &contents);
+ return contents;
}
-
- //qDebug() << "**** file" << fileName << "not found!";
- return QByteArray();
}
- virtual void macroAdded(const QByteArray &macroName, const QByteArray &macroText)
- {
- if (! m_currentDoc)
- return;
+ //qDebug() << "**** file" << fileName << "not found!";
+ return QByteArray();
+}
- m_currentDoc->appendMacro(macroName, macroText);
- }
+void CppPreprocessor::macroAdded(const Macro &macro)
+{
+ if (! m_currentDoc)
+ return;
- virtual void startExpandingMacro(unsigned offset,
- const rpp::Macro &,
- const QByteArray &originalText)
- {
- if (! m_currentDoc)
- return;
-
- //qDebug() << "start expanding:" << macro.name << "text:" << originalText;
- m_currentDoc->addMacroUse(offset, originalText.length());
- }
+ m_currentDoc->appendMacro(macro);
+}
- virtual void stopExpandingMacro(unsigned, const rpp::Macro &)
- {
- if (! m_currentDoc)
- return;
+void CppPreprocessor::startExpandingMacro(unsigned offset,
+ const Macro &,
+ const QByteArray &originalText)
+{
+ if (! m_currentDoc)
+ return;
- //qDebug() << "stop expanding:" << macro.name;
- }
+ //qDebug() << "start expanding:" << macro.name << "text:" << originalText;
+ m_currentDoc->addMacroUse(offset, originalText.length());
+}
- void mergeEnvironment(Document::Ptr doc)
- {
- QSet<QString> processed;
- mergeEnvironment(doc, &processed);
- }
+void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &)
+{
+ if (! m_currentDoc)
+ return;
- void mergeEnvironment(Document::Ptr doc, QSet<QString> *processed)
- {
- if (! doc)
- return;
+ //qDebug() << "stop expanding:" << macro.name;
+}
- const QString fn = doc->fileName();
+void CppPreprocessor::mergeEnvironment(Document::Ptr doc)
+{
+ QSet<QString> processed;
+ mergeEnvironment(doc, &processed);
+}
- if (processed->contains(fn))
- return;
+void CppPreprocessor::mergeEnvironment(Document::Ptr doc, QSet<QString> *processed)
+{
+ if (! doc)
+ return;
- processed->insert(fn);
+ const QString fn = doc->fileName();
- foreach (QString includedFile, doc->includedFiles())
- mergeEnvironment(m_documents.value(includedFile), processed);
+ if (processed->contains(fn))
+ return;
- const QByteArray macros = doc->definedMacros();
- QByteArray localFileName = doc->fileName().toUtf8();
+ processed->insert(fn);
- QByteArray dummy;
- m_proc(localFileName, macros, &dummy);
+ foreach (QString includedFile, doc->includedFiles()) {
+ mergeEnvironment(m_documents.value(includedFile), processed);
}
- virtual void startSkippingBlocks(unsigned offset)
- {
- //qDebug() << "start skipping blocks:" << offset;
- if (m_currentDoc)
- m_currentDoc->startSkippingBlocks(offset);
+ foreach (const Macro macro, doc->definedMacros()) {
+ env.bind(macro);
}
+}
- virtual void stopSkippingBlocks(unsigned offset)
- {
- //qDebug() << "stop skipping blocks:" << offset;
- if (m_currentDoc)
- m_currentDoc->stopSkippingBlocks(offset);
- }
+void CppPreprocessor::startSkippingBlocks(unsigned offset)
+{
+ //qDebug() << "start skipping blocks:" << offset;
+ if (m_currentDoc)
+ m_currentDoc->startSkippingBlocks(offset);
+}
- virtual void sourceNeeded(QString &fileName, IncludeType type)
- {
- if (fileName.isEmpty())
- return;
-
- QByteArray contents = tryIncludeFile(fileName, type);
-
- if (m_currentDoc) {
- m_currentDoc->addIncludeFile(fileName);
- if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) {
- QString msg;
- msg += fileName;
- msg += QLatin1String(": No such file or directory");
- Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning,
- m_currentDoc->fileName(),
- env.currentLine, /*column = */ 0,
- msg);
- m_currentDoc->addDiagnosticMessage(d);
- //qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
- }
+void CppPreprocessor::stopSkippingBlocks(unsigned offset)
+{
+ //qDebug() << "stop skipping blocks:" << offset;
+ if (m_currentDoc)
+ m_currentDoc->stopSkippingBlocks(offset);
+}
+
+void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type)
+{
+ if (fileName.isEmpty())
+ return;
+
+ QByteArray contents = tryIncludeFile(fileName, type);
+
+ if (m_currentDoc) {
+ m_currentDoc->addIncludeFile(fileName);
+ if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) {
+ QString msg;
+ msg += fileName;
+ msg += QLatin1String(": No such file or directory");
+ Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning,
+ m_currentDoc->fileName(),
+ env.currentLine, /*column = */ 0,
+ msg);
+ m_currentDoc->addDiagnosticMessage(d);
+ //qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
}
+ }
- if (! contents.isEmpty()) {
- Document::Ptr cachedDoc = m_documents.value(fileName);
- if (cachedDoc && m_currentDoc) {
- mergeEnvironment(cachedDoc);
- } else {
- Document::Ptr previousDoc = switchDocument(Document::create(fileName));
+ if (! contents.isEmpty()) {
+ Document::Ptr cachedDoc = m_documents.value(fileName);
+ if (cachedDoc && m_currentDoc) {
+ mergeEnvironment(cachedDoc);
+ } else {
+ Document::Ptr previousDoc = switchDocument(Document::create(fileName));
- const QByteArray previousFile = env.current_file;
- const unsigned previousLine = env.currentLine;
+ const QByteArray previousFile = env.current_file;
+ const unsigned previousLine = env.currentLine;
- env.current_file = QByteArray(m_currentDoc->translationUnit()->fileName(),
- m_currentDoc->translationUnit()->fileNameLength());
+ env.current_file = QByteArray(m_currentDoc->translationUnit()->fileName(),
+ m_currentDoc->translationUnit()->fileNameLength());
- QByteArray preprocessedCode;
- m_proc(contents, &preprocessedCode);
- //qDebug() << preprocessedCode;
+ QByteArray preprocessedCode;
+ m_proc(contents, &preprocessedCode);
+ //qDebug() << preprocessedCode;
- env.current_file = previousFile;
- env.currentLine = previousLine;
+ env.current_file = previousFile;
+ env.currentLine = previousLine;
- m_currentDoc->setSource(preprocessedCode);
- m_currentDoc->parse();
- m_currentDoc->check();
- m_currentDoc->releaseTranslationUnit(); // release the AST and the token stream.
+ m_currentDoc->setSource(preprocessedCode);
+ m_currentDoc->parse();
+ m_currentDoc->check();
+ m_currentDoc->releaseTranslationUnit(); // release the AST and the token stream.
- if (m_modelManager)
- m_modelManager->emitDocumentUpdated(m_currentDoc);
- (void) switchDocument(previousDoc);
- }
+ if (m_modelManager)
+ m_modelManager->emitDocumentUpdated(m_currentDoc);
+ (void) switchDocument(previousDoc);
}
}
+}
- Document::Ptr switchDocument(Document::Ptr doc)
- {
- Document::Ptr previousDoc = m_currentDoc;
- m_currentDoc = doc;
- return previousDoc;
- }
-
-private:
- QPointer<CppModelManager> m_modelManager;
- CppModelManager::DocumentTable m_documents;
- rpp::Environment env;
- rpp::pp m_proc;
- QStringList m_includePaths;
- QStringList m_systemIncludePaths;
- QMap<QString, QByteArray> m_workingCopy;
- QStringList m_projectFiles;
- QStringList m_frameworkPaths;
- QSet<QString> m_included;
- Document::Ptr m_currentDoc;
-};
-
-} // namespace Internal
-} // namespace CppTools
+Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc)
+{
+ Document::Ptr previousDoc = m_currentDoc;
+ m_currentDoc = doc;
+ return previousDoc;
+}
-using namespace CppTools;
-using namespace CppTools::Internal;
/*!
\class CppTools::CppModelManager
@@ -450,13 +472,26 @@ CppModelManager::CppModelManager(QObject *parent) :
CppModelManager::~CppModelManager()
{ }
-Document::Ptr CppModelManager::document(const QString &fileName)
+Document::Ptr CppModelManager::document(const QString &fileName) const
{ return m_documents.value(fileName); }
-CppModelManager::DocumentTable CppModelManager::documents()
+CppModelManager::DocumentTable CppModelManager::documents() const
{ return m_documents; }
-QStringList CppModelManager::updateProjectFiles() const
+void CppModelManager::ensureUpdated()
+{
+ QMutexLocker locker(&mutex);
+ if (! m_dirty)
+ return;
+
+ m_projectFiles = internalProjectFiles();
+ m_includePaths = internalIncludePaths();
+ m_frameworkPaths = internalFrameworkPaths();
+ m_definedMacros = internalDefinedMacros();
+ m_dirty = false;
+}
+
+QStringList CppModelManager::internalProjectFiles() const
{
QStringList files;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -465,10 +500,11 @@ QStringList CppModelManager::updateProjectFiles() const
ProjectInfo pinfo = it.value();
files += pinfo.sourceFiles;
}
+ files.removeDuplicates();
return files;
}
-QStringList CppModelManager::updateIncludePaths() const
+QStringList CppModelManager::internalIncludePaths() const
{
QStringList includePaths;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -477,10 +513,11 @@ QStringList CppModelManager::updateIncludePaths() const
ProjectInfo pinfo = it.value();
includePaths += pinfo.includePaths;
}
+ includePaths.removeDuplicates();
return includePaths;
}
-QStringList CppModelManager::updateFrameworkPaths() const
+QStringList CppModelManager::internalFrameworkPaths() const
{
QStringList frameworkPaths;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -489,10 +526,11 @@ QStringList CppModelManager::updateFrameworkPaths() const
ProjectInfo pinfo = it.value();
frameworkPaths += pinfo.frameworkPaths;
}
+ frameworkPaths.removeDuplicates();
return frameworkPaths;
}
-QByteArray CppModelManager::updateDefinedMacros() const
+QByteArray CppModelManager::internalDefinedMacros() const
{
QByteArray macros;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -527,8 +565,30 @@ QMap<QString, QByteArray> CppModelManager::buildWorkingCopyList()
void CppModelManager::updateSourceFiles(const QStringList &sourceFiles)
{ (void) refreshSourceFiles(sourceFiles); }
-CppModelManager::ProjectInfo *CppModelManager::projectInfo(ProjectExplorer::Project *project)
-{ return &m_projects[project]; }
+QList<CppModelManager::ProjectInfo> CppModelManager::projectInfos() const
+{
+ QMutexLocker locker(&mutex);
+
+ return m_projects.values();
+}
+
+CppModelManager::ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Project *project) const
+{
+ QMutexLocker locker(&mutex);
+
+ return m_projects.value(project, ProjectInfo(project));
+}
+
+void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo)
+{
+ QMutexLocker locker(&mutex);
+
+ if (! pinfo.isValid())
+ return;
+
+ m_projects.insert(pinfo.project, pinfo);
+ m_dirty = true;
+}
QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles)
{
@@ -683,7 +743,7 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
sel.cursor = c;
selections.append(sel);
}
- ed->setExtraExtraSelections(selections);
+ ed->setExtraSelections(TextEditor::BaseTextEditor::CodeWarningsSelection, selections);
break;
}
}
@@ -691,13 +751,18 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
void CppModelManager::onProjectAdded(ProjectExplorer::Project *)
{
+ QMutexLocker locker(&mutex);
m_dirty = true;
}
void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
{
- m_dirty = true;
- m_projects.remove(project);
+ do {
+ QMutexLocker locker(&mutex);
+ m_dirty = true;
+ m_projects.remove(project);
+ } while (0);
+
GC();
}
@@ -705,8 +770,15 @@ void CppModelManager::onSessionUnloaded()
{
if (m_core->progressManager()) {
m_core->progressManager()->cancelTasks(CppTools::Constants::TASK_INDEX);
- m_dirty = true;
}
+
+ do {
+ QMutexLocker locker(&mutex);
+ m_projects.clear();
+ m_dirty = true;
+ } while (0);
+
+ GC();
}
void CppModelManager::parse(QFutureInterface<void> &future,
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index a91a414e48..3b2f4e1999 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -40,6 +40,7 @@
#include <QMap>
#include <QFutureInterface>
+#include <QMutex>
namespace Core {
class ICore;
@@ -70,9 +71,13 @@ public:
virtual ~CppModelManager();
virtual void updateSourceFiles(const QStringList &sourceFiles);
- virtual ProjectInfo *projectInfo(ProjectExplorer::Project *project);
- virtual CPlusPlus::Document::Ptr document(const QString &fileName);
- virtual DocumentTable documents();
+
+ virtual QList<ProjectInfo> projectInfos() const;
+ virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const;
+ virtual void updateProjectInfo(const ProjectInfo &pinfo);
+
+ virtual CPlusPlus::Document::Ptr document(const QString &fileName) const;
+ virtual DocumentTable documents() const;
virtual void GC();
QFuture<void> refreshSourceFiles(const QStringList &sourceFiles);
@@ -127,21 +132,11 @@ private:
return m_definedMacros;
}
- QStringList updateProjectFiles() const;
- QStringList updateIncludePaths() const;
- QStringList updateFrameworkPaths() const;
- QByteArray updateDefinedMacros() const;
-
- void ensureUpdated() {
- if (! m_dirty)
- return;
-
- m_projectFiles = updateProjectFiles();
- m_includePaths = updateIncludePaths();
- m_frameworkPaths = updateFrameworkPaths();
- m_definedMacros = updateDefinedMacros();
- m_dirty = false;
- }
+ void ensureUpdated();
+ QStringList internalProjectFiles() const;
+ QStringList internalIncludePaths() const;
+ QStringList internalFrameworkPaths() const;
+ QByteArray internalDefinedMacros() const;
static void parse(QFutureInterface<void> &future,
CppPreprocessor *preproc,
@@ -166,6 +161,8 @@ private:
// project integration
QMap<ProjectExplorer::Project *, ProjectInfo> m_projects;
+ mutable QMutex mutex;
+
enum {
MAX_SELECTION_COUNT = 5
};
diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.h b/src/plugins/cpptools/cppmodelmanagerinterface.h
index 11be08a4b0..e3ad4fe961 100644
--- a/src/plugins/cpptools/cppmodelmanagerinterface.h
+++ b/src/plugins/cpptools/cppmodelmanagerinterface.h
@@ -38,6 +38,7 @@
#include <cplusplus/CppDocument.h>
#include <QtCore/QObject>
#include <QtCore/QMap>
+#include <QtCore/QPointer>
namespace ProjectExplorer {
class Project;
@@ -51,10 +52,29 @@ class CPPTOOLS_EXPORT CppModelManagerInterface
Q_OBJECT
public:
- typedef QMap<QString, CPlusPlus::Document::Ptr> DocumentTable;
+ typedef QMap<QString, CPlusPlus::Document::Ptr> DocumentTable; // ### remove me
- struct ProjectInfo
+ class ProjectInfo
{
+ public:
+ ProjectInfo()
+ { }
+
+ ProjectInfo(QPointer<ProjectExplorer::Project> project)
+ : project(project)
+ { }
+
+ operator bool() const
+ { return ! project.isNull(); }
+
+ bool isValid() const
+ { return ! project.isNull(); }
+
+ bool isNull() const
+ { return project.isNull(); }
+
+ public: // attributes
+ QPointer<ProjectExplorer::Project> project;
QString projectPath;
QByteArray defines;
QStringList sourceFiles;
@@ -69,10 +89,12 @@ public:
virtual void GC() = 0;
virtual void updateSourceFiles(const QStringList &sourceFiles) = 0;
- virtual CPlusPlus::Document::Ptr document(const QString &fileName) = 0;
- virtual DocumentTable documents() = 0;
+ virtual CPlusPlus::Document::Ptr document(const QString &fileName) const = 0;
+ virtual DocumentTable documents() const = 0;
- virtual ProjectInfo *projectInfo(ProjectExplorer::Project *project) = 0;
+ virtual QList<ProjectInfo> projectInfos() const = 0;
+ virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const = 0;
+ virtual void updateProjectInfo(const ProjectInfo &pinfo) = 0;
};
} // namespace CppTools
diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro
index 8a096900eb..92905e42ef 100644
--- a/src/plugins/cpptools/cpptools.pro
+++ b/src/plugins/cpptools/cpptools.pro
@@ -10,7 +10,7 @@ unix:QMAKE_CXXFLAGS_DEBUG += -O3
INCLUDEPATH += .
DEFINES += CPPTOOLS_LIBRARY
CONFIG += help
-include(rpp/rpp.pri)|error("Can't find RPP")
+
HEADERS += cpptools_global.h \
cppquickopenfilter.h \
cppclassesfilter.h \
diff --git a/src/plugins/cpptools/rpp/pp-cctype.h b/src/plugins/cpptools/rpp/pp-cctype.h
deleted file mode 100644
index 62b44f0bf4..0000000000
--- a/src/plugins/cpptools/rpp/pp-cctype.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/***************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-**
-** Non-Open Source Usage
-**
-** Licensees may use this file in accordance with the Qt Beta Version
-** License Agreement, Agreement version 2.2 provided with the Software or,
-** alternatively, in accordance with the terms contained in a written
-** agreement between you and Nokia.
-**
-** GNU General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the packaging
-** of this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-**
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt GPL Exception
-** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
-**
-***************************************************************************/
-/*
- Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
-
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef PP_CCTYPE_H
-#define PP_CCTYPE_H
-
-#include <cctype>
-
-namespace rpp {
-
-inline bool pp_isalpha (int __ch)
-{ return std::isalpha ((unsigned char) __ch) != 0; }
-
-inline bool pp_isalnum (int __ch)
-{ return std::isalnum ((unsigned char) __ch) != 0; }
-
-inline bool pp_isdigit (int __ch)
-{ return std::isdigit ((unsigned char) __ch) != 0; }
-
-inline bool pp_isspace (int __ch)
-{ return std::isspace ((unsigned char) __ch) != 0; }
-
-} // namespace rpp
-
-#endif // PP_CCTYPE_H
diff --git a/src/plugins/cpptools/rpp/pp-client.h b/src/plugins/cpptools/rpp/pp-client.h
deleted file mode 100644
index 974004a6ce..0000000000
--- a/src/plugins/cpptools/rpp/pp-client.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/***************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-**
-** Non-Open Source Usage
-**
-** Licensees may use this file in accordance with the Qt Beta Version
-** License Agreement, Agreement version 2.2 provided with the Software or,
-** alternatively, in accordance with the terms contained in a written
-** agreement between you and Nokia.
-**
-** GNU General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the packaging
-** of this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-**
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt GPL Exception
-** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
-**
-***************************************************************************/
-
-#ifndef PP_CLIENT_H
-#define PP_CLIENT_H
-
-#include <QByteArray>
-#include <QString>
-#include <QFile>
-
-namespace rpp {
-
-class Macro;
-
-class Client
-{
- Client(const Client &other);
- void operator=(const Client &other);
-
-public:
- enum IncludeType {
- IncludeLocal,
- IncludeGlobal
- };
-
-public:
- Client()
- { }
-
- virtual ~Client()
- { }
-
- virtual void macroAdded(const QByteArray &macroId, const QByteArray &text) = 0;
- virtual void sourceNeeded(QString &fileName, IncludeType mode) = 0; // ### FIX the signature.
-
- virtual void startExpandingMacro(unsigned offset,
- const Macro &macro,
- const QByteArray &originalTextt) = 0;
-
- virtual void stopExpandingMacro(unsigned offset,
- const Macro &macro) = 0;
-
- virtual void startSkippingBlocks(unsigned offset) = 0;
- virtual void stopSkippingBlocks(unsigned offset) = 0;
-};
-
-} // namespace rpp
-
-#endif // PP_CLIENT_H
diff --git a/src/plugins/cpptools/rpp/pp-engine.cpp b/src/plugins/cpptools/rpp/pp-engine.cpp
deleted file mode 100644
index 66e8957f35..0000000000
--- a/src/plugins/cpptools/rpp/pp-engine.cpp
+++ /dev/null
@@ -1,1124 +0,0 @@
-/***************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-**
-** Non-Open Source Usage
-**
-** Licensees may use this file in accordance with the Qt Beta Version
-** License Agreement, Agreement version 2.2 provided with the Software or,
-** alternatively, in accordance with the terms contained in a written
-** agreement between you and Nokia.
-**
-** GNU General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the packaging
-** of this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-**
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt GPL Exception
-** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
-**
-***************************************************************************/
-/*
- Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
-
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "pp.h"
-
-#include <Lexer.h>
-#include <Token.h>
-#include <QtDebug>
-#include <algorithm>
-
-using namespace rpp;
-using namespace CPlusPlus;
-
-namespace {
-
-class RangeLexer
-{
- const Token *first;
- const Token *last;
- Token trivial;
-
-public:
- inline RangeLexer(const Token *first, const Token *last)
- : first(first), last(last)
- {
- // WARN: `last' must be a valid iterator.
- trivial.offset = last->offset;
- }
-
- inline operator bool() const
- { return first != last; }
-
- inline bool isValid() const
- { return first != last; }
-
- inline int size() const
- { return std::distance(first, last); }
-
- inline const Token *dot() const
- { return first; }
-
- inline const Token &operator*() const
- {
- if (first != last)
- return *first;
-
- return trivial;
- }
-
- inline const Token *operator->() const
- {
- if (first != last)
- return first;
-
- return &trivial;
- }
-
- inline RangeLexer &operator++()
- {
- ++first;
- return *this;
- }
-};
-
-class ExpressionEvaluator
-{
- ExpressionEvaluator(const ExpressionEvaluator &other);
- void operator = (const ExpressionEvaluator &other);
-
-public:
- ExpressionEvaluator(Environment *env)
- : env(env), _lex(0)
- { }
-
- Value operator()(const Token *firstToken, const Token *lastToken,
- const QByteArray &source)
- {
- this->source = source;
- const Value previousValue = switchValue(Value());
- RangeLexer tmp(firstToken, lastToken);
- RangeLexer *previousLex = _lex;
- _lex = &tmp;
- process_expression();
- _lex = previousLex;
- return switchValue(previousValue);
- }
-
-protected:
- Value switchValue(const Value &value)
- {
- Value previousValue = _value;
- _value = value;
- return previousValue;
- }
-
- bool isTokenDefined() const
- {
- if ((*_lex)->isNot(T_IDENTIFIER))
- return false;
- const QByteArray spell = tokenSpell();
- if (spell.size() != 7)
- return false;
- return spell == "defined";
- }
-
- QByteArray tokenSpell() const
- {
- const QByteArray text = QByteArray::fromRawData(source.constData() + (*_lex)->offset,
- (*_lex)->length);
- return text;
- }
-
- bool process_expression()
- { return process_constant_expression(); }
-
- bool process_primary()
- {
- if ((*_lex)->is(T_INT_LITERAL)) {
- _value.set_long(tokenSpell().toLong());
- ++(*_lex);
- return true;
- } else if (isTokenDefined()) {
- ++(*_lex);
- if ((*_lex)->is(T_IDENTIFIER)) {
- _value.set_long(env->resolve(tokenSpell()) != 0);
- ++(*_lex);
- return true;
- } else if ((*_lex)->is(T_LPAREN)) {
- ++(*_lex);
- if ((*_lex)->is(T_IDENTIFIER)) {
- _value.set_long(env->resolve(tokenSpell()) != 0);
- ++(*_lex);
- if ((*_lex)->is(T_RPAREN)) {
- ++(*_lex);
- return true;
- }
- }
- return false;
- }
- return true;
- } else if ((*_lex)->is(T_IDENTIFIER)) {
- _value.set_long(0);
- ++(*_lex);
- return true;
- } else if ((*_lex)->is(T_MINUS)) {
- ++(*_lex);
- process_primary();
- _value.set_long(- _value.l);
- return true;
- } else if ((*_lex)->is(T_PLUS)) {
- ++(*_lex);
- process_primary();
- return true;
- } else if ((*_lex)->is(T_EXCLAIM)) {
- ++(*_lex);
- process_primary();
- _value.set_long(_value.is_zero());
- return true;
- } else if ((*_lex)->is(T_LPAREN)) {
- ++(*_lex);
- process_expression();
- if ((*_lex)->is(T_RPAREN))
- ++(*_lex);
- return true;
- }
-
- return false;
- }
-
- bool process_multiplicative()
- {
- process_primary();
-
- while ((*_lex)->is(T_STAR) || (*_lex)->is(T_SLASH) || (*_lex)->is(T_PERCENT)) {
- const Token op = *(*_lex);
- ++(*_lex);
-
- const Value left = _value;
- process_primary();
-
- if (op.is(T_STAR)) {
- _value = left * _value;
- } else if (op.is(T_SLASH)) {
- if (_value.is_zero())
- _value.set_long(0);
- else
- _value = left / _value;
- } else if (op.is(T_PERCENT)) {
- if (_value.is_zero())
- _value.set_long(0);
- else
- _value = left % _value;
- }
- }
-
- return true;
- }
-
- bool process_additive()
- {
- process_multiplicative();
-
- while ((*_lex)->is(T_PLUS) || (*_lex)->is(T_MINUS)) {
- const Token op = *(*_lex);
- ++(*_lex);
-
- const Value left = _value;
- process_multiplicative();
-
- if (op.is(T_PLUS))
- _value = left + _value;
- else if (op.is(T_MINUS))
- _value = left - _value;
- }
-
- return true;
- }
-
- bool process_shift()
- {
- process_additive();
-
- while ((*_lex)->is(T_MINUS_MINUS) || (*_lex)->is(T_GREATER_GREATER)) {
- const Token op = *(*_lex);
- ++(*_lex);
-
- const Value left = _value;
- process_additive();
-
- if (op.is(T_MINUS_MINUS))
- _value = left << _value;
- else if (op.is(T_GREATER_GREATER))
- _value = left >> _value;
- }
-
- return true;
- }
-
- bool process_relational()
- {
- process_shift();
-
- while ((*_lex)->is(T_LESS) || (*_lex)->is(T_LESS_EQUAL) ||
- (*_lex)->is(T_GREATER) || (*_lex)->is(T_GREATER_EQUAL)) {
- const Token op = *(*_lex);
- ++(*_lex);
-
- const Value left = _value;
- process_shift();
-
- if (op.is(T_LESS))
- _value = left < _value;
- else if (op.is(T_LESS_EQUAL))
- _value = left <= _value;
- else if (op.is(T_GREATER))
- _value = left > _value;
- else if (op.is(T_GREATER_EQUAL))
- _value = left >= _value;
- }
-
- return true;
- }
-
- bool process_equality()
- {
- process_relational();
-
- while ((*_lex)->is(T_EXCLAIM_EQUAL) || (*_lex)->is(T_EQUAL_EQUAL)) {
- const Token op = *(*_lex);
- ++(*_lex);
-
- const Value left = _value;
- process_relational();
-
- if (op.is(T_EXCLAIM_EQUAL))
- _value = left != _value;
- else if (op.is(T_EQUAL_EQUAL))
- _value = left == _value;
- }
-
- return true;
- }
-
- bool process_and()
- {
- process_equality();
-
- while ((*_lex)->is(T_AMPER)) {
- const Token op = *(*_lex);
- ++(*_lex);
-
- const Value left = _value;
- process_equality();
-
- _value = left & _value;
- }
-
- return true;
- }
-
- bool process_xor()
- {
- process_and();
-
- while ((*_lex)->is(T_CARET)) {
- const Token op = *(*_lex);
- ++(*_lex);
-
- const Value left = _value;
- process_and();
-
- _value = left ^ _value;
- }
-
- return true;
- }
-
- bool process_or()
- {
- process_xor();
-
- while ((*_lex)->is(T_CARET)) {
- const Token op = *(*_lex);
- ++(*_lex);
-
- const Value left = _value;
- process_xor();
-
- _value = left | _value;
- }
-
- return true;
- }
-
- bool process_logical_and()
- {
- process_or();
-
- while ((*_lex)->is(T_AMPER_AMPER)) {
- const Token op = *(*_lex);
- ++(*_lex);
-
- const Value left = _value;
- process_or();
-
- _value = left && _value;
- }
-
- return true;
- }
-
- bool process_logical_or()
- {
- process_logical_and();
-
- while ((*_lex)->is(T_PIPE_PIPE)) {
- const Token op = *(*_lex);
- ++(*_lex);
-
- const Value left = _value;
- process_logical_and();
-
- _value = left || _value;
- }
-
- return true;
- }
-
- bool process_constant_expression()
- {
- process_logical_or();
- const Value cond = _value;
- if ((*_lex)->is(T_QUESTION)) {
- ++(*_lex);
- process_constant_expression();
- Value left = _value, right;
- if ((*_lex)->is(T_COLON)) {
- ++(*_lex);
- process_constant_expression();
- right = _value;
- }
- _value = ! cond.is_zero() ? left : right;
- }
-
- return true;
- }
-
-private:
- Environment *env;
- QByteArray source;
- RangeLexer *_lex;
- Value _value;
-};
-
-} // end of anonymous namespace
-
-
-pp::pp (Client *client, Environment &env)
- : client(client),
- env(env),
- expand(env)
-{
- resetIfLevel ();
-}
-
-void pp::pushState(const State &s)
-{
- _savedStates.append(state());
- _source = s.source;
- _tokens = s.tokens;
- _dot = s.dot;
-}
-
-pp::State pp::state() const
-{
- State state;
- state.source = _source;
- state.tokens = _tokens;
- state.dot = _dot;
- return state;
-}
-
-void pp::popState()
-{
- const State &state = _savedStates.last();
- _source = state.source;
- _tokens = state.tokens;
- _dot = state.dot;
- _savedStates.removeLast();
-}
-
-void pp::operator () (const QByteArray &filename,
- const QByteArray &source,
- QByteArray *result)
-{
- const QByteArray previousFile = env.current_file;
- env.current_file = filename;
-
- operator () (source, result);
-
- env.current_file = previousFile;
-}
-
-pp::State pp::createStateFromSource(const QByteArray &source) const
-{
- State state;
- state.source = source;
- Lexer lex(state.source.constBegin(), state.source.constEnd());
- lex.setScanKeywords(false);
- Token tok;
- do {
- lex(&tok);
- state.tokens.append(tok);
- } while (tok.isNot(T_EOF_SYMBOL));
- state.dot = state.tokens.constBegin();
- return state;
-}
-
-void pp::operator()(const QByteArray &source, QByteArray *result)
-{
- pushState(createStateFromSource(source));
-
- const unsigned previousCurrentLine = env.currentLine;
- env.currentLine = 0;
-
- while (true) {
- if (env.currentLine != _dot->lineno) {
- if (env.currentLine > _dot->lineno) {
- result->append("\n# ");
- result->append(QByteArray::number(_dot->lineno));
- result->append(' ');
- result->append('"');
- result->append(env.current_file);
- result->append('"');
- result->append('\n');
- } else {
- for (unsigned i = env.currentLine; i < _dot->lineno; ++i)
- result->append('\n');
- }
- env.currentLine = _dot->lineno;
- }
-
- if (_dot->is(T_EOF_SYMBOL)) {
- break;
- } else if (_dot->is(T_POUND) && (! _dot->joined && _dot->newline)) {
- TokenIterator start = _dot;
- do {
- ++_dot;
- } while (_dot->isNot(T_EOF_SYMBOL) && (_dot->joined || ! _dot->newline));
-
- //qDebug() << QByteArray(first + beginPP.offset,
- //tokens.last().end() - beginPP.offset);
-
- const bool skippingBlocks = _skipping[iflevel];
-
- processDirective(start, _dot);
-
- if (client && skippingBlocks != _skipping[iflevel]) {
- unsigned offset = start->offset;
- if (_skipping[iflevel]) {
- if (_dot->newline)
- ++offset;
- client->startSkippingBlocks(offset);
- } else {
- if (offset)
- --offset;
- client->stopSkippingBlocks(offset);
- }
- }
- } else if (skipping()) {
- do {
- ++_dot;
- } while (_dot->isNot(T_EOF_SYMBOL) && (_dot->joined || ! _dot->newline));
- } else {
- if (_dot->joined)
- result->append("\\\n");
- else if (_dot->whitespace)
- result->append(' ');
-
- if (_dot->isNot(T_IDENTIFIER)) {
- result->append(tokenSpell(*_dot));
- ++_dot;
- } else {
- const TokenIterator identifierToken = _dot;
- ++_dot; // skip T_IDENTIFIER
-
- const QByteArray spell = tokenSpell(*identifierToken);
- if (env.isBuiltinMacro(spell)) {
- const Macro trivial;
-
- if (client)
- client->startExpandingMacro(identifierToken->offset,
- trivial, spell);
-
- expand(spell.constBegin(), spell.constEnd(), result);
-
- if (client)
- client->stopExpandingMacro(_dot->offset, trivial);
-
- continue;
- }
-
- Macro *m = env.resolve(spell);
- if (! m) {
- result->append(spell);
- } else {
- if (! m->function_like) {
- if (_dot->isNot(T_LPAREN)) {
- if (client)
- client->startExpandingMacro(identifierToken->offset,
- *m, spell);
-
- m->hidden = true;
-
- expand(m->definition.constBegin(),
- m->definition.constEnd(),
- result);
-
- if (client)
- client->stopExpandingMacro(_dot->offset, *m);
-
- m->hidden = false;
- continue;
- } else {
- QByteArray tmp;
- m->hidden = true;
-
- if (client)
- client->startExpandingMacro(identifierToken->offset,
- *m, spell);
-
- expand(m->definition.constBegin(),
- m->definition.constEnd(),
- &tmp);
-
- if (client)
- client->stopExpandingMacro(_dot->offset, *m);
-
- m->hidden = false;
-
- m = 0; // reset the active the macro
-
- pushState(createStateFromSource(tmp));
- if (_dot->is(T_IDENTIFIER)) {
- const QByteArray id = tokenSpell(*_dot);
- Macro *macro = env.resolve(id);
- if (macro && macro->function_like)
- m = macro;
- }
- popState();
-
- if (! m) {
- result->append(tmp);
- continue;
- }
- }
- }
-
- // collect the actual arguments
- if (_dot->isNot(T_LPAREN)) {
- // ### warnng expected T_LPAREN
- result->append(m->name);
- continue;
- }
-
- int count = 0;
- while (_dot->isNot(T_EOF_SYMBOL)) {
- if (_dot->is(T_LPAREN))
- ++count;
- else if (_dot->is(T_RPAREN)) {
- if (! --count)
- break;
- }
- ++_dot;
- }
- if (_dot->isNot(T_RPAREN)) {
- // ### warning expected T_RPAREN
- } else {
- const char *beginOfText = startOfToken(*identifierToken);
- const char *endOfText = endOfToken(*_dot);
- ++_dot; // skip T_RPAREN
-
- if (client) {
- const QByteArray text =
- QByteArray::fromRawData(beginOfText,
- endOfText - beginOfText);
-
- client->startExpandingMacro(identifierToken->offset,
- *m, text);
- }
-
- expand(beginOfText, endOfText, result);
-
- if (client)
- client->stopExpandingMacro(_dot->offset, *m);
- }
- }
- }
- }
- }
-
- popState();
- env.currentLine = previousCurrentLine;
-}
-
-const char *pp::startOfToken(const Token &token) const
-{ return _source.constBegin() + token.begin(); }
-
-const char *pp::endOfToken(const Token &token) const
-{ return _source.constBegin() + token.end(); }
-
-QByteArray pp::tokenSpell(const Token &token) const
-{
- const QByteArray text = QByteArray::fromRawData(_source.constBegin() + token.offset,
- token.length);
- return text;
-}
-
-QByteArray pp::tokenText(const Token &token) const
-{
- const QByteArray text(_source.constBegin() + token.offset,
- token.length);
- return text;
-}
-
-void pp::processDirective(TokenIterator firstToken, TokenIterator lastToken)
-{
- RangeLexer tk(firstToken, lastToken);
- ++tk; // skip T_POUND
-
- if (tk->is(T_IDENTIFIER)) {
- const QByteArray directive = tokenSpell(*tk);
- switch (PP_DIRECTIVE_TYPE d = classifyDirective(directive)) {
- case PP_DEFINE:
- if (! skipping())
- processDefine(firstToken, lastToken);
- break;
-
- case PP_INCLUDE:
- case PP_INCLUDE_NEXT:
- if (! skipping())
- processInclude(d == PP_INCLUDE_NEXT, firstToken, lastToken);
- break;
-
- case PP_UNDEF:
- if (! skipping())
- processUndef(firstToken, lastToken);
- break;
-
- case PP_ELIF:
- processElif(firstToken, lastToken);
- break;
-
- case PP_ELSE:
- processElse(firstToken, lastToken);
- break;
-
- case PP_ENDIF:
- processEndif(firstToken, lastToken);
- break;
-
- case PP_IF:
- processIf(firstToken, lastToken);
- break;
-
- case PP_IFDEF:
- case PP_IFNDEF:
- processIfdef(d == PP_IFNDEF, firstToken, lastToken);
- break;
-
- default:
- break;
- } // switch
- }
-}
-
-QVector<Token> pp::tokenize(const QByteArray &text) const
-{
- QVector<Token> tokens;
- Lexer lex(text.constBegin(), text.constEnd());
- lex.setScanKeywords(false);
- Token tk;
- do {
- lex(&tk);
- tokens.append(tk);
- } while (tk.isNot(T_EOF_SYMBOL));
- return tokens;
-}
-
-void pp::processInclude(bool skipCurentPath,
- TokenIterator firstToken, TokenIterator lastToken,
- bool acceptMacros)
-{
- RangeLexer tk(firstToken, lastToken);
- ++tk; // skip T_POUND
- ++tk; // skip `include|nclude_next'
-
- if (acceptMacros && tk->is(T_IDENTIFIER)) {
-#if 0
- QByteArray name;
- name.reserve(256);
- MacroExpander expandInclude(env);
- expandInclude(startOfToken(tokens.at(2)),
- startOfToken(tokens.last()),
- &name);
- const QByteArray previousSource = switchSource(name);
- //processInclude(skipCurentPath, tokenize(name), /*accept macros=*/ false);
- (void) switchSource(previousSource);
-#endif
- } else if (tk->is(T_LESS)) {
- TokenIterator start = tk.dot();
- for (; tk->isNot(T_EOF_SYMBOL); ++tk) {
- if (tk->is(T_GREATER))
- break;
- }
- const char *beginOfPath = endOfToken(*start);
- const char *endOfPath = startOfToken(*tk);
- const QByteArray path = QByteArray::fromRawData(beginOfPath,
- endOfPath - beginOfPath);
-
- QString fn = QString::fromUtf8(path.constData(), path.length());
-
- if (client)
- client->sourceNeeded(fn, Client::IncludeGlobal);
- } else if (tk->is(T_ANGLE_STRING_LITERAL) || tk->is(T_STRING_LITERAL)) {
- const QByteArray spell = tokenSpell(*tk);
- const char *beginOfPath = spell.constBegin();
- const char *endOfPath = spell.constEnd();
- const char quote = *beginOfPath;
- if (beginOfPath + 1 != endOfPath && ((quote == '"' && endOfPath[-1] == '"') ||
- (quote == '<' && endOfPath[-1] == '>'))) {
- const QByteArray path = QByteArray::fromRawData(beginOfPath + 1,
- spell.length() - 2);
- QString fn = QString::fromUtf8(path.constData(), path.length());
-
- if (client)
- client->sourceNeeded(fn, Client::IncludeLocal);
- }
- }
-}
-
-void pp::processDefine(TokenIterator firstToken, TokenIterator lastToken)
-{
- RangeLexer tk(firstToken, lastToken);
-
- if (tk.size() < 3)
- return; // nothing to do
-
- ++tk; // skip T_POUND
- ++tk; // skip T_DEFINE
-
- if (tk->isNot(T_IDENTIFIER)) {
- // ### warning expected an `identifier'
- return;
- }
-
- Macro macro;
- macro.name = tokenText(*tk);
- ++tk; // skip T_IDENTIFIER
-
- if (tk->is(T_LPAREN) && ! tk->whitespace) {
- // a function-like macro definition
- macro.function_like = true;
-
- ++tk; // skip T_LPAREN
- if (tk->is(T_IDENTIFIER)) {
- macro.formals.append(tokenText(*tk));
- ++tk; // skip T_IDENTIFIER
- while (tk->is(T_COMMA)) {
- ++tk;// skip T_COMMA
- if (tk->isNot(T_IDENTIFIER))
- break;
- macro.formals.append(tokenText(*tk));
- ++tk; // skip T_IDENTIFIER
- }
- }
-
- if (tk->is(T_DOT_DOT_DOT)) {
- macro.variadics = true;
- ++tk; // skip T_DOT_DOT_DOT
- }
-
- if (tk->isNot(T_RPAREN)) {
- // ### warning expected `)'
- return;
- }
-
- ++tk; // skip T_RPAREN
- }
-
- QByteArray macroId = macro.name;
- const bool isQtWord = isQtReservedWord(macroId);
-
- if (macro.function_like) {
- macroId += '(';
- for (int i = 0; i < macro.formals.size(); ++i) {
- if (i != 0)
- macroId += ", ";
-
- const QByteArray formal = macro.formals.at(i);
- macroId += formal;
- }
- macroId += ')';
- }
-
- if (isQtWord)
- macro.definition = macroId;
- else {
- // ### make me fast!
- const char *startOfDefinition = startOfToken(*tk);
- const char *endOfDefinition = startOfToken(*lastToken);
- macro.definition.append(startOfDefinition,
- endOfDefinition - startOfDefinition);
- macro.definition.replace("\\\n", " ");
- macro.definition.replace('\n', ' ');
- macro.definition = macro.definition.trimmed();
- }
-
- env.bind(macro);
-
- QByteArray macroText;
- macroText.reserve(64);
- macroText += "#define ";
-
- macroText += macroId;
- macroText += ' ';
- macroText += macro.definition;
- macroText += '\n';
-
- client->macroAdded(macroId, macroText);
-}
-
-void pp::processIf(TokenIterator firstToken, TokenIterator lastToken)
-{
- RangeLexer tk(firstToken, lastToken);
-
- ++tk; // skip T_POUND
- ++tk; // skipt `if'
-
- if (testIfLevel()) {
- const char *first = startOfToken(*tk);
- const char *last = startOfToken(*lastToken);
-
- MacroExpander expandCondition (env);
- QByteArray condition;
- condition.reserve(256);
- expandCondition(first, last, &condition);
-
- QVector<Token> tokens = tokenize(condition);
-
- const Value result = evalExpression(tokens.constBegin(),
- tokens.constEnd() - 1,
- condition);
-
- _true_test[iflevel] = ! result.is_zero ();
- _skipping[iflevel] = result.is_zero ();
- }
-}
-
-void pp::processElse(TokenIterator firstToken, TokenIterator lastToken)
-{
- RangeLexer tk(firstToken, lastToken);
-
- if (iflevel == 0 && !skipping ()) {
- // std::cerr << "*** WARNING #else without #if" << std::endl;
- } else if (iflevel > 0 && _skipping[iflevel - 1]) {
- _skipping[iflevel] = true;
- } else {
- _skipping[iflevel] = _true_test[iflevel];
- }
-}
-
-void pp::processElif(TokenIterator firstToken, TokenIterator lastToken)
-{
- RangeLexer tk(firstToken, lastToken);
- ++tk; // skip T_POUND
- ++tk; // skipt `elif'
-
- if (! (iflevel > 0)) {
- // std::cerr << "*** WARNING: " << __FILE__ << __LINE__ << std::endl;
- } else if (iflevel == 0 && !skipping()) {
- // std::cerr << "*** WARNING #else without #if" << std::endl;
- } else if (!_true_test[iflevel] && !_skipping[iflevel - 1]) {
- const Value result = evalExpression(tk.dot(), lastToken, _source);
- _true_test[iflevel] = ! result.is_zero ();
- _skipping[iflevel] = result.is_zero ();
- } else {
- _skipping[iflevel] = true;
- }
-}
-
-void pp::processEndif(TokenIterator, TokenIterator)
-{
- if (iflevel == 0 && !skipping()) {
- // std::cerr << "*** WARNING #endif without #if" << std::endl;
- } else {
- _skipping[iflevel] = false;
- _true_test[iflevel] = false;
-
- --iflevel;
- }
-}
-
-void pp::processIfdef(bool checkUndefined,
- TokenIterator firstToken, TokenIterator lastToken)
-{
- RangeLexer tk(firstToken, lastToken);
-
- ++tk; // skip T_POUND
- ++tk; // skip `ifdef'
- if (testIfLevel()) {
- if (tk->is(T_IDENTIFIER)) {
- const QByteArray macroName = tokenSpell(*tk);
- bool value = env.resolve(macroName) != 0 || env.isBuiltinMacro(macroName);
-
- if (checkUndefined)
- value = ! value;
-
- _true_test[iflevel] = value;
- _skipping [iflevel] = ! value;
- }
- }
-}
-
-void pp::processUndef(TokenIterator firstToken, TokenIterator lastToken)
-{
- RangeLexer tk(firstToken, lastToken);
-
- ++tk; // skip T_POUND
- ++tk; // skip `undef'
-
- if (tk->is(T_IDENTIFIER)) {
- const QByteArray macroName = tokenText(*tk);
- env.remove(macroName);
-
- QByteArray macroText;
- macroText += "#undef ";
- macroText += macroName;
- macroText += '\n';
- client->macroAdded(macroName, macroText);
- }
-}
-
-void pp::resetIfLevel ()
-{
- iflevel = 0;
- _skipping[iflevel] = false;
- _true_test[iflevel] = false;
-}
-
-pp::PP_DIRECTIVE_TYPE pp::classifyDirective (const QByteArray &__directive) const
-{
- switch (__directive.size())
- {
- case 2:
- if (__directive[0] == 'i' && __directive[1] == 'f')
- return PP_IF;
- break;
-
- case 4:
- if (__directive[0] == 'e' && __directive == "elif")
- return PP_ELIF;
- else if (__directive[0] == 'e' && __directive == "else")
- return PP_ELSE;
- break;
-
- case 5:
- if (__directive[0] == 'i' && __directive == "ifdef")
- return PP_IFDEF;
- else if (__directive[0] == 'u' && __directive == "undef")
- return PP_UNDEF;
- else if (__directive[0] == 'e' && __directive == "endif")
- return PP_ENDIF;
- break;
-
- case 6:
- if (__directive[0] == 'i' && __directive == "ifndef")
- return PP_IFNDEF;
- else if (__directive[0] == 'd' && __directive == "define")
- return PP_DEFINE;
- break;
-
- case 7:
- if (__directive[0] == 'i' && __directive == "include")
- return PP_INCLUDE;
- break;
-
- case 12:
- if (__directive[0] == 'i' && __directive == "include_next")
- return PP_INCLUDE_NEXT;
- break;
-
- default:
- break;
- }
-
- return PP_UNKNOWN_DIRECTIVE;
-}
-
-bool pp::testIfLevel()
-{
- const bool result = !_skipping[iflevel++];
- _skipping[iflevel] = _skipping[iflevel - 1];
- _true_test[iflevel] = false;
- return result;
-}
-
-int pp::skipping() const
-{ return _skipping[iflevel]; }
-
-Value pp::evalExpression(TokenIterator firstToken, TokenIterator lastToken,
- const QByteArray &source) const
-{
- ExpressionEvaluator eval(&env);
- const Value result = eval(firstToken, lastToken, source);
- return result;
-}
-
-bool pp::isQtReservedWord (const QByteArray &macroId) const
-{
- const int size = macroId.size();
- if (size == 9 && macroId.at(0) == 'Q' && macroId == "Q_SIGNALS")
- return true;
- else if (size == 7 && macroId.at(0) == 'Q' && macroId == "Q_SLOTS")
- return true;
- else if (size == 6 && macroId.at(0) == 'S' && macroId == "SIGNAL")
- return true;
- else if (size == 4 && macroId.at(0) == 'S' && macroId == "SLOT")
- return true;
- else if (size == 7 && macroId.at(0) == 's' && macroId == "signals")
- return true;
- else if (size == 5 && macroId.at(0) == 's' && macroId == "slots")
- return true;
- return false;
-}
diff --git a/src/plugins/cpptools/rpp/pp-engine.h b/src/plugins/cpptools/rpp/pp-engine.h
deleted file mode 100644
index 13135f6a31..0000000000
--- a/src/plugins/cpptools/rpp/pp-engine.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/***************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-**
-** Non-Open Source Usage
-**
-** Licensees may use this file in accordance with the Qt Beta Version
-** License Agreement, Agreement version 2.2 provided with the Software or,
-** alternatively, in accordance with the terms contained in a written
-** agreement between you and Nokia.
-**
-** GNU General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the packaging
-** of this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-**
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt GPL Exception
-** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
-**
-***************************************************************************/
-/*
- Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
-
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef PP_ENGINE_H
-#define PP_ENGINE_H
-
-#include "pp-client.h"
-
-#include <Token.h>
-#include <QVector>
-
-namespace CPlusPlus {
- class Token;
-}
-
-namespace rpp {
-
- struct Value
- {
- enum Kind {
- Kind_Long,
- Kind_ULong,
- };
-
- Kind kind;
-
- union {
- long l;
- unsigned long ul;
- };
-
-
- Value()
- : kind(Kind_Long), l(0)
- { }
-
- inline bool is_ulong () const
- { return kind == Kind_ULong; }
-
- inline void set_ulong (unsigned long v)
- {
- ul = v;
- kind = Kind_ULong;
- }
-
- inline void set_long (long v)
- {
- l = v;
- kind = Kind_Long;
- }
-
- inline bool is_zero () const
- { return l == 0; }
-
-#define PP_DEFINE_BIN_OP(name, op) \
- inline Value operator op(const Value &other) const \
- { \
- Value v = *this; \
- if (v.is_ulong () || other.is_ulong ()) \
- v.set_ulong (v.ul op other.ul); \
- else \
- v.set_long (v.l op other.l); \
- return v; \
- }
-
- PP_DEFINE_BIN_OP(op_add, +)
- PP_DEFINE_BIN_OP(op_sub, -)
- PP_DEFINE_BIN_OP(op_mult, *)
- PP_DEFINE_BIN_OP(op_div, /)
- PP_DEFINE_BIN_OP(op_mod, %)
- PP_DEFINE_BIN_OP(op_lhs, <<)
- PP_DEFINE_BIN_OP(op_rhs, >>)
- PP_DEFINE_BIN_OP(op_lt, <)
- PP_DEFINE_BIN_OP(op_gt, >)
- PP_DEFINE_BIN_OP(op_le, <=)
- PP_DEFINE_BIN_OP(op_ge, >=)
- PP_DEFINE_BIN_OP(op_eq, ==)
- PP_DEFINE_BIN_OP(op_ne, !=)
- PP_DEFINE_BIN_OP(op_bit_and, &)
- PP_DEFINE_BIN_OP(op_bit_or, |)
- PP_DEFINE_BIN_OP(op_bit_xor, ^)
- PP_DEFINE_BIN_OP(op_and, &&)
- PP_DEFINE_BIN_OP(op_or, ||)
-
-#undef PP_DEFINE_BIN_OP
- };
-
- class pp
- {
- Client *client;
- Environment &env;
- MacroExpander expand;
-
- enum { MAX_LEVEL = 512 };
-
- bool _skipping[MAX_LEVEL]; // ### move in state
- bool _true_test[MAX_LEVEL]; // ### move in state
- int iflevel; // ### move in state
-
- enum PP_DIRECTIVE_TYPE
- {
- PP_UNKNOWN_DIRECTIVE,
- PP_DEFINE,
- PP_INCLUDE,
- PP_INCLUDE_NEXT,
- PP_ELIF,
- PP_ELSE,
- PP_ENDIF,
- PP_IF,
- PP_IFDEF,
- PP_IFNDEF,
- PP_UNDEF
- };
-
- typedef const CPlusPlus::Token *TokenIterator;
-
- struct State {
- QByteArray source;
- QVector<CPlusPlus::Token> tokens;
- TokenIterator dot;
- };
-
- QList<State> _savedStates;
-
- State state() const;
- void pushState(const State &state);
- void popState();
-
- QByteArray _source;
- QVector<CPlusPlus::Token> _tokens;
- TokenIterator _dot;
-
- State createStateFromSource(const QByteArray &source) const;
-
- public:
- pp(Client *client, Environment &env);
-
- void operator()(const QByteArray &filename,
- const QByteArray &source,
- QByteArray *result);
-
- void operator()(const QByteArray &source,
- QByteArray *result);
-
- private:
- void resetIfLevel();
- bool testIfLevel();
- int skipping() const;
-
- PP_DIRECTIVE_TYPE classifyDirective(const QByteArray &directive) const;
-
- Value evalExpression(TokenIterator firstToken,
- TokenIterator lastToken,
- const QByteArray &source) const;
-
- QVector<CPlusPlus::Token> tokenize(const QByteArray &text) const;
-
- const char *startOfToken(const CPlusPlus::Token &token) const;
- const char *endOfToken(const CPlusPlus::Token &token) const;
-
- QByteArray tokenSpell(const CPlusPlus::Token &token) const;
- QByteArray tokenText(const CPlusPlus::Token &token) const; // does a deep copy
-
- void processDirective(TokenIterator dot, TokenIterator lastToken);
- void processInclude(bool skipCurrentPath,
- TokenIterator dot, TokenIterator lastToken,
- bool acceptMacros = true);
- void processDefine(TokenIterator dot, TokenIterator lastToken);
- void processIf(TokenIterator dot, TokenIterator lastToken);
- void processElse(TokenIterator dot, TokenIterator lastToken);
- void processElif(TokenIterator dot, TokenIterator lastToken);
- void processEndif(TokenIterator dot, TokenIterator lastToken);
- void processIfdef(bool checkUndefined,
- TokenIterator dot, TokenIterator lastToken);
- void processUndef(TokenIterator dot, TokenIterator lastToken);
-
- bool isQtReservedWord(const QByteArray &name) const;
- };
-
-} // namespace rpp
-
-#endif // PP_ENGINE_H
diff --git a/src/plugins/cpptools/rpp/pp-environment.cpp b/src/plugins/cpptools/rpp/pp-environment.cpp
deleted file mode 100644
index 85e432ae5b..0000000000
--- a/src/plugins/cpptools/rpp/pp-environment.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/***************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-**
-** Non-Open Source Usage
-**
-** Licensees may use this file in accordance with the Qt Beta Version
-** License Agreement, Agreement version 2.2 provided with the Software or,
-** alternatively, in accordance with the terms contained in a written
-** agreement between you and Nokia.
-**
-** GNU General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the packaging
-** of this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-**
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt GPL Exception
-** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
-**
-***************************************************************************/
-/*
- Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
-
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "pp-environment.h"
-#include "pp.h"
-#include <cstring>
-
-using namespace rpp;
-
-Environment::Environment ()
- : currentLine(0),
- hide_next(false),
- _macros(0),
- _allocated_macros(0),
- _macro_count(-1),
- _hash(0),
- _hash_count(401)
-{
-}
-
-Environment::~Environment ()
-{
- if (_macros) {
- qDeleteAll(firstMacro(), lastMacro());
- free(_macros);
- }
-
- if (_hash)
- free(_hash);
-}
-
-unsigned Environment::macroCount () const
-{ return _macro_count + 1; }
-
-Macro *Environment::macroAt (unsigned index) const
-{ return _macros[index]; }
-
-Macro *Environment::bind(const Macro &__macro)
-{
- Q_ASSERT(! __macro.name.isEmpty());
-
- Macro *m = new Macro (__macro);
- m->hashcode = hash_code(m->name);
- m->fileName = current_file;
- m->line = currentLine;
-
- if (++_macro_count == _allocated_macros) {
- if (! _allocated_macros)
- _allocated_macros = 401;
- else
- _allocated_macros <<= 1;
-
- _macros = (Macro **) realloc(_macros, sizeof(Macro *) * _allocated_macros);
- }
-
- _macros[_macro_count] = m;
-
- if (! _hash || _macro_count > (_hash_count >> 1)) {
- rehash();
- } else {
- const unsigned h = m->hashcode % _hash_count;
- m->next = _hash[h];
- _hash[h] = m;
- }
-
- return m;
-}
-
-void Environment::remove (const QByteArray &name)
-{
- Macro macro;
- macro.name = name;
- macro.hidden = true;
- bind(macro);
-}
-
-bool Environment::isBuiltinMacro(const QByteArray &s) const
-{
- if (s.length() != 8)
- return false;
-
- if (s[0] == '_') {
- if (s[1] == '_') {
- if (s[2] == 'D') {
- if (s[3] == 'A') {
- if (s[4] == 'T') {
- if (s[5] == 'E') {
- if (s[6] == '_') {
- if (s[7] == '_') {
- return true;
- }
- }
- }
- }
- }
- }
- else if (s[2] == 'F') {
- if (s[3] == 'I') {
- if (s[4] == 'L') {
- if (s[5] == 'E') {
- if (s[6] == '_') {
- if (s[7] == '_') {
- return true;
- }
- }
- }
- }
- }
- }
- else if (s[2] == 'L') {
- if (s[3] == 'I') {
- if (s[4] == 'N') {
- if (s[5] == 'E') {
- if (s[6] == '_') {
- if (s[7] == '_') {
- return true;
- }
- }
- }
- }
- }
- }
- else if (s[2] == 'T') {
- if (s[3] == 'I') {
- if (s[4] == 'M') {
- if (s[5] == 'E') {
- if (s[6] == '_') {
- if (s[7] == '_') {
- return true;
- }
- }
- }
- }
- }
- }
- }
- }
- return false;
-}
-
-Macro *Environment::resolve (const QByteArray &name) const
-{
- if (! _macros)
- return 0;
-
- Macro *it = _hash[hash_code (name) % _hash_count];
- for (; it; it = it->next) {
- if (it->name != name)
- continue;
- else if (it->hidden)
- return 0;
- else break;
- }
- return it;
-}
-
-unsigned Environment::hash_code (const QByteArray &s)
-{
- unsigned hash_value = 0;
-
- for (int i = 0; i < s.size (); ++i)
- hash_value = (hash_value << 5) - hash_value + s.at (i);
-
- return hash_value;
-}
-
-void Environment::rehash()
-{
- if (_hash) {
- free(_hash);
- _hash_count <<= 1;
- }
-
- _hash = (Macro **) calloc(_hash_count, sizeof(Macro *));
-
- for (Macro **it = firstMacro(); it != lastMacro(); ++it) {
- Macro *m= *it;
- const unsigned h = m->hashcode % _hash_count;
- m->next = _hash[h];
- _hash[h] = m;
- }
-}
diff --git a/src/plugins/cpptools/rpp/pp-environment.h b/src/plugins/cpptools/rpp/pp-environment.h
deleted file mode 100644
index 5b97c492d7..0000000000
--- a/src/plugins/cpptools/rpp/pp-environment.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/***************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-**
-** Non-Open Source Usage
-**
-** Licensees may use this file in accordance with the Qt Beta Version
-** License Agreement, Agreement version 2.2 provided with the Software or,
-** alternatively, in accordance with the terms contained in a written
-** agreement between you and Nokia.
-**
-** GNU General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the packaging
-** of this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-**
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt GPL Exception
-** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
-**
-***************************************************************************/
-/*
- Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
-
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef PP_ENVIRONMENT_H
-#define PP_ENVIRONMENT_H
-
-#include <QVector>
-#include <QByteArray>
-
-namespace rpp {
-
-struct Macro;
-
-class Environment
-{
-public:
- Environment();
- ~Environment();
-
- unsigned macroCount() const;
- Macro *macroAt(unsigned index) const;
-
- Macro *bind(const Macro &macro);
- void remove(const QByteArray &name);
-
- Macro *resolve(const QByteArray &name) const;
- bool isBuiltinMacro(const QByteArray &name) const;
-
- const Macro *const *firstMacro() const
- { return _macros; }
-
- Macro **firstMacro()
- { return _macros; }
-
- const Macro *const *lastMacro() const
- { return _macros + _macro_count + 1; }
-
- Macro **lastMacro()
- { return _macros + _macro_count + 1; }
-
-private:
- static unsigned hash_code (const QByteArray &s);
- void rehash();
-
-public:
- QByteArray current_file;
- unsigned currentLine;
- bool hide_next;
-
-private:
- Macro **_macros;
- int _allocated_macros;
- int _macro_count;
- Macro **_hash;
- int _hash_count;
-};
-
-} // namespace rpp
-
-#endif // PP_ENVIRONMENT_H
diff --git a/src/plugins/cpptools/rpp/pp-internal.h b/src/plugins/cpptools/rpp/pp-internal.h
deleted file mode 100644
index 13bc7c17e8..0000000000
--- a/src/plugins/cpptools/rpp/pp-internal.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/***************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-**
-** Non-Open Source Usage
-**
-** Licensees may use this file in accordance with the Qt Beta Version
-** License Agreement, Agreement version 2.2 provided with the Software or,
-** alternatively, in accordance with the terms contained in a written
-** agreement between you and Nokia.
-**
-** GNU General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the packaging
-** of this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-**
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt GPL Exception
-** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
-**
-***************************************************************************/
-/*
- Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
-
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef PP_INTERNAL_H
-#define PP_INTERNAL_H
-
-#include <QByteArray>
-
-namespace rpp {
-namespace _PP_internal {
-
-inline bool comment_p (const char *__first, const char *__last)
-{
- if (__first == __last)
- return false;
-
- if (*__first != '/')
- return false;
-
- if (++__first == __last)
- return false;
-
- return (*__first == '/' || *__first == '*');
-}
-
-} // _PP_internal
-} // namespace rpp
-
-#endif // PP_INTERNAL_H
diff --git a/src/plugins/cpptools/rpp/pp-macro-expander.cpp b/src/plugins/cpptools/rpp/pp-macro-expander.cpp
deleted file mode 100644
index 6b569eb132..0000000000
--- a/src/plugins/cpptools/rpp/pp-macro-expander.cpp
+++ /dev/null
@@ -1,361 +0,0 @@
-/***************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-**
-** Non-Open Source Usage
-**
-** Licensees may use this file in accordance with the Qt Beta Version
-** License Agreement, Agreement version 2.2 provided with the Software or,
-** alternatively, in accordance with the terms contained in a written
-** agreement between you and Nokia.
-**
-** GNU General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the packaging
-** of this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-**
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt GPL Exception
-** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
-**
-***************************************************************************/
-
-#include "pp.h"
-#include "pp-macro-expander.h"
-#include <QDateTime>
-
-using namespace rpp;
-
-MacroExpander::MacroExpander (Environment &env, pp_frame *frame)
- : env(env), frame(frame),
- lines(0), generated_lines(0)
-{ }
-
-const QByteArray *MacroExpander::resolve_formal(const QByteArray &__name)
-{
- if (! (frame && frame->expanding_macro))
- return 0;
-
- const QVector<QByteArray> &formals = frame->expanding_macro->formals;
- for (int index = 0; index < formals.size(); ++index) {
- const QByteArray formal = formals.at(index);
-
- if (formal == __name && index < frame->actuals.size())
- return &frame->actuals.at(index);
- }
-
- return 0;
-}
-
-const char *MacroExpander::operator () (const char *__first, const char *__last,
- QByteArray *__result)
-{
- generated_lines = 0;
- __first = skip_blanks (__first, __last);
- lines = skip_blanks.lines;
-
- while (__first != __last)
- {
- if (*__first == '\n')
- {
- __result->append("\n# ");
- __result->append(QByteArray::number(env.currentLine));
- __result->append(' ');
- __result->append('"');
- __result->append(env.current_file);
- __result->append('"');
- __result->append('\n');
- ++lines;
-
- __first = skip_blanks (++__first, __last);
- lines += skip_blanks.lines;
-
- if (__first != __last && *__first == '#')
- break;
- }
- else if (*__first == '#')
- {
- __first = skip_blanks (++__first, __last);
- lines += skip_blanks.lines;
-
- const char *end_id = skip_identifier (__first, __last);
- const QByteArray fast_name(__first, end_id - __first);
- __first = end_id;
-
- if (const QByteArray *actual = resolve_formal (fast_name))
- {
- __result->append('\"');
-
- const char *actual_begin = actual->constData ();
- const char *actual_end = actual_begin + actual->size ();
-
- for (const char *it = skip_whitespaces (actual_begin, actual_end);
- it != actual_end; ++it)
- {
- if (*it == '"' || *it == '\\')
- {
- __result->append('\\');
- __result->append(*it);
- }
- else if (*it == '\n')
- {
- __result->append('"');
- __result->append('\n');
- __result->append('"');
- }
- else
- __result->append(*it);
- }
-
- __result->append('\"');
- }
- else
- __result->append('#'); // ### warning message?
- }
- else if (*__first == '\"')
- {
- const char *next_pos = skip_string_literal (__first, __last);
- lines += skip_string_literal.lines;
- __result->append(__first, next_pos - __first);
- __first = next_pos;
- }
- else if (*__first == '\'')
- {
- const char *next_pos = skip_char_literal (__first, __last);
- lines += skip_char_literal.lines;
- __result->append(__first, next_pos - __first);
- __first = next_pos;
- }
- else if (_PP_internal::comment_p (__first, __last))
- {
- __first = skip_comment_or_divop (__first, __last);
- int n = skip_comment_or_divop.lines;
- lines += n;
-
- while (n-- > 0)
- __result->append('\n');
- }
- else if (pp_isspace (*__first))
- {
- for (; __first != __last; ++__first)
- {
- if (*__first == '\n' || !pp_isspace (*__first))
- break;
- }
-
- __result->append(' ');
- }
- else if (pp_isdigit (*__first))
- {
- const char *next_pos = skip_number (__first, __last);
- lines += skip_number.lines;
- __result->append(__first, next_pos - __first);
- __first = next_pos;
- }
- else if (pp_isalpha (*__first) || *__first == '_')
- {
- const char *name_begin = __first;
- const char *name_end = skip_identifier (__first, __last);
- __first = name_end; // advance
-
- // search for the paste token
- const char *next = skip_blanks (__first, __last);
- bool paste = false;
- if (next != __last && *next == '#')
- {
- paste = true;
- ++next;
- if (next != __last && *next == '#')
- __first = skip_blanks(++next, __last);
- }
-
- const QByteArray fast_name(name_begin, name_end - name_begin);
-
- if (const QByteArray *actual = resolve_formal (fast_name))
- {
- const char *begin = actual->constData ();
- const char *end = begin + actual->size ();
- if (paste) {
- for (--end; end != begin - 1; --end) {
- if (! pp_isspace(*end))
- break;
- }
- ++end;
- }
- __result->append(begin, end - begin);
- continue;
- }
-
- Macro *macro = env.resolve (fast_name);
- if (! macro || macro->hidden || env.hide_next)
- {
- if (fast_name.size () == 7 && fast_name [0] == 'd' && fast_name == "defined")
- env.hide_next = true;
- else
- env.hide_next = false;
-
- if (fast_name.size () == 8 && fast_name [0] == '_' && fast_name [1] == '_')
- {
- if (fast_name == "__LINE__")
- {
- char buf [16];
- const size_t count = qsnprintf (buf, 16, "%d", env.currentLine + lines);
- __result->append(buf, count);
- continue;
- }
-
- else if (fast_name == "__FILE__")
- {
- __result->append('"');
- __result->append(env.current_file);
- __result->append('"');
- continue;
- }
-
- else if (fast_name == "__DATE__")
- {
- __result->append('"');
- __result->append(QDate::currentDate().toString().toUtf8());
- __result->append('"');
- continue;
- }
-
- else if (fast_name == "__TIME__")
- {
- __result->append('"');
- __result->append(QTime::currentTime().toString().toUtf8());
- __result->append('"');
- continue;
- }
-
- }
-
- __result->append(name_begin, name_end - name_begin);
- continue;
- }
-
- if (! macro->function_like)
- {
- Macro *m = 0;
-
- if (! macro->definition.isEmpty())
- {
- macro->hidden = true;
-
- QByteArray __tmp;
- __tmp.reserve (256);
-
- MacroExpander expand_macro (env);
- expand_macro (macro->definition.constBegin (), macro->definition.constEnd (), &__tmp);
- generated_lines += expand_macro.lines;
-
- if (! __tmp.isEmpty ())
- {
- const char *__tmp_begin = __tmp.constBegin();
- const char *__tmp_end = __tmp.constEnd();
- const char *__begin_id = skip_whitespaces (__tmp_begin, __tmp_end);
- const char *__end_id = skip_identifier (__begin_id, __tmp_end);
-
- if (__end_id == __tmp_end)
- {
- const QByteArray __id (__begin_id, __end_id - __begin_id);
- m = env.resolve (__id);
- }
-
- if (! m)
- *__result += __tmp;
- }
-
- macro->hidden = false;
- }
-
- if (! m)
- continue;
-
- macro = m;
- }
-
- // function like macro
- const char *arg_it = skip_whitespaces (__first, __last);
-
- if (arg_it == __last || *arg_it != '(')
- {
- __result->append(name_begin, name_end - name_begin);
- lines += skip_whitespaces.lines;
- __first = arg_it;
- continue;
- }
-
- QVector<QByteArray> actuals;
- actuals.reserve (5);
- ++arg_it; // skip '('
-
- MacroExpander expand_actual (env, frame);
-
- const char *arg_end = skip_argument_variadics (actuals, macro, arg_it, __last);
- if (arg_it != arg_end)
- {
- const QByteArray actual (arg_it, arg_end - arg_it);
- QByteArray expanded;
- expand_actual (actual.constBegin (), actual.constEnd (), &expanded);
- actuals.push_back (expanded);
- arg_it = arg_end;
- }
-
- while (arg_it != __last && *arg_end == ',')
- {
- ++arg_it; // skip ','
-
- arg_end = skip_argument_variadics (actuals, macro, arg_it, __last);
- const QByteArray actual (arg_it, arg_end - arg_it);
- QByteArray expanded;
- expand_actual (actual.constBegin (), actual.constEnd (), &expanded);
- actuals.push_back (expanded);
- arg_it = arg_end;
- }
-
- if (! (arg_it != __last && *arg_it == ')'))
- return __last;
-
- ++arg_it; // skip ')'
- __first = arg_it;
-
- pp_frame frame (macro, actuals);
- MacroExpander expand_macro (env, &frame);
- macro->hidden = true;
- expand_macro (macro->definition.constBegin (), macro->definition.constEnd (), __result);
- macro->hidden = false;
- generated_lines += expand_macro.lines;
- }
- else
- __result->append(*__first++);
- }
-
- return __first;
-}
-
-const char *MacroExpander::skip_argument_variadics (QVector<QByteArray> const &__actuals,
- Macro *__macro,
- const char *__first, const char *__last)
-{
- const char *arg_end = skip_argument (__first, __last);
-
- while (__macro->variadics && __first != arg_end && arg_end != __last && *arg_end == ','
- && (__actuals.size () + 1) == __macro->formals.size ())
- {
- arg_end = skip_argument (++arg_end, __last);
- }
-
- return arg_end;
-}
diff --git a/src/plugins/cpptools/rpp/pp-macro-expander.h b/src/plugins/cpptools/rpp/pp-macro-expander.h
deleted file mode 100644
index dd11540c33..0000000000
--- a/src/plugins/cpptools/rpp/pp-macro-expander.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/***************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-**
-** Non-Open Source Usage
-**
-** Licensees may use this file in accordance with the Qt Beta Version
-** License Agreement, Agreement version 2.2 provided with the Software or,
-** alternatively, in accordance with the terms contained in a written
-** agreement between you and Nokia.
-**
-** GNU General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the packaging
-** of this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-**
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt GPL Exception
-** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
-**
-***************************************************************************/
-/*
- Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
-
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef PP_MACRO_EXPANDER_H
-#define PP_MACRO_EXPANDER_H
-
-namespace rpp {
-
- struct pp_frame
- {
- Macro *expanding_macro;
- const QVector<QByteArray> actuals;
-
- pp_frame (Macro *expanding_macro, const QVector<QByteArray> &actuals)
- : expanding_macro (expanding_macro),
- actuals (actuals)
- { }
- };
-
- class MacroExpander
- {
- Environment &env;
- pp_frame *frame;
-
- pp_skip_number skip_number;
- pp_skip_identifier skip_identifier;
- pp_skip_string_literal skip_string_literal;
- pp_skip_char_literal skip_char_literal;
- pp_skip_argument skip_argument;
- pp_skip_comment_or_divop skip_comment_or_divop;
- pp_skip_blanks skip_blanks;
- pp_skip_whitespaces skip_whitespaces;
-
- const QByteArray *resolve_formal (const QByteArray &name);
-
- public:
- MacroExpander (Environment &env, pp_frame *frame = 0);
-
- const char *operator () (const char *first, const char *last,
- QByteArray *result);
-
- const char *skip_argument_variadics (const QVector<QByteArray> &actuals,
- Macro *macro,
- const char *first, const char *last);
-
- public: // attributes
- int lines;
- int generated_lines;
- };
-
-} // namespace rpp
-
-#endif // PP_MACRO_EXPANDER_H
-
diff --git a/src/plugins/cpptools/rpp/pp-macro.h b/src/plugins/cpptools/rpp/pp-macro.h
deleted file mode 100644
index a7bbe35e1d..0000000000
--- a/src/plugins/cpptools/rpp/pp-macro.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/***************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-**
-** Non-Open Source Usage
-**
-** Licensees may use this file in accordance with the Qt Beta Version
-** License Agreement, Agreement version 2.2 provided with the Software or,
-** alternatively, in accordance with the terms contained in a written
-** agreement between you and Nokia.
-**
-** GNU General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the packaging
-** of this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-**
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt GPL Exception
-** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
-**
-***************************************************************************/
-/*
- Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
-
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef PP_MACRO_H
-#define PP_MACRO_H
-
-#include <QByteArray>
-#include <QVector>
-
-namespace rpp {
-
- struct Macro
- {
- QByteArray name;
- QByteArray definition;
- QVector<QByteArray> formals;
- QByteArray fileName;
- int line;
- int lines;
- Macro *next;
- unsigned hashcode;
-
- union
- {
- unsigned state;
-
- struct
- {
- unsigned hidden: 1;
- unsigned function_like: 1;
- unsigned variadics: 1;
- };
- };
-
- inline Macro():
- line(0),
- lines(0),
- next(0),
- hashcode(0),
- state(0)
- { }
- };
-
-} // namespace rpp
-
-#endif // PP_MACRO_H
diff --git a/src/plugins/cpptools/rpp/pp-scanner.h b/src/plugins/cpptools/rpp/pp-scanner.h
deleted file mode 100644
index 53fea70b52..0000000000
--- a/src/plugins/cpptools/rpp/pp-scanner.h
+++ /dev/null
@@ -1,380 +0,0 @@
-/***************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-**
-** Non-Open Source Usage
-**
-** Licensees may use this file in accordance with the Qt Beta Version
-** License Agreement, Agreement version 2.2 provided with the Software or,
-** alternatively, in accordance with the terms contained in a written
-** agreement between you and Nokia.
-**
-** GNU General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the packaging
-** of this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-**
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt GPL Exception
-** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
-**
-***************************************************************************/
-/*
- Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
-
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef PP_SCANNER_H
-#define PP_SCANNER_H
-
-namespace rpp {
-
-struct pp_skip_blanks
-{
- int lines;
-
-
- const char *operator () (const char *__first, const char *__last)
- {
- lines = 0;
-
- for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first)
- {
- if (*__first == '\\')
- {
- const char *__begin = __first;
- ++__begin;
-
- if (__begin != __last && *__begin == '\n')
- ++__first;
- else
- break;
- }
- else if (*__first == '\n' || !pp_isspace (*__first))
- break;
- }
-
- return __first;
- }
-};
-
-struct pp_skip_whitespaces
-{
- int lines;
-
-
- const char *operator () (const char *__first, const char *__last)
- {
- lines = 0;
-
- for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first)
- {
- if (! pp_isspace (*__first))
- break;
- }
-
- return __first;
- }
-};
-
-struct pp_skip_comment_or_divop
-{
- int lines;
-
-
- const char *operator () (const char *__first, const char *__last)
- {
- enum {
- MAYBE_BEGIN,
- BEGIN,
- MAYBE_END,
- END,
- IN_COMMENT,
- IN_CXX_COMMENT
- } state (MAYBE_BEGIN);
-
- lines = 0;
-
- for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first)
- {
- switch (state)
- {
- default:
- assert (0);
- break;
-
- case MAYBE_BEGIN:
- if (*__first != '/')
- return __first;
-
- state = BEGIN;
- break;
-
- case BEGIN:
- if (*__first == '*')
- state = IN_COMMENT;
- else if (*__first == '/')
- state = IN_CXX_COMMENT;
- else
- return __first;
- break;
-
- case IN_COMMENT:
- if (*__first == '*')
- state = MAYBE_END;
- break;
-
- case IN_CXX_COMMENT:
- if (*__first == '\n')
- return __first;
- break;
-
- case MAYBE_END:
- if (*__first == '/')
- state = END;
- else if (*__first != '*')
- state = IN_COMMENT;
- break;
-
- case END:
- return __first;
- }
- }
-
- return __first;
- }
-};
-
-struct pp_skip_identifier
-{
- int lines;
-
-
- const char *operator () (const char *__first, const char *__last)
- {
- lines = 0;
-
- for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first)
- {
- if (! pp_isalnum (*__first) && *__first != '_')
- break;
- }
-
- return __first;
- }
-};
-
-struct pp_skip_number
-{
- int lines;
-
-
- const char *operator () (const char *__first, const char *__last)
- {
- lines = 0;
-
- for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first)
- {
- if (! pp_isalnum (*__first) && *__first != '.')
- break;
- }
-
- return __first;
- }
-};
-
-struct pp_skip_string_literal
-{
- int lines;
-
-
- const char *operator () (const char *__first, const char *__last)
- {
- enum {
- BEGIN,
- IN_STRING,
- QUOTE,
- END
- } state (BEGIN);
-
- lines = 0;
-
- for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first)
- {
- switch (state)
- {
- default:
- assert (0);
- break;
-
- case BEGIN:
- if (*__first != '\"')
- return __first;
- state = IN_STRING;
- break;
-
- case IN_STRING:
- if (! (*__first != '\n'))
- return __last;
-
- if (*__first == '\"')
- state = END;
- else if (*__first == '\\')
- state = QUOTE;
- break;
-
- case QUOTE:
- state = IN_STRING;
- break;
-
- case END:
- return __first;
- }
- }
-
- return __first;
- }
-};
-
-struct pp_skip_char_literal
-{
- int lines;
-
-
- const char *operator () (const char *__first, const char *__last)
- {
- enum {
- BEGIN,
- IN_STRING,
- QUOTE,
- END
- } state (BEGIN);
-
- lines = 0;
-
- for (; state != END && __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first)
- {
- switch (state)
- {
- default:
- assert (0);
- break;
-
- case BEGIN:
- if (*__first != '\'')
- return __first;
- state = IN_STRING;
- break;
-
- case IN_STRING:
- if (! (*__first != '\n'))
- return __last;
-
- if (*__first == '\'')
- state = END;
- else if (*__first == '\\')
- state = QUOTE;
- break;
-
- case QUOTE:
- state = IN_STRING;
- break;
- }
- }
-
- return __first;
- }
-};
-
-struct pp_skip_argument
-{
- pp_skip_identifier skip_number;
- pp_skip_identifier skip_identifier;
- pp_skip_string_literal skip_string_literal;
- pp_skip_char_literal skip_char_literal;
- pp_skip_comment_or_divop skip_comment_or_divop;
- int lines;
-
-
- const char *operator () (const char *__first, const char *__last)
- {
- int depth = 0;
- lines = 0;
-
- while (__first != __last)
- {
- if (!depth && (*__first == ')' || *__first == ','))
- break;
- else if (*__first == '(')
- ++depth, ++__first;
- else if (*__first == ')')
- --depth, ++__first;
- else if (*__first == '\"')
- {
- __first = skip_string_literal (__first, __last);
- lines += skip_string_literal.lines;
- }
- else if (*__first == '\'')
- {
- __first = skip_char_literal (__first, __last);
- lines += skip_char_literal.lines;
- }
- else if (*__first == '/')
- {
- __first = skip_comment_or_divop (__first, __last);
- lines += skip_comment_or_divop.lines;
- }
- else if (pp_isalpha (*__first) || *__first == '_')
- {
- __first = skip_identifier (__first, __last);
- lines += skip_identifier.lines;
- }
- else if (pp_isdigit (*__first))
- {
- __first = skip_number (__first, __last);
- lines += skip_number.lines;
- }
- else if (*__first == '\n')
- {
- ++__first;
- ++lines;
- }
- else
- ++__first;
- }
-
- return __first;
- }
-};
-
-} // namespace rpp
-
-#endif // PP_SCANNER_H
-
-// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/src/plugins/cpptools/rpp/pp.h b/src/plugins/cpptools/rpp/pp.h
deleted file mode 100644
index 62f3245a28..0000000000
--- a/src/plugins/cpptools/rpp/pp.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/***************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-**
-** Non-Open Source Usage
-**
-** Licensees may use this file in accordance with the Qt Beta Version
-** License Agreement, Agreement version 2.2 provided with the Software or,
-** alternatively, in accordance with the terms contained in a written
-** agreement between you and Nokia.
-**
-** GNU General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the packaging
-** of this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-**
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt GPL Exception
-** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
-**
-***************************************************************************/
-/*
- Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
-
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef PP_H
-#define PP_H
-
-#include <cassert>
-#include <cstring>
-#include <cctype>
-
-#include "pp-cctype.h"
-#include "pp-internal.h"
-#include "pp-macro.h"
-#include "pp-environment.h"
-#include "pp-scanner.h"
-#include "pp-macro-expander.h"
-#include "pp-engine.h"
-#include "pp-client.h"
-
-#endif // PP_H
diff --git a/src/plugins/cpptools/rpp/rpp.pri b/src/plugins/cpptools/rpp/rpp.pri
deleted file mode 100644
index a79b0028a0..0000000000
--- a/src/plugins/cpptools/rpp/rpp.pri
+++ /dev/null
@@ -1,18 +0,0 @@
-DEPENDPATH += $$PWD
-INCLUDEPATH += $$PWD
-
-HEADERS += $$PWD/pp-cctype.h \
- $$PWD/pp-engine.h \
- $$PWD/pp-environment.h \
- $$PWD/pp-internal.h \
- $$PWD/pp-macro-expander.h \
- $$PWD/pp-macro.h \
- $$PWD/pp-scanner.h \
- $$PWD/pp.h \
- $$PWD/pp-client.h
-
-SOURCES += $$PWD/pp-engine.cpp \
- $$PWD/pp-environment.cpp \
- $$PWD/pp-macro-expander.cpp
-
-
diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp
index 4b1e48abdf..308449ab58 100644
--- a/src/plugins/cpptools/searchsymbols.cpp
+++ b/src/plugins/cpptools/searchsymbols.cpp
@@ -40,7 +40,8 @@ using namespace CPlusPlus;
using namespace CppTools::Internal;
SearchSymbols::SearchSymbols():
- symbolsToSearchFor(Classes | Functions | Enums)
+ symbolsToSearchFor(Classes | Functions | Enums),
+ separateScope(false)
{
}
@@ -49,6 +50,11 @@ void SearchSymbols::setSymbolsToSearchFor(SymbolTypes types)
symbolsToSearchFor = types;
}
+void SearchSymbols::setSeparateScope(bool separateScope)
+{
+ this->separateScope = separateScope;
+}
+
QList<ModelItemInfo> SearchSymbols::operator()(Document::Ptr doc, const QString &scope)
{
QString previousScope = switchScope(scope);
@@ -73,13 +79,12 @@ bool SearchSymbols::visit(Enum *symbol)
return false;
QString name = symbolName(symbol);
- QString previousScope = switchScope(name);
- QIcon icon = icons.iconForSymbol(symbol);
+ QString scopedName = scopedSymbolName(name);
+ QString previousScope = switchScope(scopedName);
+ appendItem(separateScope ? name : scopedName,
+ separateScope ? previousScope : QString(),
+ ModelItemInfo::Enum, symbol);
Scope *members = symbol->members();
- items.append(ModelItemInfo(name, QString(), ModelItemInfo::Enum,
- QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
- symbol->line(),
- icon));
for (unsigned i = 0; i < members->symbolCount(); ++i) {
accept(members->symbolAt(i));
}
@@ -93,18 +98,18 @@ bool SearchSymbols::visit(Function *symbol)
return false;
QString name = symbolName(symbol);
- QString type = overview.prettyType(symbol->type());
- QIcon icon = icons.iconForSymbol(symbol);
- items.append(ModelItemInfo(name, type, ModelItemInfo::Method,
- QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
- symbol->line(),
- icon));
+ QString scopedName = scopedSymbolName(name);
+ QString type = overview.prettyType(symbol->type(),
+ separateScope ? symbol->name() : 0);
+ appendItem(separateScope ? type : scopedName,
+ separateScope ? _scope : type,
+ ModelItemInfo::Method, symbol);
return false;
}
bool SearchSymbols::visit(Namespace *symbol)
{
- QString name = symbolName(symbol);
+ QString name = findOrInsert(scopedSymbolName(symbol));
QString previousScope = switchScope(name);
Scope *members = symbol->members();
for (unsigned i = 0; i < members->symbolCount(); ++i) {
@@ -118,12 +123,9 @@ bool SearchSymbols::visit(Namespace *symbol)
bool SearchSymbols::visit(Declaration *symbol)
{
if (symbol->type()->isFunction()) {
- QString name = symbolName(symbol);
+ QString name = scopedSymbolName(symbol);
QString type = overview.prettyType(symbol->type());
- //QIcon icon = ...;
- items.append(ModelItemInfo(name, type, ModelItemInfo::Method,
- QString::fromUtf8(symbol->fileName(), symbol->line()),
- symbol->line()));
+ appendItems(name, type, ModelItemInfo::Method, symbol->fileName());
}
return false;
}
@@ -135,12 +137,11 @@ bool SearchSymbols::visit(Class *symbol)
return false;
QString name = symbolName(symbol);
- QString previousScope = switchScope(name);
- QIcon icon = icons.iconForSymbol(symbol);
- items.append(ModelItemInfo(name, QString(), ModelItemInfo::Class,
- QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
- symbol->line(),
- icon));
+ QString scopedName = scopedSymbolName(name);
+ QString previousScope = switchScope(scopedName);
+ appendItem(separateScope ? name : scopedName,
+ separateScope ? previousScope : QString(),
+ ModelItemInfo::Class, symbol);
Scope *members = symbol->members();
for (unsigned i = 0; i < members->symbolCount(); ++i) {
accept(members->symbolAt(i));
@@ -149,11 +150,22 @@ bool SearchSymbols::visit(Class *symbol)
return false;
}
-QString SearchSymbols::symbolName(const Symbol *symbol) const
+QString SearchSymbols::scopedSymbolName(const QString &symbolName) const
{
QString name = _scope;
if (! name.isEmpty())
name += QLatin1String("::");
+ name += symbolName;
+ return name;
+}
+
+QString SearchSymbols::scopedSymbolName(const Symbol *symbol) const
+{
+ return scopedSymbolName(symbolName(symbol));
+}
+
+QString SearchSymbols::symbolName(const Symbol *symbol) const
+{
QString symbolName = overview.prettyName(symbol->name());
if (symbolName.isEmpty()) {
QString type;
@@ -176,6 +188,17 @@ QString SearchSymbols::symbolName(const Symbol *symbol) const
symbolName += type;
symbolName += QLatin1String(">");
}
- name += symbolName;
- return name;
+ return symbolName;
+}
+
+void SearchSymbols::appendItem(const QString &name,
+ const QString &info,
+ ModelItemInfo::ItemType type,
+ const Symbol *symbol)
+{
+ const QIcon icon = icons.iconForSymbol(symbol);
+ items.append(ModelItemInfo(name, info, type,
+ QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
+ symbol->line(),
+ icon));
}
diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h
index 948f9d78e8..4997e5cf04 100644
--- a/src/plugins/cpptools/searchsymbols.h
+++ b/src/plugins/cpptools/searchsymbols.h
@@ -44,6 +44,8 @@
#include <QMetaType>
#include <QString>
+#include <functional>
+
namespace CppTools {
namespace Internal {
@@ -90,6 +92,7 @@ public:
SearchSymbols();
void setSymbolsToSearchFor(SymbolTypes types);
+ void setSeparateScope(bool separateScope);
QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc)
{ return operator()(doc, QString()); }
@@ -111,14 +114,27 @@ protected:
virtual bool visit(CPlusPlus::Declaration *symbol);
#endif
virtual bool visit(CPlusPlus::Class *symbol);
+
+ QString scopedSymbolName(const QString &symbolName) const;
+ QString scopedSymbolName(const CPlusPlus::Symbol *symbol) const;
QString symbolName(const CPlusPlus::Symbol *symbol) const;
+ void appendItem(const QString &name,
+ const QString &info,
+ ModelItemInfo::ItemType type,
+ const CPlusPlus::Symbol *symbol);
private:
+ QString findOrInsert(const QString &s)
+ { return *strings.insert(s); }
+
+ QSet<QString> strings; // Used to avoid QString duplication
+
QString _scope;
CPlusPlus::Overview overview;
CPlusPlus::Icons icons;
QList<ModelItemInfo> items;
SymbolTypes symbolsToSearchFor;
+ bool separateScope;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(SearchSymbols::SymbolTypes)