Skip to content

[Driver][SYCL] For SYCL compilations, force C++ source even with .c #2491

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def err_drv_expecting_fopenmp_with_fopenmp_targets : Error<
def err_drv_expecting_fsycl_with_sycl_opt : Error<
"The option %0 must be used in conjunction with -fsycl to enable offloading.">;
def err_drv_fsycl_with_c_type : Error<
"The option %0%1 must not be used in conjunction with -fsycl which expects C++ source.">;
"The option '%0' must not be used in conjunction with '-fsycl', which expects C++ source.">;
def warn_drv_omp_offload_target_duplicate : Warning<
"The OpenMP offloading target '%0' is similar to target '%1' already specified - will be ignored.">,
InGroup<OpenMPTarget>;
Expand Down
48 changes: 36 additions & 12 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,14 +810,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
return SYCLArg;
};

// Emit an error if c-compilation is forced in -fsycl mode
if (HasValidSYCLRuntime)
for (StringRef XValue : C.getInputArgs().getAllArgValues(options::OPT_x)) {
if (XValue == "c" || XValue == "c-header")
C.getDriver().Diag(clang::diag::err_drv_fsycl_with_c_type)
<< "-x " << XValue;
}

Arg *SYCLTargets = getArgRequiringSYCLRuntime(options::OPT_fsycl_targets_EQ);
Arg *SYCLLinkTargets =
getArgRequiringSYCLRuntime(options::OPT_fsycl_link_targets_EQ);
Expand Down Expand Up @@ -2385,12 +2377,13 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
// actually use it, so we warn about unused -x arguments.
types::ID InputType = types::TY_Nothing;
Arg *InputTypeArg = nullptr;
bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false);

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

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

types::ID CType = types::TY_C;
// For SYCL, all source file inputs are considered C++.
if (IsSYCL)
CType = types::TY_CXX;

// stdin must be handled specially.
if (memcmp(Value, "-", 2) == 0) {
// If running with -E, treat as a C input (this changes the builtin
Expand All @@ -2433,7 +2431,7 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP())
Diag(IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
: clang::diag::err_drv_unknown_stdin_type);
Ty = types::TY_C;
Ty = CType;
} else {
// Otherwise lookup by extension.
// Fallback is C if invoked as C preprocessor, C++ if invoked with
Expand All @@ -2443,9 +2441,29 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
if (const char *Ext = strrchr(Value, '.'))
Ty = TC.LookupTypeForExtension(Ext + 1);

// For SYCL, convert C-type sources to C++-type sources.
if (IsSYCL) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a switch instead? I would fear this getting unwieldy otherwise in pulldown/etc or if this got any more complicated.

switch (Ty) {
case types::TY_C:
Ty = types::TY_CXX;
break;
case types::TY_CHeader:
Ty = types::TY_CXXHeader;
break;
case types::TY_PP_C:
Ty = types::TY_PP_CXX;
break;
case types::TY_PP_CHeader:
Ty = types::TY_PP_CXXHeader;
break;
default:
break;
}
Comment on lines +2446 to +2461
Copy link
Contributor

@AGindinson AGindinson Sep 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never thought I'd say this as a Python hater, but it's a shame we don't have something really analogous to a Python dict :D Take any alternative like a std::map - it's too verbose and therefore meaningless for a 4-case switch...

Copy link
Contributor

@keryell keryell Sep 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In C++23 I hope the pattern matching proposal https://wg21.link/p1371 will be voted in!
Python hater? Do not forget that C++23 is just Python, but running at 100x the speed. :-)

}

