summaryrefslogtreecommitdiff
path: root/libartbase/base/macros.h
blob: 3b8b8ff89efc3682d9d022da6e5ce02633a55041 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_LIBARTBASE_BASE_MACROS_H_
#define ART_LIBARTBASE_BASE_MACROS_H_

#include <stddef.h>  // for size_t
#include <unistd.h>  // for TEMP_FAILURE_RETRY

#include "android-base/format.h"
#include "android-base/macros.h"
#include "android-base/thread_annotations.h"

// Declare a friend relationship in a class with a test. Used rather that FRIEND_TEST to avoid
// globally importing gtest/gtest.h into the main ART header files.
#define ART_FRIEND_TEST(test_set_name, individual_test)\
friend class test_set_name##_##individual_test##_Test

// Declare a friend relationship in a class with a typed test.
#define ART_FRIEND_TYPED_TEST(test_set_name, individual_test)\
template<typename T> ART_FRIEND_TEST(test_set_name, individual_test)

// Shorthand for formatting with compile time checking of the format string
#define ART_FORMAT(str, ...) ::fmt::format(FMT_STRING(str), __VA_ARGS__)

// A macro to disallow new and delete operators for a class. It goes in the private: declarations.
// NOTE: Providing placement new (and matching delete) for constructing container elements.
#define DISALLOW_ALLOCATION() \
  public: \
    NO_RETURN ALWAYS_INLINE void operator delete(void*, size_t) { UNREACHABLE(); } \
    ALWAYS_INLINE void* operator new(size_t, void* ptr) noexcept { return ptr; } \
    ALWAYS_INLINE void operator delete(void*, void*) noexcept { } \
  private: \
    void* operator new(size_t) = delete  // NOLINT

// offsetof is not defined by the spec on types with non-standard layout,
// however it is implemented by compilers in practice.
// (note that reinterpret_cast is not valid constexpr)
//
// Alternative approach would be something like:
// #define OFFSETOF_HELPER(t, f) \
//   (reinterpret_cast<uintptr_t>(&reinterpret_cast<t*>(16)->f) - static_cast<uintptr_t>(16u))
// #define OFFSETOF_MEMBER(t, f) \
//   (__builtin_constant_p(OFFSETOF_HELPER(t,f)) ? OFFSETOF_HELPER(t,f) : OFFSETOF_HELPER(t,f))
#define OFFSETOF_MEMBER(t, f) offsetof(t, f)

#define OFFSETOF_MEMBERPTR(t, f) \
  (reinterpret_cast<uintptr_t>(&(reinterpret_cast<t*>(16)->*f)) - static_cast<uintptr_t>(16))  // NOLINT

#define ALIGNED(x) __attribute__ ((__aligned__(x)))
#define PACKED(x) __attribute__ ((__aligned__(x), __packed__))

// Stringify the argument.
#define QUOTE(x) #x
#define STRINGIFY(x) QUOTE(x)

// Append tokens after evaluating.
#define APPEND_TOKENS_AFTER_EVAL_2(a, b) a ## b
#define APPEND_TOKENS_AFTER_EVAL(a, b) APPEND_TOKENS_AFTER_EVAL_2(a, b)

#ifndef NDEBUG
#define ALWAYS_INLINE
#define FLATTEN
#else
#define ALWAYS_INLINE  __attribute__ ((always_inline))
#define FLATTEN  __attribute__ ((flatten))
#endif

#define NO_STACK_PROTECTOR __attribute__ ((no_stack_protector))

// clang doesn't like attributes on lambda functions. It would be nice to say:
//   #define ALWAYS_INLINE_LAMBDA ALWAYS_INLINE
#define ALWAYS_INLINE_LAMBDA

#define NO_INLINE __attribute__ ((noinline))

#if defined (__APPLE__)
#define HOT_ATTR
#define COLD_ATTR
#else
#define HOT_ATTR __attribute__ ((hot))
#define COLD_ATTR __attribute__ ((cold))
#endif

#define PURE __attribute__ ((__pure__))

// Define that a position within code is unreachable, for example:
//   int foo () { LOG(FATAL) << "Don't call me"; UNREACHABLE(); }
// without the UNREACHABLE a return statement would be necessary.
#define UNREACHABLE  __builtin_unreachable

// Add the C++11 noreturn attribute.
#define NO_RETURN [[ noreturn ]]  // NOLINT[whitespace/braces] [5]

// Annotalysis thread-safety analysis support. Things that are not in base.

#define LOCKABLE CAPABILITY("mutex")
#define SHARED_LOCKABLE SHARED_CAPABILITY("mutex")

// Some of the libs (e.g. libarttest(d)) require more public symbols when built
// in debug configuration.
// Using symbol visibility only for release builds allows to reduce the list of
// exported symbols and eliminates the need to check debug build configurations
// when changing the exported symbols.
#ifdef NDEBUG
#define HIDDEN __attribute__((visibility("hidden")))
#define PROTECTED __attribute__((visibility("protected")))
#define EXPORT __attribute__((visibility("default")))
#else
#define HIDDEN
#define PROTECTED
#define EXPORT
#endif

// Protected symbols must be declared with "protected" visibility attribute when
// building the library and "default" visibility when referred to from external
// libraries/binaries. Otherwise, the external code will expect the symbol to be
// defined locally and fail to link.
#ifdef BUILDING_LIBART
#define LIBART_PROTECTED PROTECTED
#else
#define LIBART_PROTECTED EXPORT
#endif

// Some global variables shouldn't be visible outside libraries declaring them.
// The attribute allows hiding them, so preventing direct access.
#define ALWAYS_HIDDEN __attribute__((visibility("hidden")))

#endif  // ART_LIBARTBASE_BASE_MACROS_H_