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_CLANG_DIAGNOSTIC_IGNORED("-Wc++26-extensions") \
34 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++14-extensions") \
35 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++17-extensions") \
36 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++20-extensions") \
37 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++23-extensions") \
38 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++26-extensions")
39# define _LIBCPP_POP_EXTENSION_DIAGNOSTICS _LIBCPP_DIAGNOSTIC_POP
40# define _LIBCPP_PUSH_ABI_PRAGMA_DIAGNOSTICS \
41 _LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpragma-clang-attribute") \
42 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wignored-attributes")
43# define _LIBCPP_POP_ABI_PRAGMA_DIAGNOSTICS _LIBCPP_DIAGNOSTIC_POP
44#else
45# define _LIBCPP_PUSH_EXTENSION_DIAGNOSTICS
46# define _LIBCPP_POP_EXTENSION_DIAGNOSTICS
47# define _LIBCPP_PUSH_ABI_PRAGMA_DIAGNOSTICS
48# define _LIBCPP_POP_ABI_PRAGMA_DIAGNOSTICS
49#endif
50
51#ifdef _LIBCPP_COMPILER_CLANG_BASED
52# define _LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS \
53 _LIBCPP_PUSH_ABI_PRAGMA_DIAGNOSTICS \
54 _Pragma(_LIBCPP_TOSTRING(clang attribute _LibcxxExplicitABIAnnotations.push( \
55 __attribute__((__exclude_from_explicit_instantiation__, \
56 __visibility__("hidden"), \
57 __abi_tag__(_LIBCPP_TOSTRING(_LIBCPP_ODR_SIGNATURE)))), \
58 apply_to = function))) _LIBCPP_POP_ABI_PRAGMA_DIAGNOSTICS
59
60# define _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS _Pragma("clang attribute _LibcxxExplicitABIAnnotations.pop")
61#else
62# define _LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
63# define _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
64#endif
65
66// clang-format off
67
68// The unversioned namespace is used when we want to be ABI compatible with other standard libraries in some way. There
69// are two main categories where that's the case:
70// - Historically, we have made exception types ABI compatible with libstdc++ to allow throwing them between libstdc++
71// and libc++. This is not used anymore for new exception types, since there is no use-case for it anymore.
72// - Types and functions which are used by the compiler are in the unversioned namespace, since the compiler has to know
73// their mangling without the appropriate declaration in some cases.
74// If it's not clear whether using the unversioned namespace is the correct thing to do, it's not. The versioned
75// namespace (_LIBCPP_BEGIN_NAMESPACE_STD) should almost always be used.
76# define _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD \
77 _LIBCPP_PUSH_EXTENSION_DIAGNOSTICS _LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS namespace _LIBCPP_NAMESPACE_VISIBILITY std {
78
79# define _LIBCPP_END_UNVERSIONED_NAMESPACE_STD } _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS _LIBCPP_POP_EXTENSION_DIAGNOSTICS
80
81# define _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD inline namespace _LIBCPP_ABI_NAMESPACE {
82# define _LIBCPP_END_NAMESPACE_STD } _LIBCPP_END_UNVERSIONED_NAMESPACE_STD
83
84// TODO: This should really be in the versioned namespace
85#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD namespace experimental {
86#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL } _LIBCPP_END_UNVERSIONED_NAMESPACE_STD
87
88#define _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace fundamentals_v1 {
89#define _LIBCPP_END_NAMESPACE_LFTS } _LIBCPP_END_NAMESPACE_EXPERIMENTAL
90
91#define _LIBCPP_BEGIN_NAMESPACE_LFTS_V2 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace fundamentals_v2 {
92#define _LIBCPP_END_NAMESPACE_LFTS_V2 } _LIBCPP_END_NAMESPACE_EXPERIMENTAL
93
94#ifdef _LIBCPP_ABI_NO_FILESYSTEM_INLINE_NAMESPACE
95# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD namespace filesystem {
96# define _LIBCPP_END_NAMESPACE_FILESYSTEM } _LIBCPP_END_NAMESPACE_STD
97#else
98# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD \
99 inline namespace __fs { namespace filesystem {
100
101# define _LIBCPP_END_NAMESPACE_FILESYSTEM }} _LIBCPP_END_NAMESPACE_STD
102#endif
103
104// clang-format on
105
106#endif // _LIBCPP___CONFIGURATION_NAMESPACE_H
107