forked from qt-creator/qt-creator
ClangCodeModel: Minimize QStringList -> QJsonArray conversions
... when setting up the compilation database. As it turns out, these conversions were the most expensive part of creating the JSON file. We now build the JSON arrays incrementally instead of setting them up from scratch for every source file. Change-Id: I1e664a6320d5b3c49b31366c58aa14f63818e008 Reviewed-by: David Schulz <david.schulz@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -1453,13 +1453,13 @@ private:
|
||||
};
|
||||
|
||||
static void addToCompilationDb(QJsonObject &cdb,
|
||||
const CppEditor::CompilerOptionsBuilder &optionsBuilder,
|
||||
const CppEditor::ProjectPart &projectPart,
|
||||
CppEditor::UsePrecompiledHeaders usePch,
|
||||
const QStringList &projectOptions,
|
||||
const QJsonArray &projectPartOptions,
|
||||
const Utils::FilePath &workingDir,
|
||||
const CppEditor::ProjectFile &sourceFile)
|
||||
{
|
||||
QStringList args = clangOptionsForFile(optionsBuilder, sourceFile, projectOptions, usePch);
|
||||
QJsonArray args = clangOptionsForFile(sourceFile, projectPart, projectPartOptions, usePch);
|
||||
|
||||
// TODO: clangd seems to apply some heuristics depending on what we put here.
|
||||
// Should we make use of them or keep using our own?
|
||||
@@ -1469,7 +1469,7 @@ static void addToCompilationDb(QJsonObject &cdb,
|
||||
args.append(fileString);
|
||||
QJsonObject value;
|
||||
value.insert("workingDirectory", workingDir.toString());
|
||||
value.insert("compilationCommand", QJsonArray::fromStringList(args));
|
||||
value.insert("compilationCommand", args);
|
||||
cdb.insert(fileString, value);
|
||||
}
|
||||
|
||||
@@ -1497,9 +1497,11 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir)
|
||||
*CppEditor::CppModelManager::instance()->fallbackProjectPart(),
|
||||
warningsConfig);
|
||||
const CppEditor::UsePrecompiledHeaders usePch = CppEditor::getPchUsage();
|
||||
const QStringList clangOptions = clangOptionsForFile(
|
||||
optionsBuilder, {}, optionsForProject(nullptr, warningsConfig), usePch);
|
||||
initOptions.insert("fallbackFlags", QJsonArray::fromStringList(clangOptions));
|
||||
const QJsonArray projectPartOptions = fullProjectPartOptions(
|
||||
optionsBuilder, optionsForProject(nullptr, warningsConfig));
|
||||
const QJsonArray clangOptions = clangOptionsForFile({}, optionsBuilder.projectPart(),
|
||||
projectPartOptions, usePch);
|
||||
initOptions.insert("fallbackFlags", clangOptions);
|
||||
setInitializationOptions(initOptions);
|
||||
}
|
||||
auto isRunningClangdClient = [](const LanguageClient::Client *c) {
|
||||
@@ -1921,8 +1923,10 @@ void ClangdClient::updateParserConfig(const Utils::FilePath &filePath,
|
||||
warningsConfig);
|
||||
const CppEditor::ProjectFile file(filePath.toString(),
|
||||
CppEditor::ProjectFile::classify(filePath.toString()));
|
||||
addToCompilationDb(cdbChanges, optionsBuilder, CppEditor::getPchUsage(),
|
||||
optionsForProject(project(), warningsConfig), filePath.parentDir(), file);
|
||||
const QJsonArray projectPartOptions = fullProjectPartOptions(
|
||||
optionsBuilder, optionsForProject(project(), warningsConfig));
|
||||
addToCompilationDb(cdbChanges, *projectPart, CppEditor::getPchUsage(), projectPartOptions,
|
||||
filePath.parentDir(), file);
|
||||
QJsonObject settings;
|
||||
addCompilationDb(settings, cdbChanges);
|
||||
DidChangeConfigurationParams configChangeParams;
|
||||
|
||||
@@ -183,11 +183,10 @@ static QStringList projectPartArguments(const ProjectPart &projectPart)
|
||||
|
||||
static QJsonObject createFileObject(const FilePath &buildDir,
|
||||
const QStringList &arguments,
|
||||
const CompilerOptionsBuilder &optionsBuilder,
|
||||
const ProjectPart &projectPart,
|
||||
const ProjectFile &projFile,
|
||||
CompilationDbPurpose purpose,
|
||||
const QStringList &projectOptions,
|
||||
const QJsonArray &projectPartOptions,
|
||||
UsePrecompiledHeaders usePch)
|
||||
{
|
||||
QJsonObject fileObject;
|
||||
@@ -213,8 +212,7 @@ static QJsonObject createFileObject(const FilePath &buildDir,
|
||||
args.append(langOptionPart);
|
||||
}
|
||||
} else {
|
||||
args = QJsonArray::fromStringList(clangOptionsForFile(optionsBuilder, projFile,
|
||||
projectOptions, usePch));
|
||||
args = clangOptionsForFile(projFile, projectPart, projectPartOptions, usePch);
|
||||
args.prepend("clang"); // TODO: clang-cl for MSVC targets? Does it matter at all what we put here?
|
||||
}
|
||||
|
||||
@@ -245,15 +243,20 @@ GenerateCompilationDbResult generateCompilationDB(const CppEditor::ProjectInfo::
|
||||
compileCommandsFile.write("[");
|
||||
|
||||
const UsePrecompiledHeaders usePch = getPchUsage();
|
||||
const QJsonArray jsonProjectOptions = QJsonArray::fromStringList(projectOptions);
|
||||
for (ProjectPart::ConstPtr projectPart : projectInfo->projectParts()) {
|
||||
QStringList args;
|
||||
const CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder(*projectPart,
|
||||
warningsConfig);
|
||||
if (purpose == CompilationDbPurpose::Project)
|
||||
QJsonArray ppOptions;
|
||||
if (purpose == CompilationDbPurpose::Project) {
|
||||
args = projectPartArguments(*projectPart);
|
||||
} else {
|
||||
ppOptions = fullProjectPartOptions(projectPartOptions(optionsBuilder), jsonProjectOptions);
|
||||
}
|
||||
for (const ProjectFile &projFile : projectPart->files) {
|
||||
const QJsonObject json = createFileObject(baseDir, args, optionsBuilder, *projectPart,
|
||||
projFile, purpose, projectOptions, usePch);
|
||||
const QJsonObject json = createFileObject(baseDir, args, *projectPart, projFile,
|
||||
purpose, ppOptions, usePch);
|
||||
if (compileCommandsFile.size() > 1)
|
||||
compileCommandsFile.write(",");
|
||||
compileCommandsFile.write('\n' + QJsonDocument(json).toJson().trimmed());
|
||||
@@ -332,25 +335,28 @@ static ClangProjectSettings &getProjectSettings(ProjectExplorer::Project *projec
|
||||
QTC_CHECK(project);
|
||||
return ClangModelManagerSupport::instance()->projectSettings(project);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
QStringList clangOptionsForFile(CompilerOptionsBuilder optionsBuilder,
|
||||
const ProjectFile &file, const QStringList &projectOptions,
|
||||
UsePrecompiledHeaders usePch)
|
||||
QJsonArray clangOptionsForFile(const ProjectFile &file, const ProjectPart &projectPart,
|
||||
const QJsonArray &generalOptions, UsePrecompiledHeaders usePch)
|
||||
{
|
||||
CompilerOptionsBuilder optionsBuilder(projectPart);
|
||||
ProjectFile::Kind fileKind = file.kind;
|
||||
if (fileKind == ProjectFile::AmbiguousHeader) {
|
||||
fileKind = optionsBuilder.projectPart().languageVersion <= LanguageVersion::LatestC
|
||||
fileKind = projectPart.languageVersion <= LanguageVersion::LatestC
|
||||
? ProjectFile::CHeader : ProjectFile::CXXHeader;
|
||||
}
|
||||
if (usePch == UsePrecompiledHeaders::Yes
|
||||
&& optionsBuilder.projectPart().precompiledHeaders.contains(file.path)) {
|
||||
&& projectPart.precompiledHeaders.contains(file.path)) {
|
||||
usePch = UsePrecompiledHeaders::No;
|
||||
}
|
||||
optionsBuilder.updateFileLanguage(file.kind);
|
||||
optionsBuilder.addPrecompiledHeaderOptions(usePch);
|
||||
return projectOptions + optionsBuilder.options();
|
||||
const QJsonArray specificOptions = QJsonArray::fromStringList(optionsBuilder.options());
|
||||
QJsonArray fullOptions = generalOptions;
|
||||
for (const QJsonValue &opt : specificOptions)
|
||||
fullOptions << opt;
|
||||
return fullOptions;
|
||||
}
|
||||
|
||||
ClangDiagnosticConfig warningsConfigForProject(Project *project)
|
||||
@@ -449,5 +455,34 @@ CompilerOptionsBuilder clangOptionsBuilder(const ProjectPart &projectPart,
|
||||
return optionsBuilder;
|
||||
}
|
||||
|
||||
QJsonArray projectPartOptions(const CppEditor::CompilerOptionsBuilder &optionsBuilder)
|
||||
{
|
||||
const QStringList optionsList = optionsBuilder.options();
|
||||
QJsonArray optionsArray;
|
||||
for (const QString &opt : optionsList) {
|
||||
// These will be added later by the file-specific code, and they trigger warnings
|
||||
// if they appear twice; see QTCREATORBUG-26664.
|
||||
if (opt != "-TP" && opt != "-TC")
|
||||
optionsArray << opt;
|
||||
}
|
||||
return optionsArray;
|
||||
}
|
||||
|
||||
QJsonArray fullProjectPartOptions(const CppEditor::CompilerOptionsBuilder &optionsBuilder,
|
||||
const QStringList &projectOptions)
|
||||
{
|
||||
return fullProjectPartOptions(projectPartOptions(optionsBuilder),
|
||||
QJsonArray::fromStringList(projectOptions));
|
||||
}
|
||||
|
||||
QJsonArray fullProjectPartOptions(const QJsonArray &projectPartOptions,
|
||||
const QJsonArray &projectOptions)
|
||||
{
|
||||
QJsonArray fullProjectPartOptions = projectPartOptions;
|
||||
for (const QJsonValue &opt : projectOptions)
|
||||
fullProjectPartOptions.prepend(opt);
|
||||
return fullProjectPartOptions;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Clang
|
||||
|
||||
@@ -63,9 +63,15 @@ const QStringList optionsForProject(ProjectExplorer::Project *project,
|
||||
CppEditor::CompilerOptionsBuilder clangOptionsBuilder(
|
||||
const CppEditor::ProjectPart &projectPart,
|
||||
const CppEditor::ClangDiagnosticConfig &warningsConfig);
|
||||
QStringList clangOptionsForFile(CppEditor::CompilerOptionsBuilder optionsBuilder,
|
||||
const CppEditor::ProjectFile &file,
|
||||
const QStringList &projectOptions, CppEditor::UsePrecompiledHeaders usePch);
|
||||
QJsonArray projectPartOptions(const CppEditor::CompilerOptionsBuilder &optionsBuilder);
|
||||
QJsonArray fullProjectPartOptions(const CppEditor::CompilerOptionsBuilder &optionsBuilder,
|
||||
const QStringList &projectOptions);
|
||||
QJsonArray fullProjectPartOptions(const QJsonArray &projectPartOptions,
|
||||
const QJsonArray &projectOptions);
|
||||
QJsonArray clangOptionsForFile(const CppEditor::ProjectFile &file,
|
||||
const CppEditor::ProjectPart &projectPart,
|
||||
const QJsonArray &generalOptions,
|
||||
CppEditor::UsePrecompiledHeaders usePch);
|
||||
|
||||
CppEditor::ProjectPart::ConstPtr projectPartForFile(const QString &filePath);
|
||||
CppEditor::ProjectPart::ConstPtr projectPartForFileBasedOnProcessor(const QString &filePath);
|
||||
|
||||
Reference in New Issue
Block a user