Skip to content

Commit 6cca352

Browse files
committed
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
1 parent 8a38f4d commit 6cca352

File tree

12 files changed

+422
-80
lines changed

12 files changed

+422
-80
lines changed

include/swift/AST/Decl.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,15 +1488,17 @@ class ExtensionDecl : public Decl, public DeclContext,
14881488
ExtensionDeclBits.CheckedInheritanceClause = checked;
14891489
}
14901490

1491+
bool hasDefaultAccessibility() const {
1492+
return ExtensionDeclBits.DefaultAccessLevel != 0;
1493+
}
1494+
14911495
Accessibility getDefaultAccessibility() const {
1492-
assert(ExtensionDeclBits.DefaultAccessLevel != 0 &&
1493-
"default accessibility not computed yet");
1496+
assert(hasDefaultAccessibility() && "not computed yet");
14941497
return static_cast<Accessibility>(ExtensionDeclBits.DefaultAccessLevel - 1);
14951498
}
14961499

14971500
void setDefaultAccessibility(Accessibility access) {
1498-
assert(ExtensionDeclBits.DefaultAccessLevel == 0 &&
1499-
"default accessibility already set");
1501+
assert(!hasDefaultAccessibility() && "default accessibility already set");
15001502
ExtensionDeclBits.DefaultAccessLevel = static_cast<unsigned>(access) + 1;
15011503
}
15021504

