benshi001 updated this revision to Diff 400375.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117423/new/

https://reviews.llvm.org/D117423

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/lib/Driver/ToolChains/AVR.cpp
  clang/lib/Driver/ToolChains/AVR.h
  clang/test/Driver/avr-mmcu.S
  clang/test/Driver/avr-mmcu.c

Index: clang/test/Driver/avr-mmcu.c
===================================================================
--- clang/test/Driver/avr-mmcu.c
+++ clang/test/Driver/avr-mmcu.c
@@ -1,12 +1,15 @@
 // 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 -c 2>&1 | FileCheck -check-prefix=CHECKA %s
+// CHECKA: error: CPU 'attiny11' does not support {{.*}} language mode
+
+// RUN: %clang -### -target avr -no-canonical-prefixes -mmcu=attiny11 -x assembler-with-cpp %s -c 2>&1 | FileCheck -check-prefix=CHECKB %s
+// CHECKB-NOT: error: CPU 'attiny11' does not support {{.*}} language mode
 
 // 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: CPU 'at90s2313' does not support {{.*}} language mode
 
 // 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"
Index: clang/test/Driver/avr-mmcu.S
===================================================================
--- /dev/null
+++ clang/test/Driver/avr-mmcu.S
@@ -0,0 +1,13 @@
+// A test for the supported language mode by different avr families.
+
+// RUN: %clang -### -target avr -no-canonical-prefixes -mmcu=attiny11 %s -c 2>&1 | FileCheck -check-prefix=CHECKA %s
+// CHECKA-NOT: error: CPU 'attiny11' does not support {{.*}} language mode
+
+// RUN: %clang -### -target avr -no-canonical-prefixes -mmcu=attiny11 -x c++ %s -c 2>&1 | FileCheck -check-prefix=CHECKB %s
+// CHECKB: error: CPU 'attiny11' does not support {{.*}} language mode
+
+// RUN: %clang -### -target avr -no-canonical-prefixes -mmcu=at90s8515 %s -c 2>&1 | FileCheck -check-prefix=CHECKC %s
+// CHECKC-NOT: error: CPU 'at90s8515' does not support {{.*}} language mode
+
+// RUN: %clang -### -target avr -no-canonical-prefixes -mmcu=at90s8515 %s -x c++ -c 2>&1 | FileCheck -check-prefix=CHECKD %s
+// CHECKD-NOT: error: CPU 'at90s8515' does not support {{.*}} language mode
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 {
+  std::string AVRMcu;
+
 public:
   AVRToolChain(const Driver &D, const llvm::Triple &Triple,
                const llvm::opt::ArgList &Args);
Index: clang/lib/Driver/ToolChains/AVR.cpp
===================================================================
--- clang/lib/Driver/ToolChains/AVR.cpp
+++ clang/lib/Driver/ToolChains/AVR.cpp
@@ -12,6 +12,7 @@
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/InputInfo.h"
 #include "clang/Driver/Options.h"
+#include "clang/Driver/Types.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -19,6 +20,7 @@
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 
 using namespace clang::driver;
 using namespace clang::driver::toolchains;
@@ -311,24 +313,26 @@
     : Generic_ELF(D, Triple, Args), LinkStdlib(false) {
   GCCInstallation.init(Triple, Args);
 
+  // Save the CPU name for further checks.
+  AVRMcu = getCPUName(D, Args, Triple);
+
   // 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()) {
+    if (AVRMcu.empty()) {
       // We cannot link any standard libraries without an MCU specified.
       D.Diag(diag::warn_drv_avr_mcu_not_specified);
     } else {
-      Optional<StringRef> FamilyName = GetMCUFamilyName(CPU);
+      Optional<StringRef> FamilyName = GetMCUFamilyName(AVRMcu);
       Optional<std::string> 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;
+            << AVRMcu;
       } else if (!GCCInstallation.isValid()) {
         // No avr-gcc found and so no runtime linked.
         D.Diag(diag::warn_drv_avr_gcc_not_found);
@@ -339,7 +343,7 @@
         std::string GCCRoot(GCCInstallation.getInstallPath());
         std::string GCCParentPath(GCCInstallation.getParentLibPath());
         std::string LibcRoot = AVRLibcRoot.getValue();
-        std::string SubPath = GetMCUSubPath(CPU);
+        std::string SubPath = GetMCUSubPath(AVRMcu);
 
         getProgramPaths().push_back(GCCParentPath + "/../bin");
         getFilePaths().push_back(LibcRoot + std::string("/lib/") + SubPath);
@@ -379,6 +383,45 @@
   if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
                           options::OPT_fno_use_init_array, false))
     CC1Args.push_back("-fno-use-init-array");
+
+  // Omit checks for non avr1 family.
+  llvm::Optional<StringRef> FamilyName = GetMCUFamilyName(AVRMcu);
+  if (!FamilyName.hasValue() || !FamilyName->equals("avr1"))
+    return;
+
+  // Only '-x assembler-with-cpp' is allowed for the avr1 family.
+  auto Langs = DriverArgs.getAllArgValues(options::OPT_x);
+  for (auto Lang : Langs)
+    if (Lang != "assembler-with-cpp")
+      getDriver().Diag(diag::err_cpu_unsupported_language) << AVRMcu << Lang;
+
+  // Get the main file name.
+  const char *MainFileName = nullptr;
+  for (unsigned I = 0; I < CC1Args.size(); I++)
+    if (StringRef(CC1Args[I]).equals("-main-file-name")) {
+      MainFileName = CC1Args[I + 1];
+      break;
+    }
+  if (!MainFileName)
+    return;
+
+  // The main input file should be assembly only, it is OK that the main
+  // input file has a '.S' suffix.
+  types::ID MainFileId = types::lookupTypeForExtension(
+      llvm::sys::path::extension(MainFileName).drop_front());
+  if (MainFileId == types::TY_Asm)
+    return;
+
+  // The main input file should be assembly only, it should be led by
+  // '-x assembler-with-cpp' if it has not a '.S' suffix.
+  for (unsigned I = 0; I < DriverArgs.size(); I++) {
+    StringRef Arg(DriverArgs.getArgString(I));
+    if (Arg.equals("assembler-with-cpp"))
+      return;
+    if (Arg.contains(MainFileName))
+      getDriver().Diag(diag::err_cpu_unsupported_language)
+          << AVRMcu << getTypeName(MainFileId);
+  }
 }
 
 Tool *AVRToolChain::buildLinker() const {
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -232,6 +232,8 @@
   : Error<"the target architecture '%0' is not supported by the target '%1'">;
 def err_cpu_unsupported_isa
   : Error<"CPU '%0' does not support '%1' execution mode">;
+def err_cpu_unsupported_language
+  : Error<"CPU '%0' does not support '%1' language mode">;
 def err_arch_unsupported_isa
   : Error<"architecture '%0' does not support '%1' execution mode">;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to