Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -533,3 +533,12 @@ ${CLANG_BINARY_DIR}/share/clang/cmake/ClangConfig.cmake COPYONLY) endif () + +option(ENABLE_CLANG_OPENMP "Enable OpenMP support." ON) +if (ENABLE_CLANG_OPENMP) + set(CLANG_ENABLE_OPENMP "1") + add_definitions(-DENABLE_CLANG_OPENMP) +else() + set(CLANG_ENABLE_OPENMP "0") +endif() + Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -2592,6 +2592,12 @@ Result.append(UID.begin(), UID.end()); } +enum LibOpenMP { + LibUnknown, + LibGOMP, + LibIOMP5 +}; + void Clang::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -3794,8 +3800,23 @@ Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type); // Forward flags for OpenMP - if (Args.hasArg(options::OPT_fopenmp_EQ) || - Args.hasArg(options::OPT_fopenmp)) { + LibOpenMP UsedOpenMPLib = LibUnknown; + if (const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ)) { + UsedOpenMPLib = llvm::StringSwitch(A->getValue()) + .Case("libgomp", LibGOMP) + .Case("libiomp5", LibIOMP5) + .Default(LibUnknown); + if (UsedOpenMPLib == LibUnknown) + getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << A->getValue(); + } else if (Args.hasArg(options::OPT_fopenmp)) { +#ifdef ENABLE_CLANG_OPENMP + UsedOpenMPLib = LibIOMP5; +#else + UsedOpenMPLib = LibGOMP; +#endif // ENABLE_CLANG_OPENMP + } + if (UsedOpenMPLib == LibIOMP5) { CmdArgs.push_back("-fopenmp"); } @@ -6215,12 +6236,6 @@ Args.AddLastArg(CmdArgs, options::OPT_Mach); } -enum LibOpenMP { - LibUnknown, - LibGOMP, - LibIOMP5 -}; - void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -6288,7 +6303,11 @@ getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << A->getValue(); } else if (Args.hasArg(options::OPT_fopenmp)) { +#ifdef ENABLE_CLANG_OPENMP UsedOpenMPLib = LibIOMP5; +#else + UsedOpenMPLib = LibGOMP; +#endif // ENABLE_CLANG_OPENMP } switch (UsedOpenMPLib) { case LibGOMP: @@ -8013,7 +8032,11 @@ D.Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << A->getValue(); } else if (Args.hasArg(options::OPT_fopenmp)) { +#ifdef ENABLE_CLANG_OPENMP UsedOpenMPLib = LibIOMP5; +#else + UsedOpenMPLib = LibGOMP; +#endif // ENABLE_CLANG_OPENMP } switch (UsedOpenMPLib) { case LibGOMP: Index: test/OpenMP/linking.c =================================================================== --- test/OpenMP/linking.c +++ test/OpenMP/linking.c @@ -1,5 +1,6 @@ // Test the that the driver produces reasonable linker invocations with // -fopenmp or -fopenmp|libgomp. +// REQUIRES: openmp // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -fopenmp -target i386-unknown-linux \ Index: test/OpenMP/linking_no_openmp.c =================================================================== --- test/OpenMP/linking_no_openmp.c +++ test/OpenMP/linking_no_openmp.c @@ -0,0 +1,70 @@ +// Test the that the driver produces reasonable linker invocations with +// -fopenmp or -fopenmp|libgomp. +// REQUIRES: no_openmp +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -fopenmp -target i386-unknown-linux \ +// RUN: | FileCheck --check-prefix=CHECK-LD-32 %s +// CHECK-LD-32: "{{.*}}ld{{(.exe)?}}" +// CHECK-LD-32: "-lgomp" "-lrt" "-lgcc" +// CHECK-LD-32: "-lpthread" "-lc" +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -fopenmp -target x86_64-unknown-linux \ +// RUN: | FileCheck --check-prefix=CHECK-LD-64 %s +// CHECK-LD-64: "{{.*}}ld{{(.exe)?}}" +// CHECK-LD-64: "-lgomp" "-lrt" "-lgcc" +// CHECK-LD-64: "-lpthread" "-lc" +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -fopenmp=libgomp -target i386-unknown-linux \ +// RUN: | FileCheck --check-prefix=CHECK-GOMP-LD-32 %s +// CHECK-GOMP-LD-32: "{{.*}}ld{{(.exe)?}}" +// CHECK-GOMP-LD-32: "-lgomp" "-lrt" "-lgcc" +// CHECK-GOMP-LD-32: "-lpthread" "-lc" +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -fopenmp=libgomp -target x86_64-unknown-linux \ +// RUN: | FileCheck --check-prefix=CHECK-GOMP-LD-64 %s +// CHECK-GOMP-LD-64: "{{.*}}ld{{(.exe)?}}" +// CHECK-GOMP-LD-64: "-lgomp" "-lrt" "-lgcc" +// CHECK-GOMP-LD-64: "-lpthread" "-lc" +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -fopenmp -target i386-unknown-linux \ +// RUN: | FileCheck --check-prefix=CHECK-IOMP5-LD-32 %s +// CHECK-IOMP5-LD-32: "{{.*}}ld{{(.exe)?}}" +// CHECK-IOMP5-LD-32: "-lgomp" "-lrt" "-lgcc" +// CHECK-IOMP5-LD-32: "-lpthread" "-lc" +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -fopenmp -target x86_64-unknown-linux \ +// RUN: | FileCheck --check-prefix=CHECK-IOMP5-LD-64 %s +// CHECK-IOMP5-LD-64: "{{.*}}ld{{(.exe)?}}" +// CHECK-IOMP5-LD-64: "-lgomp" "-lrt" "-lgcc" +// CHECK-IOMP5-LD-64: "-lpthread" "-lc" +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -fopenmp=lib -target i386-unknown-linux \ +// RUN: | FileCheck --check-prefix=CHECK-LIB-LD-32 %s +// CHECK-LIB-LD-32: error: unsupported argument 'lib' to option 'fopenmp=' +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -fopenmp=lib -target x86_64-unknown-linux \ +// RUN: | FileCheck --check-prefix=CHECK-LIB-LD-64 %s +// CHECK-LIB-LD-64: error: unsupported argument 'lib' to option 'fopenmp=' +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -fopenmp -fopenmp=libgomp -target i386-unknown-linux \ +// RUN: | FileCheck --check-prefix=CHECK-LD-OVERRIDE-32 %s +// CHECK-LD-OVERRIDE-32: "{{.*}}ld{{(.exe)?}}" +// CHECK-LD-OVERRIDE-32: "-lgomp" "-lrt" "-lgcc" +// CHECK-LD-OVERRIDE-32: "-lpthread" "-lc" +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -fopenmp -fopenmp=libgomp -target x86_64-unknown-linux \ +// RUN: | FileCheck --check-prefix=CHECK-LD-OVERRIDE-64 %s +// CHECK-LD-OVERRIDE-64: "{{.*}}ld{{(.exe)?}}" +// CHECK-LD-OVERRIDE-64: "-lgomp" "-lrt" "-lgcc" +// CHECK-LD-OVERRIDE-64: "-lpthread" "-lc" +// Index: test/lit.cfg =================================================================== --- test/lit.cfg +++ test/lit.cfg @@ -210,6 +210,11 @@ if config.clang_examples: config.available_features.add('examples') +if config.clang_openmp: + config.available_features.add('openmp') +else: + config.available_features.add('no_openmp') + # Note that when substituting %clang_cc1 also fill in the include directory of # the builtin headers. Those are part of even a freestanding environment, but # Clang relies on the driver to locate them. Index: test/lit.site.cfg.in =================================================================== --- test/lit.site.cfg.in +++ test/lit.site.cfg.in @@ -20,6 +20,7 @@ config.enable_shared = @ENABLE_SHARED@ config.enable_backtrace = "@ENABLE_BACKTRACES@" config.host_arch = "@HOST_ARCH@" +config.clang_openmp = "@CLANG_ENABLE_OPENMP@" # Support substitution of the tools and libs dirs with user parameters. This is # used when we can't determine the tool dir at configuration time.