Members of the KDE Community are recommended to subscribe to the kde-community mailing list at to allow them to participate in important discussions and receive other important announcements

Commit 0698385b authored by Bernd Buschinski's avatar Bernd Buschinski

Fix missing header guard warning for a standalone header being always present

Meaning a header that is not included in any other source file in your project.
Such a header would always have the "missing include guard" warning, regardless
if guards are present or not.

This is caused by clang_isFileMultipleIncludeGuarded returning 0 (not guarded) for
standalone header. I added a clang_Location_isFromMainFile check, which checks if
the "source location" is in the main file, which (if we only have a header) is true.
parent d348a833
......@@ -559,8 +559,11 @@ QList<ProblemPointer> ParseSession::problemsForFile(CXFile file) const
// see also TestDUChain::testReparseIncludeGuard
const QString path = QDir(ClangString(clang_getFileName(file)).toString()).canonicalPath();
const IndexedString indexedPath(path);
const auto location = clang_getLocationForOffset(d->m_unit, file, 0);
if (ClangHelpers::isHeader(path) && !clang_isFileMultipleIncludeGuarded(unit(), file)
&& !clang_Location_isInSystemHeader(clang_getLocationForOffset(d->m_unit, file, 0)))
&& !clang_Location_isInSystemHeader(location)
// clang_isFileMultipleIncludeGuarded always returns 0 in case our only file is the header
&& !clang_Location_isFromMainFile(location))
QExplicitlySharedDataPointer<StaticAssistantProblem> problem(new StaticAssistantProblem);
......@@ -1616,6 +1616,58 @@ void TestDUChain::testReparseIncludeGuard()
void TestDUChain::testIncludeGuardHeaderHeaderOnly()
QFETCH(QString, code);
// test that we do NOT get a warning for single standalone header file with include guards
TestFile header(code, QStringLiteral("h"));
QVERIFY(header.parseAndWait(TopDUContext::Features(TopDUContext::AllDeclarationsContextsAndUses | TopDUContext::AST)));
DUChainReadLocker lock;
QCOMPARE(header.topContext()->problems().size(), 0);
void TestDUChain::testIncludeGuardHeaderHeaderOnly_data()
QTest::newRow("guard-ifdef") << QStringLiteral(
"#ifndef GUARD\n"
"#define GUARD\n"
"int something;\n"
QTest::newRow("guard-pragma") << QStringLiteral(
"#pragma once\n"
"int something;\n"
void TestDUChain::testIncludeGuardHeaderWarning()
// test that we do get a warning for a header file without include guards
TestFile header(QStringLiteral("int something;\n"), QStringLiteral("h"));
TestFile impl("#include \"" + header.url().str() + "\"\n", QStringLiteral("cpp"));
QVERIFY(impl.parseAndWait(TopDUContext::Features(TopDUContext::AllDeclarationsContextsAndUses | TopDUContext::AST | TopDUContext::ForceUpdate)));
DUChainReadLocker lock;
auto context = DUChain::self()->chainForDocument(impl.url());
QCOMPARE(context->problems().size(), 0);
context = DUChain::self()->chainForDocument(header.url());
QCOMPARE(context->problems().size(), 1);
void TestDUChain::testExternC()
auto code = R"(extern "C" { void foo(); })";
......@@ -87,6 +87,9 @@ private Q_SLOTS:
void testActiveDocumentsGetBestPriority();
void testUsesCreatedForDeclarations();
void testReparseIncludeGuard();
void testIncludeGuardHeaderHeaderOnly();
void testIncludeGuardHeaderHeaderOnly_data();
void testIncludeGuardHeaderWarning();
void testExternC();
void testLambda();
void testReparseUnchanged_data();
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