diff options
author | Eike Ziller <eike.ziller@qt.io> | 2019-03-14 15:14:40 +0100 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2019-03-14 15:51:15 +0100 |
commit | c53ccceff1e1642b7704fa8b0681604c25a833a0 (patch) | |
tree | 7258d63fba4dabd6f9e2f2f36089ce45df7fe3af /src/plugins/clangcodemodel | |
parent | 62cafc1782369cde0605fbd6b1182a83d5473a12 (diff) | |
parent | 429eb73ace5909e228a58bf8b067823e2be44212 (diff) |
Merge remote-tracking branch 'origin/4.9'
Conflicts:
qbs/modules/qtc/qtc.qbs
qtcreator.pri
src/plugins/debugger/debuggerkitinformation.cpp
src/plugins/languageclient/languageclientmanager.cpp
src/plugins/plugins.pro
src/plugins/projectexplorer/kit.cpp
src/plugins/projectexplorer/kitmanager.cpp
Change-Id: I66fb941202991f35f7d7761430b21e42dfc678a8
Diffstat (limited to 'src/plugins/clangcodemodel')
6 files changed, 101 insertions, 28 deletions
diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index 11de94c395..a4a1591cf4 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -68,13 +68,12 @@ void ClangCodeModelPlugin::generateCompilationDB() { using namespace CppTools; ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject(); - if (!project) + if (!project || !project->activeTarget()) return; - m_generatorWatcher.setFuture(QtConcurrent::run( - &Utils::generateCompilationDB, - project->projectDirectory(), - CppModelManager::instance()->projectInfo(project))); + m_generatorWatcher.setFuture( + QtConcurrent::run(&Utils::generateCompilationDB, + CppModelManager::instance()->projectInfo(project))); } static bool isDBGenerationEnabled(ProjectExplorer::Project *project) diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp index db34c904d4..6f1397c487 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp @@ -214,6 +214,9 @@ void ClangCompletionAssistProcessor::handleAvailableCompletions(const CodeComple setAsyncProposalAvailable(createFunctionHintProposal(completions)); return; } + + if (!m_fallbackToNormalCompletion) + return; // else: Proceed with a normal completion in case: // 1) it was not a function call, but e.g. a function declaration like "void f(" // 2) '{' meant not a constructor call. @@ -286,6 +289,14 @@ static QByteArray modifyInput(QTextDocument *doc, int endOfExpression) { return modifiedInput; } +static QChar lastPrecedingNonWhitespaceChar(const ClangCompletionAssistInterface *interface) +{ + int pos = interface->position(); + while (pos >= 0 && interface->characterAt(pos).isSpace()) + --pos; + return pos >= 0 ? interface->characterAt(pos) : QChar::Null; +} + IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper() { ClangCompletionContextAnalyzer analyzer(m_interface.data(), m_interface->languageFeatures()); @@ -323,6 +334,8 @@ IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper() } case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen: { m_sentRequestType = FunctionHintCompletion; + if (lastPrecedingNonWhitespaceChar(m_interface.data()) == ',') + m_fallbackToNormalCompletion = false; m_requestSent = sendCompletionRequest(analyzer.positionForClang(), QByteArray(), analyzer.functionNameStart()); break; diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.h b/src/plugins/clangcodemodel/clangcompletionassistprocessor.h index 03711f0fa8..5e8c772235 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.h +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.h @@ -97,6 +97,7 @@ private: CompletionRequestType m_sentRequestType = NormalCompletion; bool m_requestSent = false; bool m_addSnippets = false; // For type == Type::NormalCompletion + bool m_fallbackToNormalCompletion = true; }; } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp b/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp index ad48a60685..a2c32a537a 100644 --- a/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp +++ b/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp @@ -110,6 +110,8 @@ int ClangCompletionContextAnalyzer::startOfFunctionCall(int endOfOperator) const functionNameSelector.setPosition(functionNameStart); functionNameSelector.setPosition(index, QTextCursor::KeepAnchor); const QString functionName = functionNameSelector.selectedText().trimmed(); + if (functionName.isEmpty() && m_completionOperator == T_LBRACE) + return endOfOperator; return functionName.isEmpty() ? -1 : functionNameStart; } @@ -139,7 +141,10 @@ void ClangCompletionContextAnalyzer::handleCommaInFunctionCall() const int start = expressionUnderCursor.startOfFunctionCall(textCursor); m_positionEndOfExpression = start; m_positionForProposal = start + 1; // After '(' of function call - m_completionOperator = T_LPAREN; + if (m_interface->characterAt(start) == '(') + m_completionOperator = T_LPAREN; + else + m_completionOperator = T_LBRACE; } } diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index 481b0774f8..fa42dedf2d 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -34,12 +34,13 @@ #include <coreplugin/idocument.h> #include <cpptools/baseeditordocumentparser.h> #include <cpptools/compileroptionsbuilder.h> +#include <cpptools/cppcodemodelsettings.h> #include <cpptools/cppmodelmanager.h> +#include <cpptools/cpptoolsreuse.h> #include <cpptools/editordocumenthandle.h> #include <cpptools/projectpart.h> -#include <cpptools/cppcodemodelsettings.h> -#include <cpptools/cpptoolsreuse.h> #include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/kitinformation.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/target.h> @@ -300,12 +301,24 @@ QString diagnosticCategoryPrefixRemoved(const QString &text) return text; } -static ::Utils::FileName buildDirectory(const CppTools::ProjectPart &projectPart) +static ::Utils::FileName compilerPath(const CppTools::ProjectPart &projectPart) { ProjectExplorer::Target *target = projectPart.project->activeTarget(); if (!target) return ::Utils::FileName(); + ProjectExplorer::ToolChain *toolchain = ProjectExplorer::ToolChainKitAspect::toolChain( + target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID); + + return toolchain->compilerCommand(); +} + +static ::Utils::FileName buildDirectory(const ProjectExplorer::Project &project) +{ + ProjectExplorer::Target *target = project.activeTarget(); + if (!target) + return ::Utils::FileName(); + ProjectExplorer::BuildConfiguration *buildConfig = target->activeBuildConfiguration(); if (!buildConfig) return ::Utils::FileName(); @@ -313,42 +326,84 @@ 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(); return fileObject; } -void generateCompilationDB(::Utils::FileName projectDir, CppTools::ProjectInfo projectInfo) +void generateCompilationDB(CppTools::ProjectInfo projectInfo) { - QFile compileCommandsFile(projectDir.toString() + "/compile_commands.json"); + const ::Utils::FileName buildDir = buildDirectory(*projectInfo.project()); + QTC_ASSERT(!buildDir.isEmpty(), return;); + QDir dir(buildDir.toString()); + if (!dir.exists()) + dir.mkpath(dir.path()); + QFile compileCommandsFile(buildDir.toString() + "/compile_commands.json"); const bool fileOpened = compileCommandsFile.open(QIODevice::WriteOnly | QIODevice::Truncate); 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); + for (ProjectPart::Ptr projectPart : projectInfo.projectParts()) { + 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/clangcodemodel/clangutils.h b/src/plugins/clangcodemodel/clangutils.h index 4db869896b..8ced14f5ad 100644 --- a/src/plugins/clangcodemodel/clangutils.h +++ b/src/plugins/clangcodemodel/clangutils.h @@ -70,7 +70,7 @@ QString diagnosticCategoryPrefixRemoved(const QString &text); ::Utils::CodeModelIcon::Type iconTypeForToken(const ClangBackEnd::TokenInfoContainer &token); -void generateCompilationDB(::Utils::FileName projectDir, CppTools::ProjectInfo projectInfo); +void generateCompilationDB(CppTools::ProjectInfo projectInfo); class DiagnosticTextInfo { |