option(LIBCXX_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
option(LIBCXX_ENABLE_CXX1Y "Enable -std=c++1y and use of c++1y language features if the compiler supports it." OFF)
option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
+option(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE "Build libc++ with support for the global filesystem namespace." ON)
option(LIBCXX_ENABLE_THREADS "Build libc++ with support for threads." ON)
option(LIBCXX_BUILD_32_BITS "Build 32 bit libc++" OFF)
option(LIBCXX_ENABLE_MONOTONIC_CLOCK
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
+# LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE configuration
+if (NOT LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE)
+ add_definitions(-D_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE)
+endif()
+
# LIBCXX_ENABLE_THREADS configuration
if (NOT LIBCXX_ENABLE_THREADS)
add_definitions(-D_LIBCPP_HAS_NO_THREADS)
_LIBCPP_HAS_NO_THREADS is defined.
#endif
+// Systems that use capability-based security (FreeBSD with Capsicum,
+// Nuxi CloudABI) may only provide local filesystem access (using *at()).
+// Functions like open(), rename(), unlink() and stat() should not be
+// used, as they attempt to access the global filesystem namespace.
+#ifdef __CloudABI__
+#define _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
+#endif
+
#if defined(__ANDROID__)
#define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
#endif
using ::fpos_t;
using ::size_t;
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
using ::remove;
using ::rename;
using ::tmpfile;
using ::tmpnam;
+#endif
using ::fclose;
using ::fflush;
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
using ::fopen;
using ::freopen;
+#endif
using ::setbuf;
using ::setvbuf;
using ::fprintf;
// 27.9.1.4 Members:
bool is_open() const;
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
basic_filebuf* open(const char* __s, ios_base::openmode __mode);
basic_filebuf* open(const string& __s, ios_base::openmode __mode);
+#endif
basic_filebuf* close();
protected:
return __file_ != 0;
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>*
basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
{
return open(__s.c_str(), __mode);
}
+#endif
template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>*
typedef typename traits_type::off_type off_type;
basic_ifstream();
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
+#endif
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
basic_ifstream(basic_ifstream&& __rhs);
#endif
basic_filebuf<char_type, traits_type>* rdbuf() const;
bool is_open() const;
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
void open(const char* __s, ios_base::openmode __mode = ios_base::in);
void open(const string& __s, ios_base::openmode __mode = ios_base::in);
+#endif
void close();
private:
{
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
if (__sb_.open(__s, __mode | ios_base::in) == 0)
this->setstate(ios_base::failbit);
}
+#endif
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
return __sb_.is_open();
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
void
basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
else
this->setstate(ios_base::failbit);
}
+#endif
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
basic_filebuf<char_type, traits_type>* rdbuf() const;
bool is_open() const;
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
void open(const char* __s, ios_base::openmode __mode = ios_base::out);
void open(const string& __s, ios_base::openmode __mode = ios_base::out);
+#endif
void close();
private:
{
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
if (__sb_.open(__s, __mode | ios_base::out) == 0)
this->setstate(ios_base::failbit);
}
+#endif
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
return __sb_.is_open();
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
void
basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
else
this->setstate(ios_base::failbit);
}
+#endif
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
typedef typename traits_type::off_type off_type;
basic_fstream();
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
+#endif
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
basic_fstream(basic_fstream&& __rhs);
#endif
basic_filebuf<char_type, traits_type>* rdbuf() const;
bool is_open() const;
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
+#endif
void close();
private:
{
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
if (__sb_.open(__s, __mode) == 0)
this->setstate(ios_base::failbit);
}
+#endif
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
return __sb_.is_open();
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
void
basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
else
this->setstate(ios_base::failbit);
}
+#endif
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
pythonize_bool(LIBCXX_ENABLE_RTTI)
pythonize_bool(LIBCXX_ENABLE_SHARED)
pythonize_bool(LIBCXX_BUILD_32_BITS)
+ pythonize_bool(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE)
pythonize_bool(LIBCXX_ENABLE_THREADS)
pythonize_bool(LIBCXX_ENABLE_MONOTONIC_CLOCK)
# The tests shouldn't link to any ABI library when it has been linked into
# Configure feature flags.
self.configure_compile_flags_exceptions()
self.configure_compile_flags_rtti()
+ self.configure_compile_flags_no_global_filesystem_namespace()
enable_32bit = self.get_lit_bool('enable_32bit', False)
if enable_32bit:
self.cxx.flags += ['-m32']
self.config.available_features.add('libcpp-no-rtti')
self.cxx.compile_flags += ['-fno-rtti', '-D_LIBCPP_NO_RTTI']
+ def configure_compile_flags_no_global_filesystem_namespace(self):
+ enable_global_filesystem_namespace = self.get_lit_bool(
+ 'enable_global_filesystem_namespace', True)
+ if not enable_global_filesystem_namespace:
+ self.config.available_features.add(
+ 'libcpp-has-no-global-filesystem-namespace')
+ self.cxx.compile_flags += [
+ '-D_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE']
+
def configure_compile_flags_no_threads(self):
self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_THREADS']
self.config.available_features.add('libcpp-has-no-threads')
is_pass_test = name.endswith('.pass.cpp')
is_fail_test = name.endswith('.fail.cpp')
+ if test.config.unsupported:
+ return (lit.Test.UNSUPPORTED,
+ "A lit.local.cfg marked this unsupported")
+
res = lit.TestRunner.parseIntegratedTestScript(
test, require_script=is_sh_test)
# Check if a result for the test was returned. If so return that
config.enable_rtti = "@LIBCXX_ENABLE_RTTI@"
config.enable_shared = "@LIBCXX_ENABLE_SHARED@"
config.enable_32bit = "@LIBCXX_BUILD_32_BITS@"
+config.enable_global_filesystem_namespace = "@LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE@"
config.enable_threads = "@LIBCXX_ENABLE_THREADS@"
config.enable_monotonic_clock = "@LIBCXX_ENABLE_MONOTONIC_CLOCK@"
config.cxx_abi = "@LIBCXX_CXX_ABI_LIBNAME@"
std::size_t s = 0;
char* cp = 0;
std::va_list va;
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
static_assert((std::is_same<decltype(std::remove("")), int>::value), "");
static_assert((std::is_same<decltype(std::rename("","")), int>::value), "");
static_assert((std::is_same<decltype(std::tmpfile()), std::FILE*>::value), "");
static_assert((std::is_same<decltype(std::tmpnam(cp)), char*>::value), "");
+#endif
static_assert((std::is_same<decltype(std::fclose(fp)), int>::value), "");
static_assert((std::is_same<decltype(std::fflush(fp)), int>::value), "");
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
static_assert((std::is_same<decltype(std::fopen("", "")), std::FILE*>::value), "");
static_assert((std::is_same<decltype(std::freopen("", "", fp)), std::FILE*>::value), "");
+#endif
static_assert((std::is_same<decltype(std::setbuf(fp,cp)), void>::value), "");
static_assert((std::is_same<decltype(std::vfprintf(fp,"",va)), int>::value), "");
static_assert((std::is_same<decltype(std::fprintf(fp," ")), int>::value), "");
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstdio>
+
+int main() {
+ // fopen is not available on systems without a global filesystem namespace.
+ std::fopen("", "");
+}
--- /dev/null
+if 'libcpp-has-no-global-filesystem-namespace' not in config.available_features:
+ config.unsupported = True
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstdio>
+
+int main() {
+ // rename is not available on systems without a global filesystem namespace.
+ std::rename("", "");
+}
--- /dev/null
+if 'libcpp-has-no-global-filesystem-namespace' in config.available_features:
+ config.unsupported = True
--- /dev/null
+if 'libcpp-has-no-global-filesystem-namespace' in config.available_features:
+ config.unsupported = True
#ifndef PLATFORM_SUPPORT_H
#define PLATFORM_SUPPORT_H
+#include <__config>
+
// locale names
#ifdef _WIN32
// WARNING: Windows does not support UTF-8 codepages.
}
#endif
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
inline
std::string
get_temp_file_name()
return Name;
#endif
}
+#endif // _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
#endif // PLATFORM_SUPPORT_H