@@ -1834,13 +1836,17 @@ class ValueDecl : public Decl {
18341836
/// Overwrite the type of this declaration.
18351837
void overwriteType(Type T);
18361838

1839+
bool hasAccessibility() const {
1840+
return TypeAndAccess.getInt() != 0;
1841+
}
1842+
18371843
Accessibility getAccessibility() const {
1838-
assert(TypeAndAccess.getInt() != 0 && "accessibility not computed yet");
1844+
assert(hasAccessibility() && "accessibility not computed yet");
18391845
return static_cast<Accessibility>(TypeAndAccess.getInt() - 1);
18401846
}
18411847

18421848
void setAccessibility(Accessibility access) {
1843-
assert(TypeAndAccess.getInt() == 0 && "accessibility already set");
1849+
assert(!hasAccessibility() && "accessibility already set");
18441850
TypeAndAccess.setInt(static_cast<unsigned>(access) + 1);
18451851
}
18461852

include/swift/Serialization/ModuleFormat.h

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const uint16_t VERSION_MAJOR = 0;
4040
/// Serialized module format minor version number.
4141
///
4242
/// When the format changes IN ANY WAY, this number should be incremented.
43-
const uint16_t VERSION_MINOR = 105;
43+
const uint16_t VERSION_MINOR = 106;
4444

4545
using DeclID = Fixnum<31>;
4646
using DeclIDField = BCFixed<31>;
@@ -210,6 +210,15 @@ enum LibraryKind : uint8_t {
210210
};
211211
using LibraryKindField = BCFixed<1>;
212212

213+
// These IDs must \em not be renumbered or reordered without incrementing
214+
// VERSION_MAJOR.
215+
enum class AccessibilityKind : uint8_t {
216+
Private = 0,
217+
Internal,
218+
Public,
219+
};
220+
using AccessibilityKindField = BCFixed<2>;
221+
213222
// These IDs must \em not be renumbered or reordered without incrementing
214223
// VERSION_MAJOR.
215224
enum SpecialModuleID : uint8_t {
@@ -583,7 +592,8 @@ namespace decls_block {
583592
DeclIDField, // context decl
584593
TypeIDField, // underlying type
585594
TypeIDField, // interface type
586-
BCFixed<1> // implicit flag
595+
BCFixed<1>, // implicit flag
596+
AccessibilityKindField // accessibility
587597
>;
588598

589599
using GenericTypeParamDeclLayout = BCRecordLayout<
@@ -611,21 +621,23 @@ namespace decls_block {
611621

612622
using StructLayout = BCRecordLayout<
613623
STRUCT_DECL,
614-
IdentifierIDField, // name
615-
DeclIDField, // context decl
616-
BCFixed<1>, // implicit flag
617-
BCArray<DeclIDField> // protocols
624+
IdentifierIDField, // name
625+
DeclIDField, // context decl
626+
BCFixed<1>, // implicit flag
627+
AccessibilityKindField, // accessibility
628+
BCArray<DeclIDField> // protocols
618629
// Trailed by the generic parameters (if any), the decl context record, and
619630
// finally conformance info (if any).
620631
>;
621632

622633
using EnumLayout = BCRecordLayout<
623634
ENUM_DECL,
624-
IdentifierIDField, // name
625-
DeclIDField, // context decl
626-
BCFixed<1>, // implicit flag
627-
TypeIDField, // raw type
628-
BCArray<DeclIDField> // protocols
635+
IdentifierIDField, // name
636+
DeclIDField, // context decl
637+
BCFixed<1>, // implicit flag
638+
TypeIDField, // raw type
639+
AccessibilityKindField, // accessibility
640+
BCArray<DeclIDField> // protocols
629641
// Trailed by the generic parameters (if any), the decl context record, and
630642
// finally conformance info (if any).
631643
>;
@@ -640,19 +652,21 @@ namespace decls_block {
640652
BCFixed<1>, // requires stored property initial values
641653
BCFixed<1>, // foreign
642654
TypeIDField, // superclass
643-
BCArray<DeclIDField> // protocols
655+
AccessibilityKindField, // accessibility
656+
BCArray<DeclIDField> // protocols
644657
// Trailed by the generic parameters (if any), the decl context record, and
645658
// finally conformance info (if any).
646659
>;
647660

648661
using ProtocolLayout = BCRecordLayout<
649662
PROTOCOL_DECL,
650-
IdentifierIDField, // name
651-
DeclIDField, // context decl
652-
BCFixed<1>, // implicit flag
653-
BCFixed<1>, // objc?
654-
BCArray<DeclIDField> // protocols
655-
// Trailed by the generic parameters (if any) and the decl context record
663+
IdentifierIDField, // name
664+
DeclIDField, // context decl
665+
BCFixed<1>, // implicit flag
666+
BCFixed<1>, // objc?
667+
AccessibilityKindField, // accessibility
668+
BCArray<DeclIDField> // protocols
669+
// Trailed by the generic parameters (if any) and the decl context record
656670
>;
657671

658672
using ConstructorLayout = BCRecordLayout<
@@ -665,6 +679,7 @@ namespace decls_block {
665679
TypeIDField, // type (signature)
666680
TypeIDField, // type (interface)
667681
DeclIDField, // overridden decl
682+
AccessibilityKindField, // accessibility
668683
BCArray<IdentifierIDField> // argument names
669684
// Trailed by its generic parameters, if any, followed by the parameter
670685
// patterns.
@@ -686,7 +701,8 @@ namespace decls_block {
686701
DeclIDField, // setter
687702
DeclIDField, // willset
688703
DeclIDField, // didset
689-
DeclIDField // overridden decl
704+
DeclIDField, // overridden decl
705+
AccessibilityKindField // accessibility
690706
>;
691707

692708
using ParamLayout = BCRecordLayout<
@@ -718,6 +734,7 @@ namespace decls_block {
718734
DeclIDField, // overridden function
719735
DeclIDField, // AccessorStorageDecl
720736
BCFixed<1>, // name is compound?
737+
AccessibilityKindField, // accessibility
721738
BCArray<IdentifierIDField> // name components
722739
// The record is trailed by:
723740
// - its asmname, if any
@@ -774,6 +791,7 @@ namespace decls_block {
774791
DeclIDField, // getter
775792
DeclIDField, // setter
776793
DeclIDField, // overridden decl
794+
AccessibilityKindField, // accessibility
777795
BCArray<IdentifierIDField> // name components
778796
// The indices pattern trails the record.
779797
>;

lib/AST/Builtins.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ getBuiltinFunction(Identifier Id,
167167
TypeLoc::withoutLoc(ResType),
168168
DC);
169169
FD->setImplicit();
170+
FD->setAccessibility(Accessibility::Public);
170171
return FD;
171172
}
172173

@@ -240,7 +241,8 @@ getBuiltinGenericFunction(Identifier Id,
240241

241242
func->setInterfaceType(InterfaceType);
242243
func->setImplicit();
243-
244+
func->setAccessibility(Accessibility::Public);
245+
244246
return func;
245247
}
246248

lib/AST/Module.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,14 @@ void BuiltinUnit::LookupCache::lookupValue(Identifier Name, NLKind LookupKind,
6868

6969
ValueDecl *&Entry = Cache[Name];
7070
ASTContext &Ctx = M.getParentModule()->Ctx;
71-
if (Entry == 0)
72-
if (Type Ty = getBuiltinType(Ctx, Name.str()))
71+
if (Entry == 0) {
72+
if (Type Ty = getBuiltinType(Ctx, Name.str())) {
7373
Entry = new (Ctx) TypeAliasDecl(SourceLoc(), Name, SourceLoc(),
7474
TypeLoc::withoutLoc(Ty),
7575
const_cast<BuiltinUnit*>(&M));
76+
Entry->setAccessibility(Accessibility::Public);
77+
}
78+
}
7679

7780
if (Entry == 0)
7881
Entry = getBuiltinValueDecl(Ctx, Name);

lib/AST/Verifier.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,16 @@ struct ASTNodeBase {};
13761376
verifyCheckedBase(E);
13771377
}
13781378

1379+
void verifyChecked(ValueDecl *VD) {
1380+
if (!VD->hasAccessibility() && !VD->getDeclContext()->isLocalContext() &&
1381+
!isa<GenericTypeParamDecl>(VD) && !isa<ParamDecl>(VD)) {
1382+
dumpRef(VD);
1383+
Out << " does not have accessibility";
1384+
abort();
1385+
}
1386+
verifyCheckedBase(VD);
1387+
}
1388+
13791389
void verifyChecked(PatternBindingDecl *binding) {
13801390
}
13811391

lib/ClangImporter/ImportDecl.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,7 @@ static FuncDecl *makeOptionSetFactoryMethod(
473473

474474
factoryDecl->setStatic();
475475
factoryDecl->setImplicit();
476+
factoryDecl->setAccessibility(Accessibility::Public);
476477

477478
Type factoryType = FunctionType::get(ParenType::get(C, rawType), retType);
478479
factoryType = FunctionType::get(selfDecl->getType(), factoryType);
@@ -533,7 +534,8 @@ static FuncDecl *makeOptionSetToRawMethod(StructDecl *optionSetDecl,
533534
toRawType = FunctionType::get(optionSetType, toRawType);
534535
toRawDecl->setType(toRawType);
535536
toRawDecl->setBodyResultType(rawType);
536-
537+
toRawDecl->setAccessibility(Accessibility::Public);
538+
537539
auto selfRef = new (C) DeclRefExpr(selfDecl, SourceLoc(), /*implicit*/ true);
538540
auto valueRef = new (C) MemberRefExpr(selfRef, SourceLoc(),
539541
valueDecl, SourceLoc(),
@@ -615,7 +617,8 @@ static FuncDecl *makeOptionSetGetLogicValueMethod(StructDecl *optionSetDecl,
615617
toRawType);
616618
getLVDecl->setType(toRawType);
617619
getLVDecl->setBodyResultType(boolType);
618-
620+
getLVDecl->setAccessibility(Accessibility::Public);
621+
619622
auto selfRef = new (C) DeclRefExpr(selfDecl, SourceLoc(), /*implicit*/ true);
620623
auto valueRef = new (C) MemberRefExpr(selfRef, SourceLoc(),
621624
valueDecl, SourceLoc(),
@@ -671,7 +674,8 @@ static FuncDecl *makeNilLiteralConformance(StructDecl *optionSetDecl,
671674

672675
factoryDecl->setStatic();
673676
factoryDecl->setImplicit();
674-
677+
factoryDecl->setAccessibility(Accessibility::Public);
678+
675679
Type factoryType = FunctionType::get(TupleType::getEmpty(C), optionSetType);
676680
factoryType = FunctionType::get(selfDecl->getType(), factoryType);
677681
factoryDecl->setType(factoryType);
@@ -724,7 +728,8 @@ static ConstructorDecl *makeOptionSetDefaultConstructor(StructDecl *optionSetDec
724728
selfPattern, methodParam,
725729
nullptr, optionSetDecl);
726730
ctorDecl->setImplicit();
727-
731+
ctorDecl->setAccessibility(Accessibility::Public);
732+
728733
auto fnTy = FunctionType::get(TupleType::getEmpty(C), optionSetType);
729734
auto allocFnTy = FunctionType::get(metaTy, fnTy);
730735
auto initFnTy = FunctionType::get(optionSetType, fnTy);
@@ -786,6 +791,7 @@ static FuncDecl *makeClassToClassImplicitConversion(ClassDecl *fromDecl,
786791
params, TypeLoc::withoutLoc(resultType), fromDecl);
787792
conversionDecl->setImplicit();
788793
conversionDecl->getMutableAttrs().add(new (C) FinalAttr(/*implicit*/ true));
794+
conversionDecl->setAccessibility(Accessibility::Public);
789795

790796
auto argType = TupleType::getEmpty(C);
791797
Type fnType = FunctionType::get(argType, resultType);
@@ -1220,6 +1226,7 @@ namespace {
12201226
auto initFnTy = FunctionType::get(selfType, fnTy);
12211227
constructor->setType(allocFnTy);
12221228
constructor->setInitializerType(initFnTy);
1229+
constructor->setAccessibility(Accessibility::Public);
12231230

12241231
// Assign all of the member variables appropriately.
12251232
SmallVector<ASTNode, 4> stmts;
@@ -1423,6 +1430,7 @@ namespace {
14231430
SourceLoc(), varName,
14241431
underlyingType,
14251432
structDecl);
1433+
var->setAccessibility(Accessibility::Private);
14261434

14271435
// Create a pattern binding to describe the variable.
14281436
Pattern *varPattern = createTypedNamedPattern(var);
@@ -1500,6 +1508,7 @@ namespace {
15001508
SourceLoc(), varName,
15011509
underlyingType,
15021510
structDecl);
1511+
var->setAccessibility(Accessibility::Private);
15031512

15041513
// Create a pattern binding to describe the variable.
15051514
Pattern *varPattern = createTypedNamedPattern(var);
@@ -1864,6 +1873,8 @@ namespace {
18641873
/*GenericParams=*/nullptr, type, bodyPatterns,
18651874
TypeLoc::withoutLoc(resultTy), dc, decl);
18661875

1876+
result->setAccessibility(Accessibility::Public);
1877+
18671878
if (decl->isNoReturn())
18681879
result->getMutableAttrs().add(
18691880
new (Impl.SwiftContext) NoReturnAttr(/*IsImplicit=*/false));
@@ -2251,6 +2262,8 @@ namespace {
22512262
SourceLoc(), name, SourceLoc(), /*GenericParams=*/nullptr, Type(),
22522263
bodyPatterns, TypeLoc(), dc, decl);
22532264

2265+
result->setAccessibility(Accessibility::Public);
2266+
22542267
auto resultTy = type->castTo<FunctionType>()->getResult();
22552268
Type interfaceType;
22562269

@@ -2827,6 +2840,7 @@ namespace {
28272840
TypeLoc::withoutLoc(elementTy), dc);
28282841
thunk->setBodyResultType(elementTy);
28292842
thunk->setInterfaceType(interfaceType);
2843+
thunk->setAccessibility(Accessibility::Public);
28302844

28312845
if (auto objcAttr = getter->getAttrs().getAttribute<ObjCAttr>())
28322846
thunk->getMutableAttrs().add(objcAttr->clone(context));
@@ -2913,6 +2927,7 @@ namespace {
29132927
TypeLoc::withoutLoc(TupleType::getEmpty(context)), dc);
29142928
thunk->setBodyResultType(TupleType::getEmpty(context));
29152929
thunk->setInterfaceType(interfaceType);
2930+
thunk->setAccessibility(Accessibility::Public);
29162931

29172932
if (auto objcAttr = setter->getAttrs().getAttribute<ObjCAttr>())
29182933
thunk->getMutableAttrs().add(objcAttr->clone(context));
@@ -3427,6 +3442,7 @@ namespace {
34273442
// Turn this into a computed property.
34283443
// FIXME: Fake locations for '{' and '}'?
34293444
result->makeComputed(SourceLoc(), getter, setter, SourceLoc());
3445+
result->setAccessibility(Accessibility::Public);
34303446
addObjCAttribute(result, Nothing);
34313447

34323448
if (overridden)
@@ -4851,6 +4867,7 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
48514867
TypeLoc::withoutLoc(type), dc);
48524868
func->setStatic(isStatic);
48534869
func->setBodyResultType(type);
4870+
func->setAccessibility(Accessibility::Public);
48544871

48554872
auto expr = valueExpr;
48564873

lib/ClangImporter/ImporterImpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
939939
auto D = ::new (DeclPtr) DeclTy(std::forward<Targs>(Args)...);
940940
D->setClangNode(ClangN);
941941
D->setEarlyAttrValidation(true);
942+
if (auto VD = dyn_cast<ValueDecl>(D))
943+
VD->setAccessibility(Accessibility::Public);
942944
return D;
943945
}
944946
};

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,11 @@ deriveEquatable_enum_eq(TypeChecker &tc, EnumDecl *enumDecl) {
239239
eqDecl->setType(fnTy);
240240
eqDecl->setInterfaceType(interfaceTy);
241241

242+
// Since we can't insert the == operator into the same FileUnit as the enum,
243+
// itself, we have to give it at least internal access.
244+
eqDecl->setAccessibility(std::max(enumDecl->getAccessibility(),
245+
Accessibility::Internal));
246+
242247
if (enumDecl->hasClangNode())
243248
tc.implicitlyDefinedFunctions.push_back(eqDecl);
244249

@@ -430,7 +435,8 @@ deriveHashable_enum_hashValue(TypeChecker &tc, EnumDecl *enumDecl) {
430435
interfaceType = type;
431436

432437
getterDecl->setInterfaceType(interfaceType);
433-
438+
getterDecl->setAccessibility(enumDecl->getAccessibility());
439+
434440
if (enumDecl->hasClangNode())
435441
tc.implicitlyDefinedFunctions.push_back(getterDecl);
436442

@@ -441,7 +447,8 @@ deriveHashable_enum_hashValue(TypeChecker &tc, EnumDecl *enumDecl) {
441447
intType, enumDecl);
442448
hashValueDecl->setImplicit();
443449
hashValueDecl->makeComputed(SourceLoc(), getterDecl, nullptr, SourceLoc());
444-
450+
hashValueDecl->setAccessibility(enumDecl->getAccessibility());
451+
445452
Pattern *hashValuePat = new (C) NamedPattern(hashValueDecl, /*implicit*/true);
446453
hashValuePat->setType(intType);
447454
hashValuePat

0 commit comments

Comments
 (0)