Warning: This file is not a C or C++ file. It does not have highlighting.
1 | //===-- Wrapper for C standard stdio.h declarations on the GPU ------------===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #if !defined(_OPENMP) && !defined(__HIP__) && !defined(__CUDA__) |
10 | #error "This file is for GPU offloading compilation only" |
11 | #endif |
12 | |
13 | #include_next <stdio.h> |
14 | |
15 | // In some old versions of glibc, other standard headers sometimes define |
16 | // special macros (e.g., __need_FILE) before including stdio.h to cause stdio.h |
17 | // to produce special definitions. Future includes of stdio.h when those |
18 | // special macros are undefined are expected to produce the normal definitions |
19 | // from stdio.h. |
20 | // |
21 | // We do not apply our include guard (__CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__) |
22 | // unconditionally to the above include_next. Otherwise, after an occurrence of |
23 | // the first glibc stdio.h use case described above, the include_next would be |
24 | // skipped for remaining includes of stdio.h, leaving required symbols |
25 | // undefined. |
26 | // |
27 | // We make the following assumptions to handle all use cases: |
28 | // |
29 | // 1. If the above include_next produces special glibc definitions, then (a) it |
30 | // does not produce the normal definitions that we must intercept below, (b) |
31 | // the current file was included from a glibc header that already defined |
32 | // __GLIBC__ (usually by including glibc's <features.h>), and (c) the above |
33 | // include_next does not define _STDIO_H. In that case, we skip the rest of |
34 | // the current file and don't guard against future includes. |
35 | // 2. If the above include_next produces the normal stdio.h definitions, then |
36 | // either (a) __GLIBC__ is not defined because C headers are from some other |
37 | // libc implementation or (b) the above include_next defines _STDIO_H to |
38 | // prevent the above include_next from having any effect in the future. |
39 | #if !defined(__GLIBC__) || defined(_STDIO_H) |
40 | |
41 | #ifndef __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__ |
42 | #define __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__ |
43 | |
44 | #if __has_include(<llvm-libc-decls/stdio.h>) |
45 | |
46 | #if defined(__HIP__) || defined(__CUDA__) |
47 | #define __LIBC_ATTRS __attribute__((device)) |
48 | #endif |
49 | |
50 | // Some headers provide these as macros. Temporarily undefine them so they do |
51 | // not conflict with any definitions for the GPU. |
52 | |
53 | #pragma push_macro("stdout") |
54 | #pragma push_macro("stdin") |
55 | #pragma push_macro("stderr") |
56 | |
57 | #undef stdout |
58 | #undef stderr |
59 | #undef stdin |
60 | |
61 | #pragma omp begin declare target |
62 | |
63 | #include <llvm-libc-decls/stdio.h> |
64 | |
65 | #pragma omp end declare target |
66 | |
67 | #undef __LIBC_ATTRS |
68 | |
69 | // Restore the original macros when compiling on the host. |
70 | #if !defined(__NVPTX__) && !defined(__AMDGPU__) |
71 | #pragma pop_macro("stdout") |
72 | #pragma pop_macro("stderr") |
73 | #pragma pop_macro("stdin") |
74 | #endif |
75 | |
76 | #endif |
77 | |
78 | #endif // __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__ |
79 | |
80 | #endif |
81 |
Warning: This file is not a C or C++ file. It does not have highlighting.