Compiler.h#

Fully qualified name: carb/Compiler.h

File members: carb/Compiler.h

// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.

#pragma once

#include "Platform.h"

#define CARB_UNSUPPORTED_COMPILER() static_assert(false, "Unsupported compiler!")

// Compiler defines
#ifdef DOXYGEN_BUILD
#    define CARB_COMPILER_MSC 0
#    define CARB_COMPILER_GNUC 1
#elif defined(CARB_COMPILER_MSC) && defined(CARB_COMPILER_GNUC)
#    if (!!CARB_COMPILER_MSC) + (!!CARB_COMPILER_GNUC) != 1
#        define CARB_COMPILER_MSC // Show previous definition
#        define CARB_COMPILER_GNUC // Show previous definition
#        error Exactly one of CARB_COMPILER_MSC or CARB_COMPILER_GNUC must be non-zero.
#    endif
#elif !defined(CARB_COMPILER_MSC) && !defined(CARB_COMPILER_GNUC)
#    ifndef CARB_COMPILER_MSC
#        if defined(_MSC_VER)
#            define CARB_COMPILER_MSC 1
#            define CARB_COMPILER_GNUC 0
#        elif defined(__GNUC__)
#            define CARB_COMPILER_MSC 0
#            define CARB_COMPILER_GNUC 1
#        else
#            error "Unsupported compiler."
#        endif
#    endif
#else
#    error "Must define CARB_COMPILER_MSC and CARB_COMPILER_GNUC or neither."
#endif

#ifdef DOXYGEN_BUILD
#    define CARB_TOOLCHAIN_CLANG 0
#elif !defined(CARB_TOOLCHAIN_CLANG)
#    if defined(__clang__)
#        define CARB_TOOLCHAIN_CLANG 1
#    else
#        define CARB_TOOLCHAIN_CLANG 0
#    endif
#endif

// Compiler specific defines. Exist for all supported compilers but may be a no-op for certain compilers.
#ifdef DOXYGEN_BUILD
#    define CARB_PRETTY_FUNCTION "<function signature here>"
#    define CARB_ATTRIBUTE(...)
#    define CARB_DECLSPEC(...)
#    define CARB_MSC_ONLY(...)
#    define CARB_NOT_MSC(...)
#    define CARB_GNUC_ONLY(...)
#    define CARB_NOT_GNUC(...)
#    define CARB_CLANG_ONLY(...)
#    define CARB_NOT_CLANG(...)
#    define CARB_PRAGMA(...)
#    define CARB_PRAGMA_MSC(...)
#    define CARB_PRAGMA_GNUC(...)

#    define CARB_EXCEPTIONS_ENABLED 1
#else
#    if CARB_TOOLCHAIN_CLANG
#        define CARB_MSC_ONLY(...)
#        define CARB_NOT_MSC(...) __VA_ARGS__
#        define CARB_GNUC_ONLY(...)
#        define CARB_NOT_GNUC(...) __VA_ARGS__
#        define CARB_CLANG_ONLY(...) __VA_ARGS__
#        define CARB_NOT_CLANG(...)
#    elif CARB_COMPILER_MSC
#        define CARB_MSC_ONLY(...) __VA_ARGS__
#        define CARB_NOT_MSC(...)
#        define CARB_GNUC_ONLY(...)
#        define CARB_NOT_GNUC(...) __VA_ARGS__
#        define CARB_CLANG_ONLY(...)
#        define CARB_NOT_CLANG(...) __VA_ARGS__
#    elif CARB_COMPILER_GNUC
#        define CARB_MSC_ONLY(...)
#        define CARB_NOT_MSC(...) __VA_ARGS__
#        define CARB_GNUC_ONLY(...) __VA_ARGS__
#        define CARB_NOT_GNUC(...)
#        define CARB_CLANG_ONLY(...)
#        define CARB_NOT_CLANG(...) __VA_ARGS__
#    else
#        error Unsupported compiler.
#    endif
#    if CARB_COMPILER_MSC
#        define CARB_PRETTY_FUNCTION __FUNCSIG__
#        if CARB_TOOLCHAIN_CLANG
#            define CARB_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
#        else
#            define CARB_ATTRIBUTE(...)
#        endif
#        define CARB_PRAGMA(...) __pragma(__VA_ARGS__)
#        define CARB_DECLSPEC(...) __declspec(__VA_ARGS__)
#        define CARB_PRAGMA_MSC(...) CARB_PRAGMA(__VA_ARGS__)
#        define CARB_PRAGMA_GNUC(...)
#        ifdef __cpp_exceptions
#            define CARB_EXCEPTIONS_ENABLED 1
#        else
#            define CARB_EXCEPTIONS_ENABLED 0
#        endif

