diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index 481b0774f8f..c8e74f663f5 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -34,12 +34,13 @@ #include #include #include +#include #include +#include #include #include -#include -#include #include +#include #include #include @@ -300,6 +301,18 @@ QString diagnosticCategoryPrefixRemoved(const QString &text) return text; } +static ::Utils::FileName compilerPath(const CppTools::ProjectPart &projectPart) +{ + ProjectExplorer::Target *target = projectPart.project->activeTarget(); + if (!target) + return ::Utils::FileName(); + + ProjectExplorer::ToolChain *toolchain = ProjectExplorer::ToolChainKitInformation::toolChain( + target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID); + + return toolchain->compilerCommand(); +} + static ::Utils::FileName buildDirectory(const CppTools::ProjectPart &projectPart) { ProjectExplorer::Target *target = projectPart.project->activeTarget(); @@ -313,17 +326,60 @@ static ::Utils::FileName buildDirectory(const CppTools::ProjectPart &projectPart return buildConfig->buildDirectory(); } -static QJsonObject createFileObject(CompilerOptionsBuilder &optionsBuilder, - const ProjectFile &projFile, - const ::Utils::FileName &buildDir) +static QStringList projectPartArguments(const ProjectPart &projectPart) { - const ProjectFile::Kind kind = ProjectFile::classify(projFile.path); - optionsBuilder.updateFileLanguage(kind); + QStringList args; + args << compilerPath(projectPart).toString(); + args << "-c"; + if (projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) { + args << "--target=" + projectPart.toolChainTargetTriple; + args << (projectPart.toolChainWordWidth == ProjectPart::WordWidth64Bit + ? QLatin1String("-m64") + : QLatin1String("-m32")); + } + args << projectPart.compilerFlags; + for (const ProjectExplorer::HeaderPath &headerPath : projectPart.headerPaths) { + if (headerPath.type == ProjectExplorer::HeaderPathType::User) { + args << "-I" + headerPath.path; + } else if (headerPath.type == ProjectExplorer::HeaderPathType::System) { + args << (projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID + ? "-I" + : "-isystem") + + headerPath.path; + } + } + for (const ProjectExplorer::Macro ¯o : projectPart.projectMacros) { + args.append(QString::fromUtf8( + macro.toKeyValue(macro.type == ProjectExplorer::MacroType::Define ? "-D" : "-U"))); + } + return args; +} + +static QJsonObject createFileObject(const ::Utils::FileName &buildDir, + const QStringList &arguments, + const ProjectPart &projectPart, + const ProjectFile &projFile) +{ QJsonObject fileObject; fileObject["file"] = projFile.path; - QJsonArray args = QJsonArray::fromStringList(optionsBuilder.options()); - args.prepend(kind == ProjectFile::CXXSource ? "clang++" : "clang"); + QJsonArray args = QJsonArray::fromStringList(arguments); + + const ProjectFile::Kind kind = ProjectFile::classify(projFile.path); + if (projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID + || projectPart.toolchainType == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID) { + if (ProjectFile::isC(kind)) + args.append("/TC"); + else if (ProjectFile::isCxx(kind)) + args.append("/TP"); + } else { + QStringList langOption + = createLanguageOptionGcc(kind, + projectPart.languageExtensions + & ::Utils::LanguageExtension::ObjectiveC); + for (const QString &langOptionPart : langOption) + args.append(langOptionPart); + } args.append(QDir::toNativeSeparators(projFile.path)); fileObject["arguments"] = args; fileObject["directory"] = buildDir.toString(); @@ -338,17 +394,12 @@ void generateCompilationDB(::Utils::FileName projectDir, CppTools::ProjectInfo p if (!fileOpened) return; compileCommandsFile.write("["); + for (ProjectPart::Ptr projectPart : projectInfo.projectParts()) { const ::Utils::FileName buildDir = buildDirectory(*projectPart); - - CompilerOptionsBuilder optionsBuilder(*projectPart, - UseSystemHeader::No, - UseTweakedHeaderPaths::No); - optionsBuilder.build(CppTools::ProjectFile::Unclassified, - CppTools::UsePrecompiledHeaders::No); - + const QStringList args = projectPartArguments(*projectPart); for (const ProjectFile &projFile : projectPart->files) { - const QJsonObject json = createFileObject(optionsBuilder, projFile, buildDir); + const QJsonObject json = createFileObject(buildDir, args, *projectPart, projFile); if (compileCommandsFile.size() > 1) compileCommandsFile.write(","); compileCommandsFile.write('\n' + QJsonDocument(json).toJson().trimmed()); diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index f757f2fe2cc..8dfe0c79773 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -172,7 +172,7 @@ void CompilerOptionsBuilder::addSyntaxOnly() isClStyle() ? add("/Zs") : add("-fsyntax-only"); } -static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt) +QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt) { QStringList options; diff --git a/src/plugins/cpptools/compileroptionsbuilder.h b/src/plugins/cpptools/compileroptionsbuilder.h index 03564ab6164..349279710ad 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.h +++ b/src/plugins/cpptools/compileroptionsbuilder.h @@ -40,6 +40,7 @@ enum class UseBuildSystemWarnings : char { Yes, No }; CPPTOOLS_EXPORT QStringList XclangArgs(const QStringList &args); CPPTOOLS_EXPORT QStringList clangArgsForCl(const QStringList &args); +CPPTOOLS_EXPORT QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt); class CPPTOOLS_EXPORT CompilerOptionsBuilder {