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:
Jordan Rose
2014-06-24 21:32:13 +00:00
parent 8a38f4d441
commit 6cca3529eb
12 changed files with 425 additions and 83 deletions

View File

@@ -1488,15 +1488,17 @@ public:
ExtensionDeclBits.CheckedInheritanceClause = checked; ExtensionDeclBits.CheckedInheritanceClause = checked;
} }
bool hasDefaultAccessibility() const {
return ExtensionDeclBits.DefaultAccessLevel != 0;
}
Accessibility getDefaultAccessibility() const { Accessibility getDefaultAccessibility() const {
assert(ExtensionDeclBits.DefaultAccessLevel != 0 && assert(hasDefaultAccessibility() && "not computed yet");
"default accessibility not computed yet");
return static_cast<Accessibility>(ExtensionDeclBits.DefaultAccessLevel - 1); return static_cast<Accessibility>(ExtensionDeclBits.DefaultAccessLevel - 1);
} }
void setDefaultAccessibility(Accessibility access) { void setDefaultAccessibility(Accessibility access) {
assert(ExtensionDeclBits.DefaultAccessLevel == 0 && assert(!hasDefaultAccessibility() && "default accessibility already set");
"default accessibility already set");
ExtensionDeclBits.DefaultAccessLevel = static_cast<unsigned>(access) + 1; ExtensionDeclBits.DefaultAccessLevel = static_cast<unsigned>(access) + 1;
} }
@@ -1834,13 +1836,17 @@ public:
/// Overwrite the type of this declaration. /// Overwrite the type of this declaration.
void overwriteType(Type T); void overwriteType(Type T);
bool hasAccessibility() const {
return TypeAndAccess.getInt() != 0;
}
Accessibility getAccessibility() const { Accessibility getAccessibility() const {
assert(TypeAndAccess.getInt() != 0 && "accessibility not computed yet"); assert(hasAccessibility() && "accessibility not computed yet");
return static_cast<Accessibility>(TypeAndAccess.getInt() - 1); return static_cast<Accessibility>(TypeAndAccess.getInt() - 1);
} }
void setAccessibility(Accessibility access) { void setAccessibility(Accessibility access) {
assert(TypeAndAccess.getInt() == 0 && "accessibility already set"); assert(!hasAccessibility() && "accessibility already set");
TypeAndAccess.setInt(static_cast<unsigned>(access) + 1); TypeAndAccess.setInt(static_cast<unsigned>(access) + 1);
} }

View File

