Devices belongs to the avr1 family do not has SRAM, so
only assembly source files should be accepted. This behaviour
conforms to GCC.
Details
- Reviewers
aykevl dylanmckay MaskRay
Diff Detail
Unit Tests
Event Timeline
This is GCC's handling on AVR
around line 10433 / function static void avr_file_start (void),
gcc rises an error architecture %qs supported for assembler only
clang/lib/Driver/ToolChains/AVR.cpp | ||
---|---|---|
419 | We need not care about '-x c++' or '-x c', which are excluded by above checks. |
clang/lib/Driver/ToolChains/AVR.cpp | ||
---|---|---|
417 | In this for loop, the key point is which one is found first. It is OK that -x assembler-with-cpp comes first, otherwise an error should be reported. |
I'm not sure this is the correct location for these checks. You're essentially checking whether the compilation looks like a C/C++ compilation or an assembly compilation based on the flags and the file name. However, the Clang driver already does something like this: it converts the command line arguments and files into a list of jobs to perform. This is done in Driver::BuildActions, Driver::BuildJobs, Clang::ConstructJob, and other places.
I think a better place to do this check is in Clang::ConstructJob. There is already something similar here:
// C++ is not supported for IAMCU. if (IsIAMCU && types::isCXX(Input.getType())) D.Diag(diag::err_drv_clang_unsupported) << "C++ for IAMCU";
I think something like this will work, in Clang::ConstructJob:
bool IsAVR = ... ... if (IsAVR) { D.Diag(diag::err_drv_clang_unsupported) << "C/C++ for AVR";
There is a different ConstructJob for assembly, so this works.
clang/lib/Driver/ToolChains/AVR.h | ||
---|---|---|
22 | I think I would have called this CPU not AVRMcu, but AVRMcu is fine. | |
clang/test/Driver/avr-mmcu.S | ||
4 ↗ | (On Diff #400375) | Is there a reason why you used {{.*}} instead of the actual value? |
Thanks for your suggestion ! I have changed to check avr-1 in Clang::ConstructJob, which is much more clear than my previous solution !
Really appreicate. A bit pity is that I have to make big changes to the constructor AVRToolChain::AVRToolChain, otherwise the expected error *** only supports assembly programming can not rise if -c is specified in clang options. Because in previous code, the reading of FamilyName is embraced by !Args.hasArg(options::OPT_c), something like
if (!Args.hasArg(options::OPT_c)) { Optional<StringRef> FamilyName = GetMCUFamilyName(CPU); }
so I have to re-arrange the code logic.
! In D117423#3251110, @aykevl wrote:
I'm not sure this is the correct location for these checks. You're essentially checking whether the compilation looks like a C/C++ compilation or an assembly compilation based on the flags and the file name. However, the Clang driver already does something like this: it converts the command line arguments and files into a list of jobs to perform. This is done in Driver::BuildActions, Driver::BuildJobs, Clang::ConstructJob, and other places.
I think a better place to do this check is in Clang::ConstructJob. There is already something similar here:// C++ is not supported for IAMCU. if (IsIAMCU && types::isCXX(Input.getType())) D.Diag(diag::err_drv_clang_unsupported) << "C++ for IAMCU";I think something like this will work, in Clang::ConstructJob:
bool IsAVR = ... ... if (IsAVR) { D.Diag(diag::err_drv_clang_unsupported) << "C/C++ for AVR";There is a different ConstructJob for assembly, so this works.
The previous logic of the constructor AVRToolChain::AVRToolChain
- if -c or -nostdlib is specified, no error will rise (even if no MCU is specified).
- if no MCU is specified, two warnings will rise
warning: no target microcontroller specified on command line warning: standard library not linked and so no interrupt vector table
- if the specified avr device has no proper avr family name, two warnings will rise
warning: support for linking stdlibs for microcontroller '%0' is not implemented warning: standard library not linked and so no interrupt vector table
- if no available avr-gcc is found, two warnings will rise
warning: no avr-gcc installation can be found on the system, warning: standard library not linked and so no interrupt vector table
- if no available avr-libc is found, two warnings will rise
warning: no avr-libc installation can be found on the system warning: standard library not linked and so no interrupt vector table
And after my re-arrangement of the constructor, the above points 2/3/4/5 do not change. But only point 1 changes to
if -c or -nostdlib is specified and a valid avr mcu is specified, no error will rise.
if -c or -nostdlib is specified but no valid avr mcu is specified, a warning will rise (no target microcontroller specified on command line)
clang/lib/Driver/ToolChains/AVR.h | ||
---|---|---|
22 | It is changed to FamilyName, since family is checked other than the device name. |
clang/lib/Driver/ToolChains/Clang.cpp | ||
---|---|---|
5149 ↗ | (On Diff #402379) | Try moving the check from the generic file to the toolchain-specific file. |
clang/lib/Driver/ToolChains/Clang.cpp | ||
---|---|---|
5149 ↗ | (On Diff #402379) | I have created another patch to do this check in avr toolchain specific files. https://reviews.llvm.org/D118095 which is much more complex than current solution. But I do see there are other target specific checks in the common Clang::ConstructJob, such as https://github.com/llvm/llvm-project/blob/main/clang/lib/Driver/ToolChains/Clang.cpp#L5153 https://github.com/llvm/llvm-project/blob/main/clang/lib/Driver/ToolChains/Clang.cpp#L5019 https://github.com/llvm/llvm-project/blob/main/clang/lib/Driver/ToolChains/Clang.cpp#L5257 |
I think I would have called this CPU not AVRMcu, but AVRMcu is fine.