• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors. All rights reserved.
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 BASE_COMPONENT_EXPORT_H_
6 #define BASE_COMPONENT_EXPORT_H_
7 
8 #include "build/build_config.h"
9 
10 // Used to annotate symbols which are exported by the component named
11 // |component|. Note that this only does the right thing if the corresponding
12 // component target's sources are compiled with |IS_$component_IMPL| defined
13 // as 1. For example:
14 //
15 //   class COMPONENT_EXPORT(FOO) Bar {};
16 //
17 // If IS_FOO_IMPL=1 at compile time, then Bar will be annotated using the
18 // COMPONENT_EXPORT_ANNOTATION macro defined below. Otherwise it will be
19 // annotated using the COMPONENT_IMPORT_ANNOTATION macro.
20 #define COMPONENT_EXPORT(component)                         \
21   COMPONENT_MACRO_CONDITIONAL_(IS_##component##_IMPL,       \
22                                COMPONENT_EXPORT_ANNOTATION, \
23                                COMPONENT_IMPORT_ANNOTATION)
24 
25 // Indicates whether the current compilation unit is being compiled as part of
26 // the implementation of the component named |component|. Expands to |1| if
27 // |IS_$component_IMPL| is defined as |1|; expands to |0| otherwise.
28 //
29 // Note in particular that if |IS_$component_IMPL| is not defined at all, it is
30 // still fine to test INSIDE_COMPONENT_IMPL(component), which expands to |0| as
31 // expected.
32 #define INSIDE_COMPONENT_IMPL(component) \
33   COMPONENT_MACRO_CONDITIONAL_(IS_##component##_IMPL, 1, 0)
34 
35 // Compiler-specific macros to annotate for export or import of a symbol. No-op
36 // in non-component builds. These should not see much if any direct use.
37 // Instead use the COMPONENT_EXPORT macro defined above.
38 #if defined(COMPONENT_BUILD)
39 #if defined(WIN32)
40 #define COMPONENT_EXPORT_ANNOTATION __declspec(dllexport)
41 #define COMPONENT_IMPORT_ANNOTATION __declspec(dllimport)
42 #else  // defined(WIN32)
43 #define COMPONENT_EXPORT_ANNOTATION __attribute__((visibility("default")))
44 #define COMPONENT_IMPORT_ANNOTATION
45 #endif  // defined(WIN32)
46 #else   // defined(COMPONENT_BUILD)
47 #define COMPONENT_EXPORT_ANNOTATION
48 #define COMPONENT_IMPORT_ANNOTATION
49 #endif  // defined(COMPONENT_BUILD)
50 
51 // Below this point are several internal utility macros used for the
52 // implementation of the above macros. Not intended for external use.
53 
54 // Helper for conditional expansion to one of two token strings. If |condition|
55 // expands to |1| then this macro expands to |consequent|; otherwise it expands
56 // to |alternate|.
57 #define COMPONENT_MACRO_CONDITIONAL_(condition, consequent, alternate) \
58   COMPONENT_MACRO_SELECT_THIRD_ARGUMENT_(                              \
59       COMPONENT_MACRO_CONDITIONAL_COMMA_(condition), consequent, alternate)
60 
61 // Expands to a comma (,) iff its first argument expands to |1|. Used in
62 // conjunction with |COMPONENT_MACRO_SELECT_THIRD_ARGUMENT_()|, as the presence
63 // or absense of an extra comma can be used to conditionally shift subsequent
64 // argument positions and thus influence which argument is selected.
65 #define COMPONENT_MACRO_CONDITIONAL_COMMA_(...) \
66   COMPONENT_MACRO_CONDITIONAL_COMMA_IMPL_(__VA_ARGS__,)
67 #define COMPONENT_MACRO_CONDITIONAL_COMMA_IMPL_(x, ...) \
68   COMPONENT_MACRO_CONDITIONAL_COMMA_##x##_
69 #define COMPONENT_MACRO_CONDITIONAL_COMMA_1_ ,
70 
71 // Helper which simply selects its third argument. Used in conjunction with
72 // |COMPONENT_MACRO_CONDITIONAL_COMMA_()| above to implement conditional macro
73 // expansion.
74 #define COMPONENT_MACRO_SELECT_THIRD_ARGUMENT_(...) \
75   COMPONENT_MACRO_EXPAND_(                          \
76       COMPONENT_MACRO_SELECT_THIRD_ARGUMENT_IMPL_(__VA_ARGS__))
77 #define COMPONENT_MACRO_SELECT_THIRD_ARGUMENT_IMPL_(a, b, c, ...) c
78 
79 // Helper to work around MSVC quirkiness wherein a macro expansion like |,|
80 // within a parameter list will be treated as a single macro argument. This is
81 // needed to ensure that |COMPONENT_MACRO_CONDITIONAL_COMMA_()| above can expand
82 // to multiple separate positional arguments in the affirmative case, thus
83 // elliciting the desired conditional behavior with
84 // |COMPONENT_MACRO_SELECT_THIRD_ARGUMENT_()|.
85 #define COMPONENT_MACRO_EXPAND_(x) x
86 
87 #endif  // BASE_COMPONENT_EXPORT_H_
88