Visibility.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- Visibility.h - Visibility enumeration and utilities ----*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. ///
  14. /// \file
  15. /// Defines the clang::Visibility enumeration and various utility
  16. /// functions.
  17. ///
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_CLANG_BASIC_VISIBILITY_H
  20. #define LLVM_CLANG_BASIC_VISIBILITY_H
  21. #include "clang/Basic/Linkage.h"
  22. #include <cassert>
  23. #include <cstdint>
  24. namespace clang {
  25. /// Describes the different kinds of visibility that a declaration
  26. /// may have.
  27. ///
  28. /// Visibility determines how a declaration interacts with the dynamic
  29. /// linker. It may also affect whether the symbol can be found by runtime
  30. /// symbol lookup APIs.
  31. ///
  32. /// Visibility is not described in any language standard and
  33. /// (nonetheless) sometimes has odd behavior. Not all platforms
  34. /// support all visibility kinds.
  35. enum Visibility {
  36. /// Objects with "hidden" visibility are not seen by the dynamic
  37. /// linker.
  38. HiddenVisibility,
  39. /// Objects with "protected" visibility are seen by the dynamic
  40. /// linker but always dynamically resolve to an object within this
  41. /// shared object.
  42. ProtectedVisibility,
  43. /// Objects with "default" visibility are seen by the dynamic linker
  44. /// and act like normal objects.
  45. DefaultVisibility
  46. };
  47. inline Visibility minVisibility(Visibility L, Visibility R) {
  48. return L < R ? L : R;
  49. }
  50. class LinkageInfo {
  51. uint8_t linkage_ : 3;
  52. uint8_t visibility_ : 2;
  53. uint8_t explicit_ : 1;
  54. void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; }
  55. public:
  56. LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility),
  57. explicit_(false) {}
  58. LinkageInfo(Linkage L, Visibility V, bool E)
  59. : linkage_(L), visibility_(V), explicit_(E) {
  60. assert(getLinkage() == L && getVisibility() == V &&
  61. isVisibilityExplicit() == E && "Enum truncated!");
  62. }
  63. static LinkageInfo external() {
  64. return LinkageInfo();
  65. }
  66. static LinkageInfo internal() {
  67. return LinkageInfo(InternalLinkage, DefaultVisibility, false);
  68. }
  69. static LinkageInfo uniqueExternal() {
  70. return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false);
  71. }
  72. static LinkageInfo none() {
  73. return LinkageInfo(NoLinkage, DefaultVisibility, false);
  74. }
  75. static LinkageInfo visible_none() {
  76. return LinkageInfo(VisibleNoLinkage, DefaultVisibility, false);
  77. }
  78. Linkage getLinkage() const { return (Linkage)linkage_; }
  79. Visibility getVisibility() const { return (Visibility)visibility_; }
  80. bool isVisibilityExplicit() const { return explicit_; }
  81. void setLinkage(Linkage L) { linkage_ = L; }
  82. void mergeLinkage(Linkage L) {
  83. setLinkage(minLinkage(getLinkage(), L));
  84. }
  85. void mergeLinkage(LinkageInfo other) {
  86. mergeLinkage(other.getLinkage());
  87. }
  88. void mergeExternalVisibility(Linkage L) {
  89. Linkage ThisL = getLinkage();
  90. if (!isExternallyVisible(L)) {
  91. if (ThisL == VisibleNoLinkage)
  92. ThisL = NoLinkage;
  93. else if (ThisL == ExternalLinkage)
  94. ThisL = UniqueExternalLinkage;
  95. }
  96. setLinkage(ThisL);
  97. }
  98. void mergeExternalVisibility(LinkageInfo Other) {
  99. mergeExternalVisibility(Other.getLinkage());
  100. }
  101. /// Merge in the visibility 'newVis'.
  102. void mergeVisibility(Visibility newVis, bool newExplicit) {
  103. Visibility oldVis = getVisibility();
  104. // Never increase visibility.
  105. if (oldVis < newVis)
  106. return;
  107. // If the new visibility is the same as the old and the new
  108. // visibility isn't explicit, we have nothing to add.
  109. if (oldVis == newVis && !newExplicit)
  110. return;
  111. // Otherwise, we're either decreasing visibility or making our
  112. // existing visibility explicit.
  113. setVisibility(newVis, newExplicit);
  114. }
  115. void mergeVisibility(LinkageInfo other) {
  116. mergeVisibility(other.getVisibility(), other.isVisibilityExplicit());
  117. }
  118. /// Merge both linkage and visibility.
  119. void merge(LinkageInfo other) {
  120. mergeLinkage(other);
  121. mergeVisibility(other);
  122. }
  123. /// Merge linkage and conditionally merge visibility.
  124. void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) {
  125. mergeLinkage(other);
  126. if (withVis) mergeVisibility(other);
  127. }
  128. };
  129. }
  130. #endif // LLVM_CLANG_BASIC_VISIBILITY_H
  131. #ifdef __GNUC__
  132. #pragma GCC diagnostic pop
  133. #endif