aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/clangcodemodel
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2019-03-14 15:14:40 +0100
committerEike Ziller <eike.ziller@qt.io>2019-03-14 15:51:15 +0100
commitc53ccceff1e1642b7704fa8b0681604c25a833a0 (patch)
tree7258d63fba4dabd6f9e2f2f36089ce45df7fe3af /src/plugins/clangcodemodel
parent62cafc1782369cde0605fbd6b1182a83d5473a12 (diff)
parent429eb73ace5909e228a58bf8b067823e2be44212 (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')
-rw-r--r--src/plugins/clangcodemodel/clangcodemodelplugin.cpp9
-rw-r--r--src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp13
-rw-r--r--src/plugins/clangcodemodel/clangcompletionassistprocessor.h1
-rw-r--r--src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp7
-rw-r--r--src/plugins/clangcodemodel/clangutils.cpp97
-rw-r--r--src/plugins/clangcodemodel/clangutils.h2
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 &macro : 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
{