jhuber6 updated this revision to Diff 535835.
jhuber6 added a comment.

Semi-fix hack for `string.h` and fix `ctype.h`. `string.h` required undefining
C++ mode so we didn't use weird GNU C++ handling, which we then still need the
`extern "C"` for. The cytpe problems come from GNU defining everything as a
macro so it fails to redeclare.

The amount of hacks that just this has required so far is fairly convincing to
me that this is the more correct solution and should be separate from `libc`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154036/new/

https://reviews.llvm.org/D154036

Files:
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Headers/CMakeLists.txt
  clang/lib/Headers/llvm_libc_wrappers/ctype.h
  clang/lib/Headers/llvm_libc_wrappers/llvm-libc-decls/README.txt
  clang/lib/Headers/llvm_libc_wrappers/stdio.h
  clang/lib/Headers/llvm_libc_wrappers/stdlib.h
  clang/lib/Headers/llvm_libc_wrappers/string.h
  clang/test/Driver/gpu-libc-headers.c
  libc/cmake/modules/LLVMLibCHeaderRules.cmake
  libc/include/CMakeLists.txt
  libc/utils/HdrGen/Generator.cpp
  libc/utils/HdrGen/Generator.h
  libc/utils/HdrGen/Main.cpp

Index: libc/utils/HdrGen/Main.cpp
===================================================================
--- libc/utils/HdrGen/Main.cpp
+++ libc/utils/HdrGen/Main.cpp
@@ -32,6 +32,9 @@
 llvm::cl::list<std::string> ReplacementValues(
     "args", llvm::cl::desc("Command separated <argument name>=<value> pairs."),
     llvm::cl::value_desc("<name=value>[,name=value]"));
+llvm::cl::opt<bool> ExportDecls(
+    "export-decls",
+    llvm::cl::desc("Output a new header containing only the entrypoints."));
 
 void ParseArgValuePairs(std::unordered_map<std::string, std::string> &Map) {
   for (std::string &R : ReplacementValues) {
@@ -48,7 +51,10 @@
   std::unordered_map<std::string, std::string> ArgMap;
   ParseArgValuePairs(ArgMap);
   Generator G(HeaderDefFile, EntrypointNamesOption, StandardHeader, ArgMap);
-  G.generate(OS, Records);
+  if (ExportDecls)
+    G.generateDecls(OS, Records);
+  else
+    G.generate(OS, Records);
 
   return false;
 }
Index: libc/utils/HdrGen/Generator.h
===================================================================
--- libc/utils/HdrGen/Generator.h
+++ libc/utils/HdrGen/Generator.h
@@ -52,6 +52,7 @@
         ArgMap(Map) {}
 
   void generate(llvm::raw_ostream &OS, llvm::RecordKeeper &Records);
+  void generateDecls(llvm::raw_ostream &OS, llvm::RecordKeeper &Records);
 };
 
 } // namespace llvm_libc
Index: libc/utils/HdrGen/Generator.cpp
===================================================================
--- libc/utils/HdrGen/Generator.cpp
+++ libc/utils/HdrGen/Generator.cpp
@@ -10,6 +10,7 @@
 
 #include "IncludeFileCommand.h"
 #include "PublicAPICommand.h"
+#include "utils/LibcTableGenUtil/APIIndexer.h"
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -116,4 +117,78 @@
   }
 }
 
