From 0c38e3aea7bd0603cb8954b98c0c51fdacb4fdfc Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 30 Nov 2018 10:34:05 +0100 Subject: [PATCH] Clang: Clean up CompilerOptionsBuilder No behavior change. * Remove virtual from methods that are not overridden * Move constant member functions that do no access any members into source file as static functions * Remove QLatin1String where possible * Make variable names a bit more consistent * Other minor stuff Change-Id: I34a582d5a468489e11365507b283e9aee157664f Reviewed-by: Marco Bubke Reviewed-by: Ivan Donchevskii --- .../clangeditordocumentprocessor.cpp | 4 +- src/plugins/clangcodemodel/clangutils.cpp | 9 +- .../clangpchmanager/projectupdater.cpp | 2 +- .../clangqueryprojectsfindfilter.cpp | 3 +- .../clangtools/clangtoolruncontrol.cpp | 4 +- .../cpptools/compileroptionsbuilder.cpp | 385 +++++++++--------- src/plugins/cpptools/compileroptionsbuilder.h | 76 ++-- src/plugins/cpptools/cpptoolsreuse.cpp | 6 +- src/plugins/cpptools/cpptoolsreuse.h | 2 +- tests/unit/mockup/cpptools/cpptoolsreuse.h | 2 +- .../unittest/compileroptionsbuilder-test.cpp | 6 +- .../unit/unittest/refactoringengine-test.cpp | 5 +- 12 files changed, 228 insertions(+), 276 deletions(-) diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 0738aa8e70d..9ec7e79fbb7 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -568,14 +568,14 @@ private: { using namespace CppTools; - if (getPchUsage() == CompilerOptionsBuilder::PchUsage::None) + if (getPchUsage() == UsePrecompiledHeaders::No) return; if (m_projectPart.precompiledHeaders.contains(m_filePath)) return; CompilerOptionsBuilder builder(m_projectPart); - builder.addPrecompiledHeaderOptions(CompilerOptionsBuilder::PchUsage::Use); + builder.addPrecompiledHeaderOptions(UsePrecompiledHeaders::Yes); m_options.append(builder.options()); } diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index 9ae6ea7d595..e58fc0bf790 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -69,8 +69,8 @@ public: LibClangOptionsBuilder(const ProjectPart &projectPart) : CompilerOptionsBuilder(projectPart, UseSystemHeader::No, - CppTools::SkipBuiltIn::No, - CppTools::SkipLanguageDefines::Yes, + SkipBuiltIn::No, + SkipLanguageDefines::Yes, QString(CLANG_VERSION), QString(CLANG_RESOURCE_DIR)) { @@ -105,8 +105,7 @@ private: QStringList createClangOptions(const ProjectPart &projectPart, ProjectFile::Kind fileKind) { - return LibClangOptionsBuilder(projectPart) - .build(fileKind, CompilerOptionsBuilder::PchUsage::None); + return LibClangOptionsBuilder(projectPart).build(fileKind, UsePrecompiledHeaders::No); } ProjectPart::Ptr projectPartForFile(const QString &filePath) @@ -341,7 +340,7 @@ void generateCompilationDB(::Utils::FileName projectDir, CppTools::ProjectInfo p CppTools::UseSystemHeader::No, CppTools::SkipBuiltIn::Yes); optionsBuilder.build(CppTools::ProjectFile::Unclassified, - CppTools::CompilerOptionsBuilder::PchUsage::None); + CppTools::UsePrecompiledHeaders::No); for (const ProjectFile &projFile : projectPart->files) { const QJsonObject json = createFileObject(optionsBuilder, projFile, buildDir); diff --git a/src/plugins/clangpchmanager/projectupdater.cpp b/src/plugins/clangpchmanager/projectupdater.cpp index 79290598507..a2c97c9d14c 100644 --- a/src/plugins/clangpchmanager/projectupdater.cpp +++ b/src/plugins/clangpchmanager/projectupdater.cpp @@ -151,7 +151,7 @@ QStringList ProjectUpdater::compilerArguments(CppTools::ProjectPart *projectPart { using CppTools::CompilerOptionsBuilder; CompilerOptionsBuilder builder(*projectPart, CppTools::UseSystemHeader::Yes); - return builder.build(CppTools::ProjectFile::CXXHeader, CompilerOptionsBuilder::PchUsage::None); + return builder.build(CppTools::ProjectFile::CXXHeader, CppTools::UsePrecompiledHeaders::No); } ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(const ProjectExplorer::Macros &projectMacros) diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp index 77d4a9ef6e2..46a18376dd1 100644 --- a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp +++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp @@ -155,8 +155,7 @@ Utils::SmallStringVector ClangQueryProjectsFindFilter::compilerArguments(CppTool CompilerOptionsBuilder builder(*projectPart, CppTools::UseSystemHeader::Yes); - return Utils::SmallStringVector(builder.build(fileKind, - CompilerOptionsBuilder::PchUsage::None)); + return Utils::SmallStringVector(builder.build(fileKind, CppTools::UsePrecompiledHeaders::No)); } QWidget *ClangQueryProjectsFindFilter::widget() const diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp index d73ab10cc4c..fe5499128e3 100644 --- a/src/plugins/clangtools/clangtoolruncontrol.cpp +++ b/src/plugins/clangtools/clangtoolruncontrol.cpp @@ -189,7 +189,7 @@ private: static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos) { AnalyzeUnits unitsToAnalyze; - const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage(); + const UsePrecompiledHeaders usePrecompiledHeaders = CppTools::getPchUsage(); for (const FileInfo &fileInfo : fileInfos) { CompilerOptionsBuilder optionsBuilder(*fileInfo.projectPart, CppTools::UseSystemHeader::No, @@ -198,7 +198,7 @@ static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos) QString(CLANG_VERSION), QString(CLANG_RESOURCE_DIR)); QStringList arguments = extraClangToolsPrependOptions(); - arguments.append(optionsBuilder.build(fileInfo.kind, pchUsage)); + arguments.append(optionsBuilder.build(fileInfo.kind, usePrecompiledHeaders)); arguments.append(extraClangToolsAppendOptions()); unitsToAnalyze << AnalyzeUnit(fileInfo.file.toString(), arguments); } diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index 085e6fe132c..5ee8937a6bc 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -28,10 +28,12 @@ #include "cppmodelmanager.h" #include -#include -#include +#include +#include #include +#include +#include #include #include @@ -41,22 +43,51 @@ namespace CppTools { +static const char defineOption[] = "-D"; +static const char undefineOption[] = "-U"; + +static const char includeUserPathOption[] = "-I"; +static const char includeSystemPathOption[] = "-isystem"; + +static const char includeFileOption[] = "-include"; + +static QByteArray macroOption(const ProjectExplorer::Macro ¯o) +{ + switch (macro.type) { + case ProjectExplorer::MacroType::Define: return defineOption; + case ProjectExplorer::MacroType::Undefine: return undefineOption; + default: return QByteArray(); + } +} + +static QByteArray toDefineOption(const ProjectExplorer::Macro ¯o) +{ + return macro.toKeyValue(macroOption(macro)); +} + +static QString defineDirectiveToDefineOption(const ProjectExplorer::Macro ¯o) +{ + const QByteArray option = toDefineOption(macro); + return QString::fromUtf8(option); +} + CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart, UseSystemHeader useSystemHeader, SkipBuiltIn skipBuiltInHeaderPathsAndDefines, SkipLanguageDefines skipLanguageDefines, - QString clangVersion, - QString clangResourceDirectory) + const QString &clangVersion, + const QString &clangResourceDirectory) : m_projectPart(projectPart) - , m_clangVersion(clangVersion) - , m_clangResourceDirectory(clangResourceDirectory) , m_useSystemHeader(useSystemHeader) , m_skipBuiltInHeaderPathsAndDefines(skipBuiltInHeaderPathsAndDefines) , m_skipLanguageDefines(skipLanguageDefines) + , m_clangVersion(clangVersion) + , m_clangResourceDirectory(clangResourceDirectory) { } -QStringList CompilerOptionsBuilder::build(CppTools::ProjectFile::Kind fileKind, PchUsage pchUsage) +QStringList CompilerOptionsBuilder::build(ProjectFile::Kind fileKind, + UsePrecompiledHeaders usePrecompiledHeaders) { m_options.clear(); @@ -87,7 +118,7 @@ QStringList CompilerOptionsBuilder::build(CppTools::ProjectFile::Kind fileKind, addBoostWorkaroundMacros(); addToolchainFlags(); - addPrecompiledHeaderOptions(pchUsage); + addPrecompiledHeaderOptions(usePrecompiledHeaders); addHeaderPathOptions(); addProjectConfigFileInclude(); @@ -102,7 +133,7 @@ QStringList CompilerOptionsBuilder::build(CppTools::ProjectFile::Kind fileKind, static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt) { - QStringList opts; + QStringList options; switch (fileKind) { case ProjectFile::Unclassified: @@ -110,80 +141,67 @@ static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objc break; case ProjectFile::CHeader: if (objcExt) - opts += QLatin1String("objective-c-header"); + options += "objective-c-header"; else - opts += QLatin1String("c-header"); + options += "c-header"; break; - case ProjectFile::CXXHeader: default: if (!objcExt) { - opts += QLatin1String("c++-header"); + options += "c++-header"; break; } Q_FALLTHROUGH(); case ProjectFile::ObjCHeader: case ProjectFile::ObjCXXHeader: - opts += QLatin1String("objective-c++-header"); + options += "objective-c++-header"; break; case ProjectFile::CSource: if (!objcExt) { - opts += QLatin1String("c"); + options += "c"; break; } Q_FALLTHROUGH(); case ProjectFile::ObjCSource: - opts += QLatin1String("objective-c"); + options += "objective-c"; break; - case ProjectFile::CXXSource: if (!objcExt) { - opts += QLatin1String("c++"); + options += "c++"; break; } Q_FALLTHROUGH(); case ProjectFile::ObjCXXSource: - opts += QLatin1String("objective-c++"); + options += "objective-c++"; break; - case ProjectFile::OpenCLSource: - opts += QLatin1String("cl"); + options += "cl"; break; case ProjectFile::CudaSource: - opts += QLatin1String("cuda"); + options += "cuda"; break; } - if (!opts.isEmpty()) - opts.prepend(QLatin1String("-x")); + if (!options.isEmpty()) + options.prepend("-x"); - return opts; -} - -QStringList CompilerOptionsBuilder::options() const -{ - return m_options; -} - -void CompilerOptionsBuilder::add(const QString &option) -{ - m_options.append(option); + return options; } void CompilerOptionsBuilder::addWordWidth() { const QString argument = m_projectPart.toolChainWordWidth == ProjectPart::WordWidth64Bit - ? QLatin1String("-m64") - : QLatin1String("-m32"); + ? "-m64" + : "-m32"; add(argument); } void CompilerOptionsBuilder::addTargetTriple() { if (!m_projectPart.toolChainTargetTriple.isEmpty()) { - m_options.append(QLatin1String("-target")); - m_options.append(m_projectPart.toolChainTargetTriple); + add("-target"); + add(m_projectPart.toolChainTargetTriple); } } @@ -198,8 +216,8 @@ void CompilerOptionsBuilder::addExtraCodeModelFlags() void CompilerOptionsBuilder::enableExceptions() { if (m_projectPart.languageVersion > ProjectExplorer::LanguageVersion::LatestC) - add(QLatin1String("-fcxx-exceptions")); - add(QLatin1String("-fexceptions")); + add("-fcxx-exceptions"); + add("-fexceptions"); } static QString creatorResourcePath() @@ -217,6 +235,8 @@ static QString clangIncludeDirectory(const QString &clangVersion, #ifndef UNIT_TESTS return Core::ICore::clangIncludeDirectory(clangVersion, clangResourceDirectory); #else + Q_UNUSED(clangVersion); + Q_UNUSED(clangResourceDirectory); return QDir::toNativeSeparators(QString::fromUtf8(CLANG_RESOURCE_DIR "")); #endif } @@ -225,8 +245,10 @@ static int lastIncludeIndex(const QStringList &options, const QRegularExpression { int index = options.lastIndexOf(includePathRegEx); - while (index > 0 && options[index - 1] != "-I" && options[index - 1] != "-isystem") + while (index > 0 && options[index - 1] != includeUserPathOption + && options[index - 1] != includeSystemPathOption) { index = options.lastIndexOf(includePathRegEx, index - 1); + } if (index == 0) index = -1; @@ -246,9 +268,8 @@ static int includeIndexForResourceDirectory(const QStringList &options, bool isM static const QRegularExpression includeRegExpMac( "\\A(" + cppIncludes + R"(|([\/\\]usr[\/\\]local[\/\\]include))" + ")\\z"); - const int cppIncludeIndex = lastIncludeIndex(options, isMacOs - ? includeRegExpMac - : includeRegExp); + const int cppIncludeIndex = lastIncludeIndex(options, + isMacOs ? includeRegExpMac : includeRegExp); if (cppIncludeIndex > 0) return cppIncludeIndex + 1; @@ -271,6 +292,17 @@ void CompilerOptionsBuilder::insertWrappedQtHeaders() m_options = m_options.mid(0, index) + wrappedQtHeaders + m_options.mid(index); } +static bool excludeHeaderPath(const QString &headerPath) +{ + // Always exclude clang system includes (including intrinsics) which do not come with libclang + // that Qt Creator uses for code model. + // For example GCC on macOS uses system clang include path which makes clang code model + // include incorrect system headers. + static const QRegularExpression clangIncludeDir( + R"(\A.*[\/\\]lib\d*[\/\\]clang[\/\\]\d+\.\d+(\.\d+)?[\/\\]include\z)"); + return clangIncludeDir.match(headerPath).hasMatch(); +} + void CompilerOptionsBuilder::addHeaderPathOptions() { using ProjectExplorer::HeaderPathType; @@ -291,20 +323,18 @@ void CompilerOptionsBuilder::addHeaderPathOptions() includes.append("-F"); includes.append(QDir::toNativeSeparators(headerPath.path)); break; - default: // This shouldn't happen, but let's be nice..: - // intentional fall-through: case HeaderPathType::User: includes.append(includeDirOptionForPath(headerPath.path)); includes.append(QDir::toNativeSeparators(headerPath.path)); break; case HeaderPathType::BuiltIn: - builtInIncludes.append("-isystem"); + builtInIncludes.append(includeSystemPathOption); builtInIncludes.append(QDir::toNativeSeparators(headerPath.path)); break; case HeaderPathType::System: - systemIncludes.append(m_useSystemHeader == UseSystemHeader::No - ? QLatin1String("-I") - : QLatin1String("-isystem")); + systemIncludes.append(m_useSystemHeader == UseSystemHeader::Yes + ? QLatin1String(includeSystemPathOption) + : QLatin1String(includeUserPathOption)); systemIncludes.append(QDir::toNativeSeparators(headerPath.path)); break; } @@ -323,39 +353,40 @@ void CompilerOptionsBuilder::addHeaderPathOptions() // Exclude all built-in includes and Clang resource directory. m_options.prepend("-nostdinc"); - const QString clangIncludePath - = clangIncludeDirectory(m_clangVersion, m_clangResourceDirectory); - int includeIndexForResourceDir = includeIndexForResourceDirectory( - builtInIncludes, m_projectPart.toolChainTargetTriple.contains("darwin")); + const QString clangIncludePath = clangIncludeDirectory(m_clangVersion, + m_clangResourceDirectory); + const int includeIndexForResourceDir + = includeIndexForResourceDirectory(builtInIncludes, + m_projectPart.toolChainTargetTriple.contains( + "darwin")); if (includeIndexForResourceDir >= 0) { builtInIncludes.insert(includeIndexForResourceDir, clangIncludePath); - builtInIncludes.insert(includeIndexForResourceDir, "-isystem"); + builtInIncludes.insert(includeIndexForResourceDir, includeSystemPathOption); } else { builtInIncludes.prepend(clangIncludePath); - builtInIncludes.prepend("-isystem"); + builtInIncludes.prepend(includeSystemPathOption); } } m_options.append(builtInIncludes); } -void CompilerOptionsBuilder::addPrecompiledHeaderOptions(PchUsage pchUsage) +void CompilerOptionsBuilder::addPrecompiledHeaderOptions(UsePrecompiledHeaders usePrecompiledHeaders) { - if (pchUsage == PchUsage::None) + if (usePrecompiledHeaders == UsePrecompiledHeaders::No) return; - QStringList result; + QStringList options; - const QString includeOptionString = includeOption(); - foreach (const QString &pchFile, m_projectPart.precompiledHeaders) { + for (const QString &pchFile : m_projectPart.precompiledHeaders) { if (QFile::exists(pchFile)) { - result += includeOptionString; - result += QDir::toNativeSeparators(pchFile); + options += includeFileOption; + options += QDir::toNativeSeparators(pchFile); } } - m_options.append(result); + m_options.append(options); } void CompilerOptionsBuilder::addToolchainAndProjectMacros() @@ -367,18 +398,18 @@ void CompilerOptionsBuilder::addToolchainAndProjectMacros() void CompilerOptionsBuilder::addMacros(const ProjectExplorer::Macros ¯os) { - QStringList result; + QStringList options; for (const ProjectExplorer::Macro ¯o : macros) { if (excludeDefineDirective(macro)) continue; const QString defineOption = defineDirectiveToDefineOption(macro); - if (!result.contains(defineOption)) - result.append(defineOption); + if (!options.contains(defineOption)) + options.append(defineOption); } - m_options.append(result); + m_options.append(options); } void CompilerOptionsBuilder::updateLanguageOption(ProjectFile::Kind fileKind) @@ -391,11 +422,10 @@ void CompilerOptionsBuilder::updateLanguageOption(ProjectFile::Kind fileKind) QTC_ASSERT(options.size() == 2, return;); int langOptIndex = m_options.indexOf("-x"); - if (langOptIndex == -1) { + if (langOptIndex == -1) m_options.append(options); - } else { + else m_options[langOptIndex + 1] = options[1]; - } } void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtensions) @@ -403,54 +433,54 @@ void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtension using ProjectExplorer::LanguageExtension; using ProjectExplorer::LanguageVersion; - QStringList opts; + QStringList options; const ProjectExplorer::LanguageExtensions languageExtensions = m_projectPart.languageExtensions; const bool gnuExtensions = languageExtensions & LanguageExtension::Gnu; switch (m_projectPart.languageVersion) { case LanguageVersion::C89: - opts << (gnuExtensions ? QLatin1String("-std=gnu89") : QLatin1String("-std=c89")); + options << (gnuExtensions ? QLatin1String("-std=gnu89") : QLatin1String("-std=c89")); break; case LanguageVersion::C99: - opts << (gnuExtensions ? QLatin1String("-std=gnu99") : QLatin1String("-std=c99")); + options << (gnuExtensions ? QLatin1String("-std=gnu99") : QLatin1String("-std=c99")); break; case LanguageVersion::C11: - opts << (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11")); + options << (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11")); break; case LanguageVersion::C18: // Clang 6, 7 and current trunk do not accept "gnu18"/"c18", so use the "*17" variants. - opts << (gnuExtensions ? QLatin1String("-std=gnu17") : QLatin1String("-std=c17")); + options << (gnuExtensions ? QLatin1String("-std=gnu17") : QLatin1String("-std=c17")); break; case LanguageVersion::CXX11: - opts << (gnuExtensions ? QLatin1String("-std=gnu++11") : QLatin1String("-std=c++11")); + options << (gnuExtensions ? QLatin1String("-std=gnu++11") : QLatin1String("-std=c++11")); break; case LanguageVersion::CXX98: - opts << (gnuExtensions ? QLatin1String("-std=gnu++98") : QLatin1String("-std=c++98")); + options << (gnuExtensions ? QLatin1String("-std=gnu++98") : QLatin1String("-std=c++98")); break; case LanguageVersion::CXX03: - opts << (gnuExtensions ? QLatin1String("-std=gnu++03") : QLatin1String("-std=c++03")); + options << (gnuExtensions ? QLatin1String("-std=gnu++03") : QLatin1String("-std=c++03")); break; case LanguageVersion::CXX14: - opts << (gnuExtensions ? QLatin1String("-std=gnu++14") : QLatin1String("-std=c++14")); + options << (gnuExtensions ? QLatin1String("-std=gnu++14") : QLatin1String("-std=c++14")); break; case LanguageVersion::CXX17: - opts << (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17")); + options << (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17")); break; case LanguageVersion::CXX2a: - opts << (gnuExtensions ? QLatin1String("-std=gnu++2a") : QLatin1String("-std=c++2a")); + options << (gnuExtensions ? QLatin1String("-std=gnu++2a") : QLatin1String("-std=c++2a")); break; } if (languageExtensions & LanguageExtension::Microsoft) - opts << QLatin1String("-fms-extensions"); + options << "-fms-extensions"; if (languageExtensions & LanguageExtension::OpenMP) - opts << QLatin1String("-fopenmp"); + options << "-fopenmp"; if (checkForBorlandExtensions && (languageExtensions & LanguageExtension::Borland)) - opts << QLatin1String("-fborland-extensions"); + options << "-fborland-extensions"; - m_options.append(opts); + m_options.append(options); } static QByteArray toMsCompatibilityVersionFormat(const QByteArray &mscFullVer) @@ -473,14 +503,12 @@ static QByteArray msCompatibilityVersionFromDefines(const ProjectExplorer::Macro void CompilerOptionsBuilder::addMsvcCompatibilityVersion() { if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) { - const ProjectExplorer::Macros macros = m_projectPart.toolChainMacros + m_projectPart.projectMacros; + 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=") - + QLatin1String(msvcVersion); - m_options.append(option); - } + if (!msvcVersion.isEmpty()) + add(QLatin1String("-fms-compatibility-version=") + msvcVersion); } } @@ -491,54 +519,54 @@ static QStringList languageFeatureMacros() // * Use latest -fms-compatibility-version and -std possible. // * Compatibility version 19 vs 1910 did not matter. // $ clang++ -fms-compatibility-version=19 -std=c++1z -dM -E D:\empty.cpp | grep __cpp_ - static QStringList macros{ - QLatin1String("__cpp_aggregate_bases"), - QLatin1String("__cpp_aggregate_nsdmi"), - QLatin1String("__cpp_alias_templates"), - QLatin1String("__cpp_aligned_new"), - QLatin1String("__cpp_attributes"), - QLatin1String("__cpp_binary_literals"), - QLatin1String("__cpp_capture_star_this"), - QLatin1String("__cpp_constexpr"), - QLatin1String("__cpp_decltype"), - QLatin1String("__cpp_decltype_auto"), - QLatin1String("__cpp_deduction_guides"), - QLatin1String("__cpp_delegating_constructors"), - QLatin1String("__cpp_digit_separators"), - QLatin1String("__cpp_enumerator_attributes"), - QLatin1String("__cpp_exceptions"), - QLatin1String("__cpp_fold_expressions"), - QLatin1String("__cpp_generic_lambdas"), - QLatin1String("__cpp_guaranteed_copy_elision"), - QLatin1String("__cpp_hex_float"), - QLatin1String("__cpp_if_constexpr"), - QLatin1String("__cpp_inheriting_constructors"), - QLatin1String("__cpp_init_captures"), - QLatin1String("__cpp_initializer_lists"), - QLatin1String("__cpp_inline_variables"), - QLatin1String("__cpp_lambdas"), - QLatin1String("__cpp_namespace_attributes"), - QLatin1String("__cpp_nested_namespace_definitions"), - QLatin1String("__cpp_noexcept_function_type"), - QLatin1String("__cpp_nontype_template_args"), - QLatin1String("__cpp_nontype_template_parameter_auto"), - QLatin1String("__cpp_nsdmi"), - QLatin1String("__cpp_range_based_for"), - QLatin1String("__cpp_raw_strings"), - QLatin1String("__cpp_ref_qualifiers"), - QLatin1String("__cpp_return_type_deduction"), - QLatin1String("__cpp_rtti"), - QLatin1String("__cpp_rvalue_references"), - QLatin1String("__cpp_static_assert"), - QLatin1String("__cpp_structured_bindings"), - QLatin1String("__cpp_template_auto"), - QLatin1String("__cpp_threadsafe_static_init"), - QLatin1String("__cpp_unicode_characters"), - QLatin1String("__cpp_unicode_literals"), - QLatin1String("__cpp_user_defined_literals"), - QLatin1String("__cpp_variable_templates"), - QLatin1String("__cpp_variadic_templates"), - QLatin1String("__cpp_variadic_using"), + static const QStringList macros{ + "__cpp_aggregate_bases", + "__cpp_aggregate_nsdmi", + "__cpp_alias_templates", + "__cpp_aligned_new", + "__cpp_attributes", + "__cpp_binary_literals", + "__cpp_capture_star_this", + "__cpp_constexpr", + "__cpp_decltype", + "__cpp_decltype_auto", + "__cpp_deduction_guides", + "__cpp_delegating_constructors", + "__cpp_digit_separators", + "__cpp_enumerator_attributes", + "__cpp_exceptions", + "__cpp_fold_expressions", + "__cpp_generic_lambdas", + "__cpp_guaranteed_copy_elision", + "__cpp_hex_float", + "__cpp_if_constexpr", + "__cpp_inheriting_constructors", + "__cpp_init_captures", + "__cpp_initializer_lists", + "__cpp_inline_variables", + "__cpp_lambdas", + "__cpp_namespace_attributes", + "__cpp_nested_namespace_definitions", + "__cpp_noexcept_function_type", + "__cpp_nontype_template_args", + "__cpp_nontype_template_parameter_auto", + "__cpp_nsdmi", + "__cpp_range_based_for", + "__cpp_raw_strings", + "__cpp_ref_qualifiers", + "__cpp_return_type_deduction", + "__cpp_rtti", + "__cpp_rvalue_references", + "__cpp_static_assert", + "__cpp_structured_bindings", + "__cpp_template_auto", + "__cpp_threadsafe_static_init", + "__cpp_unicode_characters", + "__cpp_unicode_literals", + "__cpp_user_defined_literals", + "__cpp_variable_templates", + "__cpp_variadic_templates", + "__cpp_variadic_using", }; return macros; @@ -550,15 +578,19 @@ void CompilerOptionsBuilder::undefineCppLanguageFeatureMacrosForMsvc2015() && m_projectPart.isMsvc2015Toolchain) { // Undefine the language feature macros that are pre-defined in clang-cl, // but not in MSVC's cl.exe. - foreach (const QString ¯oName, languageFeatureMacros()) - m_options.append(undefineOption() + macroName); + const QStringList macroNames = languageFeatureMacros(); + for (const QString ¯oName : macroNames) + add(undefineOption + macroName); } } void CompilerOptionsBuilder::addDefineFunctionMacrosMsvc() { - if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) - addMacros({{"__FUNCSIG__", "\"\""}, {"__FUNCTION__", "\"\""}, {"__FUNCDNAME__", "\"\""}}); + if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) { + addMacros({{"__FUNCSIG__", "\"\""}, + {"__FUNCTION__", "\"\""}, + {"__FUNCDNAME__", "\"\""}}); + } } void CompilerOptionsBuilder::addBoostWorkaroundMacros() @@ -573,46 +605,10 @@ QString CompilerOptionsBuilder::includeDirOptionForPath(const QString &path) con { if (m_useSystemHeader == UseSystemHeader::No || path.startsWith(m_projectPart.project->rootProjectDirectory().toString())) { - return QString("-I"); - } else { - return QString("-isystem"); + return includeUserPathOption; } -} -QByteArray CompilerOptionsBuilder::macroOption(const ProjectExplorer::Macro ¯o) const -{ - switch (macro.type) { - case ProjectExplorer::MacroType::Define: return defineOption().toUtf8(); - case ProjectExplorer::MacroType::Undefine: return undefineOption().toUtf8(); - default: return QByteArray(); - } -} - -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 -{ - return QLatin1String("-D"); -} - -QString CompilerOptionsBuilder::undefineOption() const -{ - return QLatin1String("-U"); -} - -QString CompilerOptionsBuilder::includeOption() const -{ - return QLatin1String("-include"); + return includeSystemPathOption; } bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro ¯o) const @@ -657,24 +653,13 @@ bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro return false; } -bool CompilerOptionsBuilder::excludeHeaderPath(const QString &headerPath) const -{ - // Always exclude clang system includes (including intrinsics) which do not come with libclang - // that Qt Creator uses for code model. - // For example GCC on macOS uses system clang include path which makes clang code model - // include incorrect system headers. - static QRegularExpression clangIncludeDir( - QLatin1String("\\A.*[\\/\\\\]lib\\d*[\\/\\\\]clang[\\/\\\\]\\d+\\.\\d+(\\.\\d+)?[\\/\\\\]include\\z")); - return clangIncludeDir.match(headerPath).hasMatch(); -} - -void CompilerOptionsBuilder::addWrappedQtHeadersIncludePath(QStringList &list) +void CompilerOptionsBuilder::addWrappedQtHeadersIncludePath(QStringList &list) const { static const QString resourcePath = creatorResourcePath(); static QString wrappedQtHeadersPath = resourcePath + "/cplusplus/wrappedQtHeaders"; QTC_ASSERT(QDir(wrappedQtHeadersPath).exists(), return;); - if (m_projectPart.qtVersion != CppTools::ProjectPart::NoQt) { + if (m_projectPart.qtVersion != ProjectPart::NoQt) { const QString wrappedQtCoreHeaderPath = wrappedQtHeadersPath + "/QtCore"; list.append(includeDirOptionForPath(wrappedQtHeadersPath)); list.append(QDir::toNativeSeparators(wrappedQtHeadersPath)); @@ -698,7 +683,7 @@ void CompilerOptionsBuilder::addToolchainFlags() void CompilerOptionsBuilder::addProjectConfigFileInclude() { if (!m_projectPart.projectConfigFile.isEmpty()) { - add("-include"); + add(includeFileOption); add(QDir::toNativeSeparators(m_projectPart.projectConfigFile)); } } @@ -706,7 +691,7 @@ void CompilerOptionsBuilder::addProjectConfigFileInclude() void CompilerOptionsBuilder::undefineClangVersionMacrosForMsvc() { if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) { - static QStringList macroNames { + static const QStringList macroNames { "__clang__", "__clang_major__", "__clang_minor__", @@ -714,8 +699,8 @@ void CompilerOptionsBuilder::undefineClangVersionMacrosForMsvc() "__clang_version__" }; - foreach (const QString ¯oName, macroNames) - add(undefineOption() + macroName); + for (const QString ¯oName : macroNames) + add(undefineOption + macroName); } } diff --git a/src/plugins/cpptools/compileroptionsbuilder.h b/src/plugins/cpptools/compileroptionsbuilder.h index 66202e72d69..12c2b8bce26 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.h +++ b/src/plugins/cpptools/compileroptionsbuilder.h @@ -31,50 +31,30 @@ namespace CppTools { -enum class UseSystemHeader : char -{ - Yes, - No -}; - -enum class SkipBuiltIn : char -{ - Yes, - No -}; - -enum class SkipLanguageDefines : char -{ - Yes, - No -}; +enum class UsePrecompiledHeaders : char { Yes, No }; +enum class UseSystemHeader : char { Yes, No }; +enum class SkipBuiltIn : char { Yes, No }; +enum class SkipLanguageDefines : char { Yes, No }; class CPPTOOLS_EXPORT CompilerOptionsBuilder { public: - enum class PchUsage { - None, - Use - }; - CompilerOptionsBuilder(const ProjectPart &projectPart, UseSystemHeader useSystemHeader = UseSystemHeader::No, SkipBuiltIn skipBuiltInHeaderPathsAndDefines = SkipBuiltIn::No, SkipLanguageDefines skipLanguageDefines = SkipLanguageDefines::Yes, - QString clangVersion = QString(), - QString clangResourceDirectory = QString()); + const QString &clangVersion = QString(), + const QString &clangResourceDirectory = QString()); - QStringList build(ProjectFile::Kind fileKind, - PchUsage pchUsage); - QStringList options() const; + QStringList build(ProjectFile::Kind fileKind, UsePrecompiledHeaders usePrecompiledHeaders); + QStringList options() const { return m_options; } - virtual void addExtraOptions() {} // Add options based on project part virtual void addToolchainAndProjectMacros(); void addWordWidth(); void addToolchainFlags(); void addHeaderPathOptions(); - void addPrecompiledHeaderOptions(PchUsage pchUsage); + void addPrecompiledHeaderOptions(UsePrecompiledHeaders usePrecompiledHeaders); void addMacros(const ProjectExplorer::Macros ¯os); void addTargetTriple(); @@ -92,36 +72,26 @@ public: void addProjectConfigFileInclude(); void undefineClangVersionMacrosForMsvc(); -protected: - virtual bool excludeDefineDirective(const ProjectExplorer::Macro ¯o) const; - virtual bool excludeHeaderPath(const QString &headerPath) const; - - virtual QString defineOption() const; - virtual QString undefineOption() const; - virtual QString includeOption() const; - // Add custom options - void add(const QString &option); - - QString includeDirOptionForPath(const QString &path) const; - - const ProjectPart &m_projectPart; + void add(const QString &option) { m_options.append(option); } + virtual void addExtraOptions() {} private: - QByteArray macroOption(const ProjectExplorer::Macro ¯o) const; - QByteArray toDefineOption(const ProjectExplorer::Macro ¯o) const; - QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const; + bool excludeDefineDirective(const ProjectExplorer::Macro ¯o) const; + QString includeDirOptionForPath(const QString &path) const; + void addWrappedQtHeadersIncludePath(QStringList &list) const; - void addWrappedQtHeadersIncludePath(QStringList &list); +private: + const ProjectPart &m_projectPart; + + const UseSystemHeader m_useSystemHeader; + const SkipBuiltIn m_skipBuiltInHeaderPathsAndDefines; + const SkipLanguageDefines m_skipLanguageDefines; + + const QString m_clangVersion; + const QString m_clangResourceDirectory; QStringList m_options; - - QString m_clangVersion; - QString m_clangResourceDirectory; - - UseSystemHeader m_useSystemHeader; - SkipBuiltIn m_skipBuiltInHeaderPathsAndDefines; - SkipLanguageDefines m_skipLanguageDefines; }; } // namespace CppTools diff --git a/src/plugins/cpptools/cpptoolsreuse.cpp b/src/plugins/cpptools/cpptoolsreuse.cpp index 944196f938c..c63a3cc293b 100644 --- a/src/plugins/cpptools/cpptoolsreuse.cpp +++ b/src/plugins/cpptools/cpptoolsreuse.cpp @@ -279,12 +279,12 @@ bool fileSizeExceedsLimit(const QFileInfo &fileInfo, int sizeLimitInMb) return false; } -CompilerOptionsBuilder::PchUsage getPchUsage() +UsePrecompiledHeaders getPchUsage() { const QSharedPointer cms = codeModelSettings(); if (cms->pchUsage() == CppCodeModelSettings::PchUse_None) - return CompilerOptionsBuilder::PchUsage::None; - return CompilerOptionsBuilder::PchUsage::Use; + return UsePrecompiledHeaders::No; + return UsePrecompiledHeaders::Yes; } } // CppTools diff --git a/src/plugins/cpptools/cpptoolsreuse.h b/src/plugins/cpptools/cpptoolsreuse.h index 505de401034..cb45fe89580 100644 --- a/src/plugins/cpptools/cpptoolsreuse.h +++ b/src/plugins/cpptools/cpptoolsreuse.h @@ -75,7 +75,7 @@ void CPPTOOLS_EXPORT switchHeaderSource(); class CppCodeModelSettings; QSharedPointer CPPTOOLS_EXPORT codeModelSettings(); -CompilerOptionsBuilder::PchUsage CPPTOOLS_EXPORT getPchUsage(); +UsePrecompiledHeaders CPPTOOLS_EXPORT getPchUsage(); int indexerFileSizeLimitInMb(); bool fileSizeExceedsLimit(const QFileInfo &fileInfo, int sizeLimitInMb); diff --git a/tests/unit/mockup/cpptools/cpptoolsreuse.h b/tests/unit/mockup/cpptools/cpptoolsreuse.h index 74db97df056..6714f7b8123 100644 --- a/tests/unit/mockup/cpptools/cpptoolsreuse.h +++ b/tests/unit/mockup/cpptools/cpptoolsreuse.h @@ -29,6 +29,6 @@ namespace CppTools { -inline CompilerOptionsBuilder::PchUsage getPchUsage() { return CompilerOptionsBuilder::PchUsage::None; } +inline CppTools::UsePrecompiledHeaders getPchUsage() { return UsePrecompiledHeaders::No; } } // CppTools diff --git a/tests/unit/unittest/compileroptionsbuilder-test.cpp b/tests/unit/unittest/compileroptionsbuilder-test.cpp index 6b2d1af11e3..65b662087bb 100644 --- a/tests/unit/unittest/compileroptionsbuilder-test.cpp +++ b/tests/unit/unittest/compileroptionsbuilder-test.cpp @@ -310,14 +310,14 @@ TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderAndroidClang) TEST_F(CompilerOptionsBuilder, NoPrecompiledHeader) { - compilerOptionsBuilder.addPrecompiledHeaderOptions(CppTools::CompilerOptionsBuilder::PchUsage::None); + compilerOptionsBuilder.addPrecompiledHeaderOptions(CppTools::UsePrecompiledHeaders::No); ASSERT_THAT(compilerOptionsBuilder.options().empty(), true); } TEST_F(CompilerOptionsBuilder, UsePrecompiledHeader) { - compilerOptionsBuilder.addPrecompiledHeaderOptions(CppTools::CompilerOptionsBuilder::PchUsage::Use); + compilerOptionsBuilder.addPrecompiledHeaderOptions(CppTools::UsePrecompiledHeaders::Yes); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-include", QDir::toNativeSeparators(TESTDATA_DIR "/compileroptionsbuilder.pch"))); @@ -434,7 +434,7 @@ TEST_F(CompilerOptionsBuilder, UndefineClangVersionMacrosForMsvc) TEST_F(CompilerOptionsBuilder, BuildAllOptions) { - compilerOptionsBuilder.build(ProjectFile::CXXSource, CppTools::CompilerOptionsBuilder::PchUsage::None); + compilerOptionsBuilder.build(ProjectFile::CXXSource, CppTools::UsePrecompiledHeaders::No); ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre( diff --git a/tests/unit/unittest/refactoringengine-test.cpp b/tests/unit/unittest/refactoringengine-test.cpp index 57b11a9523b..747c9300900 100644 --- a/tests/unit/unittest/refactoringengine-test.cpp +++ b/tests/unit/unittest/refactoringengine-test.cpp @@ -150,9 +150,8 @@ void RefactoringEngine::SetUp() projectPart->files.push_back(projectFile); CompilerOptionsBuilder optionsBuilder(*projectPart); - commandLine = Utils::SmallStringVector(optionsBuilder.build( - projectFile.kind, - CompilerOptionsBuilder::PchUsage::None)); + commandLine = Utils::SmallStringVector( + optionsBuilder.build(projectFile.kind, CppTools::UsePrecompiledHeaders::No)); commandLine.push_back(qStringFilePath); }