Files
swift-mirror/include/swift/SIL/FormalLinkage.h
Jordan Rose 014fd87928 Treat private type declarations as "hidden" in SIL (rather than public).
Easy cut down on exported symbols. Unless a private type is referenced in
an inlineable function, there's no way to generate a reference to it
outside of the current file, except in the debugger. (That last bit is why
we can't use fully private linkage, which would keep the symbol out of the
symbol table completely.)

We should be doing this for "internal" declarations as well, but the
standard library /does/ have references to internal types in inlineable
functions, and also has tests that directly access these types.

Swift SVN r24838
2015-01-30 03:54:04 +00:00

98 lines
3.4 KiB
C++

//===--- FormalLinkage.h - Formal linkage of types and decls ----*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 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
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SIL_FORMALLINKAGE_H
#define SWIFT_SIL_FORMALLINKAGE_H
namespace swift {
class CanType;
class ProtocolConformance;
class ValueDecl;
enum class SILLinkage : unsigned char;
enum ForDefinition_t : bool;
// Bits useful in defining the below.
enum {
// Bottom bit is uniqueness.
FormalLinkage_Unique = 0x0,
FormalLinkage_NonUnique = 0x1,
// Higher bits are visibility, with greater values being more
// restrictive.
FormalLinkage_Public = 0 << 1,
FormalLinkage_Hidden = 1 << 1,
FormalLinkage_Private = 2 << 1,
};
/// Formal linkage is a property of types and declarations that
/// informs, but is not completely equivalent to, the linkage of
/// symbols corresponding to those types and declarations.
///
/// Forms a semilattice with ^ as the meet operator.
enum class FormalLinkage {
/// This entity is visible in multiple Swift modules and has a
/// unique file that is known to define it.
PublicUnique = FormalLinkage_Public | FormalLinkage_Unique,
/// This entity is visible in multiple Swift modules, but does not
/// have a unique file that is known to define it.
PublicNonUnique = FormalLinkage_Public | FormalLinkage_NonUnique,
/// This entity is visible in only a single Swift module and has a
/// unique file that is known to define it.
HiddenUnique = FormalLinkage_Hidden | FormalLinkage_Unique,
/// This entity is visible in only a single Swift module but does not
/// have a unique file that is known to define it.
HiddenNonUnique = FormalLinkage_Hidden | FormalLinkage_NonUnique,
/// This entity is visible in only a single Swift file.
//
// In reality, these are by definition unique, but we use the
// non-unique flag to make merging more efficient.
Private = FormalLinkage_Private | FormalLinkage_NonUnique,
/// The top of the semilattice: (a ^ Top) == a.
Top = PublicUnique,
/// The bottom of the semilattice: (a ^ Bottom) == Bottom.
Bottom = Private,
};
/// Merge two linkages to get the more restrictive.
inline FormalLinkage operator^(FormalLinkage lhs, FormalLinkage rhs) {
// Semantically, we want the more restrictive visibility; if that's
// private, it's unique, and otherwise it's non-unique if either is
// non-unique. This is more efficient if we define away the
// special case for private by representing Private as non-unique.
if (lhs < rhs) {
return FormalLinkage(unsigned(rhs) |
(unsigned(lhs) & FormalLinkage_NonUnique));
} else {
return FormalLinkage(unsigned(lhs) |
(unsigned(rhs) & FormalLinkage_NonUnique));
}
}
inline FormalLinkage &operator^=(FormalLinkage &lhs, FormalLinkage rhs) {
return (lhs = lhs ^ rhs);
}
FormalLinkage getTypeLinkage(CanType type);
FormalLinkage getDeclLinkage(const ValueDecl *decl);
SILLinkage getSILLinkage(FormalLinkage linkage,
ForDefinition_t forDefinition);
} // end swift namespace
#endif