+void Generator::generateDecls(llvm::raw_ostream &OS,
+                              llvm::RecordKeeper &Records) {
+
+  OS << "//===-- C standard declarations for " << StdHeader << " "
+     << std::string(80 - (42 + StdHeader.size()), '-') << "===//\n"
+     << "//\n"
+     << "// Part of the LLVM Project, under the Apache License v2.0 with LLVM "
+        "Exceptions.\n"
+     << "// See https://llvm.org/LICENSE.txt for license information.\n"
+     << "// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
+     << "//\n"
+     << "//"
+        "===-------------------------------------------------------------------"
+        "---===//\n\n";
+
+  std::string HeaderGuard(StdHeader.size(), '\0');
+  llvm::transform(StdHeader, HeaderGuard.begin(), [](const char C) -> char {
+    return !isalnum(C) ? '_' : llvm::toUpper(C);
+  });
+  OS << "#ifndef __LLVM_LIBC_DECLARATIONS_" << HeaderGuard << "\n"
+     << "#define __LLVM_LIBC_DECLARATIONS_" << HeaderGuard << "\n\n";
+
+  OS << "#ifndef __LIBC_ATTRS\n"
+     << "#define __LIBC_ATTRS\n"
+     << "#endif\n\n";
+
+  OS << "#ifdef __cplusplus\n"
+     << "extern \"C\" {\n"
+     << "#endif\n\n";
+
+  APIIndexer G(StdHeader, Records);
+  for (auto &Name : EntrypointNameList) {
+    // Filter out functions not exported by this header.
+    if (G.FunctionSpecMap.find(Name) == G.FunctionSpecMap.end())
+      continue;
+
+    llvm::Record *FunctionSpec = G.FunctionSpecMap[Name];
+    llvm::Record *RetValSpec = FunctionSpec->getValueAsDef("Return");
+    llvm::Record *ReturnType = RetValSpec->getValueAsDef("ReturnType");
+
+    OS << G.getTypeAsString(ReturnType) << " " << Name << "(";
+
+    auto ArgsList = FunctionSpec->getValueAsListOfDefs("Args");
+    for (size_t i = 0; i < ArgsList.size(); ++i) {
+      llvm::Record *ArgType = ArgsList[i]->getValueAsDef("ArgType");
+      OS << G.getTypeAsString(ArgType);
+      if (i < ArgsList.size() - 1)
+        OS << ", ";
+    }
+
+    OS << ") __LIBC_ATTRS;\n\n";
+  }
+
+  // Make another pass over entrypoints to emit object declarations.
+  for (const auto &Name : EntrypointNameList) {
+    if (G.ObjectSpecMap.find(Name) == G.ObjectSpecMap.end())
+      continue;
+    llvm::Record *ObjectSpec = G.ObjectSpecMap[Name];
+    auto Type = ObjectSpec->getValueAsString("Type");
+    OS << "extern " << Type << " " << Name << " __LIBC_ATTRS;\n";
+  }
+
+  // Emit a final newline if we emitted any object declarations.
+  if (llvm::any_of(EntrypointNameList, [&](const std::string &Name) {
+        return G.ObjectSpecMap.find(Name) != G.ObjectSpecMap.end();
+      }))
+    OS << "\n";
+
+  OS << "#ifdef __cplusplus\n"
+     << "}\n"
+     << "#endif\n\n";
+  OS << "#endif\n";
+}
+
 } // namespace llvm_libc
Index: libc/include/CMakeLists.txt
===================================================================
--- libc/include/CMakeLists.txt
+++ libc/include/CMakeLists.txt
@@ -3,6 +3,11 @@
 
 include(LLVMLibCHeaderRules)
 
+# The GPU build wants to install files in the compiler's resource directory.
+if(LIBC_TARGET_ARCHITECTURE_IS_GPU)
+  include(GetClangResourceDir)
+endif()
+
 add_subdirectory(llvm-libc-macros)
 add_subdirectory(llvm-libc-types)
 
@@ -539,4 +544,21 @@
   install(FILES ${header_file}
           DESTINATION ${LIBC_INSTALL_INCLUDE_DIR}/${nested_dir}
           COMPONENT libc-headers)
+  # The GPU optionally provides the supported declarations externally so
+  # offloading languages like CUDA and OpenMP know what is supported by libc. We
+  # install these in the compiler's resource directory at a preset location.
+  if(LIBC_TARGET_ARCHITECTURE_IS_GPU)
+    get_target_property(decls_file ${target} DECLS_FILE_PATH)
+    if(NOT decls_file)
+      continue()
+    endif()
+    get_clang_resource_dir(resource_dir SUBDIR include)
+    file(RELATIVE_PATH relative_path ${LIBC_INCLUDE_BINARY_DIR} ${decls_file})
+    get_filename_component(nested_dir ${relative_path} DIRECTORY)
+    set(install_dir
+        ${CMAKE_INSTALL_PREFIX}/${resource_dir}/llvm_libc_wrappers/${nested_dir})
+    install(FILES ${decls_file}
+            DESTINATION ${install_dir}
+            COMPONENT libc-headers)
+  endif()
 endforeach()
Index: libc/cmake/modules/LLVMLibCHeaderRules.cmake
===================================================================
--- libc/cmake/modules/LLVMLibCHeaderRules.cmake
+++ libc/cmake/modules/LLVMLibCHeaderRules.cmake
@@ -131,6 +131,23 @@
             ${hdrgen_deps}
   )
 
