Files
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

208 lines
8.6 KiB
C

// Copyright Epic Games, Inc. All Rights Reserved.
// IWYU pragma: private
// Include include "AutoRTFM.h" instead
#pragma once
#if (defined(__AUTORTFM) && __AUTORTFM)
#define UE_AUTORTFM 1 // Compiler is 'verse-clang'
#else
#define UE_AUTORTFM 0
#endif
#if (defined(__AUTORTFM_ENABLED) && __AUTORTFM_ENABLED)
#define UE_AUTORTFM_ENABLED 1 // Compiled with '-fautortfm'
#else
#define UE_AUTORTFM_ENABLED 0
#endif
#if !defined(UE_AUTORTFM_ENABLED_RUNTIME_BY_DEFAULT)
#define UE_AUTORTFM_ENABLED_RUNTIME_BY_DEFAULT 1
#endif
#if !defined(UE_AUTORTFM_STATIC_VERIFIER)
#define UE_AUTORTFM_STATIC_VERIFIER 0
#endif
#if UE_AUTORTFM
// The annotated function will have no AutoRTFM closed variant generated, and
// cannot be called from another closed function. This attribute will eventually
// be deprecated and replaced with AUTORTFM_DISABLE.
#define UE_AUTORTFM_NOAUTORTFM [[clang::noautortfm]]
// Omits AutoRTFM instrumentation from the function. Calling this annotated
// function from the closed will automatically enter the open for the duration
// of the call and will return back to the closed.
#define UE_AUTORTFM_ALWAYS_OPEN [[clang::autortfm_always_open]]
// The same as UE_AUTORTFM_ALWAYS_OPEN, but disables memory validation for this
// call.
#define UE_AUTORTFM_ALWAYS_OPEN_NO_MEMORY_VALIDATION [[clang::autortfm_always_open_disable_memory_validation]]
// Annotation that can be applied to classes, methods or functions to prevent
// AutoRTFM closed function(s) from being generated.
// Applying the annotation to a class is equivalent to applying the annotation
// to each method of the class.
// When annotating a function, the attribute must be placed on a the function
// declaration (usually in the header) and not a function implementation.
// Annotated functions cannot be called from another closed function and
// attempting to do so will result in a runtime failure.
#define AUTORTFM_DISABLE [[clang::autortfm(disable)]]
// Applies the AUTORTFM_DISABLE annotation if the condition argument evaluates to true.
// Warning: This is an experimental API and may be removed in the future.
#define AUTORTFM_DISABLE_IF(...) [[clang::autortfm(disable, __VA_ARGS__)]]
// Begins a range where all classes and functions will be automatically
// annotated with AUTORTFM_DISABLE. Must be ended with AUTORTFM_DISABLE_END
// before the end of the file.
#define AUTORTFM_DISABLE_BEGIN _Pragma("clang attribute AutoRTFM_Disable.push (AUTORTFM_DISABLE, apply_to = any(function, record))")
// Ends a range started with AUTORTFM_DISABLE_BEGIN
#define AUTORTFM_DISABLE_END _Pragma("clang attribute AutoRTFM_Disable.pop")
// Annotation that can be applied to classes, methods or functions to re-enable
// AutoRTFM instrumentation which would otherwise be disabled by AUTORTFM_DISABLE.
// Useful for selectively enabling AutoRTFM on methods when a class is annotated
// AUTORTFM_DISABLE.
#define AUTORTFM_ENABLE [[clang::autortfm(enable)]]
// Annotation that can be applied to classes, methods or functions to infer
// whether AutoRTFM instrumentation should be enabled for each individual
// function based on the AutoRTFM-enabled state of each callee made by the
// function. If the function calls any AutoRTFM-disabled function, then the
// function will also be AutoRTFM-disabled, otherwise the function is
// AutoRTFM-enabled.
// Applying the annotation to a class is equivalent to applying the annotation
// to each method of the class.
// When annotating a function, the attribute must be placed on a the function
// declaration (usually in the header) and not a function implementation.
#define AUTORTFM_INFER [[clang::autortfm(infer)]]
// Annotation that can be applied to classes, methods or functions to prevent
// AutoRTFM closed function(s) from being generated. Unlike AUTORTFM_DISABLE
// annotated functions can be called from closed functions, which will call
// the uninstrumented function.
// Applying the annotation to a class is equivalent to applying the annotation
// to each method of the class.
// When annotating a function, the attribute must be placed on a the function
// declaration (usually in the header) and not a function implementation.
#define AUTORTFM_OPEN [[clang::autortfm(open)]]
// Similar to AUTORTFM_OPEN, but disables memory validation on the call.
#define AUTORTFM_OPEN_NO_VALIDATION [[clang::autortfm(open_no_validation)]]
// Evaluates to a constant true if:
// * EXPR_OR_TYPE is an address of a AutoRTFM-disabled function or method
// * EXPR_OR_TYPE is a type of a AutoRTFM-disabled class or struct
// Warning: This is an experimental API and may be removed in the future.
#define AUTORTFM_IS_DISABLED(EXPR_OR_TYPE) __autortfm_is_disabled(EXPR_OR_TYPE)
// Evaluates to a constant true if CALL_EXPR is a call a function, method,
// constructor (new T(...)) or destructor, and the call target is
// AutoRTFM-disabled.
// Warning: This is an experimental API and may be removed in the future.
#define AUTORTFM_CALL_IS_DISABLED(CALL_EXPR) __autortfm_is_disabled(__autortfm_declcall(CALL_EXPR))
// Force the call statement to be inlined.
#define UE_AUTORTFM_CALLSITE_FORCEINLINE [[clang::always_inline]]
#else // ^^^ UE_AUTORTFM ^^^ | vvv !UE_AUTORTFM vvv
#define UE_AUTORTFM_NOAUTORTFM
#define UE_AUTORTFM_ALWAYS_OPEN
#define UE_AUTORTFM_ALWAYS_OPEN_NO_MEMORY_VALIDATION
#define AUTORTFM_DISABLE
#define AUTORTFM_DISABLE_IF(CONDITION)
#define AUTORTFM_DISABLE_BEGIN
#define AUTORTFM_DISABLE_END
#define AUTORTFM_ENABLE
#define AUTORTFM_INFER
#define AUTORTFM_OPEN
#define AUTORTFM_OPEN_NO_VALIDATION
#define AUTORTFM_IS_DISABLED(EXPR_OR_TYPE) false
#define AUTORTFM_CALL_IS_DISABLED(EXPR_OR_TYPE) false
#define UE_AUTORTFM_CALLSITE_FORCEINLINE
#endif
#ifdef __cplusplus
#define AUTORTFM_NOEXCEPT noexcept
#define AUTORTFM_EXCEPT noexcept(false)
#else
#define AUTORTFM_NOEXCEPT
#define AUTORTFM_EXCEPT
#endif
#if UE_AUTORTFM && UE_AUTORTFM_STATIC_VERIFIER
#define UE_AUTORTFM_ENSURE_SAFE [[clang::autortfm_ensure_safe]]
#define UE_AUTORTFM_ASSUME_SAFE [[clang::autortfm_assume_safe]]
#else
#define UE_AUTORTFM_ENSURE_SAFE
#define UE_AUTORTFM_ASSUME_SAFE
#endif
#define UE_AUTORTFM_CONCAT_IMPL(A, B) A ## B
#define UE_AUTORTFM_CONCAT(A, B) UE_AUTORTFM_CONCAT_IMPL(A, B)
#if defined(__cplusplus) && defined(__UNREAL__) && !(defined(UE_AUTORTFM_DO_NOT_INCLUDE_PLATFORM_H) && UE_AUTORTFM_DO_NOT_INCLUDE_PLATFORM_H)
// Include HAL/Platform.h for DLLIMPORT / DLLEXPORT definitions, which
// UBT can use as a definition for AUTORTFM_API.
#include <HAL/Platform.h>
#define UE_AUTORTFM_API AUTORTFM_API
#else
#ifndef UE_AUTORTFM_API
#define UE_AUTORTFM_API
#endif
#endif
#if defined(_MSC_VER)
#define UE_AUTORTFM_FORCEINLINE __forceinline
#define UE_AUTORTFM_FORCEINLINE_ALWAYS __forceinline
#define UE_AUTORTFM_FORCENOINLINE __declspec(noinline)
#define UE_AUTORTFM_ASSUME(x) __assume(x)
#elif defined(__clang__)
#define UE_AUTORTFM_FORCEINLINE __attribute__((always_inline)) inline
#define UE_AUTORTFM_FORCEINLINE_ALWAYS __attribute__((always_inline)) inline
#define UE_AUTORTFM_FORCENOINLINE __attribute__((noinline))
#define UE_AUTORTFM_ASSUME(x) __builtin_assume(x)
#else
#define UE_AUTORTFM_FORCEINLINE inline
#define UE_AUTORTFM_FORCEINLINE_ALWAYS inline
#define UE_AUTORTFM_FORCENOINLINE
#define UE_AUTORTFM_ASSUME(x)
#endif
#if (defined(UE_BUILD_DEBUG) && UE_BUILD_DEBUG) || (defined(AUTORTFM_BUILD_DEBUG) && AUTORTFM_BUILD_DEBUG)
// Force-inlining can make debugging glitchy. Disable this if we're running a debug build.
#undef UE_AUTORTFM_CALLSITE_FORCEINLINE
#define UE_AUTORTFM_CALLSITE_FORCEINLINE
#undef UE_AUTORTFM_FORCEINLINE
#define UE_AUTORTFM_FORCEINLINE inline
#endif
#ifdef _MSC_VER
#define AUTORTFM_DISABLE_UNREACHABLE_CODE_WARNINGS \
__pragma (warning(push)) \
__pragma (warning(disable: 4702)) /* unreachable code */
#define AUTORTFM_RESTORE_UNREACHABLE_CODE_WARNINGS \
__pragma (warning(pop))
#else
#define AUTORTFM_DISABLE_UNREACHABLE_CODE_WARNINGS
#define AUTORTFM_RESTORE_UNREACHABLE_CODE_WARNINGS
#endif
#define UE_AUTORTFM_UNUSED(UNUSEDVAR) (void)UNUSEDVAR
// It is critical that these functions are both static and forceinline to prevent binary sizes to explode
// This is a trick to ensure that there will never be a non-inlined version of these functions that the linker can decide to use
#ifndef UE_HEADER_UNITS
#define UE_AUTORTFM_CRITICAL_INLINE static UE_AUTORTFM_FORCEINLINE
#define UE_AUTORTFM_CRITICAL_INLINE_ALWAYS static UE_AUTORTFM_FORCEINLINE_ALWAYS
#else
#define UE_AUTORTFM_CRITICAL_INLINE UE_AUTORTFM_FORCEINLINE // TODO: This needs to be revisited. we don't want bloated executables when modules are enabled
#define UE_AUTORTFM_CRITICAL_INLINE_ALWAYS UE_AUTORTFM_FORCEINLINE_ALWAYS // TODO: This needs to be revisited. we don't want bloated executables when modules are enabled
#endif