summaryrefslogtreecommitdiff
path: root/src/plugins/cpptools/compileroptionsbuilder.cpp
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@theqtcompany.com>2016-01-11 21:09:06 +0100
committerMarco Bubke <marco.bubke@theqtcompany.com>2016-01-13 14:47:20 +0000
commit68bd9a881f731b0879961eaad06227f5642d0b5a (patch)
tree19ff671ae3e9721f5f4d16dd3bfa9e2a33ad8478 /src/plugins/cpptools/compileroptionsbuilder.cpp
parent1ae509541c1b453463005ddf89170c0978f8d378 (diff)
downloadqt-creator-68bd9a881f731b0879961eaad06227f5642d0b5a.tar.gz
CppTools: Moving CompilerOptionsBuilder in its own header file
Change-Id: I503ffd72a98db6668f6449ce95e695e035a79a29 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
Diffstat (limited to 'src/plugins/cpptools/compileroptionsbuilder.cpp')
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.cpp261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp
new file mode 100644
index 0000000000..8ab04352e0
--- /dev/null
+++ b/src/plugins/cpptools/compileroptionsbuilder.cpp
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "compileroptionsbuilder.h"
+
+#include <projectexplorer/projectexplorerconstants.h>
+
+namespace CppTools {
+
+CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart)
+ : m_projectPart(projectPart)
+{
+}
+
+QStringList CompilerOptionsBuilder::options() const
+{
+ return m_options;
+}
+
+void CompilerOptionsBuilder::add(const QString &option)
+{
+ m_options.append(option);
+}
+
+QString CompilerOptionsBuilder::defineLineToDefineOption(const QByteArray &defineLine)
+{
+ QByteArray str = defineLine.mid(8);
+ int spaceIdx = str.indexOf(' ');
+ const QString option = defineOption();
+ const bool hasValue = spaceIdx != -1;
+ QString arg = option + QLatin1String(str.left(hasValue ? spaceIdx : str.size()) + '=');
+ if (hasValue)
+ arg += QLatin1String(str.mid(spaceIdx + 1));
+ return arg;
+}
+
+void CompilerOptionsBuilder::addDefine(const QByteArray &defineLine)
+{
+ m_options.append(defineLineToDefineOption(defineLine));
+}
+
+void CompilerOptionsBuilder::addHeaderPathOptions()
+{
+ typedef ProjectPartHeaderPath HeaderPath;
+ const QString defaultPrefix = includeOption();
+
+ QStringList result;
+
+ foreach (const HeaderPath &headerPath , m_projectPart.headerPaths) {
+ if (headerPath.path.isEmpty())
+ continue;
+
+ if (excludeHeaderPath(headerPath.path))
+ continue;
+
+ QString prefix;
+ switch (headerPath.type) {
+ case HeaderPath::FrameworkPath:
+ prefix = QLatin1String("-F");
+ break;
+ default: // This shouldn't happen, but let's be nice..:
+ // intentional fall-through:
+ case HeaderPath::IncludePath:
+ prefix = defaultPrefix;
+ break;
+ }
+
+ result.append(prefix + headerPath.path);
+ }
+
+ m_options.append(result);
+}
+
+void CompilerOptionsBuilder::addToolchainAndProjectDefines()
+{
+ QByteArray extendedDefines = m_projectPart.toolchainDefines + m_projectPart.projectDefines;
+ QStringList result;
+
+ foreach (QByteArray def, extendedDefines.split('\n')) {
+ if (def.isEmpty() || excludeDefineLine(def))
+ continue;
+
+ const QString defineOption = defineLineToDefineOption(def);
+ if (!result.contains(defineOption))
+ result.append(defineOption);
+ }
+
+ m_options.append(result);
+}
+
+static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt)
+{
+ QStringList opts;
+
+ switch (fileKind) {
+ case ProjectFile::Unclassified:
+ break;
+ case ProjectFile::CHeader:
+ if (objcExt)
+ opts += QLatin1String("objective-c-header");
+ else
+ opts += QLatin1String("c-header");
+ break;
+
+ case ProjectFile::CXXHeader:
+ default:
+ if (!objcExt) {
+ opts += QLatin1String("c++-header");
+ break;
+ } // else: fall-through!
+ case ProjectFile::ObjCHeader:
+ case ProjectFile::ObjCXXHeader:
+ opts += QLatin1String("objective-c++-header");
+ break;
+
+ case ProjectFile::CSource:
+ if (!objcExt) {
+ opts += QLatin1String("c");
+ break;
+ } // else: fall-through!
+ case ProjectFile::ObjCSource:
+ opts += QLatin1String("objective-c");
+ break;
+
+ case ProjectFile::CXXSource:
+ if (!objcExt) {
+ opts += QLatin1String("c++");
+ break;
+ } // else: fall-through!
+ case ProjectFile::ObjCXXSource:
+ opts += QLatin1String("objective-c++");
+ break;
+
+ case ProjectFile::OpenCLSource:
+ opts += QLatin1String("cl");
+ break;
+ case ProjectFile::CudaSource:
+ opts += QLatin1String("cuda");
+ break;
+ }
+
+ if (!opts.isEmpty())
+ opts.prepend(QLatin1String("-x"));
+
+ return opts;
+}
+
+void CompilerOptionsBuilder::addLanguageOption(ProjectFile::Kind fileKind)
+{
+ const bool objcExt = m_projectPart.languageExtensions & ProjectPart::ObjectiveCExtensions;
+ const QStringList options = createLanguageOptionGcc(fileKind, objcExt);
+ m_options.append(options);
+}
+
+void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtensions)
+{
+ QStringList opts;
+ const ProjectPart::LanguageExtensions languageExtensions = m_projectPart.languageExtensions;
+ const bool gnuExtensions = languageExtensions & ProjectPart::GnuExtensions;
+ switch (m_projectPart.languageVersion) {
+ case ProjectPart::C89:
+ opts << (gnuExtensions ? QLatin1String("-std=gnu89") : QLatin1String("-std=c89"));
+ break;
+ case ProjectPart::C99:
+ opts << (gnuExtensions ? QLatin1String("-std=gnu99") : QLatin1String("-std=c99"));
+ break;
+ case ProjectPart::C11:
+ opts << (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11"));
+ break;
+ case ProjectPart::CXX11:
+ opts << (gnuExtensions ? QLatin1String("-std=gnu++11") : QLatin1String("-std=c++11"));
+ break;
+ case ProjectPart::CXX98:
+ opts << (gnuExtensions ? QLatin1String("-std=gnu++98") : QLatin1String("-std=c++98"));
+ break;
+ case ProjectPart::CXX03:
+ // Clang 3.6 does not know -std=gnu++03.
+ opts << QLatin1String("-std=c++03");
+ break;
+ case ProjectPart::CXX14:
+ opts << (gnuExtensions ? QLatin1String("-std=gnu++14") : QLatin1String("-std=c++14"));
+ break;
+ case ProjectPart::CXX17:
+ // TODO: Change to (probably) "gnu++17"/"c++17" at some point in the future.
+ opts << (gnuExtensions ? QLatin1String("-std=gnu++1z") : QLatin1String("-std=c++1z"));
+ break;
+ }
+
+ if (languageExtensions & ProjectPart::MicrosoftExtensions)
+ opts << QLatin1String("-fms-extensions");
+
+ if (checkForBorlandExtensions && (languageExtensions & ProjectPart::BorlandExtensions))
+ opts << QLatin1String("-fborland-extensions");
+
+ m_options.append(opts);
+}
+
+QString CompilerOptionsBuilder::includeOption() const
+{
+ return QLatin1String("-I");
+}
+
+QString CompilerOptionsBuilder::defineOption() const
+{
+ return QLatin1String("-D");
+}
+
+bool CompilerOptionsBuilder::excludeDefineLine(const QByteArray &defineLine) const
+{
+ // This is a quick fix for QTCREATORBUG-11501.
+ // TODO: do a proper fix, see QTCREATORBUG-11709.
+ if (defineLine.startsWith("#define __cplusplus"))
+ return true;
+
+ // gcc 4.9 has:
+ // #define __has_include(STR) __has_include__(STR)
+ // #define __has_include_next(STR) __has_include_next__(STR)
+ // The right-hand sides are gcc built-ins that clang does not understand, and they'd
+ // override clang's own (non-macro, it seems) definitions of the symbols on the left-hand
+ // side.
+ const bool isGccToolchain = m_projectPart.toolchainType == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID;
+ if (isGccToolchain && defineLine.contains("has_include"))
+ return true;
+
+ return false;
+}
+
+bool CompilerOptionsBuilder::excludeHeaderPath(const QString &headerPath) const
+{
+ Q_UNUSED(headerPath);
+ return false;
+}
+
+} // namespace CppTools