/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Basic/Visibility.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- Visibility.h - Visibility enumeration and utilities ----*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | /// |
9 | | /// \file |
10 | | /// Defines the clang::Visibility enumeration and various utility |
11 | | /// functions. |
12 | | /// |
13 | | //===----------------------------------------------------------------------===// |
14 | | #ifndef LLVM_CLANG_BASIC_VISIBILITY_H |
15 | | #define LLVM_CLANG_BASIC_VISIBILITY_H |
16 | | |
17 | | #include "clang/Basic/Linkage.h" |
18 | | #include <cassert> |
19 | | #include <cstdint> |
20 | | |
21 | | namespace clang { |
22 | | |
23 | | /// Describes the different kinds of visibility that a declaration |
24 | | /// may have. |
25 | | /// |
26 | | /// Visibility determines how a declaration interacts with the dynamic |
27 | | /// linker. It may also affect whether the symbol can be found by runtime |
28 | | /// symbol lookup APIs. |
29 | | /// |
30 | | /// Visibility is not described in any language standard and |
31 | | /// (nonetheless) sometimes has odd behavior. Not all platforms |
32 | | /// support all visibility kinds. |
33 | | enum Visibility { |
34 | | /// Objects with "hidden" visibility are not seen by the dynamic |
35 | | /// linker. |
36 | | HiddenVisibility, |
37 | | |
38 | | /// Objects with "protected" visibility are seen by the dynamic |
39 | | /// linker but always dynamically resolve to an object within this |
40 | | /// shared object. |
41 | | ProtectedVisibility, |
42 | | |
43 | | /// Objects with "default" visibility are seen by the dynamic linker |
44 | | /// and act like normal objects. |
45 | | DefaultVisibility |
46 | | }; |
47 | | |
48 | 0 | inline Visibility minVisibility(Visibility L, Visibility R) { |
49 | 0 | return L < R ? L : R; |
50 | 0 | } |
51 | | |
52 | | class LinkageInfo { |
53 | | uint8_t linkage_ : 3; |
54 | | uint8_t visibility_ : 2; |
55 | | uint8_t explicit_ : 1; |
56 | | |
57 | 2.78M | void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; } |
58 | | public: |
59 | | LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility), |
60 | 33.3M | explicit_(false) {} |
61 | | LinkageInfo(Linkage L, Visibility V, bool E) |
62 | 81.4M | : linkage_(L), visibility_(V), explicit_(E) { |
63 | 81.4M | assert(getLinkage() == L && getVisibility() == V && |
64 | 81.4M | isVisibilityExplicit() == E && "Enum truncated!"); |
65 | 81.4M | } |
66 | | |
67 | 8.24M | static LinkageInfo external() { |
68 | 8.24M | return LinkageInfo(); |
69 | 8.24M | } |
70 | 9.72M | static LinkageInfo internal() { |
71 | 9.72M | return LinkageInfo(InternalLinkage, DefaultVisibility, false); |
72 | 9.72M | } |
73 | 7.03k | static LinkageInfo uniqueExternal() { |
74 | 7.03k | return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false); |
75 | 7.03k | } |
76 | 2.30M | static LinkageInfo none() { |
77 | 2.30M | return LinkageInfo(NoLinkage, DefaultVisibility, false); |
78 | 2.30M | } |
79 | 1 | static LinkageInfo visible_none() { |
80 | 1 | return LinkageInfo(VisibleNoLinkage, DefaultVisibility, false); |
81 | 1 | } |
82 | | |
83 | 214M | Linkage getLinkage() const { return (Linkage)linkage_; } |
84 | 94.4M | Visibility getVisibility() const { return (Visibility)visibility_; } |
85 | 91.4M | bool isVisibilityExplicit() const { return explicit_; } |
86 | | |
87 | 6.04M | void setLinkage(Linkage L) { linkage_ = L; } |
88 | | |
89 | 5.04M | void mergeLinkage(Linkage L) { |
90 | 5.04M | setLinkage(minLinkage(getLinkage(), L)); |
91 | 5.04M | } |
92 | 5.04M | void mergeLinkage(LinkageInfo other) { |
93 | 5.04M | mergeLinkage(other.getLinkage()); |
94 | 5.04M | } |
95 | | |
96 | 993k | void mergeExternalVisibility(Linkage L) { |
97 | 993k | Linkage ThisL = getLinkage(); |
98 | 993k | if (!isExternallyVisible(L)) { |
99 | 12.3k | if (ThisL == VisibleNoLinkage) |
100 | 0 | ThisL = NoLinkage; |
101 | 12.3k | else if (ThisL == ExternalLinkage) |
102 | 12.3k | ThisL = UniqueExternalLinkage; |
103 | 12.3k | } |
104 | 993k | setLinkage(ThisL); |
105 | 993k | } |
106 | 993k | void mergeExternalVisibility(LinkageInfo Other) { |
107 | 993k | mergeExternalVisibility(Other.getLinkage()); |
108 | 993k | } |
109 | | |
110 | | /// Merge in the visibility 'newVis'. |
111 | 7.08M | void mergeVisibility(Visibility newVis, bool newExplicit) { |
112 | 7.08M | Visibility oldVis = getVisibility(); |
113 | | |
114 | | // Never increase visibility. |
115 | 7.08M | if (oldVis < newVis) |
116 | 250k | return; |
117 | | |
118 | | // If the new visibility is the same as the old and the new |
119 | | // visibility isn't explicit, we have nothing to add. |
120 | 6.83M | if (oldVis == newVis && !newExplicit6.58M ) |
121 | 4.05M | return; |
122 | | |
123 | | // Otherwise, we're either decreasing visibility or making our |
124 | | // existing visibility explicit. |
125 | 2.78M | setVisibility(newVis, newExplicit); |
126 | 2.78M | } |
127 | 5.50M | void mergeVisibility(LinkageInfo other) { |
128 | 5.50M | mergeVisibility(other.getVisibility(), other.isVisibilityExplicit()); |
129 | 5.50M | } |
130 | | |
131 | | /// Merge both linkage and visibility. |
132 | 2.02M | void merge(LinkageInfo other) { |
133 | 2.02M | mergeLinkage(other); |
134 | 2.02M | mergeVisibility(other); |
135 | 2.02M | } |
136 | | |
137 | | /// Merge linkage and conditionally merge visibility. |
138 | 3.02M | void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) { |
139 | 3.02M | mergeLinkage(other); |
140 | 3.02M | if (withVis) mergeVisibility(other)2.47M ; |
141 | 3.02M | } |
142 | | }; |
143 | | } |
144 | | |
145 | | #endif // LLVM_CLANG_BASIC_VISIBILITY_H |