Index: clang/include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticDriverKinds.td +++ clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -57,6 +57,8 @@ "standard library not linked and so no interrupt vector table or " "compiler runtime routines will be linked">, InGroup; +def err_drv_avr_assembly_only : Error< + "device '%0' only supports assembly programming">; def err_drv_cuda_bad_gpu_arch : Error<"unsupported CUDA gpu architecture: %0">; def err_drv_no_cuda_installation : Error< "cannot find CUDA installation; provide its path via '--cuda-path', or pass " Index: clang/lib/Driver/ToolChains/AVR.h =================================================================== --- clang/lib/Driver/ToolChains/AVR.h +++ clang/lib/Driver/ToolChains/AVR.h @@ -19,6 +19,8 @@ namespace toolchains { class LLVM_LIBRARY_VISIBILITY AVRToolChain : public Generic_ELF { + StringRef FamilyName; + public: AVRToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); @@ -31,6 +33,8 @@ llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override; + StringRef getFamilyName() const { return FamilyName; } + protected: Tool *buildLinker() const override; Index: clang/lib/Driver/ToolChains/AVR.cpp =================================================================== --- clang/lib/Driver/ToolChains/AVR.cpp +++ clang/lib/Driver/ToolChains/AVR.cpp @@ -311,47 +311,57 @@ : Generic_ELF(D, Triple, Args), LinkStdlib(false) { GCCInstallation.init(Triple, Args); + std::string CPU = getCPUName(D, Args, Triple); + if (CPU.empty()) { + // We cannot link any standard libraries without an MCU specified. + D.Diag(diag::warn_drv_avr_mcu_not_specified); + D.Diag(diag::warn_drv_avr_stdlib_not_linked); + return; + } + + Optional FamilyName = GetMCUFamilyName(CPU); + if (!FamilyName.hasValue()) { + // We do not have an entry for this CPU in the family mapping table yet. + D.Diag(diag::warn_drv_avr_family_linking_stdlibs_not_implemented) << CPU; + D.Diag(diag::warn_drv_avr_stdlib_not_linked); + return; + } else { + this->FamilyName = *FamilyName; + } + // Only add default libraries if the user hasn't explicitly opted out. - if (!Args.hasArg(options::OPT_nostdlib) && - !Args.hasArg(options::OPT_nodefaultlibs) && - !Args.hasArg(options::OPT_c /* does not apply when not linking */)) { - std::string CPU = getCPUName(D, Args, Triple); - - if (CPU.empty()) { - // We cannot link any standard libraries without an MCU specified. - D.Diag(diag::warn_drv_avr_mcu_not_specified); - } else { - Optional FamilyName = GetMCUFamilyName(CPU); - Optional AVRLibcRoot = findAVRLibcInstallation(); - - if (!FamilyName.hasValue()) { - // We do not have an entry for this CPU in the family - // mapping table yet. - D.Diag(diag::warn_drv_avr_family_linking_stdlibs_not_implemented) - << CPU; - } else if (!GCCInstallation.isValid()) { - // No avr-gcc found and so no runtime linked. - D.Diag(diag::warn_drv_avr_gcc_not_found); - } else if (!AVRLibcRoot.hasValue()) { - // No avr-libc found and so no runtime linked. - D.Diag(diag::warn_drv_avr_libc_not_found); - } else { // We have enough information to link stdlibs - std::string GCCRoot(GCCInstallation.getInstallPath()); - std::string GCCParentPath(GCCInstallation.getParentLibPath()); - std::string LibcRoot = AVRLibcRoot.getValue(); - std::string SubPath = GetMCUSubPath(CPU); - - getProgramPaths().push_back(GCCParentPath + "/../bin"); - getFilePaths().push_back(LibcRoot + std::string("/lib/") + SubPath); - getFilePaths().push_back(GCCRoot + std::string("/") + SubPath); - - LinkStdlib = true; - } - } - - if (!LinkStdlib) - D.Diag(diag::warn_drv_avr_stdlib_not_linked); + if (Args.hasArg(options::OPT_nostdlib) || + Args.hasArg(options::OPT_nodefaultlibs) || + Args.hasArg(options::OPT_S /* does not apply when not linking */) || + Args.hasArg(options::OPT_c /* does not apply when not linking */)) + return; + + if (!GCCInstallation.isValid()) { + // No avr-gcc found and so no runtime linked. + D.Diag(diag::warn_drv_avr_gcc_not_found); + D.Diag(diag::warn_drv_avr_stdlib_not_linked); + return; + } + + Optional AVRLibcRoot = findAVRLibcInstallation(); + if (!AVRLibcRoot.hasValue()) { + // No avr-libc found and so no runtime linked. + D.Diag(diag::warn_drv_avr_libc_not_found); + D.Diag(diag::warn_drv_avr_stdlib_not_linked); + return; } + + // We have enough information to link stdlibs + std::string GCCRoot(GCCInstallation.getInstallPath()); + std::string GCCParentPath(GCCInstallation.getParentLibPath()); + std::string LibcRoot = AVRLibcRoot.getValue(); + std::string SubPath = GetMCUSubPath(CPU); + + getProgramPaths().push_back(GCCParentPath + "/../bin"); + getFilePaths().push_back(LibcRoot + std::string("/lib/") + SubPath); + getFilePaths().push_back(GCCRoot + std::string("/") + SubPath); + + LinkStdlib = true; } void AVRToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -8,6 +8,7 @@ #include "Clang.h" #include "AMDGPU.h" +#include "AVR.h" #include "Arch/AArch64.h" #include "Arch/ARM.h" #include "Arch/M68k.h" @@ -5144,6 +5145,14 @@ << A->getAsString(Args) << TripleStr; } + // Devices in the avr-1 family only support assembly programming. + if (TC.getArch() == llvm::Triple::avr) { + auto const &AVRTC = static_cast(TC); + if (AVRTC.getFamilyName().equals("avr1")) + D.Diag(diag::err_drv_avr_assembly_only) + << getCPUName(D, Args, TC.getTriple(), false); + } + if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) { if (TC.getTriple().isX86()) A->render(Args, CmdArgs); Index: clang/test/Driver/avr-mmcu.c =================================================================== --- clang/test/Driver/avr-mmcu.c +++ clang/test/Driver/avr-mmcu.c @@ -1,12 +1,12 @@ // A test for the propagation of the -mmcu option to -cc1 and -cc1as -// RUN: %clang -### -target avr -no-canonical-prefixes -mmcu=attiny11 -save-temps %s 2>&1 | FileCheck -check-prefix=CHECK0 %s -// CHECK0: clang{{.*}} "-cc1" {{.*}} "-target-cpu" "attiny11" -// CHECK0: clang{{.*}} "-cc1as" {{.*}} "-target-cpu" "attiny11" +// RUN: %clang -### -target avr -no-canonical-prefixes -mmcu=attiny11 %s 2>&1 | FileCheck -check-prefix=CHECK0 %s +// CHECK0: error: device 'attiny11' only supports assembly programming // RUN: %clang -### -target avr -no-canonical-prefixes -mmcu=at90s2313 -save-temps %s 2>&1 | FileCheck -check-prefix=CHECK1 %s // CHECK1: clang{{.*}} "-cc1" {{.*}} "-target-cpu" "at90s2313" // CHECK1: clang{{.*}} "-cc1as" {{.*}} "-target-cpu" "at90s2313" +// CHECK1-NOT: error: device 'at90s2313' only supports assembly programming // RUN: %clang -### -target avr -no-canonical-prefixes -mmcu=at90s8515 -save-temps %s 2>&1 | FileCheck -check-prefix=CHECK2 %s // CHECK2: clang{{.*}} "-cc1" {{.*}} "-target-cpu" "at90s8515"