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