Commit 86bad1f2 authored by Kevin Funk's avatar Kevin Funk

clang: Also detect Clang builtin dirs at runtime

CCBUG: 393779
parent 978b224b
......@@ -176,8 +176,12 @@ ClangSupport::ClangSupport(QObject* parent, const QVariantList& )
, m_refactoring(nullptr)
, m_index(nullptr)
{
clangDebug() << "Detected Clang version:" << ClangHelpers::clangVersion();
{
const auto builtinDir = ClangIntegration::DUChainUtils::clangBuiltinIncludePath();
const auto builtinDir = ClangHelpers::clangBuiltinIncludePath();
clangDebug() << "Using Clang builtin include path:" << builtinDir;
const auto headerToCheck = QLatin1String("cpuid.h");
if (!QFile::exists(builtinDir + QLatin1Char('/') + headerToCheck)) {
setErrorDescription(i18n("The clang builtin include path \"%1\" is invalid (missing %2 header).\n"
......
......@@ -32,11 +32,15 @@
#include "clangparsingenvironmentfile.h"
#include "clangindex.h"
#include "clangducontext.h"
#include "util/clangdebug.h"
#include "util/clangtypes.h"
#include "libclang_include_path.h"
#include <QCoreApplication>
#include <QFileInfo>
#include <QRegularExpression>
#include <algorithm>
using namespace KDevelop;
......@@ -343,14 +347,48 @@ bool ClangHelpers::isHeader(const QString& path)
[&](const QString& ext) { return path.endsWith(ext); });
}
QString ClangHelpers::clangVersion()
{
static const auto clangVersion = []() -> QString {
// NOTE: The apidocs for clang_getClangVersion() clearly state it shouldn't be used for parsing
// but there's no other way to retrieve the Clang version at runtime at this point...
const ClangString version(clang_getClangVersion());
clangDebug() << "Full Clang version:" << version;
// samples:
// clang version 6.0.1 (trunk 321709) (git@github.com:llvm-mirror/llvm.git 5136df4d089a086b70d452160ad5451861269498)
// clang version 7.0.0-svn341916-1~exp1~20180911115939.26 (branches/release_70)
QRegularExpression re(QStringLiteral("^clang version (\\d+\\.\\d+\\.\\d+)"));
const auto match = re.match(version.toString());
if (!match.hasMatch())
return {};
return match.captured(1); // return e.g. 7.0.0
}();
return clangVersion;
}
QString ClangHelpers::clangBuiltinIncludePath()
{
static const auto dir = []() -> QString {
auto dir = qgetenv("KDEV_CLANG_BUILTIN_DIR");
if (dir.isEmpty()) {
dir = KDEV_CLANG_BUILTIN_DIR;
auto dir = QString::fromUtf8(qgetenv("KDEV_CLANG_BUILTIN_DIR"));
if (!dir.isEmpty()) {
clangDebug() << "Using dir from $KDEV_CLANG_BUILTIN_DIR:" << dir;
return dir;
}
#ifdef Q_OS_WIN32
// attempt to use the bundled copy on Windows
dir = QStringLiteral("%1/../lib/clang/%2/include")
.arg(QCoreApplication::applicationDirPath(), clangVersion());
clangDebug() << "Trying" << dir;
if (QFileInfo(dir).isDir()) {
return dir;
}
return QString::fromUtf8(dir);
#endif
clangDebug() << "Using builtin dir:" << KDEV_CLANG_BUILTIN_DIR;
return QString::fromUtf8(KDEV_CLANG_BUILTIN_DIR);
}();
return dir;
}
......@@ -100,6 +100,8 @@ KDEVCLANGPRIVATE_EXPORT bool isSource(const QString& path);
*/
KDEVCLANGPRIVATE_EXPORT bool isHeader(const QString& path);
KDEVCLANGPRIVATE_EXPORT QString clangVersion();
/**
* @return The path containing Clang built includes (e.g. stddef.h, stdarg.h, cpuid.h)
*
......
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