Index: include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- include/clang/Basic/DiagnosticDriverKinds.td +++ include/clang/Basic/DiagnosticDriverKinds.td @@ -150,6 +150,8 @@ "The target '%0' is not a supported OpenMP host target.">; def err_drv_bitcode_unsupported_on_toolchain : Error< "-fembed-bitcode is not supported on versions of iOS prior to 6.0">; +def err_drv_cxx_not_supported : Error< + "C++ is not supported for target '%0'">; def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup; def warn_drv_lto_libpath : Warning<"libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead">, Index: include/clang/Driver/ToolChain.h =================================================================== --- include/clang/Driver/ToolChain.h +++ include/clang/Driver/ToolChain.h @@ -417,6 +417,10 @@ virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const; + /// \brief Add arguments to use MCU GCC toolchain includes. + virtual void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; + /// \brief Return sanitizers which are available in this toolchain. virtual SanitizerMask getSupportedSanitizers() const; Index: lib/Driver/Driver.cpp =================================================================== --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -2438,6 +2438,7 @@ TC = new toolchains::Minix(*this, Target, Args); break; case llvm::Triple::Linux: + case llvm::Triple::ELFIAMCU: if (Target.getArch() == llvm::Triple::hexagon) TC = new toolchains::HexagonToolChain(*this, Target, Args); else if ((Target.getVendor() == llvm::Triple::MipsTechnologies) && Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -696,3 +696,6 @@ void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const {} + +void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const {} Index: lib/Driver/ToolChains.h =================================================================== --- lib/Driver/ToolChains.h +++ lib/Driver/ToolChains.h @@ -806,6 +806,8 @@ llvm::opt::ArgStringList &CC1Args) const override; void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; bool isPIEDefault() const override; SanitizerMask getSupportedSanitizers() const override; void addProfileRTLibs(const llvm::opt::ArgList &Args, Index: lib/Driver/ToolChains.cpp =================================================================== --- lib/Driver/ToolChains.cpp +++ lib/Driver/ToolChains.cpp @@ -1570,9 +1570,13 @@ break; case llvm::Triple::x86: LibDirs.append(begin(X86LibDirs), end(X86LibDirs)); - TripleAliases.append(begin(X86Triples), end(X86Triples)); - BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); - BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); + // MCU toolchain is 32 bit only and its triple alias is TargetTriple + // itself, which will be appended below. + if (!TargetTriple.isOSIAMCU()) { + TripleAliases.append(begin(X86Triples), end(X86Triples)); + BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); + BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); + } break; case llvm::Triple::mips: LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs)); @@ -1718,14 +1722,14 @@ namespace { // Filter to remove Multilibs that don't exist as a suffix to Path class FilterNonExistent { - StringRef Base; + StringRef Base, File; vfs::FileSystem &VFS; public: - FilterNonExistent(StringRef Base, vfs::FileSystem &VFS) - : Base(Base), VFS(VFS) {} + FilterNonExistent(StringRef Base, StringRef File, vfs::FileSystem &VFS) + : Base(Base), File(File), VFS(VFS) {} bool operator()(const Multilib &M) { - return !VFS.exists(Base + M.gccSuffix() + "/crtbegin.o"); + return !VFS.exists(Base + M.gccSuffix() + File); } }; } // end anonymous namespace @@ -1811,7 +1815,7 @@ // /usr // /lib <= crt*.o files compiled with '-mips32' - FilterNonExistent NonExistent(Path, D.getVFS()); + FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); // Check for FSF toolchain multilibs MultilibSet FSFMipsMultilibs; @@ -2144,7 +2148,9 @@ .flag("-m64") .flag("+mx32"); - FilterNonExistent NonExistent(Path, D.getVFS()); + // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a. + FilterNonExistent NonExistent( + Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS()); // Determine default multilib from: 32, 64, x32 // Also handle cases such as 64 on 32, 32 on 64, etc. @@ -4125,6 +4131,16 @@ } } +void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (GCCInstallation.isValid()) { + CC1Args.push_back("-isystem"); + CC1Args.push_back(DriverArgs.MakeArgString( + GCCInstallation.getParentLibPath() + "/../" + + GCCInstallation.getTriple().str() + "/include")); + } +} + bool Linux::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); } SanitizerMask Linux::getSupportedSanitizers() const { Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -296,6 +296,8 @@ const ToolChain *AuxToolChain) const { Arg *A; + const bool IsIAMCU = getToolChain().getTriple().isOSIAMCU(); + CheckPreprocessingOptions(D, Args); Args.AddLastArg(CmdArgs, options::OPT_C); @@ -562,10 +564,15 @@ AuxToolChain->AddClangCXXStdlibIncludeArgs(Args, CmdArgs); } - // Add system include arguments. - getToolChain().AddClangSystemIncludeArgs(Args, CmdArgs); - if (AuxToolChain) + // Add system include arguments for all targets but IAMCU. + if (!IsIAMCU) { + getToolChain().AddClangSystemIncludeArgs(Args, CmdArgs); + if (AuxToolChain) AuxToolChain->AddClangCXXStdlibIncludeArgs(Args, CmdArgs); + } + // For IAMCU add special include arguments. + else + getToolChain().AddIAMCUIncludeArgs(Args, CmdArgs); // Add CUDA include arguments, if needed. if (types::isCuda(Inputs[0].getType())) @@ -3602,6 +3609,7 @@ getToolChain().getTriple().isWindowsCygwinEnvironment(); bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment(); bool IsPS4CPU = getToolChain().getTriple().isPS4CPU(); + bool IsIAMCU = getToolChain().getTriple().isOSIAMCU(); // Check number of inputs for sanity. We need at least one input. assert(Inputs.size() >= 1 && "Must have at least one input."); @@ -3612,6 +3620,10 @@ bool IsCuda = types::isCuda(Input.getType()); assert((IsCuda || Inputs.size() == 1) && "Unable to handle multiple inputs."); + // C++ is not supported for IAMCU. + if (IsIAMCU && types::isCXX(Input.getType())) + D.Diag(diag::err_drv_cxx_not_supported) << getToolChain().getTriple().str(); + // Invoke ourselves in -cc1 mode. // // FIXME: Implement custom jobs for internal actions. Index: test/Driver/miamcu-opt.c =================================================================== --- test/Driver/miamcu-opt.c +++ test/Driver/miamcu-opt.c @@ -17,5 +17,5 @@ // CHECK: "-mfloat-abi" "soft" // CHECK: "-mstack-alignment=4" -// CHECK: bin/gcc +// CHECK: bin/ld // CHECK: "-static" Index: test/Driver/miamcu-opt.cpp =================================================================== --- /dev/null +++ test/Driver/miamcu-opt.cpp @@ -0,0 +1,3 @@ +// RUN: %clang -miamcu %s -### -o %t.o 2>&1 | FileCheck %s + +// CHECK: error: C++ is not supported for target 'i586-intel-elfiamcu'