Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:51

0001 //===--- Visibility.h - Visibility enumeration and utilities ----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// Defines the clang::Visibility enumeration and various utility
0011 /// functions.
0012 ///
0013 //===----------------------------------------------------------------------===//
0014 #ifndef LLVM_CLANG_BASIC_VISIBILITY_H
0015 #define LLVM_CLANG_BASIC_VISIBILITY_H
0016 
0017 #include "clang/Basic/Linkage.h"
0018 #include "llvm/ADT/STLForwardCompat.h"
0019 #include <cassert>
0020 #include <cstdint>
0021 
0022 namespace clang {
0023 
0024 /// Describes the different kinds of visibility that a declaration
0025 /// may have.
0026 ///
0027 /// Visibility determines how a declaration interacts with the dynamic
0028 /// linker.  It may also affect whether the symbol can be found by runtime
0029 /// symbol lookup APIs.
0030 ///
0031 /// Visibility is not described in any language standard and
0032 /// (nonetheless) sometimes has odd behavior.  Not all platforms
0033 /// support all visibility kinds.
0034 enum Visibility {
0035   /// Objects with "hidden" visibility are not seen by the dynamic
0036   /// linker.
0037   HiddenVisibility,
0038 
0039   /// Objects with "protected" visibility are seen by the dynamic
0040   /// linker but always dynamically resolve to an object within this
0041   /// shared object.
0042   ProtectedVisibility,
0043 
0044   /// Objects with "default" visibility are seen by the dynamic linker
0045   /// and act like normal objects.
0046   DefaultVisibility
0047 };
0048 
0049 inline Visibility minVisibility(Visibility L, Visibility R) {
0050   return L < R ? L : R;
0051 }
0052 
0053 class LinkageInfo {
0054   LLVM_PREFERRED_TYPE(Linkage)
0055   uint8_t linkage_    : 3;
0056   LLVM_PREFERRED_TYPE(Visibility)
0057   uint8_t visibility_ : 2;
0058   LLVM_PREFERRED_TYPE(bool)
0059   uint8_t explicit_   : 1;
0060 
0061   void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; }
0062 public:
0063   LinkageInfo()
0064       : linkage_(llvm::to_underlying(Linkage::External)),
0065         visibility_(DefaultVisibility), explicit_(false) {}
0066   LinkageInfo(Linkage L, Visibility V, bool E)
0067       : linkage_(llvm::to_underlying(L)), visibility_(V), explicit_(E) {
0068     assert(getLinkage() == L && getVisibility() == V &&
0069            isVisibilityExplicit() == E && "Enum truncated!");
0070   }
0071 
0072   static LinkageInfo external() {
0073     return LinkageInfo();
0074   }
0075   static LinkageInfo internal() {
0076     return LinkageInfo(Linkage::Internal, DefaultVisibility, false);
0077   }
0078   static LinkageInfo uniqueExternal() {
0079     return LinkageInfo(Linkage::UniqueExternal, DefaultVisibility, false);
0080   }
0081   static LinkageInfo none() {
0082     return LinkageInfo(Linkage::None, DefaultVisibility, false);
0083   }
0084   static LinkageInfo visible_none() {
0085     return LinkageInfo(Linkage::VisibleNone, DefaultVisibility, false);
0086   }
0087 
0088   Linkage getLinkage() const { return static_cast<Linkage>(linkage_); }
0089   Visibility getVisibility() const { return (Visibility)visibility_; }
0090   bool isVisibilityExplicit() const { return explicit_; }
0091 
0092   void setLinkage(Linkage L) { linkage_ = llvm::to_underlying(L); }
0093 
0094   void mergeLinkage(Linkage L) {
0095     setLinkage(minLinkage(getLinkage(), L));
0096   }
0097   void mergeLinkage(LinkageInfo other) {
0098     mergeLinkage(other.getLinkage());
0099   }
0100 
0101   void mergeExternalVisibility(Linkage L) {
0102     Linkage ThisL = getLinkage();
0103     if (!isExternallyVisible(L)) {
0104       if (ThisL == Linkage::VisibleNone)
0105         ThisL = Linkage::None;
0106       else if (ThisL == Linkage::External)
0107         ThisL = Linkage::UniqueExternal;
0108     }
0109     setLinkage(ThisL);
0110   }
0111   void mergeExternalVisibility(LinkageInfo Other) {
0112     mergeExternalVisibility(Other.getLinkage());
0113   }
0114 
0115   /// Merge in the visibility 'newVis'.
0116   void mergeVisibility(Visibility newVis, bool newExplicit) {
0117     Visibility oldVis = getVisibility();
0118 
0119     // Never increase visibility.
0120     if (oldVis < newVis)
0121       return;
0122 
0123     // If the new visibility is the same as the old and the new
0124     // visibility isn't explicit, we have nothing to add.
0125     if (oldVis == newVis && !newExplicit)
0126       return;
0127 
0128     // Otherwise, we're either decreasing visibility or making our
0129     // existing visibility explicit.
0130     setVisibility(newVis, newExplicit);
0131   }
0132   void mergeVisibility(LinkageInfo other) {
0133     mergeVisibility(other.getVisibility(), other.isVisibilityExplicit());
0134   }
0135 
0136   /// Merge both linkage and visibility.
0137   void merge(LinkageInfo other) {
0138     mergeLinkage(other);
0139     mergeVisibility(other);
0140   }
0141 
0142   /// Merge linkage and conditionally merge visibility.
0143   void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) {
0144     mergeLinkage(other);
0145     if (withVis) mergeVisibility(other);
0146   }
0147 };
0148 }
0149 
0150 #endif // LLVM_CLANG_BASIC_VISIBILITY_H