- //===--- Visibility.h - Visibility enumeration and utilities ----*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- /// 
- /// \file 
- /// Defines the clang::Visibility enumeration and various utility 
- /// functions. 
- /// 
- //===----------------------------------------------------------------------===// 
- #ifndef LLVM_CLANG_BASIC_VISIBILITY_H 
- #define LLVM_CLANG_BASIC_VISIBILITY_H 
-   
- #include "clang/Basic/Linkage.h" 
- #include <cassert> 
- #include <cstdint> 
-   
- namespace clang { 
-   
- /// Describes the different kinds of visibility that a declaration 
- /// may have. 
- /// 
- /// Visibility determines how a declaration interacts with the dynamic 
- /// linker.  It may also affect whether the symbol can be found by runtime 
- /// symbol lookup APIs. 
- /// 
- /// Visibility is not described in any language standard and 
- /// (nonetheless) sometimes has odd behavior.  Not all platforms 
- /// support all visibility kinds. 
- enum Visibility { 
-   /// Objects with "hidden" visibility are not seen by the dynamic 
-   /// linker. 
-   HiddenVisibility, 
-   
-   /// Objects with "protected" visibility are seen by the dynamic 
-   /// linker but always dynamically resolve to an object within this 
-   /// shared object. 
-   ProtectedVisibility, 
-   
-   /// Objects with "default" visibility are seen by the dynamic linker 
-   /// and act like normal objects. 
-   DefaultVisibility 
- }; 
-   
- inline Visibility minVisibility(Visibility L, Visibility R) { 
-   return L < R ? L : R; 
- } 
-   
- class LinkageInfo { 
-   uint8_t linkage_    : 3; 
-   uint8_t visibility_ : 2; 
-   uint8_t explicit_   : 1; 
-   
-   void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; } 
- public: 
-   LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility), 
-                   explicit_(false) {} 
-   LinkageInfo(Linkage L, Visibility V, bool E) 
-     : linkage_(L), visibility_(V), explicit_(E) { 
-     assert(getLinkage() == L && getVisibility() == V && 
-            isVisibilityExplicit() == E && "Enum truncated!"); 
-   } 
-   
-   static LinkageInfo external() { 
-     return LinkageInfo(); 
-   } 
-   static LinkageInfo internal() { 
-     return LinkageInfo(InternalLinkage, DefaultVisibility, false); 
-   } 
-   static LinkageInfo uniqueExternal() { 
-     return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false); 
-   } 
-   static LinkageInfo none() { 
-     return LinkageInfo(NoLinkage, DefaultVisibility, false); 
-   } 
-   static LinkageInfo visible_none() { 
-     return LinkageInfo(VisibleNoLinkage, DefaultVisibility, false); 
-   } 
-   
-   Linkage getLinkage() const { return (Linkage)linkage_; } 
-   Visibility getVisibility() const { return (Visibility)visibility_; } 
-   bool isVisibilityExplicit() const { return explicit_; } 
-   
-   void setLinkage(Linkage L) { linkage_ = L; } 
-   
-   void mergeLinkage(Linkage L) { 
-     setLinkage(minLinkage(getLinkage(), L)); 
-   } 
-   void mergeLinkage(LinkageInfo other) { 
-     mergeLinkage(other.getLinkage()); 
-   } 
-   
-   void mergeExternalVisibility(Linkage L) { 
-     Linkage ThisL = getLinkage(); 
-     if (!isExternallyVisible(L)) { 
-       if (ThisL == VisibleNoLinkage) 
-         ThisL = NoLinkage; 
-       else if (ThisL == ExternalLinkage) 
-         ThisL = UniqueExternalLinkage; 
-     } 
-     setLinkage(ThisL); 
-   } 
-   void mergeExternalVisibility(LinkageInfo Other) { 
-     mergeExternalVisibility(Other.getLinkage()); 
-   } 
-   
-   /// Merge in the visibility 'newVis'. 
-   void mergeVisibility(Visibility newVis, bool newExplicit) { 
-     Visibility oldVis = getVisibility(); 
-   
-     // Never increase visibility. 
-     if (oldVis < newVis) 
-       return; 
-   
-     // If the new visibility is the same as the old and the new 
-     // visibility isn't explicit, we have nothing to add. 
-     if (oldVis == newVis && !newExplicit) 
-       return; 
-   
-     // Otherwise, we're either decreasing visibility or making our 
-     // existing visibility explicit. 
-     setVisibility(newVis, newExplicit); 
-   } 
-   void mergeVisibility(LinkageInfo other) { 
-     mergeVisibility(other.getVisibility(), other.isVisibilityExplicit()); 
-   } 
-   
-   /// Merge both linkage and visibility. 
-   void merge(LinkageInfo other) { 
-     mergeLinkage(other); 
-     mergeVisibility(other); 
-   } 
-   
-   /// Merge linkage and conditionally merge visibility. 
-   void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) { 
-     mergeLinkage(other); 
-     if (withVis) mergeVisibility(other); 
-   } 
- }; 
- } 
-   
- #endif // LLVM_CLANG_BASIC_VISIBILITY_H 
-