#        if defined(__INTELLISENSE__) && _MSC_VER < 1920
// See: https://stackoverflow.com/questions/61485127/including-windows-h-causes-unknown-attributeno-init-all-error
#            define no_init_all deprecated
#        endif
#        define CARB_ASSUME(b) __assume(b)
#    elif CARB_COMPILER_GNUC
#        define CARB_PRETTY_FUNCTION __PRETTY_FUNCTION__
#        define CARB_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
#        define CARB_DECLSPEC(...)
// clang-format off
#        define CARB_PRAGMA(x) _Pragma(#x)
// clang-format on
#        define CARB_PRAGMA_MSC(...)
#        define CARB_PRAGMA_GNUC(...) CARB_PRAGMA(__VA_ARGS__)

#        ifdef __EXCEPTIONS
#            define CARB_EXCEPTIONS_ENABLED 1
#        else
#            define CARB_EXCEPTIONS_ENABLED 0
#        endif
#        define CARB_ASSUME(b)                                                                                         \
            if (!(b))                                                                                                  \
            __builtin_unreachable()
#    else
#        error Unsupported compiler
#    endif
#endif

#define CARB_ALWAYS_INLINE CARB_MSC_ONLY(__forceinline) CARB_ATTRIBUTE(always_inline)

#define CARB_NOINLINE CARB_ATTRIBUTE(noinline) CARB_DECLSPEC(noinline)

#define CARB_UNREACHABLE() CARB_ASSUME(false)

#define CARB_PRINTF_FUNCTION(fmt_ordinal, args_ordinal) CARB_ATTRIBUTE(format(printf, fmt_ordinal, args_ordinal))

#define CARB_HIDDEN CARB_ATTRIBUTE(visibility("hidden"))

#define CARB_WEAKLINK CARB_DECLSPEC(selectany) CARB_ATTRIBUTE(weak)

// Toolchain features
#ifndef CARB_DEBUG
#    if defined(NDEBUG) || defined(DOXYGEN_BUILD)
#        define CARB_DEBUG 0
#    else
#        define CARB_DEBUG 1
#    endif
#endif

#ifdef DOXYGEN_BUILD
#    define CARB_ASAN_ENABLED 0
#elif !defined(CARB_ASAN_ENABLED)
#    if defined(__has_feature)
#        define CARB_ASAN_ENABLED __has_feature(address_sanitizer)
#    elif defined(__SANITIZE_ADDRESS__)
#        define CARB_ASAN_ENABLED __SANITIZE_ADDRESS__
#    else
#        define CARB_ASAN_ENABLED 0
#    endif
#endif

#ifdef DOXYGEN_BUILD
#    define CARB_TSAN_ENABLED 0
#elif !defined(CARB_TSAN_ENABLED)
#    if defined(__has_feature)
#        define CARB_TSAN_ENABLED __has_feature(thread_sanitizer)
#    elif defined(__SANITIZE_THREAD__)
#        define CARB_TSAN_ENABLED __SANITIZE_THREAD__
#    else
#        define CARB_TSAN_ENABLED 0
#    endif
#endif

