CppTools: Take "-include" files into account

Fixes: QTCREATORBUG-20602
Change-Id: Ibfc518fc64ed75f93265db800558ec1d2e424bb4
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Nikolai Kosjar
2018-06-11 12:52:04 +02:00
committed by Christian Kandeler
parent c05ad9a951
commit 888ea6bbbb
21 changed files with 130 additions and 20 deletions

View File

@@ -188,8 +188,10 @@ void AutotoolsBuildSystem::updateCppCodeModel()
QStringList cxxflags = m_makefileParserThread->cxxflags();
if (cxxflags.isEmpty())
cxxflags = cflags;
rpp.setFlagsForC({kitInfo.cToolChain, cflags});
rpp.setFlagsForCxx({kitInfo.cxxToolChain, cxxflags});
const QString includeFileBaseDir = projectDirectory().toString();
rpp.setFlagsForC({kitInfo.cToolChain, cflags, includeFileBaseDir});
rpp.setFlagsForCxx({kitInfo.cxxToolChain, cxxflags, includeFileBaseDir});
const QString absSrc = project()->projectDirectory().toString();
BuildConfiguration *bc = target()->activeBuildConfiguration();

View File

@@ -650,10 +650,15 @@ void CMakeBuildSystem::updateProjectData()
for (RawProjectPart &rpp : rpps) {
rpp.setQtVersion(
kitInfo.projectPartQtVersion); // TODO: Check if project actually uses Qt.
if (kitInfo.cxxToolChain)
rpp.setFlagsForCxx({kitInfo.cxxToolChain, rpp.flagsForCxx.commandLineFlags});
if (kitInfo.cToolChain)
rpp.setFlagsForC({kitInfo.cToolChain, rpp.flagsForC.commandLineFlags});
const QString includeFileBaseDir = buildConfiguration()->buildDirectory().toString();
if (kitInfo.cxxToolChain) {
rpp.setFlagsForCxx({kitInfo.cxxToolChain, rpp.flagsForCxx.commandLineFlags,
includeFileBaseDir});
}
if (kitInfo.cToolChain) {
rpp.setFlagsForC({kitInfo.cToolChain, rpp.flagsForC.commandLineFlags,
includeFileBaseDir});
}
}
m_cppCodeModelUpdater->update({p, kitInfo, cmakeBuildConfiguration()->environment(), rpps});

View File

