11fb0caaa7bef765b85972274e3b434af2572c141John McCall//===--- Visibility.h - Visibility enumeration and utilities ----*- C++ -*-===// 21fb0caaa7bef765b85972274e3b434af2572c141John McCall// 31fb0caaa7bef765b85972274e3b434af2572c141John McCall// The LLVM Compiler Infrastructure 41fb0caaa7bef765b85972274e3b434af2572c141John McCall// 51fb0caaa7bef765b85972274e3b434af2572c141John McCall// This file is distributed under the University of Illinois Open Source 61fb0caaa7bef765b85972274e3b434af2572c141John McCall// License. See LICENSE.TXT for details. 71fb0caaa7bef765b85972274e3b434af2572c141John McCall// 81fb0caaa7bef765b85972274e3b434af2572c141John McCall//===----------------------------------------------------------------------===// 92f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// 102f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// \file 112f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// \brief Defines the clang::Visibility enumeration and various utility 122f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// functions. 132f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// 141fb0caaa7bef765b85972274e3b434af2572c141John McCall//===----------------------------------------------------------------------===// 151fb0caaa7bef765b85972274e3b434af2572c141John McCall#ifndef LLVM_CLANG_BASIC_VISIBILITY_H 161fb0caaa7bef765b85972274e3b434af2572c141John McCall#define LLVM_CLANG_BASIC_VISIBILITY_H 171fb0caaa7bef765b85972274e3b434af2572c141John McCall 182beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola#include "clang/Basic/Linkage.h" 192beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola 201fb0caaa7bef765b85972274e3b434af2572c141John McCallnamespace clang { 211fb0caaa7bef765b85972274e3b434af2572c141John McCall 22af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// \brief Describes the different kinds of visibility that a declaration 23af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// may have. 24af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// 25af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// Visibility determines how a declaration interacts with the dynamic 26af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// linker. It may also affect whether the symbol can be found by runtime 27af50aab0c317462129d73ae8000c6394c718598dJames Dennett/// symbol lookup APIs. 281fb0caaa7bef765b85972274e3b434af2572c141John McCall/// 291fb0caaa7bef765b85972274e3b434af2572c141John McCall/// Visibility is not described in any language standard and 301fb0caaa7bef765b85972274e3b434af2572c141John McCall/// (nonetheless) sometimes has odd behavior. Not all platforms 311fb0caaa7bef765b85972274e3b434af2572c141John McCall/// support all visibility kinds. 321fb0caaa7bef765b85972274e3b434af2572c141John McCallenum Visibility { 331fb0caaa7bef765b85972274e3b434af2572c141John McCall /// Objects with "hidden" visibility are not seen by the dynamic 341fb0caaa7bef765b85972274e3b434af2572c141John McCall /// linker. 351fb0caaa7bef765b85972274e3b434af2572c141John McCall HiddenVisibility, 361fb0caaa7bef765b85972274e3b434af2572c141John McCall 371fb0caaa7bef765b85972274e3b434af2572c141John McCall /// Objects with "protected" visibility are seen by the dynamic 381fb0caaa7bef765b85972274e3b434af2572c141John McCall /// linker but always dynamically resolve to an object within this 391fb0caaa7bef765b85972274e3b434af2572c141John McCall /// shared object. 401fb0caaa7bef765b85972274e3b434af2572c141John McCall ProtectedVisibility, 411fb0caaa7bef765b85972274e3b434af2572c141John McCall 421fb0caaa7bef765b85972274e3b434af2572c141John McCall /// Objects with "default" visibility are seen by the dynamic linker 431fb0caaa7bef765b85972274e3b434af2572c141John McCall /// and act like normal objects. 441fb0caaa7bef765b85972274e3b434af2572c141John McCall DefaultVisibility 451fb0caaa7bef765b85972274e3b434af2572c141John McCall}; 461fb0caaa7bef765b85972274e3b434af2572c141John McCall 471fb0caaa7bef765b85972274e3b434af2572c141John McCallinline Visibility minVisibility(Visibility L, Visibility R) { 481fb0caaa7bef765b85972274e3b434af2572c141John McCall return L < R ? L : R; 491fb0caaa7bef765b85972274e3b434af2572c141John McCall} 501fb0caaa7bef765b85972274e3b434af2572c141John McCall 512beda12c3fbaa9125831b7f818680978c596b205Rafael Espindolaclass LinkageInfo { 52a99ecbcc4c431d52df0b01539035ab5281d54656Rafael Espindola uint8_t linkage_ : 3; 532beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola uint8_t visibility_ : 2; 542beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola uint8_t explicit_ : 1; 552beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola 562beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; } 572beda12c3fbaa9125831b7f818680978c596b205Rafael Espindolapublic: 582beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility), 592beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola explicit_(false) {} 602beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola LinkageInfo(Linkage L, Visibility V, bool E) 612beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola : linkage_(L), visibility_(V), explicit_(E) { 62f127eb8aeb3ce861f3dbc1adbb3362bfd98461e1Rafael Espindola assert(getLinkage() == L && getVisibility() == V && 63f127eb8aeb3ce861f3dbc1adbb3362bfd98461e1Rafael Espindola isVisibilityExplicit() == E && "Enum truncated!"); 642beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola } 652beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola 662beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola static LinkageInfo external() { 672beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola return LinkageInfo(); 682beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola } 692beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola static LinkageInfo internal() { 702beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola return LinkageInfo(InternalLinkage, DefaultVisibility, false); 712beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola } 722beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola static LinkageInfo uniqueExternal() { 732beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false); 742beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola } 752beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola static LinkageInfo none() { 762beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola return LinkageInfo(NoLinkage, DefaultVisibility, false); 772beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola } 782beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola 79f127eb8aeb3ce861f3dbc1adbb3362bfd98461e1Rafael Espindola Linkage getLinkage() const { return (Linkage)linkage_; } 80f127eb8aeb3ce861f3dbc1adbb3362bfd98461e1Rafael Espindola Visibility getVisibility() const { return (Visibility)visibility_; } 81f127eb8aeb3ce861f3dbc1adbb3362bfd98461e1Rafael Espindola bool isVisibilityExplicit() const { return explicit_; } 822beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola 832beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola void setLinkage(Linkage L) { linkage_ = L; } 842beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola 852beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola void mergeLinkage(Linkage L) { 86f127eb8aeb3ce861f3dbc1adbb3362bfd98461e1Rafael Espindola setLinkage(minLinkage(getLinkage(), L)); 872beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola } 882beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola void mergeLinkage(LinkageInfo other) { 89f127eb8aeb3ce861f3dbc1adbb3362bfd98461e1Rafael Espindola mergeLinkage(other.getLinkage()); 902beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola } 912beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola 92e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola void mergeExternalVisibility(Linkage L) { 93e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola Linkage ThisL = getLinkage(); 94e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola if (!isExternallyVisible(L)) { 95e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola if (ThisL == VisibleNoLinkage) 96e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola ThisL = NoLinkage; 97e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola else if (ThisL == ExternalLinkage) 98e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola ThisL = UniqueExternalLinkage; 99e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola } 100e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola setLinkage(ThisL); 101e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola } 102e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola void mergeExternalVisibility(LinkageInfo Other) { 103e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola mergeExternalVisibility(Other.getLinkage()); 104e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola } 105e98089083f2504a4b1f55a9f00a2a2df63cb72e0Rafael Espindola 1062beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola /// Merge in the visibility 'newVis'. 1072beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola void mergeVisibility(Visibility newVis, bool newExplicit) { 108f127eb8aeb3ce861f3dbc1adbb3362bfd98461e1Rafael Espindola Visibility oldVis = getVisibility(); 1092beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola 1102beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola // Never increase visibility. 1112beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola if (oldVis < newVis) 1122beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola return; 1132beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola 1142beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola // If the new visibility is the same as the old and the new 1152beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola // visibility isn't explicit, we have nothing to add. 1162beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola if (oldVis == newVis && !newExplicit) 1172beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola return; 1182beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola 1192beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola // Otherwise, we're either decreasing visibility or making our 1202beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola // existing visibility explicit. 1212beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola setVisibility(newVis, newExplicit); 1222beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola } 1232beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola void mergeVisibility(LinkageInfo other) { 124f127eb8aeb3ce861f3dbc1adbb3362bfd98461e1Rafael Espindola mergeVisibility(other.getVisibility(), other.isVisibilityExplicit()); 1252beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola } 1262beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola 1272beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola /// Merge both linkage and visibility. 1282beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola void merge(LinkageInfo other) { 1292beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola mergeLinkage(other); 1302beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola mergeVisibility(other); 1312beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola } 1322beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola 1332beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola /// Merge linkage and conditionally merge visibility. 1342beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) { 1352beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola mergeLinkage(other); 1362beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola if (withVis) mergeVisibility(other); 1372beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola } 1382beda12c3fbaa9125831b7f818680978c596b205Rafael Espindola}; 1391fb0caaa7bef765b85972274e3b434af2572c141John McCall} 1401fb0caaa7bef765b85972274e3b434af2572c141John McCall 1411fb0caaa7bef765b85972274e3b434af2572c141John McCall#endif // LLVM_CLANG_BASIC_VISIBILITY_H 142