@@ -40,7 +40,7 @@ const uint16_t VERSION_MAJOR = 0;
/// Serialized module format minor version number. /// Serialized module format minor version number.
/// ///
/// When the format changes IN ANY WAY, this number should be incremented. /// 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 DeclID = Fixnum<31>;
using DeclIDField = BCFixed<31>; using DeclIDField = BCFixed<31>;
@@ -210,6 +210,15 @@ enum LibraryKind : uint8_t {
}; };
using LibraryKindField = BCFixed<1>; 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 // These IDs must \em not be renumbered or reordered without incrementing
// VERSION_MAJOR. // VERSION_MAJOR.
enum SpecialModuleID : uint8_t { enum SpecialModuleID : uint8_t {
@@ -583,7 +592,8 @@ namespace decls_block {
DeclIDField, // context decl DeclIDField, // context decl
TypeIDField, // underlying type TypeIDField, // underlying type
TypeIDField, // interface type TypeIDField, // interface type
BCFixed<1> // implicit flag BCFixed<1>, // implicit flag
AccessibilityKindField // accessibility
>; >;
using GenericTypeParamDeclLayout = BCRecordLayout< using GenericTypeParamDeclLayout = BCRecordLayout<
@@ -614,6 +624,7 @@ namespace decls_block {
IdentifierIDField, // name IdentifierIDField, // name
DeclIDField, // context decl DeclIDField, // context decl
BCFixed<1>, // implicit flag BCFixed<1>, // implicit flag
AccessibilityKindField, // accessibility
BCArray<DeclIDField> // protocols BCArray<DeclIDField> // protocols
// Trailed by the generic parameters (if any), the decl context record, and // Trailed by the generic parameters (if any), the decl context record, and
// finally conformance info (if any). // finally conformance info (if any).
@@ -625,6 +636,7 @@ namespace decls_block {
DeclIDField, // context decl DeclIDField, // context decl
BCFixed<1>, // implicit flag BCFixed<1>, // implicit flag
TypeIDField, // raw type TypeIDField, // raw type
AccessibilityKindField, // accessibility
BCArray<DeclIDField> // protocols BCArray<DeclIDField> // protocols
// Trailed by the generic parameters (if any), the decl context record, and // Trailed by the generic parameters (if any), the decl context record, and
// finally conformance info (if any). // finally conformance info (if any).
@@ -640,6 +652,7 @@ namespace decls_block {
BCFixed<1>, // requires stored property initial values BCFixed<1>, // requires stored property initial values
BCFixed<1>, // foreign BCFixed<1>, // foreign
TypeIDField, // superclass TypeIDField, // superclass
AccessibilityKindField, // accessibility
BCArray<DeclIDField> // protocols BCArray<DeclIDField> // protocols
// Trailed by the generic parameters (if any), the decl context record, and // Trailed by the generic parameters (if any), the decl context record, and
// finally conformance info (if any). // finally conformance info (if any).
@@ -651,6 +664,7 @@ namespace decls_block {
DeclIDField, // context decl DeclIDField, // context decl
BCFixed<1>, // implicit flag BCFixed<1>, // implicit flag
BCFixed<1>, // objc? BCFixed<1>, // objc?
AccessibilityKindField, // accessibility
BCArray<DeclIDField> // protocols BCArray<DeclIDField> // protocols
// Trailed by the generic parameters (if any) and the decl context record // Trailed by the generic parameters (if any) and the decl context record
>; >;
@@ -665,6 +679,7 @@ namespace decls_block {
TypeIDField, // type (signature) TypeIDField, // type (signature)
TypeIDField, // type (interface) TypeIDField, // type (interface)
DeclIDField, // overridden decl DeclIDField, // overridden decl
AccessibilityKindField, // accessibility
BCArray<IdentifierIDField> // argument names BCArray<IdentifierIDField> // argument names
// Trailed by its generic parameters, if any, followed by the parameter // Trailed by its generic parameters, if any, followed by the parameter
// patterns. // patterns.
@@ -686,7 +701,8 @@ namespace decls_block {
DeclIDField, // setter DeclIDField, // setter
DeclIDField, // willset DeclIDField, // willset
DeclIDField, // didset DeclIDField, // didset
DeclIDField // overridden decl DeclIDField, // overridden decl
AccessibilityKindField // accessibility
>; >;
using ParamLayout = BCRecordLayout< using ParamLayout = BCRecordLayout<
@@ -718,6 +734,7 @@ namespace decls_block {
DeclIDField, // overridden function DeclIDField, // overridden function
DeclIDField, // AccessorStorageDecl DeclIDField, // AccessorStorageDecl
BCFixed<1>, // name is compound? BCFixed<1>, // name is compound?
AccessibilityKindField, // accessibility
BCArray<IdentifierIDField> // name components BCArray<IdentifierIDField> // name components
// The record is trailed by: // The record is trailed by:
// - its asmname, if any // - its asmname, if any
@@ -774,6 +791,7 @@ namespace decls_block {
DeclIDField, // getter DeclIDField, // getter
DeclIDField, // setter DeclIDField, // setter
DeclIDField, // overridden decl DeclIDField, // overridden decl
AccessibilityKindField, // accessibility
BCArray<IdentifierIDField> // name components BCArray<IdentifierIDField> // name components
// The indices pattern trails the record. // The indices pattern trails the record.
>; >;

View File

@@ -167,6 +167,7 @@ getBuiltinFunction(Identifier Id,
TypeLoc::withoutLoc(ResType), TypeLoc::withoutLoc(ResType),
DC); DC);
FD->setImplicit(); FD->setImplicit();
FD->setAccessibility(Accessibility::Public);
return FD; return FD;
} }
@@ -240,6 +241,7 @@ getBuiltinGenericFunction(Identifier Id,
func->setInterfaceType(InterfaceType); func->setInterfaceType(InterfaceType);
func->setImplicit(); func->setImplicit();
func->setAccessibility(Accessibility::Public);
return func; return func;
} }

View File

@@ -68,11 +68,14 @@ void BuiltinUnit::LookupCache::lookupValue(Identifier Name, NLKind LookupKind,
ValueDecl *&Entry = Cache[Name]; ValueDecl *&Entry = Cache[Name];
ASTContext &Ctx = M.getParentModule()->Ctx; ASTContext &Ctx = M.getParentModule()->Ctx;
if (Entry == 0) if (Entry == 0) {
if (Type Ty = getBuiltinType(Ctx, Name.str())) if (Type Ty = getBuiltinType(Ctx, Name.str())) {
Entry = new (Ctx) TypeAliasDecl(SourceLoc(), Name, SourceLoc(), Entry = new (Ctx) TypeAliasDecl(SourceLoc(), Name, SourceLoc(),
TypeLoc::withoutLoc(Ty), TypeLoc::withoutLoc(Ty),
const_cast<BuiltinUnit*>(&M)); const_cast<BuiltinUnit*>(&M));
Entry->setAccessibility(Accessibility::Public);
}
}
if (Entry == 0) if (Entry == 0)
Entry = getBuiltinValueDecl(Ctx, Name); Entry = getBuiltinValueDecl(Ctx, Name);

View File

@@ -1376,6 +1376,16 @@ struct ASTNodeBase {};
verifyCheckedBase(E); 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) { void verifyChecked(PatternBindingDecl *binding) {
} }

View File

@@ -473,6 +473,7 @@ static FuncDecl *makeOptionSetFactoryMethod(
factoryDecl->setStatic(); factoryDecl->setStatic();
factoryDecl->setImplicit(); factoryDecl->setImplicit();
factoryDecl->setAccessibility(Accessibility::Public);
Type factoryType = FunctionType::get(ParenType::get(C, rawType), retType); Type factoryType = FunctionType::get(ParenType::get(C, rawType), retType);
factoryType = FunctionType::get(selfDecl->getType(), factoryType); factoryType = FunctionType::get(selfDecl->getType(), factoryType);
@@ -533,6 +534,7 @@ static FuncDecl *makeOptionSetToRawMethod(StructDecl *optionSetDecl,
toRawType = FunctionType::get(optionSetType, toRawType); toRawType = FunctionType::get(optionSetType, toRawType);
toRawDecl->setType(toRawType); toRawDecl->setType(toRawType);
toRawDecl->setBodyResultType(rawType); toRawDecl->setBodyResultType(rawType);
toRawDecl->setAccessibility(Accessibility::Public);
auto selfRef = new (C) DeclRefExpr(selfDecl, SourceLoc(), /*implicit*/ true); auto selfRef = new (C) DeclRefExpr(selfDecl, SourceLoc(), /*implicit*/ true);
auto valueRef = new (C) MemberRefExpr(selfRef, SourceLoc(), auto valueRef = new (C) MemberRefExpr(selfRef, SourceLoc(),
@@ -615,6 +617,7 @@ static FuncDecl *makeOptionSetGetLogicValueMethod(StructDecl *optionSetDecl,
toRawType); toRawType);
getLVDecl->setType(toRawType); getLVDecl->setType(toRawType);
getLVDecl->setBodyResultType(boolType); getLVDecl->setBodyResultType(boolType);
getLVDecl->setAccessibility(Accessibility::Public);
auto selfRef = new (C) DeclRefExpr(selfDecl, SourceLoc(), /*implicit*/ true); auto selfRef = new (C) DeclRefExpr(selfDecl, SourceLoc(), /*implicit*/ true);
auto valueRef = new (C) MemberRefExpr(selfRef, SourceLoc(), auto valueRef = new (C) MemberRefExpr(selfRef, SourceLoc(),
@@ -671,6 +674,7 @@ static FuncDecl *makeNilLiteralConformance(StructDecl *optionSetDecl,
factoryDecl->setStatic(); factoryDecl->setStatic();
factoryDecl->setImplicit(); factoryDecl->setImplicit();
factoryDecl->setAccessibility(Accessibility::Public);
Type factoryType = FunctionType::get(TupleType::getEmpty(C), optionSetType); Type factoryType = FunctionType::get(TupleType::getEmpty(C), optionSetType);
factoryType = FunctionType::get(selfDecl->getType(), factoryType); factoryType = FunctionType::get(selfDecl->getType(), factoryType);
@@ -724,6 +728,7 @@ static ConstructorDecl *makeOptionSetDefaultConstructor(StructDecl *optionSetDec
selfPattern, methodParam, selfPattern, methodParam,
nullptr, optionSetDecl); nullptr, optionSetDecl);
ctorDecl->setImplicit(); ctorDecl->setImplicit();
ctorDecl->setAccessibility(Accessibility::Public);
auto fnTy = FunctionType::get(TupleType::getEmpty(C), optionSetType); auto fnTy = FunctionType::get(TupleType::getEmpty(C), optionSetType);
auto allocFnTy = FunctionType::get(metaTy, fnTy); auto allocFnTy = FunctionType::get(metaTy, fnTy);
@@ -786,6 +791,7 @@ static FuncDecl *makeClassToClassImplicitConversion(ClassDecl *fromDecl,
params, TypeLoc::withoutLoc(resultType), fromDecl); params, TypeLoc::withoutLoc(resultType), fromDecl);
conversionDecl->setImplicit(); conversionDecl->setImplicit();
conversionDecl->getMutableAttrs().add(new (C) FinalAttr(/*implicit*/ true)); conversionDecl->getMutableAttrs().add(new (C) FinalAttr(/*implicit*/ true));
conversionDecl->setAccessibility(Accessibility::Public);
auto argType = TupleType::getEmpty(C); auto argType = TupleType::getEmpty(C);
Type fnType = FunctionType::get(argType, resultType); Type fnType = FunctionType::get(argType, resultType);
@@ -1220,6 +1226,7 @@ namespace {
auto initFnTy = FunctionType::get(selfType, fnTy); auto initFnTy = FunctionType::get(selfType, fnTy);
constructor->setType(allocFnTy); constructor->setType(allocFnTy);
constructor->setInitializerType(initFnTy); constructor->setInitializerType(initFnTy);
constructor->setAccessibility(Accessibility::Public);
// Assign all of the member variables appropriately. // Assign all of the member variables appropriately.
SmallVector<ASTNode, 4> stmts; SmallVector<ASTNode, 4> stmts;
@@ -1423,6 +1430,7 @@ namespace {
SourceLoc(), varName, SourceLoc(), varName,
underlyingType, underlyingType,
structDecl); structDecl);
var->setAccessibility(Accessibility::Private);
// Create a pattern binding to describe the variable. // Create a pattern binding to describe the variable.
Pattern *varPattern = createTypedNamedPattern(var); Pattern *varPattern = createTypedNamedPattern(var);
@@ -1500,6 +1508,7 @@ namespace {
SourceLoc(), varName, SourceLoc(), varName,
underlyingType, underlyingType,
structDecl); structDecl);
var->setAccessibility(Accessibility::Private);
// Create a pattern binding to describe the variable. // Create a pattern binding to describe the variable.
Pattern *varPattern = createTypedNamedPattern(var); Pattern *varPattern = createTypedNamedPattern(var);
@@ -1864,6 +1873,8 @@ namespace {
/*GenericParams=*/nullptr, type, bodyPatterns, /*GenericParams=*/nullptr, type, bodyPatterns,
TypeLoc::withoutLoc(resultTy), dc, decl); TypeLoc::withoutLoc(resultTy), dc, decl);
result->setAccessibility(Accessibility::Public);
if (decl->isNoReturn()) if (decl->isNoReturn())
result->getMutableAttrs().add( result->getMutableAttrs().add(
new (Impl.SwiftContext) NoReturnAttr(/*IsImplicit=*/false)); new (Impl.SwiftContext) NoReturnAttr(/*IsImplicit=*/false));
@@ -2251,6 +2262,8 @@ namespace {
SourceLoc(), name, SourceLoc(), /*GenericParams=*/nullptr, Type(), SourceLoc(), name, SourceLoc(), /*GenericParams=*/nullptr, Type(),
bodyPatterns, TypeLoc(), dc, decl); bodyPatterns, TypeLoc(), dc, decl);
result->setAccessibility(Accessibility::Public);
auto resultTy = type->castTo<FunctionType>()->getResult(); auto resultTy = type->castTo<FunctionType>()->getResult();
Type interfaceType; Type interfaceType;
@@ -2827,6 +2840,7 @@ namespace {
TypeLoc::withoutLoc(elementTy), dc); TypeLoc::withoutLoc(elementTy), dc);
thunk->setBodyResultType(elementTy); thunk->setBodyResultType(elementTy);
thunk->setInterfaceType(interfaceType); thunk->setInterfaceType(interfaceType);
thunk->setAccessibility(Accessibility::Public);
if (auto objcAttr = getter->getAttrs().getAttribute<ObjCAttr>()) if (auto objcAttr = getter->getAttrs().getAttribute<ObjCAttr>())
thunk->getMutableAttrs().add(objcAttr->clone(context)); thunk->getMutableAttrs().add(objcAttr->clone(context));
@@ -2913,6 +2927,7 @@ namespace {
TypeLoc::withoutLoc(TupleType::getEmpty(context)), dc); TypeLoc::withoutLoc(TupleType::getEmpty(context)), dc);
thunk->setBodyResultType(TupleType::getEmpty(context)); thunk->setBodyResultType(TupleType::getEmpty(context));
thunk->setInterfaceType(interfaceType); thunk->setInterfaceType(interfaceType);
thunk->setAccessibility(Accessibility::Public);
if (auto objcAttr = setter->getAttrs().getAttribute<ObjCAttr>()) if (auto objcAttr = setter->getAttrs().getAttribute<ObjCAttr>())
thunk->getMutableAttrs().add(objcAttr->clone(context)); thunk->getMutableAttrs().add(objcAttr->clone(context));
@@ -3427,6 +3442,7 @@ namespace {
// Turn this into a computed property. // Turn this into a computed property.
// FIXME: Fake locations for '{' and '}'? // FIXME: Fake locations for '{' and '}'?
result->makeComputed(SourceLoc(), getter, setter, SourceLoc()); result->makeComputed(SourceLoc(), getter, setter, SourceLoc());
result->setAccessibility(Accessibility::Public);
addObjCAttribute(result, Nothing); addObjCAttribute(result, Nothing);
if (overridden) if (overridden)
@@ -4851,6 +4867,7 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
TypeLoc::withoutLoc(type), dc); TypeLoc::withoutLoc(type), dc);
func->setStatic(isStatic); func->setStatic(isStatic);
func->setBodyResultType(type); func->setBodyResultType(type);
func->setAccessibility(Accessibility::Public);
auto expr = valueExpr; auto expr = valueExpr;

View File

@@ -939,6 +939,8 @@ public:
auto D = ::new (DeclPtr) DeclTy(std::forward<Targs>(Args)...); auto D = ::new (DeclPtr) DeclTy(std::forward<Targs>(Args)...);
D->setClangNode(ClangN); D->setClangNode(ClangN);
D->setEarlyAttrValidation(true); D->setEarlyAttrValidation(true);
if (auto VD = dyn_cast<ValueDecl>(D))
VD->setAccessibility(Accessibility::Public);
return D; return D;
} }
}; };

View File

@@ -239,6 +239,11 @@ deriveEquatable_enum_eq(TypeChecker &tc, EnumDecl *enumDecl) {
eqDecl->setType(fnTy); eqDecl->setType(fnTy);
eqDecl->setInterfaceType(interfaceTy); 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()) if (enumDecl->hasClangNode())
tc.implicitlyDefinedFunctions.push_back(eqDecl); tc.implicitlyDefinedFunctions.push_back(eqDecl);
@@ -430,6 +435,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, EnumDecl *enumDecl) {
interfaceType = type; interfaceType = type;
getterDecl->setInterfaceType(interfaceType); getterDecl->setInterfaceType(interfaceType);
getterDecl->setAccessibility(enumDecl->getAccessibility());
if (enumDecl->hasClangNode()) if (enumDecl->hasClangNode())
tc.implicitlyDefinedFunctions.push_back(getterDecl); tc.implicitlyDefinedFunctions.push_back(getterDecl);
@@ -441,6 +447,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, EnumDecl *enumDecl) {
intType, enumDecl); intType, enumDecl);
hashValueDecl->setImplicit(); hashValueDecl->setImplicit();
hashValueDecl->makeComputed(SourceLoc(), getterDecl, nullptr, SourceLoc()); hashValueDecl->makeComputed(SourceLoc(), getterDecl, nullptr, SourceLoc());
hashValueDecl->setAccessibility(enumDecl->getAccessibility());
Pattern *hashValuePat = new (C) NamedPattern(hashValueDecl, /*implicit*/true); Pattern *hashValuePat = new (C) NamedPattern(hashValueDecl, /*implicit*/true);
hashValuePat->setType(intType); hashValuePat->setType(intType);

