1 | //===- Linkage.h - Linkage enumeration and utilities ------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | /// \file |
10 | /// Defines the Linkage enumeration and various utility functions. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_CLANG_BASIC_LINKAGE_H |
15 | #define LLVM_CLANG_BASIC_LINKAGE_H |
16 | |
17 | #include "llvm/Support/ErrorHandling.h" |
18 | #include <utility> |
19 | |
20 | namespace clang { |
21 | |
22 | /// Describes the different kinds of linkage |
23 | /// (C++ [basic.link], C99 6.2.2) that an entity may have. |
24 | enum class Linkage : unsigned char { |
25 | // Linkage hasn't been computed. |
26 | Invalid = 0, |
27 | |
28 | /// No linkage, which means that the entity is unique and |
29 | /// can only be referred to from within its scope. |
30 | None, |
31 | |
32 | /// Internal linkage, which indicates that the entity can |
33 | /// be referred to from within the translation unit (but not other |
34 | /// translation units). |
35 | Internal, |
36 | |
37 | /// External linkage within a unique namespace. |
38 | /// |
39 | /// From the language perspective, these entities have external |
40 | /// linkage. However, since they reside in an anonymous namespace, |
41 | /// their names are unique to this translation unit, which is |
42 | /// equivalent to having internal linkage from the code-generation |
43 | /// point of view. |
44 | UniqueExternal, |
45 | |
46 | /// No linkage according to the standard, but is visible from other |
47 | /// translation units because of types defined in a inline function. |
48 | VisibleNone, |
49 | |
50 | /// Module linkage, which indicates that the entity can be referred |
51 | /// to from other translation units within the same module, and indirectly |
52 | /// from arbitrary other translation units through inline functions and |
53 | /// templates in the module interface. |
54 | Module, |
55 | |
56 | /// External linkage, which indicates that the entity can |
57 | /// be referred to from other translation units. |
58 | External |
59 | }; |
60 | |
61 | /// Describes the different kinds of language linkage |
62 | /// (C++ [dcl.link]) that an entity may have. |
63 | enum LanguageLinkage { |
64 | CLanguageLinkage, |
65 | CXXLanguageLinkage, |
66 | NoLanguageLinkage |
67 | }; |
68 | |
69 | /// A more specific kind of linkage than enum Linkage. |
70 | /// |
71 | /// This is relevant to CodeGen and AST file reading. |
72 | enum GVALinkage { |
73 | GVA_Internal, |
74 | GVA_AvailableExternally, |
75 | GVA_DiscardableODR, |
76 | GVA_StrongExternal, |
77 | GVA_StrongODR |
78 | }; |
79 | |
80 | inline bool isDiscardableGVALinkage(GVALinkage L) { |
81 | return L <= GVA_DiscardableODR; |
82 | } |
83 | |
84 | /// Do we know that this will be the only definition of this symbol (excluding |
85 | /// inlining-only definitions)? |
86 | inline bool isUniqueGVALinkage(GVALinkage L) { |
87 | return L == GVA_Internal || L == GVA_StrongExternal; |
88 | } |
89 | |
90 | inline bool isExternallyVisible(Linkage L) { |
91 | switch (L) { |
92 | case Linkage::Invalid: |
93 | llvm_unreachable("Linkage hasn't been computed!" ); |
94 | case Linkage::None: |
95 | case Linkage::Internal: |
96 | case Linkage::UniqueExternal: |
97 | return false; |
98 | case Linkage::VisibleNone: |
99 | case Linkage::Module: |
100 | case Linkage::External: |
101 | return true; |
102 | } |
103 | llvm_unreachable("Unhandled Linkage enum" ); |
104 | } |
105 | |
106 | inline Linkage getFormalLinkage(Linkage L) { |
107 | switch (L) { |
108 | case Linkage::UniqueExternal: |
109 | return Linkage::External; |
110 | case Linkage::VisibleNone: |
111 | return Linkage::None; |
112 | default: |
113 | return L; |
114 | } |
115 | } |
116 | |
117 | inline bool isExternalFormalLinkage(Linkage L) { |
118 | return getFormalLinkage(L) == Linkage::External; |
119 | } |
120 | |
121 | /// Compute the minimum linkage given two linkages. |
122 | /// |
123 | /// The linkage can be interpreted as a pair formed by the formal linkage and |
124 | /// a boolean for external visibility. This is just what getFormalLinkage and |
125 | /// isExternallyVisible return. We want the minimum of both components. The |
126 | /// Linkage enum is defined in an order that makes this simple, we just need |
127 | /// special cases for when VisibleNoLinkage would lose the visible bit and |
128 | /// become NoLinkage. |
129 | inline Linkage minLinkage(Linkage L1, Linkage L2) { |
130 | if (L2 == Linkage::VisibleNone) |
131 | std::swap(a&: L1, b&: L2); |
132 | if (L1 == Linkage::VisibleNone) { |
133 | if (L2 == Linkage::Internal) |
134 | return Linkage::None; |
135 | if (L2 == Linkage::UniqueExternal) |
136 | return Linkage::None; |
137 | } |
138 | return L1 < L2 ? L1 : L2; |
139 | } |
140 | |
141 | } // namespace clang |
142 | |
143 | #endif // LLVM_CLANG_BASIC_LINKAGE_H |
144 | |