aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/clang14/include/clang/Basic/Linkage.h
blob: 73616040fd6bb17f98a9092d6218b7fc3666651e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#pragma once

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

//===- Linkage.h - Linkage 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 Linkage enumeration and various utility functions.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_BASIC_LINKAGE_H
#define LLVM_CLANG_BASIC_LINKAGE_H

#include <utility>

namespace clang {

/// Describes the different kinds of linkage
/// (C++ [basic.link], C99 6.2.2) that an entity may have.
enum Linkage : unsigned char {
  /// No linkage, which means that the entity is unique and
  /// can only be referred to from within its scope.
  NoLinkage = 0,

  /// Internal linkage, which indicates that the entity can
  /// be referred to from within the translation unit (but not other
  /// translation units).
  InternalLinkage,

  /// External linkage within a unique namespace.
  ///
  /// From the language perspective, these entities have external
  /// linkage. However, since they reside in an anonymous namespace,
  /// their names are unique to this translation unit, which is
  /// equivalent to having internal linkage from the code-generation
  /// point of view.
  UniqueExternalLinkage,

  /// No linkage according to the standard, but is visible from other
  /// translation units because of types defined in a inline function.
  VisibleNoLinkage,

  /// Internal linkage according to the Modules TS, but can be referred
  /// to from other translation units indirectly through inline functions and
  /// templates in the module interface.
  ModuleInternalLinkage,

  /// Module linkage, which indicates that the entity can be referred
  /// to from other translation units within the same module, and indirectly
  /// from arbitrary other translation units through inline functions and
  /// templates in the module interface.
  ModuleLinkage,

  /// External linkage, which indicates that the entity can
  /// be referred to from other translation units.
  ExternalLinkage
};

/// Describes the different kinds of language linkage
/// (C++ [dcl.link]) that an entity may have.
enum LanguageLinkage {
  CLanguageLinkage,
  CXXLanguageLinkage,
  NoLanguageLinkage
};

/// A more specific kind of linkage than enum Linkage.
///
/// This is relevant to CodeGen and AST file reading.
enum GVALinkage {
  GVA_Internal,
  GVA_AvailableExternally,
  GVA_DiscardableODR,
  GVA_StrongExternal,
  GVA_StrongODR
};

inline bool isDiscardableGVALinkage(GVALinkage L) {
  return L <= GVA_DiscardableODR;
}

/// Do we know that this will be the only definition of this symbol (excluding
/// inlining-only definitions)?
inline bool isUniqueGVALinkage(GVALinkage L) {
  return L == GVA_Internal || L == GVA_StrongExternal;
}

inline bool isExternallyVisible(Linkage L) {
  return L >= VisibleNoLinkage;
}

inline Linkage getFormalLinkage(Linkage L) {
  switch (L) {
  case UniqueExternalLinkage:
    return ExternalLinkage;
  case VisibleNoLinkage:
    return NoLinkage;
  case ModuleInternalLinkage:
    return InternalLinkage;
  default:
    return L;
  }
}

inline bool isExternalFormalLinkage(Linkage L) {
  return getFormalLinkage(L) == ExternalLinkage;
}

/// Compute the minimum linkage given two linkages.
///
/// The linkage can be interpreted as a pair formed by the formal linkage and
/// a boolean for external visibility. This is just what getFormalLinkage and
/// isExternallyVisible return. We want the minimum of both components. The
/// Linkage enum is defined in an order that makes this simple, we just need
/// special cases for when VisibleNoLinkage would lose the visible bit and
/// become NoLinkage.
inline Linkage minLinkage(Linkage L1, Linkage L2) {
  if (L2 == VisibleNoLinkage)
    std::swap(L1, L2);
  if (L1 == VisibleNoLinkage) {
    if (L2 == InternalLinkage)
      return NoLinkage;
    if (L2 == UniqueExternalLinkage)
      return NoLinkage;
  }
  return L1 < L2 ? L1 : L2;
}

} // namespace clang

#endif // LLVM_CLANG_BASIC_LINKAGE_H

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif