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