Commit f3a2795c authored by Orgad Shaneh's avatar Orgad Shaneh Committed by Orgad Shaneh

C++: Use correct features for document parsing

Task-number: QTCREATORBUG-8007
Change-Id: Ic96aaa433442812a99bac9d16bb9124d66762e8c
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@theqtcompany.com>
parent 97cbfb95
......@@ -396,6 +396,12 @@ public:
struct LanguageFeatures
{
LanguageFeatures() : flags(0) {}
static LanguageFeatures defaultFeatures()
{
LanguageFeatures features;
features.flags = 0xffffffff; // Enable all flags
return features;
}
union {
unsigned int flags;
......
......@@ -283,15 +283,8 @@ Document::Document(const QString &fileName)
const QByteArray localFileName = fileName.toUtf8();
const StringLiteral *fileId = _control->stringLiteral(localFileName.constData(),
localFileName.size());
LanguageFeatures features;
features.qtEnabled = true;
features.qtMocRunEnabled = true;
features.qtKeywordsEnabled = true;
features.cxx11Enabled = true;
features.objCEnabled = true;
features.c99Enabled = true;
_translationUnit = new TranslationUnit(_control, fileId);
_translationUnit->setLanguageFeatures(features);
_translationUnit->setLanguageFeatures(LanguageFeatures::defaultFeatures());
(void) _control->switchTranslationUnit(_translationUnit);
}
......@@ -596,6 +589,19 @@ void Document::setUtf8Source(const QByteArray &source)
_translationUnit->setSource(_source.constBegin(), _source.size());
}
LanguageFeatures Document::languageFeatures() const
{
if (TranslationUnit *tu = translationUnit())
return tu->languageFeatures();
return LanguageFeatures::defaultFeatures();
}
void Document::setLanguageFeatures(LanguageFeatures features)
{
if (TranslationUnit *tu = translationUnit())
tu->setLanguageFeatures(features);
}
void Document::startSkippingBlocks(unsigned utf16charsOffset)
{
_skippedBlocks.append(Block(0, 0, utf16charsOffset, 0));
......@@ -767,6 +773,7 @@ Document::Ptr Snapshot::preprocessedDocument(const QByteArray &source,
newDoc->_lastModified = thisDocument->_lastModified;
newDoc->_resolvedIncludes = thisDocument->_resolvedIncludes;
newDoc->_unresolvedIncludes = thisDocument->_unresolvedIncludes;
newDoc->setLanguageFeatures(thisDocument->languageFeatures());
}
FastPreprocessor pp(*this);
......@@ -788,6 +795,7 @@ Document::Ptr Snapshot::documentFromSource(const QByteArray &preprocessedCode,
newDoc->_unresolvedIncludes = thisDocument->_unresolvedIncludes;
newDoc->_definedMacros = thisDocument->_definedMacros;
newDoc->_macroUses = thisDocument->_macroUses;
newDoc->setLanguageFeatures(thisDocument->languageFeatures());
}
newDoc->setUtf8Source(preprocessedCode);
......
......@@ -115,6 +115,9 @@ public:
void setFingerprint(const QByteArray &fingerprint)
{ m_fingerprint = fingerprint; }
LanguageFeatures languageFeatures() const;
void setLanguageFeatures(LanguageFeatures features);
void startSkippingBlocks(unsigned utf16charsOffset);
void stopSkippingBlocks(unsigned utf16charsOffset);
......
......@@ -304,6 +304,7 @@ void PchManager::doPchInfoUpdateFuzzy(QFutureInterface<void> &future,
projectPart->languageVersion = languageVersions[pch];
projectPart->languageExtensions = languageExtensionsMap[pch];
projectPart->headerPaths = headers[pch].toList();
projectPart->updateLanguageFeatures();
QList<QByteArray> defines = definesPerPCH[pch].toList();
if (!defines.isEmpty()) {
......@@ -386,6 +387,7 @@ void PchManager::doPchInfoUpdateCustom(QFutureInterface<void> &future,
objc |= hasObjCFiles(projectPart);
cplusplus |= hasCppFiles(projectPart);
}
united->updateLanguageFeatures();
united->headerPaths = headers;
QStringList opts = Utils::createClangOptions(
united, getPrefixFileKind(objc, cplusplus));
......
......@@ -60,6 +60,7 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
ProjectPart::HeaderPaths headerPaths;
QStringList precompiledHeaders;
QString projectConfigFile;
LanguageFeatures features = LanguageFeatures::defaultFeatures();
updateProjectPart();
......@@ -75,6 +76,7 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
projectConfigFile = part->projectConfigFile;
if (usePrecompiledHeaders())
precompiledHeaders = part->precompiledHeaders;
features = part->languageFeatures;
}
if (configFile != m_configFile) {
......@@ -169,6 +171,7 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
sourceProcessor.setGlobalSnapshot(globalSnapshot);
sourceProcessor.setWorkingCopy(workingCopy);
sourceProcessor.setHeaderPaths(m_headerPaths);
sourceProcessor.setLanguageFeatures(features);
sourceProcessor.run(configurationFileName);
if (!m_projectConfigFile.isEmpty())
sourceProcessor.run(m_projectConfigFile);
......
......@@ -208,6 +208,8 @@ void index(QFutureInterface<void> &future, const ParseParams params)
CppModelManager *cmm = CppModelManager::instance();
const ProjectPart::HeaderPaths fallbackHeaderPaths = cmm->headerPaths();
const CPlusPlus::LanguageFeatures defaultFeatures =
CPlusPlus::LanguageFeatures::defaultFeatures();
for (int i = 0; i < files.size(); ++i) {
if (future.isPaused())
future.waitForResume();
......@@ -216,6 +218,11 @@ void index(QFutureInterface<void> &future, const ParseParams params)
break;
const QString fileName = files.at(i);
const QList<ProjectPart::Ptr> parts = cmm->projectPart(fileName);
const CPlusPlus::LanguageFeatures languageFeatures = parts.isEmpty()
? defaultFeatures
: parts.first()->languageFeatures;
sourceProcessor->setLanguageFeatures(languageFeatures);
const bool isSourceFile = i < sourceCount;
if (isSourceFile) {
......@@ -226,7 +233,6 @@ void index(QFutureInterface<void> &future, const ParseParams params)
processingHeaders = true;
}
QList<ProjectPart::Ptr> parts = cmm->projectPart(fileName);
ProjectPart::HeaderPaths headerPaths = parts.isEmpty()
? fallbackHeaderPaths
: parts.first()->headerPaths;
......
......@@ -840,6 +840,7 @@ ProjectPart::Ptr CppModelManager::fallbackProjectPart() const
part->languageVersion = ProjectPart::CXX14;
part->languageExtensions = ProjectPart::AllExtensions;
part->qtVersion = ProjectPart::Qt5;
part->updateLanguageFeatures();
return part;
}
......
......@@ -108,6 +108,29 @@ void ProjectPart::evaluateToolchain(const ToolChain *tc,
}
toolchainDefines = tc->predefinedMacros(commandLineFlags);
updateLanguageFeatures();
}
void ProjectPart::updateLanguageFeatures()
{
const bool hasQt = qtVersion != NoQt;
languageFeatures.cxx11Enabled = languageVersion >= CXX11;
languageFeatures.qtEnabled = hasQt;
languageFeatures.qtMocRunEnabled = hasQt;
if (!hasQt) {
languageFeatures.qtKeywordsEnabled = false;
} else {
const QByteArray noKeywordsMacro = "#define QT_NO_KEYWORDS";
const int noKeywordsIndex = projectDefines.indexOf(noKeywordsMacro);
if (noKeywordsIndex == -1) {
languageFeatures.qtKeywordsEnabled = true;
} else {
const char nextChar = projectDefines.at(noKeywordsIndex + noKeywordsMacro.length());
// Detect "#define QT_NO_KEYWORDS" and "#define QT_NO_KEYWORDS 1", but exclude
// "#define QT_NO_KEYWORDS_FOO"
languageFeatures.qtKeywordsEnabled = nextChar != '\n' && nextChar != ' ';
}
}
}
ProjectPart::Ptr ProjectPart::copy() const
......@@ -198,6 +221,7 @@ void ProjectInfo::finish()
QSet<HeaderPath> incs;
foreach (const ProjectPart::Ptr &part, m_projectParts) {
part->updateLanguageFeatures();
// Update header paths
foreach (const HeaderPath &hp, part->headerPaths) {
if (!incs.contains(hp)) {
......
......@@ -38,6 +38,8 @@
#include <projectexplorer/project.h>
#include <projectexplorer/toolchain.h>
#include <cplusplus/Token.h>
#include <QPointer>
#include <QSet>
......@@ -109,6 +111,7 @@ public: // methods
const QStringList &commandLineFlags,
const Utils::FileName &sysRoot);
void updateLanguageFeatures();
Ptr copy() const;
QString id() const;
......@@ -127,6 +130,7 @@ public: // fields
QStringList precompiledHeaders;
LanguageVersion languageVersion;
LanguageExtensions languageExtensions;
CPlusPlus::LanguageFeatures languageFeatures;
QtVersion qtVersion;
ProjectExplorer::ToolChain::WarningFlags warningFlags;
bool selectedForBuilding;
......
......@@ -116,6 +116,7 @@ CppSourceProcessor::CppSourceProcessor(const Snapshot &snapshot, DocumentCallbac
: m_snapshot(snapshot),
m_documentFinished(documentFinished),
m_preprocess(this, &m_env),
m_languageFeatures(LanguageFeatures::defaultFeatures()),
m_revision(0),
m_defaultCodec(Core::EditorManager::defaultTextCodec())
{
......@@ -145,6 +146,11 @@ void CppSourceProcessor::setHeaderPaths(const ProjectPart::HeaderPaths &headerPa
}
}
void CppSourceProcessor::setLanguageFeatures(const LanguageFeatures languageFeatures)
{
m_languageFeatures = languageFeatures;
}
// Add the given framework path, and expand private frameworks.
//
// Example:
......@@ -466,6 +472,7 @@ void CppSourceProcessor::sourceNeeded(unsigned line, const QString &fileName, In
Document::Ptr document = Document::create(absoluteFileName);
document->setRevision(m_revision);
document->setEditorRevision(editorRevision);
document->setLanguageFeatures(m_languageFeatures);
foreach (const QString &include, initialIncludes) {
m_included.insert(include);
Document::Include inc(include, include, 0, IncludeLocal);
......
......@@ -68,6 +68,7 @@ public:
void setRevision(unsigned revision);
void setWorkingCopy(const CppTools::WorkingCopy &workingCopy);
void setHeaderPaths(const ProjectPart::HeaderPaths &headerPaths);
void setLanguageFeatures(CPlusPlus::LanguageFeatures languageFeatures);
void setTodo(const QSet<QString> &files);
void run(const QString &fileName, const QStringList &initialIncludes = QStringList());
......@@ -117,6 +118,7 @@ private:
CPlusPlus::Environment m_env;
CPlusPlus::Preprocessor m_preprocess;
ProjectPart::HeaderPaths m_headerPaths;
CPlusPlus::LanguageFeatures m_languageFeatures;
CppTools::WorkingCopy m_workingCopy;
QSet<QString> m_included;
CPlusPlus::Document::Ptr m_currentDoc;
......
......@@ -538,6 +538,8 @@ void QmakeProject::updateCppCodeModel()
// part->precompiledHeaders
templatePart->precompiledHeaders.append(pro->variableValue(PrecompiledHeaderVar));
templatePart->updateLanguageFeatures();
ProjectPart::Ptr cppPart = templatePart->copy();
{ // C++ files:
// part->files
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment