81 lines
2.7 KiB
C++
81 lines
2.7 KiB
C++
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef THIRD_PARTY_BASE_COMPILER_SPECIFIC_H_
|
|
#define THIRD_PARTY_BASE_COMPILER_SPECIFIC_H_
|
|
|
|
#include "build/build_config.h"
|
|
|
|
// A wrapper around `__has_attribute`, similar to HAS_CPP_ATTRIBUTE.
|
|
#if defined(__has_attribute)
|
|
#define HAS_ATTRIBUTE(x) __has_attribute(x)
|
|
#else
|
|
#define HAS_ATTRIBUTE(x) 0
|
|
#endif
|
|
|
|
// Annotate a function indicating it should not be inlined.
|
|
// Use like:
|
|
// NOINLINE void DoStuff() { ... }
|
|
#if defined(__clang__) && HAS_ATTRIBUTE(noinline)
|
|
#define NOINLINE [[clang::noinline]]
|
|
#elif defined(COMPILER_GCC) && HAS_ATTRIBUTE(noinline)
|
|
#define NOINLINE __attribute__((noinline))
|
|
#elif defined(COMPILER_MSVC)
|
|
#define NOINLINE __declspec(noinline)
|
|
#else
|
|
#define NOINLINE
|
|
#endif
|
|
|
|
// Macro for hinting that an expression is likely to be false.
|
|
#if !defined(UNLIKELY)
|
|
#if defined(COMPILER_GCC) || defined(__clang__)
|
|
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
|
#else
|
|
#define UNLIKELY(x) (x)
|
|
#endif // defined(COMPILER_GCC)
|
|
#endif // !defined(UNLIKELY)
|
|
|
|
#if !defined(LIKELY)
|
|
#if defined(COMPILER_GCC) || defined(__clang__)
|
|
#define LIKELY(x) __builtin_expect(!!(x), 1)
|
|
#else
|
|
#define LIKELY(x) (x)
|
|
#endif // defined(COMPILER_GCC)
|
|
#endif // !defined(LIKELY)
|
|
|
|
// Marks a type as being eligible for the "trivial" ABI despite having a
|
|
// non-trivial destructor or copy/move constructor. Such types can be relocated
|
|
// after construction by simply copying their memory, which makes them eligible
|
|
// to be passed in registers. The canonical example is std::unique_ptr.
|
|
//
|
|
// Use with caution; this has some subtle effects on constructor/destructor
|
|
// ordering and will be very incorrect if the type relies on its address
|
|
// remaining constant. When used as a function argument (by value), the value
|
|
// may be constructed in the caller's stack frame, passed in a register, and
|
|
// then used and destructed in the callee's stack frame. A similar thing can
|
|
// occur when values are returned.
|
|
//
|
|
// TRIVIAL_ABI is not needed for types which have a trivial destructor and
|
|
// copy/move constructors, such as base::TimeTicks and other POD.
|
|
//
|
|
// It is also not likely to be effective on types too large to be passed in one
|
|
// or two registers on typical target ABIs.
|
|
//
|
|
// See also:
|
|
// https://clang.llvm.org/docs/AttributeReference.html#trivial-abi
|
|
// https://libcxx.llvm.org/docs/DesignDocs/UniquePtrTrivialAbi.html
|
|
#if defined(__clang__) && HAS_ATTRIBUTE(trivial_abi)
|
|
#define TRIVIAL_ABI [[clang::trivial_abi]]
|
|
#else
|
|
#define TRIVIAL_ABI
|
|
#endif
|
|
|
|
#if defined(__clang__)
|
|
#define GSL_POINTER [[gsl::Pointer]]
|
|
#else
|
|
#define GSL_POINTER
|
|
#endif
|
|
|
|
#endif // THIRD_PARTY_BASE_COMPILER_SPECIFIC_H_
|