#ifndef CARB_CPLUSPLUS
#    if defined(__cplusplus)
#        if CARB_COMPILER_MSC && defined(_MSVC_LANG)
#            define CARB_CPLUSPLUS _MSVC_LANG
#        else
#            define CARB_CPLUSPLUS __cplusplus
#        endif
#    else
#        define CARB_CPLUSPLUS 0L
#    endif
#endif

#if defined(DOXYGEN_BUILD)
#    define CARB_HAS_RTTI 1
#elif CARB_TOOLCHAIN_CLANG
#    if __has_feature(cxx_rtti)
#        define CARB_HAS_RTTI 1
#    endif
#elif CARB_COMPILER_MSC
#    ifdef _CPPRTTI
#        define CARB_HAS_RTTI 1
#    endif
#elif CARB_COMPILER_GNUC
#    ifdef __GXX_RTTI
#        define CARB_HAS_RTTI 1
#    endif
#endif
#ifndef CARB_HAS_RTTI
#    define CARB_HAS_RTTI 0
#endif

#if defined(DOXYGEN_BUILD) || defined(OMNI_BIND)
#    define CARB_OPTIMIZE_OFF_MSC()
#    define CARB_OPTIMIZE_ON_MSC()
#    define CARB_NO_OPTIMIZE_GNUC_CLANG()
#else
#    if CARB_COMPILER_MSC
#        define CARB_OPTIMIZE_OFF_MSC() CARB_PRAGMA_MSC(optimize("", off))
#        define CARB_OPTIMIZE_ON_MSC() CARB_PRAGMA_MSC(optimize("", on))
#        if CARB_TOOLCHAIN_CLANG
#            define CARB_NO_OPTIMIZE_GNUC_CLANG() CARB_ATTRIBUTE(optnone)
#        else
#            define CARB_NO_OPTIMIZE_GNUC_CLANG()
#        endif
#    elif CARB_TOOLCHAIN_CLANG
#        define CARB_NO_OPTIMIZE_GNUC_CLANG() CARB_ATTRIBUTE(optnone)
#        define CARB_OPTIMIZE_OFF_MSC()
#        define CARB_OPTIMIZE_ON_MSC()
#    elif CARB_COMPILER_GNUC
#        define CARB_NO_OPTIMIZE_GNUC_CLANG() CARB_ATTRIBUTE(optimize("-O0"))
#        define CARB_OPTIMIZE_OFF_MSC()
#        define CARB_OPTIMIZE_ON_MSC()
#    else
#        error Unsupported compiler
#    endif
#endif

// C++ standard version checks
#if CARB_CPLUSPLUS < 201700L && !defined(DOXYGEN_BUILD)
#    error "Carbonite requires C++17 or later."
#endif

#define CARB_HAS_CPP14 1

#define CARB_HAS_CPP17 1

#define CARB_CPP17_CONSTEXPR constexpr

#if CARB_CPLUSPLUS >= 202000L || defined(DOXYGEN_BUILD)
#    define CARB_HAS_CPP20 1
#else
#    define CARB_HAS_CPP20 0
#endif

// temporary local defines (undefined at the end of the file)
#ifndef DOXYGEN_BUILD
#    if defined(__has_cpp_attribute) // C++20
#        define CARBLOCAL_HAS_NODISCARD_MSG (__has_cpp_attribute(nodiscard) >= 201907L)
#        define CARBLOCAL_HAS_LIKELY (__has_cpp_attribute(likely) >= 201803L)
#        define CARBLOCAL_HAS_UNLIKELY (__has_cpp_attribute(unlikely) >= 201803L)
#        define CARBLOCAL_HAS_NO_UNIQUE_ADDRESS (__has_cpp_attribute(no_unique_address) >= 201803L)
#    else
#        define CARBLOCAL_HAS_NODISCARD_MSG 0
#        define CARBLOCAL_HAS_LIKELY 0
#        define CARBLOCAL_HAS_UNLIKELY 0
#        define CARBLOCAL_HAS_NO_UNIQUE_ADDRESS 0
#    endif
#endif