+  if(LIBC_TARGET_ARCHITECTURE_IS_GPU)
+    file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/llvm-libc-decls)
+    set(decl_out_file ${LIBC_INCLUDE_DIR}/llvm-libc-decls/${relative_path})
+    add_custom_command(
+      OUTPUT ${decl_out_file}
+      COMMAND ${hdrgen_exe} -o ${decl_out_file}
+              --header ${ADD_GEN_HDR_GEN_HDR} --def ${in_file} --export-decls
+              ${replacement_params} -I ${LIBC_SOURCE_DIR} ${ENTRYPOINT_NAME_LIST_ARG}
+              ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
+
+      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+      DEPENDS ${in_file} ${fq_data_files} ${td_includes}
+              ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
+              ${hdrgen_deps}
+    )
+  endif()
+
   if(ADD_GEN_HDR_DEPENDS)
     get_fq_deps_list(fq_deps_list ${ADD_GEN_HDR_DEPENDS})
     # Dependencies of a add_header target can only be another add_gen_header target
@@ -144,13 +161,14 @@
   endif()
   add_custom_target(
     ${fq_target_name}
-    DEPENDS ${out_file} ${fq_deps_list}
+    DEPENDS ${out_file} ${fq_deps_list} ${decl_out_file}
   )
 
   set_target_properties(
     ${fq_target_name}
     PROPERTIES
       HEADER_FILE_PATH ${out_file}
+      DECLS_FILE_PATH ${decl_out_file}
       DEPS "${fq_deps_list}"
   )
 endfunction(add_gen_header)
Index: clang/test/Driver/gpu-libc-headers.c
===================================================================
--- clang/test/Driver/gpu-libc-headers.c
+++ clang/test/Driver/gpu-libc-headers.c
@@ -1,6 +1,14 @@
 // REQUIRES: nvptx-registered-target
 // REQUIRES: amdgpu-registered-target
 
+// RUN:   %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --sysroot=./ \
+// RUN:     -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa --offload-arch=gfx908  \
+// RUN:     -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS
+// RUN:   %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --sysroot=./ \
+// RUN:     -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target=nvptx64-nvidia-cuda --offload-arch=sm_70  \
+// RUN:     -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS
+// CHECK-HEADERS: "-cc1"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}llvm_libc_wrappers"{{.*}}"-isysroot" "./"
+
 // RUN:   %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx1030 -nogpulib \
 // RUN:     -nogpuinc %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-DISABLED
 // RUN:   %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx1030 -nogpulib \
