1 // Copyright 2018 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef PARTITION_ALLOC_PARTITION_ALLOC_BASE_COMPONENT_EXPORT_H_ 6 #define PARTITION_ALLOC_PARTITION_ALLOC_BASE_COMPONENT_EXPORT_H_ 7 8 // Used to annotate symbols which are exported by the component named 9 // |component|. Note that this only does the right thing if the corresponding 10 // component target's sources are compiled with |IS_$component_IMPL| defined 11 // as 1. For example: 12 // 13 // class PA_COMPONENT_EXPORT(FOO) Bar {}; 14 // 15 // If IS_FOO_IMPL=1 at compile time, then Bar will be annotated using the 16 // PA_COMPONENT_EXPORT_ANNOTATION macro defined below. Otherwise it will be 17 // annotated using the PA_COMPONENT_IMPORT_ANNOTATION macro. 18 #define PA_COMPONENT_EXPORT(component) \ 19 PA_COMPONENT_MACRO_CONDITIONAL_(IS_##component##_IMPL, \ 20 PA_COMPONENT_EXPORT_ANNOTATION, \ 21 PA_COMPONENT_IMPORT_ANNOTATION) 22 23 // Indicates whether the current compilation unit is being compiled as part of 24 // the implementation of the component named |component|. Expands to |1| if 25 // |IS_$component_IMPL| is defined as |1|; expands to |0| otherwise. 26 // 27 // Note in particular that if |IS_$component_IMPL| is not defined at all, it is 28 // still fine to test PA_INSIDE_COMPONENT_IMPL(component), which expands to |0| 29 // as expected. 30 #define PA_INSIDE_COMPONENT_IMPL(component) \ 31 PA_COMPONENT_MACRO_CONDITIONAL_(IS_##component##_IMPL, 1, 0) 32 33 // Compiler-specific macros to annotate for export or import of a symbol. No-op 34 // in non-component builds. These should not see much if any direct use. 35 // Instead use the PA_COMPONENT_EXPORT macro defined above. 36 #if defined(COMPONENT_BUILD) 37 #if defined(WIN32) 38 #define PA_COMPONENT_EXPORT_ANNOTATION __declspec(dllexport) 39 #define PA_COMPONENT_IMPORT_ANNOTATION __declspec(dllimport) 40 #else // defined(WIN32) 41 #define PA_COMPONENT_EXPORT_ANNOTATION __attribute__((visibility("default"))) 42 #define PA_COMPONENT_IMPORT_ANNOTATION 43 #endif // defined(WIN32) 44 #else // defined(COMPONENT_BUILD) 45 #define PA_COMPONENT_EXPORT_ANNOTATION 46 #define PA_COMPONENT_IMPORT_ANNOTATION 47 #endif // defined(COMPONENT_BUILD) 48 49 // Below this point are several internal utility macros used for the 50 // implementation of the above macros. Not intended for external use. 51 52 // Helper for conditional expansion to one of two token strings. If |condition| 53 // expands to |1| then this macro expands to |consequent|; otherwise it expands 54 // to |alternate|. 55 #define PA_COMPONENT_MACRO_CONDITIONAL_(condition, consequent, alternate) \ 56 PA_COMPONENT_MACRO_SELECT_THIRD_ARGUMENT_( \ 57 PA_COMPONENT_MACRO_CONDITIONAL_COMMA_(condition), consequent, alternate) 58 59 // MSVC workaround for __VA_ARGS__ expanding into one expression. 60 #define PA_MSVC_EXPAND_ARG(arg) arg 61 62 // Expands to a comma (,) iff its first argument expands to |1|. Used in 63 // conjunction with |PA_COMPONENT_MACRO_SELECT_THIRD_ARGUMENT_()|, as the 64 // presence or absense of an extra comma can be used to conditionally shift 65 // subsequent argument positions and thus influence which argument is selected. 66 #define PA_COMPONENT_MACRO_CONDITIONAL_COMMA_(...) \ 67 PA_COMPONENT_MACRO_CONDITIONAL_COMMA_IMPL_(__VA_ARGS__, ) 68 #define PA_COMPONENT_MACRO_CONDITIONAL_COMMA_IMPL_(x, ...) \ 69 PA_COMPONENT_MACRO_CONDITIONAL_COMMA_##x##_ 70 #define PA_COMPONENT_MACRO_CONDITIONAL_COMMA_1_ , 71 72 // Helper which simply selects its third argument. Used in conjunction with 73 // |PA_COMPONENT_MACRO_CONDITIONAL_COMMA_()| above to implement conditional 74 // macro expansion. 75 #define PA_COMPONENT_MACRO_SELECT_THIRD_ARGUMENT_(...) \ 76 PA_MSVC_EXPAND_ARG( \ 77 PA_COMPONENT_MACRO_SELECT_THIRD_ARGUMENT_IMPL_(__VA_ARGS__)) 78 #define PA_COMPONENT_MACRO_SELECT_THIRD_ARGUMENT_IMPL_(a, b, c, ...) c 79 80 #endif // PARTITION_ALLOC_PARTITION_ALLOC_BASE_COMPONENT_EXPORT_H_ 81