208 lines
8.6 KiB
C
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
|