1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___CONFIGURATION_NAMESPACE_H
11#define _LIBCPP___CONFIGURATION_NAMESPACE_H
12
13#include <__config_site>
14#include <__configuration/attributes.h>
15#include <__configuration/diagnostic_suppression.h>
16#include <__configuration/utility.h>
17
18#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
19# pragma GCC system_header
20#endif
21
22// Clang modules take a significant compile time hit when pushing and popping diagnostics.
23// Since all the headers are marked as system headers unless _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER is defined, we can
24// simply disable this pushing and popping when _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER isn't defined.
25#ifdef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
26# define _LIBCPP_PUSH_EXTENSION_DIAGNOSTICS \
27 _LIBCPP_DIAGNOSTIC_PUSH \
28 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++11-extensions") \
29 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++14-extensions") \
30 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++17-extensions") \
31 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++20-extensions") \
32 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++23-extensions") \
33 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++14-extensions") \
34 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++17-extensions") \
35 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++20-extensions") \
36 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++23-extensions")
37# define _LIBCPP_POP_EXTENSION_DIAGNOSTICS _LIBCPP_DIAGNOSTIC_POP
38# define _LIBCPP_PUSH_ABI_PRAGMA_DIAGNOSTICS \
39 _LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpragma-clang-attribute") \
40 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wignored-attributes")
41# define _LIBCPP_POP_ABI_PRAGMA_DIAGNOSTICS _LIBCPP_DIAGNOSTIC_POP
42#else
43# define _LIBCPP_PUSH_EXTENSION_DIAGNOSTICS
44# define _LIBCPP_POP_EXTENSION_DIAGNOSTICS
45# define _LIBCPP_PUSH_ABI_PRAGMA_DIAGNOSTICS
46# define _LIBCPP_POP_ABI_PRAGMA_DIAGNOSTICS
47#endif
48
49#define _LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS \
50 _LIBCPP_PUSH_ABI_PRAGMA_DIAGNOSTICS \
51 _Pragma(_LIBCPP_TOSTRING(clang attribute _LibcxxExplicitABIAnnotations.push( \
52 __attribute__((__exclude_from_explicit_instantiation__, \
53 __visibility__("hidden"), \
54 __abi_tag__(_LIBCPP_TOSTRING(_LIBCPP_ODR_SIGNATURE)))), \
55 apply_to = function))) _LIBCPP_POP_ABI_PRAGMA_DIAGNOSTICS
56
57#define _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS _Pragma("clang attribute _LibcxxExplicitABIAnnotations.pop")
58
59// clang-format off
60
61// The unversioned namespace is used when we want to be ABI compatible with other standard libraries in some way. There
62// are two main categories where that's the case:
63// - Historically, we have made exception types ABI compatible with libstdc++ to allow throwing them between libstdc++
64// and libc++. This is not used anymore for new exception types, since there is no use-case for it anymore.
65// - Types and functions which are used by the compiler are in the unversioned namespace, since the compiler has to know
66// their mangling without the appropriate declaration in some cases.
67// If it's not clear whether using the unversioned namespace is the correct thing to do, it's not. The versioned
68// namespace (_LIBCPP_BEGIN_NAMESPACE_STD) should almost always be used.
69# define _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD \
70 _LIBCPP_PUSH_EXTENSION_DIAGNOSTICS _LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS namespace _LIBCPP_NAMESPACE_VISIBILITY std {
71
72# define _LIBCPP_END_UNVERSIONED_NAMESPACE_STD } _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS _LIBCPP_POP_EXTENSION_DIAGNOSTICS
73
74# define _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD inline namespace _LIBCPP_ABI_NAMESPACE {
75# define _LIBCPP_END_NAMESPACE_STD } _LIBCPP_END_UNVERSIONED_NAMESPACE_STD
76
77// TODO: This should really be in the versioned namespace
78#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD namespace experimental {
79#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL } _LIBCPP_END_UNVERSIONED_NAMESPACE_STD
80
81#define _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace fundamentals_v1 {
82#define _LIBCPP_END_NAMESPACE_LFTS } _LIBCPP_END_NAMESPACE_EXPERIMENTAL
83
84#define _LIBCPP_BEGIN_NAMESPACE_LFTS_V2 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace fundamentals_v2 {
85#define _LIBCPP_END_NAMESPACE_LFTS_V2 } _LIBCPP_END_NAMESPACE_EXPERIMENTAL
86
87#ifdef _LIBCPP_ABI_NO_FILESYSTEM_INLINE_NAMESPACE
88# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD namespace filesystem {
89# define _LIBCPP_END_NAMESPACE_FILESYSTEM } _LIBCPP_END_NAMESPACE_STD
90#else
91# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD \
92 inline namespace __fs { namespace filesystem {
93
94# define _LIBCPP_END_NAMESPACE_FILESYSTEM }} _LIBCPP_END_NAMESPACE_STD
95#endif
96
97// clang-format on
98
99#endif // _LIBCPP___CONFIGURATION_NAMESPACE_H
100