Visibility.h revision 353358
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 21namespace 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. 33enum 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 48inline Visibility minVisibility(Visibility L, Visibility R) { 49 return L < R ? L : R; 50} 51 52class LinkageInfo { 53 uint8_t linkage_ : 3; 54 uint8_t visibility_ : 2; 55 uint8_t explicit_ : 1; 56 57 void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; } 58public: 59 LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility), 60 explicit_(false) {} 61 LinkageInfo(Linkage L, Visibility V, bool E) 62 : linkage_(L), visibility_(V), explicit_(E) { 63 assert(getLinkage() == L && getVisibility() == V && 64 isVisibilityExplicit() == E && "Enum truncated!"); 65 } 66 67 static LinkageInfo external() { 68 return LinkageInfo(); 69 } 70 static LinkageInfo internal() { 71 return LinkageInfo(InternalLinkage, DefaultVisibility, false); 72 } 73 static LinkageInfo uniqueExternal() { 74 return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false); 75 } 76 static LinkageInfo none() { 77 return LinkageInfo(NoLinkage, DefaultVisibility, false); 78 } 79 static LinkageInfo visible_none() { 80 return LinkageInfo(VisibleNoLinkage, DefaultVisibility, false); 81 } 82 83 Linkage getLinkage() const { return (Linkage)linkage_; } 84 Visibility getVisibility() const { return (Visibility)visibility_; } 85 bool isVisibilityExplicit() const { return explicit_; } 86 87 void setLinkage(Linkage L) { linkage_ = L; } 88 89 void mergeLinkage(Linkage L) { 90 setLinkage(minLinkage(getLinkage(), L)); 91 } 92 void mergeLinkage(LinkageInfo other) { 93 mergeLinkage(other.getLinkage()); 94 } 95 96 void mergeExternalVisibility(Linkage L) { 97 Linkage ThisL = getLinkage(); 98 if (!isExternallyVisible(L)) { 99 if (ThisL == VisibleNoLinkage) 100 ThisL = NoLinkage; 101 else if (ThisL == ExternalLinkage) 102 ThisL = UniqueExternalLinkage; 103 } 104 setLinkage(ThisL); 105 } 106 void mergeExternalVisibility(LinkageInfo Other) { 107 mergeExternalVisibility(Other.getLinkage()); 108 } 109 110 /// Merge in the visibility 'newVis'. 111 void mergeVisibility(Visibility newVis, bool newExplicit) { 112 Visibility oldVis = getVisibility(); 113 114 // Never increase visibility. 115 if (oldVis < newVis) 116 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 if (oldVis == newVis && !newExplicit) 121 return; 122 123 // Otherwise, we're either decreasing visibility or making our 124 // existing visibility explicit. 125 setVisibility(newVis, newExplicit); 126 } 127 void mergeVisibility(LinkageInfo other) { 128 mergeVisibility(other.getVisibility(), other.isVisibilityExplicit()); 129 } 130 131 /// Merge both linkage and visibility. 132 void merge(LinkageInfo other) { 133 mergeLinkage(other); 134 mergeVisibility(other); 135 } 136 137 /// Merge linkage and conditionally merge visibility. 138 void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) { 139 mergeLinkage(other); 140 if (withVis) mergeVisibility(other); 141 } 142}; 143} 144 145#endif // LLVM_CLANG_BASIC_VISIBILITY_H 146