]> granicus.if.org Git - clang/commitdiff
[CUDA] Let NVPTX inherit the host's calling conventions.
authorJustin Lebar <jlebar@google.com>
Thu, 5 Jan 2017 16:53:38 +0000 (16:53 +0000)
committerJustin Lebar <jlebar@google.com>
Thu, 5 Jan 2017 16:53:38 +0000 (16:53 +0000)
Summary:
When compiling device code, we may still see host code with explicit
calling conventions.  NVPTX needs to claim that it supports these CCs,
so that (a) we don't raise noisy warnings, and (b) we don't break
existing code which relies on the existence of these CCs when
specializing templates.  (If a CC doesn't exist, clang ignores it, so
two template specializations which are different only insofar as one
specifies a CC are considered identical and therefore are an error if
that CC is not supported.)

Reviewers: tra

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D28323

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@291136 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Basic/Targets.cpp
test/SemaCUDA/cuda-inherits-calling-conv.cu [new file with mode: 0644]

index 4716b5e9b1c387be9fcb5d830008d47c1bb25e65..4d2b3d007599e0c5eefea4a80b084b11520d6d41 100644 (file)
@@ -1962,6 +1962,16 @@ public:
     Opts.support("cl_khr_local_int32_base_atomics");
     Opts.support("cl_khr_local_int32_extended_atomics");
   }
+
+  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
+    // CUDA compilations support all of the host's calling conventions.
+    //
+    // TODO: We should warn if you apply a non-default CC to anything other than
+    // a host function.
+    if (HostTarget)
+      return HostTarget->checkCallingConvention(CC);
+    return CCCR_Warning;
+  }
 };
 
 const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = {
diff --git a/test/SemaCUDA/cuda-inherits-calling-conv.cu b/test/SemaCUDA/cuda-inherits-calling-conv.cu
new file mode 100644 (file)
index 0000000..67c438f
--- /dev/null
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=c++11 -triple i386-windows-msvc \
+// RUN:   -aux-triple nvptx-nvidia-cuda -fsyntax-only -verify %s
+
+// RUN: %clang_cc1 -std=c++11 -triple nvptx-nvidia-cuda \
+// RUN:   -aux-triple i386-windows-msvc -fsyntax-only \
+// RUN:   -fcuda-is-device -verify %s
+
+// RUN: %clang_cc1 -std=c++11 -triple nvptx-nvidia-cuda \
+// RUN:   -aux-triple x86_64-linux-gnu -fsyntax-only \
+// RUN:   -fcuda-is-device -verify -verify-ignore-unexpected=note \
+// RUN:   -DEXPECT_ERR %s
+
+// CUDA device code should inherit the host's calling conventions.
+
+template <class T>
+struct Foo;
+
+template <class T>
+struct Foo<T()> {};
+
+// On x86_64-linux-gnu, this is a redefinition of the template, because the
+// __fastcall calling convention doesn't exist (and is therefore ignored).
+#ifndef EXPECT_ERR
+// expected-no-diagnostics
+#else
+// expected-error@+4 {{redefinition of 'Foo}}
+// expected-warning@+3 {{calling convention '__fastcall' ignored}}
+#endif
+template <class T>
+struct Foo<T __fastcall()> {};