EricWF created this revision.
EricWF added reviewers: mclow.lists, rsmith.
EricWF added a subscriber: cfe-commits.

Because `locale.h` isn't part of the libc++ modules the class definitions it 
provides are exported as part of `__locale` (since it happens to be build 
first). This breaks `<clocale>` which exports `std::lconv` without including 
`<__locale>`.

This patch implements `locale.h` to fix this issue, it also adds support for 
testing libc++ with modules.


https://reviews.llvm.org/D26826

Files:
  include/locale.h
  include/module.modulemap
  test/libcxx/depr/depr.c.headers/locale_h.pass.cpp
  test/libcxx/modules/clocale_exports.sh.cpp
  test/libcxx/test/config.py

Index: test/libcxx/test/config.py
===================================================================
--- test/libcxx/test/config.py
+++ test/libcxx/test/config.py
@@ -13,6 +13,7 @@
 import pkgutil
 import re
 import shlex
+import shutil
 import sys
 
 import lit.Test  # pylint: disable=import-error,no-name-in-module
@@ -64,6 +65,7 @@
         self.cxx_library_root = None
         self.cxx_runtime_root = None
         self.abi_library_root = None
+        self.module_cache_path = None
         self.env = {}
         self.use_target = False
         self.use_system_cxx_lib = False
@@ -117,6 +119,7 @@
         self.configure_warnings()
         self.configure_sanitizer()
         self.configure_coverage()
+        self.configure_modules()
         self.configure_substitutions()
         self.configure_features()
 
@@ -721,6 +724,27 @@
             self.cxx.flags += ['-g', '--coverage']
             self.cxx.compile_flags += ['-O0']
 
+    def configure_modules(self):
+        supports_modules = self.cxx.hasCompileFlag('-fmodules')
+        enable_modules = self.get_lit_bool('enable_modules', False)
+        if enable_modules and not supports_modules:
+            self.lit_config.fatal(
+                '-fmodules is enabled but not supported by the compiler')
+        if not supports_modules:
+            return
+        self.config.available_features.add('modules-support')
+        module_cache = os.path.join(self.config.test_exec_root,
+                                   'modules.cache')
+        module_cache = os.path.realpath(module_cache)
+        if os.path.isdir(module_cache):
+            shutil.rmtree(module_cache)
+        os.makedirs(module_cache)
+        self.module_cache_path = module_cache
+        if enable_modules:
+            self.config.available_features.add('-fmodules')
+            self.cxx.compile_flags += ['-fmodules',
+                                       '-fmodules-cache-path=' + module_cache]
+
     def configure_substitutions(self):
         sub = self.config.substitutions
         # Configure compiler substitutions
@@ -734,6 +758,13 @@
         sub.append(('%compile_flags', compile_flags_str))
         sub.append(('%link_flags', link_flags_str))
         sub.append(('%all_flags', all_flags))
+
+        module_flags = None
+        if not self.module_cache_path is None:
+            module_flags = '-fmodules -fmodules-cache-path=' \
+                           + self.module_cache_path + ' '
+
+
         # Add compile and link shortcuts
         compile_str = (self.cxx.path + ' -o %t.o %s -c ' + flags_str
                        + compile_flags_str)
@@ -743,6 +774,8 @@
         build_str = self.cxx.path + ' -o %t.exe %s ' + all_flags
         sub.append(('%compile', compile_str))
         sub.append(('%link', link_str))
+        if not module_flags is None:
+            sub.append(('%build_module', build_str + ' ' + module_flags))
         sub.append(('%build', build_str))
         # Configure exec prefix substitutions.
         exec_env_str = 'env ' if len(self.env) != 0 else ''
Index: test/libcxx/modules/clocale_exports.sh.cpp
===================================================================
--- /dev/null
+++ test/libcxx/modules/clocale_exports.sh.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: modules-support
+
+// RUN: %build_module
+
+#include <clocale>
+
+#define TEST(...) do { using T = decltype( __VA_ARGS__ ); } while(false)
+
+int main() {
+  std::lconv l; ((void)l);
+
+  TEST(std::setlocale(0, ""));
+  TEST(std::localeconv());
+}
Index: test/libcxx/depr/depr.c.headers/locale_h.pass.cpp
===================================================================
--- /dev/null
+++ test/libcxx/depr/depr.c.headers/locale_h.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <locale.h>
+
+#include <locale.h>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
Index: include/module.modulemap
===================================================================
--- include/module.modulemap
+++ include/module.modulemap
@@ -40,7 +40,13 @@
     }
     // <iso646.h> provided by compiler.
     // <limits.h> provided by compiler or C library.
-    // <locale.h> provided by C library.
+    module locale_h {
+      header "locale.h"
+/*
+      export_macros LC_ALL LC_COLLATE LC_CTYPE LC_MONETARY LC_NUMERIC LC_TIME
+*/
+      export *
+    }
     module math_h {
       header "math.h"
 /*
Index: include/locale.h
===================================================================
--- /dev/null
+++ include/locale.h
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//===---------------------------- math.h ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_LOCALE_H
+#define _LIBCPP_LOCALE_H
+
+/*
+    locale.h synopsis
+
+Macros:
+
+    LC_ALL
+    LC_COLLATE
+    LC_CTYPE
+    LC_MONETARY
+    LC_NUMERIC
+    LC_TIME
+
+Types:
+
+    lconv
+
+Functions:
+
+   setlocale
+   localeconv
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include_next <locale.h>
+
+#endif  // _LIBCPP_LOCALE_H
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to