Check detects cyclic #include dependencies between user-defined headers.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Findings on llvm:
clang-tools-extra/unittests/clang-doc/ClangDocTest.h:12:10: warning: direct self-inclusion of header file 'ClangDocTest.h' [misc-header-include-cycle] libc/src/__support/FPUtil/x86_64/LongDoubleBits.h:21:10: warning: circular header file dependency detected while including 'FPBits.h', please check the include path: 'FPBits.h' -> 'LongDoubleBits.h' -> 'FPBits.h' [misc-header-include-cycle] lldb/include/lldb/API/SBAddress.h:13:10: warning: circular header file dependency detected while including 'SBModule.h', please check the include path: 'SBModule.h' -> 'SBSymbolContext.h' -> 'SBBlock.h' -> 'SBTarget.h' -> 'SBAddress.h' -> 'SBModule.h' [misc-header-include-cycle] lldb/include/lldb/API/SBBlock.h:14:10: warning: circular header file dependency detected while including 'SBTarget.h', please check the include path: 'SBTarget.h' -> 'SBAddress.h' -> 'SBModule.h' -> 'SBSymbolContext.h' -> 'SBBlock.h' -> 'SBTarget.h' [misc-header-include-cycle] lldb/include/lldb/API/SBFunction.h:12:10: warning: circular header file dependency detected while including 'SBAddress.h', please check the include path: 'SBAddress.h' -> 'SBModule.h' -> 'SBSymbolContext.h' -> 'SBFunction.h' -> 'SBAddress.h' [misc-header-include-cycle] lldb/include/lldb/API/SBLineEntry.h:12:10: warning: circular header file dependency detected while including 'SBAddress.h', please check the include path: 'SBAddress.h' -> 'SBModule.h' -> 'SBSymbolContext.h' -> 'SBLineEntry.h' -> 'SBAddress.h' [misc-header-include-cycle] lldb/include/lldb/API/SBModule.h:15:10: warning: circular header file dependency detected while including 'SBSymbolContext.h', please check the include path: 'SBSymbolContext.h' -> 'SBBlock.h' -> 'SBTarget.h' -> 'SBAddress.h' -> 'SBModule.h' -> 'SBSymbolContext.h' [misc-header-include-cycle] lldb/include/lldb/API/SBSymbol.h:12:10: warning: circular header file dependency detected while including 'SBAddress.h', please check the include path: 'SBAddress.h' -> 'SBModule.h' -> 'SBSymbolContext.h' -> 'SBSymbol.h' -> 'SBAddress.h' [misc-header-include-cycle] lldb/include/lldb/API/SBSymbol.h:15:10: warning: circular header file dependency detected while including 'SBTarget.h', please check the include path: 'SBTarget.h' -> 'SBAddress.h' -> 'SBModule.h' -> 'SBSymbolContext.h' -> 'SBSymbol.h' -> 'SBTarget.h' [misc-header-include-cycle] lldb/include/lldb/API/SBSymbolContext.h:12:10: warning: circular header file dependency detected while including 'SBBlock.h', please check the include path: 'SBBlock.h' -> 'SBTarget.h' -> 'SBAddress.h' -> 'SBModule.h' -> 'SBSymbolContext.h' -> 'SBBlock.h' [misc-header-include-cycle] lldb/include/lldb/API/SBSymbolContext.h:15:10: warning: circular header file dependency detected while including 'SBFunction.h', please check the include path: 'SBFunction.h' -> 'SBAddress.h' -> 'SBModule.h' -> 'SBSymbolContext.h' -> 'SBFunction.h' [misc-header-include-cycle] lldb/include/lldb/API/SBSymbolContext.h:16:10: warning: circular header file dependency detected while including 'SBLineEntry.h', please check the include path: 'SBLineEntry.h' -> 'SBAddress.h' -> 'SBModule.h' -> 'SBSymbolContext.h' -> 'SBLineEntry.h' [misc-header-include-cycle] lldb/include/lldb/API/SBSymbolContext.h:17:10: warning: circular header file dependency detected while including 'SBModule.h', please check the include path: 'SBModule.h' -> 'SBSymbolContext.h' -> 'SBModule.h' [misc-header-include-cycle] lldb/include/lldb/API/SBSymbolContext.h:18:10: warning: circular header file dependency detected while including 'SBSymbol.h', please check the include path: 'SBSymbol.h' -> 'SBAddress.h' -> 'SBModule.h' -> 'SBSymbolContext.h' -> 'SBSymbol.h' [misc-header-include-cycle] lldb/include/lldb/API/SBSymbolContextList.h:13:10: warning: circular header file dependency detected while including 'SBSymbolContext.h', please check the include path: 'SBSymbolContext.h' -> 'SBBlock.h' -> 'SBTarget.h' -> 'SBSymbolContextList.h' -> 'SBSymbolContext.h' [misc-header-include-cycle] lldb/include/lldb/API/SBTarget.h:12:10: warning: circular header file dependency detected while including 'SBAddress.h', please check the include path: 'SBAddress.h' -> 'SBModule.h' -> 'SBSymbolContext.h' -> 'SBBlock.h' -> 'SBTarget.h' -> 'SBAddress.h' [misc-header-include-cycle] lldb/include/lldb/API/SBTarget.h:20:10: warning: circular header file dependency detected while including 'SBSymbolContextList.h', please check the include path: 'SBSymbolContextList.h' -> 'SBSymbolContext.h' -> 'SBBlock.h' -> 'SBTarget.h' -> 'SBSymbolContextList.h' [misc-header-include-cycle] lldb/include/lldb/lldb-private-types.h:14:10: warning: circular header file dependency detected while including 'lldb-private.h', please check the include path: 'lldb-private.h' -> 'lldb-private-types.h' -> 'lldb-private.h' [misc-header-include-cycle] lldb/include/lldb/lldb-private.h:16:10: warning: circular header file dependency detected while including 'lldb-private-types.h', please check the include path: 'lldb-private-types.h' -> 'lldb-private.h' -> 'lldb-private-types.h' [misc-header-include-cycle] lldb/source/Plugins/Process/scripted/ScriptedProcess.h:17:10: warning: circular header file dependency detected while including 'ScriptedThread.h', please check the include path: 'ScriptedThread.h' -> 'ScriptedProcess.h' -> 'ScriptedThread.h' [misc-header-include-cycle] lldb/source/Plugins/Process/scripted/ScriptedThread.h:14:10: warning: circular header file dependency detected while including 'ScriptedProcess.h', please check the include path: 'ScriptedProcess.h' -> 'ScriptedThread.h' -> 'ScriptedProcess.h' [misc-header-include-cycle] third-party/unittest/googletest/include/gtest/gtest_pred_impl.h:43:10: warning: circular header file dependency detected while including 'gtest.h', please check the include path: 'gtest.h' -> 'gtest_pred_impl.h' -> 'gtest.h' [misc-header-include-cycle]
This is a great check that I've been meaning to work on for ages but never had time.
It mostly looks good but there are a few issues
I feel there is another issue that this can be very spammy with diagnostics(though clang-tidy is likely suppressing the duplicated ones).
But maybe when we emit a warning for a specified include, we could put it in a set to not warn on that include again
clang-tools-extra/clang-tidy/misc/HeaderIncludeCycleCheck.cpp | ||
---|---|---|
107–111 | How does this handle this case where an include includes a file that self includes itself. // Foo.hpp #pragma once #include "Foo.hpp" // Bar.hpp #pragma once #include Foo.hpp // Main.cpp #include "Bar.hpp" Where will the warning be emitted, it should appear in Foo.hpp but the logic here says it won't and would just be reported as a circular dependency below. | |
113–123 | Rather than just printing out the include path, can you emit each include location as a note. Notes have better support for front end diagnostics parsing. | |
135 | 1024 entries is pushing the boat out for a small vector. | |
clang-tools-extra/docs/clang-tidy/checks/misc/header-include-cycle.rst | ||
64 | This tag line is just unnecessary |
clang-tools-extra/clang-tidy/misc/HeaderIncludeCycleCheck.cpp | ||
---|---|---|
107–111 | in theory it should raise an issue for self-include here.. | |
113–123 | yes I wanted to do that, but at the point of FileChanged, where I fill up stack, i don't have an proper info where such file wre included. | |
135 | Thats just 4KB of memory pre-allocated to avoid re-allocations. Small is "muten" here. | |
clang-tools-extra/docs/clang-tidy/checks/misc/header-include-cycle.rst | ||
64 | maybe it is unnecessary, but I just wanted to put some advertisement slogan for a check ... |
"But maybe when we emit a warning for a specified include, we could put it in a set to not warn on that include again"
I don't think so, in such case we hide include paths, and most of the time header guards should help here in reduction of cyclic dependences.
Added support for --include
Added support for self-include of source file
Added more tests
Reworked include stack.
clang-tools-extra/clang-tidy/misc/HeaderIncludeCycleCheck.cpp | ||
---|---|---|
135–136 | Is this a case that can ever come up? | |
147 | Again whats the rationale for using continue over break here? | |
149–151 | Is this a case that is expected to come up, if so can there be a test added. | |
155–162 | Dont reinvent the wheel - llvm::sys::path::filename does the same thing |
LGTM: Just one small nit.
clang-tools-extra/clang-tidy/misc/HeaderIncludeCycleCheck.cpp | ||
---|---|---|
148–150 |
This breaks tests: http://45.33.8.238/linux/104455/step_8.txt
Please take a look and revert for now if it takes a while to fix.
To be honest I have no idea why it failed, simply because there is CHECK-MESSAGES for that log. I will probably split this single test into few smaller tests.
TODO:
Split tests into multiple files (to isolate issue).
If possible remove usage of FileCheck.
How does this handle this case where an include includes a file that self includes itself.
Where will the warning be emitted, it should appear in Foo.hpp but the logic here says it won't and would just be reported as a circular dependency below.
Can you make sure the warning is emitted in Foo.hpp and add test cases that test for this, The current tests just check include a file that self references itself with no intermediate files.