Skip to content

Commit adc2ac7

Browse files
authored
[Driver][SYCL] Enforce C++ for C source files when compiling in SYCL mode (#2491)
When compiling for SYCL, we want to enforce C++ compilations. For all C source file types, enforce C++. Also move the -x c check to be in line with the other -x processing
1 parent 892ecba commit adc2ac7

File tree

7 files changed

+192
-138
lines changed

7 files changed

+192
-138
lines changed

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ def err_drv_expecting_fopenmp_with_fopenmp_targets : Error<
274274
def err_drv_expecting_fsycl_with_sycl_opt : Error<
275275
"The option %0 must be used in conjunction with -fsycl to enable offloading.">;
276276
def err_drv_fsycl_with_c_type : Error<
277-
"The option %0%1 must not be used in conjunction with -fsycl which expects C++ source.">;
277+
"The option '%0' must not be used in conjunction with '-fsycl', which expects C++ source.">;
278278
def warn_drv_omp_offload_target_duplicate : Warning<
279279
"The OpenMP offloading target '%0' is similar to target '%1' already specified - will be ignored.">,
280280
InGroup<OpenMPTarget>;

clang/lib/Driver/Driver.cpp

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -810,14 +810,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
810810
return SYCLArg;
811811
};
812812

813-
// Emit an error if c-compilation is forced in -fsycl mode
814-
if (HasValidSYCLRuntime)
815-
for (StringRef XValue : C.getInputArgs().getAllArgValues(options::OPT_x)) {
816-
if (XValue == "c" || XValue == "c-header")
817-
C.getDriver().Diag(clang::diag::err_drv_fsycl_with_c_type)
818-
<< "-x " << XValue;
819-
}
820-
821813
Arg *SYCLTargets = getArgRequiringSYCLRuntime(options::OPT_fsycl_targets_EQ);
822814
Arg *SYCLLinkTargets =
823815
getArgRequiringSYCLRuntime(options::OPT_fsycl_link_targets_EQ);
@@ -2385,12 +2377,13 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
23852377
// actually use it, so we warn about unused -x arguments.
23862378
types::ID InputType = types::TY_Nothing;
23872379
Arg *InputTypeArg = nullptr;
2380+
bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false);
23882381

23892382
// The last /TC or /TP option sets the input type to C or C++ globally.
23902383
if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
23912384
options::OPT__SLASH_TP)) {
23922385
InputTypeArg = TCTP;
2393-
InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2386+
InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) && !IsSYCL
23942387
? types::TY_C
23952388
: types::TY_CXX;
23962389

@@ -2423,6 +2416,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
24232416
if (InputTypeArg)
24242417
InputTypeArg->claim();
24252418