Index: clang/lib/Headers/llvm_libc_wrappers/string.h
===================================================================
--- /dev/null
+++ clang/lib/Headers/llvm_libc_wrappers/string.h
@@ -0,0 +1,44 @@
+//===-- Wrapper for C standard string.h declarations on the GPU------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CLANG_LLVM_LIBC_WRAPPERS_STRING_H__
+#define __CLANG_LLVM_LIBC_WRAPPERS_STRING_H__
+
+// The GNU headers provide non C-standard headers when in C++ mode. Manually
+// undefine it here so that the definitions agree with the C standard for our
+// purposes.
+#ifdef __cplusplus
+extern "C" {
+#pragma push_macro("__cplusplus")
+#undef __cplusplus
+#endif
+
+#include_next <string.h>
+
+#pragma pop_macro("__cplusplus")
+#ifdef __cplusplus
+}
+#endif
+
+#if !defined(_OPENMP) && defined(__HIP__) && defined(__CUDA__)
+#error "This file is for GPU offloading compilation only"
+#endif
+
+#if defined(__HIP__) || defined(__CUDA__)
+#define __LIBC_ATTRS __attribute__((device))
+#endif
+
+#pragma omp begin declare target
+
+#include <llvm-libc-decls/string.h>
+
+#pragma omp end declare target
+
+#undef __LIBC_ATTRS
+
+#endif
Index: clang/lib/Headers/llvm_libc_wrappers/stdlib.h
===================================================================
--- /dev/null
+++ clang/lib/Headers/llvm_libc_wrappers/stdlib.h
@@ -0,0 +1,33 @@
+//===-- Wrapper for C standard stdlib.h declarations on the GPU------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CLANG_LLVM_LIBC_WRAPPERS_STDLIB_H__
+#define __CLANG_LLVM_LIBC_WRAPPERS_STDLIB_H__
+
+#include_next <stdlib.h>
+
+#if !defined(_OPENMP) && defined(__HIP__) && defined(__CUDA__)
+#error "This file is for GPU offloading compilation only"
+#endif
+
+#if defined(__HIP__) || defined(__CUDA__)
+#define __LIBC_ATTRS __attribute__((device))
+#endif
+
+#pragma omp begin declare target
+
+// The LLVM C library uses this type so we forward declare it.
+typedef void (*__atexithandler_t)(void);
+
+#include <llvm-libc-decls/stdlib.h>
+
+#pragma omp end declare target
+
+#undef __LIBC_ATTRS
+
+#endif
Index: clang/lib/Headers/llvm_libc_wrappers/stdio.h
===================================================================
--- /dev/null
+++ clang/lib/Headers/llvm_libc_wrappers/stdio.h
@@ -0,0 +1,30 @@
+//===-- Wrapper for C standard stdio.h declarations on the GPU ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__
+#define __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__
+
+#include_next <stdio.h>
+
+#if !defined(_OPENMP) && defined(__HIP__) && defined(__CUDA__)
+#error "This file is for GPU offloading compilation only"
+#endif
+
+#if defined(__HIP__) || defined(__CUDA__)
+#define __LIBC_ATTRS __attribute__((device))
+#endif
+
+#pragma omp begin declare target
+
+#include <llvm-libc-decls/stdio.h>
+
+#pragma omp end declare target
+
+#undef __LIBC_ATTRS
+
+#endif
Index: clang/lib/Headers/llvm_libc_wrappers/llvm-libc-decls/README.txt
===================================================================
--- /dev/null
+++ clang/lib/Headers/llvm_libc_wrappers/llvm-libc-decls/README.txt
@@ -0,0 +1,6 @@
+LLVM libc declarations
+======================
+
+This directory will be filled by the `libc` project with declarations that are
+availible on the device. Each declaration will use the `__LIBC_ATTRS` attribute
+to control emission on the device side.
Index: clang/lib/Headers/llvm_libc_wrappers/ctype.h
===================================================================
--- /dev/null
+++ clang/lib/Headers/llvm_libc_wrappers/ctype.h
@@ -0,0 +1,81 @@
+//===-- Wrapper for C standard ctype.h declarations on the GPU ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CLANG_LLVM_LIBC_WRAPPERS_CTYPE_H__
+#define __CLANG_LLVM_LIBC_WRAPPERS_CTYPE_H__
+
+#include_next <ctype.h>
+
+#if !defined(_OPENMP) && defined(__HIP__) && defined(__CUDA__)
+#error "This file is for GPU offloading compilation only"
+#endif
+
+#if defined(__HIP__) || defined(__CUDA__)
+#define __LIBC_ATTRS __attribute__((device))
+#endif
+
+// The GNU headers like to provide these as macros, we need to undefine them so
+// they do not conflict with the following definitions for the GPU.
+
+#pragma push_macro("isalnum")
+#pragma push_macro("isalpha")
+#pragma push_macro("isblank")
+#pragma push_macro("iscntrl")
+#pragma push_macro("isdigit")
+#pragma push_macro("isgraph")
+#pragma push_macro("islower")
+#pragma push_macro("isprint")
+#pragma push_macro("ispunct")
+#pragma push_macro("isspace")
+#pragma push_macro("isupper")
+#pragma push_macro("isxdigit")
+#pragma push_macro("tolower")
+#pragma push_macro("toupper")
+
+#undef isalnum
+#undef isalpha
+#undef iscntrl
+#undef isdigit
+#undef islower
+#undef isgraph
+#undef isprint
+#undef ispunct
+#undef isspace
+#undef isupper
+#undef isblank
+#undef isxdigit
+#undef tolower
+#undef toupper
+
+#pragma omp begin declare target
+
+#include <llvm-libc-decls/ctype.h>
+
+#pragma omp end declare target
+
+// Restore the original macros when compiling on the host.
+#if !defined(__NVPTX__) && !defined(__AMDGPU__)
+#pragma pop_macro("isalnum")
+#pragma pop_macro("isalpha")
+#pragma pop_macro("isblank")
+#pragma pop_macro("iscntrl")
+#pragma pop_macro("isdigit")
+#pragma pop_macro("isgraph")
+#pragma pop_macro("islower")
+#pragma pop_macro("isprint")
+#pragma pop_macro("ispunct")
+#pragma pop_macro("isspace")
+#pragma pop_macro("isupper")
+#pragma pop_macro("isxdigit")
+#pragma pop_macro("tolower")
+#pragma pop_macro("toupper")
+#endif
+
+#undef __LIBC_ATTRS
+
+#endif
Index: clang/lib/Headers/CMakeLists.txt
===================================================================
--- clang/lib/Headers/CMakeLists.txt
+++ clang/lib/Headers/CMakeLists.txt
@@ -298,6 +298,13 @@
   openmp_wrappers/new
 )
 
