clang API Documentation
00001 //===--- Visibility.h - Visibility enumeration and utilities ----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// 00010 /// \file 00011 /// \brief Defines the clang::Visibility enumeration and various utility 00012 /// functions. 00013 /// 00014 //===----------------------------------------------------------------------===// 00015 #ifndef LLVM_CLANG_BASIC_VISIBILITY_H 00016 #define LLVM_CLANG_BASIC_VISIBILITY_H 00017 00018 #include "clang/Basic/Linkage.h" 00019 00020 namespace clang { 00021 00022 /// \brief Describes the different kinds of visibility that a declaration 00023 /// may have. 00024 /// 00025 /// Visibility determines how a declaration interacts with the dynamic 00026 /// linker. It may also affect whether the symbol can be found by runtime 00027 /// symbol lookup APIs. 00028 /// 00029 /// Visibility is not described in any language standard and 00030 /// (nonetheless) sometimes has odd behavior. Not all platforms 00031 /// support all visibility kinds. 00032 enum Visibility { 00033 /// Objects with "hidden" visibility are not seen by the dynamic 00034 /// linker. 00035 HiddenVisibility, 00036 00037 /// Objects with "protected" visibility are seen by the dynamic 00038 /// linker but always dynamically resolve to an object within this 00039 /// shared object. 00040 ProtectedVisibility, 00041 00042 /// Objects with "default" visibility are seen by the dynamic linker 00043 /// and act like normal objects. 00044 DefaultVisibility 00045 }; 00046 00047 inline Visibility minVisibility(Visibility L, Visibility R) { 00048 return L < R ? L : R; 00049 } 00050 00051 class LinkageInfo { 00052 uint8_t linkage_ : 3; 00053 uint8_t visibility_ : 2; 00054 uint8_t explicit_ : 1; 00055 00056 void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; } 00057 public: 00058 LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility), 00059 explicit_(false) {} 00060 LinkageInfo(Linkage L, Visibility V, bool E) 00061 : linkage_(L), visibility_(V), explicit_(E) { 00062 assert(getLinkage() == L && getVisibility() == V && 00063 isVisibilityExplicit() == E && "Enum truncated!"); 00064 } 00065 00066 static LinkageInfo external() { 00067 return LinkageInfo(); 00068 } 00069 static LinkageInfo internal() { 00070 return LinkageInfo(InternalLinkage, DefaultVisibility, false); 00071 } 00072 static LinkageInfo uniqueExternal() { 00073 return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false); 00074 } 00075 static LinkageInfo none() { 00076 return LinkageInfo(NoLinkage, DefaultVisibility, false); 00077 } 00078 00079 Linkage getLinkage() const { return (Linkage)linkage_; } 00080 Visibility getVisibility() const { return (Visibility)visibility_; } 00081 bool isVisibilityExplicit() const { return explicit_; } 00082 00083 void setLinkage(Linkage L) { linkage_ = L; } 00084 00085 void mergeLinkage(Linkage L) { 00086 setLinkage(minLinkage(getLinkage(), L)); 00087 } 00088 void mergeLinkage(LinkageInfo other) { 00089 mergeLinkage(other.getLinkage()); 00090 } 00091 00092 void mergeExternalVisibility(Linkage L) { 00093 Linkage ThisL = getLinkage(); 00094 if (!isExternallyVisible(L)) { 00095 if (ThisL == VisibleNoLinkage) 00096 ThisL = NoLinkage; 00097 else if (ThisL == ExternalLinkage) 00098 ThisL = UniqueExternalLinkage; 00099 } 00100 setLinkage(ThisL); 00101 } 00102 void mergeExternalVisibility(LinkageInfo Other) { 00103 mergeExternalVisibility(Other.getLinkage()); 00104 } 00105 00106 /// Merge in the visibility 'newVis'. 00107 void mergeVisibility(Visibility newVis, bool newExplicit) { 00108 Visibility oldVis = getVisibility(); 00109 00110 // Never increase visibility. 00111 if (oldVis < newVis) 00112 return; 00113 00114 // If the new visibility is the same as the old and the new 00115 // visibility isn't explicit, we have nothing to add. 00116 if (oldVis == newVis && !newExplicit) 00117 return; 00118 00119 // Otherwise, we're either decreasing visibility or making our 00120 // existing visibility explicit. 00121 setVisibility(newVis, newExplicit); 00122 } 00123 void mergeVisibility(LinkageInfo other) { 00124 mergeVisibility(other.getVisibility(), other.isVisibilityExplicit()); 00125 } 00126 00127 /// Merge both linkage and visibility. 00128 void merge(LinkageInfo other) { 00129 mergeLinkage(other); 00130 mergeVisibility(other); 00131 } 00132 00133 /// Merge linkage and conditionally merge visibility. 00134 void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) { 00135 mergeLinkage(other); 00136 if (withVis) mergeVisibility(other); 00137 } 00138 }; 00139 } 00140 00141 #endif // LLVM_CLANG_BASIC_VISIBILITY_H