Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1088,6 +1088,9 @@ HelpText<"Force realign the stack at entry to every function">; def mstack_alignment : Joined<["-"], "mstack-alignment=">, Group, Flags<[CC1Option]>, HelpText<"Set the stack alignment">; +def mthread_model : Separate<["-"], "mthread-model">, Group, Flags<[CC1Option]>, + HelpText<"The thread model to use, e.g. posix, single (posix by default)">; + def mmmx : Flag<["-"], "mmmx">, Group; def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group; def mno_3dnow : Flag<["-"], "mno-3dnow">, Group; Index: include/clang/Driver/ToolChain.h =================================================================== --- include/clang/Driver/ToolChain.h +++ include/clang/Driver/ToolChain.h @@ -248,6 +248,9 @@ /// UseSjLjExceptions - Does this tool chain use SjLj exceptions. virtual bool UseSjLjExceptions() const { return false; } + /// getThreadModel() - Which thread model does this target use? + virtual std::string getThreadModel() const { return "posix"; } + /// ComputeLLVMTriple - Return the LLVM target triple to use, after taking /// command line arguments into account. virtual std::string Index: include/clang/Frontend/CodeGenOptions.h =================================================================== --- include/clang/Frontend/CodeGenOptions.h +++ include/clang/Frontend/CodeGenOptions.h @@ -134,6 +134,9 @@ /// The name of the relocation model to use. std::string RelocationModel; + /// The thread model to use + std::string ThreadModel; + /// Path to blacklist file for sanitizers. std::string SanitizerBlacklistFile; Index: lib/CodeGen/BackendUtil.cpp =================================================================== --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -425,6 +425,11 @@ llvm::TargetOptions Options; + Options.ThreadModel = + llvm::StringSwitch(CodeGenOpts.ThreadModel) + .Case("posix", llvm::ThreadModel::POSIX) + .Case("single", llvm::ThreadModel::Single); + if (CodeGenOpts.DisableIntegratedAS) Options.DisableIntegratedAS = true; Index: lib/Driver/Driver.cpp =================================================================== --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -658,9 +658,12 @@ OS << "Target: " << TC.getTripleString() << '\n'; // Print the threading model. - // - // FIXME: Implement correctly. - OS << "Thread model: " << "posix" << '\n'; + OS << "Thread model: "; + if (Arg *A = C.getArgs().getLastArg(options::OPT_mthread_model)) + OS << A->getValue(); + else + OS << TC.getThreadModel(); + OS << '\n'; } /// PrintDiagnosticCategories - Implement the --print-diagnostic-categories Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -2773,6 +2773,12 @@ } } + CmdArgs.push_back("-mthread-model"); + if (Arg *A = Args.getLastArg(options::OPT_mthread_model)) + CmdArgs.push_back(A->getValue()); + else + CmdArgs.push_back(Args.MakeArgString(getToolChain().getThreadModel())); + if (!Args.hasFlag(options::OPT_fmerge_all_constants, options::OPT_fno_merge_all_constants)) CmdArgs.push_back("-fno-merge-all-constants"); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -440,6 +440,11 @@ Args.hasArg(OPT_cl_fast_relaxed_math); Opts.UnwindTables = Args.hasArg(OPT_munwind_tables); Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic"); + Opts.ThreadModel = Args.getLastArgValue(OPT_mthread_model, "posix"); + if (Opts.ThreadModel != "posix" && Opts.ThreadModel != "single") + Diags.Report(diag::err_drv_invalid_value) + << Args.getLastArg(OPT_mthread_model)->getAsString(Args) + << Opts.ThreadModel; Opts.TrapFuncName = Args.getLastArgValue(OPT_ftrap_function_EQ); Opts.UseInitArray = Args.hasArg(OPT_fuse_init_array); Index: test/Driver/thread-model.c =================================================================== --- test/Driver/thread-model.c +++ test/Driver/thread-model.c @@ -0,0 +1,13 @@ +// RUN: %clang -### -c %s -mthread-model posix -v 2>&1 | FileCheck -check-prefix CHECK-POSIX %s +// RUN: %clang -### -c %s -mthread-model single -v 2>&1 | FileCheck -check-prefix CHECK-SINGLE %s +// RUN: not %clang -c %s -mthread-model silly -v 2>&1 | FileCheck -check-prefix CHECK-INVALID %s +// CHECK-POSIX: "-mthread-model" "posix" +// CHECK-SINGLE: "-mthread-model" "single" +// CHECK-INVALID: error: invalid value 'silly' in '-mthread-model silly' + +// RUN: %clang -### -target arm-unknown-linux-gnu -c %s -v 2>&1 | FileCheck -check-prefix CHECK-LINUX-POSIX %s +// RUN: %clang -### -target arm-unknown-linux-gnu -c %s -v -mthread-model single 2>&1 | FileCheck -check-prefix CHECK-LINUX-SINGLE %s +// CHECK-LINUX-POSIX: Thread model: posix +// CHECK-LINUX-POSIX: "-mthread-model" "posix" +// CHECK-LINUX-SINGLE: Thread model: single +// CHECK-LINUX-SINGLE: "-mthread-model" "single"