mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Compute accessibility for all ValueDecls, and serialize it properly.
No validation is done yet on whether the user-specified access control makes sense in context, but all ValueDecls should at least /have/ accessibility now. /Still/ no tests yet. They will be much easier to write once we're actually enforcing access control and/or printing access control. Swift SVN r19143
This commit is contained in:
@@ -1488,15 +1488,17 @@ public:
|
||||
ExtensionDeclBits.CheckedInheritanceClause = checked;
|
||||
}
|
||||
|
||||
bool hasDefaultAccessibility() const {
|
||||
return ExtensionDeclBits.DefaultAccessLevel != 0;
|
||||
}
|
||||
|
||||
Accessibility getDefaultAccessibility() const {
|
||||
assert(ExtensionDeclBits.DefaultAccessLevel != 0 &&
|
||||
"default accessibility not computed yet");
|
||||
assert(hasDefaultAccessibility() && "not computed yet");
|
||||
return static_cast<Accessibility>(ExtensionDeclBits.DefaultAccessLevel - 1);
|
||||
}
|
||||
|
||||
void setDefaultAccessibility(Accessibility access) {
|
||||
assert(ExtensionDeclBits.DefaultAccessLevel == 0 &&
|
||||
"default accessibility already set");
|
||||
assert(!hasDefaultAccessibility() && "default accessibility already set");
|
||||
ExtensionDeclBits.DefaultAccessLevel = static_cast<unsigned>(access) + 1;
|
||||
}
|
||||
|
||||
@@ -1834,13 +1836,17 @@ public:
|
||||
/// Overwrite the type of this declaration.
|
||||
void overwriteType(Type T);
|
||||
|
||||
bool hasAccessibility() const {
|
||||
return TypeAndAccess.getInt() != 0;
|
||||
}
|
||||
|
||||
Accessibility getAccessibility() const {
|
||||
assert(TypeAndAccess.getInt() != 0 && "accessibility not computed yet");
|
||||
assert(hasAccessibility() && "accessibility not computed yet");
|
||||
return static_cast<Accessibility>(TypeAndAccess.getInt() - 1);
|
||||
}
|
||||
|
||||
void setAccessibility(Accessibility access) {
|
||||
assert(TypeAndAccess.getInt() == 0 && "accessibility already set");
|
||||
assert(!hasAccessibility() && "accessibility already set");
|
||||
TypeAndAccess.setInt(static_cast<unsigned>(access) + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ const uint16_t VERSION_MAJOR = 0;
|
||||
/// Serialized module format minor version number.
|
||||
///
|
||||
/// When the format changes IN ANY WAY, this number should be incremented.
|
||||
const uint16_t VERSION_MINOR = 105;
|
||||
const uint16_t VERSION_MINOR = 106;
|
||||
|
||||
using DeclID = Fixnum<31>;
|
||||
using DeclIDField = BCFixed<31>;
|
||||
@@ -210,6 +210,15 @@ enum LibraryKind : uint8_t {
|
||||
};
|
||||
using LibraryKindField = BCFixed<1>;
|
||||
|
||||
// These IDs must \em not be renumbered or reordered without incrementing
|
||||
// VERSION_MAJOR.
|
||||
enum class AccessibilityKind : uint8_t {
|
||||
Private = 0,
|
||||
Internal,
|
||||
Public,
|
||||
};
|
||||
using AccessibilityKindField = BCFixed<2>;
|
||||
|
||||
// These IDs must \em not be renumbered or reordered without incrementing
|
||||
// VERSION_MAJOR.
|
||||
enum SpecialModuleID : uint8_t {
|
||||
@@ -583,7 +592,8 @@ namespace decls_block {
|
||||
DeclIDField, // context decl
|
||||
TypeIDField, // underlying type
|
||||
TypeIDField, // interface type
|
||||
BCFixed<1> // implicit flag
|
||||
BCFixed<1>, // implicit flag
|
||||
AccessibilityKindField // accessibility
|
||||
>;
|
||||
|
||||
using GenericTypeParamDeclLayout = BCRecordLayout<
|
||||
@@ -614,6 +624,7 @@ namespace decls_block {
|
||||
IdentifierIDField, // name
|
||||
DeclIDField, // context decl
|
||||
BCFixed<1>, // implicit flag
|
||||
AccessibilityKindField, // accessibility
|
||||
BCArray<DeclIDField> // protocols
|
||||
// Trailed by the generic parameters (if any), the decl context record, and
|
||||
// finally conformance info (if any).
|
||||
@@ -625,6 +636,7 @@ namespace decls_block {
|
||||
DeclIDField, // context decl
|
||||
BCFixed<1>, // implicit flag
|
||||
TypeIDField, // raw type
|
||||
AccessibilityKindField, // accessibility
|
||||
BCArray<DeclIDField> // protocols
|
||||
// Trailed by the generic parameters (if any), the decl context record, and
|
||||
// finally conformance info (if any).
|
||||
@@ -640,6 +652,7 @@ namespace decls_block {
|
||||
BCFixed<1>, // requires stored property initial values
|
||||
BCFixed<1>, // foreign
|
||||
TypeIDField, // superclass
|
||||
AccessibilityKindField, // accessibility
|
||||
BCArray<DeclIDField> // protocols
|
||||
// Trailed by the generic parameters (if any), the decl context record, and
|
||||
// finally conformance info (if any).
|
||||
@@ -651,6 +664,7 @@ namespace decls_block {
|
||||
DeclIDField, // context decl
|
||||
BCFixed<1>, // implicit flag
|
||||
BCFixed<1>, // objc?
|
||||
AccessibilityKindField, // accessibility
|
||||
BCArray<DeclIDField> // protocols
|
||||
// Trailed by the generic parameters (if any) and the decl context record
|
||||
>;
|
||||
@@ -665,6 +679,7 @@ namespace decls_block {
|
||||
TypeIDField, // type (signature)
|
||||
TypeIDField, // type (interface)
|
||||
DeclIDField, // overridden decl
|
||||
AccessibilityKindField, // accessibility
|
||||
BCArray<IdentifierIDField> // argument names
|
||||
// Trailed by its generic parameters, if any, followed by the parameter
|
||||
// patterns.
|
||||
@@ -686,7 +701,8 @@ namespace decls_block {
|
||||
DeclIDField, // setter
|
||||
DeclIDField, // willset
|
||||
DeclIDField, // didset
|
||||
DeclIDField // overridden decl
|
||||
DeclIDField, // overridden decl
|
||||
AccessibilityKindField // accessibility
|
||||
>;
|
||||
|
||||
using ParamLayout = BCRecordLayout<
|
||||
@@ -718,6 +734,7 @@ namespace decls_block {
|
||||
DeclIDField, // overridden function
|
||||
DeclIDField, // AccessorStorageDecl
|
||||
BCFixed<1>, // name is compound?
|
||||
AccessibilityKindField, // accessibility
|
||||
BCArray<IdentifierIDField> // name components
|
||||
// The record is trailed by:
|
||||
// - its asmname, if any
|
||||
@@ -774,6 +791,7 @@ namespace decls_block {
|
||||
DeclIDField, // getter
|
||||
DeclIDField, // setter
|
||||
DeclIDField, // overridden decl
|
||||
AccessibilityKindField, // accessibility
|
||||
BCArray<IdentifierIDField> // name components
|
||||
// The indices pattern trails the record.
|
||||
>;
|
||||
|
||||
@@ -167,6 +167,7 @@ getBuiltinFunction(Identifier Id,
|
||||
TypeLoc::withoutLoc(ResType),
|
||||
DC);
|
||||
FD->setImplicit();
|
||||
FD->setAccessibility(Accessibility::Public);
|
||||
return FD;
|
||||
}
|
||||
|
||||
@@ -240,6 +241,7 @@ getBuiltinGenericFunction(Identifier Id,
|
||||
|
||||
func->setInterfaceType(InterfaceType);
|
||||
func->setImplicit();
|
||||
func->setAccessibility(Accessibility::Public);
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
@@ -68,11 +68,14 @@ void BuiltinUnit::LookupCache::lookupValue(Identifier Name, NLKind LookupKind,
|
||||
|
||||
ValueDecl *&Entry = Cache[Name];
|
||||
ASTContext &Ctx = M.getParentModule()->Ctx;
|
||||
if (Entry == 0)
|
||||
if (Type Ty = getBuiltinType(Ctx, Name.str()))
|
||||
if (Entry == 0) {
|
||||
if (Type Ty = getBuiltinType(Ctx, Name.str())) {
|
||||
Entry = new (Ctx) TypeAliasDecl(SourceLoc(), Name, SourceLoc(),
|
||||
TypeLoc::withoutLoc(Ty),
|
||||
const_cast<BuiltinUnit*>(&M));
|
||||
Entry->setAccessibility(Accessibility::Public);
|
||||
}
|
||||
}
|
||||
|
||||
if (Entry == 0)
|
||||
Entry = getBuiltinValueDecl(Ctx, Name);
|
||||
|
||||
@@ -1376,6 +1376,16 @@ struct ASTNodeBase {};
|
||||
verifyCheckedBase(E);
|
||||
}
|
||||
|
||||
void verifyChecked(ValueDecl *VD) {
|
||||
if (!VD->hasAccessibility() && !VD->getDeclContext()->isLocalContext() &&
|
||||
!isa<GenericTypeParamDecl>(VD) && !isa<ParamDecl>(VD)) {
|
||||
dumpRef(VD);
|
||||
Out << " does not have accessibility";
|
||||
abort();
|
||||
}
|
||||
verifyCheckedBase(VD);
|
||||
}
|
||||
|
||||
void verifyChecked(PatternBindingDecl *binding) {
|
||||
}
|
||||
|
||||
|
||||
@@ -473,6 +473,7 @@ static FuncDecl *makeOptionSetFactoryMethod(
|
||||
|
||||
factoryDecl->setStatic();
|
||||
factoryDecl->setImplicit();
|
||||
factoryDecl->setAccessibility(Accessibility::Public);
|
||||
|
||||
Type factoryType = FunctionType::get(ParenType::get(C, rawType), retType);
|
||||
factoryType = FunctionType::get(selfDecl->getType(), factoryType);
|
||||
@@ -533,6 +534,7 @@ static FuncDecl *makeOptionSetToRawMethod(StructDecl *optionSetDecl,
|
||||
toRawType = FunctionType::get(optionSetType, toRawType);
|
||||
toRawDecl->setType(toRawType);
|
||||
toRawDecl->setBodyResultType(rawType);
|
||||
toRawDecl->setAccessibility(Accessibility::Public);
|
||||
|
||||
auto selfRef = new (C) DeclRefExpr(selfDecl, SourceLoc(), /*implicit*/ true);
|
||||
auto valueRef = new (C) MemberRefExpr(selfRef, SourceLoc(),
|
||||
@@ -615,6 +617,7 @@ static FuncDecl *makeOptionSetGetLogicValueMethod(StructDecl *optionSetDecl,
|
||||
toRawType);
|
||||
getLVDecl->setType(toRawType);
|
||||
getLVDecl->setBodyResultType(boolType);
|
||||
getLVDecl->setAccessibility(Accessibility::Public);
|
||||
|
||||
auto selfRef = new (C) DeclRefExpr(selfDecl, SourceLoc(), /*implicit*/ true);
|
||||
auto valueRef = new (C) MemberRefExpr(selfRef, SourceLoc(),
|
||||
@@ -671,6 +674,7 @@ static FuncDecl *makeNilLiteralConformance(StructDecl *optionSetDecl,
|
||||
|
||||
factoryDecl->setStatic();
|
||||
factoryDecl->setImplicit();
|
||||
factoryDecl->setAccessibility(Accessibility::Public);
|
||||
|
||||
Type factoryType = FunctionType::get(TupleType::getEmpty(C), optionSetType);
|
||||
factoryType = FunctionType::get(selfDecl->getType(), factoryType);
|
||||
@@ -724,6 +728,7 @@ static ConstructorDecl *makeOptionSetDefaultConstructor(StructDecl *optionSetDec
|
||||
selfPattern, methodParam,
|
||||
nullptr, optionSetDecl);
|
||||
ctorDecl->setImplicit();
|
||||
ctorDecl->setAccessibility(Accessibility::Public);
|
||||
|
||||
auto fnTy = FunctionType::get(TupleType::getEmpty(C), optionSetType);
|
||||
auto allocFnTy = FunctionType::get(metaTy, fnTy);
|
||||
@@ -786,6 +791,7 @@ static FuncDecl *makeClassToClassImplicitConversion(ClassDecl *fromDecl,
|
||||
params, TypeLoc::withoutLoc(resultType), fromDecl);
|
||||
conversionDecl->setImplicit();
|
||||
conversionDecl->getMutableAttrs().add(new (C) FinalAttr(/*implicit*/ true));
|
||||
conversionDecl->setAccessibility(Accessibility::Public);
|
||||
|
||||
auto argType = TupleType::getEmpty(C);
|
||||
Type fnType = FunctionType::get(argType, resultType);
|
||||
@@ -1220,6 +1226,7 @@ namespace {
|
||||
auto initFnTy = FunctionType::get(selfType, fnTy);
|
||||
constructor->setType(allocFnTy);
|
||||
constructor->setInitializerType(initFnTy);
|
||||
constructor->setAccessibility(Accessibility::Public);
|
||||
|
||||
// Assign all of the member variables appropriately.
|
||||
SmallVector<ASTNode, 4> stmts;
|
||||
@@ -1423,6 +1430,7 @@ namespace {
|
||||
SourceLoc(), varName,
|
||||
underlyingType,
|
||||
structDecl);
|
||||
var->setAccessibility(Accessibility::Private);
|
||||
|
||||
// Create a pattern binding to describe the variable.
|
||||
Pattern *varPattern = createTypedNamedPattern(var);
|
||||
@@ -1500,6 +1508,7 @@ namespace {
|
||||
SourceLoc(), varName,
|
||||
underlyingType,
|
||||
structDecl);
|
||||
var->setAccessibility(Accessibility::Private);
|
||||
|
||||
// Create a pattern binding to describe the variable.
|
||||
Pattern *varPattern = createTypedNamedPattern(var);
|
||||
@@ -1864,6 +1873,8 @@ namespace {
|
||||
/*GenericParams=*/nullptr, type, bodyPatterns,
|
||||
TypeLoc::withoutLoc(resultTy), dc, decl);
|
||||
|
||||
result->setAccessibility(Accessibility::Public);
|
||||
|
||||
if (decl->isNoReturn())
|
||||
result->getMutableAttrs().add(
|
||||
new (Impl.SwiftContext) NoReturnAttr(/*IsImplicit=*/false));
|
||||
@@ -2251,6 +2262,8 @@ namespace {
|
||||
SourceLoc(), name, SourceLoc(), /*GenericParams=*/nullptr, Type(),
|
||||
bodyPatterns, TypeLoc(), dc, decl);
|
||||
|
||||
result->setAccessibility(Accessibility::Public);
|
||||
|
||||
auto resultTy = type->castTo<FunctionType>()->getResult();
|
||||
Type interfaceType;
|
||||
|
||||
@@ -2827,6 +2840,7 @@ namespace {
|
||||
TypeLoc::withoutLoc(elementTy), dc);
|
||||
thunk->setBodyResultType(elementTy);
|
||||
thunk->setInterfaceType(interfaceType);
|
||||
thunk->setAccessibility(Accessibility::Public);
|
||||
|
||||
if (auto objcAttr = getter->getAttrs().getAttribute<ObjCAttr>())
|
||||
thunk->getMutableAttrs().add(objcAttr->clone(context));
|
||||
@@ -2913,6 +2927,7 @@ namespace {
|
||||
TypeLoc::withoutLoc(TupleType::getEmpty(context)), dc);
|
||||
thunk->setBodyResultType(TupleType::getEmpty(context));
|
||||
thunk->setInterfaceType(interfaceType);
|
||||
thunk->setAccessibility(Accessibility::Public);
|
||||
|
||||
if (auto objcAttr = setter->getAttrs().getAttribute<ObjCAttr>())
|
||||
thunk->getMutableAttrs().add(objcAttr->clone(context));
|
||||
@@ -3427,6 +3442,7 @@ namespace {
|
||||
// Turn this into a computed property.
|
||||
// FIXME: Fake locations for '{' and '}'?
|
||||
result->makeComputed(SourceLoc(), getter, setter, SourceLoc());
|
||||
result->setAccessibility(Accessibility::Public);
|
||||
addObjCAttribute(result, Nothing);
|
||||
|
||||
if (overridden)
|
||||
@@ -4851,6 +4867,7 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
|
||||
TypeLoc::withoutLoc(type), dc);
|
||||
func->setStatic(isStatic);
|
||||
func->setBodyResultType(type);
|
||||
func->setAccessibility(Accessibility::Public);
|
||||
|
||||
auto expr = valueExpr;
|
||||
|
||||
|
||||
@@ -939,6 +939,8 @@ public:
|
||||
auto D = ::new (DeclPtr) DeclTy(std::forward<Targs>(Args)...);
|
||||
D->setClangNode(ClangN);
|
||||
D->setEarlyAttrValidation(true);
|
||||
if (auto VD = dyn_cast<ValueDecl>(D))
|
||||
VD->setAccessibility(Accessibility::Public);
|
||||
return D;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -239,6 +239,11 @@ deriveEquatable_enum_eq(TypeChecker &tc, EnumDecl *enumDecl) {
|
||||
eqDecl->setType(fnTy);
|
||||
eqDecl->setInterfaceType(interfaceTy);
|
||||
|
||||
// Since we can't insert the == operator into the same FileUnit as the enum,
|
||||
// itself, we have to give it at least internal access.
|
||||
eqDecl->setAccessibility(std::max(enumDecl->getAccessibility(),
|
||||
Accessibility::Internal));
|
||||
|
||||
if (enumDecl->hasClangNode())
|
||||
tc.implicitlyDefinedFunctions.push_back(eqDecl);
|
||||
|
||||
@@ -430,6 +435,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, EnumDecl *enumDecl) {
|
||||
interfaceType = type;
|
||||
|
||||
getterDecl->setInterfaceType(interfaceType);
|
||||
getterDecl->setAccessibility(enumDecl->getAccessibility());
|
||||
|
||||
if (enumDecl->hasClangNode())
|
||||
tc.implicitlyDefinedFunctions.push_back(getterDecl);
|
||||
@@ -441,6 +447,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, EnumDecl *enumDecl) {
|
||||
intType, enumDecl);
|
||||
hashValueDecl->setImplicit();
|
||||
hashValueDecl->makeComputed(SourceLoc(), getterDecl, nullptr, SourceLoc());
|
||||
hashValueDecl->setAccessibility(enumDecl->getAccessibility());
|
||||
|
||||
Pattern *hashValuePat = new (C) NamedPattern(hashValueDecl, /*implicit*/true);
|
||||
hashValuePat->setType(intType);
|
||||
|
||||
@@ -88,6 +88,7 @@ static TypeDecl *deriveRawRepresentable_RawType(TypeChecker &tc,
|
||||
rawTypeDecl->setImplicit();
|
||||
rawTypeDecl->setType(rawType);
|
||||
rawTypeDecl->setInterfaceType(rawInterfaceType);
|
||||
rawTypeDecl->setAccessibility(enumDecl->getAccessibility());
|
||||
enumDecl->addMember(rawTypeDecl);
|
||||
return rawTypeDecl;
|
||||
}
|
||||
@@ -207,6 +208,7 @@ static FuncDecl *deriveRawRepresentable_toRaw(TypeChecker &tc,
|
||||
else
|
||||
interfaceType = type;
|
||||
toRawDecl->setInterfaceType(interfaceType);
|
||||
toRawDecl->setAccessibility(enumDecl->getAccessibility());
|
||||
|
||||
if (enumDecl->hasClangNode())
|
||||
tc.implicitlyDefinedFunctions.push_back(toRawDecl);
|
||||
@@ -388,6 +390,7 @@ static FuncDecl *deriveRawRepresentable_fromRaw(TypeChecker &tc,
|
||||
else
|
||||
interfaceType = type;
|
||||
fromRawDecl->setInterfaceType(interfaceType);
|
||||
fromRawDecl->setAccessibility(enumDecl->getAccessibility());
|
||||
|
||||
if (enumDecl->hasClangNode())
|
||||
tc.implicitlyDefinedFunctions.push_back(fromRawDecl);
|
||||
|
||||
@@ -2057,6 +2057,80 @@ static void configureConstructorType(ConstructorDecl *ctor,
|
||||
ctor->setInitializerType(initFnType);
|
||||
}
|
||||
|
||||
const AccessibilityAttr *findAccessibilityAttr(const DeclAttributes &attrs,
|
||||
bool forSetter = false) {
|
||||
auto explicitAttrIter = std::find_if(attrs.begin(), attrs.end(),
|
||||
[=](const DeclAttribute *attr) -> bool {
|
||||
if (auto AA = dyn_cast<AccessibilityAttr>(attr))
|
||||
return AA->isForSetter() == forSetter;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (explicitAttrIter != attrs.end())
|
||||
return cast<AccessibilityAttr>(*explicitAttrIter);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void computeDefaultAccessibility(TypeChecker &TC, ExtensionDecl *ED) {
|
||||
if (ED->hasDefaultAccessibility())
|
||||
return;
|
||||
|
||||
if (const AccessibilityAttr *AA = findAccessibilityAttr(ED->getAttrs())) {
|
||||
ED->setDefaultAccessibility(AA->getAccess());
|
||||
return;
|
||||
}
|
||||
|
||||
TC.checkInheritanceClause(ED);
|
||||
if (auto nominal = ED->getExtendedType()->getAnyNominal()) {
|
||||
TC.validateDecl(nominal);
|
||||
ED->setDefaultAccessibility(std::min(nominal->getAccessibility(),
|
||||
Accessibility::Internal));
|
||||
} else {
|
||||
// Recover by assuming "internal", which is the most common thing anyway.
|
||||
ED->setDefaultAccessibility(Accessibility::Internal);
|
||||
}
|
||||
}
|
||||
|
||||
static void computeAccessibility(TypeChecker &TC, ValueDecl *D) {
|
||||
if (D->hasAccessibility())
|
||||
return;
|
||||
|
||||
// Check if the decl has an explicit accessibility attribute.
|
||||
if (const AccessibilityAttr *AA = findAccessibilityAttr(D->getAttrs())) {
|
||||
D->setAccessibility(AA->getAccess());
|
||||
return;
|
||||
}
|
||||
|
||||
// If not, it inherits the default accessibility of its parent context.
|
||||
DeclContext *DC = D->getDeclContext();
|
||||
switch (DC->getContextKind()) {
|
||||
case DeclContextKind::AbstractClosureExpr:
|
||||
case DeclContextKind::Initializer:
|
||||
case DeclContextKind::TopLevelCodeDecl:
|
||||
case DeclContextKind::AbstractFunctionDecl:
|
||||
D->setAccessibility(Accessibility::Private);
|
||||
break;
|
||||
case DeclContextKind::Module:
|
||||
case DeclContextKind::FileUnit:
|
||||
D->setAccessibility(Accessibility::Internal);
|
||||
break;
|
||||
case DeclContextKind::NominalTypeDecl: {
|
||||
auto nominal = cast<NominalTypeDecl>(DC);
|
||||
TC.validateDecl(nominal);
|
||||
Accessibility access = nominal->getAccessibility();
|
||||
if (!isa<ProtocolDecl>(nominal))
|
||||
access = std::min(access, Accessibility::Internal);
|
||||
D->setAccessibility(access);
|
||||
break;
|
||||
}
|
||||
case DeclContextKind::ExtensionDecl: {
|
||||
auto extension = cast<ExtensionDecl>(DC);
|
||||
computeDefaultAccessibility(TC, extension);
|
||||
D->setAccessibility(extension->getDefaultAccessibility());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class DeclChecker : public DeclVisitor<DeclChecker> {
|
||||
@@ -2190,6 +2264,7 @@ public:
|
||||
|
||||
validateAttributes(TC, VD);
|
||||
TC.checkDeclAttributesEarly(VD);
|
||||
computeAccessibility(TC, VD);
|
||||
|
||||
// The instance var requires ObjC interop if it has an @objc or @iboutlet
|
||||
// attribute or if it's a member of an ObjC class or protocol.
|
||||
@@ -2424,6 +2499,7 @@ public:
|
||||
"Decl parsing must prevent subscripts outside of types!");
|
||||
|
||||
TC.checkDeclAttributesEarly(SD);
|
||||
computeAccessibility(TC, SD);
|
||||
|
||||
auto dc = SD->getDeclContext();
|
||||
bool isInvalid = TC.validateType(SD->getElementTypeLoc(), dc);
|
||||
@@ -2521,6 +2597,7 @@ public:
|
||||
TAD->setIsBeingTypeChecked();
|
||||
|
||||
TC.checkDeclAttributesEarly(TAD);
|
||||
computeAccessibility(TC, TAD);
|
||||
if (!IsSecondPass) {
|
||||
TypeResolutionOptions options;
|
||||
if (TAD->getDeclContext()->isTypeContext()) {
|
||||
@@ -2556,6 +2633,9 @@ public:
|
||||
|
||||
void visitAssociatedTypeDecl(AssociatedTypeDecl *assocType) {
|
||||
TC.checkDeclAttributesEarly(assocType);
|
||||
if (!assocType->hasAccessibility())
|
||||
assocType->setAccessibility(assocType->getProtocol()->getAccessibility());
|
||||
|
||||
// Check the default definition, if there is one.
|
||||
TypeLoc &defaultDefinition = assocType->getDefaultDefinitionLoc();
|
||||
if (!defaultDefinition.isNull() &&
|
||||
@@ -2616,6 +2696,7 @@ public:
|
||||
return;
|
||||
|
||||
TC.checkDeclAttributesEarly(ED);
|
||||
computeAccessibility(TC, ED);
|
||||
|
||||
if (!IsSecondPass) {
|
||||
TC.validateDecl(ED);
|
||||
@@ -2777,6 +2858,7 @@ public:
|
||||
return;
|
||||
|
||||
TC.checkDeclAttributesEarly(SD);
|
||||
computeAccessibility(TC, SD);
|
||||
|
||||
if (!IsSecondPass) {
|
||||
TC.validateDecl(SD);
|
||||
@@ -2947,6 +3029,7 @@ public:
|
||||
return;
|
||||
|
||||
TC.checkDeclAttributesEarly(CD);
|
||||
computeAccessibility(TC, CD);
|
||||
|
||||
if (!IsSecondPass) {
|
||||
TC.validateDecl(CD);
|
||||
@@ -3104,6 +3187,7 @@ public:
|
||||
return;
|
||||
|
||||
TC.checkDeclAttributesEarly(PD);
|
||||
computeAccessibility(TC, PD);
|
||||
|
||||
if (IsSecondPass) {
|
||||
return;
|
||||
@@ -3489,6 +3573,7 @@ public:
|
||||
}
|
||||
|
||||
TC.checkDeclAttributesEarly(FD);
|
||||
computeAccessibility(TC, FD);
|
||||
|
||||
if (IsSecondPass || FD->hasType())
|
||||
return;
|
||||
@@ -4224,6 +4309,9 @@ public:
|
||||
EnumDecl *ED = EED->getParentEnum();
|
||||
Type ElemTy = ED->getDeclaredTypeInContext();
|
||||
|
||||
if (!EED->hasAccessibility())
|
||||
EED->setAccessibility(ED->getAccessibility());
|
||||
|
||||
// Only attempt to validate the argument type or raw value if the element
|
||||
// is not currenly being validated.
|
||||
if (EED->getRecursiveness() == ElementRecursiveness::NotRecursive) {
|
||||
@@ -4377,6 +4465,7 @@ public:
|
||||
}
|
||||
|
||||
TC.checkDeclAttributesEarly(CD);
|
||||
computeAccessibility(TC, CD);
|
||||
|
||||
assert(CD->getDeclContext()->isTypeContext()
|
||||
&& "Decl parsing must prevent constructors outside of types!");
|
||||
@@ -4510,11 +4599,15 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
TC.checkDeclAttributesEarly(DD);
|
||||
|
||||
assert(DD->getDeclContext()->isTypeContext()
|
||||
&& "Decl parsing must prevent destructors outside of types!");
|
||||
|
||||
TC.checkDeclAttributesEarly(DD);
|
||||
if (!DD->hasAccessibility()) {
|
||||
auto enclosingClass = cast<ClassDecl>(DD->getParent());
|
||||
DD->setAccessibility(enclosingClass->getAccessibility());
|
||||
}
|
||||
|
||||
GenericParamList *outerGenericParams;
|
||||
Type SelfTy = configureImplicitSelf(DD, outerGenericParams);
|
||||
|
||||
@@ -4568,6 +4661,8 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
|
||||
llvm_unreachable("not a value decl");
|
||||
|
||||
case DeclKind::TypeAlias: {
|
||||
computeAccessibility(*this, D);
|
||||
|
||||
// Type aliases may not have an underlying type yet.
|
||||
auto typeAlias = cast<TypeAliasDecl>(D);
|
||||
if (typeAlias->getUnderlyingTypeLoc().getTypeRepr() &&
|
||||
@@ -4597,9 +4692,13 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
|
||||
case DeclContextKind::Initializer:
|
||||
llvm_unreachable("cannot have type params");
|
||||
|
||||
case DeclContextKind::NominalTypeDecl:
|
||||
typeCheckDecl(cast<NominalTypeDecl>(DC), true);
|
||||
case DeclContextKind::NominalTypeDecl: {
|
||||
auto nominal = cast<NominalTypeDecl>(DC);
|
||||
typeCheckDecl(nominal, true);
|
||||
if (!typeParam->hasAccessibility())
|
||||
typeParam->setAccessibility(nominal->getAccessibility());
|
||||
break;
|
||||
}
|
||||
|
||||
case DeclContextKind::ExtensionDecl:
|
||||
llvm_unreachable("not yet implemented");
|
||||
@@ -4607,14 +4706,18 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
|
||||
case DeclContextKind::AbstractClosureExpr:
|
||||
llvm_unreachable("cannot have type params");
|
||||
|
||||
case DeclContextKind::AbstractFunctionDecl:
|
||||
case DeclContextKind::AbstractFunctionDecl: {
|
||||
if (auto nominal = dyn_cast<NominalTypeDecl>(DC->getParent()))
|
||||
typeCheckDecl(nominal, true);
|
||||
else if (auto extension = dyn_cast<ExtensionDecl>(DC->getParent()))
|
||||
typeCheckDecl(extension, true);
|
||||
typeCheckDecl(cast<AbstractFunctionDecl>(DC), true);
|
||||
auto fn = cast<AbstractFunctionDecl>(DC);
|
||||
typeCheckDecl(fn, true);
|
||||
if (!typeParam->hasAccessibility())
|
||||
typeParam->setAccessibility(fn->getAccessibility());
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4647,6 +4750,7 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
|
||||
// Compute the declared type.
|
||||
nominal->computeType();
|
||||
|
||||
computeAccessibility(*this, D);
|
||||
validateAttributes(*this, D);
|
||||
checkInheritanceClause(D);
|
||||
|
||||
@@ -4686,6 +4790,7 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
|
||||
proto->getDeclContext());
|
||||
finalizeGenericParamList(builder, proto->getGenericParams(), proto, *this);
|
||||
|
||||
computeAccessibility(*this, D);
|
||||
checkInheritanceClause(D);
|
||||
validateAttributes(*this, D);
|
||||
|
||||
@@ -4728,6 +4833,7 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
|
||||
|
||||
case DeclKind::Var:
|
||||
case DeclKind::Param: {
|
||||
computeAccessibility(*this, D);
|
||||
if (D->hasType())
|
||||
return;
|
||||
|
||||
@@ -4772,17 +4878,41 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
|
||||
break;
|
||||
}
|
||||
|
||||
case DeclKind::Func:
|
||||
case DeclKind::Subscript:
|
||||
case DeclKind::Constructor:
|
||||
case DeclKind::Destructor:
|
||||
case DeclKind::EnumElement:
|
||||
case DeclKind::Func: {
|
||||
auto fn = cast<FuncDecl>(D);
|
||||
if (D->hasType())
|
||||
return;
|
||||
if (AbstractStorageDecl *storage = fn->getAccessorStorageDecl()) {
|
||||
computeAccessibility(*this, storage);
|
||||
// FIXME: Handle setter accessibility.
|
||||
fn->setAccessibility(storage->getAccessibility());
|
||||
} else {
|
||||
computeAccessibility(*this, D);
|
||||
}
|
||||
typeCheckDecl(D, true);
|
||||
break;
|
||||
}
|
||||
|
||||
case DeclKind::Subscript:
|
||||
case DeclKind::Constructor:
|
||||
if (D->hasType())
|
||||
return;
|
||||
computeAccessibility(*this, D);
|
||||
typeCheckDecl(D, true);
|
||||
break;
|
||||
|
||||
case DeclKind::Destructor:
|
||||
case DeclKind::EnumElement: {
|
||||
if (D->hasType())
|
||||
return;
|
||||
auto container = cast<NominalTypeDecl>(D->getDeclContext());
|
||||
validateDecl(container);
|
||||
D->setAccessibility(container->getAccessibility());
|
||||
typeCheckDecl(D, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(D->hasType());
|
||||
}
|
||||
|
||||
@@ -4810,6 +4940,9 @@ static ConstructorDecl *createImplicitConstructor(TypeChecker &tc,
|
||||
ImplicitConstructorKind ICK) {
|
||||
ASTContext &context = tc.Context;
|
||||
SourceLoc Loc = decl->getLoc();
|
||||
Accessibility accessLevel = std::min(decl->getAccessibility(),
|
||||
Accessibility::Internal);
|
||||
|
||||
// Determine the parameter type of the implicit constructor.
|
||||
SmallVector<TuplePatternElt, 8> patternElts;
|
||||
SmallVector<Identifier, 8> argNames;
|
||||
@@ -4819,6 +4952,7 @@ static ConstructorDecl *createImplicitConstructor(TypeChecker &tc,
|
||||
// Computed and static properties are not initialized.
|
||||
for (auto var : decl->getStoredProperties()) {
|
||||
tc.validateDecl(var);
|
||||
accessLevel = std::min(accessLevel, var->getAccessibility());
|
||||
|
||||
auto varType = tc.getTypeOfRValue(var);
|
||||
|
||||
@@ -4851,6 +4985,7 @@ static ConstructorDecl *createImplicitConstructor(TypeChecker &tc,
|
||||
|
||||
// Mark implicit.
|
||||
ctor->setImplicit();
|
||||
ctor->setAccessibility(accessLevel);
|
||||
|
||||
// Type-check the constructor declaration.
|
||||
tc.typeCheckDecl(ctor, /*isFirstPass=*/true);
|
||||
@@ -5091,6 +5226,8 @@ createDesignatedInitOverride(TypeChecker &tc,
|
||||
selfBodyPattern, bodyParamPatterns,
|
||||
nullptr, classDecl);
|
||||
ctor->setImplicit();
|
||||
ctor->setAccessibility(std::min(classDecl->getAccessibility(),
|
||||
Accessibility::Internal));
|
||||
|
||||
// Configure 'self'.
|
||||
GenericParamList *outerGenericParams = nullptr;
|
||||
|
||||
@@ -1377,6 +1377,20 @@ getActualCtorInitializerKind(uint8_t raw) {
|
||||
return Nothing;
|
||||
}
|
||||
|
||||
static Optional<swift::Accessibility>
|
||||
getActualAccessibility(uint8_t raw) {
|
||||
switch (serialization::AccessibilityKind(raw)) {
|
||||
#define CASE(NAME) \
|
||||
case serialization::AccessibilityKind::NAME: \
|
||||
return Accessibility::NAME;
|
||||
CASE(Private)
|
||||
CASE(Internal)
|
||||
CASE(Public)
|
||||
#undef CASE
|
||||
}
|
||||
return Nothing;
|
||||
}
|
||||
|
||||
Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
if (DID == 0)
|
||||
return nullptr;
|
||||
@@ -1423,12 +1437,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
if (isDeclAttrRecord(recordID)) {
|
||||
DeclAttribute *Attr = nullptr;
|
||||
switch (recordID) {
|
||||
case decls_block::Asmname_DECL_ATTR:
|
||||
case decls_block::Asmname_DECL_ATTR: {
|
||||
bool isImplicit;
|
||||
serialization::decls_block::AsmnameDeclAttrLayout::readRecord(
|
||||
scratch, isImplicit);
|
||||
Attr = new (ctx) AsmnameAttr(blobData, isImplicit);
|
||||
break;
|
||||
}
|
||||
|
||||
case decls_block::Availability_DECL_ATTR: {
|
||||
bool isImplicit;
|
||||
@@ -1503,10 +1518,11 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
DeclID contextID;
|
||||
TypeID underlyingTypeID, interfaceTypeID;
|
||||
bool isImplicit;
|
||||
uint8_t rawAccessLevel;
|
||||
|
||||
decls_block::TypeAliasLayout::readRecord(scratch, nameID, contextID,
|
||||
underlyingTypeID, interfaceTypeID,
|
||||
isImplicit);
|
||||
isImplicit, rawAccessLevel);
|
||||
|
||||
auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
|
||||
auto underlyingType = TypeLoc::withoutLoc(getType(underlyingTypeID));
|
||||
@@ -1518,6 +1534,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
SourceLoc(), underlyingType, DC);
|
||||
declOrOffset = alias;
|
||||
|
||||
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
|
||||
alias->setAccessibility(*accessLevel);
|
||||
} else {
|
||||
error();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (auto interfaceType = getType(interfaceTypeID))
|
||||
alias->setInterfaceType(interfaceType);
|
||||
|
||||
@@ -1602,6 +1625,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
defaultDefinitionID);
|
||||
declOrOffset = assocType;
|
||||
|
||||
assocType->setAccessibility(cast<ProtocolDecl>(DC)->getAccessibility());
|
||||
assocType->setSuperclass(getType(superclassID));
|
||||
assocType->setArchetype(getType(archetypeID)->castTo<ArchetypeType>());
|
||||
if (isImplicit)
|
||||
@@ -1621,10 +1645,12 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
IdentifierID nameID;
|
||||
DeclID contextID;
|
||||
bool isImplicit;
|
||||
uint8_t rawAccessLevel;
|
||||
ArrayRef<uint64_t> rawProtocolIDs;
|
||||
|
||||
decls_block::StructLayout::readRecord(scratch, nameID, contextID,
|
||||
isImplicit, rawProtocolIDs);
|
||||
isImplicit, rawAccessLevel,
|
||||
rawProtocolIDs);
|
||||
|
||||
auto DC = getDeclContext(contextID);
|
||||
if (declOrOffset.isComplete())
|
||||
@@ -1638,6 +1664,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
SourceLoc(), { }, genericParams, DC);
|
||||
declOrOffset = theStruct;
|
||||
|
||||
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
|
||||
theStruct->setAccessibility(*accessLevel);
|
||||
} else {
|
||||
error();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (isImplicit)
|
||||
theStruct->setImplicit();
|
||||
if (genericParams) {
|
||||
@@ -1675,7 +1708,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
case decls_block::CONSTRUCTOR_DECL: {
|
||||
DeclID parentID;
|
||||
bool isImplicit, isObjC, isTransparent;
|
||||
uint8_t storedInitKind;
|
||||
uint8_t storedInitKind, rawAccessLevel;
|
||||
TypeID signatureID;
|
||||
TypeID interfaceID;
|
||||
DeclID overriddenID;
|
||||
@@ -1685,7 +1718,8 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
isObjC, isTransparent,
|
||||
storedInitKind,
|
||||
signatureID, interfaceID,
|
||||
overriddenID, argNameIDs);
|
||||
overriddenID, rawAccessLevel,
|
||||
argNameIDs);
|
||||
auto parent = getDeclContext(parentID);
|
||||
if (declOrOffset.isComplete())
|
||||
return declOrOffset;
|
||||
@@ -1705,6 +1739,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
genericParams, parent);
|
||||
declOrOffset = ctor;
|
||||
|
||||
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
|
||||
ctor->setAccessibility(*accessLevel);
|
||||
} else {
|
||||
error();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Pattern *bodyParams0 = maybeReadPattern();
|
||||
Pattern *bodyParams1 = maybeReadPattern();
|
||||
assert(bodyParams0&&bodyParams1 && "missing body patterns for constructor");
|
||||
@@ -1763,16 +1804,17 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
IdentifierID nameID;
|
||||
DeclID contextID;
|
||||
bool isImplicit, isObjC, isOptional, isStatic, isLet;
|
||||
uint8_t StorageKind;
|
||||
uint8_t storageKind, rawAccessLevel;
|
||||
TypeID typeID, interfaceTypeID;
|
||||
DeclID getterID, setterID, willSetID, didSetID;
|
||||
DeclID overriddenID;
|
||||
|
||||
decls_block::VarLayout::readRecord(scratch, nameID, contextID, isImplicit,
|
||||
isObjC, isOptional, isStatic,
|
||||
isLet, StorageKind, typeID,
|
||||
isLet, storageKind, typeID,
|
||||
interfaceTypeID, getterID, setterID,
|
||||
willSetID, didSetID, overriddenID);
|
||||
willSetID, didSetID, overriddenID,
|
||||
rawAccessLevel);
|
||||
|
||||
auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
|
||||
if (declOrOffset.isComplete())
|
||||
@@ -1787,10 +1829,17 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
|
||||
declOrOffset = var;
|
||||
|
||||
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
|
||||
var->setAccessibility(*accessLevel);
|
||||
} else {
|
||||
error();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (auto interfaceType = getType(interfaceTypeID))
|
||||
var->setInterfaceType(interfaceType);
|
||||
|
||||
switch ((VarDeclStorageKind)StorageKind) {
|
||||
switch ((VarDeclStorageKind)storageKind) {
|
||||
case VarDeclStorageKind::Stored: break;
|
||||
case VarDeclStorageKind::StoredWithTrivialAccessors:
|
||||
var->makeStoredWithTrivialAccessors(
|
||||
@@ -1860,7 +1909,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
DeclID contextID;
|
||||
bool isImplicit;
|
||||
bool isStatic;
|
||||
uint8_t RawStaticSpelling;
|
||||
uint8_t rawStaticSpelling, rawAccessLevel;
|
||||
bool isAssignmentOrConversion;
|
||||
bool isObjC, isTransparent, isMutating, hasDynamicSelf;
|
||||
bool isOptional;
|
||||
@@ -1874,14 +1923,15 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
ArrayRef<uint64_t> nameIDs;
|
||||
|
||||
decls_block::FuncLayout::readRecord(scratch, contextID, isImplicit,
|
||||
isStatic, RawStaticSpelling,
|
||||
isStatic, rawStaticSpelling,
|
||||
isAssignmentOrConversion,
|
||||
isObjC, isTransparent,
|
||||
isMutating, hasDynamicSelf, isOptional,
|
||||
numParamPatterns, signatureID,
|
||||
interfaceTypeID, associatedDeclID,
|
||||
overriddenID, accessorStorageDeclID,
|
||||
hasCompoundName, nameIDs);
|
||||
hasCompoundName, rawAccessLevel,
|
||||
nameIDs);
|
||||
|
||||
// Resolve the name ids.
|
||||
SmallVector<Identifier, 2> names;
|
||||
@@ -1897,8 +1947,8 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
// DeclContext for now.
|
||||
GenericParamList *genericParams = maybeReadGenericParams(DC, DeclTypeCursor);
|
||||
|
||||
auto StaticSpelling = getActualStaticSpellingKind(RawStaticSpelling);
|
||||
if (!StaticSpelling.hasValue()) {
|
||||
auto staticSpelling = getActualStaticSpellingKind(rawStaticSpelling);
|
||||
if (!staticSpelling.hasValue()) {
|
||||
error();
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1915,10 +1965,17 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
name = DeclName(names[0]);
|
||||
}
|
||||
auto fn = FuncDecl::createDeserialized(
|
||||
ctx, SourceLoc(), StaticSpelling.getValue(), SourceLoc(), name,
|
||||
ctx, SourceLoc(), staticSpelling.getValue(), SourceLoc(), name,
|
||||
SourceLoc(), genericParams, /*type=*/nullptr, numParamPatterns, DC);
|
||||
declOrOffset = fn;
|
||||
|
||||
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
|
||||
fn->setAccessibility(*accessLevel);
|
||||
} else {
|
||||
error();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (Decl *associated = getDecl(associatedDeclID)) {
|
||||
if (auto op = dyn_cast<OperatorDecl>(associated)) {
|
||||
fn->setOperatorDecl(op);
|
||||
@@ -2015,10 +2072,11 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
IdentifierID nameID;
|
||||
DeclID contextID;
|
||||
bool isImplicit, isObjC;
|
||||
uint8_t rawAccessLevel;
|
||||
ArrayRef<uint64_t> protocolIDs;
|
||||
|
||||
decls_block::ProtocolLayout::readRecord(scratch, nameID, contextID,
|
||||
isImplicit, isObjC,
|
||||
isImplicit, isObjC, rawAccessLevel,
|
||||
protocolIDs);
|
||||
|
||||
auto DC = getDeclContext(contextID);
|
||||
@@ -2029,6 +2087,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
getIdentifier(nameID), { });
|
||||
declOrOffset = proto;
|
||||
|
||||
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
|
||||
proto->setAccessibility(*accessLevel);
|
||||
} else {
|
||||
error();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (auto genericParams = maybeReadGenericParams(DC, DeclTypeCursor)) {
|
||||
proto->setGenericParams(genericParams);
|
||||
SmallVector<GenericTypeParamType *, 4> paramTypes;
|
||||
@@ -2045,7 +2110,6 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
proto->setGenericSignature(sig);
|
||||
}
|
||||
|
||||
|
||||
if (isImplicit)
|
||||
proto->setImplicit();
|
||||
proto->computeType();
|
||||
@@ -2123,13 +2187,14 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
bool requiresStoredPropertyInits;
|
||||
bool foreign;
|
||||
TypeID superclassID;
|
||||
uint8_t rawAccessLevel;
|
||||
ArrayRef<uint64_t> rawProtocolIDs;
|
||||
decls_block::ClassLayout::readRecord(scratch, nameID, contextID,
|
||||
isImplicit, isObjC,
|
||||
attrRequiresStoredPropertyInits,
|
||||
requiresStoredPropertyInits,
|
||||
foreign,
|
||||
superclassID, rawProtocolIDs);
|
||||
foreign, superclassID, rawAccessLevel,
|
||||
rawProtocolIDs);
|
||||
|
||||
auto DC = getDeclContext(contextID);
|
||||
if (declOrOffset.isComplete())
|
||||
@@ -2143,6 +2208,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
SourceLoc(), { }, genericParams, DC);
|
||||
declOrOffset = theClass;
|
||||
|
||||
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
|
||||
theClass->setAccessibility(*accessLevel);
|
||||
} else {
|
||||
error();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
theClass->setAddedImplicitInitializers();
|
||||
if (isImplicit)
|
||||
theClass->setImplicit();
|
||||
@@ -2193,10 +2265,11 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
DeclID contextID;
|
||||
bool isImplicit;
|
||||
TypeID rawTypeID;
|
||||
uint8_t rawAccessLevel;
|
||||
ArrayRef<uint64_t> rawProtocolIDs;
|
||||
|
||||
decls_block::EnumLayout::readRecord(scratch, nameID, contextID,
|
||||
isImplicit, rawTypeID,
|
||||
isImplicit, rawTypeID, rawAccessLevel,
|
||||
rawProtocolIDs);
|
||||
|
||||
auto DC = getDeclContext(contextID);
|
||||
@@ -2212,6 +2285,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
|
||||
declOrOffset = theEnum;
|
||||
|
||||
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
|
||||
theEnum->setAccessibility(*accessLevel);
|
||||
} else {
|
||||
error();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (isImplicit)
|
||||
theEnum->setImplicit();
|
||||
theEnum->setRawType(getType(rawTypeID));
|
||||
@@ -2279,6 +2359,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
elem->setInterfaceType(interfaceType);
|
||||
if (isImplicit)
|
||||
elem->setImplicit();
|
||||
elem->setAccessibility(cast<EnumDecl>(DC)->getAccessibility());
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -2289,6 +2370,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
TypeID declTypeID, elemTypeID, interfaceTypeID;
|
||||
DeclID getterID, setterID;
|
||||
DeclID overriddenID;
|
||||
uint8_t rawAccessLevel;
|
||||
ArrayRef<uint64_t> argNameIDs;
|
||||
|
||||
decls_block::SubscriptLayout::readRecord(scratch, contextID, isImplicit,
|
||||
@@ -2296,7 +2378,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
declTypeID, elemTypeID,
|
||||
interfaceTypeID,
|
||||
getterID, setterID,
|
||||
overriddenID,
|
||||
overriddenID, rawAccessLevel,
|
||||
argNameIDs);
|
||||
auto Getter = cast_or_null<FuncDecl>(getDecl(getterID));
|
||||
auto Setter = cast_or_null<FuncDecl>(getDecl(setterID));
|
||||
@@ -2321,6 +2403,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
SourceLoc(), elemTy, DC);
|
||||
declOrOffset = subscript;
|
||||
|
||||
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
|
||||
subscript->setAccessibility(*accessLevel);
|
||||
} else {
|
||||
error();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
subscript->setAccessors(SourceRange(), Getter, Setter);
|
||||
subscript->setType(getType(declTypeID));
|
||||
if (auto interfaceType = getType(interfaceTypeID))
|
||||
@@ -2383,15 +2472,15 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
decls_block::DestructorLayout::readRecord(scratch, parentID, isImplicit,
|
||||
isObjC, signatureID);
|
||||
|
||||
DeclContext *parent = getDeclContext(parentID);
|
||||
DeclContext *DC = getDeclContext(parentID);
|
||||
if (declOrOffset.isComplete())
|
||||
return declOrOffset;
|
||||
|
||||
auto dtor = new (ctx) DestructorDecl(ctx.Id_deinit, SourceLoc(),
|
||||
/*selfpat*/nullptr, parent);
|
||||
/*selfpat*/nullptr, DC);
|
||||
declOrOffset = dtor;
|
||||
|
||||
|
||||
dtor->setAccessibility(cast<ClassDecl>(DC)->getAccessibility());
|
||||
Pattern *selfParams = maybeReadPattern();
|
||||
assert(selfParams && "Didn't get self pattern?");
|
||||
dtor->setSelfPattern(selfParams);
|
||||
|
||||
@@ -1172,6 +1172,18 @@ getStableStaticSpelling(swift::StaticSpellingKind SS) {
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t getRawStableAccessibility(Accessibility access) {
|
||||
switch (access) {
|
||||
#define CASE(NAME) \
|
||||
case Accessibility::NAME: \
|
||||
return static_cast<uint8_t>(serialization::AccessibilityKind::NAME);
|
||||
CASE(Private)
|
||||
CASE(Internal)
|
||||
CASE(Public)
|
||||
#undef CASE
|
||||
}
|
||||
}
|
||||
|
||||
/// Asserts if the declaration has any attributes other than the ones
|
||||
/// specified in the template parameters.
|
||||
///
|
||||
@@ -1465,13 +1477,17 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
if (typeAlias->hasUnderlyingType())
|
||||
underlying = typeAlias->getUnderlyingType();
|
||||
|
||||
uint8_t rawAccessLevel =
|
||||
getRawStableAccessibility(typeAlias->getAccessibility());
|
||||
|
||||
unsigned abbrCode = DeclTypeAbbrCodes[TypeAliasLayout::Code];
|
||||
TypeAliasLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
addIdentifierRef(typeAlias->getName()),
|
||||
addDeclRef(DC),
|
||||
addTypeRef(underlying),
|
||||
addTypeRef(typeAlias->getInterfaceType()),
|
||||
typeAlias->isImplicit());
|
||||
typeAlias->isImplicit(),
|
||||
rawAccessLevel);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1534,11 +1550,15 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
for (auto proto : theStruct->getProtocols())
|
||||
protocols.push_back(addDeclRef(proto));
|
||||
|
||||
uint8_t rawAccessLevel =
|
||||
getRawStableAccessibility(theStruct->getAccessibility());
|
||||
|
||||
unsigned abbrCode = DeclTypeAbbrCodes[StructLayout::Code];
|
||||
StructLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
addIdentifierRef(theStruct->getName()),
|
||||
addDeclRef(DC),
|
||||
theStruct->isImplicit(),
|
||||
rawAccessLevel,
|
||||
protocols);
|
||||
|
||||
|
||||
@@ -1561,12 +1581,16 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
for (auto proto : theEnum->getProtocols())
|
||||
protocols.push_back(addDeclRef(proto));
|
||||
|
||||
uint8_t rawAccessLevel =
|
||||
getRawStableAccessibility(theEnum->getAccessibility());
|
||||
|
||||
unsigned abbrCode = DeclTypeAbbrCodes[EnumLayout::Code];
|
||||
EnumLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
addIdentifierRef(theEnum->getName()),
|
||||
addDeclRef(DC),
|
||||
theEnum->isImplicit(),
|
||||
addTypeRef(theEnum->getRawType()),
|
||||
rawAccessLevel,
|
||||
protocols);
|
||||
|
||||
writeGenericParams(theEnum->getGenericParams(), DeclTypeAbbrCodes);
|
||||
@@ -1589,6 +1613,9 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
for (auto proto : theClass->getProtocols())
|
||||
protocols.push_back(addDeclRef(proto));
|
||||
|
||||
uint8_t rawAccessLevel =
|
||||
getRawStableAccessibility(theClass->getAccessibility());
|
||||
|
||||
unsigned abbrCode = DeclTypeAbbrCodes[ClassLayout::Code];
|
||||
ClassLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
addIdentifierRef(theClass->getName()),
|
||||
@@ -1599,6 +1626,7 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
theClass->requiresStoredPropertyInits(),
|
||||
theClass->isForeign(),
|
||||
addTypeRef(theClass->getSuperclass()),
|
||||
rawAccessLevel,
|
||||
protocols);
|
||||
|
||||
writeGenericParams(theClass->getGenericParams(), DeclTypeAbbrCodes);
|
||||
@@ -1620,12 +1648,16 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
for (auto proto : proto->getProtocols())
|
||||
protocols.push_back(addDeclRef(proto));
|
||||
|
||||
uint8_t rawAccessLevel =
|
||||
getRawStableAccessibility(proto->getAccessibility());
|
||||
|
||||
unsigned abbrCode = DeclTypeAbbrCodes[ProtocolLayout::Code];
|
||||
ProtocolLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
addIdentifierRef(proto->getName()),
|
||||
addDeclRef(DC),
|
||||
proto->isImplicit(),
|
||||
proto->isObjC(),
|
||||
rawAccessLevel,
|
||||
protocols);
|
||||
|
||||
writeGenericParams(proto->getGenericParams(), DeclTypeAbbrCodes);
|
||||
@@ -1644,26 +1676,29 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
const Decl *DC = getDeclForContext(var->getDeclContext());
|
||||
Type type = var->hasType() ? var->getType() : nullptr;
|
||||
|
||||
FuncDecl *WillSet = nullptr, *DidSet = nullptr;
|
||||
FuncDecl *willSet = nullptr, *didSet = nullptr;
|
||||
|
||||
VarDeclStorageKind StorageKind;
|
||||
VarDeclStorageKind storageKind;
|
||||
switch (var->getStorageKind()) {
|
||||
case VarDecl::Stored:
|
||||
StorageKind = VarDeclStorageKind::Stored;
|
||||
storageKind = VarDeclStorageKind::Stored;
|
||||
break;
|
||||
case VarDecl::StoredWithTrivialAccessors:
|
||||
StorageKind = VarDeclStorageKind::StoredWithTrivialAccessors;
|
||||
storageKind = VarDeclStorageKind::StoredWithTrivialAccessors;
|
||||
break;
|
||||
case VarDecl::Computed:
|
||||
StorageKind = VarDeclStorageKind::Computed;
|
||||
storageKind = VarDeclStorageKind::Computed;
|
||||
break;
|
||||
case VarDecl::Observing:
|
||||
StorageKind = VarDeclStorageKind::Observing;
|
||||
WillSet = var->getWillSetFunc();
|
||||
DidSet = var->getDidSetFunc();
|
||||
storageKind = VarDeclStorageKind::Observing;
|
||||
willSet = var->getWillSetFunc();
|
||||
didSet = var->getDidSetFunc();
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t rawAccessLevel =
|
||||
getRawStableAccessibility(var->getAccessibility());
|
||||
|
||||
unsigned abbrCode = DeclTypeAbbrCodes[VarLayout::Code];
|
||||
VarLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
addIdentifierRef(var->getName()),
|
||||
@@ -1673,14 +1708,15 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
var->getAttrs().isOptional(),
|
||||
var->isStatic(),
|
||||
var->isLet(),
|
||||
uint8_t(StorageKind),
|
||||
uint8_t(storageKind),
|
||||
addTypeRef(type),
|
||||
addTypeRef(var->getInterfaceType()),
|
||||
addDeclRef(var->getGetter()),
|
||||
addDeclRef(var->getSetter()),
|
||||
addDeclRef(WillSet),
|
||||
addDeclRef(DidSet),
|
||||
addDeclRef(var->getOverriddenDecl()));
|
||||
addDeclRef(willSet),
|
||||
addDeclRef(didSet),
|
||||
addDeclRef(var->getOverriddenDecl()),
|
||||
rawAccessLevel);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1722,6 +1758,9 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
for (auto argName : fn->getFullName().getArgumentNames())
|
||||
nameComponents.push_back(addIdentifierRef(argName));
|
||||
|
||||
uint8_t rawAccessLevel =
|
||||
getRawStableAccessibility(fn->getAccessibility());
|
||||
|
||||
FuncLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
addDeclRef(DC),
|
||||
fn->isImplicit(),
|
||||
@@ -1740,6 +1779,7 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
addDeclRef(fn->getOverriddenDecl()),
|
||||
addDeclRef(fn->getAccessorStorageDecl()),
|
||||
!fn->getFullName().isSimpleName(),
|
||||
rawAccessLevel,
|
||||
nameComponents);
|
||||
|
||||
writeGenericParams(fn->getGenericParams(), DeclTypeAbbrCodes);
|
||||
@@ -1779,6 +1819,9 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
for (auto argName : subscript->getFullName().getArgumentNames())
|
||||
nameComponents.push_back(addIdentifierRef(argName));
|
||||
|
||||
uint8_t rawAccessLevel =
|
||||
getRawStableAccessibility(subscript->getAccessibility());
|
||||
|
||||
unsigned abbrCode = DeclTypeAbbrCodes[SubscriptLayout::Code];
|
||||
SubscriptLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
addDeclRef(DC),
|
||||
@@ -1791,6 +1834,7 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
addDeclRef(subscript->getGetter()),
|
||||
addDeclRef(subscript->getSetter()),
|
||||
addDeclRef(subscript->getOverriddenDecl()),
|
||||
rawAccessLevel,
|
||||
nameComponents);
|
||||
|
||||
writePattern(subscript->getIndices());
|
||||
@@ -1809,6 +1853,9 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
for (auto argName : ctor->getFullName().getArgumentNames())
|
||||
nameComponents.push_back(addIdentifierRef(argName));
|
||||
|
||||
uint8_t rawAccessLevel =
|
||||
getRawStableAccessibility(ctor->getAccessibility());
|
||||
|
||||
unsigned abbrCode = DeclTypeAbbrCodes[ConstructorLayout::Code];
|
||||
ConstructorLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
addDeclRef(DC),
|
||||
@@ -1820,6 +1867,7 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
addTypeRef(ctor->getType()),
|
||||
addTypeRef(ctor->getInterfaceType()),
|
||||
addDeclRef(ctor->getOverriddenDecl()),
|
||||
rawAccessLevel,
|
||||
nameComponents);
|
||||
|
||||
writeGenericParams(ctor->getGenericParams(), DeclTypeAbbrCodes);
|
||||
|
||||
Reference in New Issue
Block a user