2419+
types::ID CType = types::TY_C;
2420+
// For SYCL, all source file inputs are considered C++.
2421+
if (IsSYCL)
2422+
CType = types::TY_CXX;
2423+
24262424
// stdin must be handled specially.
24272425
if (memcmp(Value, "-", 2) == 0) {
24282426
// If running with -E, treat as a C input (this changes the builtin
@@ -2433,7 +2431,7 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
24332431
if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP())
24342432
Diag(IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
24352433
: clang::diag::err_drv_unknown_stdin_type);
2436-
Ty = types::TY_C;
2434+
Ty = CType;
24372435
} else {
24382436
// Otherwise lookup by extension.
24392437
// Fallback is C if invoked as C preprocessor, C++ if invoked with
@@ -2443,9 +2441,29 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
24432441
if (const char *Ext = strrchr(Value, '.'))
24442442
Ty = TC.LookupTypeForExtension(Ext + 1);
24452443

2444+
// For SYCL, convert C-type sources to C++-type sources.
2445+
if (IsSYCL) {
2446+
switch (Ty) {
2447+
case types::TY_C:
2448+
Ty = types::TY_CXX;
2449+
break;
2450+
case types::TY_CHeader:
2451+
Ty = types::TY_CXXHeader;
2452+
break;
2453+
case types::TY_PP_C:
2454+
Ty = types::TY_PP_CXX;
2455+
break;
2456+
case types::TY_PP_CHeader:
2457+
Ty = types::TY_PP_CXXHeader;
2458+
break;
2459+
default:
2460+
break;
2461+
}
2462+
}
2463+
24462464
if (Ty == types::TY_INVALID) {
24472465
if (CCCIsCPP())
2448-
Ty = types::TY_C;
2466+
Ty = CType;
24492467
else if (IsCLMode() && Args.hasArgNoClaim(options::OPT_E))
24502468
Ty = types::TY_CXX;
24512469
else
@@ -2504,7 +2522,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
25042522
if (DiagnoseInputExistence(Args, Value, types::TY_C,
25052523
/*TypoCorrect=*/false)) {
25062524
Arg *InputArg = MakeInputArg(Args, Opts, A->getValue());
2507-
Inputs.push_back(std::make_pair(types::TY_C, InputArg));
2525+
Inputs.push_back(
2526+
std::make_pair(IsSYCL ? types::TY_CXX : types::TY_C, InputArg));
25082527
}
25092528
A->claim();
25102529
} else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
@@ -2532,6 +2551,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
25322551
Diag(clang::diag::err_drv_unknown_language) << A->getValue();
25332552
InputType = types::TY_Object;
25342553
}
2554+
// Emit an error if c-compilation is forced in -fsycl mode
2555+
if (IsSYCL && (InputType == types::TY_C || InputType == types::TY_PP_C ||
2556+
InputType == types::TY_CHeader))
2557+
Diag(clang::diag::err_drv_fsycl_with_c_type) << A->getAsString(Args);
2558+
25352559
} else if (A->getOption().getID() == options::OPT_U) {
25362560
assert(A->getNumValues() == 1 && "The /U option has one value.");
25372561
StringRef Val = A->getValue(0);

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "clang/Basic/CharInfo.h"
2727
#include "clang/Basic/CodeGenOptions.h"
2828
#include "clang/Basic/LangOptions.h"
29+
#include "clang/Basic/LangStandard.h"
2930
#include "clang/Basic/ObjCRuntime.h"
3031
#include "clang/Basic/Version.h"
3132
#include "clang/Driver/Distro.h"
@@ -5153,8 +5154,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
51535154
CmdArgs.push_back("-std=c++98");
51545155
else
51555156
CmdArgs.push_back("-std=c89");
5156-
else
5157+
else {
5158+
if (Args.hasArg(options::OPT_fsycl)) {
5159+
// Use of -std= with 'C' is not supported for SYCL.
5160+
const LangStandard *LangStd =
5161+
LangStandard::getLangStandardForName(Std->getValue());
5162+
if (LangStd && LangStd->getLanguage() == Language::C)
5163+
D.Diag(diag::err_drv_argument_not_allowed_with)
5164+
<< Std->getAsString(Args) << "-fsycl";
5165+
}
51575166
Std->render(Args, CmdArgs);
5167+
}
51585168

51595169
// If -f(no-)trigraphs appears after the language standard flag, honor it.
51605170
if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,

clang/test/Driver/sycl-cxx-default.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// When -fsycl is used, C++ source is the default
2+
// REQUIRES: clang-driver
3+
4+
// RUN: %clang -c -fsycl %s -### 2>&1 \
5+
// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s
6+
// RUN: %clangxx -c -fsycl %s -### 2>&1 \
7+
// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s
8+
// RUN: %clang_cl -c -fsycl %s -### 2>&1 \
9+
// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s
10+
// RUN: %clang_cl -c -fsycl /TC %s -### 2>&1 \
11+
// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s
12+
// RUN: %clang_cl -c -fsycl /Tc%s -### 2>&1 \
13+
// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s
14+
// CXX_TYPE_CHECK: "-x" "c++"
15+
// CXX_TYPE_CHECK-NOT: "-x" "c"
16+
17+
// RUN: %clang -c -fsycl -std=c99 %s -### 2>&1 \
18+
// RUN: | FileCheck -check-prefix=C_SYCL_ERROR_CHECK %s
19+
// C_SYCL_ERROR_CHECK: error: invalid argument '-std=c99' not allowed with '-fsycl

clang/test/Driver/sycl-offload-win.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@
6363
// RUN: | FileCheck -DLIB=%t.lib %s -check-prefix=FOFFLOAD_STATIC_LIB_SRC
6464

6565
// FOFFLOAD_STATIC_LIB_SRC: 0: input, "[[INPUTLIB:.+\.lib]]", object, (host-sycl)
66-
// FOFFLOAD_STATIC_LIB_SRC: 1: input, "[[INPUTC:.+\.c]]", c, (host-sycl)
67-
// FOFFLOAD_STATIC_LIB_SRC: 2: preprocessor, {1}, cpp-output, (host-sycl)
68-
// FOFFLOAD_STATIC_LIB_SRC: 3: input, "[[INPUTC]]", c, (device-sycl)
69-
// FOFFLOAD_STATIC_LIB_SRC: 4: preprocessor, {3}, cpp-output, (device-sycl)
66+
// FOFFLOAD_STATIC_LIB_SRC: 1: input, "[[INPUTC:.+\.c]]", c++, (host-sycl)
67+
// FOFFLOAD_STATIC_LIB_SRC: 2: preprocessor, {1}, c++-cpp-output, (host-sycl)
68+
// FOFFLOAD_STATIC_LIB_SRC: 3: input, "[[INPUTC]]", c++, (device-sycl)
69+
// FOFFLOAD_STATIC_LIB_SRC: 4: preprocessor, {3}, c++-cpp-output, (device-sycl)
7070
// FOFFLOAD_STATIC_LIB_SRC: 5: compiler, {4}, sycl-header, (device-sycl)
71-
// FOFFLOAD_STATIC_LIB_SRC: 6: offload, "host-sycl (x86_64-pc-windows-msvc)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, cpp-output
71+
// FOFFLOAD_STATIC_LIB_SRC: 6: offload, "host-sycl (x86_64-pc-windows-msvc)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, c++-cpp-output
7272
// FOFFLOAD_STATIC_LIB_SRC: 7: compiler, {6}, ir, (host-sycl)
7373
// FOFFLOAD_STATIC_LIB_SRC: 8: backend, {7}, assembler, (host-sycl)
7474
// FOFFLOAD_STATIC_LIB_SRC: 9: assembler, {8}, object, (host-sycl)
@@ -97,9 +97,9 @@
9797

9898
// Check for /P behaviors
9999
// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -P %s -### 2>&1 | FileCheck -check-prefix=FSYCL_P %s
100-
// FSYCL_P: clang{{.*}} "-cc1" "-triple" "spir64-unknown-unknown-sycldevice" {{.*}} "-E" {{.*}} "-o" "[[DEVICEPP:.+\.i]]"
101-
// FSYCL_P: clang{{.*}} "-cc1" "-triple" "x86_64-pc-windows-msvc{{.*}}" {{.*}} "-E" {{.*}} "-o" "[[HOSTPP:.+\.i]]"
102-
// FSYCL_P: clang-offload-bundler{{.*}} "-type=i" "-targets=sycl-spir64-unknown-unknown-sycldevice,host-x86_64-pc-windows-msvc" {{.*}} "-inputs=[[DEVICEPP]],[[HOSTPP]]"
100+
// FSYCL_P: clang{{.*}} "-cc1" "-triple" "spir64-unknown-unknown-sycldevice" {{.*}} "-E" {{.*}} "-o" "[[DEVICEPP:.+\.ii]]"
101+
// FSYCL_P: clang{{.*}} "-cc1" "-triple" "x86_64-pc-windows-msvc{{.*}}" {{.*}} "-E" {{.*}} "-o" "[[HOSTPP:.+\.ii]]"
102+
// FSYCL_P: clang-offload-bundler{{.*}} "-type=ii" "-targets=sycl-spir64-unknown-unknown-sycldevice,host-x86_64-pc-windows-msvc" {{.*}} "-inputs=[[DEVICEPP]],[[HOSTPP]]"
103103

104104
// TODO: SYCL specific fail - analyze and enable
105105
// XFAIL: windows-msvc

0 commit comments

Comments
 (0)