blob: b5cb364f0d4a7bf794031c801ddcc58199be6f0a [file] [log] [blame]
Ken Rockot3044d212018-01-23 02:44:391// 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_