| 581 | } |
| 582 | |
| 583 | QList<ProblemPointer> ParseSession::problemsForFile(CXFile file) const |
| 584 | { |
| 585 | if (!d) { |
| 586 | return {}; |
| 587 | } |
| 588 | |
| 589 | QList<ProblemPointer> problems; |
| 590 | |
| 591 | // extra clang diagnostics |
| 592 | const uint numDiagnostics = clang_getNumDiagnostics(d->m_unit); |
| 593 | problems.reserve(numDiagnostics); |
| 594 | d->m_diagnosticsCache.resize(numDiagnostics); |
| 595 | |
| 596 | for (uint i = 0; i < numDiagnostics; ++i) { |
| 597 | auto diagnostic = clang_getDiagnostic(d->m_unit, i); |
| 598 | |
| 599 | CXSourceLocation location = clang_getDiagnosticLocation(diagnostic); |
| 600 | CXFile diagnosticFile; |
| 601 | clang_getFileLocation(location, &diagnosticFile, nullptr, nullptr, nullptr); |
| 602 | |
| 603 | const auto requestedHereProblems = createRequestedHereProblems(i, diagnostic, file); |
| 604 | for (const auto& ptr : requestedHereProblems) { |
| 605 | problems.append(static_cast<const ProblemPointer&>(ptr)); |
| 606 | } |
| 607 | |
| 608 | // missing-include problems are so severe in clang that we always propagate |
| 609 | // them to this document, to ensure that the user will see the error. |
| 610 | if (diagnosticFile != file && ClangDiagnosticEvaluator::diagnosticType(diagnostic) != ClangDiagnosticEvaluator::IncludeFileNotFoundProblem) { |
| 611 | continue; |
| 612 | } |
| 613 | |
| 614 | problems << ((diagnosticFile == file) ? |
| 615 | getOrCreateProblem(i, diagnostic) : |
| 616 | createExternalProblem(i, diagnostic, ki18n("In included file: %1"))); |
| 617 | |
| 618 | clang_disposeDiagnostic(diagnostic); |
| 619 | } |
| 620 | |
| 621 | // other problem sources |
| 622 | |
| 623 | TodoExtractor extractor(unit(), file); |
| 624 | problems << extractor.problems(); |
| 625 | |
| 626 | #if CINDEX_VERSION_MINOR > 30 |
| 627 | // note that the below warning is triggered on every reparse when there is a precompiled preamble |
| 628 | // see also TestDUChain::testReparseIncludeGuard |
| 629 | const QString path = QDir(ClangString(clang_getFileName(file)).toString()).canonicalPath(); |
| 630 | const IndexedString indexedPath(path); |
| 631 | const auto location = clang_getLocationForOffset(d->m_unit, file, 0); |
| 632 | if (ClangHelpers::isHeader(path) && !clang_isFileMultipleIncludeGuarded(unit(), file) |
| 633 | && !clang_Location_isInSystemHeader(location) |
| 634 | // clang_isFileMultipleIncludeGuarded always returns 0 in case our only file is the header |
| 635 | && !clang_Location_isFromMainFile(location)) |
| 636 | { |
| 637 | QExplicitlySharedDataPointer<StaticAssistantProblem> problem(new StaticAssistantProblem); |
| 638 | problem->setSeverity(IProblem::Warning); |
| 639 | problem->setDescription(i18n("Header is not guarded against multiple inclusions")); |
| 640 | problem->setExplanation(i18n("The given header is not guarded against multiple inclusions, " |