Changeset View
Standalone View
plugins/clang/duchain/clanghelpers.cpp
Show First 20 Lines • Show All 365 Lines • ▼ Show 20 Line(s) | 353 | static const auto clangVersion = []() -> QString { | |||
---|---|---|---|---|---|
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 | QString ClangHelpers::clangBuiltinIncludePath() | 372 | QString ClangHelpers::clangBuiltinIncludePath() | ||
373 | { | 373 | { | ||
374 | // use a lambda to store the result in a static variable which can be | ||||
375 | // returned without recomputing the string on subsequent calls. | ||||
374 | static const auto dir = []() -> QString { | 376 | static const auto dir = []() -> QString { | ||
377 | auto isValidDir = [](const QString &dir) { | ||||
378 | return QFile::exists(dir + QLatin1String("/cpuid.h")); | ||||
379 | }; | ||||
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")); | 380 | auto dir = QString::fromUtf8(qgetenv("KDEV_CLANG_BUILTIN_DIR")); | ||
376 | if (!dir.isEmpty()) { | 381 | if (!dir.isEmpty() && isValidDir(dir)) { | ||
377 | clangDebug() << "Using dir from $KDEV_CLANG_BUILTIN_DIR:" << dir; | 382 | clangDebug() << "Using dir from $KDEV_CLANG_BUILTIN_DIR:" << dir; | ||
378 | return dir; | 383 | return dir; | ||
379 | } | 384 | } | ||
380 | 385 | | |||
381 | #ifdef Q_OS_WIN32 | 386 | #ifdef Q_OS_WIN32 | ||
382 | // attempt to use the bundled copy on Windows | 387 | // attempt to use the bundled copy on Windows | ||
383 | dir = QDir::cleanPath(QStringLiteral("%1/../lib/clang/%2/include") | 388 | dir = QDir::cleanPath(QStringLiteral("%1/../lib/clang/%2/include") | ||
384 | .arg(QCoreApplication::applicationDirPath(), clangVersion())); | 389 | .arg(QCoreApplication::applicationDirPath(), clangVersion())); | ||
385 | clangDebug() << "Trying" << dir; | 390 | if (isValidDir(dir)) { | ||
386 | if (QFileInfo(dir).isDir()) { | 391 | clangDebug() << "Using builtin dir:" << dir; | ||
392 | return dir; | ||||
393 | } | ||||
394 | #elif defined(Q_OS_UNIX) | ||||
395 | // a clang minor version upgrade since we were last built can | ||||
396 | // cause problems if the "clang/$fullversion/include" path component | ||||
397 | // changed. Try to generate the correct builtin_dir for the current | ||||
398 | // major.minor.patchlevel version: pop the last 2 components then | ||||
399 | // chdir through with the updated version directory. | ||||
400 | dir = QDir::cleanPath(QStringLiteral(KDEV_CLANG_BUILTIN_DIR "/../../%1/include").arg(clangVersion())); | ||||
401 | if (isValidDir(dir)) { | ||||
402 | 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; | 403 | return dir; | ||
388 | } | 404 | } | ||
389 | #endif | 405 | #endif | ||
390 | 406 | | |||
mwolff: this hunk could be undone now | |||||
407 | dir = QString::fromUtf8(KDEV_CLANG_BUILTIN_DIR); | ||||
408 | if (isValidDir(dir)) { | ||||
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 dir; | ||
411 | } | ||||
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… | |||||
412 | // return empty string to signal failure | ||||
simplify this to if (hardcodedDir.cd(...) && hardcodedDir.exists(entryToCheck)) mwolff: simplify this to
if (hardcodedDir.cd(...) && hardcodedDir.exists(entryToCheck)) | |||||
413 | return QString(); | ||||
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… | |||||
mwolff: don't change this (see above) | |||||
393 | }(); | 414 | }(); | ||
394 | return dir; | 415 | return dir; | ||
395 | } | 416 | } |
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