1218887Sdim//===--- Visibility.h - Visibility enumeration and utilities ----*- C++ -*-===// 2218887Sdim// 3218887Sdim// The LLVM Compiler Infrastructure 4218887Sdim// 5218887Sdim// This file is distributed under the University of Illinois Open Source 6218887Sdim// License. See LICENSE.TXT for details. 7218887Sdim// 8218887Sdim//===----------------------------------------------------------------------===// 9245431Sdim/// 10245431Sdim/// \file 11245431Sdim/// \brief Defines the clang::Visibility enumeration and various utility 12245431Sdim/// functions. 13245431Sdim/// 14218887Sdim//===----------------------------------------------------------------------===// 15218887Sdim#ifndef LLVM_CLANG_BASIC_VISIBILITY_H 16218887Sdim#define LLVM_CLANG_BASIC_VISIBILITY_H 17218887Sdim 18252723Sdim#include "clang/Basic/Linkage.h" 19252723Sdim 20218887Sdimnamespace clang { 21218887Sdim 22245431Sdim/// \brief Describes the different kinds of visibility that a declaration 23245431Sdim/// may have. 24218887Sdim/// 25245431Sdim/// Visibility determines how a declaration interacts with the dynamic 26245431Sdim/// linker. It may also affect whether the symbol can be found by runtime 27245431Sdim/// symbol lookup APIs. 28245431Sdim/// 29218887Sdim/// Visibility is not described in any language standard and 30218887Sdim/// (nonetheless) sometimes has odd behavior. Not all platforms 31218887Sdim/// support all visibility kinds. 32218887Sdimenum Visibility { 33218887Sdim /// Objects with "hidden" visibility are not seen by the dynamic 34218887Sdim /// linker. 35218887Sdim HiddenVisibility, 36218887Sdim 37218887Sdim /// Objects with "protected" visibility are seen by the dynamic 38218887Sdim /// linker but always dynamically resolve to an object within this 39218887Sdim /// shared object. 40218887Sdim ProtectedVisibility, 41218887Sdim 42218887Sdim /// Objects with "default" visibility are seen by the dynamic linker 43218887Sdim /// and act like normal objects. 44218887Sdim DefaultVisibility 45218887Sdim}; 46218887Sdim 47218887Sdiminline Visibility minVisibility(Visibility L, Visibility R) { 48218887Sdim return L < R ? L : R; 49218887Sdim} 50218887Sdim 51252723Sdimclass LinkageInfo { 52263509Sdim uint8_t linkage_ : 3; 53252723Sdim uint8_t visibility_ : 2; 54252723Sdim uint8_t explicit_ : 1; 55252723Sdim 56252723Sdim void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; } 57252723Sdimpublic: 58252723Sdim LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility), 59252723Sdim explicit_(false) {} 60252723Sdim LinkageInfo(Linkage L, Visibility V, bool E) 61252723Sdim : linkage_(L), visibility_(V), explicit_(E) { 62252723Sdim assert(getLinkage() == L && getVisibility() == V && 63252723Sdim isVisibilityExplicit() == E && "Enum truncated!"); 64252723Sdim } 65252723Sdim 66252723Sdim static LinkageInfo external() { 67252723Sdim return LinkageInfo(); 68252723Sdim } 69252723Sdim static LinkageInfo internal() { 70252723Sdim return LinkageInfo(InternalLinkage, DefaultVisibility, false); 71252723Sdim } 72252723Sdim static LinkageInfo uniqueExternal() { 73252723Sdim return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false); 74252723Sdim } 75252723Sdim static LinkageInfo none() { 76252723Sdim return LinkageInfo(NoLinkage, DefaultVisibility, false); 77252723Sdim } 78252723Sdim 79252723Sdim Linkage getLinkage() const { return (Linkage)linkage_; } 80252723Sdim Visibility getVisibility() const { return (Visibility)visibility_; } 81252723Sdim bool isVisibilityExplicit() const { return explicit_; } 82252723Sdim 83252723Sdim void setLinkage(Linkage L) { linkage_ = L; } 84252723Sdim 85252723Sdim void mergeLinkage(Linkage L) { 86252723Sdim setLinkage(minLinkage(getLinkage(), L)); 87252723Sdim } 88252723Sdim void mergeLinkage(LinkageInfo other) { 89252723Sdim mergeLinkage(other.getLinkage()); 90252723Sdim } 91252723Sdim 92263509Sdim void mergeExternalVisibility(Linkage L) { 93263509Sdim Linkage ThisL = getLinkage(); 94263509Sdim if (!isExternallyVisible(L)) { 95263509Sdim if (ThisL == VisibleNoLinkage) 96263509Sdim ThisL = NoLinkage; 97263509Sdim else if (ThisL == ExternalLinkage) 98263509Sdim ThisL = UniqueExternalLinkage; 99263509Sdim } 100263509Sdim setLinkage(ThisL); 101263509Sdim } 102263509Sdim void mergeExternalVisibility(LinkageInfo Other) { 103263509Sdim mergeExternalVisibility(Other.getLinkage()); 104263509Sdim } 105263509Sdim 106252723Sdim /// Merge in the visibility 'newVis'. 107252723Sdim void mergeVisibility(Visibility newVis, bool newExplicit) { 108252723Sdim Visibility oldVis = getVisibility(); 109252723Sdim 110252723Sdim // Never increase visibility. 111252723Sdim if (oldVis < newVis) 112252723Sdim return; 113252723Sdim 114252723Sdim // If the new visibility is the same as the old and the new 115252723Sdim // visibility isn't explicit, we have nothing to add. 116252723Sdim if (oldVis == newVis && !newExplicit) 117252723Sdim return; 118252723Sdim 119252723Sdim // Otherwise, we're either decreasing visibility or making our 120252723Sdim // existing visibility explicit. 121252723Sdim setVisibility(newVis, newExplicit); 122252723Sdim } 123252723Sdim void mergeVisibility(LinkageInfo other) { 124252723Sdim mergeVisibility(other.getVisibility(), other.isVisibilityExplicit()); 125252723Sdim } 126252723Sdim 127252723Sdim /// Merge both linkage and visibility. 128252723Sdim void merge(LinkageInfo other) { 129252723Sdim mergeLinkage(other); 130252723Sdim mergeVisibility(other); 131252723Sdim } 132252723Sdim 133252723Sdim /// Merge linkage and conditionally merge visibility. 134252723Sdim void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) { 135252723Sdim mergeLinkage(other); 136252723Sdim if (withVis) mergeVisibility(other); 137252723Sdim } 138252723Sdim}; 139218887Sdim} 140218887Sdim 141218887Sdim#endif // LLVM_CLANG_BASIC_VISIBILITY_H 142