1 //===- Linkage.h - Linkage enumeration and utilities ------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// Defines the Linkage enumeration and various utility functions.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_BASIC_LINKAGE_H
16 #define LLVM_CLANG_BASIC_LINKAGE_H
17 
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 Linkage : unsigned char {
25   /// No linkage, which means that the entity is unique and
26   /// can only be referred to from within its scope.
27   NoLinkage = 0,
28 
29   /// Internal linkage, which indicates that the entity can
30   /// be referred to from within the translation unit (but not other
31   /// translation units).
32   InternalLinkage,
33 
34   /// External linkage within a unique namespace.
35   ///
36   /// From the language perspective, these entities have external
37   /// linkage. However, since they reside in an anonymous namespace,
38   /// their names are unique to this translation unit, which is
39   /// equivalent to having internal linkage from the code-generation
40   /// point of view.
41   UniqueExternalLinkage,
42 
43   /// No linkage according to the standard, but is visible from other
44   /// translation units because of types defined in a inline function.
45   VisibleNoLinkage,
46 
47   /// Internal linkage according to the Modules TS, but can be referred
48   /// to from other translation units indirectly through inline functions and
49   /// templates in the module interface.
50   ModuleInternalLinkage,
51 
52   /// Module linkage, which indicates that the entity can be referred
53   /// to from other translation units within the same module, and indirectly
54   /// from arbitrary other translation units through inline functions and
55   /// templates in the module interface.
56   ModuleLinkage,
57 
58   /// External linkage, which indicates that the entity can
59   /// be referred to from other translation units.
60   ExternalLinkage
61 };
62 
63 /// Describes the different kinds of language linkage
64 /// (C++ [dcl.link]) that an entity may have.
65 enum LanguageLinkage {
66   CLanguageLinkage,
67   CXXLanguageLinkage,
68   NoLanguageLinkage
69 };
70 
71 /// A more specific kind of linkage than enum Linkage.
72 ///
73 /// This is relevant to CodeGen and AST file reading.
74 enum GVALinkage {
75   GVA_Internal,
76   GVA_AvailableExternally,
77   GVA_DiscardableODR,
78   GVA_StrongExternal,
79   GVA_StrongODR
80 };
81 
isDiscardableGVALinkage(GVALinkage L)82 inline bool isDiscardableGVALinkage(GVALinkage L) {
83   return L <= GVA_DiscardableODR;
84 }
85 
isExternallyVisible(Linkage L)86 inline bool isExternallyVisible(Linkage L) {
87   return L >= VisibleNoLinkage;
88 }
89 
getFormalLinkage(Linkage L)90 inline Linkage getFormalLinkage(Linkage L) {
91   switch (L) {
92   case UniqueExternalLinkage:
93     return ExternalLinkage;
94   case VisibleNoLinkage:
95     return NoLinkage;
96   case ModuleInternalLinkage:
97     return InternalLinkage;
98   default:
99     return L;
100   }
101 }
102 
isExternalFormalLinkage(Linkage L)103 inline bool isExternalFormalLinkage(Linkage L) {
104   return getFormalLinkage(L) == ExternalLinkage;
105 }
106 
107 /// Compute the minimum linkage given two linkages.
108 ///
109 /// The linkage can be interpreted as a pair formed by the formal linkage and
110 /// a boolean for external visibility. This is just what getFormalLinkage and
111 /// isExternallyVisible return. We want the minimum of both components. The
112 /// Linkage enum is defined in an order that makes this simple, we just need
113 /// special cases for when VisibleNoLinkage would lose the visible bit and
114 /// become NoLinkage.
minLinkage(Linkage L1,Linkage L2)115 inline Linkage minLinkage(Linkage L1, Linkage L2) {
116   if (L2 == VisibleNoLinkage)
117     std::swap(L1, L2);
118   if (L1 == VisibleNoLinkage) {
119     if (L2 == InternalLinkage)
120       return NoLinkage;
121     if (L2 == UniqueExternalLinkage)
122       return NoLinkage;
123   }
124   return L1 < L2 ? L1 : L2;
125 }
126 
127 } // namespace clang
128 
129 #endif // LLVM_CLANG_BASIC_LINKAGE_H
130