summaryrefslogtreecommitdiffstats
path: root/include/clang/Basic/Linkage.h
blob: 6ec8763f24910a37c53b5721d057bebf64a74b09 (plain)
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
//===--- Linkage.h - Linkage enumeration and utilities ----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Defines the Linkage enumeration and various utility functions.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_LINKAGE_H
#define LLVM_CLANG_BASIC_LINKAGE_H

#include <assert.h>
#include <stdint.h>
#include <utility>

namespace clang {

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

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

  /// \brief 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,

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

  /// \brief 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,

  /// \brief 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,

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

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

/// \brief 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;
}

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;
}

/// \brief 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;
}

} // end namespace clang

#endif // LLVM_CLANG_BASIC_LINKAGE_H