if (Ty == types::TY_INVALID) {
if (CCCIsCPP())
Ty = types::TY_C;
Ty = CType;
else if (IsCLMode() && Args.hasArgNoClaim(options::OPT_E))
Ty = types::TY_CXX;
else
Expand Down Expand Up @@ -2504,7 +2522,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
if (DiagnoseInputExistence(Args, Value, types::TY_C,
/*TypoCorrect=*/false)) {
Arg *InputArg = MakeInputArg(Args, Opts, A->getValue());
Inputs.push_back(std::make_pair(types::TY_C, InputArg));
Inputs.push_back(
std::make_pair(IsSYCL ? types::TY_CXX : types::TY_C, InputArg));
}
A->claim();
} else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
Expand Down Expand Up @@ -2532,6 +2551,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
Diag(clang::diag::err_drv_unknown_language) << A->getValue();
InputType = types::TY_Object;
}
// Emit an error if c-compilation is forced in -fsycl mode
if (IsSYCL && (InputType == types::TY_C || InputType == types::TY_PP_C ||
InputType == types::TY_CHeader))
Diag(clang::diag::err_drv_fsycl_with_c_type) << A->getAsString(Args);

} else if (A->getOption().getID() == options::OPT_U) {
assert(A->getNumValues() == 1 && "The /U option has one value.");
StringRef Val = A->getValue(0);
Expand Down
12 changes: 11 additions & 1 deletion clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/LangStandard.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Version.h"
#include "clang/Driver/Distro.h"
Expand Down Expand Up @@ -5153,8 +5154,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-std=c++98");
else
CmdArgs.push_back("-std=c89");
else
else {
if (Args.hasArg(options::OPT_fsycl)) {
// Use of -std= with 'C' is not supported for SYCL.
const LangStandard *LangStd =
LangStandard::getLangStandardForName(Std->getValue());
if (LangStd && LangStd->getLanguage() == Language::C)
D.Diag(diag::err_drv_argument_not_allowed_with)
<< Std->getAsString(Args) << "-fsycl";
}
Std->render(Args, CmdArgs);
}

// If -f(no-)trigraphs appears after the language standard flag, honor it.
if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
Expand Down
19 changes: 19 additions & 0 deletions clang/test/Driver/sycl-cxx-default.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/// When -fsycl is used, C++ source is the default
// REQUIRES: clang-driver

// RUN: %clang -c -fsycl %s -### 2>&1 \
// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s
// RUN: %clangxx -c -fsycl %s -### 2>&1 \
// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s
// RUN: %clang_cl -c -fsycl %s -### 2>&1 \
// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s
// RUN: %clang_cl -c -fsycl /TC %s -### 2>&1 \
// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s
// RUN: %clang_cl -c -fsycl /Tc%s -### 2>&1 \
// RUN: | FileCheck -check-prefix=CXX_TYPE_CHECK %s
// CXX_TYPE_CHECK: "-x" "c++"
// CXX_TYPE_CHECK-NOT: "-x" "c"

// RUN: %clang -c -fsycl -std=c99 %s -### 2>&1 \
// RUN: | FileCheck -check-prefix=C_SYCL_ERROR_CHECK %s
// C_SYCL_ERROR_CHECK: error: invalid argument '-std=c99' not allowed with '-fsycl
16 changes: 8 additions & 8 deletions clang/test/Driver/sycl-offload-win.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@
// RUN: | FileCheck -DLIB=%t.lib %s -check-prefix=FOFFLOAD_STATIC_LIB_SRC

// FOFFLOAD_STATIC_LIB_SRC: 0: input, "[[INPUTLIB:.+\.lib]]", object, (host-sycl)
// FOFFLOAD_STATIC_LIB_SRC: 1: input, "[[INPUTC:.+\.c]]", c, (host-sycl)
// FOFFLOAD_STATIC_LIB_SRC: 2: preprocessor, {1}, cpp-output, (host-sycl)
// FOFFLOAD_STATIC_LIB_SRC: 3: input, "[[INPUTC]]", c, (device-sycl)
// FOFFLOAD_STATIC_LIB_SRC: 4: preprocessor, {3}, cpp-output, (device-sycl)
// FOFFLOAD_STATIC_LIB_SRC: 1: input, "[[INPUTC:.+\.c]]", c++, (host-sycl)
// FOFFLOAD_STATIC_LIB_SRC: 2: preprocessor, {1}, c++-cpp-output, (host-sycl)
// FOFFLOAD_STATIC_LIB_SRC: 3: input, "[[INPUTC]]", c++, (device-sycl)
// FOFFLOAD_STATIC_LIB_SRC: 4: preprocessor, {3}, c++-cpp-output, (device-sycl)
// FOFFLOAD_STATIC_LIB_SRC: 5: compiler, {4}, sycl-header, (device-sycl)
// FOFFLOAD_STATIC_LIB_SRC: 6: offload, "host-sycl (x86_64-pc-windows-msvc)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, cpp-output
// FOFFLOAD_STATIC_LIB_SRC: 6: offload, "host-sycl (x86_64-pc-windows-msvc)" {2}, "device-sycl (spir64-unknown-unknown-sycldevice)" {5}, c++-cpp-output
// FOFFLOAD_STATIC_LIB_SRC: 7: compiler, {6}, ir, (host-sycl)
// FOFFLOAD_STATIC_LIB_SRC: 8: backend, {7}, assembler, (host-sycl)
// FOFFLOAD_STATIC_LIB_SRC: 9: assembler, {8}, object, (host-sycl)
Expand Down Expand Up @@ -97,9 +97,9 @@

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

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