mirror of
https://github.com/llvm-mirror/libcxx.git
synced 2025-10-24 03:32:35 +08:00
[libcxx] Implement locale.h to fix modules build
Summary: 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. Reviewers: mclow.lists, rsmith, EricWF Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D26826 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@287413 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
45
include/locale.h
Normal file
45
include/locale.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
//===---------------------------- locale.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
|
@@ -40,7 +40,13 @@ module std [system] {
|
|||||||
}
|
}
|
||||||
// <iso646.h> provided by compiler.
|
// <iso646.h> provided by compiler.
|
||||||
// <limits.h> provided by compiler or C library.
|
// <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 {
|
module math_h {
|
||||||
header "math.h"
|
header "math.h"
|
||||||
/*
|
/*
|
||||||
|
20
test/libcxx/depr/depr.c.headers/locale_h.pass.cpp
Normal file
20
test/libcxx/depr/depr.c.headers/locale_h.pass.cpp
Normal file
@@ -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()
|
||||||
|
{
|
||||||
|
}
|
23
test/libcxx/modules/clocale_exports.sh.cpp
Normal file
23
test/libcxx/modules/clocale_exports.sh.cpp
Normal file
@@ -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());
|
||||||
|
}
|
@@ -13,6 +13,7 @@ import platform
|
|||||||
import pkgutil
|
import pkgutil
|
||||||
import re
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import lit.Test # pylint: disable=import-error,no-name-in-module
|
import lit.Test # pylint: disable=import-error,no-name-in-module
|
||||||
@@ -64,6 +65,7 @@ class Configuration(object):
|
|||||||
self.cxx_library_root = None
|
self.cxx_library_root = None
|
||||||
self.cxx_runtime_root = None
|
self.cxx_runtime_root = None
|
||||||
self.abi_library_root = None
|
self.abi_library_root = None
|
||||||
|
self.module_cache_path = None
|
||||||
self.env = {}
|
self.env = {}
|
||||||
self.use_target = False
|
self.use_target = False
|
||||||
self.use_system_cxx_lib = False
|
self.use_system_cxx_lib = False
|
||||||
@@ -117,6 +119,7 @@ class Configuration(object):
|
|||||||
self.configure_warnings()
|
self.configure_warnings()
|
||||||
self.configure_sanitizer()
|
self.configure_sanitizer()
|
||||||
self.configure_coverage()
|
self.configure_coverage()
|
||||||
|
self.configure_modules()
|
||||||
self.configure_substitutions()
|
self.configure_substitutions()
|
||||||
self.configure_features()
|
self.configure_features()
|
||||||
|
|
||||||
@@ -721,6 +724,27 @@ class Configuration(object):
|
|||||||
self.cxx.flags += ['-g', '--coverage']
|
self.cxx.flags += ['-g', '--coverage']
|
||||||
self.cxx.compile_flags += ['-O0']
|
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):
|
def configure_substitutions(self):
|
||||||
sub = self.config.substitutions
|
sub = self.config.substitutions
|
||||||
# Configure compiler substitutions
|
# Configure compiler substitutions
|
||||||
@@ -734,6 +758,13 @@ class Configuration(object):
|
|||||||
sub.append(('%compile_flags', compile_flags_str))
|
sub.append(('%compile_flags', compile_flags_str))
|
||||||
sub.append(('%link_flags', link_flags_str))
|
sub.append(('%link_flags', link_flags_str))
|
||||||
sub.append(('%all_flags', all_flags))
|
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
|
# Add compile and link shortcuts
|
||||||
compile_str = (self.cxx.path + ' -o %t.o %s -c ' + flags_str
|
compile_str = (self.cxx.path + ' -o %t.o %s -c ' + flags_str
|
||||||
+ compile_flags_str)
|
+ compile_flags_str)
|
||||||
@@ -743,6 +774,8 @@ class Configuration(object):
|
|||||||
build_str = self.cxx.path + ' -o %t.exe %s ' + all_flags
|
build_str = self.cxx.path + ' -o %t.exe %s ' + all_flags
|
||||||
sub.append(('%compile', compile_str))
|
sub.append(('%compile', compile_str))
|
||||||
sub.append(('%link', link_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))
|
sub.append(('%build', build_str))
|
||||||
# Configure exec prefix substitutions.
|
# Configure exec prefix substitutions.
|
||||||
exec_env_str = 'env ' if len(self.env) != 0 else ''
|
exec_env_str = 'env ' if len(self.env) != 0 else ''
|
||||||
|
Reference in New Issue
Block a user