123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===--- 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
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|