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