Changeset View
Standalone View
plugins/clang/duchain/clanghelpers.cpp
Show First 20 Lines • Show All 363 Lines • ▼ Show 20 Line(s) | 353 | static const auto clangVersion = []() -> QString { | |||
---|---|---|---|---|---|
364 | if (!match.hasMatch()) | 364 | if (!match.hasMatch()) | ||
365 | return {}; | 365 | return {}; | ||
366 | 366 | | |||
367 | return match.captured(1); // return e.g. 7.0.0 | 367 | return match.captured(1); // return e.g. 7.0.0 | ||
368 | }(); | 368 | }(); | ||
369 | return clangVersion; | 369 | return clangVersion; | ||
370 | } | 370 | } | ||
371 | 371 | | |||
372 | bool ClangHelpers::isValidClangBuiltingIncludePath(const QString& path) | ||||
373 | { | ||||
374 | return QFile::exists(path + QLatin1String("/cpuid.h")); | ||||
375 | } | ||||
376 | | ||||
372 | QString ClangHelpers::clangBuiltinIncludePath() | 377 | QString ClangHelpers::clangBuiltinIncludePath() | ||
373 | { | 378 | { | ||
379 | // use a lambda to store the result in a static variable which can be | ||||
380 | // returned without recomputing the string on subsequent calls. | ||||
374 | static const auto dir = []() -> QString { | 381 | static const auto dir = []() -> QString { | ||
mwolff: the lambda is there to store the result in the `static const` value that will be returned. we… | |||||
Now why does that remind me of the obfuscated C contests of old? :) I'll add a comment so others won't make the same mistake. rjvbb: Now why does that remind me of the obfuscated C contests of old? :)
I'll add a comment so… | |||||
375 | auto dir = QString::fromUtf8(qgetenv("KDEV_CLANG_BUILTIN_DIR")); | 382 | auto dir = QString::fromUtf8(qgetenv("KDEV_CLANG_BUILTIN_DIR")); | ||
376 | if (!dir.isEmpty()) { | 383 | if (!dir.isEmpty() && isValidClangBuiltingIncludePath(dir)) { | ||
377 | clangDebug() << "Using dir from $KDEV_CLANG_BUILTIN_DIR:" << dir; | 384 | clangDebug() << "Using dir from $KDEV_CLANG_BUILTIN_DIR:" << dir; | ||
378 | return dir; | 385 | return dir; | ||
379 | } | 386 | } | ||
380 | 387 | | |||
381 | #ifdef Q_OS_WIN32 | 388 | #ifdef Q_OS_WIN32 | ||
382 | // attempt to use the bundled copy on Windows | 389 | // attempt to use the bundled copy on Windows | ||
383 | dir = QDir::cleanPath(QStringLiteral("%1/../lib/clang/%2/include") | 390 | dir = QDir::cleanPath(QStringLiteral("%1/../lib/clang/%2/include") | ||
384 | .arg(QCoreApplication::applicationDirPath(), clangVersion())); | 391 | .arg(QCoreApplication::applicationDirPath(), clangVersion())); | ||
385 | clangDebug() << "Trying" << dir; | 392 | if (isValidClangBuiltingIncludePath(dir)) { | ||
386 | if (QFileInfo(dir).isDir()) { | 393 | clangDebug() << "Using builtin dir:" << dir; | ||
394 | return dir; | ||||
395 | } | ||||
396 | #elif defined(Q_OS_UNIX) | ||||
397 | // a clang version upgrade since we were last built can | ||||
398 | // cause problems if the "clang/$fullversion/include" path component | ||||
399 | // changed. Try to generate the correct builtin_dir for the current | ||||
400 | // major.minor.patchlevel version: pop the last 2 components then | ||||
401 | // chdir through with the updated version directory. | ||||
402 | dir = QDir::cleanPath(QStringLiteral(KDEV_CLANG_BUILTIN_DIR "/../../%1/include").arg(clangVersion())); | ||||
403 | if (isValidClangBuiltingIncludePath(dir)) { | ||||
404 | clangDebug() << "Using builtin dir:" << dir; | ||||
the QFileInfo(dir).isDir() can be removed, since the file check in the line below implicitly checks that too mwolff: the `QFileInfo(dir).isDir()` can be removed, since the file check in the line below implicitly… | |||||
387 | return dir; | 405 | return dir; | ||
388 | } | 406 | } | ||
389 | #endif | 407 | #endif | ||
390 | 408 | | |||
mwolff: this hunk could be undone now | |||||
391 | clangDebug() << "Using builtin dir:" << KDEV_CLANG_BUILTIN_DIR; | 409 | clangDebug() << "Using builtin dir:" << KDEV_CLANG_BUILTIN_DIR; | ||
392 | return QString::fromUtf8(KDEV_CLANG_BUILTIN_DIR); | 410 | return QString::fromUtf8(KDEV_CLANG_BUILTIN_DIR); | ||
393 | }(); | 411 | }(); | ||
394 | return dir; | 412 | return dir; | ||
395 | } | 413 | } | ||
does the following simplified code work as well? auto dir = QDir(QStringLiteral(KDEV_CLANG_BUILTIN_DIR); if (dir.cd(QStringLiteral("../../%1/include").arg(clangVersion()) { clangDebug() << "Using builtin dir:" << dir.currentPath(); return dir.currentPath(); } mwolff: does the following simplified code work as well?
```
auto dir = QDir(QStringLiteral… | |||||
It does - after counting the braces, and when I use dir.path() (currentPath() is the app's cwd ;) ) rjvbb: It does - after counting the braces, and when I use dir.path() (currentPath() is the app's cwd… | |||||
simplify this to if (hardcodedDir.cd(...) && hardcodedDir.exists(entryToCheck)) mwolff: simplify this to
if (hardcodedDir.cd(...) && hardcodedDir.exists(entryToCheck)) | |||||
actually, thinking about this once more, it can be further simplified similar to the path above: dir = QStringLiteral(KDEV_CLANG_BUILTIN_DIR "/../../%1/include").arg(clangVersion()); if (QFile::exists(dir + QLatin1Char('/') + entryToCheck)) { return dir; } then all code paths are basically the same in regard to the entryToCheck check, just for different base paths. This could thus be shared, too: auto isValidDir = [](const QString &dir) { return QFile::exists(dir + QLatin1String("/cpuid.h")); } then use this in the three conditionals mwolff: actually, thinking about this once more, it can be further simplified similar to the path above… | |||||
Done. I just added a cleanPath() as in the WIN32 code path, so we don't return a path containing a "detour" (../..). rjvbb: Done. I just added a `cleanPath()` as in the WIN32 code path, so we don't return a path… | |||||
mwolff: don't change this (see above) |
the lambda is there to store the result in the static const value that will be returned. we don't want to compute the result multiple times