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