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:
Marco Bubke
2017-02-07 15:00:38 +01:00
parent 3adb71d45e
commit b6e12f4a1c
60 changed files with 1144 additions and 420 deletions

View File

@@ -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;

View File

@@ -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 &macro)
{
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 &macros)
{
QStringList result;
foreach (QByteArray def, defineDirectives.split('\n')) {
if (def.isEmpty() || excludeDefineDirective(def))
for (const ProjectExplorer::Macro &macro : 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 &macros)
{
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 &macro : 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 &macro) 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 &macro) const
{
return macro.toKeyValue(macroOption(macro));
}
QString CompilerOptionsBuilder::defineDirectiveToDefineOption(const ProjectExplorer::Macro &macro) 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 &macro) 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;
}

View File

@@ -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 &macros);
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 &macro) 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 &macro) const;
QByteArray toDefineOption(const ProjectExplorer::Macro &macro) const;
QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const;
QStringList m_options;
};

View File

@@ -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";
}

View File

@@ -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 &macro, doc->definedMacros()) {
foreach (const CPlusPlus::Macro &macro, doc->definedMacros()) {
const QString macroName = macro.nameToQString();
if (!macro.isHidden())
definedMacros->insert(macroName);

View File

@@ -607,13 +607,13 @@ class FindMacroUsesInFile: public std::unary_function<QString, QList<Usage> >
{
const WorkingCopy workingCopy;
const Snapshot snapshot;
const Macro &macro;
const CPlusPlus::Macro &macro;
QFutureInterface<Usage> *future;
public:
FindMacroUsesInFile(const WorkingCopy &workingCopy,
const Snapshot snapshot,
const Macro &macro,
const CPlusPlus::Macro &macro,
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 &macro)
void CppFindReferences::findMacroUses(const CPlusPlus::Macro &macro)
{
findMacroUses(macro, QString(), false);
}
void CppFindReferences::findMacroUses(const Macro &macro, const QString &replacement, bool replace)
void CppFindReferences::findMacroUses(const CPlusPlus::Macro &macro, const QString &replacement,
bool replace)
{
SearchResult *search = SearchResultWindow::instance()->startNewSearch(
tr("C++ Macro Usages:"),
@@ -753,7 +754,7 @@ void CppFindReferences::findMacroUses(const Macro &macro, const QString &replace
connect(progress, &FutureProgress::clicked, search, &SearchResult::popup);
}
void CppFindReferences::renameMacroUses(const Macro &macro, const QString &replacement)
void CppFindReferences::renameMacroUses(const CPlusPlus::Macro &macro, const QString &replacement)
{
const QString textToReplace = replacement.isEmpty() ? macro.nameToQString() : replacement;
findMacroUses(macro, textToReplace, true);

View File

@@ -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 &macros,
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 &macro : 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'), &macros, &alreadyIn);
addUnique(part->projectDefines.split('\n'), &macros, &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 &macro)
void CppModelManager::findMacroUsages(const CPlusPlus::Macro &macro)
{
d->m_findReferences->findMacroUses(macro);
}
void CppModelManager::renameMacroUsages(const Macro &macro, const QString &replacement)
void CppModelManager::renameMacroUsages(const CPlusPlus::Macro &macro, 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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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 &macros)
{
this->projectDefines = defines;
this->projectMacros = macros;
}
void RawProjectPart::setHeaderPaths(const ProjectPartHeaderPaths &headerPaths)

View File

@@ -67,7 +67,7 @@ public:
void setQtVersion(ProjectPart::QtVersion qtVersion);
void setDefines(const QByteArray &defines);
void setMacros(const ProjectExplorer::Macros &macros);
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;

View File

@@ -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 &macro, definedMacros) {
foreach (const CPlusPlus::Macro &macro, 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 &macro)
inline const CPlusPlus::Macro revision(const WorkingCopy &workingCopy,
const CPlusPlus::Macro &macro)
{
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 &macro)
void CppSourceProcessor::macroAdded(const CPlusPlus::Macro &macro)
{
if (!m_currentDoc)
return;
@@ -325,7 +326,7 @@ void CppSourceProcessor::macroAdded(const Macro &macro)
}
void CppSourceProcessor::passedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset,
unsigned line, const Macro &macro)
unsigned line, const CPlusPlus::Macro &macro)
{
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 &macro)
unsigned line, const CPlusPlus::Macro &macro)
{
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 &macro,
unsigned line, const CPlusPlus::Macro &macro,
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;

View File

@@ -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 += \

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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 &macro) { return macro.key == "QT_NO_KEYWORDS"; });
}
}

View File

@@ -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;
};