View File

@@ -88,6 +88,7 @@ static TypeDecl *deriveRawRepresentable_RawType(TypeChecker &tc,
rawTypeDecl->setImplicit(); rawTypeDecl->setImplicit();
rawTypeDecl->setType(rawType); rawTypeDecl->setType(rawType);
rawTypeDecl->setInterfaceType(rawInterfaceType); rawTypeDecl->setInterfaceType(rawInterfaceType);
rawTypeDecl->setAccessibility(enumDecl->getAccessibility());
enumDecl->addMember(rawTypeDecl); enumDecl->addMember(rawTypeDecl);
return rawTypeDecl; return rawTypeDecl;
} }
@@ -207,6 +208,7 @@ static FuncDecl *deriveRawRepresentable_toRaw(TypeChecker &tc,
else else
interfaceType = type; interfaceType = type;
toRawDecl->setInterfaceType(interfaceType); toRawDecl->setInterfaceType(interfaceType);
toRawDecl->setAccessibility(enumDecl->getAccessibility());
if (enumDecl->hasClangNode()) if (enumDecl->hasClangNode())
tc.implicitlyDefinedFunctions.push_back(toRawDecl); tc.implicitlyDefinedFunctions.push_back(toRawDecl);
@@ -388,6 +390,7 @@ static FuncDecl *deriveRawRepresentable_fromRaw(TypeChecker &tc,
else else
interfaceType = type; interfaceType = type;
fromRawDecl->setInterfaceType(interfaceType); fromRawDecl->setInterfaceType(interfaceType);
fromRawDecl->setAccessibility(enumDecl->getAccessibility());
if (enumDecl->hasClangNode()) if (enumDecl->hasClangNode())
tc.implicitlyDefinedFunctions.push_back(fromRawDecl); tc.implicitlyDefinedFunctions.push_back(fromRawDecl);

View File

@@ -2057,6 +2057,80 @@ static void configureConstructorType(ConstructorDecl *ctor,
ctor->setInitializerType(initFnType); 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 { namespace {
class DeclChecker : public DeclVisitor<DeclChecker> { class DeclChecker : public DeclVisitor<DeclChecker> {
@@ -2190,6 +2264,7 @@ public:
validateAttributes(TC, VD); validateAttributes(TC, VD);
TC.checkDeclAttributesEarly(VD); TC.checkDeclAttributesEarly(VD);
computeAccessibility(TC, VD);
// The instance var requires ObjC interop if it has an @objc or @iboutlet // 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. // 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!"); "Decl parsing must prevent subscripts outside of types!");
TC.checkDeclAttributesEarly(SD); TC.checkDeclAttributesEarly(SD);
computeAccessibility(TC, SD);
auto dc = SD->getDeclContext(); auto dc = SD->getDeclContext();
bool isInvalid = TC.validateType(SD->getElementTypeLoc(), dc); bool isInvalid = TC.validateType(SD->getElementTypeLoc(), dc);
@@ -2521,6 +2597,7 @@ public:
TAD->setIsBeingTypeChecked(); TAD->setIsBeingTypeChecked();
TC.checkDeclAttributesEarly(TAD); TC.checkDeclAttributesEarly(TAD);
computeAccessibility(TC, TAD);
if (!IsSecondPass) { if (!IsSecondPass) {
TypeResolutionOptions options; TypeResolutionOptions options;
if (TAD->getDeclContext()->isTypeContext()) { if (TAD->getDeclContext()->isTypeContext()) {
@@ -2556,6 +2633,9 @@ public:
void visitAssociatedTypeDecl(AssociatedTypeDecl *assocType) { void visitAssociatedTypeDecl(AssociatedTypeDecl *assocType) {
TC.checkDeclAttributesEarly(assocType); TC.checkDeclAttributesEarly(assocType);
if (!assocType->hasAccessibility())
assocType->setAccessibility(assocType->getProtocol()->getAccessibility());
// Check the default definition, if there is one. // Check the default definition, if there is one.
TypeLoc &defaultDefinition = assocType->getDefaultDefinitionLoc(); TypeLoc &defaultDefinition = assocType->getDefaultDefinitionLoc();
if (!defaultDefinition.isNull() && if (!defaultDefinition.isNull() &&
@@ -2616,6 +2696,7 @@ public:
return; return;
TC.checkDeclAttributesEarly(ED); TC.checkDeclAttributesEarly(ED);
computeAccessibility(TC, ED);
if (!IsSecondPass) { if (!IsSecondPass) {
TC.validateDecl(ED); TC.validateDecl(ED);
@@ -2777,6 +2858,7 @@ public:
return; return;
TC.checkDeclAttributesEarly(SD); TC.checkDeclAttributesEarly(SD);
computeAccessibility(TC, SD);
if (!IsSecondPass) { if (!IsSecondPass) {
TC.validateDecl(SD); TC.validateDecl(SD);
@@ -2947,6 +3029,7 @@ public:
return; return;
TC.checkDeclAttributesEarly(CD); TC.checkDeclAttributesEarly(CD);
computeAccessibility(TC, CD);
if (!IsSecondPass) { if (!IsSecondPass) {
TC.validateDecl(CD); TC.validateDecl(CD);
@@ -3104,6 +3187,7 @@ public:
return; return;
TC.checkDeclAttributesEarly(PD); TC.checkDeclAttributesEarly(PD);
computeAccessibility(TC, PD);
if (IsSecondPass) { if (IsSecondPass) {
return; return;
@@ -3489,6 +3573,7 @@ public:
} }
TC.checkDeclAttributesEarly(FD); TC.checkDeclAttributesEarly(FD);
computeAccessibility(TC, FD);
if (IsSecondPass || FD->hasType()) if (IsSecondPass || FD->hasType())
return; return;
@@ -4224,6 +4309,9 @@ public:
EnumDecl *ED = EED->getParentEnum(); EnumDecl *ED = EED->getParentEnum();
Type ElemTy = ED->getDeclaredTypeInContext(); Type ElemTy = ED->getDeclaredTypeInContext();
if (!EED->hasAccessibility())
EED->setAccessibility(ED->getAccessibility());
// Only attempt to validate the argument type or raw value if the element // Only attempt to validate the argument type or raw value if the element
// is not currenly being validated. // is not currenly being validated.
if (EED->getRecursiveness() == ElementRecursiveness::NotRecursive) { if (EED->getRecursiveness() == ElementRecursiveness::NotRecursive) {
@@ -4377,6 +4465,7 @@ public:
} }
TC.checkDeclAttributesEarly(CD); TC.checkDeclAttributesEarly(CD);
computeAccessibility(TC, CD);
assert(CD->getDeclContext()->isTypeContext() assert(CD->getDeclContext()->isTypeContext()
&& "Decl parsing must prevent constructors outside of types!"); && "Decl parsing must prevent constructors outside of types!");
@@ -4510,11 +4599,15 @@ public:
return; return;
} }
TC.checkDeclAttributesEarly(DD);
assert(DD->getDeclContext()->isTypeContext() assert(DD->getDeclContext()->isTypeContext()
&& "Decl parsing must prevent destructors outside of types!"); && "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; GenericParamList *outerGenericParams;
Type SelfTy = configureImplicitSelf(DD, outerGenericParams); Type SelfTy = configureImplicitSelf(DD, outerGenericParams);
@@ -4568,6 +4661,8 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
llvm_unreachable("not a value decl"); llvm_unreachable("not a value decl");
case DeclKind::TypeAlias: { case DeclKind::TypeAlias: {
computeAccessibility(*this, D);
// Type aliases may not have an underlying type yet. // Type aliases may not have an underlying type yet.
auto typeAlias = cast<TypeAliasDecl>(D); auto typeAlias = cast<TypeAliasDecl>(D);
if (typeAlias->getUnderlyingTypeLoc().getTypeRepr() && if (typeAlias->getUnderlyingTypeLoc().getTypeRepr() &&
@@ -4597,9 +4692,13 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
case DeclContextKind::Initializer: case DeclContextKind::Initializer:
llvm_unreachable("cannot have type params"); llvm_unreachable("cannot have type params");
case DeclContextKind::NominalTypeDecl: case DeclContextKind::NominalTypeDecl: {
typeCheckDecl(cast<NominalTypeDecl>(DC), true); auto nominal = cast<NominalTypeDecl>(DC);
typeCheckDecl(nominal, true);
if (!typeParam->hasAccessibility())
typeParam->setAccessibility(nominal->getAccessibility());
break; break;
}
case DeclContextKind::ExtensionDecl: case DeclContextKind::ExtensionDecl:
llvm_unreachable("not yet implemented"); llvm_unreachable("not yet implemented");
@@ -4607,14 +4706,18 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
case DeclContextKind::AbstractClosureExpr: case DeclContextKind::AbstractClosureExpr:
llvm_unreachable("cannot have type params"); llvm_unreachable("cannot have type params");
case DeclContextKind::AbstractFunctionDecl: case DeclContextKind::AbstractFunctionDecl: {
if (auto nominal = dyn_cast<NominalTypeDecl>(DC->getParent())) if (auto nominal = dyn_cast<NominalTypeDecl>(DC->getParent()))
typeCheckDecl(nominal, true); typeCheckDecl(nominal, true);
else if (auto extension = dyn_cast<ExtensionDecl>(DC->getParent())) else if (auto extension = dyn_cast<ExtensionDecl>(DC->getParent()))
typeCheckDecl(extension, true); 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;
} }
}
break; break;
} }
@@ -4647,6 +4750,7 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
// Compute the declared type. // Compute the declared type.
nominal->computeType(); nominal->computeType();
computeAccessibility(*this, D);
validateAttributes(*this, D); validateAttributes(*this, D);
checkInheritanceClause(D); checkInheritanceClause(D);
@@ -4686,6 +4790,7 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
proto->getDeclContext()); proto->getDeclContext());
finalizeGenericParamList(builder, proto->getGenericParams(), proto, *this); finalizeGenericParamList(builder, proto->getGenericParams(), proto, *this);
computeAccessibility(*this, D);
checkInheritanceClause(D); checkInheritanceClause(D);
validateAttributes(*this, D); validateAttributes(*this, D);
@@ -4728,6 +4833,7 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
case DeclKind::Var: case DeclKind::Var:
case DeclKind::Param: { case DeclKind::Param: {
computeAccessibility(*this, D);
if (D->hasType()) if (D->hasType())
return; return;
@@ -4772,17 +4878,41 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
break; break;
} }
case DeclKind::Func: case DeclKind::Func: {
case DeclKind::Subscript: auto fn = cast<FuncDecl>(D);
case DeclKind::Constructor:
case DeclKind::Destructor:
case DeclKind::EnumElement:
if (D->hasType()) if (D->hasType())
return; return;
if (AbstractStorageDecl *storage = fn->getAccessorStorageDecl()) {
computeAccessibility(*this, storage);
// FIXME: Handle setter accessibility.
fn->setAccessibility(storage->getAccessibility());
} else {
computeAccessibility(*this, D);
}
typeCheckDecl(D, true); typeCheckDecl(D, true);
break; 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()); assert(D->hasType());
} }
@@ -4810,6 +4940,9 @@ static ConstructorDecl *createImplicitConstructor(TypeChecker &tc,
ImplicitConstructorKind ICK) { ImplicitConstructorKind ICK) {
ASTContext &context = tc.Context; ASTContext &context = tc.Context;
SourceLoc Loc = decl->getLoc(); SourceLoc Loc = decl->getLoc();
Accessibility accessLevel = std::min(decl->getAccessibility(),
Accessibility::Internal);
// Determine the parameter type of the implicit constructor. // Determine the parameter type of the implicit constructor.
SmallVector<TuplePatternElt, 8> patternElts; SmallVector<TuplePatternElt, 8> patternElts;
SmallVector<Identifier, 8> argNames; SmallVector<Identifier, 8> argNames;
@@ -4819,6 +4952,7 @@ static ConstructorDecl *createImplicitConstructor(TypeChecker &tc,
// Computed and static properties are not initialized. // Computed and static properties are not initialized.
for (auto var : decl->getStoredProperties()) { for (auto var : decl->getStoredProperties()) {
tc.validateDecl(var); tc.validateDecl(var);
accessLevel = std::min(accessLevel, var->getAccessibility());
auto varType = tc.getTypeOfRValue(var); auto varType = tc.getTypeOfRValue(var);
@@ -4851,6 +4985,7 @@ static ConstructorDecl *createImplicitConstructor(TypeChecker &tc,
// Mark implicit. // Mark implicit.
ctor->setImplicit(); ctor->setImplicit();
ctor->setAccessibility(accessLevel);
// Type-check the constructor declaration. // Type-check the constructor declaration.
tc.typeCheckDecl(ctor, /*isFirstPass=*/true); tc.typeCheckDecl(ctor, /*isFirstPass=*/true);
@@ -5091,6 +5226,8 @@ createDesignatedInitOverride(TypeChecker &tc,
selfBodyPattern, bodyParamPatterns, selfBodyPattern, bodyParamPatterns,
nullptr, classDecl); nullptr, classDecl);
ctor->setImplicit(); ctor->setImplicit();
ctor->setAccessibility(std::min(classDecl->getAccessibility(),
Accessibility::Internal));
// Configure 'self'. // Configure 'self'.
GenericParamList *outerGenericParams = nullptr; GenericParamList *outerGenericParams = nullptr;

View File

@@ -1377,6 +1377,20 @@ getActualCtorInitializerKind(uint8_t raw) {
return Nothing; 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) { Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
if (DID == 0) if (DID == 0)
return nullptr; return nullptr;
@@ -1423,12 +1437,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
if (isDeclAttrRecord(recordID)) { if (isDeclAttrRecord(recordID)) {
DeclAttribute *Attr = nullptr; DeclAttribute *Attr = nullptr;
switch (recordID) { switch (recordID) {
case decls_block::Asmname_DECL_ATTR: case decls_block::Asmname_DECL_ATTR: {
bool isImplicit; bool isImplicit;
serialization::decls_block::AsmnameDeclAttrLayout::readRecord( serialization::decls_block::AsmnameDeclAttrLayout::readRecord(
scratch, isImplicit); scratch, isImplicit);
Attr = new (ctx) AsmnameAttr(blobData, isImplicit); Attr = new (ctx) AsmnameAttr(blobData, isImplicit);
break; break;
}
case decls_block::Availability_DECL_ATTR: { case decls_block::Availability_DECL_ATTR: {
bool isImplicit; bool isImplicit;
@@ -1503,10 +1518,11 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
DeclID contextID; DeclID contextID;
TypeID underlyingTypeID, interfaceTypeID; TypeID underlyingTypeID, interfaceTypeID;
bool isImplicit; bool isImplicit;
uint8_t rawAccessLevel;
decls_block::TypeAliasLayout::readRecord(scratch, nameID, contextID, decls_block::TypeAliasLayout::readRecord(scratch, nameID, contextID,
underlyingTypeID, interfaceTypeID, underlyingTypeID, interfaceTypeID,
isImplicit); isImplicit, rawAccessLevel);
auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID); auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
auto underlyingType = TypeLoc::withoutLoc(getType(underlyingTypeID)); auto underlyingType = TypeLoc::withoutLoc(getType(underlyingTypeID));
@@ -1518,6 +1534,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
SourceLoc(), underlyingType, DC); SourceLoc(), underlyingType, DC);
declOrOffset = alias; declOrOffset = alias;
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
alias->setAccessibility(*accessLevel);
} else {
error();
return nullptr;
}
if (auto interfaceType = getType(interfaceTypeID)) if (auto interfaceType = getType(interfaceTypeID))
alias->setInterfaceType(interfaceType); alias->setInterfaceType(interfaceType);
@@ -1602,6 +1625,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
defaultDefinitionID); defaultDefinitionID);
declOrOffset = assocType; declOrOffset = assocType;
assocType->setAccessibility(cast<ProtocolDecl>(DC)->getAccessibility());
assocType->setSuperclass(getType(superclassID)); assocType->setSuperclass(getType(superclassID));
assocType->setArchetype(getType(archetypeID)->castTo<ArchetypeType>()); assocType->setArchetype(getType(archetypeID)->castTo<ArchetypeType>());
if (isImplicit) if (isImplicit)
@@ -1621,10 +1645,12 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
IdentifierID nameID; IdentifierID nameID;
DeclID contextID; DeclID contextID;
bool isImplicit; bool isImplicit;
uint8_t rawAccessLevel;
ArrayRef<uint64_t> rawProtocolIDs; ArrayRef<uint64_t> rawProtocolIDs;
decls_block::StructLayout::readRecord(scratch, nameID, contextID, decls_block::StructLayout::readRecord(scratch, nameID, contextID,
isImplicit, rawProtocolIDs); isImplicit, rawAccessLevel,
rawProtocolIDs);
auto DC = getDeclContext(contextID); auto DC = getDeclContext(contextID);
if (declOrOffset.isComplete()) if (declOrOffset.isComplete())
@@ -1638,6 +1664,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
SourceLoc(), { }, genericParams, DC); SourceLoc(), { }, genericParams, DC);
declOrOffset = theStruct; declOrOffset = theStruct;
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
theStruct->setAccessibility(*accessLevel);
} else {
error();
return nullptr;
}
if (isImplicit) if (isImplicit)
theStruct->setImplicit(); theStruct->setImplicit();
if (genericParams) { if (genericParams) {
@@ -1675,7 +1708,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
case decls_block::CONSTRUCTOR_DECL: { case decls_block::CONSTRUCTOR_DECL: {
DeclID parentID; DeclID parentID;
bool isImplicit, isObjC, isTransparent; bool isImplicit, isObjC, isTransparent;
uint8_t storedInitKind; uint8_t storedInitKind, rawAccessLevel;
TypeID signatureID; TypeID signatureID;
TypeID interfaceID; TypeID interfaceID;
DeclID overriddenID; DeclID overriddenID;
@@ -1685,7 +1718,8 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
isObjC, isTransparent, isObjC, isTransparent,
storedInitKind, storedInitKind,
signatureID, interfaceID, signatureID, interfaceID,
overriddenID, argNameIDs); overriddenID, rawAccessLevel,
argNameIDs);
auto parent = getDeclContext(parentID); auto parent = getDeclContext(parentID);
if (declOrOffset.isComplete()) if (declOrOffset.isComplete())
return declOrOffset; return declOrOffset;
@@ -1705,6 +1739,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
genericParams, parent); genericParams, parent);
declOrOffset = ctor; declOrOffset = ctor;
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
ctor->setAccessibility(*accessLevel);
} else {
error();
return nullptr;
}
Pattern *bodyParams0 = maybeReadPattern(); Pattern *bodyParams0 = maybeReadPattern();
Pattern *bodyParams1 = maybeReadPattern(); Pattern *bodyParams1 = maybeReadPattern();
assert(bodyParams0&&bodyParams1 && "missing body patterns for constructor"); assert(bodyParams0&&bodyParams1 && "missing body patterns for constructor");
@@ -1763,16 +1804,17 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
IdentifierID nameID; IdentifierID nameID;
DeclID contextID; DeclID contextID;
bool isImplicit, isObjC, isOptional, isStatic, isLet; bool isImplicit, isObjC, isOptional, isStatic, isLet;
uint8_t StorageKind; uint8_t storageKind, rawAccessLevel;
TypeID typeID, interfaceTypeID; TypeID typeID, interfaceTypeID;
DeclID getterID, setterID, willSetID, didSetID; DeclID getterID, setterID, willSetID, didSetID;
DeclID overriddenID; DeclID overriddenID;
decls_block::VarLayout::readRecord(scratch, nameID, contextID, isImplicit, decls_block::VarLayout::readRecord(scratch, nameID, contextID, isImplicit,
isObjC, isOptional, isStatic, isObjC, isOptional, isStatic,
isLet, StorageKind, typeID, isLet, storageKind, typeID,
interfaceTypeID, getterID, setterID, interfaceTypeID, getterID, setterID,
willSetID, didSetID, overriddenID); willSetID, didSetID, overriddenID,
rawAccessLevel);
auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID); auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
if (declOrOffset.isComplete()) if (declOrOffset.isComplete())
@@ -1787,10 +1829,17 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
declOrOffset = var; declOrOffset = var;
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
var->setAccessibility(*accessLevel);
} else {
error();
return nullptr;
}
if (auto interfaceType = getType(interfaceTypeID)) if (auto interfaceType = getType(interfaceTypeID))
var->setInterfaceType(interfaceType); var->setInterfaceType(interfaceType);
switch ((VarDeclStorageKind)StorageKind) { switch ((VarDeclStorageKind)storageKind) {
case VarDeclStorageKind::Stored: break; case VarDeclStorageKind::Stored: break;
case VarDeclStorageKind::StoredWithTrivialAccessors: case VarDeclStorageKind::StoredWithTrivialAccessors:
var->makeStoredWithTrivialAccessors( var->makeStoredWithTrivialAccessors(
@@ -1860,7 +1909,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
DeclID contextID; DeclID contextID;
bool isImplicit; bool isImplicit;
bool isStatic; bool isStatic;
uint8_t RawStaticSpelling; uint8_t rawStaticSpelling, rawAccessLevel;
bool isAssignmentOrConversion; bool isAssignmentOrConversion;
bool isObjC, isTransparent, isMutating, hasDynamicSelf; bool isObjC, isTransparent, isMutating, hasDynamicSelf;
bool isOptional; bool isOptional;
@@ -1874,14 +1923,15 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
ArrayRef<uint64_t> nameIDs; ArrayRef<uint64_t> nameIDs;
decls_block::FuncLayout::readRecord(scratch, contextID, isImplicit, decls_block::FuncLayout::readRecord(scratch, contextID, isImplicit,
isStatic, RawStaticSpelling, isStatic, rawStaticSpelling,
isAssignmentOrConversion, isAssignmentOrConversion,
isObjC, isTransparent, isObjC, isTransparent,
isMutating, hasDynamicSelf, isOptional, isMutating, hasDynamicSelf, isOptional,
numParamPatterns, signatureID, numParamPatterns, signatureID,
interfaceTypeID, associatedDeclID, interfaceTypeID, associatedDeclID,
overriddenID, accessorStorageDeclID, overriddenID, accessorStorageDeclID,
hasCompoundName, nameIDs); hasCompoundName, rawAccessLevel,
nameIDs);
// Resolve the name ids. // Resolve the name ids.
SmallVector<Identifier, 2> names; SmallVector<Identifier, 2> names;
@@ -1897,8 +1947,8 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
// DeclContext for now. // DeclContext for now.
GenericParamList *genericParams = maybeReadGenericParams(DC, DeclTypeCursor); GenericParamList *genericParams = maybeReadGenericParams(DC, DeclTypeCursor);
auto StaticSpelling = getActualStaticSpellingKind(RawStaticSpelling); auto staticSpelling = getActualStaticSpellingKind(rawStaticSpelling);
if (!StaticSpelling.hasValue()) { if (!staticSpelling.hasValue()) {
error(); error();
return nullptr; return nullptr;
} }
@@ -1915,10 +1965,17 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
name = DeclName(names[0]); name = DeclName(names[0]);
} }
auto fn = FuncDecl::createDeserialized( auto fn = FuncDecl::createDeserialized(
ctx, SourceLoc(), StaticSpelling.getValue(), SourceLoc(), name, ctx, SourceLoc(), staticSpelling.getValue(), SourceLoc(), name,
SourceLoc(), genericParams, /*type=*/nullptr, numParamPatterns, DC); SourceLoc(), genericParams, /*type=*/nullptr, numParamPatterns, DC);
declOrOffset = fn; declOrOffset = fn;
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
fn->setAccessibility(*accessLevel);
} else {
error();
return nullptr;
}
if (Decl *associated = getDecl(associatedDeclID)) { if (Decl *associated = getDecl(associatedDeclID)) {
if (auto op = dyn_cast<OperatorDecl>(associated)) { if (auto op = dyn_cast<OperatorDecl>(associated)) {
fn->setOperatorDecl(op); fn->setOperatorDecl(op);
@@ -2015,10 +2072,11 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
IdentifierID nameID; IdentifierID nameID;
DeclID contextID; DeclID contextID;
bool isImplicit, isObjC; bool isImplicit, isObjC;
uint8_t rawAccessLevel;
ArrayRef<uint64_t> protocolIDs; ArrayRef<uint64_t> protocolIDs;
decls_block::ProtocolLayout::readRecord(scratch, nameID, contextID, decls_block::ProtocolLayout::readRecord(scratch, nameID, contextID,
isImplicit, isObjC, isImplicit, isObjC, rawAccessLevel,
protocolIDs); protocolIDs);
auto DC = getDeclContext(contextID); auto DC = getDeclContext(contextID);
@@ -2029,6 +2087,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
getIdentifier(nameID), { }); getIdentifier(nameID), { });
declOrOffset = proto; declOrOffset = proto;
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
proto->setAccessibility(*accessLevel);
} else {
error();
return nullptr;
}
if (auto genericParams = maybeReadGenericParams(DC, DeclTypeCursor)) { if (auto genericParams = maybeReadGenericParams(DC, DeclTypeCursor)) {
proto->setGenericParams(genericParams); proto->setGenericParams(genericParams);
SmallVector<GenericTypeParamType *, 4> paramTypes; SmallVector<GenericTypeParamType *, 4> paramTypes;
@@ -2045,7 +2110,6 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
proto->setGenericSignature(sig); proto->setGenericSignature(sig);
} }
if (isImplicit) if (isImplicit)
proto->setImplicit(); proto->setImplicit();
proto->computeType(); proto->computeType();
@@ -2123,13 +2187,14 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
bool requiresStoredPropertyInits; bool requiresStoredPropertyInits;
bool foreign; bool foreign;
TypeID superclassID; TypeID superclassID;
uint8_t rawAccessLevel;
ArrayRef<uint64_t> rawProtocolIDs; ArrayRef<uint64_t> rawProtocolIDs;
decls_block::ClassLayout::readRecord(scratch, nameID, contextID, decls_block::ClassLayout::readRecord(scratch, nameID, contextID,
isImplicit, isObjC, isImplicit, isObjC,
attrRequiresStoredPropertyInits, attrRequiresStoredPropertyInits,
requiresStoredPropertyInits, requiresStoredPropertyInits,
foreign, foreign, superclassID, rawAccessLevel,
superclassID, rawProtocolIDs); rawProtocolIDs);
auto DC = getDeclContext(contextID); auto DC = getDeclContext(contextID);
if (declOrOffset.isComplete()) if (declOrOffset.isComplete())
@@ -2143,6 +2208,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
SourceLoc(), { }, genericParams, DC); SourceLoc(), { }, genericParams, DC);
declOrOffset = theClass; declOrOffset = theClass;
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
theClass->setAccessibility(*accessLevel);
} else {
error();
return nullptr;
}
theClass->setAddedImplicitInitializers(); theClass->setAddedImplicitInitializers();
if (isImplicit) if (isImplicit)
theClass->setImplicit(); theClass->setImplicit();
@@ -2193,10 +2265,11 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
DeclID contextID; DeclID contextID;
bool isImplicit; bool isImplicit;
TypeID rawTypeID; TypeID rawTypeID;
uint8_t rawAccessLevel;
ArrayRef<uint64_t> rawProtocolIDs; ArrayRef<uint64_t> rawProtocolIDs;
decls_block::EnumLayout::readRecord(scratch, nameID, contextID, decls_block::EnumLayout::readRecord(scratch, nameID, contextID,
isImplicit, rawTypeID, isImplicit, rawTypeID, rawAccessLevel,
rawProtocolIDs); rawProtocolIDs);
auto DC = getDeclContext(contextID); auto DC = getDeclContext(contextID);
@@ -2212,6 +2285,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
declOrOffset = theEnum; declOrOffset = theEnum;
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
theEnum->setAccessibility(*accessLevel);
} else {
error();
return nullptr;
}
if (isImplicit) if (isImplicit)
theEnum->setImplicit(); theEnum->setImplicit();
theEnum->setRawType(getType(rawTypeID)); theEnum->setRawType(getType(rawTypeID));
@@ -2279,6 +2359,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
elem->setInterfaceType(interfaceType); elem->setInterfaceType(interfaceType);
if (isImplicit) if (isImplicit)
elem->setImplicit(); elem->setImplicit();
elem->setAccessibility(cast<EnumDecl>(DC)->getAccessibility());
break; break;
} }
@@ -2289,6 +2370,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
TypeID declTypeID, elemTypeID, interfaceTypeID; TypeID declTypeID, elemTypeID, interfaceTypeID;
DeclID getterID, setterID; DeclID getterID, setterID;
DeclID overriddenID; DeclID overriddenID;
uint8_t rawAccessLevel;
ArrayRef<uint64_t> argNameIDs; ArrayRef<uint64_t> argNameIDs;
decls_block::SubscriptLayout::readRecord(scratch, contextID, isImplicit, decls_block::SubscriptLayout::readRecord(scratch, contextID, isImplicit,
@@ -2296,7 +2378,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
declTypeID, elemTypeID, declTypeID, elemTypeID,
interfaceTypeID, interfaceTypeID,
getterID, setterID, getterID, setterID,
overriddenID, overriddenID, rawAccessLevel,
argNameIDs); argNameIDs);
auto Getter = cast_or_null<FuncDecl>(getDecl(getterID)); auto Getter = cast_or_null<FuncDecl>(getDecl(getterID));
auto Setter = cast_or_null<FuncDecl>(getDecl(setterID)); auto Setter = cast_or_null<FuncDecl>(getDecl(setterID));
@@ -2321,6 +2403,13 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
SourceLoc(), elemTy, DC); SourceLoc(), elemTy, DC);
declOrOffset = subscript; declOrOffset = subscript;
if (auto accessLevel = getActualAccessibility(rawAccessLevel)) {
subscript->setAccessibility(*accessLevel);
} else {
error();
return nullptr;
}
subscript->setAccessors(SourceRange(), Getter, Setter); subscript->setAccessors(SourceRange(), Getter, Setter);
subscript->setType(getType(declTypeID)); subscript->setType(getType(declTypeID));
if (auto interfaceType = getType(interfaceTypeID)) if (auto interfaceType = getType(interfaceTypeID))
@@ -2383,15 +2472,15 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
decls_block::DestructorLayout::readRecord(scratch, parentID, isImplicit, decls_block::DestructorLayout::readRecord(scratch, parentID, isImplicit,
isObjC, signatureID); isObjC, signatureID);
DeclContext *parent = getDeclContext(parentID); DeclContext *DC = getDeclContext(parentID);
if (declOrOffset.isComplete()) if (declOrOffset.isComplete())
return declOrOffset; return declOrOffset;
auto dtor = new (ctx) DestructorDecl(ctx.Id_deinit, SourceLoc(), auto dtor = new (ctx) DestructorDecl(ctx.Id_deinit, SourceLoc(),
/*selfpat*/nullptr, parent); /*selfpat*/nullptr, DC);
declOrOffset = dtor; declOrOffset = dtor;
dtor->setAccessibility(cast<ClassDecl>(DC)->getAccessibility());
Pattern *selfParams = maybeReadPattern(); Pattern *selfParams = maybeReadPattern();
assert(selfParams && "Didn't get self pattern?"); assert(selfParams && "Didn't get self pattern?");
dtor->setSelfPattern(selfParams); dtor->setSelfPattern(selfParams);

View File

@@ -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 /// Asserts if the declaration has any attributes other than the ones
/// specified in the template parameters. /// specified in the template parameters.
/// ///
@@ -1465,13 +1477,17 @@ void Serializer::writeDecl(const Decl *D) {
if (typeAlias->hasUnderlyingType()) if (typeAlias->hasUnderlyingType())
underlying = typeAlias->getUnderlyingType(); underlying = typeAlias->getUnderlyingType();
uint8_t rawAccessLevel =
getRawStableAccessibility(typeAlias->getAccessibility());
unsigned abbrCode = DeclTypeAbbrCodes[TypeAliasLayout::Code]; unsigned abbrCode = DeclTypeAbbrCodes[TypeAliasLayout::Code];
TypeAliasLayout::emitRecord(Out, ScratchRecord, abbrCode, TypeAliasLayout::emitRecord(Out, ScratchRecord, abbrCode,
addIdentifierRef(typeAlias->getName()), addIdentifierRef(typeAlias->getName()),
addDeclRef(DC), addDeclRef(DC),
addTypeRef(underlying), addTypeRef(underlying),
addTypeRef(typeAlias->getInterfaceType()), addTypeRef(typeAlias->getInterfaceType()),
typeAlias->isImplicit()); typeAlias->isImplicit(),
rawAccessLevel);
break; break;
} }
@@ -1534,11 +1550,15 @@ void Serializer::writeDecl(const Decl *D) {
for (auto proto : theStruct->getProtocols()) for (auto proto : theStruct->getProtocols())
protocols.push_back(addDeclRef(proto)); protocols.push_back(addDeclRef(proto));
uint8_t rawAccessLevel =
getRawStableAccessibility(theStruct->getAccessibility());
unsigned abbrCode = DeclTypeAbbrCodes[StructLayout::Code]; unsigned abbrCode = DeclTypeAbbrCodes[StructLayout::Code];
StructLayout::emitRecord(Out, ScratchRecord, abbrCode, StructLayout::emitRecord(Out, ScratchRecord, abbrCode,
addIdentifierRef(theStruct->getName()), addIdentifierRef(theStruct->getName()),
addDeclRef(DC), addDeclRef(DC),
theStruct->isImplicit(), theStruct->isImplicit(),
rawAccessLevel,
protocols); protocols);
@@ -1561,12 +1581,16 @@ void Serializer::writeDecl(const Decl *D) {
for (auto proto : theEnum->getProtocols()) for (auto proto : theEnum->getProtocols())
protocols.push_back(addDeclRef(proto)); protocols.push_back(addDeclRef(proto));
uint8_t rawAccessLevel =
getRawStableAccessibility(theEnum->getAccessibility());
unsigned abbrCode = DeclTypeAbbrCodes[EnumLayout::Code]; unsigned abbrCode = DeclTypeAbbrCodes[EnumLayout::Code];
EnumLayout::emitRecord(Out, ScratchRecord, abbrCode, EnumLayout::emitRecord(Out, ScratchRecord, abbrCode,
addIdentifierRef(theEnum->getName()), addIdentifierRef(theEnum->getName()),
addDeclRef(DC), addDeclRef(DC),
theEnum->isImplicit(), theEnum->isImplicit(),
addTypeRef(theEnum->getRawType()), addTypeRef(theEnum->getRawType()),
rawAccessLevel,
protocols); protocols);
writeGenericParams(theEnum->getGenericParams(), DeclTypeAbbrCodes); writeGenericParams(theEnum->getGenericParams(), DeclTypeAbbrCodes);
@@ -1589,6 +1613,9 @@ void Serializer::writeDecl(const Decl *D) {
for (auto proto : theClass->getProtocols()) for (auto proto : theClass->getProtocols())
protocols.push_back(addDeclRef(proto)); protocols.push_back(addDeclRef(proto));
uint8_t rawAccessLevel =
getRawStableAccessibility(theClass->getAccessibility());
unsigned abbrCode = DeclTypeAbbrCodes[ClassLayout::Code]; unsigned abbrCode = DeclTypeAbbrCodes[ClassLayout::Code];
ClassLayout::emitRecord(Out, ScratchRecord, abbrCode, ClassLayout::emitRecord(Out, ScratchRecord, abbrCode,
addIdentifierRef(theClass->getName()), addIdentifierRef(theClass->getName()),
@@ -1599,6 +1626,7 @@ void Serializer::writeDecl(const Decl *D) {
theClass->requiresStoredPropertyInits(), theClass->requiresStoredPropertyInits(),
theClass->isForeign(), theClass->isForeign(),
addTypeRef(theClass->getSuperclass()), addTypeRef(theClass->getSuperclass()),
rawAccessLevel,
protocols); protocols);
writeGenericParams(theClass->getGenericParams(), DeclTypeAbbrCodes); writeGenericParams(theClass->getGenericParams(), DeclTypeAbbrCodes);
@@ -1620,12 +1648,16 @@ void Serializer::writeDecl(const Decl *D) {
for (auto proto : proto->getProtocols()) for (auto proto : proto->getProtocols())
protocols.push_back(addDeclRef(proto)); protocols.push_back(addDeclRef(proto));
uint8_t rawAccessLevel =
getRawStableAccessibility(proto->getAccessibility());
unsigned abbrCode = DeclTypeAbbrCodes[ProtocolLayout::Code]; unsigned abbrCode = DeclTypeAbbrCodes[ProtocolLayout::Code];
ProtocolLayout::emitRecord(Out, ScratchRecord, abbrCode, ProtocolLayout::emitRecord(Out, ScratchRecord, abbrCode,
addIdentifierRef(proto->getName()), addIdentifierRef(proto->getName()),
addDeclRef(DC), addDeclRef(DC),
proto->isImplicit(), proto->isImplicit(),
proto->isObjC(), proto->isObjC(),
rawAccessLevel,
protocols); protocols);
writeGenericParams(proto->getGenericParams(), DeclTypeAbbrCodes); writeGenericParams(proto->getGenericParams(), DeclTypeAbbrCodes);
@@ -1644,26 +1676,29 @@ void Serializer::writeDecl(const Decl *D) {
const Decl *DC = getDeclForContext(var->getDeclContext()); const Decl *DC = getDeclForContext(var->getDeclContext());
Type type = var->hasType() ? var->getType() : nullptr; Type type = var->hasType() ? var->getType() : nullptr;
FuncDecl *WillSet = nullptr, *DidSet = nullptr; FuncDecl *willSet = nullptr, *didSet = nullptr;
VarDeclStorageKind StorageKind; VarDeclStorageKind storageKind;
switch (var->getStorageKind()) { switch (var->getStorageKind()) {
case VarDecl::Stored: case VarDecl::Stored:
StorageKind = VarDeclStorageKind::Stored; storageKind = VarDeclStorageKind::Stored;
break; break;
case VarDecl::StoredWithTrivialAccessors: case VarDecl::StoredWithTrivialAccessors:
StorageKind = VarDeclStorageKind::StoredWithTrivialAccessors; storageKind = VarDeclStorageKind::StoredWithTrivialAccessors;
break; break;
case VarDecl::Computed: case VarDecl::Computed:
StorageKind = VarDeclStorageKind::Computed; storageKind = VarDeclStorageKind::Computed;
break; break;
case VarDecl::Observing: case VarDecl::Observing:
StorageKind = VarDeclStorageKind::Observing; storageKind = VarDeclStorageKind::Observing;
WillSet = var->getWillSetFunc(); willSet = var->getWillSetFunc();
DidSet = var->getDidSetFunc(); didSet = var->getDidSetFunc();
break; break;
} }
uint8_t rawAccessLevel =
getRawStableAccessibility(var->getAccessibility());
unsigned abbrCode = DeclTypeAbbrCodes[VarLayout::Code]; unsigned abbrCode = DeclTypeAbbrCodes[VarLayout::Code];
VarLayout::emitRecord(Out, ScratchRecord, abbrCode, VarLayout::emitRecord(Out, ScratchRecord, abbrCode,
addIdentifierRef(var->getName()), addIdentifierRef(var->getName()),
@@ -1673,14 +1708,15 @@ void Serializer::writeDecl(const Decl *D) {
var->getAttrs().isOptional(), var->getAttrs().isOptional(),
var->isStatic(), var->isStatic(),
var->isLet(), var->isLet(),
uint8_t(StorageKind), uint8_t(storageKind),
addTypeRef(type), addTypeRef(type),
addTypeRef(var->getInterfaceType()), addTypeRef(var->getInterfaceType()),
addDeclRef(var->getGetter()), addDeclRef(var->getGetter()),
addDeclRef(var->getSetter()), addDeclRef(var->getSetter()),
addDeclRef(WillSet), addDeclRef(willSet),
addDeclRef(DidSet), addDeclRef(didSet),
addDeclRef(var->getOverriddenDecl())); addDeclRef(var->getOverriddenDecl()),
rawAccessLevel);
break; break;
} }
@@ -1722,6 +1758,9 @@ void Serializer::writeDecl(const Decl *D) {
for (auto argName : fn->getFullName().getArgumentNames()) for (auto argName : fn->getFullName().getArgumentNames())
nameComponents.push_back(addIdentifierRef(argName)); nameComponents.push_back(addIdentifierRef(argName));
uint8_t rawAccessLevel =
getRawStableAccessibility(fn->getAccessibility());
FuncLayout::emitRecord(Out, ScratchRecord, abbrCode, FuncLayout::emitRecord(Out, ScratchRecord, abbrCode,
addDeclRef(DC), addDeclRef(DC),
fn->isImplicit(), fn->isImplicit(),
@@ -1740,6 +1779,7 @@ void Serializer::writeDecl(const Decl *D) {
addDeclRef(fn->getOverriddenDecl()), addDeclRef(fn->getOverriddenDecl()),
addDeclRef(fn->getAccessorStorageDecl()), addDeclRef(fn->getAccessorStorageDecl()),
!fn->getFullName().isSimpleName(), !fn->getFullName().isSimpleName(),
rawAccessLevel,
nameComponents); nameComponents);
writeGenericParams(fn->getGenericParams(), DeclTypeAbbrCodes); writeGenericParams(fn->getGenericParams(), DeclTypeAbbrCodes);
@@ -1779,6 +1819,9 @@ void Serializer::writeDecl(const Decl *D) {
for (auto argName : subscript->getFullName().getArgumentNames()) for (auto argName : subscript->getFullName().getArgumentNames())
nameComponents.push_back(addIdentifierRef(argName)); nameComponents.push_back(addIdentifierRef(argName));
uint8_t rawAccessLevel =
getRawStableAccessibility(subscript->getAccessibility());
unsigned abbrCode = DeclTypeAbbrCodes[SubscriptLayout::Code]; unsigned abbrCode = DeclTypeAbbrCodes[SubscriptLayout::Code];
SubscriptLayout::emitRecord(Out, ScratchRecord, abbrCode, SubscriptLayout::emitRecord(Out, ScratchRecord, abbrCode,
addDeclRef(DC), addDeclRef(DC),
@@ -1791,6 +1834,7 @@ void Serializer::writeDecl(const Decl *D) {
addDeclRef(subscript->getGetter()), addDeclRef(subscript->getGetter()),
addDeclRef(subscript->getSetter()), addDeclRef(subscript->getSetter()),
addDeclRef(subscript->getOverriddenDecl()), addDeclRef(subscript->getOverriddenDecl()),
rawAccessLevel,
nameComponents); nameComponents);
writePattern(subscript->getIndices()); writePattern(subscript->getIndices());
@@ -1809,6 +1853,9 @@ void Serializer::writeDecl(const Decl *D) {
for (auto argName : ctor->getFullName().getArgumentNames()) for (auto argName : ctor->getFullName().getArgumentNames())
nameComponents.push_back(addIdentifierRef(argName)); nameComponents.push_back(addIdentifierRef(argName));
uint8_t rawAccessLevel =
getRawStableAccessibility(ctor->getAccessibility());
unsigned abbrCode = DeclTypeAbbrCodes[ConstructorLayout::Code]; unsigned abbrCode = DeclTypeAbbrCodes[ConstructorLayout::Code];
ConstructorLayout::emitRecord(Out, ScratchRecord, abbrCode, ConstructorLayout::emitRecord(Out, ScratchRecord, abbrCode,
addDeclRef(DC), addDeclRef(DC),
@@ -1820,6 +1867,7 @@ void Serializer::writeDecl(const Decl *D) {
addTypeRef(ctor->getType()), addTypeRef(ctor->getType()),
addTypeRef(ctor->getInterfaceType()), addTypeRef(ctor->getInterfaceType()),
addDeclRef(ctor->getOverriddenDecl()), addDeclRef(ctor->getOverriddenDecl()),
rawAccessLevel,
nameComponents); nameComponents);
writeGenericParams(ctor->getGenericParams(), DeclTypeAbbrCodes); writeGenericParams(ctor->getGenericParams(), DeclTypeAbbrCodes);