forked from qt-creator/qt-creator
		
	Convert macros from plain QByteArray to a vector of structs
The old code model expected the macros as C++ formatted text
("#define Foo 42) but newer targets like the Clang codemodel expect key
value arguments like "-DFoo=42". So instead of parsing the text again and
again we use an abstract data description.
Task-number: QTCREATORBUG-17915
Change-Id: I0179fd13c48a581e91ee79bba9d42d501c26f19f
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
			
			
This commit is contained in:
		| @@ -26,6 +26,7 @@ | ||||
| #include "builtineditordocumentparser.h" | ||||
| #include "cppsourceprocessor.h" | ||||
|  | ||||
| #include <projectexplorer/projectmacro.h> | ||||
| #include <projectexplorer/projectexplorerconstants.h> | ||||
|  | ||||
| #include <utils/qtcassert.h> | ||||
| @@ -91,9 +92,9 @@ void BuiltinEditorDocumentParser::updateImpl(const QFutureInterface<void> &futur | ||||
|     } | ||||
|  | ||||
|     if (const ProjectPart::Ptr part = baseState.projectPartInfo.projectPart) { | ||||
|         configFile += part->toolchainDefines; | ||||
|         configFile += ProjectExplorer::Macro::toByteArray(part->toolChainMacros); | ||||
|         configFile += overwrittenToolchainDefines(*part.data()); | ||||
|         configFile += part->projectDefines; | ||||
|         configFile += ProjectExplorer::Macro::toByteArray(part->projectMacros); | ||||
|         if (!part->projectConfigFile.isEmpty()) | ||||
|             configFile += ProjectPart::readProjectConfigFile(part); | ||||
|         headerPaths = part->headerPaths; | ||||
|   | ||||
| @@ -48,44 +48,9 @@ void CompilerOptionsBuilder::add(const QString &option) | ||||
|     m_options.append(option); | ||||
| } | ||||
|  | ||||
| struct Macro { | ||||
|     static Macro fromDefineDirective(const QByteArray &defineDirective); | ||||
|     QByteArray toDefineOption(const QByteArray &option) const; | ||||
|  | ||||
|     QByteArray name; | ||||
|     QByteArray value; | ||||
| }; | ||||
|  | ||||
| Macro Macro::fromDefineDirective(const QByteArray &defineDirective) | ||||
| void CompilerOptionsBuilder::addDefine(const ProjectExplorer::Macro ¯o) | ||||
| { | ||||
|     const QByteArray str = defineDirective.mid(8); | ||||
|     const int spaceIdx = str.indexOf(' '); | ||||
|     const bool hasValue = spaceIdx != -1; | ||||
|  | ||||
|     Macro macro; | ||||
|     macro.name = str.left(hasValue ? spaceIdx : str.size()); | ||||
|     if (hasValue) | ||||
|         macro.value = str.mid(spaceIdx + 1); | ||||
|  | ||||
|     return macro; | ||||
| } | ||||
|  | ||||
| QByteArray Macro::toDefineOption(const QByteArray &option) const | ||||
| { | ||||
|     QByteArray result; | ||||
|  | ||||
|     result.append(option); | ||||
|     result.append(name); | ||||
|     result.append('='); | ||||
|     if (!value.isEmpty()) | ||||
|         result.append(value); | ||||
|  | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| void CompilerOptionsBuilder::addDefine(const QByteArray &defineDirective) | ||||
| { | ||||
|     m_options.append(defineDirectiveToDefineOption(defineDirective)); | ||||
|     m_options.append(defineDirectiveToDefineOption(macro)); | ||||
| } | ||||
|  | ||||
| void CompilerOptionsBuilder::addWordWidth() | ||||
| @@ -162,19 +127,19 @@ void CompilerOptionsBuilder::addPrecompiledHeaderOptions(PchUsage pchUsage) | ||||
|  | ||||
| void CompilerOptionsBuilder::addToolchainAndProjectDefines() | ||||
| { | ||||
|     addDefines(m_projectPart.toolchainDefines); | ||||
|     addDefines(m_projectPart.projectDefines); | ||||
|     addMacros(m_projectPart.toolChainMacros); | ||||
|     addMacros(m_projectPart.projectMacros); | ||||
| } | ||||
|  | ||||
| void CompilerOptionsBuilder::addDefines(const QByteArray &defineDirectives) | ||||
| void CompilerOptionsBuilder::addMacros(const ProjectExplorer::Macros ¯os) | ||||
| { | ||||
|     QStringList result; | ||||
|  | ||||
|     foreach (QByteArray def, defineDirectives.split('\n')) { | ||||
|         if (def.isEmpty() || excludeDefineDirective(def)) | ||||
|     for (const ProjectExplorer::Macro ¯o : macros) { | ||||
|         if (excludeDefineDirective(macro)) | ||||
|             continue; | ||||
|  | ||||
|         const QString defineOption = defineDirectiveToDefineOption(def); | ||||
|         const QString defineOption = defineDirectiveToDefineOption(macro); | ||||
|         if (!result.contains(defineOption)) | ||||
|             result.append(defineOption); | ||||
|     } | ||||
| @@ -303,8 +268,8 @@ void CompilerOptionsBuilder::addDefineToAvoidIncludingGccOrMinGwIntrinsics() | ||||
|     const Core::Id type = m_projectPart.toolchainType; | ||||
|     if (type == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID | ||||
|             || type == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID) { | ||||
|         addDefine("#define _X86INTRIN_H_INCLUDED"); | ||||
|         addDefine("#define BOOST_UUID_NO_SIMD"); | ||||
|         addDefine({"_X86INTRIN_H_INCLUDED"}); | ||||
|         addDefine({"BOOST_UUID_NO_SIMD"}); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -315,14 +280,10 @@ static QByteArray toMsCompatibilityVersionFormat(const QByteArray &mscFullVer) | ||||
|          + mscFullVer.mid(2, 2); | ||||
| } | ||||
|  | ||||
| static QByteArray msCompatibilityVersionFromDefines(const QByteArray &defineDirectives) | ||||
| static QByteArray msCompatibilityVersionFromDefines(const ProjectExplorer::Macros ¯os) | ||||
| { | ||||
|     foreach (QByteArray defineDirective, defineDirectives.split('\n')) { | ||||
|         if (defineDirective.isEmpty()) | ||||
|             continue; | ||||
|  | ||||
|         const Macro macro = Macro::fromDefineDirective(defineDirective); | ||||
|         if (macro.name == "_MSC_FULL_VER") | ||||
|     for (const ProjectExplorer::Macro ¯o : macros) { | ||||
|         if (macro.key == "_MSC_FULL_VER") | ||||
|             return toMsCompatibilityVersionFormat(macro.value); | ||||
|     } | ||||
|  | ||||
| @@ -332,8 +293,8 @@ static QByteArray msCompatibilityVersionFromDefines(const QByteArray &defineDire | ||||
| void CompilerOptionsBuilder::addMsvcCompatibilityVersion() | ||||
| { | ||||
|     if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) { | ||||
|         const QByteArray defines = m_projectPart.toolchainDefines + m_projectPart.projectDefines; | ||||
|         const QByteArray msvcVersion = msCompatibilityVersionFromDefines(defines); | ||||
|         const ProjectExplorer::Macros macros = m_projectPart.toolChainMacros + m_projectPart.projectMacros; | ||||
|         const QByteArray msvcVersion = msCompatibilityVersionFromDefines(macros); | ||||
|  | ||||
|         if (!msvcVersion.isEmpty()) { | ||||
|             const QString option = QLatin1String("-fms-compatibility-version=") | ||||
| @@ -398,7 +359,7 @@ void CompilerOptionsBuilder::addDefineFloat128ForMingw() | ||||
|     // CLANG-UPGRADE-CHECK: Workaround still needed? | ||||
|     // https://llvm.org/bugs/show_bug.cgi?id=30685 | ||||
|     if (m_projectPart.toolchainType == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) | ||||
|         addDefine("#define __float128 short"); | ||||
|         addDefine({"__float128", "short", ProjectExplorer::MacroType::Define}); | ||||
| } | ||||
|  | ||||
| QString CompilerOptionsBuilder::includeDirOption() const | ||||
| @@ -406,12 +367,25 @@ QString CompilerOptionsBuilder::includeDirOption() const | ||||
|     return QLatin1String("-I"); | ||||
| } | ||||
|  | ||||
| QString CompilerOptionsBuilder::defineDirectiveToDefineOption(const QByteArray &defineDirective) | ||||
| QByteArray CompilerOptionsBuilder::macroOption(const ProjectExplorer::Macro ¯o) const | ||||
| { | ||||
|     const Macro macro = Macro::fromDefineDirective(defineDirective); | ||||
|     const QByteArray option = macro.toDefineOption(defineOption().toLatin1()); | ||||
|     switch (macro.type) { | ||||
|         case ProjectExplorer::MacroType::Define:     return defineOption().toUtf8(); | ||||
|         case ProjectExplorer::MacroType::Undefine:   return undefineOption().toUtf8(); | ||||
|         default: return QByteArray(); | ||||
|     } | ||||
| } | ||||
|  | ||||
|     return QString::fromLatin1(option); | ||||
| QByteArray CompilerOptionsBuilder::toDefineOption(const ProjectExplorer::Macro ¯o) const | ||||
| { | ||||
|     return macro.toKeyValue(macroOption(macro)); | ||||
| } | ||||
|  | ||||
| QString CompilerOptionsBuilder::defineDirectiveToDefineOption(const ProjectExplorer::Macro ¯o) const | ||||
| { | ||||
|     const QByteArray option = toDefineOption(macro); | ||||
|  | ||||
|     return QString::fromUtf8(option); | ||||
| } | ||||
|  | ||||
| QString CompilerOptionsBuilder::defineOption() const | ||||
| @@ -435,11 +409,11 @@ static bool isGccOrMinGwToolchain(const Core::Id &toolchainType) | ||||
|         || toolchainType == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID; | ||||
| } | ||||
|  | ||||
| bool CompilerOptionsBuilder::excludeDefineDirective(const QByteArray &defineDirective) const | ||||
| bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro ¯o) const | ||||
| { | ||||
|     // This is a quick fix for QTCREATORBUG-11501. | ||||
|     // TODO: do a proper fix, see QTCREATORBUG-11709. | ||||
|     if (defineDirective.startsWith("#define __cplusplus")) | ||||
|     if (macro.key == "__cplusplus") | ||||
|         return true; | ||||
|  | ||||
|     // gcc 4.9 has: | ||||
| @@ -449,7 +423,7 @@ bool CompilerOptionsBuilder::excludeDefineDirective(const QByteArray &defineDire | ||||
|     // override clang's own (non-macro, it seems) definitions of the symbols on the left-hand | ||||
|     // side. | ||||
|     if (isGccOrMinGwToolchain(m_projectPart.toolchainType) | ||||
|             && defineDirective.contains("has_include")) { | ||||
|             && macro.key.contains("has_include")) { | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @@ -459,14 +433,14 @@ bool CompilerOptionsBuilder::excludeDefineDirective(const QByteArray &defineDire | ||||
|     // __builtin_va_arg_pack, which clang does not support (yet), so avoid | ||||
|     // including those. | ||||
|     if (m_projectPart.toolchainType == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID | ||||
|             && defineDirective.startsWith("#define _FORTIFY_SOURCE")) { | ||||
|             && macro.key == "_FORTIFY_SOURCE") { | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     // MinGW 6 supports some fancy asm output flags and uses them in an | ||||
|     // intrinsics header pulled in by windows.h. Clang does not know them. | ||||
|     if (m_projectPart.toolchainType == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID | ||||
|             && defineDirective.startsWith("#define __GCC_ASM_FLAG_OUTPUTS__")) { | ||||
|             && macro.key == "__GCC_ASM_FLAG_OUTPUTS__") { | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -46,7 +46,7 @@ public: | ||||
|  | ||||
|     // Add custom options | ||||
|     void add(const QString &option); | ||||
|     void addDefine(const QByteArray &defineDirective); | ||||
|     void addDefine(const ProjectExplorer::Macro &marco); | ||||
|  | ||||
|     // Add options based on project part | ||||
|     void addWordWidth(); | ||||
| @@ -55,7 +55,7 @@ public: | ||||
|     void addHeaderPathOptions(); | ||||
|     void addPrecompiledHeaderOptions(PchUsage pchUsage); | ||||
|     void addToolchainAndProjectDefines(); | ||||
|     void addDefines(const QByteArray &defineDirectives); | ||||
|     void addMacros(const ProjectExplorer::Macros ¯os); | ||||
|     virtual void addLanguageOption(ProjectFile::Kind fileKind); | ||||
|     virtual void addOptionsForLanguage(bool checkForBorlandExtensions = true); | ||||
|  | ||||
| @@ -67,7 +67,7 @@ public: | ||||
|     void addDefineFloat128ForMingw(); | ||||
|  | ||||
| protected: | ||||
|     virtual bool excludeDefineDirective(const QByteArray &defineDirective) const; | ||||
|     virtual bool excludeDefineDirective(const ProjectExplorer::Macro ¯o) const; | ||||
|     virtual bool excludeHeaderPath(const QString &headerPath) const; | ||||
|  | ||||
|     virtual QString defineOption() const; | ||||
| @@ -78,7 +78,9 @@ protected: | ||||
|     const ProjectPart m_projectPart; | ||||
|  | ||||
| private: | ||||
|     QString defineDirectiveToDefineOption(const QByteArray &defineDirective); | ||||
|     QByteArray macroOption(const ProjectExplorer::Macro ¯o) const; | ||||
|     QByteArray toDefineOption(const ProjectExplorer::Macro ¯o) const; | ||||
|     QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const; | ||||
|  | ||||
|     QStringList m_options; | ||||
| }; | ||||
|   | ||||
| @@ -31,6 +31,7 @@ | ||||
| #include <app/app_version.h> | ||||
| #include <coreplugin/icore.h> | ||||
| #include <cpptools/cppprojectfile.h> | ||||
| #include <projectexplorer/projectmacro.h> | ||||
| #include <projectexplorer/project.h> | ||||
| #include <utils/algorithm.h> | ||||
| #include <utils/temporarydirectory.h> | ||||
| @@ -495,15 +496,17 @@ void Dumper::dumpProjectInfos( const QList<ProjectInfo> &projectInfos) | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (!part->toolchainDefines.isEmpty()) { | ||||
|             if (!part->toolChainMacros.isEmpty()) { | ||||
|                 m_out << i3 << "Toolchain Defines:{{{4\n"; | ||||
|                 const QList<QByteArray> defineLines = part->toolchainDefines.split('\n'); | ||||
|                 const QList<QByteArray> defineLines = | ||||
|                         ProjectExplorer::Macro::toByteArray(part->toolChainMacros).split('\n'); | ||||
|                 foreach (const QByteArray &defineLine, defineLines) | ||||
|                     m_out << i4 << defineLine << "\n"; | ||||
|             } | ||||
|             if (!part->projectDefines.isEmpty()) { | ||||
|             if (!part->projectMacros.isEmpty()) { | ||||
|                 m_out << i3 << "Project Defines:{{{4\n"; | ||||
|                 const QList<QByteArray> defineLines = part->projectDefines.split('\n'); | ||||
|                 const QList<QByteArray> defineLines = | ||||
|                         ProjectExplorer::Macro::toByteArray(part->projectMacros).split('\n'); | ||||
|                 foreach (const QByteArray &defineLine, defineLines) | ||||
|                     m_out << i4 << defineLine << "\n"; | ||||
|             } | ||||
|   | ||||
| @@ -1902,7 +1902,7 @@ void InternalCppCompletionAssistProcessor::addMacros_helper(const Snapshot &snap | ||||
|     foreach (const Document::Include &i, doc->resolvedIncludes()) | ||||
|         addMacros_helper(snapshot, i.resolvedFileName(), processed, definedMacros); | ||||
|  | ||||
|     foreach (const Macro ¯o, doc->definedMacros()) { | ||||
|     foreach (const CPlusPlus::Macro ¯o, doc->definedMacros()) { | ||||
|         const QString macroName = macro.nameToQString(); | ||||
|         if (!macro.isHidden()) | ||||
|             definedMacros->insert(macroName); | ||||
|   | ||||
| @@ -607,13 +607,13 @@ class FindMacroUsesInFile: public std::unary_function<QString, QList<Usage> > | ||||
| { | ||||
|     const WorkingCopy workingCopy; | ||||
|     const Snapshot snapshot; | ||||
|     const Macro ¯o; | ||||
|     const CPlusPlus::Macro ¯o; | ||||
|     QFutureInterface<Usage> *future; | ||||
|  | ||||
| public: | ||||
|     FindMacroUsesInFile(const WorkingCopy &workingCopy, | ||||
|                         const Snapshot snapshot, | ||||
|                         const Macro ¯o, | ||||
|                         const CPlusPlus::Macro ¯o, | ||||
|                         QFutureInterface<Usage> *future) | ||||
|         : workingCopy(workingCopy), snapshot(snapshot), macro(macro), future(future) | ||||
|     { } | ||||
| @@ -632,7 +632,7 @@ restart_search: | ||||
|  | ||||
|         usages.clear(); | ||||
|         foreach (const Document::MacroUse &use, doc->macroUses()) { | ||||
|             const Macro &useMacro = use.macro(); | ||||
|             const CPlusPlus::Macro &useMacro = use.macro(); | ||||
|  | ||||
|             if (useMacro.fileName() == macro.fileName()) { // Check if this is a match, but possibly against an outdated document. | ||||
|                 if (source.isEmpty()) | ||||
| @@ -687,7 +687,7 @@ restart_search: | ||||
| static void findMacroUses_helper(QFutureInterface<Usage> &future, | ||||
|                                  const WorkingCopy workingCopy, | ||||
|                                  const Snapshot snapshot, | ||||
|                                  const Macro macro) | ||||
|                                  const CPlusPlus::Macro macro) | ||||
| { | ||||
|     const Utils::FileName sourceFile = Utils::FileName::fromString(macro.fileName()); | ||||
|     Utils::FileNameList files{sourceFile}; | ||||
| @@ -704,12 +704,13 @@ static void findMacroUses_helper(QFutureInterface<Usage> &future, | ||||
|     future.setProgressValue(files.size()); | ||||
| } | ||||
|  | ||||
| void CppFindReferences::findMacroUses(const Macro ¯o) | ||||
| void CppFindReferences::findMacroUses(const CPlusPlus::Macro ¯o) | ||||
| { | ||||
|     findMacroUses(macro, QString(), false); | ||||
| } | ||||
|  | ||||
| void CppFindReferences::findMacroUses(const Macro ¯o, const QString &replacement, bool replace) | ||||
| void CppFindReferences::findMacroUses(const CPlusPlus::Macro ¯o, const QString &replacement, | ||||
|                                       bool replace) | ||||
| { | ||||
|     SearchResult *search = SearchResultWindow::instance()->startNewSearch( | ||||
|                 tr("C++ Macro Usages:"), | ||||
| @@ -753,7 +754,7 @@ void CppFindReferences::findMacroUses(const Macro ¯o, const QString &replace | ||||
|     connect(progress, &FutureProgress::clicked, search, &SearchResult::popup); | ||||
| } | ||||
|  | ||||
| void CppFindReferences::renameMacroUses(const Macro ¯o, const QString &replacement) | ||||
| void CppFindReferences::renameMacroUses(const CPlusPlus::Macro ¯o, const QString &replacement) | ||||
| { | ||||
|     const QString textToReplace = replacement.isEmpty() ? macro.nameToQString() : replacement; | ||||
|     findMacroUses(macro, textToReplace, true); | ||||
|   | ||||
| @@ -47,6 +47,7 @@ | ||||
| #include <texteditor/textdocument.h> | ||||
| #include <projectexplorer/project.h> | ||||
| #include <projectexplorer/projectexplorer.h> | ||||
| #include <projectexplorer/projectmacro.h> | ||||
| #include <projectexplorer/session.h> | ||||
| #include <extensionsystem/pluginmanager.h> | ||||
| #include <utils/fileutils.h> | ||||
| @@ -138,7 +139,7 @@ public: | ||||
|     bool m_dirty; | ||||
|     QStringList m_projectFiles; | ||||
|     ProjectPartHeaderPaths m_headerPaths; | ||||
|     QByteArray m_definedMacros; | ||||
|     ProjectExplorer::Macros m_definedMacros; | ||||
|  | ||||
|     // Editor integration | ||||
|     mutable QMutex m_cppEditorDocumentsMutex; | ||||
| @@ -446,35 +447,31 @@ ProjectPartHeaderPaths CppModelManager::internalHeaderPaths() const | ||||
|     return headerPaths; | ||||
| } | ||||
|  | ||||
| static void addUnique(const QList<QByteArray> &defs, QByteArray *macros, QSet<QByteArray> *alreadyIn) | ||||
| static void addUnique(const ProjectExplorer::Macros &newMacros, | ||||
|                       ProjectExplorer::Macros ¯os, | ||||
|                       QSet<ProjectExplorer::Macro> &alreadyIn) | ||||
| { | ||||
|     Q_ASSERT(macros); | ||||
|     Q_ASSERT(alreadyIn); | ||||
|  | ||||
|     foreach (const QByteArray &def, defs) { | ||||
|         if (def.trimmed().isEmpty()) | ||||
|             continue; | ||||
|         if (!alreadyIn->contains(def)) { | ||||
|             macros->append(def); | ||||
|             macros->append('\n'); | ||||
|             alreadyIn->insert(def); | ||||
|     for (const ProjectExplorer::Macro ¯o : newMacros) { | ||||
|         if (!alreadyIn.contains(macro)) { | ||||
|             macros += macro; | ||||
|             alreadyIn.insert(macro); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| QByteArray CppModelManager::internalDefinedMacros() const | ||||
| ProjectExplorer::Macros CppModelManager::internalDefinedMacros() const | ||||
| { | ||||
|     QByteArray macros; | ||||
|     QSet<QByteArray> alreadyIn; | ||||
|     ProjectExplorer::Macros macros; | ||||
|     QSet<ProjectExplorer::Macro> alreadyIn; | ||||
|     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(d->m_projectToProjectsInfo); | ||||
|     while (it.hasNext()) { | ||||
|         it.next(); | ||||
|         const ProjectInfo pinfo = it.value(); | ||||
|         foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) { | ||||
|             addUnique(part->toolchainDefines.split('\n'), ¯os, &alreadyIn); | ||||
|             addUnique(part->projectDefines.split('\n'), ¯os, &alreadyIn); | ||||
|         for (const ProjectPart::Ptr &part : pinfo.projectParts()) { | ||||
|             addUnique(part->toolChainMacros, macros, alreadyIn); | ||||
|             addUnique(part->projectMacros, macros, alreadyIn); | ||||
|             if (!part->projectConfigFile.isEmpty()) | ||||
|                 macros += ProjectPart::readProjectConfigFile(part); | ||||
|                 macros += ProjectExplorer::Macro::toMacros(ProjectPart::readProjectConfigFile(part)); | ||||
|         } | ||||
|     } | ||||
|     return macros; | ||||
| @@ -491,7 +488,8 @@ void CppModelManager::dumpModelManagerConfiguration(const QString &logFileId) | ||||
|     dumper.dumpProjectInfos(projectInfos()); | ||||
|     dumper.dumpSnapshot(globalSnapshot, globalSnapshotTitle, /*isGlobalSnapshot=*/ true); | ||||
|     dumper.dumpWorkingCopy(workingCopy()); | ||||
|     dumper.dumpMergedEntities(headerPaths(), definedMacros()); | ||||
|     dumper.dumpMergedEntities(headerPaths(), | ||||
|                               ProjectExplorer:: Macro::toByteArray(definedMacros())); | ||||
| } | ||||
|  | ||||
| QSet<AbstractEditorSupport *> CppModelManager::abstractEditorSupports() const | ||||
| @@ -569,12 +567,12 @@ void CppModelManager::renameUsages(Symbol *symbol, | ||||
|         d->m_findReferences->renameUsages(symbol, context, replacement); | ||||
| } | ||||
|  | ||||
| void CppModelManager::findMacroUsages(const Macro ¯o) | ||||
| void CppModelManager::findMacroUsages(const CPlusPlus::Macro ¯o) | ||||
| { | ||||
|     d->m_findReferences->findMacroUses(macro); | ||||
| } | ||||
|  | ||||
| void CppModelManager::renameMacroUsages(const Macro ¯o, const QString &replacement) | ||||
| void CppModelManager::renameMacroUsages(const CPlusPlus::Macro ¯o, const QString &replacement) | ||||
| { | ||||
|     d->m_findReferences->renameMacroUses(macro, replacement); | ||||
| } | ||||
| @@ -603,7 +601,7 @@ WorkingCopy CppModelManager::buildWorkingCopyList() | ||||
|  | ||||
|     // Add the project configuration file | ||||
|     QByteArray conf = codeModelConfiguration(); | ||||
|     conf += definedMacros(); | ||||
|     conf += ProjectExplorer::Macro::toByteArray(definedMacros()); | ||||
|     workingCopy.insert(configurationFileName(), conf); | ||||
|  | ||||
|     return workingCopy; | ||||
| @@ -991,7 +989,7 @@ ProjectPart::Ptr CppModelManager::fallbackProjectPart() | ||||
| { | ||||
|     ProjectPart::Ptr part(new ProjectPart); | ||||
|  | ||||
|     part->projectDefines = definedMacros(); | ||||
|     part->projectMacros = definedMacros(); | ||||
|     part->headerPaths = headerPaths(); | ||||
|  | ||||
|     // Do not activate ObjectiveCExtensions since this will lead to the | ||||
| @@ -1270,7 +1268,7 @@ void CppModelManager::setHeaderPaths(const ProjectPartHeaderPaths &headerPaths) | ||||
|     d->m_headerPaths = headerPaths; | ||||
| } | ||||
|  | ||||
| QByteArray CppModelManager::definedMacros() | ||||
| ProjectExplorer::Macros CppModelManager::definedMacros() | ||||
| { | ||||
|     QMutexLocker locker(&d->m_projectMutex); | ||||
|     ensureUpdated(); | ||||
|   | ||||
| @@ -163,7 +163,7 @@ public: | ||||
|     // Use this *only* for auto tests | ||||
|     void setHeaderPaths(const ProjectPartHeaderPaths &headerPaths); | ||||
|  | ||||
|     QByteArray definedMacros(); | ||||
|     ProjectExplorer::Macros definedMacros(); | ||||
|  | ||||
|     void enableGarbageCollector(bool enable); | ||||
|  | ||||
| @@ -229,7 +229,7 @@ private: | ||||
|     void ensureUpdated(); | ||||
|     QStringList internalProjectFiles() const; | ||||
|     ProjectPartHeaderPaths internalHeaderPaths() const; | ||||
|     QByteArray internalDefinedMacros() const; | ||||
|     ProjectExplorer::Macros internalDefinedMacros() const; | ||||
|  | ||||
|     void dumpModelManagerConfiguration(const QString &logFileId); | ||||
|  | ||||
|   | ||||
| @@ -187,7 +187,7 @@ void CppToolsPlugin::test_modelmanager_paths_are_clean() | ||||
|  | ||||
|     ProjectPart::Ptr part(new ProjectPart); | ||||
|     part->qtVersion = ProjectPart::Qt5; | ||||
|     part->projectDefines = QByteArray("#define OH_BEHAVE -1\n"); | ||||
|     part->projectMacros = {ProjectExplorer::Macro("OH_BEHAVE", "-1")}; | ||||
|     part->headerPaths = {HeaderPath(testDataDir.includeDir(false), HeaderPath::IncludePath), | ||||
|                          HeaderPath(testDataDir.frameworksDir(false), HeaderPath::FrameworkPath)}; | ||||
|     pi.appendProjectPart(part); | ||||
| @@ -219,7 +219,7 @@ void CppToolsPlugin::test_modelmanager_framework_headers() | ||||
|  | ||||
|     ProjectPart::Ptr part(new ProjectPart); | ||||
|     part->qtVersion = ProjectPart::Qt5; | ||||
|     part->projectDefines = QByteArray("#define OH_BEHAVE -1\n"); | ||||
|     part->projectMacros = {{"OH_BEHAVE", "-1"}}; | ||||
|     part->headerPaths = {HeaderPath(testDataDir.includeDir(false), HeaderPath::IncludePath), | ||||
|                          HeaderPath(testDataDir.frameworksDir(false), HeaderPath::FrameworkPath)}; | ||||
|     const QString &source = testDataDir.fileFromSourcesDir( | ||||
| @@ -268,7 +268,7 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files() | ||||
|  | ||||
|     ProjectPart::Ptr part(new ProjectPart); | ||||
|     part->qtVersion = ProjectPart::Qt5; | ||||
|     part->projectDefines = QByteArray("#define OH_BEHAVE -1\n"); | ||||
|     part->projectMacros = {{"OH_BEHAVE", "-1"}}; | ||||
|     part->headerPaths = {HeaderPath(testDataDir.includeDir(false), HeaderPath::IncludePath)}; | ||||
|     part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); | ||||
|     pi.appendProjectPart(part); | ||||
| @@ -286,7 +286,7 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files() | ||||
|     QVERIFY(macrosInHeaderBefore.first().name() == "test_modelmanager_refresh_h"); | ||||
|  | ||||
|     // Introduce a define that will enable another define once the document is reparsed. | ||||
|     part->projectDefines = QByteArray("#define TEST_DEFINE 1\n"); | ||||
|     part->projectMacros = {{"TEST_DEFINE", "1"}}; | ||||
|     pi = ProjectInfo(project); | ||||
|     pi.appendProjectPart(part); | ||||
|  | ||||
| @@ -334,13 +334,13 @@ void CppToolsPlugin::test_modelmanager_refresh_several_times() | ||||
|     QSet<QString> refreshedFiles; | ||||
|     CPlusPlus::Document::Ptr document; | ||||
|  | ||||
|     QByteArray defines = "#define FIRST_DEFINE"; | ||||
|     ProjectExplorer::Macros macros = {{"FIRST_DEFINE"}}; | ||||
|     for (int i = 0; i < 2; ++i) { | ||||
|         pi = ProjectInfo(project); | ||||
|         ProjectPart::Ptr part(new ProjectPart); | ||||
|         // Simulate project configuration change by having different defines each time. | ||||
|         defines += "\n#define ANOTHER_DEFINE"; | ||||
|         part->projectDefines = defines; | ||||
|         macros += {"ANOTHER_DEFINE"}; | ||||
|         part->projectMacros = macros; | ||||
|         part->qtVersion = ProjectPart::Qt5; | ||||
|         part->files.append(ProjectFile(testHeader1, ProjectFile::CXXHeader)); | ||||
|         part->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader)); | ||||
| @@ -762,7 +762,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_project() | ||||
|     part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource)); | ||||
|     part1->files.append(ProjectFile(header, ProjectFile::CXXHeader)); | ||||
|     part1->qtVersion = ProjectPart::NoQt; | ||||
|     part1->projectDefines = QByteArray("#define SUB1\n"); | ||||
|     part1->projectMacros = {{"SUB1"}}; | ||||
|     part1->headerPaths = {HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath)}; | ||||
|  | ||||
|     ProjectPart::Ptr part2(new ProjectPart); | ||||
| @@ -770,7 +770,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_project() | ||||
|     part2->files.append(ProjectFile(main2File, ProjectFile::CXXSource)); | ||||
|     part2->files.append(ProjectFile(header, ProjectFile::CXXHeader)); | ||||
|     part2->qtVersion = ProjectPart::NoQt; | ||||
|     part2->projectDefines = QByteArray("#define SUB2\n"); | ||||
|     part2->projectMacros = {{"SUB2"}}; | ||||
|     part2->headerPaths = {HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath)}; | ||||
|  | ||||
|     ProjectInfo pi = ProjectInfo(project); | ||||
|   | ||||
| @@ -143,7 +143,7 @@ private: | ||||
|         if (!m_tcInfo.predefinedMacrosRunner) | ||||
|             return; // No compiler set in kit. | ||||
|  | ||||
|         m_projectPart.toolchainDefines = m_tcInfo.predefinedMacrosRunner(m_flags.commandLineFlags); | ||||
|         m_projectPart.toolChainMacros = m_tcInfo.predefinedMacrosRunner(m_flags.commandLineFlags); | ||||
|     } | ||||
|  | ||||
| private: | ||||
| @@ -187,7 +187,7 @@ static ProjectPart::Ptr projectPartFromRawProjectPart(const RawProjectPart &rawP | ||||
|     part->callGroupId = rawProjectPart.callGroupId; | ||||
|     part->buildSystemTarget = rawProjectPart.buildSystemTarget; | ||||
|     part->qtVersion = rawProjectPart.qtVersion; | ||||
|     part->projectDefines = rawProjectPart.projectDefines; | ||||
|     part->projectMacros = rawProjectPart.projectMacros; | ||||
|     part->headerPaths = rawProjectPart.headerPaths; | ||||
|     part->precompiledHeaders = rawProjectPart.precompiledHeaders; | ||||
|     part->selectedForBuilding = rawProjectPart.selectedForBuilding; | ||||
|   | ||||
| @@ -81,9 +81,9 @@ void RawProjectPart::setQtVersion(ProjectPart::QtVersion qtVersion) | ||||
|     this->qtVersion = qtVersion; | ||||
| } | ||||
|  | ||||
| void RawProjectPart::setDefines(const QByteArray &defines) | ||||
| void RawProjectPart::setMacros(const ProjectExplorer::Macros ¯os) | ||||
| { | ||||
|     this->projectDefines = defines; | ||||
|     this->projectMacros = macros; | ||||
| } | ||||
|  | ||||
| void RawProjectPart::setHeaderPaths(const ProjectPartHeaderPaths &headerPaths) | ||||
|   | ||||
| @@ -67,7 +67,7 @@ public: | ||||
|  | ||||
|     void setQtVersion(ProjectPart::QtVersion qtVersion); | ||||
|  | ||||
|     void setDefines(const QByteArray &defines); | ||||
|     void setMacros(const ProjectExplorer::Macros ¯os); | ||||
|     void setHeaderPaths(const ProjectPartHeaderPaths &headerPaths); | ||||
|     void setIncludePaths(const QStringList &includePaths); | ||||
|  | ||||
| @@ -88,7 +88,7 @@ public: | ||||
|     QString buildSystemTarget; | ||||
|     QStringList precompiledHeaders; | ||||
|     ProjectPartHeaderPaths headerPaths; | ||||
|     QByteArray projectDefines; | ||||
|     ProjectExplorer::Macros projectMacros; | ||||
|     ProjectPart::QtVersion qtVersion = ProjectPart::UnknownQt; | ||||
|     bool selectedForBuilding = true; | ||||
|  | ||||
|   | ||||
| @@ -62,11 +62,12 @@ static Q_LOGGING_CATEGORY(log, "qtc.cpptools.sourceprocessor") | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| inline QByteArray generateFingerPrint(const QList<Macro> &definedMacros, const QByteArray &code) | ||||
| inline QByteArray generateFingerPrint(const QList<CPlusPlus::Macro> &definedMacros, | ||||
|                                       const QByteArray &code) | ||||
| { | ||||
|     QCryptographicHash hash(QCryptographicHash::Sha1); | ||||
|     hash.addData(code); | ||||
|     foreach (const Macro ¯o, definedMacros) { | ||||
|     foreach (const CPlusPlus::Macro ¯o, definedMacros) { | ||||
|         if (macro.isHidden()) { | ||||
|             static const QByteArray undef("#undef "); | ||||
|             hash.addData(undef); | ||||
| @@ -98,10 +99,10 @@ inline Message messageNoFileContents(Document::Ptr &document, const QString &fil | ||||
|     return Message(Message::Warning, document->fileName(), line, /*column =*/ 0, text); | ||||
| } | ||||
|  | ||||
| inline const Macro revision(const WorkingCopy &workingCopy, | ||||
|                             const Macro ¯o) | ||||
| inline const CPlusPlus::Macro revision(const WorkingCopy &workingCopy, | ||||
|                                        const CPlusPlus::Macro ¯o) | ||||
| { | ||||
|     Macro newMacro(macro); | ||||
|     CPlusPlus::Macro newMacro(macro); | ||||
|     newMacro.setFileRevision(workingCopy.get(macro.fileName()).second); | ||||
|     return newMacro; | ||||
| } | ||||
| @@ -316,7 +317,7 @@ QString CppSourceProcessor::resolveFile_helper(const QString &fileName, | ||||
|     return QString(); | ||||
| } | ||||
|  | ||||
| void CppSourceProcessor::macroAdded(const Macro ¯o) | ||||
| void CppSourceProcessor::macroAdded(const CPlusPlus::Macro ¯o) | ||||
| { | ||||
|     if (!m_currentDoc) | ||||
|         return; | ||||
| @@ -325,7 +326,7 @@ void CppSourceProcessor::macroAdded(const Macro ¯o) | ||||
| } | ||||
|  | ||||
| void CppSourceProcessor::passedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset, | ||||
|                                                     unsigned line, const Macro ¯o) | ||||
|                                                     unsigned line, const CPlusPlus::Macro ¯o) | ||||
| { | ||||
|     if (!m_currentDoc) | ||||
|         return; | ||||
| @@ -347,7 +348,7 @@ void CppSourceProcessor::failedMacroDefinitionCheck(unsigned bytesOffset, unsign | ||||
| } | ||||
|  | ||||
| void CppSourceProcessor::notifyMacroReference(unsigned bytesOffset, unsigned utf16charOffset, | ||||
|                                               unsigned line, const Macro ¯o) | ||||
|                                               unsigned line, const CPlusPlus::Macro ¯o) | ||||
| { | ||||
|     if (!m_currentDoc) | ||||
|         return; | ||||
| @@ -359,7 +360,7 @@ void CppSourceProcessor::notifyMacroReference(unsigned bytesOffset, unsigned utf | ||||
| } | ||||
|  | ||||
| void CppSourceProcessor::startExpandingMacro(unsigned bytesOffset, unsigned utf16charOffset, | ||||
|                                              unsigned line, const Macro ¯o, | ||||
|                                              unsigned line, const CPlusPlus::Macro ¯o, | ||||
|                                              const QVector<MacroArgumentReference> &actuals) | ||||
| { | ||||
|     if (!m_currentDoc) | ||||
| @@ -371,7 +372,7 @@ void CppSourceProcessor::startExpandingMacro(unsigned bytesOffset, unsigned utf1 | ||||
|                               line, actuals); | ||||
| } | ||||
|  | ||||
| void CppSourceProcessor::stopExpandingMacro(unsigned, const Macro &) | ||||
| void CppSourceProcessor::stopExpandingMacro(unsigned, const CPlusPlus::Macro &) | ||||
| { | ||||
|     if (!m_currentDoc) | ||||
|         return; | ||||
|   | ||||
| @@ -1,11 +1,7 @@ | ||||
| # Currently there are no tests for the project explorer plugin, but we include | ||||
| # headers from it that needs to have the export/import adapted for Windows. | ||||
| shared { | ||||
|     DEFINES += CPPTOOLS_LIBRARY | ||||
|     DEFINES += PROJECTEXPLORER_LIBRARY | ||||
| } else { | ||||
|     DEFINES += CPPTOOLS_STATIC_LIBRARY | ||||
|     DEFINES += PROJECTEXPLORER_STATIC_LIBRARY | ||||
| } | ||||
|  | ||||
| HEADERS += \ | ||||
|   | ||||
| @@ -160,13 +160,10 @@ void ProjectInfo::finish() | ||||
|             m_sourceFiles.insert(file.path); | ||||
|  | ||||
|         // Update defines | ||||
|         m_defines.append(part->toolchainDefines); | ||||
|         m_defines.append(part->projectDefines); | ||||
|         if (!part->projectConfigFile.isEmpty()) { | ||||
|             m_defines.append('\n'); | ||||
|             m_defines += ProjectPart::readProjectConfigFile(part); | ||||
|             m_defines.append('\n'); | ||||
|         } | ||||
|         m_defines.append(part->toolChainMacros); | ||||
|         m_defines.append(part->projectMacros); | ||||
|         if (!part->projectConfigFile.isEmpty()) | ||||
|             m_defines += ProjectExplorer::Macro::toMacros(ProjectPart::readProjectConfigFile(part)); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -123,7 +123,7 @@ private: | ||||
|     // The members below are (re)calculated from the project parts with finish() | ||||
|     ProjectPartHeaderPaths m_headerPaths; | ||||
|     QSet<QString> m_sourceFiles; | ||||
|     QByteArray m_defines; | ||||
|     ProjectExplorer::Macros m_defines; | ||||
| }; | ||||
|  | ||||
| } // namespace CppTools | ||||
|   | ||||
| @@ -25,6 +25,8 @@ | ||||
|  | ||||
| #include "projectpart.h" | ||||
|  | ||||
| #include <utils/algorithm.h> | ||||
|  | ||||
| #include <QFile> | ||||
| #include <QDir> | ||||
| #include <QTextStream> | ||||
| @@ -43,16 +45,9 @@ void ProjectPart::updateLanguageFeatures() | ||||
|     if (!hasQt) { | ||||
|         languageFeatures.qtKeywordsEnabled = false; | ||||
|     } else { | ||||
|         const QByteArray noKeywordsMacro = "#define QT_NO_KEYWORDS"; | ||||
|         const int noKeywordsIndex = projectDefines.indexOf(noKeywordsMacro); | ||||
|         if (noKeywordsIndex == -1) { | ||||
|             languageFeatures.qtKeywordsEnabled = true; | ||||
|         } else { | ||||
|             const char nextChar = projectDefines.at(noKeywordsIndex + noKeywordsMacro.length()); | ||||
|             // Detect "#define QT_NO_KEYWORDS" and "#define QT_NO_KEYWORDS 1", but exclude | ||||
|             // "#define QT_NO_KEYWORDS_FOO" | ||||
|             languageFeatures.qtKeywordsEnabled = nextChar != '\n' && nextChar != ' '; | ||||
|         } | ||||
|         languageFeatures.qtKeywordsEnabled = !Utils::contains( | ||||
|                     projectMacros, | ||||
|                     [] (const ProjectExplorer::Macro ¯o) { return macro.key == "QT_NO_KEYWORDS"; }); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -31,6 +31,7 @@ | ||||
| #include "projectpartheaderpath.h" | ||||
|  | ||||
| #include <projectexplorer/projectexplorer_global.h> | ||||
| #include <projectexplorer/projectmacro.h> | ||||
|  | ||||
| #include <coreplugin/id.h> | ||||
|  | ||||
| @@ -118,7 +119,7 @@ public: | ||||
|     QStringList precompiledHeaders; | ||||
|     ProjectPartHeaderPaths headerPaths; | ||||
|  | ||||
|     QByteArray projectDefines; | ||||
|     ProjectExplorer::Macros projectMacros; | ||||
|  | ||||
|     LanguageVersion languageVersion = LatestCxxVersion; | ||||
|     LanguageExtensions languageExtensions = NoExtensions; | ||||
| @@ -130,7 +131,7 @@ public: | ||||
|  | ||||
|     Core::Id toolchainType; | ||||
|     bool isMsvc2015Toolchain = false; | ||||
|     QByteArray toolchainDefines; | ||||
|     ProjectExplorer::Macros toolChainMacros; | ||||
|     ToolChainWordWidth toolChainWordWidth = WordWidth32Bit; | ||||
|     QString toolChainTargetTriple; | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user