Skip to content

Commit 71e0597

Browse files
committed
---
yaml --- r: 348508 b: refs/heads/master c: f9a3c37 h: refs/heads/master
1 parent 6027b3f commit 71e0597

32 files changed

+427
-199
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 5c7a32a3335e23c36f3c6ad00a617dcb7e70fdbc
2+
refs/heads/master: f9a3c37ed6338c0df33af03f3534922c9aee48bd
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/AST/Decl.h

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -940,9 +940,31 @@ class alignas(1 << DeclAlignInBits) Decl {
940940

941941
bool isPrivateStdlibDecl(bool treatNonBuiltinProtocolsAsPublic = true) const;
942942

943-
/// Whether this declaration is weak-imported.
944-
bool isWeakImported(ModuleDecl *fromModule,
945-
AvailabilityContext fromContext) const;
943+
AvailabilityContext getAvailabilityForLinkage() const;
944+
945+
/// Whether this declaration or one of its outer contexts has the
946+
/// @_weakLinked attribute.
947+
bool isAlwaysWeakImported() const;
948+
949+
/// Whether this declaration is weak-imported from the given module,
950+
/// either because of the presence of the @_weakLinked attribute, or
951+
/// because of availability.
952+
///
953+
/// Note that \p fromModule should either be the "main module" or
954+
/// nullptr. (This is because when it is non-null, we query the
955+
/// current deployment target, and not the deployment target that
956+
/// the module was built with.)
957+
///
958+
/// If \p fromModule is the main module, this returns false when the
959+
/// declaration is part of the main module, or if the declaration is
960+
/// at least as available as the current deployment target.
961+
///
962+
/// If \p fromModule is null, we instead return true if the
963+
/// declaration is meant to be weak linked with _some_ deployment
964+
/// target; that is, the presence of the @_weakLinked attribute or
965+
/// any kind of availability is enough, irrespective of the current
966+
/// deployment target.
967+
bool isWeakImported(ModuleDecl *fromModule) const;
946968

947969
/// Returns true if the nature of this declaration allows overrides.
948970
/// Note that this does not consider whether it is final or whether

trunk/include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,8 @@ ERROR(expected_sil_function_type, none,
640640
"sil function expected to have SIL function type", ())
641641
ERROR(sil_dynamically_replaced_func_not_found,none,
642642
"dynamically replaced function not found %0", (Identifier))
643+
ERROR(sil_availability_expected_version,none,
644+
"expected version number in 'available' attribute", ())
643645

644646
// SIL Stage
645647
ERROR(expected_sil_stage_name, none,

trunk/include/swift/AST/ProtocolConformance.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,7 @@ class RootProtocolConformance : public ProtocolConformance {
343343
bool isInvalid() const;
344344

345345
/// Whether this conformance is weak-imported.
346-
bool isWeakImported(ModuleDecl *fromModule,
347-
AvailabilityContext fromContext) const;
346+
bool isWeakImported(ModuleDecl *fromModule) const;
348347

349348
bool hasWitness(ValueDecl *requirement) const;
350349
Witness getWitness(ValueDecl *requirement) const;

trunk/include/swift/IRGen/Linking.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,8 +1111,7 @@ class LinkEntity {
11111111
}
11121112

11131113
/// Determine whether this entity will be weak-imported.
1114-
bool isWeakImported(ModuleDecl *module,
1115-
AvailabilityContext fromContext) const;
1114+
bool isWeakImported(ModuleDecl *module) const;
11161115

11171116
/// Return the source file whose codegen should trigger emission of this
11181117
/// link entity, if one can be identified.
@@ -1182,7 +1181,6 @@ class LinkInfo {
11821181

11831182
static LinkInfo get(const UniversalLinkageInfo &linkInfo,
11841183
ModuleDecl *swiftModule,
1185-
AvailabilityContext availabilityContext,
11861184
const LinkEntity &entity,
11871185
ForDefinition_t forDefinition);
11881186

trunk/include/swift/SIL/SILFunction.h

Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define SWIFT_SIL_SILFUNCTION_H
1919

2020
#include "swift/AST/ASTNode.h"
21+
#include "swift/AST/Availability.h"
2122
#include "swift/AST/ResilienceExpansion.h"
2223
#include "swift/Basic/ProfileCounter.h"
2324
#include "swift/SIL/SILBasicBlock.h"
@@ -165,6 +166,27 @@ class SILFunction
165166

166167
Identifier ObjCReplacementFor;
167168

169+
/// The function's set of semantics attributes.
170+
///
171+
/// TODO: Why is this using a std::string? Why don't we use uniqued
172+
/// StringRefs?
173+
std::vector<std::string> SemanticsAttrSet;
174+
175+
/// The function's remaining set of specialize attributes.
176+
std::vector<SILSpecializeAttr*> SpecializeAttrSet;
177+
178+
/// Has value if there's a profile for this function
179+
/// Contains Function Entry Count
180+
ProfileCounter EntryCount;
181+
182+
/// The availability used to determine if declarations of this function
183+
/// should use weak linking.
184+
AvailabilityContext Availability;
185+
186+
/// This is the number of uses of this SILFunction inside the SIL.
187+
/// It does not include references from debug scopes.
188+
unsigned RefCount = 0;
189+
168190
/// The function's bare attribute. Bare means that the function is SIL-only
169191
/// and does not require debug info.
170192
unsigned Bare : 1;
@@ -199,8 +221,9 @@ class SILFunction
199221
/// would indicate.
200222
unsigned HasCReferences : 1;
201223

202-
/// Whether cross-module references to this function should use weak linking.
203-
unsigned IsWeakLinked : 1;
224+
/// Whether cross-module references to this function should always use
225+
/// weak linking.
226+
unsigned IsWeakImported : 1;
204227

205228
/// Whether the implementation can be dynamically replaced.
206229
unsigned IsDynamicReplaceable : 1;
@@ -209,33 +232,9 @@ class SILFunction
209232
/// invoked with a `self` argument of the exact base class type.
210233
unsigned ExactSelfClass : 1;
211234

212-
/// If != OptimizationMode::NotSet, the optimization mode specified with an
213-
/// function attribute.
214-
OptimizationMode OptMode;
215-
216-
/// This is the number of uses of this SILFunction inside the SIL.
217-
/// It does not include references from debug scopes.
218-
unsigned RefCount = 0;
219-
220-
/// The function's set of semantics attributes.
221-
///
222-
/// TODO: Why is this using a std::string? Why don't we use uniqued
223-
/// StringRefs?
224-
llvm::SmallVector<std::string, 1> SemanticsAttrSet;
225-
226-
/// The function's remaining set of specialize attributes.
227-
std::vector<SILSpecializeAttr*> SpecializeAttrSet;
228-
229-
/// The function's effects attribute.
230-
EffectsKind EffectsKindAttr;
231-
232-
/// Has value if there's a profile for this function
233-
/// Contains Function Entry Count
234-
ProfileCounter EntryCount;
235-
236235
/// True if this function is inlined at least once. This means that the
237236
/// debug info keeps a pointer to this function.
238-
bool Inlined = false;
237+
unsigned Inlined : 1;
239238

240239
/// True if this function is a zombie function. This means that the function
241240
/// is dead and not referenced from anywhere inside the SIL. But it is kept
@@ -244,28 +243,35 @@ class SILFunction
244243
/// *) It is a dead method of a class which has higher visibility than the
245244
/// method itself. In this case we need to create a vtable stub for it.
246245
/// *) It is a function referenced by the specialization information.
247-
bool Zombie = false;
246+
unsigned Zombie : 1;
248247

249248
/// True if this function is in Ownership SSA form and thus must pass
250249
/// ownership verification.
251250
///
252251
/// This enables the verifier to easily prove that before the Ownership Model
253252
/// Eliminator runs on a function, we only see a non-semantic-arc world and
254253
/// after the pass runs, we only see a semantic-arc world.
255-
bool HasOwnership = true;
254+
unsigned HasOwnership : 1;
256255

257256
/// Set if the function body was deserialized from canonical SIL. This implies
258257
/// that the function's home module performed SIL diagnostics prior to
259258
/// serialization.
260-
bool WasDeserializedCanonical = false;
259+
unsigned WasDeserializedCanonical : 1;
261260

262261
/// True if this is a reabstraction thunk of escaping function type whose
263262
/// single argument is a potentially non-escaping closure. This is an escape
264263
/// hatch to allow non-escaping functions to be stored or passed as an
265264
/// argument with escaping function type. The thunk argument's function type
266265
/// is not necessarily @noescape. The only relevant aspect of the argument is
267266
/// that it may have unboxed capture (i.e. @inout_aliasable parameters).
268-
bool IsWithoutActuallyEscapingThunk = false;
267+
unsigned IsWithoutActuallyEscapingThunk : 1;
268+
269+
/// If != OptimizationMode::NotSet, the optimization mode specified with an
270+
/// function attribute.
271+
unsigned OptMode : NumOptimizationModeBits;
272+
273+
/// The function's effects attribute.
274+
unsigned EffectsKindAttr : NumEffectsKindBits;
269275

270276
static void
271277
validateSubclassScope(SubclassScope scope, IsThunk_t isThunk,
@@ -591,16 +597,26 @@ class SILFunction
591597
bool hasCReferences() const { return HasCReferences; }
592598
void setHasCReferences(bool value) { HasCReferences = value; }
593599

600+
/// Returns the availability context used to determine if the function's
601+
/// symbol should be weakly referenced across module boundaries.
602+
AvailabilityContext getAvailabilityForLinkage() const {
603+
return Availability;
604+
}
605+
606+
void setAvailabilityForLinkage(AvailabilityContext availability) {
607+
Availability = availability;
608+
}
609+
594610
/// Returns whether this function's symbol must always be weakly referenced
595611
/// across module boundaries.
596-
bool isWeakLinked() const { return IsWeakLinked; }
597-
/// Forces IRGen to treat references to this function as weak across module
598-
/// boundaries (i.e. if it has external linkage).
599-
void setWeakLinked(bool value = true) {
600-
assert(!IsWeakLinked && "already set");
601-
IsWeakLinked = value;
612+
bool isAlwaysWeakImported() const { return IsWeakImported; }
613+
614+
void setAlwaysWeakImported(bool value) {
615+
IsWeakImported = value;
602616
}
603617

618+
bool isWeakImported() const;
619+
604620
/// Returns whether this function implementation can be dynamically replaced.
605621
IsDynamicallyReplaceable_t isDynamicallyReplaceable() const {
606622
return IsDynamicallyReplaceable_t(IsDynamicReplaceable);
@@ -671,13 +687,17 @@ class SILFunction
671687

672688
/// Get this function's optimization mode or OptimizationMode::NotSet if it is
673689
/// not set for this specific function.
674-
OptimizationMode getOptimizationMode() const { return OptMode; }
690+
OptimizationMode getOptimizationMode() const {
691+
return OptimizationMode(OptMode);
692+
}
675693

676694
/// Returns the optimization mode for the function. If no mode is set for the
677695
/// function, returns the global mode, i.e. the mode of the module's options.
678696
OptimizationMode getEffectiveOptimizationMode() const;
679697

680-
void setOptimizationMode(OptimizationMode mode) { OptMode = mode; }
698+
void setOptimizationMode(OptimizationMode mode) {
699+
OptMode = unsigned(mode);
700+
}
681701

682702
/// \returns True if the function is optimizable (i.e. not marked as no-opt),
683703
/// or is raw SIL (so that the mandatory passes still run).
@@ -755,16 +775,16 @@ class SILFunction
755775
void setInlineStrategy(Inline_t inStr) { InlineStrategy = inStr; }
756776

757777
/// \return the function side effects information.
758-
EffectsKind getEffectsKind() const { return EffectsKindAttr; }
778+
EffectsKind getEffectsKind() const { return EffectsKind(EffectsKindAttr); }
759779

760780
/// \return True if the function is annotated with the @_effects attribute.
761781
bool hasEffectsKind() const {
762-
return EffectsKindAttr != EffectsKind::Unspecified;
782+
return EffectsKind(EffectsKindAttr) != EffectsKind::Unspecified;
763783
}
764784

765785
/// Set the function side effect information.
766786
void setEffectsKind(EffectsKind E) {
767-
EffectsKindAttr = E;
787+
EffectsKindAttr = unsigned(E);
768788
}
769789

770790
/// Get this function's global_init attribute.

trunk/lib/AST/Decl.cpp

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -617,42 +617,66 @@ bool Decl::isPrivateStdlibDecl(bool treatNonBuiltinProtocolsAsPublic) const {
617617
return false;
618618
}
619619

620-
bool Decl::isWeakImported(ModuleDecl *fromModule,
621-
AvailabilityContext fromContext) const {
620+
AvailabilityContext Decl::getAvailabilityForLinkage() const {
621+
auto containingContext =
622+
AvailabilityInference::annotatedAvailableRange(this, getASTContext());
623+
if (containingContext.hasValue())
624+
return *containingContext;
625+
626+
if (auto *accessor = dyn_cast<AccessorDecl>(this))
627+
return accessor->getStorage()->getAvailabilityForLinkage();
628+
629+
auto *dc = getDeclContext();
630+
if (auto *ext = dyn_cast<ExtensionDecl>(dc))
631+
return ext->getAvailabilityForLinkage();
632+
else if (auto *nominal = dyn_cast<NominalTypeDecl>(dc))
633+
return nominal->getAvailabilityForLinkage();
634+
635+
return AvailabilityContext::alwaysAvailable();
636+
}
637+
638+
bool Decl::isAlwaysWeakImported() const {
622639
// For a Clang declaration, trust Clang.
623640
if (auto clangDecl = getClangDecl()) {
624641
return clangDecl->isWeakImported();
625642
}
626643

627-
auto *containingModule = getModuleContext();
628-
if (containingModule == fromModule)
629-
return false;
630-
631-
auto containingContext =
632-
AvailabilityInference::availableRange(this,
633-
containingModule->getASTContext());
634-
if (!fromContext.isContainedIn(containingContext))
635-
return true;
636-
637644
if (getAttrs().hasAttribute<WeakLinkedAttr>())
638645
return true;
639646

640647
if (auto *accessor = dyn_cast<AccessorDecl>(this))
641-
return accessor->getStorage()->isWeakImported(fromModule, fromContext);
642-
643-
if (auto *dtor = dyn_cast<DestructorDecl>(this))
644-
return cast<ClassDecl>(dtor->getDeclContext())->isWeakImported(
645-
fromModule, fromContext);
648+
return accessor->getStorage()->isAlwaysWeakImported();
646649

647650
auto *dc = getDeclContext();
648651
if (auto *ext = dyn_cast<ExtensionDecl>(dc))
649-
return ext->isWeakImported(fromModule, fromContext);
650-
if (auto *ntd = dyn_cast<NominalTypeDecl>(dc))
651-
return ntd->isWeakImported(fromModule, fromContext);
652+
return ext->isAlwaysWeakImported();
653+
if (auto *nominal = dyn_cast<NominalTypeDecl>(dc))
654+
return nominal->isAlwaysWeakImported();
652655

653656
return false;
654657
}
655658

659+
bool Decl::isWeakImported(ModuleDecl *fromModule) const {
660+
if (fromModule == nullptr) {
661+
return (isAlwaysWeakImported() ||
662+
!getAvailabilityForLinkage().isAlwaysAvailable());
663+
}
664+
665+
if (getModuleContext() == fromModule)
666+
return false;
667+
668+
if (isAlwaysWeakImported())
669+
return true;
670+
671+
auto containingContext = getAvailabilityForLinkage();
672+
if (containingContext.isAlwaysAvailable())
673+
return false;
674+
675+
auto fromContext = AvailabilityContext::forDeploymentTarget(
676+
fromModule->getASTContext());
677+
return !fromContext.isContainedIn(containingContext);
678+
}
679+
656680
GenericParamList::GenericParamList(SourceLoc LAngleLoc,
657681
ArrayRef<GenericTypeParamDecl *> Params,
658682
SourceLoc WhereLoc,

trunk/lib/AST/ProtocolConformance.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -400,25 +400,24 @@ SourceLoc RootProtocolConformance::getLoc() const {
400400
}
401401

402402
bool
403-
RootProtocolConformance::isWeakImported(ModuleDecl *fromModule,
404-
AvailabilityContext fromContext) const {
403+
RootProtocolConformance::isWeakImported(ModuleDecl *fromModule) const {
405404
auto *dc = getDeclContext();
406405
if (dc->getParentModule() == fromModule)
407406
return false;
408407

409408
// If the protocol is weak imported, so are any conformances to it.
410-
if (getProtocol()->isWeakImported(fromModule, fromContext))
409+
if (getProtocol()->isWeakImported(fromModule))
411410
return true;
412411

413412
// If the conforming type is weak imported, so are any of its conformances.
414413
if (auto *nominal = getType()->getAnyNominal())
415-
if (nominal->isWeakImported(fromModule, fromContext))
414+
if (nominal->isWeakImported(fromModule))
416415
return true;
417416

418417
// If the conformance is declared in an extension with the @_weakLinked
419418
// attribute, it is weak imported.
420419
if (auto *ext = dyn_cast<ExtensionDecl>(dc))
421-
if (ext->isWeakImported(fromModule, fromContext))
420+
if (ext->isWeakImported(fromModule))
422421
return true;
423422

424423
return false;

0 commit comments

Comments
 (0)