Clang utilizes LLVMOption to process command line options. Each option has a “claimed” bit to state whether the option has been processed by APIs like hasArg/getLastArg.
In clangDriver, most action classes utilize clang::driver::tools::Clang. Clang::ConstructJob is where most driver options are handled. Target-specific options are handled by Clang 's member function RenderTargetOptions. For assembler input, we use ClangAs whose ConstructJob method handles very few options.
Therefore, most compilation options will lead to a -Wunused-command-line-argument diagnostic.
On the other hand, for linking, we claim all CompileOnly_Group options, not seeing -Wunused-command-line-argument diagnostics. This is partly because it’s very common to use CFLAGS/CXXFLAGS for linking.
% clang -c -faddrsig -ftime-trace -falign-functions=16 -fpic -march=generic a.s
clang: warning: argument unused during compilation: '-faddrsig' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-ftime-trace' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-falign-functions=16' [-Wunused-command-line-argument]
% clang -c -faddrsig -ftime-trace -falign-functions=16 -fpic -march=generic a.S # no diagnostic
% clang -faddrsig -ftime-trace -falign-functions=16 -fpic -march=generic a.o # no diagnostic
% clang -c -faddrsig -ftime-trace -falign-functions=16 -fpic -march=x86-64 a.c # no diagnostic
What do people think of the diagnostics for input assembly files that do not need preprocessing? Shall we keep -Wunused-command-line-argument or suppress it like we do for linking and assembler-with-cpp? I have mixed feelings.
On one hand, I do see that people may see the diagnostics for assembly files are annoying.
On the other hand, this may push projects to think of ASFLAGS when they do assemble assembly files.
Note: GCC doesn’t have the -Wunused-command-line-argument feature. When assembling a file, it seems to accept every option that a C file accepts.
Appendix
GNU make’s default rules:
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
COMPILE.S = $(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c
COMPILE.s = $(AS) $(ASFLAGS) $(TARGET_MACH)