+set(llvm_libc_wrapper_files
+  llvm_libc_wrappers/stdio.h
+  llvm_libc_wrappers/stdlib.h
+  llvm_libc_wrappers/string.h
+  llvm_libc_wrappers/ctype.h
+)
+
 include(GetClangResourceDir)
 get_clang_resource_dir(output_dir PREFIX ${LLVM_LIBRARY_OUTPUT_INTDIR}/.. SUBDIR include)
 set(out_files)
@@ -333,7 +340,8 @@
 
 # Copy header files from the source directory to the build directory
 foreach( f ${files} ${cuda_wrapper_files} ${cuda_wrapper_bits_files}
-           ${ppc_wrapper_files} ${openmp_wrapper_files} ${hlsl_files})
+           ${ppc_wrapper_files} ${openmp_wrapper_files} ${hlsl_files}
+           ${llvm_libc_wrapper_files})
   copy_header_to_output_dir(${CMAKE_CURRENT_SOURCE_DIR} ${f})
 endforeach( f )
 
@@ -427,6 +435,7 @@
                  "x86-resource-headers"
                  "opencl-resource-headers"
                  "openmp-resource-headers"
+                 "llvm-libc-resource-headers"
                  "windows-resource-headers"
                  "utility-resource-headers")
 
@@ -453,6 +462,7 @@
 # Other header groupings
 add_header_target("hlsl-resource-headers" ${hlsl_files})
 add_header_target("opencl-resource-headers" ${opencl_files})
+add_header_target("llvm-libc-resource-headers" ${llvm_libc_wrapper_files})
 add_header_target("openmp-resource-headers" ${openmp_wrapper_files})
 add_header_target("windows-resource-headers" ${windows_only_files})
 add_header_target("utility-resource-headers" ${utility_files})
@@ -481,6 +491,11 @@
   DESTINATION ${header_install_dir}/ppc_wrappers
   COMPONENT clang-resource-headers)
 
+install(
+  FILES ${llvm_libc_wrapper_files}
+  DESTINATION ${header_install_dir}/llvm_libc_wrappers
+  COMPONENT clang-resource-headers)
+
 install(
   FILES ${openmp_wrapper_files}
   DESTINATION ${header_install_dir}/openmp_wrappers
@@ -636,6 +651,12 @@
   EXCLUDE_FROM_ALL
   COMPONENT openmp-resource-headers)
 
+install(
+  FILES ${openmp_wrapper_files}
+  DESTINATION ${header_install_dir}/openmp_wrappers
+  EXCLUDE_FROM_ALL
+  COMPONENT openmp-resource-headers)
+
 install(
   FILES ${utility_files}
   DESTINATION ${header_install_dir}
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -1181,23 +1181,28 @@
 
   // If we are compiling for a GPU target we want to override the system headers
   // with ones created by the 'libc' project if present.
-  // FIXME: We need to find a way to make these headers compatible with the
-  // host environment so they can be included from offloading languages. For now
-  // these are only active when targeting the GPU with cross-compilation.
   if (!Args.hasArg(options::OPT_nostdinc) &&
       !Args.hasArg(options::OPT_nogpuinc) &&
       !Args.hasArg(options::OPT_nobuiltininc) &&
-      C.getActiveOffloadKinds() == Action::OFK_None &&
       (getToolChain().getTriple().isNVPTX() ||
        getToolChain().getTriple().isAMDGCN())) {
 
-      // Add include/gpu-none-libc/* to our system include path. This lets us use
-      // GPU-specific system headers first.
+    // Without an offloading language we will include these headers directly.
+    // Offloading languages will instead only use the declarations stored in
+    // the resource directory at clang/lib/Headers/llvm_libc_wrappers.
+    if (C.getActiveOffloadKinds() == Action::OFK_None) {
       SmallString<128> P(llvm::sys::path::parent_path(D.InstalledDir));
       llvm::sys::path::append(P, "include");
       llvm::sys::path::append(P, "gpu-none-llvm");
       CmdArgs.push_back("-c-isystem");
       CmdArgs.push_back(Args.MakeArgString(P));
+    } else {
+      SmallString<128> P(D.ResourceDir);
+      llvm::sys::path::append(P, "include");
+      llvm::sys::path::append(P, "llvm_libc_wrappers");
+      CmdArgs.push_back("-internal-isystem");
+      CmdArgs.push_back(Args.MakeArgString(P));
+    }
   }
 
   // If we are offloading to a target via OpenMP we need to include the
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to