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)