@@ -203,7 +203,7 @@ RawProjectPart makeRawProjectPart(const Utils::FilePath &projectFile,
ProjectExplorer::Constants::C_LANGUAGE_ID);
}
addDriverModeFlagIfNeeded(kitInfo.cToolChain, flags, originalFlags);
rpp.setFlagsForC({kitInfo.cToolChain, flags});
rpp.setFlagsForC({kitInfo.cToolChain, flags, workingDir});
} else {
if (!kitInfo.cxxToolChain) {
kitInfo.cxxToolChain = toolchainFromFlags(kit,
@@ -211,7 +211,7 @@ RawProjectPart makeRawProjectPart(const Utils::FilePath &projectFile,
ProjectExplorer::Constants::CXX_LANGUAGE_ID);
}
addDriverModeFlagIfNeeded(kitInfo.cxxToolChain, flags, originalFlags);
rpp.setFlagsForCxx({kitInfo.cxxToolChain, flags});
rpp.setFlagsForCxx({kitInfo.cxxToolChain, flags, workingDir});
}
return rpp;

View File

@@ -77,6 +77,7 @@ void BuiltinEditorDocumentParser::updateImpl(const QFutureInterface<void> &futur
CppModelManager *modelManager = CppModelManager::instance();
QByteArray configFile = modelManager->codeModelConfiguration();
ProjectExplorer::HeaderPaths headerPaths;
QStringList includedFiles;
QStringList precompiledHeaders;
QString projectConfigFile;
LanguageFeatures features = LanguageFeatures::defaultFeatures();
@@ -102,6 +103,7 @@ void BuiltinEditorDocumentParser::updateImpl(const QFutureInterface<void> &futur
configFile += ProjectPart::readProjectConfigFile(part);
headerPaths = part->headerPaths;
projectConfigFile = part->projectConfigFile;
includedFiles = part->includedFiles;
if (baseConfig.usePrecompiledHeaders)
precompiledHeaders = part->precompiledHeaders;
features = part->languageFeatures;
@@ -129,6 +131,11 @@ void BuiltinEditorDocumentParser::updateImpl(const QFutureInterface<void> &futur
invalidateSnapshot = true;
}
if (includedFiles != state.includedFiles) {
state.includedFiles = includedFiles;
invalidateSnapshot = true;
}
if (precompiledHeaders != state.precompiledHeaders) {
state.precompiledHeaders = precompiledHeaders;
invalidateSnapshot = true;
@@ -212,8 +219,11 @@ void BuiltinEditorDocumentParser::updateImpl(const QFutureInterface<void> &futur
}
if (!baseState.editorDefines.isEmpty())
sourceProcessor.run(editorDefinesFileName);
sourceProcessor.run(filePath(), baseConfig.usePrecompiledHeaders ? state.precompiledHeaders
: QStringList());
QStringList includedFiles = state.includedFiles;
if (baseConfig.usePrecompiledHeaders)
includedFiles << state.precompiledHeaders;
includedFiles.removeDuplicates();
sourceProcessor.run(filePath(), includedFiles);
state.snapshot = sourceProcessor.snapshot();
Snapshot newSnapshot = state.snapshot.simplified(state.snapshot.document(filePath()));
for (Snapshot::const_iterator i = state.snapshot.begin(), ei = state.snapshot.end(); i != ei; ++i) {

View File

@@ -69,6 +69,7 @@ private:
ProjectExplorer::HeaderPaths headerPaths;
QString projectConfigFile;
QStringList includedFiles;
QStringList precompiledHeaders;
CPlusPlus::Snapshot snapshot;

View File

@@ -140,6 +140,7 @@ QStringList CompilerOptionsBuilder::build(ProjectFile::Kind fileKind,
addLanguageVersionAndExtensions();
addMsvcExceptions();
addIncludedFiles(m_projectPart.includedFiles); // GCC adds these before precompiled headers.
addPrecompiledHeaderOptions(usePrecompiledHeaders);
addProjectConfigFileInclude();
@@ -368,6 +369,21 @@ void CompilerOptionsBuilder::addHeaderPathOptions()
}
}
void CompilerOptionsBuilder::addIncludedFiles(const QStringList &files)
{
QStringList result;
const QString includeOptionString
= QLatin1String(isClStyle() ? includeFileOptionCl : includeFileOptionGcc);
for (const QString &file : files) {
if (QFile::exists(file)) {
result += includeOptionString;
result += QDir::toNativeSeparators(file);
}
}
m_options.append(result);
}
void CompilerOptionsBuilder::addPrecompiledHeaderOptions(UsePrecompiledHeaders usePrecompiledHeaders)
{
for (const QString &pchFile : m_projectPart.precompiledHeaders) {
@@ -830,6 +846,12 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
continue;
}
// These were already parsed into ProjectPart::includedFiles.
if (option == includeFileOptionCl || option == includeFileOptionGcc) {
skipNext = true;
continue;
}
if (option.startsWith("/Y", Qt::CaseSensitive)
|| (option.startsWith("/F", Qt::CaseSensitive) && option != "/F")) {
// Precompiled header flags.

View File

@@ -62,6 +62,7 @@ public:
void addWordWidth();
void addHeaderPathOptions();
void addPrecompiledHeaderOptions(UsePrecompiledHeaders usePrecompiledHeaders);
void addIncludedFiles(const QStringList &files);
void addMacros(const ProjectExplorer::Macros &macros);
void addTargetTriple();

View File

@@ -106,6 +106,7 @@ static ProjectPart::Ptr projectPartFromRawProjectPart(
}
part->precompiledHeaders = rawProjectPart.precompiledHeaders;
part->includedFiles = rawProjectPart.includedFiles;
part->selectedForBuilding = rawProjectPart.selectedForBuilding;
return part;
@@ -205,6 +206,11 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(
part->extraCodeModelFlags = tcInfo.extraCodeModelFlags;
part->compilerFlags = flags.commandLineFlags;
part->warningFlags = flags.warningFlags;
if (part->includedFiles.isEmpty()) {
// The project manager did not provide the included files, so take
// the ones we were able to detect from the toolchain's command line.
part->includedFiles = flags.includedFiles;
}
part->language = language;
part->languageExtensions = flags.languageExtensions;

View File

@@ -87,6 +87,7 @@ public:
// Files
ProjectFiles files;
QStringList includedFiles;
QStringList precompiledHeaders;
ProjectExplorer::HeaderPaths headerPaths;
QString projectConfigFile; // Generic Project Manager only

View File

@@ -562,8 +562,8 @@ void GenericBuildSystem::refreshCppCodeModel()
rpp.setQtVersion(kitInfo.projectPartQtVersion);
rpp.setHeaderPaths(m_projectIncludePaths);
rpp.setConfigFileName(m_configFileName);
rpp.setFlagsForCxx({nullptr, m_cxxflags});
rpp.setFlagsForC({nullptr, m_cflags});
rpp.setFlagsForCxx({nullptr, m_cxxflags, projectDirectory().toString()});
rpp.setFlagsForC({nullptr, m_cflags, projectDirectory().toString()});
rpp.setFiles(m_files);
m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), {rpp}});

View File

@@ -285,9 +285,9 @@ ProjectExplorer::RawProjectPart MesonProjectParser::buildRawPart(
part.setIncludePaths(toAbsolutePath(m_buildDir, flags.includePaths));
part.setProjectFileLocation(target.definedIn);
if (sources.language == "cpp")
part.setFlagsForCxx({cxxToolChain, flags.args});
part.setFlagsForCxx({cxxToolChain, flags.args, {}});
else if (sources.language == "c")
part.setFlagsForC({cToolChain, flags.args});
part.setFlagsForC({cToolChain, flags.args, {}});
part.setQtVersion(m_qtVersion);
return part;
}

View File

@@ -564,6 +564,11 @@ WarningFlags GccToolChain::warningFlags(const QStringList &cflags) const
return flags;
}
QStringList GccToolChain::includedFiles(const QStringList &flags, const QString &directoryPath) const
{
return ToolChain::includedFiles("-include", flags, directoryPath);
}
QStringList GccToolChain::gccPrepareArguments(const QStringList &flags,
const QString &sysRoot,
const QStringList &platformCodeGenFlags,

View File

@@ -82,6 +82,8 @@ public:
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override;
Utils::WarningFlags warningFlags(const QStringList &cflags) const override;
QStringList includedFiles(const QStringList &flags,
const QString &directoryPath) const override;
MacroInspectionRunner createMacroInspectionRunner() const override;
Macros predefinedMacros(const QStringList &cxxflags) const override;

View File

@@ -1070,6 +1070,12 @@ WarningFlags MsvcToolChain::warningFlags(const QStringList &cflags) const
return flags;
}
QStringList MsvcToolChain::includedFiles(const QStringList &flags,
const QString &directoryPath) const
{
return ToolChain::includedFiles("/FI", flags, directoryPath);
}
ToolChain::BuiltInHeaderPathsRunner MsvcToolChain::createBuiltInHeaderPathsRunner(
const Environment &env) const
{

View File

@@ -80,6 +80,8 @@ public:
Macros predefinedMacros(const QStringList &cxxflags) const override;
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override;
Utils::WarningFlags warningFlags(const QStringList &cflags) const override;
QStringList includedFiles(const QStringList &flags,
const QString &directoryPath) const override;
BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(
const Utils::Environment &env) const override;
HeaderPaths builtInHeaderPaths(const QStringList &cxxflags,

View File

@@ -36,7 +36,8 @@
namespace ProjectExplorer {
RawProjectPartFlags::RawProjectPartFlags(const ToolChain *toolChain,
const QStringList &commandLineFlags)
const QStringList &commandLineFlags,
const QString &includeFileBaseDir)
{
// Keep the following cheap/non-blocking for the ui thread. Expensive
// operations are encapsulated in ToolChainInfo as "runners".
@@ -44,6 +45,7 @@ RawProjectPartFlags::RawProjectPartFlags(const ToolChain *toolChain,
if (toolChain) {
warningFlags = toolChain->warningFlags(commandLineFlags);
languageExtensions = toolChain->languageExtensions(commandLineFlags);
includedFiles = toolChain->includedFiles(commandLineFlags, includeFileBaseDir);
}
}
@@ -130,6 +132,11 @@ void RawProjectPart::setPreCompiledHeaders(const QStringList &preCompiledHeaders
this->precompiledHeaders = preCompiledHeaders;
}
void RawProjectPart::setIncludedFiles(const QStringList &files)
{
includedFiles = files;
}
void RawProjectPart::setSelectedForBuilding(bool yesno)
{
this->selectedForBuilding = yesno;

View File

@@ -50,13 +50,15 @@ class PROJECTEXPLORER_EXPORT RawProjectPartFlags
{
public:
RawProjectPartFlags() = default;
RawProjectPartFlags(const ToolChain *toolChain, const QStringList &commandLineFlags);
RawProjectPartFlags(const ToolChain *toolChain, const QStringList &commandLineFlags,
const QString &includeFileBaseDir);
public:
QStringList commandLineFlags;
// The following are deduced from commandLineFlags.
Utils::WarningFlags warningFlags = Utils::WarningFlags::Default;
Utils::LanguageExtensions languageExtensions = Utils::LanguageExtension::None;
QStringList includedFiles;
};
class PROJECTEXPLORER_EXPORT RawProjectPart
@@ -78,6 +80,7 @@ public:
void setHeaderPaths(const HeaderPaths &headerPaths);
void setIncludePaths(const QStringList &includePaths);
void setPreCompiledHeaders(const QStringList &preCompiledHeaders);
void setIncludedFiles(const QStringList &files);
void setBuildSystemTarget(const QString &target);
void setBuildTargetType(BuildTargetType type);
@@ -102,6 +105,7 @@ public:
FileIsActive fileIsActive;
GetMimeType getMimeType;
QStringList precompiledHeaders;
QStringList includedFiles;
HeaderPaths headerPaths;
QString projectConfigFile; // Generic Project Manager only

View File

@@ -35,6 +35,8 @@
#include <utils/qtcassert.h>
#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QUuid>
static const char ID_KEY[] = "ProjectExplorer.ToolChain.Id";
@@ -185,6 +187,13 @@ Abis ToolChain::supportedAbis() const
return {targetAbi()};
}
QStringList ToolChain::includedFiles(const QStringList &flags, const QString &directory) const
{
Q_UNUSED(flags)
Q_UNUSED(directory)
return {};
}
Utils::Id ToolChain::language() const
{
return d->m_language;
@@ -389,6 +398,24 @@ Utils::LanguageVersion ToolChain::languageVersion(const Utils::Id &language, con
}
}
QStringList ToolChain::includedFiles(const QString &option,
const QStringList &flags,
const QString &directoryPath)
{
QStringList result;
for (int i = 0; i < flags.size(); ++i) {
if (flags[i] == option && i + 1 < flags.size()) {
QString includeFile = flags[++i];
if (!QFileInfo(includeFile).isAbsolute())
includeFile = directoryPath + "/" + includeFile;
result.append(QDir::cleanPath(includeFile));
}
}
return result;
}
/*!
Used by the tool chain kit information to validate the kit.
*/

View File

@@ -119,6 +119,7 @@ public:
virtual Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const = 0;
virtual Utils::WarningFlags warningFlags(const QStringList &cflags) const = 0;
virtual QStringList includedFiles(const QStringList &flags, const QString &directory) const;
virtual QString sysRoot() const;
class MacroInspectionReport
@@ -182,6 +183,10 @@ protected:
// Make sure to call this function when deriving!
virtual bool fromMap(const QVariantMap &data);
static QStringList includedFiles(const QString &option,
const QStringList &flags,
const QString &directoryPath);
private:
ToolChain(const ToolChain &) = delete;
ToolChain &operator=(const ToolChain &) = delete;

View File

@@ -888,8 +888,8 @@ static RawProjectParts generateProjectParts(
QStringList cFlags;
QStringList cxxFlags;
getExpandedCompilerFlags(cFlags, cxxFlags, props);
rpp.setFlagsForC({cToolChain.get(), cFlags});
rpp.setFlagsForCxx({cxxToolChain.get(), cxxFlags});
rpp.setFlagsForC({cToolChain.get(), cFlags, {}});
rpp.setFlagsForCxx({cxxToolChain.get(), cxxFlags, {}});
const QStringList defines = arrayToStringList(props.value("cpp.defines"))
+ arrayToStringList(props.value("cpp.platformDefines"));
@@ -978,6 +978,7 @@ static RawProjectParts generateProjectParts(
qCWarning(qbsPmLog) << "Expect problems with code model";
}
rpp.setPreCompiledHeaders(Utils::toList(pchFiles));
rpp.setIncludedFiles(arrayToStringList(props.value("cpp.prefixHeaders")));
rpp.setFiles(filePathToSourceArtifact.keys(), {},
[filePathToSourceArtifact](const QString &filePath) {
// Keep this lambda thread-safe!

View File

@@ -351,8 +351,11 @@ void QmakeBuildSystem::updateCppCodeModel()
rpp.setBuildTargetType(BuildTargetType::Unknown);
break;
}
rpp.setFlagsForCxx({kitInfo.cxxToolChain, pro->variableValue(Variable::CppFlags)});
rpp.setFlagsForC({kitInfo.cToolChain, pro->variableValue(Variable::CFlags)});
const QString includeFileBaseDir = pro->sourceDir().toString();
rpp.setFlagsForCxx({kitInfo.cxxToolChain, pro->variableValue(Variable::CppFlags),
includeFileBaseDir});
rpp.setFlagsForC({kitInfo.cToolChain, pro->variableValue(Variable::CFlags),
includeFileBaseDir});
rpp.setMacros(ProjectExplorer::Macro::toMacros(pro->cxxDefines()));
rpp.setPreCompiledHeaders(pro->variableValue(Variable::PrecompiledHeader));
rpp.setSelectedForBuilding(pro->includedInExactParse());