forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSIL.cpp
156 lines (130 loc) · 5.25 KB
/
SIL.cpp
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
146
147
148
149
150
151
152
153
154
155
156
//===--- SIL.cpp - Implements random SIL functionality --------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "swift/SIL/FormalLinkage.h"
#include "swift/SIL/SILModule.h"
#include "swift/SIL/SILBuilder.h"
#include "swift/SIL/SILDeclRef.h"
#include "swift/SIL/SILType.h"
#include "swift/SIL/SILUndef.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/AnyFunctionRef.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
#include "swift/AST/Mangle.h"
#include "swift/AST/Pattern.h"
#include "swift/ClangImporter/ClangModule.h"
#include "swift/Basic/Fallthrough.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
using namespace swift;
void ValueBase::replaceAllUsesWith(ValueBase *RHS) {
assert(this != RHS && "Cannot RAUW a value with itself");
while (!use_empty()) {
Operand *Op = *use_begin();
Op->set(RHS);
}
}
SILUndef *SILUndef::get(SILType Ty, SILModule *M) {
// Unique these.
SILUndef *&Entry = M->UndefValues[Ty];
if (Entry == nullptr)
Entry = new (*M) SILUndef(Ty);
return Entry;
}
FormalLinkage swift::getDeclLinkage(const ValueDecl *D) {
const DeclContext *fileContext = D->getDeclContext()->getModuleScopeContext();
// Clang declarations are public and can't be assured of having a
// unique defining location.
if (isa<ClangModuleUnit>(fileContext))
return FormalLinkage::PublicNonUnique;
if (!D->hasAccessibility()) {
assert(D->getDeclContext()->isLocalContext());
return FormalLinkage::Private;
}
switch (D->getEffectiveAccess()) {
case Accessibility::Public:
return FormalLinkage::PublicUnique;
case Accessibility::Internal:
// If we're serializing all function bodies, type metadata for internal
// types needs to be public too.
if (D->getDeclContext()->getParentModule()->getResilienceStrategy()
== ResilienceStrategy::Fragile)
return FormalLinkage::PublicUnique;
return FormalLinkage::HiddenUnique;
case Accessibility::Private:
// Why "hidden" instead of "private"? Because the debugger may need to
// access these symbols.
return FormalLinkage::HiddenUnique;
}
}
FormalLinkage swift::getTypeLinkage(CanType type) {
FormalLinkage result = FormalLinkage::Top;
// Merge all nominal types from the structural type.
(void) type.findIf([&](Type _type) {
CanType type = CanType(_type);
// For any nominal type reference, look at the type declaration.
if (auto nominal = type->getAnyNominal())
result ^= getDeclLinkage(nominal);
assert(!isa<PolymorphicFunctionType>(type) &&
"Don't expect a polymorphic function type here");
return false; // continue searching
});
return result;
}
SILLinkage swift::getSILLinkage(FormalLinkage linkage,
ForDefinition_t forDefinition) {
switch (linkage) {
case FormalLinkage::PublicUnique:
return (forDefinition ? SILLinkage::Public : SILLinkage::PublicExternal);
case FormalLinkage::PublicNonUnique:
// FIXME: any place we have to do this that actually requires
// uniqueness is buggy.
return (forDefinition ? SILLinkage::Shared : SILLinkage::PublicExternal);
case FormalLinkage::HiddenUnique:
return (forDefinition ? SILLinkage::Hidden : SILLinkage::HiddenExternal);
case FormalLinkage::HiddenNonUnique:
return (forDefinition ? SILLinkage::Shared : SILLinkage::HiddenExternal);
case FormalLinkage::Private:
return SILLinkage::Private;
}
llvm_unreachable("bad formal linkage");
}
SILLinkage
swift::getLinkageForProtocolConformance(const NormalProtocolConformance *C,
ForDefinition_t definition) {
// Behavior conformances are always private.
if (C->isBehaviorConformance())
return (definition ? SILLinkage::Private : SILLinkage::PrivateExternal);
ModuleDecl *conformanceModule = C->getDeclContext()->getParentModule();
// If the conformance was synthesized by the ClangImporter, give it
// shared linkage.
auto typeDecl = C->getType()->getNominalOrBoundGenericNominal();
auto typeUnit = typeDecl->getModuleScopeContext();
if (isa<ClangModuleUnit>(typeUnit)
&& conformanceModule == typeUnit->getParentModule())
return SILLinkage::Shared;
// If we're building with -sil-serialize-all, give the conformance public
// linkage.
if (conformanceModule->getResilienceStrategy()
== ResilienceStrategy::Fragile)
return (definition ? SILLinkage::Public : SILLinkage::PublicExternal);
// FIXME: This should be using std::min(protocol's access, type's access).
switch (C->getProtocol()->getEffectiveAccess()) {
case Accessibility::Private:
return (definition ? SILLinkage::Private : SILLinkage::PrivateExternal);
case Accessibility::Internal:
return (definition ? SILLinkage::Hidden : SILLinkage::HiddenExternal);
default:
return (definition ? SILLinkage::Public : SILLinkage::PublicExternal);
}
}