// [[nodiscard]]
#define CARB_NODISCARD [[nodiscard]]

#define CARB_NODISCARD_TYPE [[nodiscard]]

// [[nodiscard(msg)]]
#if (CARB_HAS_CPP20 && CARBLOCAL_HAS_NODISCARD_MSG) || defined(DOXYGEN_BUILD)
#    define CARB_NODISCARD_MSG(msg) [[nodiscard(msg)]]
#    define CARB_NODISCARD_TYPE_MSG(msg) [[nodiscard(msg)]]
#else
#    define CARB_NODISCARD_MSG(msg) [[nodiscard]]
#    define CARB_NODISCARD_TYPE_MSG(msg) CARB_NODISCARD_TYPE
#endif

// [[fallthrough]]
#define CARB_FALLTHROUGH [[fallthrough]]

// [[maybe_unused]]
#define CARB_MAYBE_UNUSED [[maybe_unused]]

// [[likely]] / [[unlikely]]
#if (CARB_HAS_CPP20 && CARBLOCAL_HAS_LIKELY) || defined(DOXYGEN_BUILD)
#    define CARB_CPP20_LIKELY [[likely]]
#else
#    define CARB_CPP20_LIKELY
#endif

#if (CARB_HAS_CPP20 && CARBLOCAL_HAS_UNLIKELY) || defined(DOXYGEN_BUILD)
#    define CARB_CPP20_UNLIKELY [[unlikely]]
#else
#    define CARB_CPP20_UNLIKELY
#endif

#if CARB_COMPILER_GNUC || defined(DOXYGEN_BUILD)
#    define CARB_LIKELY(expr) __builtin_expect(!!(expr), 1)
#    define CARB_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
#else // not supported
#    define CARB_LIKELY(expr) (!!(expr))
#    define CARB_UNLIKELY(expr) (!!(expr))
#endif

#define CARB_LIKELY_IF(...)                                                                                            \
    if (CARB_LIKELY(__VA_ARGS__))                                                                                      \
    CARB_CPP20_LIKELY

#define CARB_UNLIKELY_IF(...)                                                                                          \
    if (CARB_UNLIKELY(__VA_ARGS__))                                                                                    \
    CARB_CPP20_UNLIKELY

// [[no_unique_address]]
#if (CARB_HAS_CPP20 && CARBLOCAL_HAS_NO_UNIQUE_ADDRESS) || defined(DOXYGEN_BUILD)
#    define CARB_NO_UNIQUE_ADDRESS [[no_unique_address]]
#else // not supported
#    define CARB_NO_UNIQUE_ADDRESS
#endif

// constexpr in CPP20, but not before
#if (CARB_HAS_CPP20 && __cpp_constexpr >= 201907L) || defined(DOXYGEN_BUILD)
#    define CARB_CPP20_CONSTEXPR constexpr
#else
#    define CARB_CPP20_CONSTEXPR
#endif

#if (CARB_HAS_CPP20 && defined(__cpp_consteval)) || defined(DOXYGEN_BUILD)
#    define CARB_CONSTEVAL consteval
#else
#    define CARB_CONSTEVAL constexpr
#endif

// Undefine temporaries
#undef CARBLOCAL_HAS_NODISCARD_MSG
#undef CARBLOCAL_HAS_LIKELY
#undef CARBLOCAL_HAS_UNLIKELY
#undef CARBLOCAL_HAS_NO_UNIQUE_ADDRESS

// Miscellaneous compiler-related defines
#if CARB_COMPILER_MSC || defined(DOXYGEN_BUILD)
#    define PRIdword "lu"

#    define PRIxdword "lx"
#else
#    define PRIdword "u"
#    define PRIxdword "x"
#endif