• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 #ifndef SkMacros_DEFINED
8 #define SkMacros_DEFINED
9 
10 /*
11  *  Usage:  SK_MACRO_CONCAT(a, b)   to construct the symbol ab
12  *
13  *  SK_MACRO_CONCAT_IMPL_PRIV just exists to make this work. Do not use directly
14  *
15  */
16 #define SK_MACRO_CONCAT(X, Y)           SK_MACRO_CONCAT_IMPL_PRIV(X, Y)
17 #define SK_MACRO_CONCAT_IMPL_PRIV(X, Y)  X ## Y
18 
19 /*
20  *  Usage: SK_MACRO_APPEND_LINE(foo)    to make foo123, where 123 is the current
21  *                                      line number. Easy way to construct
22  *                                      unique names for local functions or
23  *                                      variables.
24  */
25 #define SK_MACRO_APPEND_LINE(name)  SK_MACRO_CONCAT(name, __LINE__)
26 
27 #define SK_MACRO_APPEND_COUNTER(name) SK_MACRO_CONCAT(name, __COUNTER__)
28 
29 ////////////////////////////////////////////////////////////////////////////////
30 
31 // Can be used to bracket data types that must be dense/packed, e.g. hash keys.
32 #if defined(__clang__)  // This should work on GCC too, but GCC diagnostic pop didn't seem to work!
33     #define SK_BEGIN_REQUIRE_DENSE _Pragma("GCC diagnostic push") \
34                                    _Pragma("GCC diagnostic error \"-Wpadded\"")
35     #define SK_END_REQUIRE_DENSE   _Pragma("GCC diagnostic pop")
36 #else
37     #define SK_BEGIN_REQUIRE_DENSE
38     #define SK_END_REQUIRE_DENSE
39 #endif
40 
41 #if defined(__clang__) && defined(__has_feature)
42     // Some compilers have a preprocessor that does not appear to do short-circuit
43     // evaluation as expected
44     #if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
45         // Chrome had issues if we tried to include lsan_interface.h ourselves.
46         // https://github.com/llvm/llvm-project/blob/10a35632d55bb05004fe3d0c2d4432bb74897ee7/compiler-rt/include/sanitizer/lsan_interface.h#L26
47 extern "C" {
48         void __lsan_ignore_object(const void *p);
49 }
50         #define SK_INTENTIONALLY_LEAKED(X) __lsan_ignore_object(X)
51     #else
52         #define SK_INTENTIONALLY_LEAKED(X) ((void)0)
53     #endif
54 #else
55     #define SK_INTENTIONALLY_LEAKED(X) ((void)0)
56 #endif
57 
58 #define SK_INIT_TO_AVOID_WARNING    = 0
59 
60 ////////////////////////////////////////////////////////////////////////////////
61 
62 /**
63  * Defines overloaded bitwise operators to make it easier to use an enum as a
64  * bitfield.
65  */
66 #define SK_MAKE_BITFIELD_OPS(X) \
67     inline X operator ~(X a) { \
68         using U = std::underlying_type_t<X>; \
69         return (X) (~static_cast<U>(a)); \
70     } \
71     inline X operator |(X a, X b) { \
72         using U = std::underlying_type_t<X>; \
73         return (X) (static_cast<U>(a) | static_cast<U>(b)); \
74     } \
75     inline X& operator |=(X& a, X b) { \
76         return (a = a | b); \
77     } \
78     inline X operator &(X a, X b) { \
79         using U = std::underlying_type_t<X>; \
80         return (X) (static_cast<U>(a) & static_cast<U>(b)); \
81     } \
82     inline X& operator &=(X& a, X b) { \
83         return (a = a & b); \
84     }
85 
86 #define SK_DECL_BITFIELD_OPS_FRIENDS(X) \
87     friend X operator ~(X a); \
88     friend X operator |(X a, X b); \
89     friend X& operator |=(X& a, X b); \
90     \
91     friend X operator &(X a, X b); \
92     friend X& operator &=(X& a, X b);
93 
94 #endif  // SkMacros_DEFINED
95